aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-11-29 05:48:15 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-12-02 14:25:17 -0500
commitcf4582875a77c13adf8fec79b8ab3896d2b38e97 (patch)
tree5b56d455abcc3043325897a17a4c6684dc8a3b04
parent8dee77bab2eda24b48bfb8aecf5ac1370e424416 (diff)
brcmfmac: replace dongle command list with .preinit() callback
The bus-specific interface allowed a list of dongle commands to be provided to the common driver part. However, upcoming functionality requires a more dynamic behaviour. Hence the list is replaced by a new callback function so the bus-specific driver part can implement this behaviour. Reviewed-by: Franky Lin <frankyl@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c15
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c58
4 files changed, 51 insertions, 44 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index a129d21498ff..6a54905528be 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
34/** 34/**
35 * struct brcmf_bus_ops - bus callback operations. 35 * struct brcmf_bus_ops - bus callback operations.
36 * 36 *
37 * @preinit: execute bus/device specific dongle init commands (optional).
37 * @init: prepare for communication with dongle. 38 * @init: prepare for communication with dongle.
38 * @stop: clear pending frames, disable data flow. 39 * @stop: clear pending frames, disable data flow.
39 * @txdata: send a data frame to the dongle. When the data 40 * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
51 * indicated otherwise these callbacks are mandatory. 52 * indicated otherwise these callbacks are mandatory.
52 */ 53 */
53struct brcmf_bus_ops { 54struct brcmf_bus_ops {
55 int (*preinit)(struct device *dev);
54 int (*init)(struct device *dev); 56 int (*init)(struct device *dev);
55 void (*stop)(struct device *dev); 57 void (*stop)(struct device *dev);
56 int (*txdata)(struct device *dev, struct sk_buff *skb); 58 int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -85,7 +87,6 @@ struct brcmf_bus {
85 unsigned long tx_realloc; 87 unsigned long tx_realloc;
86 u32 chip; 88 u32 chip;
87 u32 chiprev; 89 u32 chiprev;
88 struct list_head dcmd_list;
89 90
90 struct brcmf_bus_ops *ops; 91 struct brcmf_bus_ops *ops;
91}; 92};
@@ -93,6 +94,13 @@ struct brcmf_bus {
93/* 94/*
94 * callback wrappers 95 * callback wrappers
95 */ 96 */
97static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
98{
99 if (!bus->ops->preinit)
100 return 0;
101 return bus->ops->preinit(bus->dev);
102}
103
96static inline int brcmf_bus_init(struct brcmf_bus *bus) 104static inline int brcmf_bus_init(struct brcmf_bus *bus)
97{ 105{
98 return bus->ops->init(bus->dev); 106 return bus->ops->init(bus->dev);
@@ -151,6 +159,8 @@ void brcmf_txflowblock(struct device *dev, bool state);
151void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 159void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
152 160
153int brcmf_bus_start(struct device *dev); 161int brcmf_bus_start(struct device *dev);
162s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
163 u32 len);
154void brcmf_bus_add_txhdrlen(struct device *dev, uint len); 164void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
155 165
156#ifdef CONFIG_BRCMFMAC_SDIO 166#ifdef CONFIG_BRCMFMAC_SDIO
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 9431af2465f3..5c0c9191b794 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
257 u8 buf[BRCMF_DCMD_SMLEN]; 257 u8 buf[BRCMF_DCMD_SMLEN];
258 char *ptr; 258 char *ptr;
259 s32 err; 259 s32 err;
260 struct brcmf_bus_dcmd *cmdlst;
261 struct list_head *cur, *q;
262 260
263 /* retreive mac address */ 261 /* retreive mac address */
264 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, 262 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -342,17 +340,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
342 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, 340 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
343 0, true); 341 0, true);
344 342
345 /* set bus specific command if there is any */ 343 /* do bus specific preinit here */
346 list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { 344 err = brcmf_bus_preinit(ifp->drvr->bus_if);
347 cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
348 if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
349 brcmf_fil_iovar_data_set(ifp, cmdlst->name,
350 cmdlst->param,
351 cmdlst->param_len);
352 }
353 list_del(cur);
354 kfree(cmdlst);
355 }
356done: 345done:
357 return err; 346 return err;
358} 347}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 0c4c2306647d..ab207e22e515 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1048,8 +1048,6 @@ int brcmf_attach(struct device *dev)
1048 /* attach firmware event handler */ 1048 /* attach firmware event handler */
1049 brcmf_fweh_attach(drvr); 1049 brcmf_fweh_attach(drvr);
1050 1050
1051 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
1052
1053 return ret; 1051 return ret;
1054 1052
1055fail: 1053fail:
@@ -1206,6 +1204,14 @@ void brcmf_detach(struct device *dev)
1206 kfree(drvr); 1204 kfree(drvr);
1207} 1205}
1208 1206
1207s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
1208{
1209 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1210 struct brcmf_if *ifp = bus_if->drvr->iflist[0];
1211
1212 return brcmf_fil_iovar_data_set(ifp, name, data, len);
1213}
1214
1209static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp) 1215static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1210{ 1216{
1211 return atomic_read(&ifp->pend_8021x_cnt); 1217 return atomic_read(&ifp->pend_8021x_cnt);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 928983be800b..2597a534e694 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3425,6 +3425,35 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3425 return ret; 3425 return ret;
3426} 3426}
3427 3427
3428static int brcmf_sdbrcm_bus_preinit(struct device *dev)
3429{
3430 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3431 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3432 struct brcmf_sdio *bus = sdiodev->bus;
3433 u32 value;
3434 u8 idx;
3435 int err;
3436
3437 /* sdio bus core specific dcmd */
3438 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
3439 if (bus->ci->c_inf[idx].rev < 12) {
3440 /* for sdio core rev < 12, disable txgloming */
3441 value = 0;
3442 err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
3443 sizeof(u32));
3444 } else {
3445 /* otherwise, set txglomalign */
3446 value = 4;
3447 if (sdiodev->pdata)
3448 value = sdiodev->pdata->sd_sgentry_align;
3449 /* SDIO ADMA requires at least 32 bit alignment */
3450 value = max_t(u32, value, 4);
3451 err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
3452 sizeof(u32));
3453 }
3454 return err;
3455}
3456
3428static int brcmf_sdbrcm_bus_init(struct device *dev) 3457static int brcmf_sdbrcm_bus_init(struct device *dev)
3429{ 3458{
3430 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 3459 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -3905,6 +3934,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3905 3934
3906static struct brcmf_bus_ops brcmf_sdio_bus_ops = { 3935static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3907 .stop = brcmf_sdbrcm_bus_stop, 3936 .stop = brcmf_sdbrcm_bus_stop,
3937 .preinit = brcmf_sdbrcm_bus_preinit,
3908 .init = brcmf_sdbrcm_bus_init, 3938 .init = brcmf_sdbrcm_bus_init,
3909 .txdata = brcmf_sdbrcm_bus_txdata, 3939 .txdata = brcmf_sdbrcm_bus_txdata,
3910 .txctl = brcmf_sdbrcm_bus_txctl, 3940 .txctl = brcmf_sdbrcm_bus_txctl,
@@ -3916,10 +3946,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3916{ 3946{
3917 int ret; 3947 int ret;
3918 struct brcmf_sdio *bus; 3948 struct brcmf_sdio *bus;
3919 struct brcmf_bus_dcmd *dlst;
3920 u32 dngl_txglom;
3921 u32 txglomalign = 0;
3922 u8 idx;
3923 3949
3924 brcmf_dbg(TRACE, "Enter\n"); 3950 brcmf_dbg(TRACE, "Enter\n");
3925 3951
@@ -4003,30 +4029,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4003 brcmf_sdio_debugfs_create(bus); 4029 brcmf_sdio_debugfs_create(bus);
4004 brcmf_dbg(INFO, "completed!!\n"); 4030 brcmf_dbg(INFO, "completed!!\n");
4005 4031
4006 /* sdio bus core specific dcmd */
4007 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
4008 dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
4009 if (dlst) {
4010 if (bus->ci->c_inf[idx].rev < 12) {
4011 /* for sdio core rev < 12, disable txgloming */
4012 dngl_txglom = 0;
4013 dlst->name = "bus:txglom";
4014 dlst->param = (char *)&dngl_txglom;
4015 dlst->param_len = sizeof(u32);
4016 } else {
4017 /* otherwise, set txglomalign */
4018 if (sdiodev->pdata)
4019 txglomalign = sdiodev->pdata->sd_sgentry_align;
4020 /* SDIO ADMA requires at least 32 bit alignment */
4021 if (txglomalign < 4)
4022 txglomalign = 4;
4023 dlst->name = "bus:txglomalign";
4024 dlst->param = (char *)&txglomalign;
4025 dlst->param_len = sizeof(u32);
4026 }
4027 list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
4028 }
4029
4030 brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); 4032 brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
4031 4033
4032 /* if firmware path present try to download and bring up bus */ 4034 /* if firmware path present try to download and bring up bus */