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 if (err
== -ENOENT
) {
186 brcmf_dbg(INFO
, "continue with CLM data currently present in firmware\n");
189 brcmf_err("request CLM blob file failed (%d)\n", err
);
193 chunk_buf
= kzalloc(sizeof(*chunk_buf
) + MAX_CHUNK_LEN
- 1, GFP_KERNEL
);
202 if (datalen
> MAX_CHUNK_LEN
) {
203 chunk_len
= MAX_CHUNK_LEN
;
208 memcpy(chunk_buf
->data
, clm
->data
+ cumulative_len
, chunk_len
);
210 err
= brcmf_c_download(ifp
, dl_flag
, chunk_buf
, chunk_len
);
212 dl_flag
&= ~DL_BEGIN
;
214 cumulative_len
+= chunk_len
;
215 datalen
-= chunk_len
;
216 } while ((datalen
> 0) && (err
== 0));
219 brcmf_err("clmload (%zu byte file) failed (%d); ",
221 /* Retrieve clmload_status and print */
222 err
= brcmf_fil_iovar_int_get(ifp
, "clmload_status", &status
);
224 brcmf_err("get clmload_status failed (%d)\n", err
);
226 brcmf_dbg(INFO
, "clmload_status=%d\n", status
);
232 release_firmware(clm
);
236 int brcmf_c_preinit_dcmds(struct brcmf_if
*ifp
)
238 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
239 u8 buf
[BRCMF_DCMD_SMLEN
];
240 struct brcmf_rev_info_le revinfo
;
241 struct brcmf_rev_info
*ri
;
246 /* retreive mac address */
247 err
= brcmf_fil_iovar_data_get(ifp
, "cur_etheraddr", ifp
->mac_addr
,
248 sizeof(ifp
->mac_addr
));
250 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err
);
253 memcpy(ifp
->drvr
->mac
, ifp
->mac_addr
, sizeof(ifp
->drvr
->mac
));
255 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_REVINFO
,
256 &revinfo
, sizeof(revinfo
));
257 ri
= &ifp
->drvr
->revinfo
;
259 brcmf_err("retrieving revision info failed, %d\n", err
);
261 ri
->vendorid
= le32_to_cpu(revinfo
.vendorid
);
262 ri
->deviceid
= le32_to_cpu(revinfo
.deviceid
);
263 ri
->radiorev
= le32_to_cpu(revinfo
.radiorev
);
264 ri
->chiprev
= le32_to_cpu(revinfo
.chiprev
);
265 ri
->corerev
= le32_to_cpu(revinfo
.corerev
);
266 ri
->boardid
= le32_to_cpu(revinfo
.boardid
);
267 ri
->boardvendor
= le32_to_cpu(revinfo
.boardvendor
);
268 ri
->boardrev
= le32_to_cpu(revinfo
.boardrev
);
269 ri
->driverrev
= le32_to_cpu(revinfo
.driverrev
);
270 ri
->ucoderev
= le32_to_cpu(revinfo
.ucoderev
);
271 ri
->bus
= le32_to_cpu(revinfo
.bus
);
272 ri
->chipnum
= le32_to_cpu(revinfo
.chipnum
);
273 ri
->phytype
= le32_to_cpu(revinfo
.phytype
);
274 ri
->phyrev
= le32_to_cpu(revinfo
.phyrev
);
275 ri
->anarev
= le32_to_cpu(revinfo
.anarev
);
276 ri
->chippkg
= le32_to_cpu(revinfo
.chippkg
);
277 ri
->nvramrev
= le32_to_cpu(revinfo
.nvramrev
);
281 /* Do any CLM downloading */
282 err
= brcmf_c_process_clm_blob(ifp
);
284 brcmf_err("download CLM blob file failed, %d\n", err
);
288 /* query for 'ver' to get version info from firmware */
289 memset(buf
, 0, sizeof(buf
));
291 err
= brcmf_fil_iovar_data_get(ifp
, "ver", buf
, sizeof(buf
));
293 brcmf_err("Retreiving version information failed, %d\n",
300 /* Print fw version info */
301 brcmf_info("Firmware version = %s\n", buf
);
303 /* locate firmware version number for ethtool */
304 ptr
= strrchr(buf
, ' ') + 1;
305 strlcpy(ifp
->drvr
->fwver
, ptr
, sizeof(ifp
->drvr
->fwver
));
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
));
311 brcmf_dbg(TRACE
, "retrieving clmver failed, %d\n", err
);
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
));
317 /* Replace all newline/linefeed characters with space
321 while ((ptr
= strnchr(ptr
, '\n', sizeof(buf
))) != NULL
)
324 brcmf_dbg(INFO
, "CLM version = %s\n", clmver
);
328 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", 1);
330 brcmf_err("failed setting mpc\n");
334 brcmf_c_set_joinpref_default(ifp
);
336 /* Setup event_msgs, enable E_IF */
337 err
= brcmf_fil_iovar_data_get(ifp
, "event_msgs", eventmask
,
338 BRCMF_EVENTING_MASK_LEN
);
340 brcmf_err("Get event_msgs error (%d)\n", err
);
343 setbit(eventmask
, BRCMF_E_IF
);
344 err
= brcmf_fil_iovar_data_set(ifp
, "event_msgs", eventmask
,
345 BRCMF_EVENTING_MASK_LEN
);
347 brcmf_err("Set event_msgs error (%d)\n", err
);
351 /* Setup default scan channel time */
352 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
353 BRCMF_DEFAULT_SCAN_CHANNEL_TIME
);
355 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
360 /* Setup default scan unassoc time */
361 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
362 BRCMF_DEFAULT_SCAN_UNASSOC_TIME
);
364 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
369 /* Enable tx beamforming, errors can be ignored (not supported) */
370 (void)brcmf_fil_iovar_int_set(ifp
, "txbf", 1);
372 /* do bus specific preinit here */
373 err
= brcmf_bus_preinit(ifp
->drvr
->bus_if
);
378 #ifndef CONFIG_BRCM_TRACING
379 void __brcmf_err(const char *func
, const char *fmt
, ...)
381 struct va_format vaf
;
388 pr_err("%s: %pV", func
, &vaf
);
394 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
395 void __brcmf_dbg(u32 level
, const char *func
, const char *fmt
, ...)
397 struct va_format vaf
= {
404 if (brcmf_msg_level
& level
)
405 pr_debug("%s %pV", func
, &vaf
);
406 trace_brcmf_dbg(level
, func
, &vaf
);
411 static void brcmf_mp_attach(void)
413 /* If module param firmware path is set then this will always be used,
414 * if not set then if available use the platform data version. To make
415 * sure it gets initialized at all, always copy the module param version
417 strlcpy(brcmf_mp_global
.firmware_path
, brcmf_firmware_path
,
418 BRCMF_FW_ALTPATH_LEN
);
419 if ((brcmfmac_pdata
) && (brcmfmac_pdata
->fw_alternative_path
) &&
420 (brcmf_mp_global
.firmware_path
[0] == '\0')) {
421 strlcpy(brcmf_mp_global
.firmware_path
,
422 brcmfmac_pdata
->fw_alternative_path
,
423 BRCMF_FW_ALTPATH_LEN
);
427 struct brcmf_mp_device
*brcmf_get_module_param(struct device
*dev
,
428 enum brcmf_bus_type bus_type
,
429 u32 chip
, u32 chiprev
)
431 struct brcmf_mp_device
*settings
;
432 struct brcmfmac_pd_device
*device_pd
;
436 brcmf_dbg(INFO
, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type
, chip
,
438 settings
= kzalloc(sizeof(*settings
), GFP_ATOMIC
);
442 /* start by using the module paramaters */
443 settings
->p2p_enable
= !!brcmf_p2p_enable
;
444 settings
->feature_disable
= brcmf_feature_disable
;
445 settings
->fcmode
= brcmf_fcmode
;
446 settings
->roamoff
= !!brcmf_roamoff
;
448 settings
->ignore_probe_fail
= !!brcmf_ignore_probe_fail
;
451 if (bus_type
== BRCMF_BUSTYPE_SDIO
)
452 settings
->bus
.sdio
.txglomsz
= brcmf_sdiod_txglomsz
;
454 /* See if there is any device specific platform data configured */
456 if (brcmfmac_pdata
) {
457 for (i
= 0; i
< brcmfmac_pdata
->device_count
; i
++) {
458 device_pd
= &brcmfmac_pdata
->devices
[i
];
459 if ((device_pd
->bus_type
== bus_type
) &&
460 (device_pd
->id
== chip
) &&
461 ((device_pd
->rev
== chiprev
) ||
462 (device_pd
->rev
== -1))) {
463 brcmf_dbg(INFO
, "Platform data for device found\n");
464 settings
->country_codes
=
465 device_pd
->country_codes
;
466 if (device_pd
->bus_type
== BRCMF_BUSTYPE_SDIO
)
467 memcpy(&settings
->bus
.sdio
,
468 &device_pd
->bus
.sdio
,
469 sizeof(settings
->bus
.sdio
));
476 /* No platform data for this device, try OF (Open Firwmare) */
477 brcmf_of_probe(dev
, bus_type
, settings
);
482 void brcmf_release_module_param(struct brcmf_mp_device
*module_param
)
487 static int __init
brcmf_common_pd_probe(struct platform_device
*pdev
)
489 brcmf_dbg(INFO
, "Enter\n");
491 brcmfmac_pdata
= dev_get_platdata(&pdev
->dev
);
493 if (brcmfmac_pdata
->power_on
)
494 brcmfmac_pdata
->power_on();
499 static int brcmf_common_pd_remove(struct platform_device
*pdev
)
501 brcmf_dbg(INFO
, "Enter\n");
503 if (brcmfmac_pdata
->power_off
)
504 brcmfmac_pdata
->power_off();
509 static struct platform_driver brcmf_pd
= {
510 .remove
= brcmf_common_pd_remove
,
512 .name
= BRCMFMAC_PDATA_NAME
,
516 static int __init
brcmfmac_module_init(void)
520 /* Initialize debug system first */
521 brcmf_debugfs_init();
523 /* Get the platform data (if available) for our devices */
524 err
= platform_driver_probe(&brcmf_pd
, brcmf_common_pd_probe
);
526 brcmf_dbg(INFO
, "No platform data available.\n");
528 /* Initialize global module paramaters */
531 /* Continue the initialization by registering the different busses */
532 err
= brcmf_core_init();
534 brcmf_debugfs_exit();
536 platform_driver_unregister(&brcmf_pd
);
542 static void __exit
brcmfmac_module_exit(void)
546 platform_driver_unregister(&brcmf_pd
);
547 brcmf_debugfs_exit();
550 module_init(brcmfmac_module_init
);
551 module_exit(brcmfmac_module_exit
);