aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb/beacon.c
diff options
context:
space:
mode:
authorStefano Panella <stefano.panella@csr.com>2008-11-04 10:39:08 -0500
committerDavid Vrabel <david.vrabel@csr.com>2008-11-04 10:55:26 -0500
commitfec1a5932f16c0eb1b3f5ca2e18d81d860924088 (patch)
tree48836158dbd458bb462b18f4deffa89e9db80376 /drivers/uwb/beacon.c
parent6d5a681dfb583b2f1eefe7cd5505419ca2d4d6c8 (diff)
uwb: per-radio controller event thread and beacon cache
Use an event thread per-radio controller so processing events from one radio controller doesn't delay another. A radio controller shouldn't have information on devices seen by a different radio controller (they may be on different channels) so make the beacon cache per-radio controller. Signed-off-by: Stefano Panella <stefano.panella@csr.com> Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/uwb/beacon.c')
-rw-r--r--drivers/uwb/beacon.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c
index ad823987ced..d9f2a8acc59 100644
--- a/drivers/uwb/beacon.c
+++ b/drivers/uwb/beacon.c
@@ -168,12 +168,6 @@ out_up:
168 * FIXME: use something faster for search than a list 168 * FIXME: use something faster for search than a list
169 */ 169 */
170 170
171struct uwb_beca uwb_beca = {
172 .list = LIST_HEAD_INIT(uwb_beca.list),
173 .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex)
174};
175
176
177void uwb_bce_kfree(struct kref *_bce) 171void uwb_bce_kfree(struct kref *_bce)
178{ 172{
179 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); 173 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt);
@@ -185,10 +179,11 @@ void uwb_bce_kfree(struct kref *_bce)
185 179
186/* Find a beacon by dev addr in the cache */ 180/* Find a beacon by dev addr in the cache */
187static 181static
188struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) 182struct uwb_beca_e *__uwb_beca_find_bydev(struct uwb_rc *rc,
183 const struct uwb_dev_addr *dev_addr)
189{ 184{
190 struct uwb_beca_e *bce, *next; 185 struct uwb_beca_e *bce, *next;
191 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 186 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
192 d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n", 187 d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n",
193 dev_addr->data[0], dev_addr->data[1], 188 dev_addr->data[0], dev_addr->data[1],
194 bce->dev_addr.data[0], bce->dev_addr.data[1]); 189 bce->dev_addr.data[0], bce->dev_addr.data[1]);
@@ -202,10 +197,11 @@ out:
202 197
203/* Find a beacon by dev addr in the cache */ 198/* Find a beacon by dev addr in the cache */
204static 199static
205struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) 200struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc,
201 const struct uwb_mac_addr *mac_addr)
206{ 202{
207 struct uwb_beca_e *bce, *next; 203 struct uwb_beca_e *bce, *next;
208 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 204 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
209 if (!memcmp(bce->mac_addr, mac_addr->data, 205 if (!memcmp(bce->mac_addr, mac_addr->data,
210 sizeof(struct uwb_mac_addr))) 206 sizeof(struct uwb_mac_addr)))
211 goto out; 207 goto out;
@@ -229,11 +225,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
229 struct uwb_dev *found = NULL; 225 struct uwb_dev *found = NULL;
230 struct uwb_beca_e *bce; 226 struct uwb_beca_e *bce;
231 227
232 mutex_lock(&uwb_beca.mutex); 228 mutex_lock(&rc->uwb_beca.mutex);
233 bce = __uwb_beca_find_bydev(devaddr); 229 bce = __uwb_beca_find_bydev(rc, devaddr);
234 if (bce) 230 if (bce)
235 found = uwb_dev_try_get(rc, bce->uwb_dev); 231 found = uwb_dev_try_get(rc, bce->uwb_dev);
236 mutex_unlock(&uwb_beca.mutex); 232 mutex_unlock(&rc->uwb_beca.mutex);
237 233
238 return found; 234 return found;
239} 235}
@@ -249,11 +245,11 @@ struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
249 struct uwb_dev *found = NULL; 245 struct uwb_dev *found = NULL;
250 struct uwb_beca_e *bce; 246 struct uwb_beca_e *bce;
251 247
252 mutex_lock(&uwb_beca.mutex); 248 mutex_lock(&rc->uwb_beca.mutex);
253 bce = __uwb_beca_find_bymac(macaddr); 249 bce = __uwb_beca_find_bymac(rc, macaddr);
254 if (bce) 250 if (bce)
255 found = uwb_dev_try_get(rc, bce->uwb_dev); 251 found = uwb_dev_try_get(rc, bce->uwb_dev);
256 mutex_unlock(&uwb_beca.mutex); 252 mutex_unlock(&rc->uwb_beca.mutex);
257 253
258 return found; 254 return found;
259} 255}
@@ -274,7 +270,9 @@ static void uwb_beca_e_init(struct uwb_beca_e *bce)
274 * @bf: Beacon frame (part of b, really) 270 * @bf: Beacon frame (part of b, really)
275 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received 271 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received
276 */ 272 */
277struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, 273static
274struct uwb_beca_e *__uwb_beca_add(struct uwb_rc *rc,
275 struct uwb_rc_evt_beacon *be,
278 struct uwb_beacon_frame *bf, 276 struct uwb_beacon_frame *bf,
279 unsigned long ts_jiffies) 277 unsigned long ts_jiffies)
280{ 278{
@@ -286,7 +284,7 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
286 uwb_beca_e_init(bce); 284 uwb_beca_e_init(bce);
287 bce->ts_jiffies = ts_jiffies; 285 bce->ts_jiffies = ts_jiffies;
288 bce->uwb_dev = NULL; 286 bce->uwb_dev = NULL;
289 list_add(&bce->node, &uwb_beca.list); 287 list_add(&bce->node, &rc->uwb_beca.list);
290 return bce; 288 return bce;
291} 289}
292 290
@@ -295,13 +293,13 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
295 * 293 *
296 * Remove associated devicest too. 294 * Remove associated devicest too.
297 */ 295 */
298void uwb_beca_purge(void) 296void uwb_beca_purge(struct uwb_rc *rc)
299{ 297{
300 struct uwb_beca_e *bce, *next; 298 struct uwb_beca_e *bce, *next;
301 unsigned long expires; 299 unsigned long expires;
302 300
303 mutex_lock(&uwb_beca.mutex); 301 mutex_lock(&rc->uwb_beca.mutex);
304 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 302 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
305 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); 303 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms);
306 if (time_after(jiffies, expires)) { 304 if (time_after(jiffies, expires)) {
307 uwbd_dev_offair(bce); 305 uwbd_dev_offair(bce);
@@ -309,19 +307,20 @@ void uwb_beca_purge(void)
309 uwb_bce_put(bce); 307 uwb_bce_put(bce);
310 } 308 }
311 } 309 }
312 mutex_unlock(&uwb_beca.mutex); 310 mutex_unlock(&rc->uwb_beca.mutex);
313} 311}
314 312
315/* Clean up the whole beacon cache. Called on shutdown */ 313/* Clean up the whole beacon cache. Called on shutdown */
316void uwb_beca_release(void) 314void uwb_beca_release(struct uwb_rc *rc)
317{ 315{
318 struct uwb_beca_e *bce, *next; 316 struct uwb_beca_e *bce, *next;
319 mutex_lock(&uwb_beca.mutex); 317
320 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 318 mutex_lock(&rc->uwb_beca.mutex);
319 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
321 list_del(&bce->node); 320 list_del(&bce->node);
322 uwb_bce_put(bce); 321 uwb_bce_put(bce);
323 } 322 }
324 mutex_unlock(&uwb_beca.mutex); 323 mutex_unlock(&rc->uwb_beca.mutex);
325} 324}
326 325
327static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, 326static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be,
@@ -437,18 +436,18 @@ int uwbd_evt_handle_rc_beacon(struct uwb_event *evt)
437 if (uwb_mac_addr_bcast(&bf->Device_Identifier)) 436 if (uwb_mac_addr_bcast(&bf->Device_Identifier))
438 return 0; 437 return 0;
439 438
440 mutex_lock(&uwb_beca.mutex); 439 mutex_lock(&rc->uwb_beca.mutex);
441 bce = __uwb_beca_find_bymac(&bf->Device_Identifier); 440 bce = __uwb_beca_find_bymac(rc, &bf->Device_Identifier);
442 if (bce == NULL) { 441 if (bce == NULL) {
443 /* Not in there, a new device is pinging */ 442 /* Not in there, a new device is pinging */
444 uwb_beacon_print(evt->rc, be, bf); 443 uwb_beacon_print(evt->rc, be, bf);
445 bce = __uwb_beca_add(be, bf, evt->ts_jiffies); 444 bce = __uwb_beca_add(rc, be, bf, evt->ts_jiffies);
446 if (bce == NULL) { 445 if (bce == NULL) {
447 mutex_unlock(&uwb_beca.mutex); 446 mutex_unlock(&rc->uwb_beca.mutex);
448 return -ENOMEM; 447 return -ENOMEM;
449 } 448 }
450 } 449 }
451 mutex_unlock(&uwb_beca.mutex); 450 mutex_unlock(&rc->uwb_beca.mutex);
452 451
453 mutex_lock(&bce->mutex); 452 mutex_lock(&bce->mutex);
454 /* purge old beacon data */ 453 /* purge old beacon data */