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");
78 static int brcmf_iapp_enable
;
79 module_param_named(iapp
, brcmf_iapp_enable
, int, 0);
80 MODULE_PARM_DESC(iapp
, "Enable partial support for the obsoleted Inter-Access Point Protocol");
83 /* always succeed brcmf_bus_started() */
84 static int brcmf_ignore_probe_fail
;
85 module_param_named(ignore_probe_fail
, brcmf_ignore_probe_fail
, int, 0);
86 MODULE_PARM_DESC(ignore_probe_fail
, "always succeed probe for debugging");
89 static struct brcmfmac_platform_data
*brcmfmac_pdata
;
90 struct brcmf_mp_global_t brcmf_mp_global
;
92 void brcmf_c_set_joinpref_default(struct brcmf_if
*ifp
)
94 struct brcmf_join_pref_params join_pref_params
[2];
97 /* Setup join_pref to select target by RSSI (boost on 5GHz) */
98 join_pref_params
[0].type
= BRCMF_JOIN_PREF_RSSI_DELTA
;
99 join_pref_params
[0].len
= 2;
100 join_pref_params
[0].rssi_gain
= BRCMF_JOIN_PREF_RSSI_BOOST
;
101 join_pref_params
[0].band
= WLC_BAND_5G
;
103 join_pref_params
[1].type
= BRCMF_JOIN_PREF_RSSI
;
104 join_pref_params
[1].len
= 2;
105 join_pref_params
[1].rssi_gain
= 0;
106 join_pref_params
[1].band
= 0;
107 err
= brcmf_fil_iovar_data_set(ifp
, "join_pref", join_pref_params
,
108 sizeof(join_pref_params
));
110 brcmf_err("Set join_pref error (%d)\n", err
);
113 static int brcmf_c_download(struct brcmf_if
*ifp
, u16 flag
,
114 struct brcmf_dload_data_le
*dload_buf
,
119 flag
|= (DLOAD_HANDLER_VER
<< DLOAD_FLAG_VER_SHIFT
);
120 dload_buf
->flag
= cpu_to_le16(flag
);
121 dload_buf
->dload_type
= cpu_to_le16(DL_TYPE_CLM
);
122 dload_buf
->len
= cpu_to_le32(len
);
123 dload_buf
->crc
= cpu_to_le32(0);
124 len
= sizeof(*dload_buf
) + len
- 1;
126 err
= brcmf_fil_iovar_data_set(ifp
, "clmload", dload_buf
, len
);
131 static int brcmf_c_get_clm_name(struct brcmf_if
*ifp
, u8
*clm_name
)
133 struct brcmf_bus
*bus
= ifp
->drvr
->bus_if
;
134 struct brcmf_rev_info
*ri
= &ifp
->drvr
->revinfo
;
135 u8 fw_name
[BRCMF_FW_NAME_LEN
];
140 memset(fw_name
, 0, BRCMF_FW_NAME_LEN
);
141 err
= brcmf_bus_get_fwname(bus
, ri
->chipnum
, ri
->chiprev
, fw_name
);
143 brcmf_err("get firmware name failed (%d)\n", err
);
147 /* generate CLM blob file name */
148 ptr
= strrchr(fw_name
, '.');
154 len
= ptr
- fw_name
+ 1;
155 if (len
+ strlen(".clm_blob") > BRCMF_FW_NAME_LEN
) {
158 strlcpy(clm_name
, fw_name
, len
);
159 strlcat(clm_name
, ".clm_blob", BRCMF_FW_NAME_LEN
);
165 static int brcmf_c_process_clm_blob(struct brcmf_if
*ifp
)
167 struct device
*dev
= ifp
->drvr
->bus_if
->dev
;
168 struct brcmf_dload_data_le
*chunk_buf
;
169 const struct firmware
*clm
= NULL
;
170 u8 clm_name
[BRCMF_FW_NAME_LEN
];
174 u16 dl_flag
= DL_BEGIN
;
178 brcmf_dbg(TRACE
, "Enter\n");
180 memset(clm_name
, 0, BRCMF_FW_NAME_LEN
);
181 err
= brcmf_c_get_clm_name(ifp
, clm_name
);
183 brcmf_err("get CLM blob file name failed (%d)\n", err
);
187 err
= request_firmware(&clm
, clm_name
, dev
);
189 brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n",
194 chunk_buf
= kzalloc(sizeof(*chunk_buf
) + MAX_CHUNK_LEN
- 1, GFP_KERNEL
);
203 if (datalen
> MAX_CHUNK_LEN
) {
204 chunk_len
= MAX_CHUNK_LEN
;
209 memcpy(chunk_buf
->data
, clm
->data
+ cumulative_len
, chunk_len
);
211 err
= brcmf_c_download(ifp
, dl_flag
, chunk_buf
, chunk_len
);
213 dl_flag
&= ~DL_BEGIN
;
215 cumulative_len
+= chunk_len
;
216 datalen
-= chunk_len
;
217 } while ((datalen
> 0) && (err
== 0));
220 brcmf_err("clmload (%zu byte file) failed (%d); ",
222 /* Retrieve clmload_status and print */
223 err
= brcmf_fil_iovar_int_get(ifp
, "clmload_status", &status
);
225 brcmf_err("get clmload_status failed (%d)\n", err
);
227 brcmf_dbg(INFO
, "clmload_status=%d\n", status
);
233 release_firmware(clm
);
237 int brcmf_c_preinit_dcmds(struct brcmf_if
*ifp
)
239 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
240 u8 buf
[BRCMF_DCMD_SMLEN
];
241 struct brcmf_rev_info_le revinfo
;
242 struct brcmf_rev_info
*ri
;
247 /* retreive mac address */
248 err
= brcmf_fil_iovar_data_get(ifp
, "cur_etheraddr", ifp
->mac_addr
,
249 sizeof(ifp
->mac_addr
));
251 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err
);
254 memcpy(ifp
->drvr
->mac
, ifp
->mac_addr
, sizeof(ifp
->drvr
->mac
));
256 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_REVINFO
,
257 &revinfo
, sizeof(revinfo
));
258 ri
= &ifp
->drvr
->revinfo
;
260 brcmf_err("retrieving revision info failed, %d\n", err
);
262 ri
->vendorid
= le32_to_cpu(revinfo
.vendorid
);
263 ri
->deviceid
= le32_to_cpu(revinfo
.deviceid
);
264 ri
->radiorev
= le32_to_cpu(revinfo
.radiorev
);
265 ri
->chiprev
= le32_to_cpu(revinfo
.chiprev
);
266 ri
->corerev
= le32_to_cpu(revinfo
.corerev
);
267 ri
->boardid
= le32_to_cpu(revinfo
.boardid
);
268 ri
->boardvendor
= le32_to_cpu(revinfo
.boardvendor
);
269 ri
->boardrev
= le32_to_cpu(revinfo
.boardrev
);
270 ri
->driverrev
= le32_to_cpu(revinfo
.driverrev
);
271 ri
->ucoderev
= le32_to_cpu(revinfo
.ucoderev
);
272 ri
->bus
= le32_to_cpu(revinfo
.bus
);
273 ri
->chipnum
= le32_to_cpu(revinfo
.chipnum
);
274 ri
->phytype
= le32_to_cpu(revinfo
.phytype
);
275 ri
->phyrev
= le32_to_cpu(revinfo
.phyrev
);
276 ri
->anarev
= le32_to_cpu(revinfo
.anarev
);
277 ri
->chippkg
= le32_to_cpu(revinfo
.chippkg
);
278 ri
->nvramrev
= le32_to_cpu(revinfo
.nvramrev
);
282 /* Do any CLM downloading */
283 err
= brcmf_c_process_clm_blob(ifp
);
285 brcmf_err("download CLM blob file failed, %d\n", err
);
289 /* query for 'ver' to get version info from firmware */
290 memset(buf
, 0, sizeof(buf
));
292 err
= brcmf_fil_iovar_data_get(ifp
, "ver", buf
, sizeof(buf
));
294 brcmf_err("Retreiving version information failed, %d\n",
301 /* Print fw version info */
302 brcmf_info("Firmware version = %s\n", buf
);
304 /* locate firmware version number for ethtool */
305 ptr
= strrchr(buf
, ' ') + 1;
306 strlcpy(ifp
->drvr
->fwver
, ptr
, sizeof(ifp
->drvr
->fwver
));
308 /* Query for 'clmver' to get CLM version info from firmware */
309 memset(buf
, 0, sizeof(buf
));
310 err
= brcmf_fil_iovar_data_get(ifp
, "clmver", buf
, sizeof(buf
));
312 brcmf_dbg(TRACE
, "retrieving clmver failed, %d\n", err
);
314 clmver
= (char *)buf
;
315 /* store CLM version for adding it to revinfo debugfs file */
316 memcpy(ifp
->drvr
->clmver
, clmver
, sizeof(ifp
->drvr
->clmver
));
318 /* Replace all newline/linefeed characters with space
322 while ((ptr
= strnchr(ptr
, '\n', sizeof(buf
))) != NULL
)
325 brcmf_dbg(INFO
, "CLM version = %s\n", clmver
);
329 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", 1);
331 brcmf_err("failed setting mpc\n");
335 brcmf_c_set_joinpref_default(ifp
);
337 /* Setup event_msgs, enable E_IF */
338 err
= brcmf_fil_iovar_data_get(ifp
, "event_msgs", eventmask
,
339 BRCMF_EVENTING_MASK_LEN
);
341 brcmf_err("Get event_msgs error (%d)\n", err
);
344 setbit(eventmask
, BRCMF_E_IF
);
345 err
= brcmf_fil_iovar_data_set(ifp
, "event_msgs", eventmask
,
346 BRCMF_EVENTING_MASK_LEN
);
348 brcmf_err("Set event_msgs error (%d)\n", err
);
352 /* Setup default scan channel time */
353 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
354 BRCMF_DEFAULT_SCAN_CHANNEL_TIME
);
356 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
361 /* Setup default scan unassoc time */
362 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
363 BRCMF_DEFAULT_SCAN_UNASSOC_TIME
);
365 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
370 /* Enable tx beamforming, errors can be ignored (not supported) */
371 (void)brcmf_fil_iovar_int_set(ifp
, "txbf", 1);
373 /* do bus specific preinit here */
374 err
= brcmf_bus_preinit(ifp
->drvr
->bus_if
);
379 #ifndef CONFIG_BRCM_TRACING
380 void __brcmf_err(const char *func
, const char *fmt
, ...)
382 struct va_format vaf
;
389 pr_err("%s: %pV", func
, &vaf
);
395 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
396 void __brcmf_dbg(u32 level
, const char *func
, const char *fmt
, ...)
398 struct va_format vaf
= {
405 if (brcmf_msg_level
& level
)
406 pr_debug("%s %pV", func
, &vaf
);
407 trace_brcmf_dbg(level
, func
, &vaf
);
412 static void brcmf_mp_attach(void)
414 /* If module param firmware path is set then this will always be used,
415 * if not set then if available use the platform data version. To make
416 * sure it gets initialized at all, always copy the module param version
418 strlcpy(brcmf_mp_global
.firmware_path
, brcmf_firmware_path
,
419 BRCMF_FW_ALTPATH_LEN
);
420 if ((brcmfmac_pdata
) && (brcmfmac_pdata
->fw_alternative_path
) &&
421 (brcmf_mp_global
.firmware_path
[0] == '\0')) {
422 strlcpy(brcmf_mp_global
.firmware_path
,
423 brcmfmac_pdata
->fw_alternative_path
,
424 BRCMF_FW_ALTPATH_LEN
);
428 struct brcmf_mp_device
*brcmf_get_module_param(struct device
*dev
,
429 enum brcmf_bus_type bus_type
,
430 u32 chip
, u32 chiprev
)
432 struct brcmf_mp_device
*settings
;
433 struct brcmfmac_pd_device
*device_pd
;
437 brcmf_dbg(INFO
, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type
, chip
,
439 settings
= kzalloc(sizeof(*settings
), GFP_ATOMIC
);
443 /* start by using the module paramaters */
444 settings
->p2p_enable
= !!brcmf_p2p_enable
;
445 settings
->feature_disable
= brcmf_feature_disable
;
446 settings
->fcmode
= brcmf_fcmode
;
447 settings
->roamoff
= !!brcmf_roamoff
;
448 settings
->iapp
= !!brcmf_iapp_enable
;
450 settings
->ignore_probe_fail
= !!brcmf_ignore_probe_fail
;
453 if (bus_type
== BRCMF_BUSTYPE_SDIO
)
454 settings
->bus
.sdio
.txglomsz
= brcmf_sdiod_txglomsz
;
456 /* See if there is any device specific platform data configured */
458 if (brcmfmac_pdata
) {
459 for (i
= 0; i
< brcmfmac_pdata
->device_count
; i
++) {
460 device_pd
= &brcmfmac_pdata
->devices
[i
];
461 if ((device_pd
->bus_type
== bus_type
) &&
462 (device_pd
->id
== chip
) &&
463 ((device_pd
->rev
== chiprev
) ||
464 (device_pd
->rev
== -1))) {
465 brcmf_dbg(INFO
, "Platform data for device found\n");
466 settings
->country_codes
=
467 device_pd
->country_codes
;
468 if (device_pd
->bus_type
== BRCMF_BUSTYPE_SDIO
)
469 memcpy(&settings
->bus
.sdio
,
470 &device_pd
->bus
.sdio
,
471 sizeof(settings
->bus
.sdio
));
478 /* No platform data for this device, try OF (Open Firwmare) */
479 brcmf_of_probe(dev
, bus_type
, settings
);
484 void brcmf_release_module_param(struct brcmf_mp_device
*module_param
)
489 static int __init
brcmf_common_pd_probe(struct platform_device
*pdev
)
491 brcmf_dbg(INFO
, "Enter\n");
493 brcmfmac_pdata
= dev_get_platdata(&pdev
->dev
);
495 if (brcmfmac_pdata
->power_on
)
496 brcmfmac_pdata
->power_on();
501 static int brcmf_common_pd_remove(struct platform_device
*pdev
)
503 brcmf_dbg(INFO
, "Enter\n");
505 if (brcmfmac_pdata
->power_off
)
506 brcmfmac_pdata
->power_off();
511 static struct platform_driver brcmf_pd
= {
512 .remove
= brcmf_common_pd_remove
,
514 .name
= BRCMFMAC_PDATA_NAME
,
518 static int __init
brcmfmac_module_init(void)
522 /* Initialize debug system first */
523 brcmf_debugfs_init();
525 /* Get the platform data (if available) for our devices */
526 err
= platform_driver_probe(&brcmf_pd
, brcmf_common_pd_probe
);
528 brcmf_dbg(INFO
, "No platform data available.\n");
530 /* Initialize global module paramaters */
533 /* Continue the initialization by registering the different busses */
534 err
= brcmf_core_init();
536 brcmf_debugfs_exit();
538 platform_driver_unregister(&brcmf_pd
);
544 static void __exit
brcmfmac_module_exit(void)
548 platform_driver_unregister(&brcmf_pd
);
549 brcmf_debugfs_exit();
552 module_init(brcmfmac_module_init
);
553 module_exit(brcmfmac_module_exit
);