Linux 4.19.133
[linux/fpc-iii.git] / drivers / net / wireless / broadcom / brcm80211 / brcmfmac / common.c
blob8510d207ee87d1f5b2f65dfae112a19201d6ba5e
1 /*
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>
24 #include "core.h"
25 #include "bus.h"
26 #include "debug.h"
27 #include "fwil.h"
28 #include "fwil_types.h"
29 #include "tracepoint.h"
30 #include "common.h"
31 #include "of.h"
32 #include "firmware.h"
33 #include "chip.h"
35 MODULE_AUTHOR("Broadcom Corporation");
36 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
37 MODULE_LICENSE("Dual BSD/GPL");
39 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
40 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
42 /* default boost value for RSSI_DELTA in preferred join selection */
43 #define BRCMF_JOIN_PREF_RSSI_BOOST 8
45 #define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
47 static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
48 module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
49 MODULE_PARM_DESC(txglomsz, "Maximum tx packet chain size [SDIO]");
51 /* Debug level configuration. See debug.h for bits, sysfs modifiable */
52 int brcmf_msg_level;
53 module_param_named(debug, brcmf_msg_level, int, 0600);
54 MODULE_PARM_DESC(debug, "Level of debug output");
56 static int brcmf_p2p_enable;
57 module_param_named(p2pon, brcmf_p2p_enable, int, 0);
58 MODULE_PARM_DESC(p2pon, "Enable legacy p2p management functionality");
60 static int brcmf_feature_disable;
61 module_param_named(feature_disable, brcmf_feature_disable, int, 0);
62 MODULE_PARM_DESC(feature_disable, "Disable features");
64 static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
65 module_param_string(alternative_fw_path, brcmf_firmware_path,
66 BRCMF_FW_ALTPATH_LEN, 0400);
67 MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");
69 static int brcmf_fcmode;
70 module_param_named(fcmode, brcmf_fcmode, int, 0);
71 MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
73 static int brcmf_roamoff;
74 module_param_named(roamoff, brcmf_roamoff, int, 0400);
75 MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
77 static int brcmf_iapp_enable;
78 module_param_named(iapp, brcmf_iapp_enable, int, 0);
79 MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
81 #ifdef DEBUG
82 /* always succeed brcmf_bus_started() */
83 static int brcmf_ignore_probe_fail;
84 module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
85 MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
86 #endif
88 static struct brcmfmac_platform_data *brcmfmac_pdata;
89 struct brcmf_mp_global_t brcmf_mp_global;
91 void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
93 struct brcmf_join_pref_params join_pref_params[2];
94 int err;
96 /* Setup join_pref to select target by RSSI (boost on 5GHz) */
97 join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
98 join_pref_params[0].len = 2;
99 join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
100 join_pref_params[0].band = WLC_BAND_5G;
102 join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
103 join_pref_params[1].len = 2;
104 join_pref_params[1].rssi_gain = 0;
105 join_pref_params[1].band = 0;
106 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
107 sizeof(join_pref_params));
108 if (err)
109 brcmf_err("Set join_pref error (%d)\n", err);
112 static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
113 struct brcmf_dload_data_le *dload_buf,
114 u32 len)
116 s32 err;
118 flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
119 dload_buf->flag = cpu_to_le16(flag);
120 dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
121 dload_buf->len = cpu_to_le32(len);
122 dload_buf->crc = cpu_to_le32(0);
123 len = sizeof(*dload_buf) + len - 1;
125 err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
127 return err;
130 static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
132 struct brcmf_bus *bus = ifp->drvr->bus_if;
133 struct brcmf_dload_data_le *chunk_buf;
134 const struct firmware *clm = NULL;
135 u8 clm_name[BRCMF_FW_NAME_LEN];
136 u32 chunk_len;
137 u32 datalen;
138 u32 cumulative_len;
139 u16 dl_flag = DL_BEGIN;
140 u32 status;
141 s32 err;
143 brcmf_dbg(TRACE, "Enter\n");
145 memset(clm_name, 0, sizeof(clm_name));
146 err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name);
147 if (err) {
148 brcmf_err("get CLM blob file name failed (%d)\n", err);
149 return err;
152 err = firmware_request_nowarn(&clm, clm_name, bus->dev);
153 if (err) {
154 brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n",
155 err);
156 return 0;
159 chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
160 if (!chunk_buf) {
161 err = -ENOMEM;
162 goto done;
165 datalen = clm->size;
166 cumulative_len = 0;
167 do {
168 if (datalen > MAX_CHUNK_LEN) {
169 chunk_len = MAX_CHUNK_LEN;
170 } else {
171 chunk_len = datalen;
172 dl_flag |= DL_END;
174 memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
176 err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
178 dl_flag &= ~DL_BEGIN;
180 cumulative_len += chunk_len;
181 datalen -= chunk_len;
182 } while ((datalen > 0) && (err == 0));
184 if (err) {
185 brcmf_err("clmload (%zu byte file) failed (%d); ",
186 clm->size, err);
187 /* Retrieve clmload_status and print */
188 err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
189 if (err)
190 brcmf_err("get clmload_status failed (%d)\n", err);
191 else
192 brcmf_dbg(INFO, "clmload_status=%d\n", status);
193 err = -EIO;
196 kfree(chunk_buf);
197 done:
198 release_firmware(clm);
199 return err;
202 int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
204 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
205 u8 buf[BRCMF_DCMD_SMLEN];
206 struct brcmf_bus *bus;
207 struct brcmf_rev_info_le revinfo;
208 struct brcmf_rev_info *ri;
209 char *clmver;
210 char *ptr;
211 s32 err;
213 /* retreive mac address */
214 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
215 sizeof(ifp->mac_addr));
216 if (err < 0) {
217 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
218 goto done;
220 memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
221 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
223 bus = ifp->drvr->bus_if;
224 ri = &ifp->drvr->revinfo;
226 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO,
227 &revinfo, sizeof(revinfo));
228 if (err < 0) {
229 brcmf_err("retrieving revision info failed, %d\n", err);
230 strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname));
231 } else {
232 ri->vendorid = le32_to_cpu(revinfo.vendorid);
233 ri->deviceid = le32_to_cpu(revinfo.deviceid);
234 ri->radiorev = le32_to_cpu(revinfo.radiorev);
235 ri->corerev = le32_to_cpu(revinfo.corerev);
236 ri->boardid = le32_to_cpu(revinfo.boardid);
237 ri->boardvendor = le32_to_cpu(revinfo.boardvendor);
238 ri->boardrev = le32_to_cpu(revinfo.boardrev);
239 ri->driverrev = le32_to_cpu(revinfo.driverrev);
240 ri->ucoderev = le32_to_cpu(revinfo.ucoderev);
241 ri->bus = le32_to_cpu(revinfo.bus);
242 ri->phytype = le32_to_cpu(revinfo.phytype);
243 ri->phyrev = le32_to_cpu(revinfo.phyrev);
244 ri->anarev = le32_to_cpu(revinfo.anarev);
245 ri->chippkg = le32_to_cpu(revinfo.chippkg);
246 ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
248 /* use revinfo if not known yet */
249 if (!bus->chip) {
250 bus->chip = le32_to_cpu(revinfo.chipnum);
251 bus->chiprev = le32_to_cpu(revinfo.chiprev);
254 ri->result = err;
256 if (bus->chip)
257 brcmf_chip_name(bus->chip, bus->chiprev,
258 ri->chipname, sizeof(ri->chipname));
260 /* Do any CLM downloading */
261 err = brcmf_c_process_clm_blob(ifp);
262 if (err < 0) {
263 brcmf_err("download CLM blob file failed, %d\n", err);
264 goto done;
267 /* query for 'ver' to get version info from firmware */
268 memset(buf, 0, sizeof(buf));
269 strcpy(buf, "ver");
270 err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
271 if (err < 0) {
272 brcmf_err("Retreiving version information failed, %d\n",
273 err);
274 goto done;
276 ptr = (char *)buf;
277 strsep(&ptr, "\n");
279 /* Print fw version info */
280 brcmf_info("Firmware: %s %s\n", ri->chipname, buf);
282 /* locate firmware version number for ethtool */
283 ptr = strrchr(buf, ' ') + 1;
284 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
286 /* Query for 'clmver' to get CLM version info from firmware */
287 memset(buf, 0, sizeof(buf));
288 err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
289 if (err) {
290 brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
291 } else {
292 clmver = (char *)buf;
293 /* store CLM version for adding it to revinfo debugfs file */
294 memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
296 /* Replace all newline/linefeed characters with space
297 * character
299 strreplace(clmver, '\n', ' ');
301 brcmf_dbg(INFO, "CLM version = %s\n", clmver);
304 /* set mpc */
305 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
306 if (err) {
307 brcmf_err("failed setting mpc\n");
308 goto done;
311 brcmf_c_set_joinpref_default(ifp);
313 /* Setup event_msgs, enable E_IF */
314 err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
315 BRCMF_EVENTING_MASK_LEN);
316 if (err) {
317 brcmf_err("Get event_msgs error (%d)\n", err);
318 goto done;
320 setbit(eventmask, BRCMF_E_IF);
321 err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
322 BRCMF_EVENTING_MASK_LEN);
323 if (err) {
324 brcmf_err("Set event_msgs error (%d)\n", err);
325 goto done;
328 /* Setup default scan channel time */
329 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
330 BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
331 if (err) {
332 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
333 err);
334 goto done;
337 /* Setup default scan unassoc time */
338 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
339 BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
340 if (err) {
341 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
342 err);
343 goto done;
346 /* Enable tx beamforming, errors can be ignored (not supported) */
347 (void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
348 done:
349 return err;
352 #ifndef CONFIG_BRCM_TRACING
353 void __brcmf_err(const char *func, const char *fmt, ...)
355 struct va_format vaf;
356 va_list args;
358 va_start(args, fmt);
360 vaf.fmt = fmt;
361 vaf.va = &args;
362 pr_err("%s: %pV", func, &vaf);
364 va_end(args);
366 #endif
368 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
369 void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
371 struct va_format vaf = {
372 .fmt = fmt,
374 va_list args;
376 va_start(args, fmt);
377 vaf.va = &args;
378 if (brcmf_msg_level & level)
379 pr_debug("%s %pV", func, &vaf);
380 trace_brcmf_dbg(level, func, &vaf);
381 va_end(args);
383 #endif
385 static void brcmf_mp_attach(void)
387 /* If module param firmware path is set then this will always be used,
388 * if not set then if available use the platform data version. To make
389 * sure it gets initialized at all, always copy the module param version
391 strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
392 BRCMF_FW_ALTPATH_LEN);
393 if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
394 (brcmf_mp_global.firmware_path[0] == '\0')) {
395 strlcpy(brcmf_mp_global.firmware_path,
396 brcmfmac_pdata->fw_alternative_path,
397 BRCMF_FW_ALTPATH_LEN);
401 struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
402 enum brcmf_bus_type bus_type,
403 u32 chip, u32 chiprev)
405 struct brcmf_mp_device *settings;
406 struct brcmfmac_pd_device *device_pd;
407 bool found;
408 int i;
410 brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip,
411 chiprev);
412 settings = kzalloc(sizeof(*settings), GFP_ATOMIC);
413 if (!settings)
414 return NULL;
416 /* start by using the module paramaters */
417 settings->p2p_enable = !!brcmf_p2p_enable;
418 settings->feature_disable = brcmf_feature_disable;
419 settings->fcmode = brcmf_fcmode;
420 settings->roamoff = !!brcmf_roamoff;
421 settings->iapp = !!brcmf_iapp_enable;
422 #ifdef DEBUG
423 settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
424 #endif
426 if (bus_type == BRCMF_BUSTYPE_SDIO)
427 settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
429 /* See if there is any device specific platform data configured */
430 found = false;
431 if (brcmfmac_pdata) {
432 for (i = 0; i < brcmfmac_pdata->device_count; i++) {
433 device_pd = &brcmfmac_pdata->devices[i];
434 if ((device_pd->bus_type == bus_type) &&
435 (device_pd->id == chip) &&
436 ((device_pd->rev == chiprev) ||
437 (device_pd->rev == -1))) {
438 brcmf_dbg(INFO, "Platform data for device found\n");
439 settings->country_codes =
440 device_pd->country_codes;
441 if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
442 memcpy(&settings->bus.sdio,
443 &device_pd->bus.sdio,
444 sizeof(settings->bus.sdio));
445 found = true;
446 break;
450 if (!found) {
451 /* No platform data for this device, try OF (Open Firwmare) */
452 brcmf_of_probe(dev, bus_type, settings);
454 return settings;
457 void brcmf_release_module_param(struct brcmf_mp_device *module_param)
459 kfree(module_param);
462 static int __init brcmf_common_pd_probe(struct platform_device *pdev)
464 brcmf_dbg(INFO, "Enter\n");
466 brcmfmac_pdata = dev_get_platdata(&pdev->dev);
468 if (brcmfmac_pdata->power_on)
469 brcmfmac_pdata->power_on();
471 return 0;
474 static int brcmf_common_pd_remove(struct platform_device *pdev)
476 brcmf_dbg(INFO, "Enter\n");
478 if (brcmfmac_pdata->power_off)
479 brcmfmac_pdata->power_off();
481 return 0;
484 static struct platform_driver brcmf_pd = {
485 .remove = brcmf_common_pd_remove,
486 .driver = {
487 .name = BRCMFMAC_PDATA_NAME,
491 static int __init brcmfmac_module_init(void)
493 int err;
495 /* Get the platform data (if available) for our devices */
496 err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe);
497 if (err == -ENODEV)
498 brcmf_dbg(INFO, "No platform data available.\n");
500 /* Initialize global module paramaters */
501 brcmf_mp_attach();
503 /* Continue the initialization by registering the different busses */
504 err = brcmf_core_init();
505 if (err) {
506 if (brcmfmac_pdata)
507 platform_driver_unregister(&brcmf_pd);
510 return err;
513 static void __exit brcmfmac_module_exit(void)
515 brcmf_core_exit();
516 if (brcmfmac_pdata)
517 platform_driver_unregister(&brcmf_pd);
520 module_init(brcmfmac_module_init);
521 module_exit(brcmfmac_module_exit);