netfilter: netns: shrink netns_ct struct
[linux-2.6-microblaze.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 = request_firmware(&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         ptr = (char *)buf;
277         strsep(&ptr, "\n");
278
279         /* Print fw version info */
280         brcmf_info("Firmware: %s %s\n", ri->chipname, buf);
281
282         /* locate firmware version number for ethtool */
283         ptr = strrchr(buf, ' ') + 1;
284         strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
285
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));
295
296                 /* Replace all newline/linefeed characters with space
297                  * character
298                  */
299                 strreplace(clmver, '\n', ' ');
300
301                 brcmf_dbg(INFO, "CLM version = %s\n", clmver);
302         }
303
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;
309         }
310
311         brcmf_c_set_joinpref_default(ifp);
312
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;
319         }
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;
326         }
327
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;
335         }
336
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;
344         }
345
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;
350 }
351
352 #ifndef CONFIG_BRCM_TRACING
353 void __brcmf_err(const char *func, const char *fmt, ...)
354 {
355         struct va_format vaf;
356         va_list args;
357
358         va_start(args, fmt);
359
360         vaf.fmt = fmt;
361         vaf.va = &args;
362         pr_err("%s: %pV", func, &vaf);
363
364         va_end(args);
365 }
366 #endif
367
368 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
369 void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
370 {
371         struct va_format vaf = {
372                 .fmt = fmt,
373         };
374         va_list args;
375
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);
382 }
383 #endif
384
385 static void brcmf_mp_attach(void)
386 {
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
390          */
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);
398         }
399 }
400
401 struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
402                                                enum brcmf_bus_type bus_type,
403                                                u32 chip, u32 chiprev)
404 {
405         struct brcmf_mp_device *settings;
406         struct brcmfmac_pd_device *device_pd;
407         bool found;
408         int i;
409
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;
415
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
425
426         if (bus_type == BRCMF_BUSTYPE_SDIO)
427                 settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
428
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;
447                         }
448                 }
449         }
450         if (!found) {
451                 /* No platform data for this device, try OF (Open Firwmare) */
452                 brcmf_of_probe(dev, bus_type, settings);
453         }
454         return settings;
455 }
456
457 void brcmf_release_module_param(struct brcmf_mp_device *module_param)
458 {
459         kfree(module_param);
460 }
461
462 static int __init brcmf_common_pd_probe(struct platform_device *pdev)
463 {
464         brcmf_dbg(INFO, "Enter\n");
465
466         brcmfmac_pdata = dev_get_platdata(&pdev->dev);
467
468         if (brcmfmac_pdata->power_on)
469                 brcmfmac_pdata->power_on();
470
471         return 0;
472 }
473
474 static int brcmf_common_pd_remove(struct platform_device *pdev)
475 {
476         brcmf_dbg(INFO, "Enter\n");
477
478         if (brcmfmac_pdata->power_off)
479                 brcmfmac_pdata->power_off();
480
481         return 0;
482 }
483
484 static struct platform_driver brcmf_pd = {
485         .remove         = brcmf_common_pd_remove,
486         .driver         = {
487                 .name   = BRCMFMAC_PDATA_NAME,
488         }
489 };
490
491 static int __init brcmfmac_module_init(void)
492 {
493         int err;
494
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");
499
500         /* Initialize global module paramaters */
501         brcmf_mp_attach();
502
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);
508         }
509
510         return err;
511 }
512
513 static void __exit brcmfmac_module_exit(void)
514 {
515         brcmf_core_exit();
516         if (brcmfmac_pdata)
517                 platform_driver_unregister(&brcmf_pd);
518 }
519
520 module_init(brcmfmac_module_init);
521 module_exit(brcmfmac_module_exit);
522