Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (c) 2010 Broadcom Corporation
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/string.h>
0008 #include <linux/netdevice.h>
0009 #include <linux/module.h>
0010 #include <linux/firmware.h>
0011 #include <brcmu_wifi.h>
0012 #include <brcmu_utils.h>
0013 #include "core.h"
0014 #include "bus.h"
0015 #include "debug.h"
0016 #include "fwil.h"
0017 #include "fwil_types.h"
0018 #include "tracepoint.h"
0019 #include "common.h"
0020 #include "of.h"
0021 #include "firmware.h"
0022 #include "chip.h"
0023 
0024 MODULE_AUTHOR("Broadcom Corporation");
0025 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
0026 MODULE_LICENSE("Dual BSD/GPL");
0027 
0028 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
0029 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
0030 
0031 /* default boost value for RSSI_DELTA in preferred join selection */
0032 #define BRCMF_JOIN_PREF_RSSI_BOOST  8
0033 
0034 #define BRCMF_DEFAULT_TXGLOM_SIZE   32  /* max tx frames in glom chain */
0035 
0036 static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
0037 module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
0038 MODULE_PARM_DESC(txglomsz, "Maximum tx packet chain size [SDIO]");
0039 
0040 /* Debug level configuration. See debug.h for bits, sysfs modifiable */
0041 int brcmf_msg_level;
0042 module_param_named(debug, brcmf_msg_level, int, 0600);
0043 MODULE_PARM_DESC(debug, "Level of debug output");
0044 
0045 static int brcmf_p2p_enable;
0046 module_param_named(p2pon, brcmf_p2p_enable, int, 0);
0047 MODULE_PARM_DESC(p2pon, "Enable legacy p2p management functionality");
0048 
0049 static int brcmf_feature_disable;
0050 module_param_named(feature_disable, brcmf_feature_disable, int, 0);
0051 MODULE_PARM_DESC(feature_disable, "Disable features");
0052 
0053 static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
0054 module_param_string(alternative_fw_path, brcmf_firmware_path,
0055             BRCMF_FW_ALTPATH_LEN, 0400);
0056 MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");
0057 
0058 static int brcmf_fcmode;
0059 module_param_named(fcmode, brcmf_fcmode, int, 0);
0060 MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
0061 
0062 static int brcmf_roamoff;
0063 module_param_named(roamoff, brcmf_roamoff, int, 0400);
0064 MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
0065 
0066 static int brcmf_iapp_enable;
0067 module_param_named(iapp, brcmf_iapp_enable, int, 0);
0068 MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
0069 
0070 #ifdef DEBUG
0071 /* always succeed brcmf_bus_started() */
0072 static int brcmf_ignore_probe_fail;
0073 module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
0074 MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
0075 #endif
0076 
0077 static struct brcmfmac_platform_data *brcmfmac_pdata;
0078 struct brcmf_mp_global_t brcmf_mp_global;
0079 
0080 void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
0081 {
0082     struct brcmf_pub *drvr = ifp->drvr;
0083     struct brcmf_join_pref_params join_pref_params[2];
0084     int err;
0085 
0086     /* Setup join_pref to select target by RSSI (boost on 5GHz) */
0087     join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
0088     join_pref_params[0].len = 2;
0089     join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
0090     join_pref_params[0].band = WLC_BAND_5G;
0091 
0092     join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
0093     join_pref_params[1].len = 2;
0094     join_pref_params[1].rssi_gain = 0;
0095     join_pref_params[1].band = 0;
0096     err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
0097                        sizeof(join_pref_params));
0098     if (err)
0099         bphy_err(drvr, "Set join_pref error (%d)\n", err);
0100 }
0101 
0102 static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
0103                 struct brcmf_dload_data_le *dload_buf,
0104                 u32 len)
0105 {
0106     s32 err;
0107 
0108     flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
0109     dload_buf->flag = cpu_to_le16(flag);
0110     dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
0111     dload_buf->len = cpu_to_le32(len);
0112     dload_buf->crc = cpu_to_le32(0);
0113     len = sizeof(*dload_buf) + len - 1;
0114 
0115     err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
0116 
0117     return err;
0118 }
0119 
0120 static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
0121 {
0122     struct brcmf_pub *drvr = ifp->drvr;
0123     struct brcmf_bus *bus = drvr->bus_if;
0124     struct brcmf_dload_data_le *chunk_buf;
0125     const struct firmware *clm = NULL;
0126     u8 clm_name[BRCMF_FW_NAME_LEN];
0127     u32 chunk_len;
0128     u32 datalen;
0129     u32 cumulative_len;
0130     u16 dl_flag = DL_BEGIN;
0131     u32 status;
0132     s32 err;
0133 
0134     brcmf_dbg(TRACE, "Enter\n");
0135 
0136     memset(clm_name, 0, sizeof(clm_name));
0137     err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name);
0138     if (err) {
0139         bphy_err(drvr, "get CLM blob file name failed (%d)\n", err);
0140         return err;
0141     }
0142 
0143     err = firmware_request_nowarn(&clm, clm_name, bus->dev);
0144     if (err) {
0145         brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n",
0146                err);
0147         return 0;
0148     }
0149 
0150     chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
0151     if (!chunk_buf) {
0152         err = -ENOMEM;
0153         goto done;
0154     }
0155 
0156     datalen = clm->size;
0157     cumulative_len = 0;
0158     do {
0159         if (datalen > MAX_CHUNK_LEN) {
0160             chunk_len = MAX_CHUNK_LEN;
0161         } else {
0162             chunk_len = datalen;
0163             dl_flag |= DL_END;
0164         }
0165         memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
0166 
0167         err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
0168 
0169         dl_flag &= ~DL_BEGIN;
0170 
0171         cumulative_len += chunk_len;
0172         datalen -= chunk_len;
0173     } while ((datalen > 0) && (err == 0));
0174 
0175     if (err) {
0176         bphy_err(drvr, "clmload (%zu byte file) failed (%d)\n",
0177              clm->size, err);
0178         /* Retrieve clmload_status and print */
0179         err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
0180         if (err)
0181             bphy_err(drvr, "get clmload_status failed (%d)\n", err);
0182         else
0183             brcmf_dbg(INFO, "clmload_status=%d\n", status);
0184         err = -EIO;
0185     }
0186 
0187     kfree(chunk_buf);
0188 done:
0189     release_firmware(clm);
0190     return err;
0191 }
0192 
0193 int brcmf_c_set_cur_etheraddr(struct brcmf_if *ifp, const u8 *addr)
0194 {
0195     s32 err;
0196 
0197     err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", addr, ETH_ALEN);
0198     if (err < 0)
0199         bphy_err(ifp->drvr, "Setting cur_etheraddr failed, %d\n", err);
0200 
0201     return err;
0202 }
0203 
0204 /* On some boards there is no eeprom to hold the nvram, in this case instead
0205  * a board specific nvram is loaded from /lib/firmware. On most boards the
0206  * macaddr setting in the /lib/firmware nvram file is ignored because the
0207  * wifibt chip has a unique MAC programmed into the chip itself.
0208  * But in some cases the actual MAC from the /lib/firmware nvram file gets
0209  * used, leading to MAC conflicts.
0210  * The MAC addresses in the troublesome nvram files seem to all come from
0211  * the same nvram file template, so we only need to check for 1 known
0212  * address to detect this.
0213  */
0214 static const u8 brcmf_default_mac_address[ETH_ALEN] = {
0215     0x00, 0x90, 0x4c, 0xc5, 0x12, 0x38
0216 };
0217 
0218 int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
0219 {
0220     struct brcmf_pub *drvr = ifp->drvr;
0221     s8 eventmask[BRCMF_EVENTING_MASK_LEN];
0222     u8 buf[BRCMF_DCMD_SMLEN];
0223     struct brcmf_bus *bus;
0224     struct brcmf_rev_info_le revinfo;
0225     struct brcmf_rev_info *ri;
0226     char *clmver;
0227     char *ptr;
0228     s32 err;
0229 
0230     if (is_valid_ether_addr(ifp->mac_addr)) {
0231         /* set mac address */
0232         err = brcmf_c_set_cur_etheraddr(ifp, ifp->mac_addr);
0233         if (err < 0)
0234             goto done;
0235     } else {
0236         /* retrieve mac address */
0237         err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
0238                            sizeof(ifp->mac_addr));
0239         if (err < 0) {
0240             bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err);
0241             goto done;
0242         }
0243 
0244         if (ether_addr_equal_unaligned(ifp->mac_addr, brcmf_default_mac_address)) {
0245             bphy_err(drvr, "Default MAC is used, replacing with random MAC to avoid conflicts\n");
0246             eth_random_addr(ifp->mac_addr);
0247             ifp->ndev->addr_assign_type = NET_ADDR_RANDOM;
0248             err = brcmf_c_set_cur_etheraddr(ifp, ifp->mac_addr);
0249             if (err < 0)
0250                 goto done;
0251         }
0252     }
0253 
0254     memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
0255     memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
0256 
0257     bus = ifp->drvr->bus_if;
0258     ri = &ifp->drvr->revinfo;
0259 
0260     err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO,
0261                      &revinfo, sizeof(revinfo));
0262     if (err < 0) {
0263         bphy_err(drvr, "retrieving revision info failed, %d\n", err);
0264         strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname));
0265     } else {
0266         ri->vendorid = le32_to_cpu(revinfo.vendorid);
0267         ri->deviceid = le32_to_cpu(revinfo.deviceid);
0268         ri->radiorev = le32_to_cpu(revinfo.radiorev);
0269         ri->corerev = le32_to_cpu(revinfo.corerev);
0270         ri->boardid = le32_to_cpu(revinfo.boardid);
0271         ri->boardvendor = le32_to_cpu(revinfo.boardvendor);
0272         ri->boardrev = le32_to_cpu(revinfo.boardrev);
0273         ri->driverrev = le32_to_cpu(revinfo.driverrev);
0274         ri->ucoderev = le32_to_cpu(revinfo.ucoderev);
0275         ri->bus = le32_to_cpu(revinfo.bus);
0276         ri->phytype = le32_to_cpu(revinfo.phytype);
0277         ri->phyrev = le32_to_cpu(revinfo.phyrev);
0278         ri->anarev = le32_to_cpu(revinfo.anarev);
0279         ri->chippkg = le32_to_cpu(revinfo.chippkg);
0280         ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
0281 
0282         /* use revinfo if not known yet */
0283         if (!bus->chip) {
0284             bus->chip = le32_to_cpu(revinfo.chipnum);
0285             bus->chiprev = le32_to_cpu(revinfo.chiprev);
0286         }
0287     }
0288     ri->result = err;
0289 
0290     if (bus->chip)
0291         brcmf_chip_name(bus->chip, bus->chiprev,
0292                 ri->chipname, sizeof(ri->chipname));
0293 
0294     /* Do any CLM downloading */
0295     err = brcmf_c_process_clm_blob(ifp);
0296     if (err < 0) {
0297         bphy_err(drvr, "download CLM blob file failed, %d\n", err);
0298         goto done;
0299     }
0300 
0301     /* query for 'ver' to get version info from firmware */
0302     memset(buf, 0, sizeof(buf));
0303     err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
0304     if (err < 0) {
0305         bphy_err(drvr, "Retrieving version information failed, %d\n",
0306              err);
0307         goto done;
0308     }
0309     ptr = (char *)buf;
0310     strsep(&ptr, "\n");
0311 
0312     /* Print fw version info */
0313     brcmf_info("Firmware: %s %s\n", ri->chipname, buf);
0314 
0315     /* locate firmware version number for ethtool */
0316     ptr = strrchr(buf, ' ') + 1;
0317     strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
0318 
0319     /* Query for 'clmver' to get CLM version info from firmware */
0320     memset(buf, 0, sizeof(buf));
0321     err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
0322     if (err) {
0323         brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
0324     } else {
0325         clmver = (char *)buf;
0326         /* store CLM version for adding it to revinfo debugfs file */
0327         memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
0328 
0329         /* Replace all newline/linefeed characters with space
0330          * character
0331          */
0332         strreplace(clmver, '\n', ' ');
0333 
0334         brcmf_dbg(INFO, "CLM version = %s\n", clmver);
0335     }
0336 
0337     /* set mpc */
0338     err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
0339     if (err) {
0340         bphy_err(drvr, "failed setting mpc\n");
0341         goto done;
0342     }
0343 
0344     brcmf_c_set_joinpref_default(ifp);
0345 
0346     /* Setup event_msgs, enable E_IF */
0347     err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
0348                        BRCMF_EVENTING_MASK_LEN);
0349     if (err) {
0350         bphy_err(drvr, "Get event_msgs error (%d)\n", err);
0351         goto done;
0352     }
0353     setbit(eventmask, BRCMF_E_IF);
0354     err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
0355                        BRCMF_EVENTING_MASK_LEN);
0356     if (err) {
0357         bphy_err(drvr, "Set event_msgs error (%d)\n", err);
0358         goto done;
0359     }
0360 
0361     /* Setup default scan channel time */
0362     err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
0363                     BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
0364     if (err) {
0365         bphy_err(drvr, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
0366              err);
0367         goto done;
0368     }
0369 
0370     /* Setup default scan unassoc time */
0371     err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
0372                     BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
0373     if (err) {
0374         bphy_err(drvr, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
0375              err);
0376         goto done;
0377     }
0378 
0379     /* Enable tx beamforming, errors can be ignored (not supported) */
0380     (void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
0381 done:
0382     return err;
0383 }
0384 
0385 #ifndef CONFIG_BRCM_TRACING
0386 void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
0387 {
0388     struct va_format vaf;
0389     va_list args;
0390 
0391     va_start(args, fmt);
0392 
0393     vaf.fmt = fmt;
0394     vaf.va = &args;
0395     if (bus)
0396         dev_err(bus->dev, "%s: %pV", func, &vaf);
0397     else
0398         pr_err("%s: %pV", func, &vaf);
0399 
0400     va_end(args);
0401 }
0402 #endif
0403 
0404 #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
0405 void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
0406 {
0407     struct va_format vaf = {
0408         .fmt = fmt,
0409     };
0410     va_list args;
0411 
0412     va_start(args, fmt);
0413     vaf.va = &args;
0414     if (brcmf_msg_level & level)
0415         pr_debug("%s %pV", func, &vaf);
0416     trace_brcmf_dbg(level, func, &vaf);
0417     va_end(args);
0418 }
0419 #endif
0420 
0421 static void brcmf_mp_attach(void)
0422 {
0423     /* If module param firmware path is set then this will always be used,
0424      * if not set then if available use the platform data version. To make
0425      * sure it gets initialized at all, always copy the module param version
0426      */
0427     strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
0428         BRCMF_FW_ALTPATH_LEN);
0429     if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
0430         (brcmf_mp_global.firmware_path[0] == '\0')) {
0431         strlcpy(brcmf_mp_global.firmware_path,
0432             brcmfmac_pdata->fw_alternative_path,
0433             BRCMF_FW_ALTPATH_LEN);
0434     }
0435 }
0436 
0437 struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
0438                            enum brcmf_bus_type bus_type,
0439                            u32 chip, u32 chiprev)
0440 {
0441     struct brcmf_mp_device *settings;
0442     struct brcmfmac_pd_device *device_pd;
0443     bool found;
0444     int i;
0445 
0446     brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip,
0447           chiprev);
0448     settings = kzalloc(sizeof(*settings), GFP_ATOMIC);
0449     if (!settings)
0450         return NULL;
0451 
0452     /* start by using the module paramaters */
0453     settings->p2p_enable = !!brcmf_p2p_enable;
0454     settings->feature_disable = brcmf_feature_disable;
0455     settings->fcmode = brcmf_fcmode;
0456     settings->roamoff = !!brcmf_roamoff;
0457     settings->iapp = !!brcmf_iapp_enable;
0458 #ifdef DEBUG
0459     settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
0460 #endif
0461 
0462     if (bus_type == BRCMF_BUSTYPE_SDIO)
0463         settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
0464 
0465     /* See if there is any device specific platform data configured */
0466     found = false;
0467     if (brcmfmac_pdata) {
0468         for (i = 0; i < brcmfmac_pdata->device_count; i++) {
0469             device_pd = &brcmfmac_pdata->devices[i];
0470             if ((device_pd->bus_type == bus_type) &&
0471                 (device_pd->id == chip) &&
0472                 ((device_pd->rev == chiprev) ||
0473                  (device_pd->rev == -1))) {
0474                 brcmf_dbg(INFO, "Platform data for device found\n");
0475                 settings->country_codes =
0476                         device_pd->country_codes;
0477                 if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
0478                     memcpy(&settings->bus.sdio,
0479                            &device_pd->bus.sdio,
0480                            sizeof(settings->bus.sdio));
0481                 found = true;
0482                 break;
0483             }
0484         }
0485     }
0486     if (!found) {
0487         /* No platform data for this device, try OF and DMI data */
0488         brcmf_dmi_probe(settings, chip, chiprev);
0489         brcmf_of_probe(dev, bus_type, settings);
0490     }
0491     return settings;
0492 }
0493 
0494 void brcmf_release_module_param(struct brcmf_mp_device *module_param)
0495 {
0496     kfree(module_param);
0497 }
0498 
0499 static int __init brcmf_common_pd_probe(struct platform_device *pdev)
0500 {
0501     brcmf_dbg(INFO, "Enter\n");
0502 
0503     brcmfmac_pdata = dev_get_platdata(&pdev->dev);
0504 
0505     if (brcmfmac_pdata->power_on)
0506         brcmfmac_pdata->power_on();
0507 
0508     return 0;
0509 }
0510 
0511 static int brcmf_common_pd_remove(struct platform_device *pdev)
0512 {
0513     brcmf_dbg(INFO, "Enter\n");
0514 
0515     if (brcmfmac_pdata->power_off)
0516         brcmfmac_pdata->power_off();
0517 
0518     return 0;
0519 }
0520 
0521 static struct platform_driver brcmf_pd = {
0522     .remove     = brcmf_common_pd_remove,
0523     .driver     = {
0524         .name   = BRCMFMAC_PDATA_NAME,
0525     }
0526 };
0527 
0528 static int __init brcmfmac_module_init(void)
0529 {
0530     int err;
0531 
0532     /* Get the platform data (if available) for our devices */
0533     err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe);
0534     if (err == -ENODEV)
0535         brcmf_dbg(INFO, "No platform data available.\n");
0536 
0537     /* Initialize global module paramaters */
0538     brcmf_mp_attach();
0539 
0540     /* Continue the initialization by registering the different busses */
0541     err = brcmf_core_init();
0542     if (err) {
0543         if (brcmfmac_pdata)
0544             platform_driver_unregister(&brcmf_pd);
0545     }
0546 
0547     return err;
0548 }
0549 
0550 static void __exit brcmfmac_module_exit(void)
0551 {
0552     brcmf_core_exit();
0553     if (brcmfmac_pdata)
0554         platform_driver_unregister(&brcmf_pd);
0555 }
0556 
0557 module_init(brcmfmac_module_init);
0558 module_exit(brcmfmac_module_exit);
0559