diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-03 06:40:33 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-03 15:07:04 -0400 |
commit | fba1400a9b8149b3c7ee02be3b1ea0429912372e (patch) | |
tree | ea9912614123763ca8e26e74c629b85f77c7a53c /drivers | |
parent | 43fa635e16c0674c9248b7feb271084c2874bb0a (diff) |
brcmfmac: add firmware-signalling cleanup function
Add a cleanup function releasing any queued packet buffers in
the mac descriptor entries.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Piotr Haber <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 542a971539b2..69f460b1a4e0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
@@ -197,6 +197,7 @@ struct brcmf_fws_info { | |||
197 | struct brcmf_pub *drvr; | 197 | struct brcmf_pub *drvr; |
198 | struct brcmf_fws_stats stats; | 198 | struct brcmf_fws_stats stats; |
199 | struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE]; | 199 | struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE]; |
200 | struct brcmf_fws_mac_descriptor other; | ||
200 | int fifo_credit[NL80211_NUM_ACS+1+1]; | 201 | int fifo_credit[NL80211_NUM_ACS+1+1]; |
201 | }; | 202 | }; |
202 | 203 | ||
@@ -264,6 +265,38 @@ brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea) | |||
264 | return ERR_PTR(-ENOENT); | 265 | return ERR_PTR(-ENOENT); |
265 | } | 266 | } |
266 | 267 | ||
268 | static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_mac_descriptor *entry, | ||
269 | bool (*fn)(struct sk_buff *, void *), | ||
270 | int ifidx) | ||
271 | { | ||
272 | brcmf_dbg(TRACE, "enter: entry=(ea=%pM,ifid=%d), ifidx=%d\n", | ||
273 | entry->ea, entry->interface_id, ifidx); | ||
274 | if (entry->occupied && (fn == NULL || (ifidx == entry->interface_id))) { | ||
275 | brcmf_dbg(TRACE, "flush delayQ: ifidx=%d, qlen=%d\n", | ||
276 | ifidx, entry->psq.len); | ||
277 | /* release packets held in DELAYQ */ | ||
278 | brcmu_pktq_flush(&entry->psq, true, fn, &ifidx); | ||
279 | entry->occupied = !!(entry->psq.len); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx) | ||
284 | { | ||
285 | int i; | ||
286 | struct brcmf_fws_mac_descriptor *table; | ||
287 | |||
288 | brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx); | ||
289 | if (fws == NULL) | ||
290 | return; | ||
291 | |||
292 | /* cleanup individual nodes */ | ||
293 | table = &fws->nodes[0]; | ||
294 | for (i = 0; i < ARRAY_SIZE(fws->nodes); i++) | ||
295 | brcmf_fws_mac_desc_cleanup(&table[i], NULL, ifidx); | ||
296 | |||
297 | brcmf_fws_mac_desc_cleanup(&fws->other, NULL, ifidx); | ||
298 | } | ||
299 | |||
267 | static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) | 300 | static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) |
268 | { | 301 | { |
269 | brcmf_dbg(CTL, "rssi %d\n", rssi); | 302 | brcmf_dbg(CTL, "rssi %d\n", rssi); |
@@ -394,12 +427,12 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
394 | goto fail; | 427 | goto fail; |
395 | } | 428 | } |
396 | 429 | ||
397 | /* set linkage back */ | ||
398 | drvr->fws->drvr = drvr; | ||
399 | |||
400 | /* create debugfs file for statistics */ | 430 | /* create debugfs file for statistics */ |
401 | brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats); | 431 | brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats); |
402 | 432 | ||
433 | /* set linkage back */ | ||
434 | drvr->fws->drvr = drvr; | ||
435 | |||
403 | /* TODO: remove upon feature delivery */ | 436 | /* TODO: remove upon feature delivery */ |
404 | brcmf_err("%s bdcv2 tlv signaling [%x]\n", | 437 | brcmf_err("%s bdcv2 tlv signaling [%x]\n", |
405 | drvr->fw_signals ? "enabled" : "disabled", tlv); | 438 | drvr->fw_signals ? "enabled" : "disabled", tlv); |
@@ -414,9 +447,17 @@ fail: | |||
414 | 447 | ||
415 | void brcmf_fws_deinit(struct brcmf_pub *drvr) | 448 | void brcmf_fws_deinit(struct brcmf_pub *drvr) |
416 | { | 449 | { |
417 | /* free top structure */ | 450 | struct brcmf_fws_info *fws = drvr->fws; |
418 | kfree(drvr->fws); | 451 | ulong flags; |
452 | |||
453 | /* cleanup */ | ||
454 | brcmf_fws_lock(drvr, flags); | ||
455 | brcmf_fws_cleanup(fws, -1); | ||
419 | drvr->fws = NULL; | 456 | drvr->fws = NULL; |
457 | brcmf_fws_unlock(drvr, flags); | ||
458 | |||
459 | /* free top structure */ | ||
460 | kfree(fws); | ||
420 | } | 461 | } |
421 | 462 | ||
422 | int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | 463 | int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, |