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