1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Ultra Wide Band
4  * DRP availability management
5  *
6  * Copyright (C) 2005-2006 Intel Corporation
7  * Reinette Chatre <reinette.chatre@intel.com>
8  * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
9  *
10  * Manage DRP Availability (the MAS available for DRP
11  * reservations). Thus:
12  *
13  * - Handle DRP Availability Change notifications
14  *
15  * - Allow the reservation manager to indicate MAS reserved/released
16  *   by local (owned by/targeted at the radio controller)
17  *   reservations.
18  *
19  * - Based on the two sources above, generate a DRP Availability IE to
20  *   be included in the beacon.
21  *
22  * See also the documentation for struct uwb_drp_avail.
23  */
24 
25 #include <linux/errno.h>
26 #include <linux/module.h>
27 #include <linux/device.h>
28 #include <linux/bitmap.h>
29 #include "uwb-internal.h"
30 
31 /**
32  * uwb_drp_avail_init - initialize an RC's MAS availability
33  *
34  * All MAS are available initially.  The RC will inform use which
35  * slots are used for the BP (it may change in size).
36  */
uwb_drp_avail_init(struct uwb_rc * rc)37 void uwb_drp_avail_init(struct uwb_rc *rc)
38 {
39 	bitmap_fill(rc->drp_avail.global, UWB_NUM_MAS);
40 	bitmap_fill(rc->drp_avail.local, UWB_NUM_MAS);
41 	bitmap_fill(rc->drp_avail.pending, UWB_NUM_MAS);
42 }
43 
44 /*
45  * Determine MAS available for new local reservations.
46  *
47  * avail = global & local & pending
48  */
uwb_drp_available(struct uwb_rc * rc,struct uwb_mas_bm * avail)49 void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail)
50 {
51 	bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
52 	bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS);
53 }
54 
55 /**
56  * uwb_drp_avail_reserve_pending - reserve MAS for a new reservation
57  * @rc: the radio controller
58  * @mas: the MAS to reserve
59  *
60  * Returns 0 on success, or -EBUSY if the MAS requested aren't available.
61  */
uwb_drp_avail_reserve_pending(struct uwb_rc * rc,struct uwb_mas_bm * mas)62 int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas)
63 {
64 	struct uwb_mas_bm avail;
65 
66 	uwb_drp_available(rc, &avail);
67 	if (!bitmap_subset(mas->bm, avail.bm, UWB_NUM_MAS))
68 		return -EBUSY;
69 
70 	bitmap_andnot(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
71 	return 0;
72 }
73 
74 /**
75  * uwb_drp_avail_reserve - reserve MAS for an established reservation
76  * @rc: the radio controller
77  * @mas: the MAS to reserve
78  */
uwb_drp_avail_reserve(struct uwb_rc * rc,struct uwb_mas_bm * mas)79 void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas)
80 {
81 	bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
82 	bitmap_andnot(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS);
83 	rc->drp_avail.ie_valid = false;
84 }
85 
86 /**
87  * uwb_drp_avail_release - release MAS from a pending or established reservation
88  * @rc: the radio controller
89  * @mas: the MAS to release
90  */
uwb_drp_avail_release(struct uwb_rc * rc,struct uwb_mas_bm * mas)91 void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas)
92 {
93 	bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS);
94 	bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
95 	rc->drp_avail.ie_valid = false;
96 	uwb_rsv_handle_drp_avail_change(rc);
97 }
98 
99 /**
100  * uwb_drp_avail_ie_update - update the DRP Availability IE
101  * @rc: the radio controller
102  *
103  * avail = global & local
104  */
uwb_drp_avail_ie_update(struct uwb_rc * rc)105 void uwb_drp_avail_ie_update(struct uwb_rc *rc)
106 {
107 	struct uwb_mas_bm avail;
108 
109 	bitmap_and(avail.bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
110 
111 	rc->drp_avail.ie.hdr.element_id = UWB_IE_DRP_AVAILABILITY;
112 	rc->drp_avail.ie.hdr.length = UWB_NUM_MAS / 8;
113 	uwb_mas_bm_copy_le(rc->drp_avail.ie.bmp, &avail);
114 	rc->drp_avail.ie_valid = true;
115 }
116 
117 /**
118  * Create an unsigned long from a buffer containing a byte stream.
119  *
120  * @array: pointer to buffer
121  * @itr:   index of buffer from where we start
122  * @len:   the buffer's remaining size may not be exact multiple of
123  *         sizeof(unsigned long), @len is the length of buffer that needs
124  *         to be converted. This will be sizeof(unsigned long) or smaller
125  *         (BUG if not). If it is smaller then we will pad the remaining
126  *         space of the result with zeroes.
127  */
128 static
get_val(u8 * array,size_t itr,size_t len)129 unsigned long get_val(u8 *array, size_t itr, size_t len)
130 {
131 	unsigned long val = 0;
132 	size_t top = itr + len;
133 
134 	BUG_ON(len > sizeof(val));
135 
136 	while (itr < top) {
137 		val <<= 8;
138 		val |= array[top - 1];
139 		top--;
140 	}
141 	val <<= 8 * (sizeof(val) - len); /* padding */
142 	return val;
143 }
144 
145 /**
146  * Initialize bitmap from data buffer.
147  *
148  * The bitmap to be converted could come from a IE, for example a
149  * DRP Availability IE.
150  * From ECMA-368 1.0 [16.8.7]: "
151  * octets: 1            1               N * (0 to 32)
152  *         Element ID   Length (=N)     DRP Availability Bitmap
153  *
154  * The DRP Availability Bitmap field is up to 256 bits long, one
155  * bit for each MAS in the superframe, where the least-significant
156  * bit of the field corresponds to the first MAS in the superframe
157  * and successive bits correspond to successive MASs."
158  *
159  * The DRP Availability bitmap is in octets from 0 to 32, so octet
160  * 32 contains bits for MAS 1-8, etc. If the bitmap is smaller than 32
161  * octets, the bits in octets not included at the end of the bitmap are
162  * treated as zero. In this case (when the bitmap is smaller than 32
163  * octets) the MAS represented range from MAS 1 to MAS (size of bitmap)
164  * with the last octet still containing bits for MAS 1-8, etc.
165  *
166  * For example:
167  * F00F0102 03040506 0708090A 0B0C0D0E 0F010203
168  * ^^^^
169  * ||||
170  * ||||
171  * |||\LSB of byte is MAS 9
172  * ||\MSB of byte is MAS 16
173  * |\LSB of first byte is MAS 1
174  * \ MSB of byte is MAS 8
175  *
176  * An example of this encoding can be found in ECMA-368 Annex-D [Table D.11]
177  *
178  * The resulting bitmap will have the following mapping:
179  *	bit position 0 == MAS 1
180  *	bit position 1 == MAS 2
181  *	...
182  *	bit position (UWB_NUM_MAS - 1) == MAS UWB_NUM_MAS
183  *
184  * @bmp_itr:	pointer to bitmap (can be declared with DECLARE_BITMAP)
185  * @buffer:	pointer to buffer containing bitmap data in big endian
186  *              format (MSB first)
187  * @buffer_size:number of bytes with which bitmap should be initialized
188  */
189 static
buffer_to_bmp(unsigned long * bmp_itr,void * _buffer,size_t buffer_size)190 void buffer_to_bmp(unsigned long *bmp_itr, void *_buffer,
191 		   size_t buffer_size)
192 {
193 	u8 *buffer = _buffer;
194 	size_t itr, len;
195 	unsigned long val;
196 
197 	itr = 0;
198 	while (itr < buffer_size) {
199 		len = buffer_size - itr >= sizeof(val) ?
200 			sizeof(val) : buffer_size - itr;
201 		val = get_val(buffer, itr, len);
202 		bmp_itr[itr / sizeof(val)] = val;
203 		itr += sizeof(val);
204 	}
205 }
206 
207 
208 /**
209  * Extract DRP Availability bitmap from the notification.
210  *
211  * The notification that comes in contains a bitmap of (UWB_NUM_MAS / 8) bytes
212  * We convert that to our internal representation.
213  */
214 static
uwbd_evt_get_drp_avail(struct uwb_event * evt,unsigned long * bmp)215 int uwbd_evt_get_drp_avail(struct uwb_event *evt, unsigned long *bmp)
216 {
217 	struct device *dev = &evt->rc->uwb_dev.dev;
218 	struct uwb_rc_evt_drp_avail *drp_evt;
219 	int result = -EINVAL;
220 
221 	/* Is there enough data to decode the event? */
222 	if (evt->notif.size < sizeof(*drp_evt)) {
223 		dev_err(dev, "DRP Availability Change: Not enough "
224 			"data to decode event [%zu bytes, %zu "
225 			"needed]\n", evt->notif.size, sizeof(*drp_evt));
226 		goto error;
227 	}
228 	drp_evt = container_of(evt->notif.rceb, struct uwb_rc_evt_drp_avail, rceb);
229 	buffer_to_bmp(bmp, drp_evt->bmp, UWB_NUM_MAS/8);
230 	result = 0;
231 error:
232 	return result;
233 }
234 
235 
236 /**
237  * Process an incoming DRP Availability notification.
238  *
239  * @evt:	Event information (packs the actual event data, which
240  *              radio controller it came to, etc).
241  *
242  * @returns:    0 on success (so uwbd() frees the event buffer), < 0
243  *              on error.
244  *
245  * According to ECMA-368 1.0 [16.8.7], bits set to ONE indicate that
246  * the MAS slot is available, bits set to ZERO indicate that the slot
247  * is busy.
248  *
249  * So we clear available slots, we set used slots :)
250  *
251  * The notification only marks non-availability based on the BP and
252  * received DRP IEs that are not for this radio controller.  A copy of
253  * this bitmap is needed to generate the real availability (which
254  * includes local and pending reservations).
255  *
256  * The DRP Availability IE that this radio controller emits will need
257  * to be updated.
258  */
uwbd_evt_handle_rc_drp_avail(struct uwb_event * evt)259 int uwbd_evt_handle_rc_drp_avail(struct uwb_event *evt)
260 {
261 	int result;
262 	struct uwb_rc *rc = evt->rc;
263 	DECLARE_BITMAP(bmp, UWB_NUM_MAS);
264 
265 	result = uwbd_evt_get_drp_avail(evt, bmp);
266 	if (result < 0)
267 		return result;
268 
269 	mutex_lock(&rc->rsvs_mutex);
270 	bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS);
271 	rc->drp_avail.ie_valid = false;
272 	uwb_rsv_handle_drp_avail_change(rc);
273 	mutex_unlock(&rc->rsvs_mutex);
274 
275 	uwb_rsv_sched_update(rc);
276 
277 	return 0;
278 }
279