]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/uwb/drp-avail.c
3 * DRP availability management
5 * Copyright (C) 2005-2006 Intel Corporation
6 * Reinette Chatre <reinette.chatre@intel.com>
7 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * Manage DRP Availability (the MAS available for DRP
23 * reservations). Thus:
25 * - Handle DRP Availability Change notifications
27 * - Allow the reservation manager to indicate MAS reserved/released
28 * by local (owned by/targeted at the radio controller)
31 * - Based on the two sources above, generate a DRP Availability IE to
32 * be included in the beacon.
34 * See also the documentation for struct uwb_drp_avail.
37 #include <linux/errno.h>
38 #include <linux/module.h>
39 #include <linux/device.h>
40 #include <linux/bitmap.h>
41 #include "uwb-internal.h"
44 * uwb_drp_avail_init - initialize an RC's MAS availability
46 * All MAS are available initially. The RC will inform use which
47 * slots are used for the BP (it may change in size).
49 void uwb_drp_avail_init(struct uwb_rc
*rc
)
51 bitmap_fill(rc
->drp_avail
.global
, UWB_NUM_MAS
);
52 bitmap_fill(rc
->drp_avail
.local
, UWB_NUM_MAS
);
53 bitmap_fill(rc
->drp_avail
.pending
, UWB_NUM_MAS
);
57 * Determine MAS available for new local reservations.
59 * avail = global & local & pending
61 static void uwb_drp_available(struct uwb_rc
*rc
, struct uwb_mas_bm
*avail
)
63 bitmap_and(avail
->bm
, rc
->drp_avail
.global
, rc
->drp_avail
.local
, UWB_NUM_MAS
);
64 bitmap_and(avail
->bm
, avail
->bm
, rc
->drp_avail
.pending
, UWB_NUM_MAS
);
68 * uwb_drp_avail_reserve_pending - reserve MAS for a new reservation
69 * @rc: the radio controller
70 * @mas: the MAS to reserve
72 * Returns 0 on success, or -EBUSY if the MAS requested aren't available.
74 int uwb_drp_avail_reserve_pending(struct uwb_rc
*rc
, struct uwb_mas_bm
*mas
)
76 struct uwb_mas_bm avail
;
78 uwb_drp_available(rc
, &avail
);
79 if (!bitmap_subset(mas
->bm
, avail
.bm
, UWB_NUM_MAS
))
82 bitmap_andnot(rc
->drp_avail
.pending
, rc
->drp_avail
.pending
, mas
->bm
, UWB_NUM_MAS
);
87 * uwb_drp_avail_reserve - reserve MAS for an established reservation
88 * @rc: the radio controller
89 * @mas: the MAS to reserve
91 void uwb_drp_avail_reserve(struct uwb_rc
*rc
, struct uwb_mas_bm
*mas
)
93 bitmap_or(rc
->drp_avail
.pending
, rc
->drp_avail
.pending
, mas
->bm
, UWB_NUM_MAS
);
94 bitmap_andnot(rc
->drp_avail
.local
, rc
->drp_avail
.local
, mas
->bm
, UWB_NUM_MAS
);
95 rc
->drp_avail
.ie_valid
= false;
99 * uwb_drp_avail_release - release MAS from a pending or established reservation
100 * @rc: the radio controller
101 * @mas: the MAS to release
103 void uwb_drp_avail_release(struct uwb_rc
*rc
, struct uwb_mas_bm
*mas
)
105 bitmap_or(rc
->drp_avail
.local
, rc
->drp_avail
.local
, mas
->bm
, UWB_NUM_MAS
);
106 bitmap_or(rc
->drp_avail
.pending
, rc
->drp_avail
.pending
, mas
->bm
, UWB_NUM_MAS
);
107 rc
->drp_avail
.ie_valid
= false;
111 * uwb_drp_avail_ie_update - update the DRP Availability IE
112 * @rc: the radio controller
114 * avail = global & local
116 void uwb_drp_avail_ie_update(struct uwb_rc
*rc
)
118 struct uwb_mas_bm avail
;
120 bitmap_and(avail
.bm
, rc
->drp_avail
.global
, rc
->drp_avail
.local
, UWB_NUM_MAS
);
122 rc
->drp_avail
.ie
.hdr
.element_id
= UWB_IE_DRP_AVAILABILITY
;
123 rc
->drp_avail
.ie
.hdr
.length
= UWB_NUM_MAS
/ 8;
124 uwb_mas_bm_copy_le(rc
->drp_avail
.ie
.bmp
, &avail
);
125 rc
->drp_avail
.ie_valid
= true;
129 * Create an unsigned long from a buffer containing a byte stream.
131 * @array: pointer to buffer
132 * @itr: index of buffer from where we start
133 * @len: the buffer's remaining size may not be exact multiple of
134 * sizeof(unsigned long), @len is the length of buffer that needs
135 * to be converted. This will be sizeof(unsigned long) or smaller
136 * (BUG if not). If it is smaller then we will pad the remaining
137 * space of the result with zeroes.
140 unsigned long get_val(u8
*array
, size_t itr
, size_t len
)
142 unsigned long val
= 0;
143 size_t top
= itr
+ len
;
145 BUG_ON(len
> sizeof(val
));
149 val
|= array
[top
- 1];
152 val
<<= 8 * (sizeof(val
) - len
); /* padding */
157 * Initialize bitmap from data buffer.
159 * The bitmap to be converted could come from a IE, for example a
160 * DRP Availability IE.
161 * From ECMA-368 1.0 [16.8.7]: "
162 * octets: 1 1 N * (0 to 32)
163 * Element ID Length (=N) DRP Availability Bitmap
165 * The DRP Availability Bitmap field is up to 256 bits long, one
166 * bit for each MAS in the superframe, where the least-significant
167 * bit of the field corresponds to the first MAS in the superframe
168 * and successive bits correspond to successive MASs."
170 * The DRP Availability bitmap is in octets from 0 to 32, so octet
171 * 32 contains bits for MAS 1-8, etc. If the bitmap is smaller than 32
172 * octets, the bits in octets not included at the end of the bitmap are
173 * treated as zero. In this case (when the bitmap is smaller than 32
174 * octets) the MAS represented range from MAS 1 to MAS (size of bitmap)
175 * with the last octet still containing bits for MAS 1-8, etc.
178 * F00F0102 03040506 0708090A 0B0C0D0E 0F010203
182 * |||\LSB of byte is MAS 9
183 * ||\MSB of byte is MAS 16
184 * |\LSB of first byte is MAS 1
185 * \ MSB of byte is MAS 8
187 * An example of this encoding can be found in ECMA-368 Annex-D [Table D.11]
189 * The resulting bitmap will have the following mapping:
190 * bit position 0 == MAS 1
191 * bit position 1 == MAS 2
193 * bit position (UWB_NUM_MAS - 1) == MAS UWB_NUM_MAS
195 * @bmp_itr: pointer to bitmap (can be declared with DECLARE_BITMAP)
196 * @buffer: pointer to buffer containing bitmap data in big endian
198 * @buffer_size:number of bytes with which bitmap should be initialized
201 void buffer_to_bmp(unsigned long *bmp_itr
, void *_buffer
,
204 u8
*buffer
= _buffer
;
209 while (itr
< buffer_size
) {
210 len
= buffer_size
- itr
>= sizeof(val
) ?
211 sizeof(val
) : buffer_size
- itr
;
212 val
= get_val(buffer
, itr
, len
);
213 bmp_itr
[itr
/ sizeof(val
)] = val
;
220 * Extract DRP Availability bitmap from the notification.
222 * The notification that comes in contains a bitmap of (UWB_NUM_MAS / 8) bytes
223 * We convert that to our internal representation.
226 int uwbd_evt_get_drp_avail(struct uwb_event
*evt
, unsigned long *bmp
)
228 struct device
*dev
= &evt
->rc
->uwb_dev
.dev
;
229 struct uwb_rc_evt_drp_avail
*drp_evt
;
230 int result
= -EINVAL
;
232 /* Is there enough data to decode the event? */
233 if (evt
->notif
.size
< sizeof(*drp_evt
)) {
234 dev_err(dev
, "DRP Availability Change: Not enough "
235 "data to decode event [%zu bytes, %zu "
236 "needed]\n", evt
->notif
.size
, sizeof(*drp_evt
));
239 drp_evt
= container_of(evt
->notif
.rceb
, struct uwb_rc_evt_drp_avail
, rceb
);
240 buffer_to_bmp(bmp
, drp_evt
->bmp
, UWB_NUM_MAS
/8);
248 * Process an incoming DRP Availability notification.
250 * @evt: Event information (packs the actual event data, which
251 * radio controller it came to, etc).
253 * @returns: 0 on success (so uwbd() frees the event buffer), < 0
256 * According to ECMA-368 1.0 [16.8.7], bits set to ONE indicate that
257 * the MAS slot is available, bits set to ZERO indicate that the slot
260 * So we clear available slots, we set used slots :)
262 * The notification only marks non-availability based on the BP and
263 * received DRP IEs that are not for this radio controller. A copy of
264 * this bitmap is needed to generate the real availability (which
265 * includes local and pending reservations).
267 * The DRP Availability IE that this radio controller emits will need
270 int uwbd_evt_handle_rc_drp_avail(struct uwb_event
*evt
)
273 struct uwb_rc
*rc
= evt
->rc
;
274 DECLARE_BITMAP(bmp
, UWB_NUM_MAS
);
276 result
= uwbd_evt_get_drp_avail(evt
, bmp
);
280 mutex_lock(&rc
->rsvs_mutex
);
281 bitmap_copy(rc
->drp_avail
.global
, bmp
, UWB_NUM_MAS
);
282 rc
->drp_avail
.ie_valid
= false;
283 mutex_unlock(&rc
->rsvs_mutex
);
285 uwb_rsv_sched_update(rc
);