diff options
Diffstat (limited to 'drivers/uwb/beacon.c')
-rw-r--r-- | drivers/uwb/beacon.c | 134 |
1 files changed, 50 insertions, 84 deletions
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 46b18ee..36bc315 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -22,19 +22,16 @@ * * FIXME: docs */ - #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> #include <linux/err.h> #include <linux/kdev_t.h> -#include "uwb-internal.h" -#define D_LOCAL 0 -#include <linux/uwb/debug.h> +#include "uwb-internal.h" -/** Start Beaconing command structure */ +/* Start Beaconing command structure */ struct uwb_rc_cmd_start_beacon { struct uwb_rccb rccb; __le16 wBPSTOffset; @@ -119,7 +116,6 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) int result; struct device *dev = &rc->uwb_dev.dev; - mutex_lock(&rc->uwb_dev.mutex); if (channel < 0) channel = -1; if (channel == -1) @@ -128,7 +124,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) /* channel >= 0...dah */ result = uwb_rc_start_beacon(rc, bpst_offset, channel); if (result < 0) - goto out_up; + return result; if (le16_to_cpu(rc->ies->wIELength) > 0) { result = uwb_rc_set_ie(rc, rc->ies); if (result < 0) { @@ -137,19 +133,12 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) result = uwb_rc_stop_beacon(rc); channel = -1; bpst_offset = 0; - } else - result = 0; + } } } - if (result < 0) - goto out_up; - rc->beaconing = channel; - - uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE); - -out_up: - mutex_unlock(&rc->uwb_dev.mutex); + if (result >= 0) + rc->beaconing = channel; return result; } @@ -168,12 +157,6 @@ out_up: * FIXME: use something faster for search than a list */ -struct uwb_beca uwb_beca = { - .list = LIST_HEAD_INIT(uwb_beca.list), - .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex) -}; - - void uwb_bce_kfree(struct kref *_bce) { struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); @@ -185,13 +168,11 @@ void uwb_bce_kfree(struct kref *_bce) /* Find a beacon by dev addr in the cache */ static -struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) +struct uwb_beca_e *__uwb_beca_find_bydev(struct uwb_rc *rc, + const struct uwb_dev_addr *dev_addr) { struct uwb_beca_e *bce, *next; - list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { - d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n", - dev_addr->data[0], dev_addr->data[1], - bce->dev_addr.data[0], bce->dev_addr.data[1]); + list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr))) goto out; } @@ -202,10 +183,11 @@ out: /* Find a beacon by dev addr in the cache */ static -struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) +struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc, + const struct uwb_mac_addr *mac_addr) { struct uwb_beca_e *bce, *next; - list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { + list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { if (!memcmp(bce->mac_addr, mac_addr->data, sizeof(struct uwb_mac_addr))) goto out; @@ -229,11 +211,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, struct uwb_dev *found = NULL; struct uwb_beca_e *bce; - mutex_lock(&uwb_beca.mutex); - bce = __uwb_beca_find_bydev(devaddr); + mutex_lock(&rc->uwb_beca.mutex); + bce = __uwb_beca_find_bydev(rc, devaddr); if (bce) found = uwb_dev_try_get(rc, bce->uwb_dev); - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); return found; } @@ -249,11 +231,11 @@ struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, struct uwb_dev *found = NULL; struct uwb_beca_e *bce; - mutex_lock(&uwb_beca.mutex); - bce = __uwb_beca_find_bymac(macaddr); + mutex_lock(&rc->uwb_beca.mutex); + bce = __uwb_beca_find_bymac(rc, macaddr); if (bce) found = uwb_dev_try_get(rc, bce->uwb_dev); - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); return found; } @@ -274,7 +256,9 @@ static void uwb_beca_e_init(struct uwb_beca_e *bce) * @bf: Beacon frame (part of b, really) * @ts_jiffies: Timestamp (in jiffies) when the beacon was received */ -struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, +static +struct uwb_beca_e *__uwb_beca_add(struct uwb_rc *rc, + struct uwb_rc_evt_beacon *be, struct uwb_beacon_frame *bf, unsigned long ts_jiffies) { @@ -286,7 +270,7 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, uwb_beca_e_init(bce); bce->ts_jiffies = ts_jiffies; bce->uwb_dev = NULL; - list_add(&bce->node, &uwb_beca.list); + list_add(&bce->node, &rc->uwb_beca.list); return bce; } @@ -295,33 +279,32 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, * * Remove associated devicest too. */ -void uwb_beca_purge(void) +void uwb_beca_purge(struct uwb_rc *rc) { struct uwb_beca_e *bce, *next; unsigned long expires; - mutex_lock(&uwb_beca.mutex); - list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { + mutex_lock(&rc->uwb_beca.mutex); + list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); if (time_after(jiffies, expires)) { uwbd_dev_offair(bce); - list_del(&bce->node); - uwb_bce_put(bce); } } - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); } /* Clean up the whole beacon cache. Called on shutdown */ -void uwb_beca_release(void) +void uwb_beca_release(struct uwb_rc *rc) { struct uwb_beca_e *bce, *next; - mutex_lock(&uwb_beca.mutex); - list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { + + mutex_lock(&rc->uwb_beca.mutex); + list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { list_del(&bce->node); uwb_bce_put(bce); } - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); } static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, @@ -349,22 +332,22 @@ ssize_t uwb_bce_print_IEs(struct uwb_dev *uwb_dev, struct uwb_beca_e *bce, ssize_t result = 0; struct uwb_rc_evt_beacon *be; struct uwb_beacon_frame *bf; - struct uwb_buf_ctx ctx = { - .buf = buf, - .bytes = 0, - .size = size - }; + int ies_len; + struct uwb_ie_hdr *ies; mutex_lock(&bce->mutex); + be = bce->be; - if (be == NULL) - goto out; - bf = (void *) be->BeaconInfo; - uwb_ie_for_each(uwb_dev, uwb_ie_dump_hex, &ctx, - bf->IEData, be->wBeaconInfoLength - sizeof(*bf)); - result = ctx.bytes; -out: + if (be) { + bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo; + ies_len = be->wBeaconInfoLength - sizeof(struct uwb_beacon_frame); + ies = (struct uwb_ie_hdr *)bf->IEData; + + result = uwb_ie_dump_hex(ies, ies_len, buf, size); + } + mutex_unlock(&bce->mutex); + return result; } @@ -437,18 +420,18 @@ int uwbd_evt_handle_rc_beacon(struct uwb_event *evt) if (uwb_mac_addr_bcast(&bf->Device_Identifier)) return 0; - mutex_lock(&uwb_beca.mutex); - bce = __uwb_beca_find_bymac(&bf->Device_Identifier); + mutex_lock(&rc->uwb_beca.mutex); + bce = __uwb_beca_find_bymac(rc, &bf->Device_Identifier); if (bce == NULL) { /* Not in there, a new device is pinging */ uwb_beacon_print(evt->rc, be, bf); - bce = __uwb_beca_add(be, bf, evt->ts_jiffies); + bce = __uwb_beca_add(rc, be, bf, evt->ts_jiffies); if (bce == NULL) { - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); return -ENOMEM; } } - mutex_unlock(&uwb_beca.mutex); + mutex_unlock(&rc->uwb_beca.mutex); mutex_lock(&bce->mutex); /* purge old beacon data */ @@ -588,19 +571,6 @@ error: return result; } -/** - * uwb_bg_joined - is the RC in a beacon group? - * @rc: the radio controller - * - * Returns true if the radio controller is in a beacon group (even if - * it's the sole member). - */ -int uwb_bg_joined(struct uwb_rc *rc) -{ - return rc->beaconing != -1; -} -EXPORT_SYMBOL_GPL(uwb_bg_joined); - /* * Print beaconing state. */ @@ -619,9 +589,6 @@ static ssize_t uwb_rc_beacon_show(struct device *dev, /* * Start beaconing on the specified channel, or stop beaconing. - * - * The BPST offset of when to start searching for a beacon group to - * join may be specified. */ static ssize_t uwb_rc_beacon_store(struct device *dev, struct device_attribute *attr, @@ -630,12 +597,11 @@ static ssize_t uwb_rc_beacon_store(struct device *dev, struct uwb_dev *uwb_dev = to_uwb_dev(dev); struct uwb_rc *rc = uwb_dev->rc; int channel; - unsigned bpst_offset = 0; ssize_t result = -EINVAL; - result = sscanf(buf, "%d %u\n", &channel, &bpst_offset); + result = sscanf(buf, "%d", &channel); if (result >= 1) - result = uwb_rc_beacon(rc, channel, bpst_offset); + result = uwb_radio_force_channel(rc, channel); return result < 0 ? result : size; } |