aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-03 06:40:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-03 15:07:05 -0400
commite2432b6787a15e0b3c255a017d16033ba30204c0 (patch)
tree120ec7a56fd856db6b7e34b17939e7c8c5990ba1 /drivers/net/wireless
parent6971280aefe437262f6d52339b0b2d5d64ab4e15 (diff)
brcmfmac: add optional bus callback definition for tx queue cleanup
Add a callback to obtain packet queue from the bus-specific code used to cleanup packet buffers from firmware-signalling code. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Piotr Haber <phaber@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c36
3 files changed, 56 insertions, 3 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 883ef9063e8a..080395f49fa5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -39,10 +39,12 @@ struct brcmf_bus_dcmd {
39 * @txdata: send a data frame to the dongle (callee disposes skb). 39 * @txdata: send a data frame to the dongle (callee disposes skb).
40 * @txctl: transmit a control request message to dongle. 40 * @txctl: transmit a control request message to dongle.
41 * @rxctl: receive a control response message from dongle. 41 * @rxctl: receive a control response message from dongle.
42 * @gettxq: obtain a reference of bus transmit queue (optional).
42 * 43 *
43 * This structure provides an abstract interface towards the 44 * This structure provides an abstract interface towards the
44 * bus specific driver. For control messages to common driver 45 * bus specific driver. For control messages to common driver
45 * will assure there is only one active transaction. 46 * will assure there is only one active transaction. Unless
47 * indicated otherwise these callbacks are mandatory.
46 */ 48 */
47struct brcmf_bus_ops { 49struct brcmf_bus_ops {
48 int (*init)(struct device *dev); 50 int (*init)(struct device *dev);
@@ -50,6 +52,7 @@ struct brcmf_bus_ops {
50 int (*txdata)(struct device *dev, struct sk_buff *skb); 52 int (*txdata)(struct device *dev, struct sk_buff *skb);
51 int (*txctl)(struct device *dev, unsigned char *msg, uint len); 53 int (*txctl)(struct device *dev, unsigned char *msg, uint len);
52 int (*rxctl)(struct device *dev, unsigned char *msg, uint len); 54 int (*rxctl)(struct device *dev, unsigned char *msg, uint len);
55 struct pktq * (*gettxq)(struct device *dev);
53}; 56};
54 57
55/** 58/**
@@ -115,6 +118,14 @@ int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len)
115 return bus->ops->rxctl(bus->dev, msg, len); 118 return bus->ops->rxctl(bus->dev, msg, len);
116} 119}
117 120
121static inline
122struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus)
123{
124 if (!bus->ops->gettxq)
125 return ERR_PTR(-ENOENT);
126
127 return bus->ops->gettxq(bus->dev);
128}
118/* 129/*
119 * interface functions from common layer 130 * interface functions from common layer
120 */ 131 */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f5f04ba65e8c..a5354e731eaa 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2293,6 +2293,15 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2293 } 2293 }
2294} 2294}
2295 2295
2296static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev)
2297{
2298 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2299 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2300 struct brcmf_sdio *bus = sdiodev->bus;
2301
2302 return &bus->txq;
2303}
2304
2296static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2305static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2297{ 2306{
2298 int ret = -EBADE; 2307 int ret = -EBADE;
@@ -3834,6 +3843,7 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3834 .txdata = brcmf_sdbrcm_bus_txdata, 3843 .txdata = brcmf_sdbrcm_bus_txdata,
3835 .txctl = brcmf_sdbrcm_bus_txctl, 3844 .txctl = brcmf_sdbrcm_bus_txctl,
3836 .rxctl = brcmf_sdbrcm_bus_rxctl, 3845 .rxctl = brcmf_sdbrcm_bus_rxctl,
3846 .gettxq = brcmf_sdbrcm_bus_gettxq,
3837}; 3847};
3838 3848
3839void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) 3849void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index a6443c667e33..2afd850f22c6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -25,6 +25,7 @@
25#include <brcmu_wifi.h> 25#include <brcmu_wifi.h>
26#include "dhd.h" 26#include "dhd.h"
27#include "dhd_dbg.h" 27#include "dhd_dbg.h"
28#include "dhd_bus.h"
28#include "fwil.h" 29#include "fwil.h"
29#include "fweh.h" 30#include "fweh.h"
30#include "fwsignal.h" 31#include "fwsignal.h"
@@ -236,11 +237,11 @@ struct brcmf_skbuff_cb {
236#define BRCMF_SKB_HTOD_TAG_FREERUN_SHIFT 0 237#define BRCMF_SKB_HTOD_TAG_FREERUN_SHIFT 0
237 238
238#define brcmf_skb_htod_tag_set_field(skb, field, value) \ 239#define brcmf_skb_htod_tag_set_field(skb, field, value) \
239 brcmu_maskset32(&(brcmf_skbcb(skb)->htod_tag), \ 240 brcmu_maskset32(&(brcmf_skbcb(skb)->htod), \
240 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ 241 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
241 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT, (value)) 242 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT, (value))
242#define brcmf_skb_htod_tag_get_field(skb, field) \ 243#define brcmf_skb_htod_tag_get_field(skb, field) \
243 brcmu_maskget32(brcmf_skbcb(skb)->htod_tag, \ 244 brcmu_maskget32(brcmf_skbcb(skb)->htod, \
244 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ 245 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
245 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) 246 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
246 247
@@ -548,6 +549,36 @@ static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_mac_descriptor *entry,
548 } 549 }
549} 550}
550 551
552static void brcmf_fws_bus_txq_cleanup(struct brcmf_fws_info *fws,
553 bool (*fn)(struct sk_buff *, void *),
554 int ifidx)
555{
556 struct brcmf_fws_hanger_item *hi;
557 struct pktq *txq;
558 struct sk_buff *skb;
559 int prec;
560 u32 hslot;
561
562 brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
563 txq = brcmf_bus_gettxq(fws->drvr->bus_if);
564 if (IS_ERR(txq)) {
565 brcmf_dbg(TRACE, "no txq to clean up\n");
566 return;
567 }
568
569 for (prec = 0; prec < txq->num_prec; prec++) {
570 skb = brcmu_pktq_pdeq_match(txq, prec, fn, &ifidx);
571 while (skb) {
572 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
573 hi = &fws->hanger.items[hslot];
574 WARN_ON(skb != hi->pkt);
575 hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
576 brcmu_pkt_buf_free_skb(skb);
577 skb = brcmu_pktq_pdeq_match(txq, prec, fn, &ifidx);
578 }
579 }
580}
581
551static bool brcmf_fws_ifidx_match(struct sk_buff *skb, void *arg) 582static bool brcmf_fws_ifidx_match(struct sk_buff *skb, void *arg)
552{ 583{
553 u32 ifidx = brcmf_skb_if_flags_get_field(skb, INDEX); 584 u32 ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
@@ -573,6 +604,7 @@ static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
573 brcmf_fws_mac_desc_cleanup(&table[i], matchfn, ifidx); 604 brcmf_fws_mac_desc_cleanup(&table[i], matchfn, ifidx);
574 605
575 brcmf_fws_mac_desc_cleanup(&fws->other, matchfn, ifidx); 606 brcmf_fws_mac_desc_cleanup(&fws->other, matchfn, ifidx);
607 brcmf_fws_bus_txq_cleanup(fws, matchfn, ifidx);
576 brcmf_fws_hanger_cleanup(&fws->hanger, matchfn, ifidx); 608 brcmf_fws_hanger_cleanup(&fws->hanger, matchfn, ifidx);
577} 609}
578 610