diff options
author | Stefano Panella <stefano.panella@csr.com> | 2008-11-04 10:39:08 -0500 |
---|---|---|
committer | David Vrabel <david.vrabel@csr.com> | 2008-11-04 10:55:26 -0500 |
commit | fec1a5932f16c0eb1b3f5ca2e18d81d860924088 (patch) | |
tree | 48836158dbd458bb462b18f4deffa89e9db80376 /drivers/uwb/beacon.c | |
parent | 6d5a681dfb583b2f1eefe7cd5505419ca2d4d6c8 (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.c | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index ad823987cede..d9f2a8acc593 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 | ||
171 | struct uwb_beca uwb_beca = { | ||
172 | .list = LIST_HEAD_INIT(uwb_beca.list), | ||
173 | .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex) | ||
174 | }; | ||
175 | |||
176 | |||
177 | void uwb_bce_kfree(struct kref *_bce) | 171 | void 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 */ |
187 | static | 181 | static |
188 | struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) | 182 | struct 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 */ |
204 | static | 199 | static |
205 | struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) | 200 | struct 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 | */ |
277 | struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, | 273 | static |
274 | struct 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 | */ |
298 | void uwb_beca_purge(void) | 296 | void 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 */ |
316 | void uwb_beca_release(void) | 314 | void 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 | ||
327 | static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, | 326 | static 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 */ |