1/* 2 * UWB reservation management. 3 * 4 * Copyright (C) 2008 Cambridge Silicon Radio Ltd. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18#include <linux/kernel.h> 19#include <linux/uwb.h> 20#include <linux/slab.h> 21#include <linux/random.h> 22 23#include "uwb-internal.h" 24 25static void uwb_rsv_timer(unsigned long arg); 26 27static const char *rsv_states[] = { 28 [UWB_RSV_STATE_NONE] = "none ", 29 [UWB_RSV_STATE_O_INITIATED] = "o initiated ", 30 [UWB_RSV_STATE_O_PENDING] = "o pending ", 31 [UWB_RSV_STATE_O_MODIFIED] = "o modified ", 32 [UWB_RSV_STATE_O_ESTABLISHED] = "o established ", 33 [UWB_RSV_STATE_O_TO_BE_MOVED] = "o to be moved ", 34 [UWB_RSV_STATE_O_MOVE_EXPANDING] = "o move expanding", 35 [UWB_RSV_STATE_O_MOVE_COMBINING] = "o move combining", 36 [UWB_RSV_STATE_O_MOVE_REDUCING] = "o move reducing ", 37 [UWB_RSV_STATE_T_ACCEPTED] = "t accepted ", 38 [UWB_RSV_STATE_T_CONFLICT] = "t conflict ", 39 [UWB_RSV_STATE_T_PENDING] = "t pending ", 40 [UWB_RSV_STATE_T_DENIED] = "t denied ", 41 [UWB_RSV_STATE_T_RESIZED] = "t resized ", 42 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = "t expanding acc ", 43 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = "t expanding conf", 44 [UWB_RSV_STATE_T_EXPANDING_PENDING] = "t expanding pend", 45 [UWB_RSV_STATE_T_EXPANDING_DENIED] = "t expanding den ", 46}; 47 48static const char *rsv_types[] = { 49 [UWB_DRP_TYPE_ALIEN_BP] = "alien-bp", 50 [UWB_DRP_TYPE_HARD] = "hard", 51 [UWB_DRP_TYPE_SOFT] = "soft", 52 [UWB_DRP_TYPE_PRIVATE] = "private", 53 [UWB_DRP_TYPE_PCA] = "pca", 54}; 55 56bool uwb_rsv_has_two_drp_ies(struct uwb_rsv *rsv) 57{ 58 static const bool has_two_drp_ies[] = { 59 [UWB_RSV_STATE_O_INITIATED] = false, 60 [UWB_RSV_STATE_O_PENDING] = false, 61 [UWB_RSV_STATE_O_MODIFIED] = false, 62 [UWB_RSV_STATE_O_ESTABLISHED] = false, 63 [UWB_RSV_STATE_O_TO_BE_MOVED] = false, 64 [UWB_RSV_STATE_O_MOVE_COMBINING] = false, 65 [UWB_RSV_STATE_O_MOVE_REDUCING] = false, 66 [UWB_RSV_STATE_O_MOVE_EXPANDING] = true, 67 [UWB_RSV_STATE_T_ACCEPTED] = false, 68 [UWB_RSV_STATE_T_CONFLICT] = false, 69 [UWB_RSV_STATE_T_PENDING] = false, 70 [UWB_RSV_STATE_T_DENIED] = false, 71 [UWB_RSV_STATE_T_RESIZED] = false, 72 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = true, 73 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = true, 74 [UWB_RSV_STATE_T_EXPANDING_PENDING] = true, 75 [UWB_RSV_STATE_T_EXPANDING_DENIED] = true, 76 }; 77 78 return has_two_drp_ies[rsv->state]; 79} 80 81/** 82 * uwb_rsv_state_str - return a string for a reservation state 83 * @state: the reservation state. 84 */ 85const char *uwb_rsv_state_str(enum uwb_rsv_state state) 86{ 87 if (state < UWB_RSV_STATE_NONE || state >= UWB_RSV_STATE_LAST) 88 return "unknown"; 89 return rsv_states[state]; 90} 91EXPORT_SYMBOL_GPL(uwb_rsv_state_str); 92 93/** 94 * uwb_rsv_type_str - return a string for a reservation type 95 * @type: the reservation type 96 */ 97const char *uwb_rsv_type_str(enum uwb_drp_type type) 98{ 99 if (type < UWB_DRP_TYPE_ALIEN_BP || type > UWB_DRP_TYPE_PCA) 100 return "invalid"; 101 return rsv_types[type]; 102} 103EXPORT_SYMBOL_GPL(uwb_rsv_type_str); 104 105void uwb_rsv_dump(char *text, struct uwb_rsv *rsv) 106{ 107 struct device *dev = &rsv->rc->uwb_dev.dev; 108 struct uwb_dev_addr devaddr; 109 char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE]; 110 111 uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr); 112 if (rsv->target.type == UWB_RSV_TARGET_DEV) 113 devaddr = rsv->target.dev->dev_addr; 114 else 115 devaddr = rsv->target.devaddr; 116 uwb_dev_addr_print(target, sizeof(target), &devaddr); 117 118 dev_dbg(dev, "rsv %s %s -> %s: %s\n", 119 text, owner, target, uwb_rsv_state_str(rsv->state)); 120} 121 122static void uwb_rsv_release(struct kref *kref) 123{ 124 struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref); 125 126 kfree(rsv); 127} 128 129void uwb_rsv_get(struct uwb_rsv *rsv) 130{ 131 kref_get(&rsv->kref); 132} 133 134void uwb_rsv_put(struct uwb_rsv *rsv) 135{ 136 kref_put(&rsv->kref, uwb_rsv_release); 137} 138 139/* 140 * Get a free stream index for a reservation. 141 * 142 * If the target is a DevAddr (e.g., a WUSB cluster reservation) then 143 * the stream is allocated from a pool of per-RC stream indexes, 144 * otherwise a unique stream index for the target is selected. 145 */ 146static int uwb_rsv_get_stream(struct uwb_rsv *rsv) 147{ 148 struct uwb_rc *rc = rsv->rc; 149 struct device *dev = &rc->uwb_dev.dev; 150 unsigned long *streams_bm; 151 int stream; 152 153 switch (rsv->target.type) { 154 case UWB_RSV_TARGET_DEV: 155 streams_bm = rsv->target.dev->streams; 156 break; 157 case UWB_RSV_TARGET_DEVADDR: 158 streams_bm = rc->uwb_dev.streams; 159 break; 160 default: 161 return -EINVAL; 162 } 163 164 stream = find_first_zero_bit(streams_bm, UWB_NUM_STREAMS); 165 if (stream >= UWB_NUM_STREAMS) 166 return -EBUSY; 167 168 rsv->stream = stream; 169 set_bit(stream, streams_bm); 170 171 dev_dbg(dev, "get stream %d\n", rsv->stream); 172 173 return 0; 174} 175 176static void uwb_rsv_put_stream(struct uwb_rsv *rsv) 177{ 178 struct uwb_rc *rc = rsv->rc; 179 struct device *dev = &rc->uwb_dev.dev; 180 unsigned long *streams_bm; 181 182 switch (rsv->target.type) { 183 case UWB_RSV_TARGET_DEV: 184 streams_bm = rsv->target.dev->streams; 185 break; 186 case UWB_RSV_TARGET_DEVADDR: 187 streams_bm = rc->uwb_dev.streams; 188 break; 189 default: 190 return; 191 } 192 193 clear_bit(rsv->stream, streams_bm); 194 195 dev_dbg(dev, "put stream %d\n", rsv->stream); 196} 197 198void uwb_rsv_backoff_win_timer(unsigned long arg) 199{ 200 struct uwb_drp_backoff_win *bow = (struct uwb_drp_backoff_win *)arg; 201 struct uwb_rc *rc = container_of(bow, struct uwb_rc, bow); 202 struct device *dev = &rc->uwb_dev.dev; 203 204 bow->can_reserve_extra_mases = true; 205 if (bow->total_expired <= 4) { 206 bow->total_expired++; 207 } else { 208 /* after 4 backoff window has expired we can exit from 209 * the backoff procedure */ 210 bow->total_expired = 0; 211 bow->window = UWB_DRP_BACKOFF_WIN_MIN >> 1; 212 } 213 dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n: ", bow->total_expired, bow->n); 214 215 /* try to relocate all the "to be moved" relocations */ 216 uwb_rsv_handle_drp_avail_change(rc); 217} 218 219void uwb_rsv_backoff_win_increment(struct uwb_rc *rc) 220{ 221 struct uwb_drp_backoff_win *bow = &rc->bow; 222 struct device *dev = &rc->uwb_dev.dev; 223 unsigned timeout_us; 224 225 dev_dbg(dev, "backoff_win_increment: window=%d\n", bow->window); 226 227 bow->can_reserve_extra_mases = false; 228 229 if((bow->window << 1) == UWB_DRP_BACKOFF_WIN_MAX) 230 return; 231 232 bow->window <<= 1; 233 bow->n = random32() & (bow->window - 1); 234 dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n); 235 236 /* reset the timer associated variables */ 237 timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US; 238 bow->total_expired = 0; 239 mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us)); 240} 241 242static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) 243{ 244 int sframes = UWB_MAX_LOST_BEACONS; 245 246 /* 247 * Multicast reservations can become established within 1 248 * super frame and should not be terminated if no response is 249 * received. 250 */ 251 if (rsv->is_multicast) { 252 if (rsv->state == UWB_RSV_STATE_O_INITIATED 253 || rsv->state == UWB_RSV_STATE_O_MOVE_EXPANDING 254 || rsv->state == UWB_RSV_STATE_O_MOVE_COMBINING 255 || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING) 256 sframes = 1; 257 if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED) 258 sframes = 0; 259 260 } 261 262 if (sframes > 0) { 263 /* 264 * Add an additional 2 superframes to account for the 265 * time to send the SET DRP IE command. 266 */ 267 unsigned timeout_us = (sframes + 2) * UWB_SUPERFRAME_LENGTH_US; 268 mod_timer(&rsv->timer, jiffies + usecs_to_jiffies(timeout_us)); 269 } else 270 del_timer(&rsv->timer); 271} 272 273/* 274 * Update a reservations state, and schedule an update of the 275 * transmitted DRP IEs. 276 */ 277static void uwb_rsv_state_update(struct uwb_rsv *rsv, 278 enum uwb_rsv_state new_state) 279{ 280 rsv->state = new_state; 281 rsv->ie_valid = false; 282 283 uwb_rsv_dump("SU", rsv); 284 285 uwb_rsv_stroke_timer(rsv); 286 uwb_rsv_sched_update(rsv->rc); 287} 288 289static void uwb_rsv_callback(struct uwb_rsv *rsv) 290{ 291 if (rsv->callback) 292 rsv->callback(rsv); 293} 294 295void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) 296{ 297 struct uwb_rsv_move *mv = &rsv->mv; 298 299 if (rsv->state == new_state) { 300 switch (rsv->state) { 301 case UWB_RSV_STATE_O_ESTABLISHED: 302 case UWB_RSV_STATE_O_MOVE_EXPANDING: 303 case UWB_RSV_STATE_O_MOVE_COMBINING: 304 case UWB_RSV_STATE_O_MOVE_REDUCING: 305 case UWB_RSV_STATE_T_ACCEPTED: 306 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: 307 case UWB_RSV_STATE_T_RESIZED: 308 case UWB_RSV_STATE_NONE: 309 uwb_rsv_stroke_timer(rsv); 310 break; 311 default: 312 /* Expecting a state transition so leave timer 313 as-is. */ 314 break; 315 } 316 return; 317 } 318 319 uwb_rsv_dump("SC", rsv); 320 321 switch (new_state) { 322 case UWB_RSV_STATE_NONE: 323 uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); 324 uwb_rsv_callback(rsv); 325 break; 326 case UWB_RSV_STATE_O_INITIATED: 327 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_INITIATED); 328 break; 329 case UWB_RSV_STATE_O_PENDING: 330 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING); 331 break; 332 case UWB_RSV_STATE_O_MODIFIED: 333 /* in the companion there are the MASes to drop */ 334 bitmap_andnot(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS); 335 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MODIFIED); 336 break; 337 case UWB_RSV_STATE_O_ESTABLISHED: 338 if (rsv->state == UWB_RSV_STATE_O_MODIFIED 339 || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING) { 340 uwb_drp_avail_release(rsv->rc, &mv->companion_mas); 341 rsv->needs_release_companion_mas = false; 342 } 343 uwb_drp_avail_reserve(rsv->rc, &rsv->mas); 344 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED); 345 uwb_rsv_callback(rsv); 346 break; 347 case UWB_RSV_STATE_O_MOVE_EXPANDING: 348 rsv->needs_release_companion_mas = true; 349 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING); 350 break; 351 case UWB_RSV_STATE_O_MOVE_COMBINING: 352 rsv->needs_release_companion_mas = false; 353 uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas); 354 bitmap_or(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS); 355 rsv->mas.safe += mv->companion_mas.safe; 356 rsv->mas.unsafe += mv->companion_mas.unsafe; 357 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); 358 break; 359 case UWB_RSV_STATE_O_MOVE_REDUCING: 360 bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS); 361 rsv->needs_release_companion_mas = true; 362 rsv->mas.safe = mv->final_mas.safe; 363 rsv->mas.unsafe = mv->final_mas.unsafe; 364 bitmap_copy(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS); 365 bitmap_copy(rsv->mas.unsafe_bm, mv->final_mas.unsafe_bm, UWB_NUM_MAS); 366 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); 367 break; 368 case UWB_RSV_STATE_T_ACCEPTED: 369 case UWB_RSV_STATE_T_RESIZED: 370 rsv->needs_release_companion_mas = false; 371 uwb_drp_avail_reserve(rsv->rc, &rsv->mas); 372 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED); 373 uwb_rsv_callback(rsv); 374 break; 375 case UWB_RSV_STATE_T_DENIED: 376 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED); 377 break; 378 case UWB_RSV_STATE_T_CONFLICT: 379 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_CONFLICT); 380 break; 381 case UWB_RSV_STATE_T_PENDING: 382 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_PENDING); 383 break; 384 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: 385 rsv->needs_release_companion_mas = true; 386 uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas); 387 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED); 388 break; 389 default: 390 dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n", 391 uwb_rsv_state_str(new_state), new_state); 392 } 393} 394 395static void uwb_rsv_handle_timeout_work(struct work_struct *work) 396{ 397 struct uwb_rsv *rsv = container_of(work, struct uwb_rsv, 398 handle_timeout_work); 399 struct uwb_rc *rc = rsv->rc; 400 401 mutex_lock(&rc->rsvs_mutex); 402 403 uwb_rsv_dump("TO", rsv); 404 405 switch (rsv->state) { 406 case UWB_RSV_STATE_O_INITIATED: 407 if (rsv->is_multicast) { 408 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); 409 goto unlock; 410 } 411 break; 412 case UWB_RSV_STATE_O_MOVE_EXPANDING: 413 if (rsv->is_multicast) { 414 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); 415 goto unlock; 416 } 417 break; 418 case UWB_RSV_STATE_O_MOVE_COMBINING: 419 if (rsv->is_multicast) { 420 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); 421 goto unlock; 422 } 423 break; 424 case UWB_RSV_STATE_O_MOVE_REDUCING: 425 if (rsv->is_multicast) { 426 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); 427 goto unlock; 428 } 429 break; 430 case UWB_RSV_STATE_O_ESTABLISHED: 431 if (rsv->is_multicast) 432 goto unlock; 433 break; 434 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: 435 /* 436 * The time out could be for the main or of the 437 * companion DRP, assume it's for the companion and 438 * drop that first. A further time out is required to 439 * drop the main. 440 */ 441 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); 442 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); 443 goto unlock; 444 default: 445 break; 446 } 447 448 uwb_rsv_remove(rsv); 449 450unlock: 451 mutex_unlock(&rc->rsvs_mutex); 452} 453 454static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc) 455{ 456 struct uwb_rsv *rsv; 457 458 rsv = kzalloc(sizeof(struct uwb_rsv), GFP_KERNEL); 459 if (!rsv) 460 return NULL; 461 462 INIT_LIST_HEAD(&rsv->rc_node); 463 INIT_LIST_HEAD(&rsv->pal_node); 464 kref_init(&rsv->kref); 465 init_timer(&rsv->timer); 466 rsv->timer.function = uwb_rsv_timer; 467 rsv->timer.data = (unsigned long)rsv; 468 469 rsv->rc = rc; 470 INIT_WORK(&rsv->handle_timeout_work, uwb_rsv_handle_timeout_work); 471 472 return rsv; 473} 474 475/** 476 * uwb_rsv_create - allocate and initialize a UWB reservation structure 477 * @rc: the radio controller 478 * @cb: callback to use when the reservation completes or terminates 479 * @pal_priv: data private to the PAL to be passed in the callback 480 * 481 * The callback is called when the state of the reservation changes from: 482 * 483 * - pending to accepted 484 * - pending to denined 485 * - accepted to terminated 486 * - pending to terminated 487 */ 488struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb, void *pal_priv) 489{ 490 struct uwb_rsv *rsv; 491 492 rsv = uwb_rsv_alloc(rc); 493 if (!rsv) 494 return NULL; 495 496 rsv->callback = cb; 497 rsv->pal_priv = pal_priv; 498 499 return rsv; 500} 501EXPORT_SYMBOL_GPL(uwb_rsv_create); 502 503void uwb_rsv_remove(struct uwb_rsv *rsv) 504{ 505 uwb_rsv_dump("RM", rsv); 506 507 if (rsv->state != UWB_RSV_STATE_NONE) 508 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 509 510 if (rsv->needs_release_companion_mas) 511 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); 512 uwb_drp_avail_release(rsv->rc, &rsv->mas); 513 514 if (uwb_rsv_is_owner(rsv)) 515 uwb_rsv_put_stream(rsv); 516 517 uwb_dev_put(rsv->owner); 518 if (rsv->target.type == UWB_RSV_TARGET_DEV) 519 uwb_dev_put(rsv->target.dev); 520 521 list_del_init(&rsv->rc_node); 522 uwb_rsv_put(rsv); 523} 524 525/** 526 * uwb_rsv_destroy - free a UWB reservation structure 527 * @rsv: the reservation to free 528 * 529 * The reservation must already be terminated. 530 */ 531void uwb_rsv_destroy(struct uwb_rsv *rsv) 532{ 533 uwb_rsv_put(rsv); 534} 535EXPORT_SYMBOL_GPL(uwb_rsv_destroy); 536 537/** 538 * usb_rsv_establish - start a reservation establishment 539 * @rsv: the reservation 540 * 541 * The PAL should fill in @rsv's owner, target, type, max_mas, 542 * min_mas, max_interval and is_multicast fields. If the target is a 543 * uwb_dev it must be referenced. 544 * 545 * The reservation's callback will be called when the reservation is 546 * accepted, denied or times out. 547 */ 548int uwb_rsv_establish(struct uwb_rsv *rsv) 549{ 550 struct uwb_rc *rc = rsv->rc; 551 struct uwb_mas_bm available; 552 int ret; 553 554 mutex_lock(&rc->rsvs_mutex); 555 ret = uwb_rsv_get_stream(rsv); 556 if (ret) 557 goto out; 558 559 rsv->tiebreaker = random32() & 1; 560 /* get available mas bitmap */ 561 uwb_drp_available(rc, &available); 562 563 ret = uwb_rsv_find_best_allocation(rsv, &available, &rsv->mas); 564 if (ret == UWB_RSV_ALLOC_NOT_FOUND) { 565 ret = -EBUSY; 566 uwb_rsv_put_stream(rsv); 567 goto out; 568 } 569 570 ret = uwb_drp_avail_reserve_pending(rc, &rsv->mas); 571 if (ret != 0) { 572 uwb_rsv_put_stream(rsv); 573 goto out; 574 } 575 576 uwb_rsv_get(rsv); 577 list_add_tail(&rsv->rc_node, &rc->reservations); 578 rsv->owner = &rc->uwb_dev; 579 uwb_dev_get(rsv->owner); 580 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_INITIATED); 581out: 582 mutex_unlock(&rc->rsvs_mutex); 583 return ret; 584} 585EXPORT_SYMBOL_GPL(uwb_rsv_establish); 586 587int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int max_interval) 588{ 589 return -ENOSYS; 590} 591EXPORT_SYMBOL_GPL(uwb_rsv_modify); 592 593/* 594 * move an already established reservation (rc->rsvs_mutex must to be 595 * taken when tis function is called) 596 */ 597int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available) 598{ 599 struct uwb_rc *rc = rsv->rc; 600 struct uwb_drp_backoff_win *bow = &rc->bow; 601 struct device *dev = &rc->uwb_dev.dev; 602 struct uwb_rsv_move *mv; 603 int ret = 0; 604 605 if (bow->can_reserve_extra_mases == false) 606 return -EBUSY; 607 608 mv = &rsv->mv; 609 610 if (uwb_rsv_find_best_allocation(rsv, available, &mv->final_mas) == UWB_RSV_ALLOC_FOUND) { 611 612 if (!bitmap_equal(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS)) { 613 /* We want to move the reservation */ 614 bitmap_andnot(mv->companion_mas.bm, mv->final_mas.bm, rsv->mas.bm, UWB_NUM_MAS); 615 uwb_drp_avail_reserve_pending(rc, &mv->companion_mas); 616 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING); 617 } 618 } else { 619 dev_dbg(dev, "new allocation not found\n"); 620 } 621 622 return ret; 623} 624 625/* It will try to move every reservation in state O_ESTABLISHED giving 626 * to the MAS allocator algorithm an availability that is the real one 627 * plus the allocation already established from the reservation. */ 628void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc) 629{ 630 struct uwb_drp_backoff_win *bow = &rc->bow; 631 struct uwb_rsv *rsv; 632 struct uwb_mas_bm mas; 633 634 if (bow->can_reserve_extra_mases == false) 635 return; 636 637 list_for_each_entry(rsv, &rc->reservations, rc_node) { 638 if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED || 639 rsv->state == UWB_RSV_STATE_O_TO_BE_MOVED) { 640 uwb_drp_available(rc, &mas); 641 bitmap_or(mas.bm, mas.bm, rsv->mas.bm, UWB_NUM_MAS); 642 uwb_rsv_try_move(rsv, &mas); 643 } 644 } 645 646} 647 648/** 649 * uwb_rsv_terminate - terminate an established reservation 650 * @rsv: the reservation to terminate 651 * 652 * A reservation is terminated by removing the DRP IE from the beacon, 653 * the other end will consider the reservation to be terminated when 654 * it does not see the DRP IE for at least mMaxLostBeacons. 655 * 656 * If applicable, the reference to the target uwb_dev will be released. 657 */ 658void uwb_rsv_terminate(struct uwb_rsv *rsv) 659{ 660 struct uwb_rc *rc = rsv->rc; 661 662 mutex_lock(&rc->rsvs_mutex); 663 664 if (rsv->state != UWB_RSV_STATE_NONE) 665 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 666 667 mutex_unlock(&rc->rsvs_mutex); 668} 669EXPORT_SYMBOL_GPL(uwb_rsv_terminate); 670 671/** 672 * uwb_rsv_accept - accept a new reservation from a peer 673 * @rsv: the reservation 674 * @cb: call back for reservation changes 675 * @pal_priv: data to be passed in the above call back 676 * 677 * Reservation requests from peers are denied unless a PAL accepts it 678 * by calling this function. 679 * 680 * The PAL call uwb_rsv_destroy() for all accepted reservations before 681 * calling uwb_pal_unregister(). 682 */ 683void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv) 684{ 685 uwb_rsv_get(rsv); 686 687 rsv->callback = cb; 688 rsv->pal_priv = pal_priv; 689 rsv->state = UWB_RSV_STATE_T_ACCEPTED; 690} 691EXPORT_SYMBOL_GPL(uwb_rsv_accept); 692 693/* 694 * Is a received DRP IE for this reservation? 695 */ 696static bool uwb_rsv_match(struct uwb_rsv *rsv, struct uwb_dev *src, 697 struct uwb_ie_drp *drp_ie) 698{ 699 struct uwb_dev_addr *rsv_src; 700 int stream; 701 702 stream = uwb_ie_drp_stream_index(drp_ie); 703 704 if (rsv->stream != stream) 705 return false; 706 707 switch (rsv->target.type) { 708 case UWB_RSV_TARGET_DEVADDR: 709 return rsv->stream == stream; 710 case UWB_RSV_TARGET_DEV: 711 if (uwb_ie_drp_owner(drp_ie)) 712 rsv_src = &rsv->owner->dev_addr; 713 else 714 rsv_src = &rsv->target.dev->dev_addr; 715 return uwb_dev_addr_cmp(&src->dev_addr, rsv_src) == 0; 716 } 717 return false; 718} 719 720static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc, 721 struct uwb_dev *src, 722 struct uwb_ie_drp *drp_ie) 723{ 724 struct uwb_rsv *rsv; 725 struct uwb_pal *pal; 726 enum uwb_rsv_state state; 727 728 rsv = uwb_rsv_alloc(rc); 729 if (!rsv) 730 return NULL; 731 732 rsv->rc = rc; 733 rsv->owner = src; 734 uwb_dev_get(rsv->owner); 735 rsv->target.type = UWB_RSV_TARGET_DEV; 736 rsv->target.dev = &rc->uwb_dev; 737 uwb_dev_get(&rc->uwb_dev); 738 rsv->type = uwb_ie_drp_type(drp_ie); 739 rsv->stream = uwb_ie_drp_stream_index(drp_ie); 740 uwb_drp_ie_to_bm(&rsv->mas, drp_ie); 741 742 /* 743 * See if any PALs are interested in this reservation. If not, 744 * deny the request. 745 */ 746 rsv->state = UWB_RSV_STATE_T_DENIED; 747 mutex_lock(&rc->uwb_dev.mutex); 748 list_for_each_entry(pal, &rc->pals, node) { 749 if (pal->new_rsv) 750 pal->new_rsv(pal, rsv); 751 if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) 752 break; 753 } 754 mutex_unlock(&rc->uwb_dev.mutex); 755 756 list_add_tail(&rsv->rc_node, &rc->reservations); 757 state = rsv->state; 758 rsv->state = UWB_RSV_STATE_NONE; 759 760 if (state == UWB_RSV_STATE_T_ACCEPTED 761 && uwb_drp_avail_reserve_pending(rc, &rsv->mas) == -EBUSY) { 762 } else { 763 uwb_rsv_set_state(rsv, state); 764 } 765 766 return rsv; 767} 768 769/** 770 * uwb_rsv_get_usable_mas - get the bitmap of the usable MAS of a reservations 771 * @rsv: the reservation. 772 * @mas: returns the available MAS. 773 * 774 * The usable MAS of a reservation may be less than the negotiated MAS 775 * if alien BPs are present. 776 */ 777void uwb_rsv_get_usable_mas(struct uwb_rsv *rsv, struct uwb_mas_bm *mas) 778{ 779 bitmap_zero(mas->bm, UWB_NUM_MAS); 780 bitmap_andnot(mas->bm, rsv->mas.bm, rsv->rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS); 781} 782EXPORT_SYMBOL_GPL(uwb_rsv_get_usable_mas); 783 784/** 785 * uwb_rsv_find - find a reservation for a received DRP IE. 786 * @rc: the radio controller 787 * @src: source of the DRP IE 788 * @drp_ie: the DRP IE 789 * 790 * If the reservation cannot be found and the DRP IE is from a peer 791 * attempting to establish a new reservation, create a new reservation 792 * and add it to the list. 793 */ 794struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src, 795 struct uwb_ie_drp *drp_ie) 796{ 797 struct uwb_rsv *rsv; 798 799 list_for_each_entry(rsv, &rc->reservations, rc_node) { 800 if (uwb_rsv_match(rsv, src, drp_ie)) 801 return rsv; 802 } 803 804 if (uwb_ie_drp_owner(drp_ie)) 805 return uwb_rsv_new_target(rc, src, drp_ie); 806 807 return NULL; 808} 809 810static bool uwb_rsv_update_all(struct uwb_rc *rc) 811{ 812 struct uwb_rsv *rsv, *t; 813 bool ie_updated = false; 814 815 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { 816 if (!rsv->ie_valid) { 817 uwb_drp_ie_update(rsv); 818 ie_updated = true; 819 } 820 } 821 822 return ie_updated; 823} 824 825void uwb_rsv_queue_update(struct uwb_rc *rc) 826{ 827 unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE; 828 829 queue_delayed_work(rc->rsv_workq, &rc->rsv_update_work, usecs_to_jiffies(delay_us)); 830} 831 832void uwb_rsv_sched_update(struct uwb_rc *rc) 833{ 834 spin_lock_bh(&rc->rsvs_lock); 835 if (!delayed_work_pending(&rc->rsv_update_work)) { 836 if (rc->set_drp_ie_pending > 0) { 837 rc->set_drp_ie_pending++; 838 goto unlock; 839 } 840 uwb_rsv_queue_update(rc); 841 } 842unlock: 843 spin_unlock_bh(&rc->rsvs_lock); 844} 845 846/* 847 * Update DRP IEs and, if necessary, the DRP Availability IE and send 848 * the updated IEs to the radio controller. 849 */ 850static void uwb_rsv_update_work(struct work_struct *work) 851{ 852 struct uwb_rc *rc = container_of(work, struct uwb_rc, 853 rsv_update_work.work); 854 bool ie_updated; 855 856 mutex_lock(&rc->rsvs_mutex); 857 858 ie_updated = uwb_rsv_update_all(rc); 859 860 if (!rc->drp_avail.ie_valid) { 861 uwb_drp_avail_ie_update(rc); 862 ie_updated = true; 863 } 864 865 if (ie_updated && (rc->set_drp_ie_pending == 0)) 866 uwb_rc_send_all_drp_ie(rc); 867 868 mutex_unlock(&rc->rsvs_mutex); 869} 870 871static void uwb_rsv_alien_bp_work(struct work_struct *work) 872{ 873 struct uwb_rc *rc = container_of(work, struct uwb_rc, 874 rsv_alien_bp_work.work); 875 struct uwb_rsv *rsv; 876 877 mutex_lock(&rc->rsvs_mutex); 878 879 list_for_each_entry(rsv, &rc->reservations, rc_node) { 880 if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) { 881 rsv->callback(rsv); 882 } 883 } 884 885 mutex_unlock(&rc->rsvs_mutex); 886} 887 888static void uwb_rsv_timer(unsigned long arg) 889{ 890 struct uwb_rsv *rsv = (struct uwb_rsv *)arg; 891 892 queue_work(rsv->rc->rsv_workq, &rsv->handle_timeout_work); 893} 894 895/** 896 * uwb_rsv_remove_all - remove all reservations 897 * @rc: the radio controller 898 * 899 * A DRP IE update is not done. 900 */ 901void uwb_rsv_remove_all(struct uwb_rc *rc) 902{ 903 struct uwb_rsv *rsv, *t; 904 905 mutex_lock(&rc->rsvs_mutex); 906 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { 907 if (rsv->state != UWB_RSV_STATE_NONE) 908 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 909 del_timer_sync(&rsv->timer); 910 } 911 /* Cancel any postponed update. */ 912 rc->set_drp_ie_pending = 0; 913 mutex_unlock(&rc->rsvs_mutex); 914 915 cancel_delayed_work_sync(&rc->rsv_update_work); 916 flush_workqueue(rc->rsv_workq); 917 918 mutex_lock(&rc->rsvs_mutex); 919 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { 920 uwb_rsv_remove(rsv); 921 } 922 mutex_unlock(&rc->rsvs_mutex); 923} 924 925void uwb_rsv_init(struct uwb_rc *rc) 926{ 927 INIT_LIST_HEAD(&rc->reservations); 928 INIT_LIST_HEAD(&rc->cnflt_alien_list); 929 mutex_init(&rc->rsvs_mutex); 930 spin_lock_init(&rc->rsvs_lock); 931 INIT_DELAYED_WORK(&rc->rsv_update_work, uwb_rsv_update_work); 932 INIT_DELAYED_WORK(&rc->rsv_alien_bp_work, uwb_rsv_alien_bp_work); 933 rc->bow.can_reserve_extra_mases = true; 934 rc->bow.total_expired = 0; 935 rc->bow.window = UWB_DRP_BACKOFF_WIN_MIN >> 1; 936 init_timer(&rc->bow.timer); 937 rc->bow.timer.function = uwb_rsv_backoff_win_timer; 938 rc->bow.timer.data = (unsigned long)&rc->bow; 939 940 bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS); 941} 942 943int uwb_rsv_setup(struct uwb_rc *rc) 944{ 945 char name[16]; 946 947 snprintf(name, sizeof(name), "%s_rsvd", dev_name(&rc->uwb_dev.dev)); 948 rc->rsv_workq = create_singlethread_workqueue(name); 949 if (rc->rsv_workq == NULL) 950 return -ENOMEM; 951 952 return 0; 953} 954 955void uwb_rsv_cleanup(struct uwb_rc *rc) 956{ 957 uwb_rsv_remove_all(rc); 958 destroy_workqueue(rc->rsv_workq); 959} 960