aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChung-Hsien Hsu <stanley.hsu@cypress.com>2017-11-10 04:27:15 -0500
committerKalle Valo <kvalo@codeaurora.org>2017-11-10 20:04:09 -0500
commitfdd0bd88ceaecf729db103ac8836af5805dd2dc1 (patch)
tree83676889c062a8f8a96329758dd61d47ba9a8648
parent4775ae7afec62e6ae1bc1f99ab57db2a36b8807e (diff)
brcmfmac: add CLM download support
The firmware for brcmfmac devices includes information regarding regulatory constraints. For certain devices this information is kept separately in a binary form that needs to be downloaded to the device. This patch adds support to download this so-called CLM blob file. It uses the same naming scheme as the other firmware files with extension of .clm_blob. The CLM blob file is optional. If the file does not exist, the download process will be bypassed. It will not affect the driver loading. Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c157
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h31
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c19
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c19
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c18
8 files changed, 258 insertions, 0 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 163ddc49f951..0b76a615708e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd {
71 * @wowl_config: specify if dongle is configured for wowl when going to suspend 71 * @wowl_config: specify if dongle is configured for wowl when going to suspend
72 * @get_ramsize: obtain size of device memory. 72 * @get_ramsize: obtain size of device memory.
73 * @get_memdump: obtain device memory dump in provided buffer. 73 * @get_memdump: obtain device memory dump in provided buffer.
74 * @get_fwname: obtain firmware name.
74 * 75 *
75 * This structure provides an abstract interface towards the 76 * This structure provides an abstract interface towards the
76 * bus specific driver. For control messages to common driver 77 * bus specific driver. For control messages to common driver
@@ -87,6 +88,8 @@ struct brcmf_bus_ops {
87 void (*wowl_config)(struct device *dev, bool enabled); 88 void (*wowl_config)(struct device *dev, bool enabled);
88 size_t (*get_ramsize)(struct device *dev); 89 size_t (*get_ramsize)(struct device *dev);
89 int (*get_memdump)(struct device *dev, void *data, size_t len); 90 int (*get_memdump)(struct device *dev, void *data, size_t len);
91 int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
92 unsigned char *fw_name);
90}; 93};
91 94
92 95
@@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
224 return bus->ops->get_memdump(bus->dev, data, len); 227 return bus->ops->get_memdump(bus->dev, data, len);
225} 228}
226 229
230static inline
231int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
232 unsigned char *fw_name)
233{
234 return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
235}
236
227/* 237/*
228 * interface functions from common layer 238 * interface functions from common layer
229 */ 239 */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 7a2b49587b4d..6a59d0609d30 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -18,6 +18,7 @@
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/firmware.h>
21#include <brcmu_wifi.h> 22#include <brcmu_wifi.h>
22#include <brcmu_utils.h> 23#include <brcmu_utils.h>
23#include "core.h" 24#include "core.h"
@@ -28,6 +29,7 @@
28#include "tracepoint.h" 29#include "tracepoint.h"
29#include "common.h" 30#include "common.h"
30#include "of.h" 31#include "of.h"
32#include "firmware.h"
31 33
32MODULE_AUTHOR("Broadcom Corporation"); 34MODULE_AUTHOR("Broadcom Corporation");
33MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); 35MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
104 brcmf_err("Set join_pref error (%d)\n", err); 106 brcmf_err("Set join_pref error (%d)\n", err);
105} 107}
106 108
109static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
110 struct brcmf_dload_data_le *dload_buf,
111 u32 len)
112{
113 s32 err;
114
115 flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
116 dload_buf->flag = cpu_to_le16(flag);
117 dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
118 dload_buf->len = cpu_to_le32(len);
119 dload_buf->crc = cpu_to_le32(0);
120 len = sizeof(*dload_buf) + len - 1;
121
122 err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
123
124 return err;
125}
126
127static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
128{
129 struct brcmf_bus *bus = ifp->drvr->bus_if;
130 struct brcmf_rev_info *ri = &ifp->drvr->revinfo;
131 u8 fw_name[BRCMF_FW_NAME_LEN];
132 u8 *ptr;
133 size_t len;
134 s32 err;
135
136 memset(fw_name, 0, BRCMF_FW_NAME_LEN);
137 err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name);
138 if (err) {
139 brcmf_err("get firmware name failed (%d)\n", err);
140 goto done;
141 }
142
143 /* generate CLM blob file name */
144 ptr = strrchr(fw_name, '.');
145 if (!ptr) {
146 err = -ENOENT;
147 goto done;
148 }
149
150 len = ptr - fw_name + 1;
151 if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
152 err = -E2BIG;
153 } else {
154 strlcpy(clm_name, fw_name, len);
155 strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
156 }
157done:
158 return err;
159}
160
161static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
162{
163 struct device *dev = ifp->drvr->bus_if->dev;
164 struct brcmf_dload_data_le *chunk_buf;
165 const struct firmware *clm = NULL;
166 u8 clm_name[BRCMF_FW_NAME_LEN];
167 u32 chunk_len;
168 u32 datalen;
169 u32 cumulative_len;
170 u16 dl_flag = DL_BEGIN;
171 u32 status;
172 s32 err;
173
174 brcmf_dbg(TRACE, "Enter\n");
175
176 memset(clm_name, 0, BRCMF_FW_NAME_LEN);
177 err = brcmf_c_get_clm_name(ifp, clm_name);
178 if (err) {
179 brcmf_err("get CLM blob file name failed (%d)\n", err);
180 return err;
181 }
182
183 err = request_firmware(&clm, clm_name, dev);
184 if (err) {
185 if (err == -ENOENT) {
186 brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n");
187 return 0;
188 }
189 brcmf_err("request CLM blob file failed (%d)\n", err);
190 return err;
191 }
192
193 chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
194 if (!chunk_buf) {
195 err = -ENOMEM;
196 goto done;
197 }
198
199 datalen = clm->size;
200 cumulative_len = 0;
201 do {
202 if (datalen > MAX_CHUNK_LEN) {
203 chunk_len = MAX_CHUNK_LEN;
204 } else {
205 chunk_len = datalen;
206 dl_flag |= DL_END;
207 }
208 memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
209
210 err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
211
212 dl_flag &= ~DL_BEGIN;
213
214 cumulative_len += chunk_len;
215 datalen -= chunk_len;
216 } while ((datalen > 0) && (err == 0));
217
218 if (err) {
219 brcmf_err("clmload (%zu byte file) failed (%d); ",
220 clm->size, err);
221 /* Retrieve clmload_status and print */
222 err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
223 if (err)
224 brcmf_err("get clmload_status failed (%d)\n", err);
225 else
226 brcmf_dbg(INFO, "clmload_status=%d\n", status);
227 err = -EIO;
228 }
229
230 kfree(chunk_buf);
231done:
232 release_firmware(clm);
233 return err;
234}
235
107int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) 236int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
108{ 237{
109 s8 eventmask[BRCMF_EVENTING_MASK_LEN]; 238 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
110 u8 buf[BRCMF_DCMD_SMLEN]; 239 u8 buf[BRCMF_DCMD_SMLEN];
111 struct brcmf_rev_info_le revinfo; 240 struct brcmf_rev_info_le revinfo;
112 struct brcmf_rev_info *ri; 241 struct brcmf_rev_info *ri;
242 char *clmver;
113 char *ptr; 243 char *ptr;
114 s32 err; 244 s32 err;
115 245
@@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
148 } 278 }
149 ri->result = err; 279 ri->result = err;
150 280
281 /* Do any CLM downloading */
282 err = brcmf_c_process_clm_blob(ifp);
283 if (err < 0) {
284 brcmf_err("download CLM blob file failed, %d\n", err);
285 goto done;
286 }
287
151 /* query for 'ver' to get version info from firmware */ 288 /* query for 'ver' to get version info from firmware */
152 memset(buf, 0, sizeof(buf)); 289 memset(buf, 0, sizeof(buf));
153 strcpy(buf, "ver"); 290 strcpy(buf, "ver");
@@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
167 ptr = strrchr(buf, ' ') + 1; 304 ptr = strrchr(buf, ' ') + 1;
168 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); 305 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
169 306
307 /* Query for 'clmver' to get CLM version info from firmware */
308 memset(buf, 0, sizeof(buf));
309 err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
310 if (err) {
311 brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
312 } else {
313 clmver = (char *)buf;
314 /* store CLM version for adding it to revinfo debugfs file */
315 memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
316
317 /* Replace all newline/linefeed characters with space
318 * character
319 */
320 ptr = clmver;
321 while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL)
322 *ptr = ' ';
323
324 brcmf_dbg(INFO, "CLM version = %s\n", clmver);
325 }
326
170 /* set mpc */ 327 /* set mpc */
171 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); 328 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
172 if (err) { 329 if (err) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 9c7536daf8f7..930e423f83a8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -988,6 +988,8 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
988 seq_printf(s, "anarev: %u\n", ri->anarev); 988 seq_printf(s, "anarev: %u\n", ri->anarev);
989 seq_printf(s, "nvramrev: %08x\n", ri->nvramrev); 989 seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
990 990
991 seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);
992
991 return 0; 993 return 0;
992} 994}
993 995
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 17085712bae2..df8a1ecb9924 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -141,6 +141,8 @@ struct brcmf_pub {
141 struct notifier_block inetaddr_notifier; 141 struct notifier_block inetaddr_notifier;
142 struct notifier_block inet6addr_notifier; 142 struct notifier_block inet6addr_notifier;
143 struct brcmf_mp_device *settings; 143 struct brcmf_mp_device *settings;
144
145 u8 clmver[BRCMF_DCMD_SMLEN];
144}; 146};
145 147
146/* forward declarations */ 148/* forward declarations */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index e0d22fedb2b4..4b290705e3e6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -155,6 +155,21 @@
155#define BRCMF_MFP_CAPABLE 1 155#define BRCMF_MFP_CAPABLE 1
156#define BRCMF_MFP_REQUIRED 2 156#define BRCMF_MFP_REQUIRED 2
157 157
158/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
159 * ioctl. It is relatively small because firmware has small maximum size input
160 * playload restriction for ioctls.
161 */
162#define MAX_CHUNK_LEN 1400
163
164#define DLOAD_HANDLER_VER 1 /* Downloader version */
165#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
166#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
167
168#define DL_BEGIN 0x0002
169#define DL_END 0x0004
170
171#define DL_TYPE_CLM 2
172
158/* join preference types for join_pref iovar */ 173/* join preference types for join_pref iovar */
159enum brcmf_join_pref_types { 174enum brcmf_join_pref_types {
160 BRCMF_JOIN_PREF_RSSI = 1, 175 BRCMF_JOIN_PREF_RSSI = 1,
@@ -827,6 +842,22 @@ struct brcmf_pno_macaddr_le {
827}; 842};
828 843
829/** 844/**
845 * struct brcmf_dload_data_le - data passing to firmware for downloading
846 * @flag: flags related to download data.
847 * @dload_type: type of download data.
848 * @len: length in bytes of download data.
849 * @crc: crc of download data.
850 * @data: download data.
851 */
852struct brcmf_dload_data_le {
853 __le16 flag;
854 __le16 dload_type;
855 __le32 len;
856 __le32 crc;
857 u8 data[1];
858};
859
860/**
830 * struct brcmf_pno_bssid_le - bssid configuration for PNO scan. 861 * struct brcmf_pno_bssid_le - bssid configuration for PNO scan.
831 * 862 *
832 * @bssid: BSS network identifier. 863 * @bssid: BSS network identifier.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index e6e9b00b79d7..3c87157f5b85 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
1350 return 0; 1350 return 0;
1351} 1351}
1352 1352
1353static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev,
1354 u8 *fw_name)
1355{
1356 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1357 struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
1358 struct brcmf_pciedev_info *devinfo = buspub->devinfo;
1359 int ret = 0;
1360
1361 if (devinfo->fw_name[0] != '\0')
1362 strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
1363 else
1364 ret = brcmf_fw_map_chip_to_name(chip, chiprev,
1365 brcmf_pcie_fwnames,
1366 ARRAY_SIZE(brcmf_pcie_fwnames),
1367 fw_name, NULL);
1368
1369 return ret;
1370}
1353 1371
1354static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { 1372static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
1355 .txdata = brcmf_pcie_tx, 1373 .txdata = brcmf_pcie_tx,
@@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
1359 .wowl_config = brcmf_pcie_wowl_config, 1377 .wowl_config = brcmf_pcie_wowl_config,
1360 .get_ramsize = brcmf_pcie_get_ramsize, 1378 .get_ramsize = brcmf_pcie_get_ramsize,
1361 .get_memdump = brcmf_pcie_get_memdump, 1379 .get_memdump = brcmf_pcie_get_memdump,
1380 .get_fwname = brcmf_pcie_get_fwname,
1362}; 1381};
1363 1382
1364 1383
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 00de73d9e152..b2256aa76eb6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3985,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data)
3985 } 3985 }
3986} 3986}
3987 3987
3988static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev,
3989 u8 *fw_name)
3990{
3991 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3992 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3993 int ret = 0;
3994
3995 if (sdiodev->fw_name[0] != '\0')
3996 strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN);
3997 else
3998 ret = brcmf_fw_map_chip_to_name(chip, chiprev,
3999 brcmf_sdio_fwnames,
4000 ARRAY_SIZE(brcmf_sdio_fwnames),
4001 fw_name, NULL);
4002
4003 return ret;
4004}
4005
3988static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { 4006static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3989 .stop = brcmf_sdio_bus_stop, 4007 .stop = brcmf_sdio_bus_stop,
3990 .preinit = brcmf_sdio_bus_preinit, 4008 .preinit = brcmf_sdio_bus_preinit,
@@ -3995,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3995 .wowl_config = brcmf_sdio_wowl_config, 4013 .wowl_config = brcmf_sdio_wowl_config,
3996 .get_ramsize = brcmf_sdio_bus_get_ramsize, 4014 .get_ramsize = brcmf_sdio_bus_get_ramsize,
3997 .get_memdump = brcmf_sdio_bus_get_memdump, 4015 .get_memdump = brcmf_sdio_bus_get_memdump,
4016 .get_fwname = brcmf_sdio_get_fwname,
3998}; 4017};
3999 4018
4000static void brcmf_sdio_firmware_callback(struct device *dev, int err, 4019static void brcmf_sdio_firmware_callback(struct device *dev, int err,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 11ffaa01599e..b27170c12482 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
1128 device_set_wakeup_enable(devinfo->dev, false); 1128 device_set_wakeup_enable(devinfo->dev, false);
1129} 1129}
1130 1130
1131static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev,
1132 u8 *fw_name)
1133{
1134 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
1135 int ret = 0;
1136
1137 if (devinfo->fw_name[0] != '\0')
1138 strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
1139 else
1140 ret = brcmf_fw_map_chip_to_name(chip, chiprev,
1141 brcmf_usb_fwnames,
1142 ARRAY_SIZE(brcmf_usb_fwnames),
1143 fw_name, NULL);
1144
1145 return ret;
1146}
1147
1131static const struct brcmf_bus_ops brcmf_usb_bus_ops = { 1148static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
1132 .txdata = brcmf_usb_tx, 1149 .txdata = brcmf_usb_tx,
1133 .stop = brcmf_usb_down, 1150 .stop = brcmf_usb_down,
1134 .txctl = brcmf_usb_tx_ctlpkt, 1151 .txctl = brcmf_usb_tx_ctlpkt,
1135 .rxctl = brcmf_usb_rx_ctlpkt, 1152 .rxctl = brcmf_usb_rx_ctlpkt,
1136 .wowl_config = brcmf_usb_wowl_config, 1153 .wowl_config = brcmf_usb_wowl_config,
1154 .get_fwname = brcmf_usb_get_fwname,
1137}; 1155};
1138 1156
1139static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) 1157static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)