root/drivers/staging/uwb/rsv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uwb_rsv_has_two_drp_ies
  2. uwb_rsv_state_str
  3. uwb_rsv_type_str
  4. uwb_rsv_dump
  5. uwb_rsv_release
  6. uwb_rsv_get
  7. uwb_rsv_put
  8. uwb_rsv_get_stream
  9. uwb_rsv_put_stream
  10. uwb_rsv_backoff_win_timer
  11. uwb_rsv_backoff_win_increment
  12. uwb_rsv_stroke_timer
  13. uwb_rsv_state_update
  14. uwb_rsv_callback
  15. uwb_rsv_set_state
  16. uwb_rsv_handle_timeout_work
  17. uwb_rsv_alloc
  18. uwb_rsv_create
  19. uwb_rsv_remove
  20. uwb_rsv_destroy
  21. uwb_rsv_establish
  22. uwb_rsv_modify
  23. uwb_rsv_try_move
  24. uwb_rsv_handle_drp_avail_change
  25. uwb_rsv_terminate
  26. uwb_rsv_accept
  27. uwb_rsv_match
  28. uwb_rsv_new_target
  29. uwb_rsv_get_usable_mas
  30. uwb_rsv_find
  31. uwb_rsv_update_all
  32. uwb_rsv_queue_update
  33. uwb_rsv_sched_update
  34. uwb_rsv_update_work
  35. uwb_rsv_alien_bp_work
  36. uwb_rsv_timer
  37. uwb_rsv_remove_all
  38. uwb_rsv_init
  39. uwb_rsv_setup
  40. uwb_rsv_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */