aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-03 06:40:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-03 15:07:04 -0400
commitfba1400a9b8149b3c7ee02be3b1ea0429912372e (patch)
treeea9912614123763ca8e26e74c629b85f77c7a53c /drivers
parent43fa635e16c0674c9248b7feb271084c2874bb0a (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.c51
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
268static 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
283static 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
267static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) 300static 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
415void brcmf_fws_deinit(struct brcmf_pub *drvr) 448void 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
422int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, 463int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,