rsv.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  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 "uwb-internal.h"
  21. static void uwb_rsv_timer(unsigned long arg);
  22. static const char *rsv_states[] = {
  23. [UWB_RSV_STATE_NONE] = "none",
  24. [UWB_RSV_STATE_O_INITIATED] = "initiated",
  25. [UWB_RSV_STATE_O_PENDING] = "pending",
  26. [UWB_RSV_STATE_O_MODIFIED] = "modified",
  27. [UWB_RSV_STATE_O_ESTABLISHED] = "established",
  28. [UWB_RSV_STATE_T_ACCEPTED] = "accepted",
  29. [UWB_RSV_STATE_T_DENIED] = "denied",
  30. [UWB_RSV_STATE_T_PENDING] = "pending",
  31. };
  32. static const char *rsv_types[] = {
  33. [UWB_DRP_TYPE_ALIEN_BP] = "alien-bp",
  34. [UWB_DRP_TYPE_HARD] = "hard",
  35. [UWB_DRP_TYPE_SOFT] = "soft",
  36. [UWB_DRP_TYPE_PRIVATE] = "private",
  37. [UWB_DRP_TYPE_PCA] = "pca",
  38. };
  39. /**
  40. * uwb_rsv_state_str - return a string for a reservation state
  41. * @state: the reservation state.
  42. */
  43. const char *uwb_rsv_state_str(enum uwb_rsv_state state)
  44. {
  45. if (state < UWB_RSV_STATE_NONE || state >= UWB_RSV_STATE_LAST)
  46. return "unknown";
  47. return rsv_states[state];
  48. }
  49. EXPORT_SYMBOL_GPL(uwb_rsv_state_str);
  50. /**
  51. * uwb_rsv_type_str - return a string for a reservation type
  52. * @type: the reservation type
  53. */
  54. const char *uwb_rsv_type_str(enum uwb_drp_type type)
  55. {
  56. if (type < UWB_DRP_TYPE_ALIEN_BP || type > UWB_DRP_TYPE_PCA)
  57. return "invalid";
  58. return rsv_types[type];
  59. }
  60. EXPORT_SYMBOL_GPL(uwb_rsv_type_str);
  61. static void uwb_rsv_dump(struct uwb_rsv *rsv)
  62. {
  63. struct device *dev = &rsv->rc->uwb_dev.dev;
  64. struct uwb_dev_addr devaddr;
  65. char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
  66. uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
  67. if (rsv->target.type == UWB_RSV_TARGET_DEV)
  68. devaddr = rsv->target.dev->dev_addr;
  69. else
  70. devaddr = rsv->target.devaddr;
  71. uwb_dev_addr_print(target, sizeof(target), &devaddr);
  72. dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
  73. }
  74. static void uwb_rsv_release(struct kref *kref)
  75. {
  76. struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref);
  77. kfree(rsv);
  78. }
  79. static void uwb_rsv_get(struct uwb_rsv *rsv)
  80. {
  81. kref_get(&rsv->kref);
  82. }
  83. static void uwb_rsv_put(struct uwb_rsv *rsv)
  84. {
  85. kref_put(&rsv->kref, uwb_rsv_release);
  86. }
  87. /*
  88. * Get a free stream index for a reservation.
  89. *
  90. * If the target is a DevAddr (e.g., a WUSB cluster reservation) then
  91. * the stream is allocated from a pool of per-RC stream indexes,
  92. * otherwise a unique stream index for the target is selected.
  93. */
  94. static int uwb_rsv_get_stream(struct uwb_rsv *rsv)
  95. {
  96. struct uwb_rc *rc = rsv->rc;
  97. unsigned long *streams_bm;
  98. int stream;
  99. switch (rsv->target.type) {
  100. case UWB_RSV_TARGET_DEV:
  101. streams_bm = rsv->target.dev->streams;
  102. break;
  103. case UWB_RSV_TARGET_DEVADDR:
  104. streams_bm = rc->uwb_dev.streams;
  105. break;
  106. default:
  107. return -EINVAL;
  108. }
  109. stream = find_first_zero_bit(streams_bm, UWB_NUM_STREAMS);
  110. if (stream >= UWB_NUM_STREAMS)
  111. return -EBUSY;
  112. rsv->stream = stream;
  113. set_bit(stream, streams_bm);
  114. return 0;
  115. }
  116. static void uwb_rsv_put_stream(struct uwb_rsv *rsv)
  117. {
  118. struct uwb_rc *rc = rsv->rc;
  119. unsigned long *streams_bm;
  120. switch (rsv->target.type) {
  121. case UWB_RSV_TARGET_DEV:
  122. streams_bm = rsv->target.dev->streams;
  123. break;
  124. case UWB_RSV_TARGET_DEVADDR:
  125. streams_bm = rc->uwb_dev.streams;
  126. break;
  127. default:
  128. return;
  129. }
  130. clear_bit(rsv->stream, streams_bm);
  131. }
  132. /*
  133. * Generate a MAS allocation with a single row component.
  134. */
  135. static void uwb_rsv_gen_alloc_row(struct uwb_mas_bm *mas,
  136. int first_mas, int mas_per_zone,
  137. int zs, int ze)
  138. {
  139. struct uwb_mas_bm col;
  140. int z;
  141. bitmap_zero(mas->bm, UWB_NUM_MAS);
  142. bitmap_zero(col.bm, UWB_NUM_MAS);
  143. bitmap_fill(col.bm, mas_per_zone);
  144. bitmap_shift_left(col.bm, col.bm, first_mas + zs * UWB_MAS_PER_ZONE, UWB_NUM_MAS);
  145. for (z = zs; z <= ze; z++) {
  146. bitmap_or(mas->bm, mas->bm, col.bm, UWB_NUM_MAS);
  147. bitmap_shift_left(col.bm, col.bm, UWB_MAS_PER_ZONE, UWB_NUM_MAS);
  148. }
  149. }
  150. /*
  151. * Allocate some MAS for this reservation based on current local
  152. * availability, the reservation parameters (max_mas, min_mas,
  153. * sparsity), and the WiMedia rules for MAS allocations.
  154. *
  155. * Returns -EBUSY is insufficient free MAS are available.
  156. *
  157. * FIXME: to simplify this, only safe reservations with a single row
  158. * component in zones 1 to 15 are tried (zone 0 is skipped to avoid
  159. * problems with the MAS reserved for the BP).
  160. *
  161. * [ECMA-368] section B.2.
  162. */
  163. static int uwb_rsv_alloc_mas(struct uwb_rsv *rsv)
  164. {
  165. static const int safe_mas_in_row[UWB_NUM_ZONES] = {
  166. 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1,
  167. };
  168. int n, r;
  169. struct uwb_mas_bm mas;
  170. bool found = false;
  171. /*
  172. * Search all valid safe allocations until either: too few MAS
  173. * are available; or the smallest allocation with sufficient
  174. * MAS is found.
  175. *
  176. * The top of the zones are preferred, so space for larger
  177. * allocations is available in the bottom of the zone (e.g., a
  178. * 15 MAS allocation should start in row 14 leaving space for
  179. * a 120 MAS allocation at row 0).
  180. */
  181. for (n = safe_mas_in_row[0]; n >= 1; n--) {
  182. int num_mas;
  183. num_mas = n * (UWB_NUM_ZONES - 1);
  184. if (num_mas < rsv->min_mas)
  185. break;
  186. if (found && num_mas < rsv->max_mas)
  187. break;
  188. for (r = UWB_MAS_PER_ZONE-1; r >= 0; r--) {
  189. if (safe_mas_in_row[r] < n)
  190. continue;
  191. uwb_rsv_gen_alloc_row(&mas, r, n, 1, UWB_NUM_ZONES);
  192. if (uwb_drp_avail_reserve_pending(rsv->rc, &mas) == 0) {
  193. found = true;
  194. break;
  195. }
  196. }
  197. }
  198. if (!found)
  199. return -EBUSY;
  200. bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS);
  201. return 0;
  202. }
  203. static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv)
  204. {
  205. int sframes = UWB_MAX_LOST_BEACONS;
  206. /*
  207. * Multicast reservations can become established within 1
  208. * super frame and should not be terminated if no response is
  209. * received.
  210. */
  211. if (rsv->is_multicast) {
  212. if (rsv->state == UWB_RSV_STATE_O_INITIATED)
  213. sframes = 1;
  214. if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED)
  215. sframes = 0;
  216. }
  217. rsv->expired = false;
  218. if (sframes > 0) {
  219. /*
  220. * Add an additional 2 superframes to account for the
  221. * time to send the SET DRP IE command.
  222. */
  223. unsigned timeout_us = (sframes + 2) * UWB_SUPERFRAME_LENGTH_US;
  224. mod_timer(&rsv->timer, jiffies + usecs_to_jiffies(timeout_us));
  225. } else
  226. del_timer(&rsv->timer);
  227. }
  228. /*
  229. * Update a reservations state, and schedule an update of the
  230. * transmitted DRP IEs.
  231. */
  232. static void uwb_rsv_state_update(struct uwb_rsv *rsv,
  233. enum uwb_rsv_state new_state)
  234. {
  235. rsv->state = new_state;
  236. rsv->ie_valid = false;
  237. uwb_rsv_dump(rsv);
  238. uwb_rsv_stroke_timer(rsv);
  239. uwb_rsv_sched_update(rsv->rc);
  240. }
  241. static void uwb_rsv_callback(struct uwb_rsv *rsv)
  242. {
  243. if (rsv->callback)
  244. rsv->callback(rsv);
  245. }
  246. void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
  247. {
  248. if (rsv->state == new_state) {
  249. switch (rsv->state) {
  250. case UWB_RSV_STATE_O_ESTABLISHED:
  251. case UWB_RSV_STATE_T_ACCEPTED:
  252. case UWB_RSV_STATE_NONE:
  253. uwb_rsv_stroke_timer(rsv);
  254. break;
  255. default:
  256. /* Expecting a state transition so leave timer
  257. as-is. */
  258. break;
  259. }
  260. return;
  261. }
  262. switch (new_state) {
  263. case UWB_RSV_STATE_NONE:
  264. uwb_drp_avail_release(rsv->rc, &rsv->mas);
  265. if (uwb_rsv_is_owner(rsv))
  266. uwb_rsv_put_stream(rsv);
  267. uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE);
  268. uwb_rsv_callback(rsv);
  269. break;
  270. case UWB_RSV_STATE_O_INITIATED:
  271. uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_INITIATED);
  272. break;
  273. case UWB_RSV_STATE_O_PENDING:
  274. uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING);
  275. break;
  276. case UWB_RSV_STATE_O_ESTABLISHED:
  277. uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
  278. uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED);
  279. uwb_rsv_callback(rsv);
  280. break;
  281. case UWB_RSV_STATE_T_ACCEPTED:
  282. uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
  283. uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED);
  284. uwb_rsv_callback(rsv);
  285. break;
  286. case UWB_RSV_STATE_T_DENIED:
  287. uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED);
  288. break;
  289. default:
  290. dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n",
  291. uwb_rsv_state_str(new_state), new_state);
  292. }
  293. }
  294. static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
  295. {
  296. struct uwb_rsv *rsv;
  297. rsv = kzalloc(sizeof(struct uwb_rsv), GFP_KERNEL);
  298. if (!rsv)
  299. return NULL;
  300. INIT_LIST_HEAD(&rsv->rc_node);
  301. INIT_LIST_HEAD(&rsv->pal_node);
  302. kref_init(&rsv->kref);
  303. init_timer(&rsv->timer);
  304. rsv->timer.function = uwb_rsv_timer;
  305. rsv->timer.data = (unsigned long)rsv;
  306. rsv->rc = rc;
  307. return rsv;
  308. }
  309. /**
  310. * uwb_rsv_create - allocate and initialize a UWB reservation structure
  311. * @rc: the radio controller
  312. * @cb: callback to use when the reservation completes or terminates
  313. * @pal_priv: data private to the PAL to be passed in the callback
  314. *
  315. * The callback is called when the state of the reservation changes from:
  316. *
  317. * - pending to accepted
  318. * - pending to denined
  319. * - accepted to terminated
  320. * - pending to terminated
  321. */
  322. struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb, void *pal_priv)
  323. {
  324. struct uwb_rsv *rsv;
  325. rsv = uwb_rsv_alloc(rc);
  326. if (!rsv)
  327. return NULL;
  328. rsv->callback = cb;
  329. rsv->pal_priv = pal_priv;
  330. return rsv;
  331. }
  332. EXPORT_SYMBOL_GPL(uwb_rsv_create);
  333. void uwb_rsv_remove(struct uwb_rsv *rsv)
  334. {
  335. if (rsv->state != UWB_RSV_STATE_NONE)
  336. uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
  337. del_timer_sync(&rsv->timer);
  338. uwb_dev_put(rsv->owner);
  339. if (rsv->target.type == UWB_RSV_TARGET_DEV)
  340. uwb_dev_put(rsv->target.dev);
  341. list_del_init(&rsv->rc_node);
  342. uwb_rsv_put(rsv);
  343. }
  344. /**
  345. * uwb_rsv_destroy - free a UWB reservation structure
  346. * @rsv: the reservation to free
  347. *
  348. * The reservation must already be terminated.
  349. */
  350. void uwb_rsv_destroy(struct uwb_rsv *rsv)
  351. {
  352. uwb_rsv_put(rsv);
  353. }
  354. EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
  355. /**
  356. * usb_rsv_establish - start a reservation establishment
  357. * @rsv: the reservation
  358. *
  359. * The PAL should fill in @rsv's owner, target, type, max_mas,
  360. * min_mas, sparsity and is_multicast fields. If the target is a
  361. * uwb_dev it must be referenced.
  362. *
  363. * The reservation's callback will be called when the reservation is
  364. * accepted, denied or times out.
  365. */
  366. int uwb_rsv_establish(struct uwb_rsv *rsv)
  367. {
  368. struct uwb_rc *rc = rsv->rc;
  369. int ret;
  370. mutex_lock(&rc->rsvs_mutex);
  371. ret = uwb_rsv_get_stream(rsv);
  372. if (ret)
  373. goto out;
  374. ret = uwb_rsv_alloc_mas(rsv);
  375. if (ret) {
  376. uwb_rsv_put_stream(rsv);
  377. goto out;
  378. }
  379. uwb_rsv_get(rsv);
  380. list_add_tail(&rsv->rc_node, &rc->reservations);
  381. rsv->owner = &rc->uwb_dev;
  382. uwb_dev_get(rsv->owner);
  383. uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_INITIATED);
  384. out:
  385. mutex_unlock(&rc->rsvs_mutex);
  386. return ret;
  387. }
  388. EXPORT_SYMBOL_GPL(uwb_rsv_establish);
  389. /**
  390. * uwb_rsv_modify - modify an already established reservation
  391. * @rsv: the reservation to modify
  392. * @max_mas: new maximum MAS to reserve
  393. * @min_mas: new minimum MAS to reserve
  394. * @sparsity: new sparsity to use
  395. *
  396. * FIXME: implement this once there are PALs that use it.
  397. */
  398. int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int sparsity)
  399. {
  400. return -ENOSYS;
  401. }
  402. EXPORT_SYMBOL_GPL(uwb_rsv_modify);
  403. /**
  404. * uwb_rsv_terminate - terminate an established reservation
  405. * @rsv: the reservation to terminate
  406. *
  407. * A reservation is terminated by removing the DRP IE from the beacon,
  408. * the other end will consider the reservation to be terminated when
  409. * it does not see the DRP IE for at least mMaxLostBeacons.
  410. *
  411. * If applicable, the reference to the target uwb_dev will be released.
  412. */
  413. void uwb_rsv_terminate(struct uwb_rsv *rsv)
  414. {
  415. struct uwb_rc *rc = rsv->rc;
  416. mutex_lock(&rc->rsvs_mutex);
  417. uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
  418. mutex_unlock(&rc->rsvs_mutex);
  419. }
  420. EXPORT_SYMBOL_GPL(uwb_rsv_terminate);
  421. /**
  422. * uwb_rsv_accept - accept a new reservation from a peer
  423. * @rsv: the reservation
  424. * @cb: call back for reservation changes
  425. * @pal_priv: data to be passed in the above call back
  426. *
  427. * Reservation requests from peers are denied unless a PAL accepts it
  428. * by calling this function.
  429. *
  430. * The PAL call uwb_rsv_destroy() for all accepted reservations before
  431. * calling uwb_pal_unregister().
  432. */
  433. void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv)
  434. {
  435. uwb_rsv_get(rsv);
  436. rsv->callback = cb;
  437. rsv->pal_priv = pal_priv;
  438. rsv->state = UWB_RSV_STATE_T_ACCEPTED;
  439. }
  440. EXPORT_SYMBOL_GPL(uwb_rsv_accept);
  441. /*
  442. * Is a received DRP IE for this reservation?
  443. */
  444. static bool uwb_rsv_match(struct uwb_rsv *rsv, struct uwb_dev *src,
  445. struct uwb_ie_drp *drp_ie)
  446. {
  447. struct uwb_dev_addr *rsv_src;
  448. int stream;
  449. stream = uwb_ie_drp_stream_index(drp_ie);
  450. if (rsv->stream != stream)
  451. return false;
  452. switch (rsv->target.type) {
  453. case UWB_RSV_TARGET_DEVADDR:
  454. return rsv->stream == stream;
  455. case UWB_RSV_TARGET_DEV:
  456. if (uwb_ie_drp_owner(drp_ie))
  457. rsv_src = &rsv->owner->dev_addr;
  458. else
  459. rsv_src = &rsv->target.dev->dev_addr;
  460. return uwb_dev_addr_cmp(&src->dev_addr, rsv_src) == 0;
  461. }
  462. return false;
  463. }
  464. static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
  465. struct uwb_dev *src,
  466. struct uwb_ie_drp *drp_ie)
  467. {
  468. struct uwb_rsv *rsv;
  469. struct uwb_pal *pal;
  470. enum uwb_rsv_state state;
  471. rsv = uwb_rsv_alloc(rc);
  472. if (!rsv)
  473. return NULL;
  474. rsv->rc = rc;
  475. rsv->owner = src;
  476. uwb_dev_get(rsv->owner);
  477. rsv->target.type = UWB_RSV_TARGET_DEV;
  478. rsv->target.dev = &rc->uwb_dev;
  479. rsv->type = uwb_ie_drp_type(drp_ie);
  480. rsv->stream = uwb_ie_drp_stream_index(drp_ie);
  481. uwb_drp_ie_to_bm(&rsv->mas, drp_ie);
  482. /*
  483. * See if any PALs are interested in this reservation. If not,
  484. * deny the request.
  485. */
  486. rsv->state = UWB_RSV_STATE_T_DENIED;
  487. mutex_lock(&rc->uwb_dev.mutex);
  488. list_for_each_entry(pal, &rc->pals, node) {
  489. if (pal->new_rsv)
  490. pal->new_rsv(pal, rsv);
  491. if (rsv->state == UWB_RSV_STATE_T_ACCEPTED)
  492. break;
  493. }
  494. mutex_unlock(&rc->uwb_dev.mutex);
  495. list_add_tail(&rsv->rc_node, &rc->reservations);
  496. state = rsv->state;
  497. rsv->state = UWB_RSV_STATE_NONE;
  498. uwb_rsv_set_state(rsv, state);
  499. return rsv;
  500. }
  501. /**
  502. * uwb_rsv_find - find a reservation for a received DRP IE.
  503. * @rc: the radio controller
  504. * @src: source of the DRP IE
  505. * @drp_ie: the DRP IE
  506. *
  507. * If the reservation cannot be found and the DRP IE is from a peer
  508. * attempting to establish a new reservation, create a new reservation
  509. * and add it to the list.
  510. */
  511. struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
  512. struct uwb_ie_drp *drp_ie)
  513. {
  514. struct uwb_rsv *rsv;
  515. list_for_each_entry(rsv, &rc->reservations, rc_node) {
  516. if (uwb_rsv_match(rsv, src, drp_ie))
  517. return rsv;
  518. }
  519. if (uwb_ie_drp_owner(drp_ie))
  520. return uwb_rsv_new_target(rc, src, drp_ie);
  521. return NULL;
  522. }
  523. /*
  524. * Go through all the reservations and check for timeouts and (if
  525. * necessary) update their DRP IEs.
  526. *
  527. * FIXME: look at building the SET_DRP_IE command here rather than
  528. * having to rescan the list in uwb_rc_send_all_drp_ie().
  529. */
  530. static bool uwb_rsv_update_all(struct uwb_rc *rc)
  531. {
  532. struct uwb_rsv *rsv, *t;
  533. bool ie_updated = false;
  534. list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
  535. if (rsv->expired)
  536. uwb_drp_handle_timeout(rsv);
  537. if (!rsv->ie_valid) {
  538. uwb_drp_ie_update(rsv);
  539. ie_updated = true;
  540. }
  541. }
  542. return ie_updated;
  543. }
  544. void uwb_rsv_sched_update(struct uwb_rc *rc)
  545. {
  546. queue_work(rc->rsv_workq, &rc->rsv_update_work);
  547. }
  548. /*
  549. * Update DRP IEs and, if necessary, the DRP Availability IE and send
  550. * the updated IEs to the radio controller.
  551. */
  552. static void uwb_rsv_update_work(struct work_struct *work)
  553. {
  554. struct uwb_rc *rc = container_of(work, struct uwb_rc, rsv_update_work);
  555. bool ie_updated;
  556. mutex_lock(&rc->rsvs_mutex);
  557. ie_updated = uwb_rsv_update_all(rc);
  558. if (!rc->drp_avail.ie_valid) {
  559. uwb_drp_avail_ie_update(rc);
  560. ie_updated = true;
  561. }
  562. if (ie_updated)
  563. uwb_rc_send_all_drp_ie(rc);
  564. mutex_unlock(&rc->rsvs_mutex);
  565. }
  566. static void uwb_rsv_timer(unsigned long arg)
  567. {
  568. struct uwb_rsv *rsv = (struct uwb_rsv *)arg;
  569. rsv->expired = true;
  570. uwb_rsv_sched_update(rsv->rc);
  571. }
  572. /**
  573. * uwb_rsv_remove_all - remove all reservations
  574. * @rc: the radio controller
  575. *
  576. * A DRP IE update is not done.
  577. */
  578. void uwb_rsv_remove_all(struct uwb_rc *rc)
  579. {
  580. struct uwb_rsv *rsv, *t;
  581. mutex_lock(&rc->rsvs_mutex);
  582. list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
  583. uwb_rsv_remove(rsv);
  584. }
  585. mutex_unlock(&rc->rsvs_mutex);
  586. cancel_work_sync(&rc->rsv_update_work);
  587. }
  588. void uwb_rsv_init(struct uwb_rc *rc)
  589. {
  590. INIT_LIST_HEAD(&rc->reservations);
  591. mutex_init(&rc->rsvs_mutex);
  592. INIT_WORK(&rc->rsv_update_work, uwb_rsv_update_work);
  593. bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS);
  594. }
  595. int uwb_rsv_setup(struct uwb_rc *rc)
  596. {
  597. char name[16];
  598. snprintf(name, sizeof(name), "%s_rsvd", dev_name(&rc->uwb_dev.dev));
  599. rc->rsv_workq = create_singlethread_workqueue(name);
  600. if (rc->rsv_workq == NULL)
  601. return -ENOMEM;
  602. return 0;
  603. }
  604. void uwb_rsv_cleanup(struct uwb_rc *rc)
  605. {
  606. uwb_rsv_remove_all(rc);
  607. destroy_workqueue(rc->rsv_workq);
  608. }