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 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;
 
 108         uwb_rsv_handle_drp_avail_change(rc);
 
 112  * uwb_drp_avail_ie_update - update the DRP Availability IE
 
 113  * @rc: the radio controller
 
 115  * avail = global & local
 
 117 void uwb_drp_avail_ie_update(struct uwb_rc *rc)
 
 119         struct uwb_mas_bm avail;
 
 121         bitmap_and(avail.bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
 
 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;
 
 130  * Create an unsigned long from a buffer containing a byte stream.
 
 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.
 
 141 unsigned long get_val(u8 *array, size_t itr, size_t len)
 
 143         unsigned long val = 0;
 
 144         size_t top = itr + len;
 
 146         BUG_ON(len > sizeof(val));
 
 150                 val |= array[top - 1];
 
 153         val <<= 8 * (sizeof(val) - len); /* padding */
 
 158  * Initialize bitmap from data buffer.
 
 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
 
 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."
 
 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.
 
 179  * F00F0102 03040506 0708090A 0B0C0D0E 0F010203
 
 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
 
 188  * An example of this encoding can be found in ECMA-368 Annex-D [Table D.11]
 
 190  * The resulting bitmap will have the following mapping:
 
 191  *      bit position 0 == MAS 1
 
 192  *      bit position 1 == MAS 2
 
 194  *      bit position (UWB_NUM_MAS - 1) == MAS UWB_NUM_MAS
 
 196  * @bmp_itr:    pointer to bitmap (can be declared with DECLARE_BITMAP)
 
 197  * @buffer:     pointer to buffer containing bitmap data in big endian
 
 199  * @buffer_size:number of bytes with which bitmap should be initialized
 
 202 void buffer_to_bmp(unsigned long *bmp_itr, void *_buffer,
 
 205         u8 *buffer = _buffer;
 
 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;
 
 221  * Extract DRP Availability bitmap from the notification.
 
 223  * The notification that comes in contains a bitmap of (UWB_NUM_MAS / 8) bytes
 
 224  * We convert that to our internal representation.
 
 227 int uwbd_evt_get_drp_avail(struct uwb_event *evt, unsigned long *bmp)
 
 229         struct device *dev = &evt->rc->uwb_dev.dev;
 
 230         struct uwb_rc_evt_drp_avail *drp_evt;
 
 231         int result = -EINVAL;
 
 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));
 
 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);
 
 249  * Process an incoming DRP Availability notification.
 
 251  * @evt:        Event information (packs the actual event data, which
 
 252  *              radio controller it came to, etc).
 
 254  * @returns:    0 on success (so uwbd() frees the event buffer), < 0
 
 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
 
 261  * So we clear available slots, we set used slots :)
 
 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).
 
 268  * The DRP Availability IE that this radio controller emits will need
 
 271 int uwbd_evt_handle_rc_drp_avail(struct uwb_event *evt)
 
 274         struct uwb_rc *rc = evt->rc;
 
 275         DECLARE_BITMAP(bmp, UWB_NUM_MAS);
 
 277         result = uwbd_evt_get_drp_avail(evt, bmp);
 
 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);
 
 287         uwb_rsv_sched_update(rc);