Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rsv.c
Go to the documentation of this file.
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 #include <linux/export.h>
23 
24 #include "uwb-internal.h"
25 
26 static void uwb_rsv_timer(unsigned long arg);
27 
28 static const char *rsv_states[] = {
29  [UWB_RSV_STATE_NONE] = "none ",
30  [UWB_RSV_STATE_O_INITIATED] = "o initiated ",
31  [UWB_RSV_STATE_O_PENDING] = "o pending ",
32  [UWB_RSV_STATE_O_MODIFIED] = "o modified ",
33  [UWB_RSV_STATE_O_ESTABLISHED] = "o established ",
34  [UWB_RSV_STATE_O_TO_BE_MOVED] = "o to be moved ",
35  [UWB_RSV_STATE_O_MOVE_EXPANDING] = "o move expanding",
36  [UWB_RSV_STATE_O_MOVE_COMBINING] = "o move combining",
37  [UWB_RSV_STATE_O_MOVE_REDUCING] = "o move reducing ",
38  [UWB_RSV_STATE_T_ACCEPTED] = "t accepted ",
39  [UWB_RSV_STATE_T_CONFLICT] = "t conflict ",
40  [UWB_RSV_STATE_T_PENDING] = "t pending ",
41  [UWB_RSV_STATE_T_DENIED] = "t denied ",
42  [UWB_RSV_STATE_T_RESIZED] = "t resized ",
43  [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = "t expanding acc ",
44  [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = "t expanding conf",
45  [UWB_RSV_STATE_T_EXPANDING_PENDING] = "t expanding pend",
46  [UWB_RSV_STATE_T_EXPANDING_DENIED] = "t expanding den ",
47 };
48 
49 static const char *rsv_types[] = {
50  [UWB_DRP_TYPE_ALIEN_BP] = "alien-bp",
51  [UWB_DRP_TYPE_HARD] = "hard",
52  [UWB_DRP_TYPE_SOFT] = "soft",
53  [UWB_DRP_TYPE_PRIVATE] = "private",
54  [UWB_DRP_TYPE_PCA] = "pca",
55 };
56 
58 {
59  static const bool has_two_drp_ies[] = {
60  [UWB_RSV_STATE_O_INITIATED] = false,
61  [UWB_RSV_STATE_O_PENDING] = false,
62  [UWB_RSV_STATE_O_MODIFIED] = false,
68  [UWB_RSV_STATE_T_ACCEPTED] = false,
69  [UWB_RSV_STATE_T_CONFLICT] = false,
70  [UWB_RSV_STATE_T_PENDING] = false,
71  [UWB_RSV_STATE_T_DENIED] = false,
72  [UWB_RSV_STATE_T_RESIZED] = false,
77  };
78 
79  return has_two_drp_ies[rsv->state];
80 }
81 
87 {
89  return "unknown";
90  return rsv_states[state];
91 }
93 
99 {
101  return "invalid";
102  return rsv_types[type];
103 }
105 
106 void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
107 {
108  struct device *dev = &rsv->rc->uwb_dev.dev;
109  struct uwb_dev_addr devaddr;
111 
112  uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
113  if (rsv->target.type == UWB_RSV_TARGET_DEV)
114  devaddr = rsv->target.dev->dev_addr;
115  else
116  devaddr = rsv->target.devaddr;
117  uwb_dev_addr_print(target, sizeof(target), &devaddr);
118 
119  dev_dbg(dev, "rsv %s %s -> %s: %s\n",
120  text, owner, target, uwb_rsv_state_str(rsv->state));
121 }
122 
123 static void uwb_rsv_release(struct kref *kref)
124 {
125  struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref);
126 
127  kfree(rsv);
128 }
129 
130 void uwb_rsv_get(struct uwb_rsv *rsv)
131 {
132  kref_get(&rsv->kref);
133 }
134 
135 void uwb_rsv_put(struct uwb_rsv *rsv)
136 {
137  kref_put(&rsv->kref, uwb_rsv_release);
138 }
139 
140 /*
141  * Get a free stream index for a reservation.
142  *
143  * If the target is a DevAddr (e.g., a WUSB cluster reservation) then
144  * the stream is allocated from a pool of per-RC stream indexes,
145  * otherwise a unique stream index for the target is selected.
146  */
147 static int uwb_rsv_get_stream(struct uwb_rsv *rsv)
148 {
149  struct uwb_rc *rc = rsv->rc;
150  struct device *dev = &rc->uwb_dev.dev;
151  unsigned long *streams_bm;
152  int stream;
153 
154  switch (rsv->target.type) {
155  case UWB_RSV_TARGET_DEV:
156  streams_bm = rsv->target.dev->streams;
157  break;
159  streams_bm = rc->uwb_dev.streams;
160  break;
161  default:
162  return -EINVAL;
163  }
164 
165  stream = find_first_zero_bit(streams_bm, UWB_NUM_STREAMS);
166  if (stream >= UWB_NUM_STREAMS)
167  return -EBUSY;
168 
169  rsv->stream = stream;
170  set_bit(stream, streams_bm);
171 
172  dev_dbg(dev, "get stream %d\n", rsv->stream);
173 
174  return 0;
175 }
176 
177 static void uwb_rsv_put_stream(struct uwb_rsv *rsv)
178 {
179  struct uwb_rc *rc = rsv->rc;
180  struct device *dev = &rc->uwb_dev.dev;
181  unsigned long *streams_bm;
182 
183  switch (rsv->target.type) {
184  case UWB_RSV_TARGET_DEV:
185  streams_bm = rsv->target.dev->streams;
186  break;
188  streams_bm = rc->uwb_dev.streams;
189  break;
190  default:
191  return;
192  }
193 
194  clear_bit(rsv->stream, streams_bm);
195 
196  dev_dbg(dev, "put stream %d\n", rsv->stream);
197 }
198 
199 void uwb_rsv_backoff_win_timer(unsigned long arg)
200 {
201  struct uwb_drp_backoff_win *bow = (struct uwb_drp_backoff_win *)arg;
202  struct uwb_rc *rc = container_of(bow, struct uwb_rc, bow);
203  struct device *dev = &rc->uwb_dev.dev;
204 
205  bow->can_reserve_extra_mases = true;
206  if (bow->total_expired <= 4) {
207  bow->total_expired++;
208  } else {
209  /* after 4 backoff window has expired we can exit from
210  * the backoff procedure */
211  bow->total_expired = 0;
212  bow->window = UWB_DRP_BACKOFF_WIN_MIN >> 1;
213  }
214  dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n: ", bow->total_expired, bow->n);
215 
216  /* try to relocate all the "to be moved" relocations */
218 }
219 
221 {
222  struct uwb_drp_backoff_win *bow = &rc->bow;
223  struct device *dev = &rc->uwb_dev.dev;
224  unsigned timeout_us;
225 
226  dev_dbg(dev, "backoff_win_increment: window=%d\n", bow->window);
227 
228  bow->can_reserve_extra_mases = false;
229 
230  if((bow->window << 1) == UWB_DRP_BACKOFF_WIN_MAX)
231  return;
232 
233  bow->window <<= 1;
234  bow->n = random32() & (bow->window - 1);
235  dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n);
236 
237  /* reset the timer associated variables */
238  timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US;
239  bow->total_expired = 0;
240  mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us));
241 }
242 
243 static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv)
244 {
245  int sframes = UWB_MAX_LOST_BEACONS;
246 
247  /*
248  * Multicast reservations can become established within 1
249  * super frame and should not be terminated if no response is
250  * received.
251  */
252  if (rsv->is_multicast) {
253  if (rsv->state == UWB_RSV_STATE_O_INITIATED
257  sframes = 1;
259  sframes = 0;
260 
261  }
262 
263  if (sframes > 0) {
264  /*
265  * Add an additional 2 superframes to account for the
266  * time to send the SET DRP IE command.
267  */
268  unsigned timeout_us = (sframes + 2) * UWB_SUPERFRAME_LENGTH_US;
269  mod_timer(&rsv->timer, jiffies + usecs_to_jiffies(timeout_us));
270  } else
271  del_timer(&rsv->timer);
272 }
273 
274 /*
275  * Update a reservations state, and schedule an update of the
276  * transmitted DRP IEs.
277  */
278 static void uwb_rsv_state_update(struct uwb_rsv *rsv,
280 {
281  rsv->state = new_state;
282  rsv->ie_valid = false;
283 
284  uwb_rsv_dump("SU", rsv);
285 
286  uwb_rsv_stroke_timer(rsv);
287  uwb_rsv_sched_update(rsv->rc);
288 }
289 
290 static void uwb_rsv_callback(struct uwb_rsv *rsv)
291 {
292  if (rsv->callback)
293  rsv->callback(rsv);
294 }
295 
297 {
298  struct uwb_rsv_move *mv = &rsv->mv;
299 
300  if (rsv->state == new_state) {
301  switch (rsv->state) {
309  case UWB_RSV_STATE_NONE:
310  uwb_rsv_stroke_timer(rsv);
311  break;
312  default:
313  /* Expecting a state transition so leave timer
314  as-is. */
315  break;
316  }
317  return;
318  }
319 
320  uwb_rsv_dump("SC", rsv);
321 
322  switch (new_state) {
323  case UWB_RSV_STATE_NONE:
324  uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE);
325  uwb_rsv_callback(rsv);
326  break;
328  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_INITIATED);
329  break;
331  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING);
332  break;
334  /* in the companion there are the MASes to drop */
335  bitmap_andnot(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS);
336  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MODIFIED);
337  break;
339  if (rsv->state == UWB_RSV_STATE_O_MODIFIED
342  rsv->needs_release_companion_mas = false;
343  }
344  uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
345  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED);
346  uwb_rsv_callback(rsv);
347  break;
349  rsv->needs_release_companion_mas = true;
350  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING);
351  break;
353  rsv->needs_release_companion_mas = false;
355  bitmap_or(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS);
356  rsv->mas.safe += mv->companion_mas.safe;
357  rsv->mas.unsafe += mv->companion_mas.unsafe;
358  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_COMBINING);
359  break;
361  bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS);
362  rsv->needs_release_companion_mas = true;
363  rsv->mas.safe = mv->final_mas.safe;
364  rsv->mas.unsafe = mv->final_mas.unsafe;
365  bitmap_copy(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS);
366  bitmap_copy(rsv->mas.unsafe_bm, mv->final_mas.unsafe_bm, UWB_NUM_MAS);
367  uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_REDUCING);
368  break;
371  rsv->needs_release_companion_mas = false;
372  uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
373  uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED);
374  uwb_rsv_callback(rsv);
375  break;
377  uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED);
378  break;
380  uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_CONFLICT);
381  break;
383  uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_PENDING);
384  break;
386  rsv->needs_release_companion_mas = true;
388  uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED);
389  break;
390  default:
391  dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n",
392  uwb_rsv_state_str(new_state), new_state);
393  }
394 }
395 
396 static void uwb_rsv_handle_timeout_work(struct work_struct *work)
397 {
398  struct uwb_rsv *rsv = container_of(work, struct uwb_rsv,
400  struct uwb_rc *rc = rsv->rc;
401 
402  mutex_lock(&rc->rsvs_mutex);
403 
404  uwb_rsv_dump("TO", rsv);
405 
406  switch (rsv->state) {
408  if (rsv->is_multicast) {
410  goto unlock;
411  }
412  break;
414  if (rsv->is_multicast) {
416  goto unlock;
417  }
418  break;
420  if (rsv->is_multicast) {
422  goto unlock;
423  }
424  break;
426  if (rsv->is_multicast) {
428  goto unlock;
429  }
430  break;
432  if (rsv->is_multicast)
433  goto unlock;
434  break;
436  /*
437  * The time out could be for the main or of the
438  * companion DRP, assume it's for the companion and
439  * drop that first. A further time out is required to
440  * drop the main.
441  */
443  uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
444  goto unlock;
445  default:
446  break;
447  }
448 
449  uwb_rsv_remove(rsv);
450 
451 unlock:
452  mutex_unlock(&rc->rsvs_mutex);
453 }
454 
455 static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
456 {
457  struct uwb_rsv *rsv;
458 
459  rsv = kzalloc(sizeof(struct uwb_rsv), GFP_KERNEL);
460  if (!rsv)
461  return NULL;
462 
463  INIT_LIST_HEAD(&rsv->rc_node);
464  INIT_LIST_HEAD(&rsv->pal_node);
465  kref_init(&rsv->kref);
466  init_timer(&rsv->timer);
467  rsv->timer.function = uwb_rsv_timer;
468  rsv->timer.data = (unsigned long)rsv;
469 
470  rsv->rc = rc;
471  INIT_WORK(&rsv->handle_timeout_work, uwb_rsv_handle_timeout_work);
472 
473  return rsv;
474 }
475 
490 {
491  struct uwb_rsv *rsv;
492 
493  rsv = uwb_rsv_alloc(rc);
494  if (!rsv)
495  return NULL;
496 
497  rsv->callback = cb;
498  rsv->pal_priv = pal_priv;
499 
500  return rsv;
501 }
503 
504 void uwb_rsv_remove(struct uwb_rsv *rsv)
505 {
506  uwb_rsv_dump("RM", rsv);
507 
508  if (rsv->state != UWB_RSV_STATE_NONE)
510 
512  uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
513  uwb_drp_avail_release(rsv->rc, &rsv->mas);
514 
515  if (uwb_rsv_is_owner(rsv))
516  uwb_rsv_put_stream(rsv);
517 
518  uwb_dev_put(rsv->owner);
519  if (rsv->target.type == UWB_RSV_TARGET_DEV)
520  uwb_dev_put(rsv->target.dev);
521 
522  list_del_init(&rsv->rc_node);
523  uwb_rsv_put(rsv);
524 }
525 
532 void uwb_rsv_destroy(struct uwb_rsv *rsv)
533 {
534  uwb_rsv_put(rsv);
535 }
537 
549 int uwb_rsv_establish(struct uwb_rsv *rsv)
550 {
551  struct uwb_rc *rc = rsv->rc;
552  struct uwb_mas_bm available;
553  int ret;
554 
555  mutex_lock(&rc->rsvs_mutex);
556  ret = uwb_rsv_get_stream(rsv);
557  if (ret)
558  goto out;
559 
560  rsv->tiebreaker = random32() & 1;
561  /* get available mas bitmap */
562  uwb_drp_available(rc, &available);
563 
564  ret = uwb_rsv_find_best_allocation(rsv, &available, &rsv->mas);
565  if (ret == UWB_RSV_ALLOC_NOT_FOUND) {
566  ret = -EBUSY;
567  uwb_rsv_put_stream(rsv);
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  goto out;
575  }
576 
577  uwb_rsv_get(rsv);
578  list_add_tail(&rsv->rc_node, &rc->reservations);
579  rsv->owner = &rc->uwb_dev;
580  uwb_dev_get(rsv->owner);
582 out:
583  mutex_unlock(&rc->rsvs_mutex);
584  return ret;
585 }
587 
597 int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int max_interval)
598 {
599  return -ENOSYS;
600 }
602 
603 /*
604  * move an already established reservation (rc->rsvs_mutex must to be
605  * taken when tis function is called)
606  */
607 int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available)
608 {
609  struct uwb_rc *rc = rsv->rc;
610  struct uwb_drp_backoff_win *bow = &rc->bow;
611  struct device *dev = &rc->uwb_dev.dev;
612  struct uwb_rsv_move *mv;
613  int ret = 0;
614 
615  if (bow->can_reserve_extra_mases == false)
616  return -EBUSY;
617 
618  mv = &rsv->mv;
619 
620  if (uwb_rsv_find_best_allocation(rsv, available, &mv->final_mas) == UWB_RSV_ALLOC_FOUND) {
621 
622  if (!bitmap_equal(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS)) {
623  /* We want to move the reservation */
624  bitmap_andnot(mv->companion_mas.bm, mv->final_mas.bm, rsv->mas.bm, UWB_NUM_MAS);
627  }
628  } else {
629  dev_dbg(dev, "new allocation not found\n");
630  }
631 
632  return ret;
633 }
634 
635 /* It will try to move every reservation in state O_ESTABLISHED giving
636  * to the MAS allocator algorithm an availability that is the real one
637  * plus the allocation already established from the reservation. */
639 {
640  struct uwb_drp_backoff_win *bow = &rc->bow;
641  struct uwb_rsv *rsv;
642  struct uwb_mas_bm mas;
643 
644  if (bow->can_reserve_extra_mases == false)
645  return;
646 
647  list_for_each_entry(rsv, &rc->reservations, rc_node) {
648  if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED ||
650  uwb_drp_available(rc, &mas);
651  bitmap_or(mas.bm, mas.bm, rsv->mas.bm, UWB_NUM_MAS);
652  uwb_rsv_try_move(rsv, &mas);
653  }
654  }
655 
656 }
657 
668 void uwb_rsv_terminate(struct uwb_rsv *rsv)
669 {
670  struct uwb_rc *rc = rsv->rc;
671 
672  mutex_lock(&rc->rsvs_mutex);
673 
674  if (rsv->state != UWB_RSV_STATE_NONE)
676 
677  mutex_unlock(&rc->rsvs_mutex);
678 }
680 
693 void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv)
694 {
695  uwb_rsv_get(rsv);
696 
697  rsv->callback = cb;
698  rsv->pal_priv = pal_priv;
700 }
702 
703 /*
704  * Is a received DRP IE for this reservation?
705  */
706 static bool uwb_rsv_match(struct uwb_rsv *rsv, struct uwb_dev *src,
707  struct uwb_ie_drp *drp_ie)
708 {
709  struct uwb_dev_addr *rsv_src;
710  int stream;
711 
712  stream = uwb_ie_drp_stream_index(drp_ie);
713 
714  if (rsv->stream != stream)
715  return false;
716 
717  switch (rsv->target.type) {
719  return rsv->stream == stream;
720  case UWB_RSV_TARGET_DEV:
721  if (uwb_ie_drp_owner(drp_ie))
722  rsv_src = &rsv->owner->dev_addr;
723  else
724  rsv_src = &rsv->target.dev->dev_addr;
725  return uwb_dev_addr_cmp(&src->dev_addr, rsv_src) == 0;
726  }
727  return false;
728 }
729 
730 static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
731  struct uwb_dev *src,
732  struct uwb_ie_drp *drp_ie)
733 {
734  struct uwb_rsv *rsv;
735  struct uwb_pal *pal;
736  enum uwb_rsv_state state;
737 
738  rsv = uwb_rsv_alloc(rc);
739  if (!rsv)
740  return NULL;
741 
742  rsv->rc = rc;
743  rsv->owner = src;
744  uwb_dev_get(rsv->owner);
745  rsv->target.type = UWB_RSV_TARGET_DEV;
746  rsv->target.dev = &rc->uwb_dev;
747  uwb_dev_get(&rc->uwb_dev);
748  rsv->type = uwb_ie_drp_type(drp_ie);
749  rsv->stream = uwb_ie_drp_stream_index(drp_ie);
750  uwb_drp_ie_to_bm(&rsv->mas, drp_ie);
751 
752  /*
753  * See if any PALs are interested in this reservation. If not,
754  * deny the request.
755  */
757  mutex_lock(&rc->uwb_dev.mutex);
758  list_for_each_entry(pal, &rc->pals, node) {
759  if (pal->new_rsv)
760  pal->new_rsv(pal, rsv);
761  if (rsv->state == UWB_RSV_STATE_T_ACCEPTED)
762  break;
763  }
764  mutex_unlock(&rc->uwb_dev.mutex);
765 
766  list_add_tail(&rsv->rc_node, &rc->reservations);
767  state = rsv->state;
768  rsv->state = UWB_RSV_STATE_NONE;
769 
770  /* FIXME: do something sensible here */
771  if (state == UWB_RSV_STATE_T_ACCEPTED
772  && uwb_drp_avail_reserve_pending(rc, &rsv->mas) == -EBUSY) {
773  /* FIXME: do something sensible here */
774  } else {
775  uwb_rsv_set_state(rsv, state);
776  }
777 
778  return rsv;
779 }
780 
789 void uwb_rsv_get_usable_mas(struct uwb_rsv *rsv, struct uwb_mas_bm *mas)
790 {
791  bitmap_zero(mas->bm, UWB_NUM_MAS);
792  bitmap_andnot(mas->bm, rsv->mas.bm, rsv->rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS);
793 }
795 
806 struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
807  struct uwb_ie_drp *drp_ie)
808 {
809  struct uwb_rsv *rsv;
810 
812  if (uwb_rsv_match(rsv, src, drp_ie))
813  return rsv;
814  }
815 
816  if (uwb_ie_drp_owner(drp_ie))
817  return uwb_rsv_new_target(rc, src, drp_ie);
818 
819  return NULL;
820 }
821 
822 /*
823  * Go through all the reservations and check for timeouts and (if
824  * necessary) update their DRP IEs.
825  *
826  * FIXME: look at building the SET_DRP_IE command here rather than
827  * having to rescan the list in uwb_rc_send_all_drp_ie().
828  */
829 static bool uwb_rsv_update_all(struct uwb_rc *rc)
830 {
831  struct uwb_rsv *rsv, *t;
832  bool ie_updated = false;
833 
835  if (!rsv->ie_valid) {
836  uwb_drp_ie_update(rsv);
837  ie_updated = true;
838  }
839  }
840 
841  return ie_updated;
842 }
843 
844 void uwb_rsv_queue_update(struct uwb_rc *rc)
845 {
846  unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE;
847 
849 }
850 
873 void uwb_rsv_sched_update(struct uwb_rc *rc)
874 {
875  spin_lock_bh(&rc->rsvs_lock);
877  if (rc->set_drp_ie_pending > 0) {
878  rc->set_drp_ie_pending++;
879  goto unlock;
880  }
882  }
883 unlock:
884  spin_unlock_bh(&rc->rsvs_lock);
885 }
886 
887 /*
888  * Update DRP IEs and, if necessary, the DRP Availability IE and send
889  * the updated IEs to the radio controller.
890  */
891 static void uwb_rsv_update_work(struct work_struct *work)
892 {
893  struct uwb_rc *rc = container_of(work, struct uwb_rc,
894  rsv_update_work.work);
895  bool ie_updated;
896 
897  mutex_lock(&rc->rsvs_mutex);
898 
899  ie_updated = uwb_rsv_update_all(rc);
900 
901  if (!rc->drp_avail.ie_valid) {
903  ie_updated = true;
904  }
905 
906  if (ie_updated && (rc->set_drp_ie_pending == 0))
908 
909  mutex_unlock(&rc->rsvs_mutex);
910 }
911 
912 static void uwb_rsv_alien_bp_work(struct work_struct *work)
913 {
914  struct uwb_rc *rc = container_of(work, struct uwb_rc,
915  rsv_alien_bp_work.work);
916  struct uwb_rsv *rsv;
917 
918  mutex_lock(&rc->rsvs_mutex);
919 
921  if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) {
922  rsv->callback(rsv);
923  }
924  }
925 
926  mutex_unlock(&rc->rsvs_mutex);
927 }
928 
929 static void uwb_rsv_timer(unsigned long arg)
930 {
931  struct uwb_rsv *rsv = (struct uwb_rsv *)arg;
932 
933  queue_work(rsv->rc->rsv_workq, &rsv->handle_timeout_work);
934 }
935 
942 void uwb_rsv_remove_all(struct uwb_rc *rc)
943 {
944  struct uwb_rsv *rsv, *t;
945 
946  mutex_lock(&rc->rsvs_mutex);
948  if (rsv->state != UWB_RSV_STATE_NONE)
950  del_timer_sync(&rsv->timer);
951  }
952  /* Cancel any postponed update. */
953  rc->set_drp_ie_pending = 0;
954  mutex_unlock(&rc->rsvs_mutex);
955 
958 
959  mutex_lock(&rc->rsvs_mutex);
961  uwb_rsv_remove(rsv);
962  }
963  mutex_unlock(&rc->rsvs_mutex);
964 }
965 
966 void uwb_rsv_init(struct uwb_rc *rc)
967 {
968  INIT_LIST_HEAD(&rc->reservations);
969  INIT_LIST_HEAD(&rc->cnflt_alien_list);
970  mutex_init(&rc->rsvs_mutex);
972  INIT_DELAYED_WORK(&rc->rsv_update_work, uwb_rsv_update_work);
973  INIT_DELAYED_WORK(&rc->rsv_alien_bp_work, uwb_rsv_alien_bp_work);
974  rc->bow.can_reserve_extra_mases = true;
975  rc->bow.total_expired = 0;
976  rc->bow.window = UWB_DRP_BACKOFF_WIN_MIN >> 1;
977  init_timer(&rc->bow.timer);
978  rc->bow.timer.function = uwb_rsv_backoff_win_timer;
979  rc->bow.timer.data = (unsigned long)&rc->bow;
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));
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);
1000 }