2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/netdevice.h>
20 #include <linux/module.h>
21 #include <linux/firmware.h>
22 #include <brcmu_wifi.h>
23 #include <brcmu_utils.h>
28 #include "fwil_types.h"
29 #include "tracepoint.h"
34 MODULE_AUTHOR("Broadcom Corporation");
35 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
36 MODULE_LICENSE("Dual BSD/GPL");
38 const u8 ALLFFMAC
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
40 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
41 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
43 /* default boost value for RSSI_DELTA in preferred join selection */
44 #define BRCMF_JOIN_PREF_RSSI_BOOST 8
46 #define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
48 static int brcmf_sdiod_txglomsz
= BRCMF_DEFAULT_TXGLOM_SIZE
;
49 module_param_named(txglomsz
, brcmf_sdiod_txglomsz
, int, 0);
50 MODULE_PARM_DESC(txglomsz
, "Maximum tx packet chain size [SDIO]");
52 /* Debug level configuration. See debug.h for bits, sysfs modifiable */
54 module_param_named(debug
, brcmf_msg_level
, int, S_IRUSR
| S_IWUSR
);
55 MODULE_PARM_DESC(debug
, "Level of debug output");
57 static int brcmf_p2p_enable
;
58 module_param_named(p2pon
, brcmf_p2p_enable
, int, 0);
59 MODULE_PARM_DESC(p2pon
, "Enable legacy p2p management functionality");
61 static int brcmf_feature_disable
;
62 module_param_named(feature_disable
, brcmf_feature_disable
, int, 0);
63 MODULE_PARM_DESC(feature_disable
, "Disable features");
65 static char brcmf_firmware_path
[BRCMF_FW_ALTPATH_LEN
];
66 module_param_string(alternative_fw_path
, brcmf_firmware_path
,
67 BRCMF_FW_ALTPATH_LEN
, S_IRUSR
);
68 MODULE_PARM_DESC(alternative_fw_path
, "Alternative firmware path");
70 static int brcmf_fcmode
;
71 module_param_named(fcmode
, brcmf_fcmode
, int, 0);
72 MODULE_PARM_DESC(fcmode
, "Mode of firmware signalled flow control");
74 static int brcmf_roamoff
;
75 module_param_named(roamoff
, brcmf_roamoff
, int, S_IRUSR
);
76 MODULE_PARM_DESC(roamoff
, "Do not use internal roaming engine");
79 /* always succeed brcmf_bus_started() */
80 static int brcmf_ignore_probe_fail
;
81 module_param_named(ignore_probe_fail
, brcmf_ignore_probe_fail
, int, 0);
82 MODULE_PARM_DESC(ignore_probe_fail
, "always succeed probe for debugging");
85 static struct brcmfmac_platform_data
*brcmfmac_pdata
;
86 struct brcmf_mp_global_t brcmf_mp_global
;
88 void brcmf_c_set_joinpref_default(struct brcmf_if
*ifp
)
90 struct brcmf_join_pref_params join_pref_params
[2];
93 /* Setup join_pref to select target by RSSI (boost on 5GHz) */
94 join_pref_params
[0].type
= BRCMF_JOIN_PREF_RSSI_DELTA
;
95 join_pref_params
[0].len
= 2;
96 join_pref_params
[0].rssi_gain
= BRCMF_JOIN_PREF_RSSI_BOOST
;
97 join_pref_params
[0].band
= WLC_BAND_5G
;
99 join_pref_params
[1].type
= BRCMF_JOIN_PREF_RSSI
;
100 join_pref_params
[1].len
= 2;
101 join_pref_params
[1].rssi_gain
= 0;
102 join_pref_params
[1].band
= 0;
103 err
= brcmf_fil_iovar_data_set(ifp
, "join_pref", join_pref_params
,
104 sizeof(join_pref_params
));
106 brcmf_err("Set join_pref error (%d)\n", err
);
109 static int brcmf_c_download(struct brcmf_if
*ifp
, u16 flag
,
110 struct brcmf_dload_data_le
*dload_buf
,
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;
122 err
= brcmf_fil_iovar_data_set(ifp
, "clmload", dload_buf
, len
);
127 static int brcmf_c_get_clm_name(struct brcmf_if
*ifp
, u8
*clm_name
)
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
];
136 memset(fw_name
, 0, BRCMF_FW_NAME_LEN
);
137 err
= brcmf_bus_get_fwname(bus
, ri
->chipnum
, ri
->chiprev
, fw_name
);
139 brcmf_err("get firmware name failed (%d)\n", err
);
143 /* generate CLM blob file name */
144 ptr
= strrchr(fw_name
, '.');
150 len
= ptr
- fw_name
+ 1;
151 if (len
+ strlen(".clm_blob") > BRCMF_FW_NAME_LEN
) {
154 strlcpy(clm_name
, fw_name
, len
);
155 strlcat(clm_name
, ".clm_blob", BRCMF_FW_NAME_LEN
);
161 static int brcmf_c_process_clm_blob(struct brcmf_if
*ifp
)
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
];
170 u16 dl_flag
= DL_BEGIN
;
174 brcmf_dbg(TRACE
, "Enter\n");
176 memset(clm_name
, 0, BRCMF_FW_NAME_LEN
);
177 err
= brcmf_c_get_clm_name(ifp
, clm_name
);
179 brcmf_err("get CLM blob file name failed (%d)\n", err
);
183 err
= request_firmware(&clm
, clm_name
, dev
);
185 brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n",
190 chunk_buf
= kzalloc(sizeof(*chunk_buf
) + MAX_CHUNK_LEN
- 1, GFP_KERNEL
);
199 if (datalen
> MAX_CHUNK_LEN
) {
200 chunk_len
= MAX_CHUNK_LEN
;
205 memcpy(chunk_buf
->data
, clm
->data
+ cumulative_len
, chunk_len
);
207 err
= brcmf_c_download(ifp
, dl_flag
, chunk_buf
, chunk_len
);
209 dl_flag
&= ~DL_BEGIN
;
211 cumulative_len
+= chunk_len
;
212 datalen
-= chunk_len
;
213 } while ((datalen
> 0) && (err
== 0));
216 brcmf_err("clmload (%zu byte file) failed (%d); ",
218 /* Retrieve clmload_status and print */
219 err
= brcmf_fil_iovar_int_get(ifp
, "clmload_status", &status
);
221 brcmf_err("get clmload_status failed (%d)\n", err
);
223 brcmf_dbg(INFO
, "clmload_status=%d\n", status
);
229 release_firmware(clm
);
233 int brcmf_c_preinit_dcmds(struct brcmf_if
*ifp
)
235 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
236 u8 buf
[BRCMF_DCMD_SMLEN
];
237 struct brcmf_rev_info_le revinfo
;
238 struct brcmf_rev_info
*ri
;
243 /* retreive mac address */
244 err
= brcmf_fil_iovar_data_get(ifp
, "cur_etheraddr", ifp
->mac_addr
,
245 sizeof(ifp
->mac_addr
));
247 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err
);
250 memcpy(ifp
->drvr
->mac
, ifp
->mac_addr
, sizeof(ifp
->drvr
->mac
));
252 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_REVINFO
,
253 &revinfo
, sizeof(revinfo
));
254 ri
= &ifp
->drvr
->revinfo
;
256 brcmf_err("retrieving revision info failed, %d\n", err
);
258 ri
->vendorid
= le32_to_cpu(revinfo
.vendorid
);
259 ri
->deviceid
= le32_to_cpu(revinfo
.deviceid
);
260 ri
->radiorev
= le32_to_cpu(revinfo
.radiorev
);
261 ri
->chiprev
= le32_to_cpu(revinfo
.chiprev
);
262 ri
->corerev
= le32_to_cpu(revinfo
.corerev
);
263 ri
->boardid
= le32_to_cpu(revinfo
.boardid
);
264 ri
->boardvendor
= le32_to_cpu(revinfo
.boardvendor
);
265 ri
->boardrev
= le32_to_cpu(revinfo
.boardrev
);
266 ri
->driverrev
= le32_to_cpu(revinfo
.driverrev
);
267 ri
->ucoderev
= le32_to_cpu(revinfo
.ucoderev
);
268 ri
->bus
= le32_to_cpu(revinfo
.bus
);
269 ri
->chipnum
= le32_to_cpu(revinfo
.chipnum
);
270 ri
->phytype
= le32_to_cpu(revinfo
.phytype
);
271 ri
->phyrev
= le32_to_cpu(revinfo
.phyrev
);
272 ri
->anarev
= le32_to_cpu(revinfo
.anarev
);
273 ri
->chippkg
= le32_to_cpu(revinfo
.chippkg
);
274 ri
->nvramrev
= le32_to_cpu(revinfo
.nvramrev
);
278 /* Do any CLM downloading */
279 err
= brcmf_c_process_clm_blob(ifp
);
281 brcmf_err("download CLM blob file failed, %d\n", err
);
285 /* query for 'ver' to get version info from firmware */
286 memset(buf
, 0, sizeof(buf
));
288 err
= brcmf_fil_iovar_data_get(ifp
, "ver", buf
, sizeof(buf
));
290 brcmf_err("Retreiving version information failed, %d\n",
297 /* Print fw version info */
298 brcmf_info("Firmware version = %s\n", buf
);
300 /* locate firmware version number for ethtool */
301 ptr
= strrchr(buf
, ' ') + 1;
302 strlcpy(ifp
->drvr
->fwver
, ptr
, sizeof(ifp
->drvr
->fwver
));
304 /* Query for 'clmver' to get CLM version info from firmware */
305 memset(buf
, 0, sizeof(buf
));
306 err
= brcmf_fil_iovar_data_get(ifp
, "clmver", buf
, sizeof(buf
));
308 brcmf_dbg(TRACE
, "retrieving clmver failed, %d\n", err
);
310 clmver
= (char *)buf
;
311 /* store CLM version for adding it to revinfo debugfs file */
312 memcpy(ifp
->drvr
->clmver
, clmver
, sizeof(ifp
->drvr
->clmver
));
314 /* Replace all newline/linefeed characters with space
318 while ((ptr
= strnchr(ptr
, '\n', sizeof(buf
))) != NULL
)
321 brcmf_dbg(INFO
, "CLM version = %s\n", clmver
);
325 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", 1);
327 brcmf_err("failed setting mpc\n");
331 brcmf_c_set_joinpref_default(ifp
);
333 /* Setup event_msgs, enable E_IF */
334 err
= brcmf_fil_iovar_data_get(ifp
, "event_msgs", eventmask
,
335 BRCMF_EVENTING_MASK_LEN
);
337 brcmf_err("Get event_msgs error (%d)\n", err
);
340 setbit(eventmask
, BRCMF_E_IF
);
341 err
= brcmf_fil_iovar_data_set(ifp
, "event_msgs", eventmask
,
342 BRCMF_EVENTING_MASK_LEN
);
344 brcmf_err("Set event_msgs error (%d)\n", err
);
348 /* Setup default scan channel time */
349 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
350 BRCMF_DEFAULT_SCAN_CHANNEL_TIME
);
352 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
357 /* Setup default scan unassoc time */
358 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
359 BRCMF_DEFAULT_SCAN_UNASSOC_TIME
);
361 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
366 /* Enable tx beamforming, errors can be ignored (not supported) */
367 (void)brcmf_fil_iovar_int_set(ifp
, "txbf", 1);
369 /* do bus specific preinit here */
370 err
= brcmf_bus_preinit(ifp
->drvr
->bus_if
);
375 #ifndef CONFIG_BRCM_TRACING
376 void __brcmf_err(const char *func
, const char *fmt
, ...)
378 struct va_format vaf
;
385 pr_err("%s: %pV", func
, &vaf
);
391 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
392 void __brcmf_dbg(u32 level
, const char *func
, const char *fmt
, ...)
394 struct va_format vaf
= {
401 if (brcmf_msg_level
& level
)
402 pr_debug("%s %pV", func
, &vaf
);
403 trace_brcmf_dbg(level
, func
, &vaf
);
408 static void brcmf_mp_attach(void)
410 /* If module param firmware path is set then this will always be used,
411 * if not set then if available use the platform data version. To make
412 * sure it gets initialized at all, always copy the module param version
414 strlcpy(brcmf_mp_global
.firmware_path
, brcmf_firmware_path
,
415 BRCMF_FW_ALTPATH_LEN
);
416 if ((brcmfmac_pdata
) && (brcmfmac_pdata
->fw_alternative_path
) &&
417 (brcmf_mp_global
.firmware_path
[0] == '\0')) {
418 strlcpy(brcmf_mp_global
.firmware_path
,
419 brcmfmac_pdata
->fw_alternative_path
,
420 BRCMF_FW_ALTPATH_LEN
);
424 struct brcmf_mp_device
*brcmf_get_module_param(struct device
*dev
,
425 enum brcmf_bus_type bus_type
,
426 u32 chip
, u32 chiprev
)
428 struct brcmf_mp_device
*settings
;
429 struct brcmfmac_pd_device
*device_pd
;
433 brcmf_dbg(INFO
, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type
, chip
,
435 settings
= kzalloc(sizeof(*settings
), GFP_ATOMIC
);
439 /* start by using the module paramaters */
440 settings
->p2p_enable
= !!brcmf_p2p_enable
;
441 settings
->feature_disable
= brcmf_feature_disable
;
442 settings
->fcmode
= brcmf_fcmode
;
443 settings
->roamoff
= !!brcmf_roamoff
;
445 settings
->ignore_probe_fail
= !!brcmf_ignore_probe_fail
;
448 if (bus_type
== BRCMF_BUSTYPE_SDIO
)
449 settings
->bus
.sdio
.txglomsz
= brcmf_sdiod_txglomsz
;
451 /* See if there is any device specific platform data configured */
453 if (brcmfmac_pdata
) {
454 for (i
= 0; i
< brcmfmac_pdata
->device_count
; i
++) {
455 device_pd
= &brcmfmac_pdata
->devices
[i
];
456 if ((device_pd
->bus_type
== bus_type
) &&
457 (device_pd
->id
== chip
) &&
458 ((device_pd
->rev
== chiprev
) ||
459 (device_pd
->rev
== -1))) {
460 brcmf_dbg(INFO
, "Platform data for device found\n");
461 settings
->country_codes
=
462 device_pd
->country_codes
;
463 if (device_pd
->bus_type
== BRCMF_BUSTYPE_SDIO
)
464 memcpy(&settings
->bus
.sdio
,
465 &device_pd
->bus
.sdio
,
466 sizeof(settings
->bus
.sdio
));
473 /* No platform data for this device, try OF (Open Firwmare) */
474 brcmf_of_probe(dev
, bus_type
, settings
);
479 void brcmf_release_module_param(struct brcmf_mp_device
*module_param
)
484 static int __init
brcmf_common_pd_probe(struct platform_device
*pdev
)
486 brcmf_dbg(INFO
, "Enter\n");
488 brcmfmac_pdata
= dev_get_platdata(&pdev
->dev
);
490 if (brcmfmac_pdata
->power_on
)
491 brcmfmac_pdata
->power_on();
496 static int brcmf_common_pd_remove(struct platform_device
*pdev
)
498 brcmf_dbg(INFO
, "Enter\n");
500 if (brcmfmac_pdata
->power_off
)
501 brcmfmac_pdata
->power_off();
506 static struct platform_driver brcmf_pd
= {
507 .remove
= brcmf_common_pd_remove
,
509 .name
= BRCMFMAC_PDATA_NAME
,
513 static int __init
brcmfmac_module_init(void)
517 /* Initialize debug system first */
518 brcmf_debugfs_init();
520 /* Get the platform data (if available) for our devices */
521 err
= platform_driver_probe(&brcmf_pd
, brcmf_common_pd_probe
);
523 brcmf_dbg(INFO
, "No platform data available.\n");
525 /* Initialize global module paramaters */
528 /* Continue the initialization by registering the different busses */
529 err
= brcmf_core_init();
531 brcmf_debugfs_exit();
533 platform_driver_unregister(&brcmf_pd
);
539 static void __exit
brcmfmac_module_exit(void)
543 platform_driver_unregister(&brcmf_pd
);
544 brcmf_debugfs_exit();
547 module_init(brcmfmac_module_init
);
548 module_exit(brcmfmac_module_exit
);