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