GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / net / wireless / broadcom / brcm80211 / brcmfmac / common.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
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.
7  *
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.
15  */
16
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"
34
35 MODULE_AUTHOR("Broadcom Corporation");
36 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
37 MODULE_LICENSE("Dual BSD/GPL");
38
39 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
40 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
41
42 /* default boost value for RSSI_DELTA in preferred join selection */
43 #define BRCMF_JOIN_PREF_RSSI_BOOST      8
44
45 #define BRCMF_DEFAULT_TXGLOM_SIZE       32  /* max tx frames in glom chain */
46
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]");
50
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");
55
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");
59
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");
63
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");
68
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");
72
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");
76
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");
80
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
87
88 static struct brcmfmac_platform_data *brcmfmac_pdata;
89 struct brcmf_mp_global_t brcmf_mp_global;
90
91 void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
92 {
93         struct brcmf_join_pref_params join_pref_params[2];
94         int err;
95
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;
101
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);
110 }
111
112 static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
113                             struct brcmf_dload_data_le *dload_buf,
114                             u32 len)
115 {
116         s32 err;
117
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;
124
125         err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
126
127         return err;
128 }
129
130 static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
131 {
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;
142
143         brcmf_dbg(TRACE, "Enter\n");
144
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;
150         }
151
152         err = firmware_reject_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;
157         }
158
159         chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
160         if (!chunk_buf) {
161                 err = -ENOMEM;
162                 goto done;
163         }
164
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;
173                 }
174                 memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
175
176                 err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
177
178                 dl_flag &= ~DL_BEGIN;
179
180                 cumulative_len += chunk_len;
181                 datalen -= chunk_len;
182         } while ((datalen > 0) && (err == 0));
183
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;
194         }
195
196         kfree(chunk_buf);
197 done:
198         release_firmware(clm);
199         return err;
200 }
201
202 int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
203 {
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;
212
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;
219         }
220         memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
221         memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
222
223         bus = ifp->drvr->bus_if;
224         ri = &ifp->drvr->revinfo;
225
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);
247
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);
252                 }
253         }
254         ri->result = err;
255
256         if (bus->chip)
257                 brcmf_chip_name(bus->chip, bus->chiprev,
258                                 ri->chipname, sizeof(ri->chipname));
259
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;
265         }
266
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;
275         }
276         buf[sizeof(buf) - 1] = '\0';
277         ptr = (char *)buf;
278         strsep(&ptr, "\n");
279
280         /* Print fw version info */
281         brcmf_info("Firmware: %s %s\n", ri->chipname, buf);
282
283         /* locate firmware version number for ethtool */
284         ptr = strrchr(buf, ' ') + 1;
285         strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
286
287         /* Query for 'clmver' to get CLM version info from firmware */
288         memset(buf, 0, sizeof(buf));
289         err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
290         if (err) {
291                 brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
292         } else {
293                 buf[sizeof(buf) - 1] = '\0';
294                 clmver = (char *)buf;
295
296                 /* Replace all newline/linefeed characters with space
297                  * character
298                  */
299                 strreplace(clmver, '\n', ' ');
300
301                 /* store CLM version for adding it to revinfo debugfs file */
302                 memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
303
304                 brcmf_dbg(INFO, "CLM version = %s\n", clmver);
305         }
306
307         /* set mpc */
308         err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
309         if (err) {
310                 brcmf_err("failed setting mpc\n");
311                 goto done;
312         }
313
314         brcmf_c_set_joinpref_default(ifp);
315
316         /* Setup event_msgs, enable E_IF */
317         err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
318                                        BRCMF_EVENTING_MASK_LEN);
319         if (err) {
320                 brcmf_err("Get event_msgs error (%d)\n", err);
321                 goto done;
322         }
323         setbit(eventmask, BRCMF_E_IF);
324         err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
325                                        BRCMF_EVENTING_MASK_LEN);
326         if (err) {
327                 brcmf_err("Set event_msgs error (%d)\n", err);
328                 goto done;
329         }
330
331         /* Setup default scan channel time */
332         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
333                                     BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
334         if (err) {
335                 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
336                           err);
337                 goto done;
338         }
339
340         /* Setup default scan unassoc time */
341         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
342                                     BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
343         if (err) {
344                 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
345                           err);
346                 goto done;
347         }
348
349         /* Enable tx beamforming, errors can be ignored (not supported) */
350         (void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
351 done:
352         return err;
353 }
354
355 #ifndef CONFIG_BRCM_TRACING
356 void __brcmf_err(const char *func, const char *fmt, ...)
357 {
358         struct va_format vaf;
359         va_list args;
360
361         va_start(args, fmt);
362
363         vaf.fmt = fmt;
364         vaf.va = &args;
365         pr_err("%s: %pV", func, &vaf);
366
367         va_end(args);
368 }
369 #endif
370
371 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
372 void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
373 {
374         struct va_format vaf = {
375                 .fmt = fmt,
376         };
377         va_list args;
378
379         va_start(args, fmt);
380         vaf.va = &args;
381         if (brcmf_msg_level & level)
382                 pr_debug("%s %pV", func, &vaf);
383         trace_brcmf_dbg(level, func, &vaf);
384         va_end(args);
385 }
386 #endif
387
388 static void brcmf_mp_attach(void)
389 {
390         /* If module param firmware path is set then this will always be used,
391          * if not set then if available use the platform data version. To make
392          * sure it gets initialized at all, always copy the module param version
393          */
394         strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
395                 BRCMF_FW_ALTPATH_LEN);
396         if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
397             (brcmf_mp_global.firmware_path[0] == '\0')) {
398                 strlcpy(brcmf_mp_global.firmware_path,
399                         brcmfmac_pdata->fw_alternative_path,
400                         BRCMF_FW_ALTPATH_LEN);
401         }
402 }
403
404 struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
405                                                enum brcmf_bus_type bus_type,
406                                                u32 chip, u32 chiprev)
407 {
408         struct brcmf_mp_device *settings;
409         struct brcmfmac_pd_device *device_pd;
410         bool found;
411         int i;
412
413         brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip,
414                   chiprev);
415         settings = kzalloc(sizeof(*settings), GFP_ATOMIC);
416         if (!settings)
417                 return NULL;
418
419         /* start by using the module paramaters */
420         settings->p2p_enable = !!brcmf_p2p_enable;
421         settings->feature_disable = brcmf_feature_disable;
422         settings->fcmode = brcmf_fcmode;
423         settings->roamoff = !!brcmf_roamoff;
424         settings->iapp = !!brcmf_iapp_enable;
425 #ifdef DEBUG
426         settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
427 #endif
428
429         if (bus_type == BRCMF_BUSTYPE_SDIO)
430                 settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
431
432         /* See if there is any device specific platform data configured */
433         found = false;
434         if (brcmfmac_pdata) {
435                 for (i = 0; i < brcmfmac_pdata->device_count; i++) {
436                         device_pd = &brcmfmac_pdata->devices[i];
437                         if ((device_pd->bus_type == bus_type) &&
438                             (device_pd->id == chip) &&
439                             ((device_pd->rev == chiprev) ||
440                              (device_pd->rev == -1))) {
441                                 brcmf_dbg(INFO, "Platform data for device found\n");
442                                 settings->country_codes =
443                                                 device_pd->country_codes;
444                                 if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
445                                         memcpy(&settings->bus.sdio,
446                                                &device_pd->bus.sdio,
447                                                sizeof(settings->bus.sdio));
448                                 found = true;
449                                 break;
450                         }
451                 }
452         }
453         if (!found) {
454                 /* No platform data for this device, try OF (Open Firwmare) */
455                 brcmf_of_probe(dev, bus_type, settings);
456         }
457         return settings;
458 }
459
460 void brcmf_release_module_param(struct brcmf_mp_device *module_param)
461 {
462         kfree(module_param);
463 }
464
465 static int __init brcmf_common_pd_probe(struct platform_device *pdev)
466 {
467         brcmf_dbg(INFO, "Enter\n");
468
469         brcmfmac_pdata = dev_get_platdata(&pdev->dev);
470
471         if (brcmfmac_pdata->power_on)
472                 brcmfmac_pdata->power_on();
473
474         return 0;
475 }
476
477 static int brcmf_common_pd_remove(struct platform_device *pdev)
478 {
479         brcmf_dbg(INFO, "Enter\n");
480
481         if (brcmfmac_pdata->power_off)
482                 brcmfmac_pdata->power_off();
483
484         return 0;
485 }
486
487 static struct platform_driver brcmf_pd = {
488         .remove         = brcmf_common_pd_remove,
489         .driver         = {
490                 .name   = BRCMFMAC_PDATA_NAME,
491         }
492 };
493
494 static int __init brcmfmac_module_init(void)
495 {
496         int err;
497
498         /* Get the platform data (if available) for our devices */
499         err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe);
500         if (err == -ENODEV)
501                 brcmf_dbg(INFO, "No platform data available.\n");
502
503         /* Initialize global module paramaters */
504         brcmf_mp_attach();
505
506         /* Continue the initialization by registering the different busses */
507         err = brcmf_core_init();
508         if (err) {
509                 if (brcmfmac_pdata)
510                         platform_driver_unregister(&brcmf_pd);
511         }
512
513         return err;
514 }
515
516 static void __exit brcmfmac_module_exit(void)
517 {
518         brcmf_core_exit();
519         if (brcmfmac_pdata)
520                 platform_driver_unregister(&brcmf_pd);
521 }
522
523 module_init(brcmfmac_module_init);
524 module_exit(brcmfmac_module_exit);
525