From 5779ae6a5559252adabc5b5e807381dc7a16f1ff Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Sat, 12 Jul 2014 08:49:34 +0200 Subject: brcmfmac: Cleanup used device IDs. This patch cleans up used broadcom IDs, device IDs for all the bus layers and uses consistent naming for all IDs. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 23 +++++---- drivers/net/wireless/brcm80211/brcmfmac/chip.c | 28 +++++----- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 32 ++++++------ drivers/net/wireless/brcm80211/brcmfmac/usb.c | 49 +++++++++--------- .../net/wireless/brcm80211/include/brcm_hw_ids.h | 60 +++++++++++++++------- 5 files changed, 107 insertions(+), 85 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index a16e644e7c08..f467cafe3e8f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -979,18 +978,20 @@ out: return ret; } +#define BRCMF_SDIO_DEVICE(dev_id) \ + {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)} + /* devices we support, null terminated */ static const struct sdio_device_id brcmf_sdmmc_ids[] = { - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, - SDIO_DEVICE_ID_BROADCOM_4335_4339)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)}, - { /* end: all zeroes */ }, + BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID), + { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c index c7c9f15c0fe0..96800db0536b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c @@ -482,30 +482,30 @@ static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) { switch (ci->pub.chip) { - case BCM4329_CHIP_ID: + case BRCM_CC_4329_CHIP_ID: ci->pub.ramsize = BCM4329_RAMSIZE; break; - case BCM43143_CHIP_ID: + case BRCM_CC_43143_CHIP_ID: ci->pub.ramsize = BCM43143_RAMSIZE; break; - case BCM43241_CHIP_ID: + case BRCM_CC_43241_CHIP_ID: ci->pub.ramsize = 0x90000; break; - case BCM4330_CHIP_ID: + case BRCM_CC_4330_CHIP_ID: ci->pub.ramsize = 0x48000; break; - case BCM4334_CHIP_ID: + case BRCM_CC_4334_CHIP_ID: ci->pub.ramsize = 0x80000; break; - case BCM4335_CHIP_ID: + case BRCM_CC_4335_CHIP_ID: ci->pub.ramsize = 0xc0000; ci->pub.rambase = 0x180000; break; - case BCM43362_CHIP_ID: + case BRCM_CC_43362_CHIP_ID: ci->pub.ramsize = 0x3c000; break; - case BCM4339_CHIP_ID: - case BCM4354_CHIP_ID: + case BRCM_CC_4339_CHIP_ID: + case BRCM_CC_4354_CHIP_ID: ci->pub.ramsize = 0xc0000; ci->pub.rambase = 0x180000; break; @@ -682,7 +682,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) ci->pub.chiprev); if (socitype == SOCI_SB) { - if (ci->pub.chip != BCM4329_CHIP_ID) { + if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) { brcmf_err("SB chip is not supported\n"); return -ENODEV; } @@ -1008,13 +1008,13 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub) chip = container_of(pub, struct brcmf_chip_priv, pub); switch (pub->chip) { - case BCM4354_CHIP_ID: + case BRCM_CC_4354_CHIP_ID: /* explicitly check SR engine enable bit */ pmu_cc3_mask = BIT(2); /* fall-through */ - case BCM43241_CHIP_ID: - case BCM4335_CHIP_ID: - case BCM4339_CHIP_ID: + case BRCM_CC_43241_CHIP_ID: + case BRCM_CC_4335_CHIP_ID: + case BRCM_CC_4339_CHIP_ID: /* read PMU chipcontrol register 3 */ addr = CORE_CC_REG(base, chipcontrol_addr); chip->ops->write32(chip->ctx, addr, 3); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 8fa0dbbbda72..bf9bc2d89230 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -620,16 +620,16 @@ enum brcmf_firmware_type { name ## _FIRMWARE_NAME, name ## _NVRAM_NAME static const struct brcmf_firmware_names brcmf_fwname_data[] = { - { BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) }, - { BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) }, - { BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, - { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, - { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, - { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, - { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, - { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, - { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } + { BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) }, + { BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) }, + { BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, + { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, + { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, + { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, + { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, + { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, + { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } }; static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci, @@ -3598,17 +3598,17 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, return; switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { - case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): + case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12): str_tab = sdiod_drvstr_tab1_1v8; str_mask = 0x00003800; str_shift = 11; break; - case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17): + case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17): str_tab = sdiod_drvstr_tab6_1v8; str_mask = 0x00001800; str_shift = 11; break; - case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): + case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17): /* note: 43143 does not support tristate */ i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) { @@ -3619,7 +3619,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n", ci->name, drivestrength); break; - case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): + case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13): str_tab = sdiod_drive_strength_tab5_1v8; str_mask = 0x00003800; str_shift = 11; @@ -3720,12 +3720,12 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr) u32 val, rev; val = brcmf_sdiod_regrl(sdiodev, addr, NULL); - if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && + if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID && addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; if (rev >= 2) { val &= ~CID_ID_MASK; - val |= BCM4339_CHIP_ID; + val |= BRCM_CC_4339_CHIP_ID; } } return val; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index b732a99e402c..dc135915470d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -913,16 +914,16 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) static bool brcmf_usb_chip_support(int chipid, int chiprev) { switch(chipid) { - case 43143: + case BRCM_CC_43143_CHIP_ID: return true; - case 43235: - case 43236: - case 43238: + case BRCM_CC_43235_CHIP_ID: + case BRCM_CC_43236_CHIP_ID: + case BRCM_CC_43238_CHIP_ID: return (chiprev == 3); - case 43242: + case BRCM_CC_43242_CHIP_ID: return true; - case 43566: - case 43569: + case BRCM_CC_43566_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: return true; default: break; @@ -1016,16 +1017,16 @@ static int check_file(const u8 *headers) static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo) { switch (devinfo->bus_pub.devid) { - case 43143: + case BRCM_CC_43143_CHIP_ID: return BRCMF_USB_43143_FW_NAME; - case 43235: - case 43236: - case 43238: + case BRCM_CC_43235_CHIP_ID: + case BRCM_CC_43236_CHIP_ID: + case BRCM_CC_43238_CHIP_ID: return BRCMF_USB_43236_FW_NAME; - case 43242: + case BRCM_CC_43242_CHIP_ID: return BRCMF_USB_43242_FW_NAME; - case 43566: - case 43569: + case BRCM_CC_43566_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: return BRCMF_USB_43569_FW_NAME; default: return NULL; @@ -1366,21 +1367,17 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) brcmf_usb_probe_phase2); } -#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c -#define BRCMF_USB_DEVICE_ID_43143 0xbd1e -#define BRCMF_USB_DEVICE_ID_43236 0xbd17 -#define BRCMF_USB_DEVICE_ID_43242 0xbd1f -#define BRCMF_USB_DEVICE_ID_43569 0xbd27 -#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc +#define BRCMF_USB_DEVICE(dev_id) \ + { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) } static struct usb_device_id brcmf_usb_devid_table[] = { - { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) }, - { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) }, - { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) }, - { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43569) }, + BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID), /* special entry for device with firmware loaded and running */ - { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, - { } + BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID), + { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index d816270db3be..64d1a7ba040c 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h @@ -17,32 +17,56 @@ #ifndef _BRCM_HW_IDS_H_ #define _BRCM_HW_IDS_H_ -#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ +#include +#include + +#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c +#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM +#define BRCM_SDIO_VENDOR_ID_BROADCOM SDIO_VENDOR_ID_BROADCOM + +/* Chipcommon Core Chip IDs */ +#define BRCM_CC_43143_CHIP_ID 43143 +#define BRCM_CC_43235_CHIP_ID 43235 +#define BRCM_CC_43236_CHIP_ID 43236 +#define BRCM_CC_43238_CHIP_ID 43238 +#define BRCM_CC_43241_CHIP_ID 0x4324 +#define BRCM_CC_43242_CHIP_ID 43242 +#define BRCM_CC_4329_CHIP_ID 0x4329 +#define BRCM_CC_4330_CHIP_ID 0x4330 +#define BRCM_CC_4334_CHIP_ID 0x4334 +#define BRCM_CC_43362_CHIP_ID 43362 +#define BRCM_CC_4335_CHIP_ID 0x4335 +#define BRCM_CC_4339_CHIP_ID 0x4339 +#define BRCM_CC_4354_CHIP_ID 0x4354 +#define BRCM_CC_43566_CHIP_ID 43566 +#define BRCM_CC_43569_CHIP_ID 43569 + +/* SDIO Device IDs */ +#define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID +#define BRCM_SDIO_43241_DEVICE_ID BRCM_CC_43241_CHIP_ID +#define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID +#define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID +#define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID +#define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID +#define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID +#define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID +/* USB Device IDs */ +#define BRCM_USB_43143_DEVICE_ID 0xbd1e +#define BRCM_USB_43236_DEVICE_ID 0xbd17 +#define BRCM_USB_43242_DEVICE_ID 0xbd1f +#define BRCM_USB_43569_DEVICE_ID 0xbd27 +#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc + +/* brcmsmac IDs */ +#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ #define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ #define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */ - #define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ - #define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ #define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ -/* Chipcommon Core Chip IDs */ #define BCM4313_CHIP_ID 0x4313 -#define BCM43143_CHIP_ID 43143 #define BCM43224_CHIP_ID 43224 -#define BCM43225_CHIP_ID 43225 -#define BCM43235_CHIP_ID 43235 -#define BCM43236_CHIP_ID 43236 -#define BCM43238_CHIP_ID 43238 -#define BCM43241_CHIP_ID 0x4324 -#define BCM4329_CHIP_ID 0x4329 -#define BCM4330_CHIP_ID 0x4330 -#define BCM4331_CHIP_ID 0x4331 -#define BCM4334_CHIP_ID 0x4334 -#define BCM4335_CHIP_ID 0x4335 -#define BCM43362_CHIP_ID 43362 -#define BCM4339_CHIP_ID 0x4339 -#define BCM4354_CHIP_ID 0x4354 #endif /* _BRCM_HW_IDS_H_ */ -- cgit v1.2.2 From 1b1e4e9e3abca01b7be6400db879ca8c475a2c96 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:35 +0200 Subject: brcmfmac: make use of seq_file API for debugfs entries The use of seq_file simplifies the debugfs code. Simpler is better. Reviewed-by: Hante Meuleman Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 249 ++++++++++----------- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 122 ++++------ 2 files changed, 170 insertions(+), 201 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 03fe8aca4d32..e1ac932a3154 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -41,28 +41,27 @@ void brcmf_debugfs_exit(void) root_folder = NULL; } -static -ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) { - struct brcmf_pub *drvr = f->private_data; + struct brcmf_pub *drvr = seq->private; struct brcmf_bus *bus = drvr->bus_if; - char buf[40]; - int res; - /* only allow read from start */ - if (*ppos > 0) - return 0; + seq_printf(seq, "chip: %x(%u) rev %u\n", + bus->chip, bus->chip, bus->chiprev); + return 0; +} - res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n", - bus->chip, bus->chip, bus->chiprev); - return simple_read_from_buffer(data, count, ppos, buf, res); +static int brcmf_debugfs_chipinfo_open(struct inode *inode, struct file *f) +{ + return single_open(f, brcmf_debugfs_chipinfo_read, inode->i_private); } static const struct file_operations brcmf_debugfs_chipinfo_ops = { .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_debugfs_chipinfo_read + .open = brcmf_debugfs_chipinfo_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek }; static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr) @@ -98,55 +97,54 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) return drvr->dbgfs_dir; } -static -ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data) { - struct brcmf_sdio_count *sdcnt = f->private_data; - char buf[750]; - int res; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), - "intrcount: %u\nlastintrs: %u\n" - "pollcnt: %u\nregfails: %u\n" - "tx_sderrs: %u\nfcqueued: %u\n" - "rxrtx: %u\nrx_toolong: %u\n" - "rxc_errors: %u\nrx_hdrfail: %u\n" - "rx_badhdr: %u\nrx_badseq: %u\n" - "fc_rcvd: %u\nfc_xoff: %u\n" - "fc_xon: %u\nrxglomfail: %u\n" - "rxglomframes: %u\nrxglompkts: %u\n" - "f2rxhdrs: %u\nf2rxdata: %u\n" - "f2txdata: %u\nf1regdata: %u\n" - "tickcnt: %u\ntx_ctlerrs: %lu\n" - "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" - "rx_ctlpkts: %lu\nrx_readahead: %lu\n", - sdcnt->intrcount, sdcnt->lastintrs, - sdcnt->pollcnt, sdcnt->regfails, - sdcnt->tx_sderrs, sdcnt->fcqueued, - sdcnt->rxrtx, sdcnt->rx_toolong, - sdcnt->rxc_errors, sdcnt->rx_hdrfail, - sdcnt->rx_badhdr, sdcnt->rx_badseq, - sdcnt->fc_rcvd, sdcnt->fc_xoff, - sdcnt->fc_xon, sdcnt->rxglomfail, - sdcnt->rxglomframes, sdcnt->rxglompkts, - sdcnt->f2rxhdrs, sdcnt->f2rxdata, - sdcnt->f2txdata, sdcnt->f1regdata, - sdcnt->tickcnt, sdcnt->tx_ctlerrs, - sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, - sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); - - return simple_read_from_buffer(data, count, ppos, buf, res); + struct brcmf_sdio_count *sdcnt = seq->private; + + seq_printf(seq, + "intrcount: %u\nlastintrs: %u\n" + "pollcnt: %u\nregfails: %u\n" + "tx_sderrs: %u\nfcqueued: %u\n" + "rxrtx: %u\nrx_toolong: %u\n" + "rxc_errors: %u\nrx_hdrfail: %u\n" + "rx_badhdr: %u\nrx_badseq: %u\n" + "fc_rcvd: %u\nfc_xoff: %u\n" + "fc_xon: %u\nrxglomfail: %u\n" + "rxglomframes: %u\nrxglompkts: %u\n" + "f2rxhdrs: %u\nf2rxdata: %u\n" + "f2txdata: %u\nf1regdata: %u\n" + "tickcnt: %u\ntx_ctlerrs: %lu\n" + "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" + "rx_ctlpkts: %lu\nrx_readahead: %lu\n", + sdcnt->intrcount, sdcnt->lastintrs, + sdcnt->pollcnt, sdcnt->regfails, + sdcnt->tx_sderrs, sdcnt->fcqueued, + sdcnt->rxrtx, sdcnt->rx_toolong, + sdcnt->rxc_errors, sdcnt->rx_hdrfail, + sdcnt->rx_badhdr, sdcnt->rx_badseq, + sdcnt->fc_rcvd, sdcnt->fc_xoff, + sdcnt->fc_xon, sdcnt->rxglomfail, + sdcnt->rxglomframes, sdcnt->rxglompkts, + sdcnt->f2rxhdrs, sdcnt->f2rxdata, + sdcnt->f2txdata, sdcnt->f1regdata, + sdcnt->tickcnt, sdcnt->tx_ctlerrs, + sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, + sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); + + return 0; +} + +static int brcmf_debugfs_sdio_count_open(struct inode *inode, struct file *f) +{ + return single_open(f, brcmf_debugfs_sdio_count_read, inode->i_private); } static const struct file_operations brcmf_debugfs_sdio_counter_ops = { .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_debugfs_sdio_counter_read + .open = brcmf_debugfs_sdio_count_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek }; void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, @@ -159,79 +157,78 @@ void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, sdcnt, &brcmf_debugfs_sdio_counter_ops); } -static -ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data) +{ + struct brcmf_fws_stats *fwstats = seq->private; + + seq_printf(seq, + "header_pulls: %u\n" + "header_only_pkt: %u\n" + "tlv_parse_failed: %u\n" + "tlv_invalid_type: %u\n" + "mac_update_fails: %u\n" + "ps_update_fails: %u\n" + "if_update_fails: %u\n" + "pkt2bus: %u\n" + "generic_error: %u\n" + "rollback_success: %u\n" + "rollback_failed: %u\n" + "delayq_full: %u\n" + "supprq_full: %u\n" + "txs_indicate: %u\n" + "txs_discard: %u\n" + "txs_suppr_core: %u\n" + "txs_suppr_ps: %u\n" + "txs_tossed: %u\n" + "txs_host_tossed: %u\n" + "bus_flow_block: %u\n" + "fws_flow_block: %u\n" + "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n" + "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n", + fwstats->header_pulls, + fwstats->header_only_pkt, + fwstats->tlv_parse_failed, + fwstats->tlv_invalid_type, + fwstats->mac_update_failed, + fwstats->mac_ps_update_failed, + fwstats->if_update_failed, + fwstats->pkt2bus, + fwstats->generic_error, + fwstats->rollback_success, + fwstats->rollback_failed, + fwstats->delayq_full_error, + fwstats->supprq_full_error, + fwstats->txs_indicate, + fwstats->txs_discard, + fwstats->txs_supp_core, + fwstats->txs_supp_ps, + fwstats->txs_tossed, + fwstats->txs_host_tossed, + fwstats->bus_flow_block, + fwstats->fws_flow_block, + fwstats->send_pkts[0], fwstats->send_pkts[1], + fwstats->send_pkts[2], fwstats->send_pkts[3], + fwstats->send_pkts[4], + fwstats->requested_sent[0], + fwstats->requested_sent[1], + fwstats->requested_sent[2], + fwstats->requested_sent[3], + fwstats->requested_sent[4]); + + return 0; +} + +static int brcmf_debugfs_fws_stats_open(struct inode *inode, struct file *f) { - struct brcmf_fws_stats *fwstats = f->private_data; - char buf[650]; - int res; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), - "header_pulls: %u\n" - "header_only_pkt: %u\n" - "tlv_parse_failed: %u\n" - "tlv_invalid_type: %u\n" - "mac_update_fails: %u\n" - "ps_update_fails: %u\n" - "if_update_fails: %u\n" - "pkt2bus: %u\n" - "generic_error: %u\n" - "rollback_success: %u\n" - "rollback_failed: %u\n" - "delayq_full: %u\n" - "supprq_full: %u\n" - "txs_indicate: %u\n" - "txs_discard: %u\n" - "txs_suppr_core: %u\n" - "txs_suppr_ps: %u\n" - "txs_tossed: %u\n" - "txs_host_tossed: %u\n" - "bus_flow_block: %u\n" - "fws_flow_block: %u\n" - "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n" - "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n", - fwstats->header_pulls, - fwstats->header_only_pkt, - fwstats->tlv_parse_failed, - fwstats->tlv_invalid_type, - fwstats->mac_update_failed, - fwstats->mac_ps_update_failed, - fwstats->if_update_failed, - fwstats->pkt2bus, - fwstats->generic_error, - fwstats->rollback_success, - fwstats->rollback_failed, - fwstats->delayq_full_error, - fwstats->supprq_full_error, - fwstats->txs_indicate, - fwstats->txs_discard, - fwstats->txs_supp_core, - fwstats->txs_supp_ps, - fwstats->txs_tossed, - fwstats->txs_host_tossed, - fwstats->bus_flow_block, - fwstats->fws_flow_block, - fwstats->send_pkts[0], fwstats->send_pkts[1], - fwstats->send_pkts[2], fwstats->send_pkts[3], - fwstats->send_pkts[4], - fwstats->requested_sent[0], - fwstats->requested_sent[1], - fwstats->requested_sent[2], - fwstats->requested_sent[3], - fwstats->requested_sent[4]); - - return simple_read_from_buffer(data, count, ppos, buf, res); + return single_open(f, brcmf_debugfs_fws_stats_read, inode->i_private); } static const struct file_operations brcmf_debugfs_fws_stats_ops = { .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_debugfs_fws_stats_read + .open = brcmf_debugfs_fws_stats_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek }; void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index bf9bc2d89230..0c98a7942a0f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2898,16 +2898,13 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } #ifdef DEBUG -static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, - struct sdpcm_shared *sh, char __user *data, - size_t count) +static int brcmf_sdio_dump_console(struct seq_file *seq, struct brcmf_sdio *bus, + struct sdpcm_shared *sh) { u32 addr, console_ptr, console_size, console_index; char *conbuf = NULL; __le32 sh_val; int rv; - loff_t pos = 0; - int nbytes = 0; /* obtain console information from device memory */ addr = sh->console_addr + offsetof(struct rte_console, log_le); @@ -2945,33 +2942,24 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, if (rv < 0) goto done; - rv = simple_read_from_buffer(data, count, &pos, - conbuf + console_index, - console_size - console_index); + rv = seq_write(seq, conbuf + console_index, + console_size - console_index); if (rv < 0) goto done; - nbytes = rv; - if (console_index > 0) { - pos = 0; - rv = simple_read_from_buffer(data+nbytes, count, &pos, - conbuf, console_index - 1); - if (rv < 0) - goto done; - rv += nbytes; - } + if (console_index > 0) + rv = seq_write(seq, conbuf, console_index - 1); + done: vfree(conbuf); return rv; } -static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, - char __user *data, size_t count) +static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus, + struct sdpcm_shared *sh) { - int error, res; - char buf[350]; + int error; struct brcmf_trap_info tr; - loff_t pos = 0; if ((sh->flags & SDPCM_SHARED_TRAP) == 0) { brcmf_dbg(INFO, "no trap in firmware\n"); @@ -2983,34 +2971,30 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, if (error < 0) return error; - res = scnprintf(buf, sizeof(buf), - "dongle trap info: type 0x%x @ epc 0x%08x\n" - " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" - " lr 0x%08x pc 0x%08x offset 0x%x\n" - " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" - " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", - le32_to_cpu(tr.type), le32_to_cpu(tr.epc), - le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), - le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), - le32_to_cpu(tr.pc), sh->trap_addr, - le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), - le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), - le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), - le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); - - return simple_read_from_buffer(data, count, &pos, buf, res); + seq_printf(seq, + "dongle trap info: type 0x%x @ epc 0x%08x\n" + " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" + " lr 0x%08x pc 0x%08x offset 0x%x\n" + " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" + " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", + le32_to_cpu(tr.type), le32_to_cpu(tr.epc), + le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), + le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), + le32_to_cpu(tr.pc), sh->trap_addr, + le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), + le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), + le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), + le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); + + return 0; } -static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, - struct sdpcm_shared *sh, char __user *data, - size_t count) +static int brcmf_sdio_assert_info(struct seq_file *seq, struct brcmf_sdio *bus, + struct sdpcm_shared *sh) { int error = 0; - char buf[200]; char file[80] = "?"; char expr[80] = ""; - int res; - loff_t pos = 0; if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { brcmf_dbg(INFO, "firmware not built with -assert\n"); @@ -3035,10 +3019,9 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, } sdio_release_host(bus->sdiodev->func[1]); - res = scnprintf(buf, sizeof(buf), - "dongle assert: %s:%d: assert(%s)\n", - file, sh->assert_line, expr); - return simple_read_from_buffer(data, count, &pos, buf, res); + seq_printf(seq, "dongle assert: %s:%d: assert(%s)\n", + file, sh->assert_line, expr); + return 0; } static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) @@ -3062,58 +3045,47 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) return 0; } -static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_sdio_died_dump(struct seq_file *seq, struct brcmf_sdio *bus) { int error = 0; struct sdpcm_shared sh; - int nbytes = 0; - loff_t pos = *ppos; - - if (pos != 0) - return 0; error = brcmf_sdio_readshared(bus, &sh); if (error < 0) goto done; - error = brcmf_sdio_assert_info(bus, &sh, data, count); + error = brcmf_sdio_assert_info(seq, bus, &sh); if (error < 0) goto done; - nbytes = error; - error = brcmf_sdio_trap_info(bus, &sh, data+nbytes, count); + error = brcmf_sdio_trap_info(seq, bus, &sh); if (error < 0) goto done; - nbytes += error; - error = brcmf_sdio_dump_console(bus, &sh, data+nbytes, count); - if (error < 0) - goto done; - nbytes += error; + error = brcmf_sdio_dump_console(seq, bus, &sh); - error = nbytes; - *ppos += nbytes; done: return error; } -static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data) { - struct brcmf_sdio *bus = f->private_data; - int res; + struct brcmf_sdio *bus = seq->private; - res = brcmf_sdio_died_dump(bus, data, count, ppos); - if (res > 0) - *ppos += res; - return (ssize_t)res; + return brcmf_sdio_died_dump(seq, bus); +} + +static int brcmf_sdio_forensic_open(struct inode *inode, struct file *f) +{ + return single_open(f, brcmf_sdio_forensic_read, inode->i_private); } static const struct file_operations brcmf_sdio_forensic_ops = { .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_sdio_forensic_read + .open = brcmf_sdio_forensic_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek }; static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) -- cgit v1.2.2 From 82d957e09d4f0ff8091ca67e39b51ec6bdc672b1 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:36 +0200 Subject: brcmfmac: rework debugfs functions in the driver Reworked the debugfs functions in the driver making it easier for other driver parts to add a debugfs entry and keeping the information they want to expose in debugfs private, ie. not in a header. This is accomplished by providing the function brcmf_debugfs_add_entry() in which the caller provides a read function in which they provide the content. The debugfs function will take care of creating the debugfs entry and cleaning up upon removal. Reviewed-by: Hante Meuleman Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 179 ++++----------------- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 74 +-------- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 89 ++++++++-- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 100 +++++++++++- 4 files changed, 207 insertions(+), 235 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index e1ac932a3154..be9f4f829192 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -43,37 +43,13 @@ void brcmf_debugfs_exit(void) static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) { - struct brcmf_pub *drvr = seq->private; - struct brcmf_bus *bus = drvr->bus_if; + struct brcmf_bus *bus = dev_get_drvdata(seq->private); seq_printf(seq, "chip: %x(%u) rev %u\n", bus->chip, bus->chip, bus->chiprev); return 0; } -static int brcmf_debugfs_chipinfo_open(struct inode *inode, struct file *f) -{ - return single_open(f, brcmf_debugfs_chipinfo_read, inode->i_private); -} - -static const struct file_operations brcmf_debugfs_chipinfo_ops = { - .owner = THIS_MODULE, - .open = brcmf_debugfs_chipinfo_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek -}; - -static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr) -{ - struct dentry *dentry = drvr->dbgfs_dir; - - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr, - &brcmf_debugfs_chipinfo_ops); - return 0; -} - int brcmf_debugfs_attach(struct brcmf_pub *drvr) { struct device *dev = drvr->bus_if->dev; @@ -82,7 +58,8 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr) return -ENODEV; drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); - brcmf_debugfs_create_chipinfo(drvr); + brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read); + return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); } @@ -97,146 +74,44 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) return drvr->dbgfs_dir; } -static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data) -{ - struct brcmf_sdio_count *sdcnt = seq->private; - - seq_printf(seq, - "intrcount: %u\nlastintrs: %u\n" - "pollcnt: %u\nregfails: %u\n" - "tx_sderrs: %u\nfcqueued: %u\n" - "rxrtx: %u\nrx_toolong: %u\n" - "rxc_errors: %u\nrx_hdrfail: %u\n" - "rx_badhdr: %u\nrx_badseq: %u\n" - "fc_rcvd: %u\nfc_xoff: %u\n" - "fc_xon: %u\nrxglomfail: %u\n" - "rxglomframes: %u\nrxglompkts: %u\n" - "f2rxhdrs: %u\nf2rxdata: %u\n" - "f2txdata: %u\nf1regdata: %u\n" - "tickcnt: %u\ntx_ctlerrs: %lu\n" - "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" - "rx_ctlpkts: %lu\nrx_readahead: %lu\n", - sdcnt->intrcount, sdcnt->lastintrs, - sdcnt->pollcnt, sdcnt->regfails, - sdcnt->tx_sderrs, sdcnt->fcqueued, - sdcnt->rxrtx, sdcnt->rx_toolong, - sdcnt->rxc_errors, sdcnt->rx_hdrfail, - sdcnt->rx_badhdr, sdcnt->rx_badseq, - sdcnt->fc_rcvd, sdcnt->fc_xoff, - sdcnt->fc_xon, sdcnt->rxglomfail, - sdcnt->rxglomframes, sdcnt->rxglompkts, - sdcnt->f2rxhdrs, sdcnt->f2rxdata, - sdcnt->f2txdata, sdcnt->f1regdata, - sdcnt->tickcnt, sdcnt->tx_ctlerrs, - sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, - sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); - - return 0; -} +struct brcmf_debugfs_entry { + int (*read)(struct seq_file *seq, void *data); + struct brcmf_pub *drvr; +}; -static int brcmf_debugfs_sdio_count_open(struct inode *inode, struct file *f) +static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f) { - return single_open(f, brcmf_debugfs_sdio_count_read, inode->i_private); + struct brcmf_debugfs_entry *entry = inode->i_private; + + return single_open(f, entry->read, entry->drvr->bus_if->dev); } -static const struct file_operations brcmf_debugfs_sdio_counter_ops = { +static const struct file_operations brcmf_debugfs_def_ops = { .owner = THIS_MODULE, - .open = brcmf_debugfs_sdio_count_open, + .open = brcmf_debugfs_entry_open, .release = single_release, .read = seq_read, .llseek = seq_lseek }; -void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, - struct brcmf_sdio_count *sdcnt) +int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) { - struct dentry *dentry = drvr->dbgfs_dir; + struct dentry *dentry = drvr->dbgfs_dir; + struct brcmf_debugfs_entry *entry; - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("counters", S_IRUGO, dentry, - sdcnt, &brcmf_debugfs_sdio_counter_ops); -} + if (IS_ERR_OR_NULL(dentry)) + return -ENOENT; -static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data) -{ - struct brcmf_fws_stats *fwstats = seq->private; - - seq_printf(seq, - "header_pulls: %u\n" - "header_only_pkt: %u\n" - "tlv_parse_failed: %u\n" - "tlv_invalid_type: %u\n" - "mac_update_fails: %u\n" - "ps_update_fails: %u\n" - "if_update_fails: %u\n" - "pkt2bus: %u\n" - "generic_error: %u\n" - "rollback_success: %u\n" - "rollback_failed: %u\n" - "delayq_full: %u\n" - "supprq_full: %u\n" - "txs_indicate: %u\n" - "txs_discard: %u\n" - "txs_suppr_core: %u\n" - "txs_suppr_ps: %u\n" - "txs_tossed: %u\n" - "txs_host_tossed: %u\n" - "bus_flow_block: %u\n" - "fws_flow_block: %u\n" - "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n" - "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n", - fwstats->header_pulls, - fwstats->header_only_pkt, - fwstats->tlv_parse_failed, - fwstats->tlv_invalid_type, - fwstats->mac_update_failed, - fwstats->mac_ps_update_failed, - fwstats->if_update_failed, - fwstats->pkt2bus, - fwstats->generic_error, - fwstats->rollback_success, - fwstats->rollback_failed, - fwstats->delayq_full_error, - fwstats->supprq_full_error, - fwstats->txs_indicate, - fwstats->txs_discard, - fwstats->txs_supp_core, - fwstats->txs_supp_ps, - fwstats->txs_tossed, - fwstats->txs_host_tossed, - fwstats->bus_flow_block, - fwstats->fws_flow_block, - fwstats->send_pkts[0], fwstats->send_pkts[1], - fwstats->send_pkts[2], fwstats->send_pkts[3], - fwstats->send_pkts[4], - fwstats->requested_sent[0], - fwstats->requested_sent[1], - fwstats->requested_sent[2], - fwstats->requested_sent[3], - fwstats->requested_sent[4]); + entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; - return 0; -} + entry->read = read_fn; + entry->drvr = drvr; -static int brcmf_debugfs_fws_stats_open(struct inode *inode, struct file *f) -{ - return single_open(f, brcmf_debugfs_fws_stats_read, inode->i_private); -} - -static const struct file_operations brcmf_debugfs_fws_stats_ops = { - .owner = THIS_MODULE, - .open = brcmf_debugfs_fws_stats_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek -}; - -void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, - struct brcmf_fws_stats *stats) -{ - struct dentry *dentry = drvr->dbgfs_dir; + dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, + &brcmf_debugfs_def_ops); - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("fws_stats", S_IRUGO, dentry, - stats, &brcmf_debugfs_fws_stats_ops); + return PTR_ERR_OR_ZERO(dentry); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index ef52ed7abc69..6eade7c60c63 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -100,68 +100,6 @@ do { \ extern int brcmf_msg_level; -/* - * hold counter variables used in brcmfmac sdio driver. - */ -struct brcmf_sdio_count { - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ - uint pollcnt; /* Count of active polls */ - uint regfails; /* Count of R_REG failures */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - uint tickcnt; /* Number of watchdog been schedule */ - ulong tx_ctlerrs; /* Err of sending ctrl frames */ - ulong tx_ctlpkts; /* Ctrl frames sent to dongle */ - ulong rx_ctlerrs; /* Err of processing rx ctrl frames */ - ulong rx_ctlpkts; /* Ctrl frames processed from dongle */ - ulong rx_readahead_cnt; /* packets where header read-ahead was used */ -}; - -struct brcmf_fws_stats { - u32 tlv_parse_failed; - u32 tlv_invalid_type; - u32 header_only_pkt; - u32 header_pulls; - u32 pkt2bus; - u32 send_pkts[5]; - u32 requested_sent[5]; - u32 generic_error; - u32 mac_update_failed; - u32 mac_ps_update_failed; - u32 if_update_failed; - u32 packet_request_failed; - u32 credit_request_failed; - u32 rollback_success; - u32 rollback_failed; - u32 delayq_full_error; - u32 supprq_full_error; - u32 txs_indicate; - u32 txs_discard; - u32 txs_supp_core; - u32 txs_supp_ps; - u32 txs_tossed; - u32 txs_host_tossed; - u32 bus_flow_block; - u32 fws_flow_block; -}; - struct brcmf_pub; #ifdef DEBUG void brcmf_debugfs_init(void); @@ -169,10 +107,8 @@ void brcmf_debugfs_exit(void); int brcmf_debugfs_attach(struct brcmf_pub *drvr); void brcmf_debugfs_detach(struct brcmf_pub *drvr); struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); -void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, - struct brcmf_sdio_count *sdcnt); -void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, - struct brcmf_fws_stats *stats); +int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)); #else static inline void brcmf_debugfs_init(void) { @@ -187,9 +123,11 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr) static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) { } -static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, - struct brcmf_fws_stats *stats) +static inline +int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) { + return 0; } #endif diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 0c98a7942a0f..c0486329331b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -391,6 +391,40 @@ struct brcmf_sdio_hdrinfo { u16 tail_pad; }; +/* + * hold counter variables + */ +struct brcmf_sdio_count { + uint intrcount; /* Count of device interrupt callbacks */ + uint lastintrs; /* Count as of last watchdog timer */ + uint pollcnt; /* Count of active polls */ + uint regfails; /* Count of R_REG failures */ + uint tx_sderrs; /* Count of tx attempts with sd errors */ + uint fcqueued; /* Tx packets that got queued */ + uint rxrtx; /* Count of rtx requests (NAK to dongle) */ + uint rx_toolong; /* Receive frames too long to receive */ + uint rxc_errors; /* SDIO errors when reading control frames */ + uint rx_hdrfail; /* SDIO errors on header reads */ + uint rx_badhdr; /* Bad received headers (roosync?) */ + uint rx_badseq; /* Mismatched rx sequence number */ + uint fc_rcvd; /* Number of flow-control events received */ + uint fc_xoff; /* Number which turned on flow-control */ + uint fc_xon; /* Number which turned off flow-control */ + uint rxglomfail; /* Failed deglom attempts */ + uint rxglomframes; /* Number of glom frames (superframes) */ + uint rxglompkts; /* Number of packets from glom frames */ + uint f2rxhdrs; /* Number of header reads */ + uint f2rxdata; /* Number of frame data reads */ + uint f2txdata; /* Number of f2 frame writes */ + uint f1regdata; /* Number of f1 register accesses */ + uint tickcnt; /* Number of watchdog been schedule */ + ulong tx_ctlerrs; /* Err of sending ctrl frames */ + ulong tx_ctlpkts; /* Ctrl frames sent to dongle */ + ulong rx_ctlerrs; /* Err of processing rx ctrl frames */ + ulong rx_ctlpkts; /* Ctrl frames processed from dongle */ + ulong rx_readahead_cnt; /* packets where header read-ahead was used */ +}; + /* misc chip info needed by some of the routines */ /* Private data for SDIO bus interaction */ struct brcmf_sdio { @@ -3070,23 +3104,50 @@ done: static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data) { - struct brcmf_sdio *bus = seq->private; + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); + struct brcmf_sdio *bus = bus_if->bus_priv.sdio->bus; return brcmf_sdio_died_dump(seq, bus); } -static int brcmf_sdio_forensic_open(struct inode *inode, struct file *f) +static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data) { - return single_open(f, brcmf_sdio_forensic_read, inode->i_private); -} + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio_count *sdcnt = &sdiodev->bus->sdcnt; -static const struct file_operations brcmf_sdio_forensic_ops = { - .owner = THIS_MODULE, - .open = brcmf_sdio_forensic_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek -}; + seq_printf(seq, + "intrcount: %u\nlastintrs: %u\n" + "pollcnt: %u\nregfails: %u\n" + "tx_sderrs: %u\nfcqueued: %u\n" + "rxrtx: %u\nrx_toolong: %u\n" + "rxc_errors: %u\nrx_hdrfail: %u\n" + "rx_badhdr: %u\nrx_badseq: %u\n" + "fc_rcvd: %u\nfc_xoff: %u\n" + "fc_xon: %u\nrxglomfail: %u\n" + "rxglomframes: %u\nrxglompkts: %u\n" + "f2rxhdrs: %u\nf2rxdata: %u\n" + "f2txdata: %u\nf1regdata: %u\n" + "tickcnt: %u\ntx_ctlerrs: %lu\n" + "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" + "rx_ctlpkts: %lu\nrx_readahead: %lu\n", + sdcnt->intrcount, sdcnt->lastintrs, + sdcnt->pollcnt, sdcnt->regfails, + sdcnt->tx_sderrs, sdcnt->fcqueued, + sdcnt->rxrtx, sdcnt->rx_toolong, + sdcnt->rxc_errors, sdcnt->rx_hdrfail, + sdcnt->rx_badhdr, sdcnt->rx_badseq, + sdcnt->fc_rcvd, sdcnt->fc_xoff, + sdcnt->fc_xon, sdcnt->rxglomfail, + sdcnt->rxglomframes, sdcnt->rxglompkts, + sdcnt->f2rxhdrs, sdcnt->f2rxdata, + sdcnt->f2txdata, sdcnt->f1regdata, + sdcnt->tickcnt, sdcnt->tx_ctlerrs, + sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, + sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); + + return 0; +} static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) { @@ -3096,9 +3157,9 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) if (IS_ERR_OR_NULL(dentry)) return; - debugfs_create_file("forensics", S_IRUGO, dentry, bus, - &brcmf_sdio_forensic_ops); - brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); + brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read); + brcmf_debugfs_add_entry(drvr, "counters", + brcmf_debugfs_sdio_count_read); debugfs_create_u32("console_interval", 0644, dentry, &bus->console_interval); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 699908de314a..d42f7d04b65f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -454,6 +454,34 @@ struct brcmf_fws_macdesc_table { struct brcmf_fws_mac_descriptor other; }; +struct brcmf_fws_stats { + u32 tlv_parse_failed; + u32 tlv_invalid_type; + u32 header_only_pkt; + u32 header_pulls; + u32 pkt2bus; + u32 send_pkts[5]; + u32 requested_sent[5]; + u32 generic_error; + u32 mac_update_failed; + u32 mac_ps_update_failed; + u32 if_update_failed; + u32 packet_request_failed; + u32 credit_request_failed; + u32 rollback_success; + u32 rollback_failed; + u32 delayq_full_error; + u32 supprq_full_error; + u32 txs_indicate; + u32 txs_discard; + u32 txs_supp_core; + u32 txs_supp_ps; + u32 txs_tossed; + u32 txs_host_tossed; + u32 bus_flow_block; + u32 fws_flow_block; +}; + struct brcmf_fws_info { struct brcmf_pub *drvr; spinlock_t spinlock; @@ -2017,6 +2045,75 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) brcmf_fws_unlock(fws); } +#ifdef DEBUG +static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); + struct brcmf_fws_stats *fwstats = &bus_if->drvr->fws->stats; + + seq_printf(seq, + "header_pulls: %u\n" + "header_only_pkt: %u\n" + "tlv_parse_failed: %u\n" + "tlv_invalid_type: %u\n" + "mac_update_fails: %u\n" + "ps_update_fails: %u\n" + "if_update_fails: %u\n" + "pkt2bus: %u\n" + "generic_error: %u\n" + "rollback_success: %u\n" + "rollback_failed: %u\n" + "delayq_full: %u\n" + "supprq_full: %u\n" + "txs_indicate: %u\n" + "txs_discard: %u\n" + "txs_suppr_core: %u\n" + "txs_suppr_ps: %u\n" + "txs_tossed: %u\n" + "txs_host_tossed: %u\n" + "bus_flow_block: %u\n" + "fws_flow_block: %u\n" + "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n" + "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n", + fwstats->header_pulls, + fwstats->header_only_pkt, + fwstats->tlv_parse_failed, + fwstats->tlv_invalid_type, + fwstats->mac_update_failed, + fwstats->mac_ps_update_failed, + fwstats->if_update_failed, + fwstats->pkt2bus, + fwstats->generic_error, + fwstats->rollback_success, + fwstats->rollback_failed, + fwstats->delayq_full_error, + fwstats->supprq_full_error, + fwstats->txs_indicate, + fwstats->txs_discard, + fwstats->txs_supp_core, + fwstats->txs_supp_ps, + fwstats->txs_tossed, + fwstats->txs_host_tossed, + fwstats->bus_flow_block, + fwstats->fws_flow_block, + fwstats->send_pkts[0], fwstats->send_pkts[1], + fwstats->send_pkts[2], fwstats->send_pkts[3], + fwstats->send_pkts[4], + fwstats->requested_sent[0], + fwstats->requested_sent[1], + fwstats->requested_sent[2], + fwstats->requested_sent[3], + fwstats->requested_sent[4]); + + return 0; +} +#else +static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data) +{ + return 0; +} +#endif + int brcmf_fws_init(struct brcmf_pub *drvr) { struct brcmf_fws_info *fws; @@ -2107,7 +2204,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr) BRCMF_FWS_PSQ_LEN); /* create debugfs file for statistics */ - brcmf_debugfs_create_fws_stats(drvr, &fws->stats); + brcmf_debugfs_add_entry(drvr, "fws_stats", + brcmf_debugfs_fws_stats_read); brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", fws->fw_signals ? "enabled" : "disabled", tlv); -- cgit v1.2.2 From c1b20532ef395f23c2d24bc9c7f772a45e0420c7 Mon Sep 17 00:00:00 2001 From: Daniel Kim Date: Sat, 12 Jul 2014 08:49:37 +0200 Subject: brcmfmac: Make firmware path a module parameter This patch makes firmware path a module parameter so that firmware and nvram files can be loaded from the specified path. Signed-off-by: Daniel Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 47 +++++++++++++--------- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 5 +++ drivers/net/wireless/brcm80211/brcmfmac/firmware.h | 5 +++ .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 4 ++ 4 files changed, 41 insertions(+), 20 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index c0486329331b..67d91d5cc13d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -666,28 +666,34 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } }; -static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci, - enum brcmf_firmware_type type) +static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci, + struct brcmf_sdio_dev *sdiodev) { int i; for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) { if (brcmf_fwname_data[i].chipid == ci->chip && - brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) { - switch (type) { - case BRCMF_FIRMWARE_BIN: - return brcmf_fwname_data[i].bin; - case BRCMF_FIRMWARE_NVRAM: - return brcmf_fwname_data[i].nv; - default: - brcmf_err("invalid firmware type (%d)\n", type); - return NULL; - } - } + brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) + break; } - brcmf_err("Unknown chipid %d [%d]\n", - ci->chip, ci->chiprev); - return NULL; + + if (i == ARRAY_SIZE(brcmf_fwname_data)) { + brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev); + return -ENODEV; + } + + /* check if firmware path is provided by module parameter */ + if (brcmf_firmware_path[0] != '\0') { + if (brcmf_firmware_path[strlen(brcmf_firmware_path) - 1] != '/') + strcat(brcmf_firmware_path, "/"); + + strcpy(sdiodev->fw_name, brcmf_firmware_path); + strcpy(sdiodev->nvram_name, brcmf_firmware_path); + } + strcat(sdiodev->fw_name, brcmf_fwname_data[i].bin); + strcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv); + + return 0; } static void pkt_align(struct sk_buff *p, int len, int align) @@ -4160,11 +4166,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); + ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev); + if (ret) + goto fail; + ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, - brcmf_sdio_get_fwname(bus->ci, - BRCMF_FIRMWARE_BIN), - brcmf_sdio_get_fwname(bus->ci, - BRCMF_FIRMWARE_NVRAM), + sdiodev->fw_name, sdiodev->nvram_name, brcmf_sdio_firmware_callback); if (ret != 0) { brcmf_err("async firmware request failed: %d\n", ret); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index 7b7d237c1ddb..8ea9f283d2b8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -18,10 +18,15 @@ #include #include #include +#include #include "dhd_dbg.h" #include "firmware.h" +char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; +module_param_string(firmware_path, brcmf_firmware_path, + BRCMF_FW_PATH_LEN, 0440); + enum nvram_parser_state { IDLE, KEY, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h index 6431bfd7afff..4d3482356b77 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h @@ -21,6 +21,11 @@ #define BRCMF_FW_REQ_FLAGS 0x00F0 #define BRCMF_FW_REQ_NV_OPTIONAL 0x0010 +#define BRCMF_FW_PATH_LEN 256 +#define BRCMF_FW_NAME_LEN 32 + +extern char brcmf_firmware_path[]; + void brcmf_fw_nvram_free(void *nvram); /* * Request firmware(s) asynchronously. When the asynchronous request diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 3deab7959a0d..6c5e585ccda9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -18,6 +18,8 @@ #define _BRCM_SDH_H_ #include +#include +#include "firmware.h" #define SDIO_FUNC_0 0 #define SDIO_FUNC_1 1 @@ -182,6 +184,8 @@ struct brcmf_sdio_dev { uint max_segment_size; uint txglomsz; struct sg_table sgtable; + char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; + char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; }; /* sdio core registers */ -- cgit v1.2.2 From ccfd1e810bb7f053e74bc796b84c8e1de37c21fa Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:38 +0200 Subject: brcmfmac: move attach and detach functions in wl_cfg80211.c Preparing for another patch move the functions in separate commit. Reviewed-by: Hante Meuleman Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 215 ++++++++++----------- 1 file changed, 107 insertions(+), 108 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 9682cf213ec4..dd487e93141f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4967,114 +4967,6 @@ static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) return err; } -struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, - struct device *busdev) -{ - struct net_device *ndev = drvr->iflist[0]->ndev; - struct brcmf_cfg80211_info *cfg; - struct wiphy *wiphy; - struct brcmf_cfg80211_vif *vif; - struct brcmf_if *ifp; - s32 err = 0; - s32 io_type; - - if (!ndev) { - brcmf_err("ndev is invalid\n"); - return NULL; - } - - ifp = netdev_priv(ndev); - wiphy = brcmf_setup_wiphy(busdev); - if (IS_ERR(wiphy)) - return NULL; - - cfg = wiphy_priv(wiphy); - cfg->wiphy = wiphy; - cfg->pub = drvr; - init_vif_event(&cfg->vif_event); - INIT_LIST_HEAD(&cfg->vif_list); - - vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false); - if (IS_ERR(vif)) { - wiphy_free(wiphy); - return NULL; - } - - vif->ifp = ifp; - vif->wdev.netdev = ndev; - ndev->ieee80211_ptr = &vif->wdev; - SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy)); - - err = wl_init_priv(cfg); - if (err) { - brcmf_err("Failed to init iwm_priv (%d)\n", err); - goto cfg80211_attach_out; - } - ifp->vif = vif; - - err = brcmf_p2p_attach(cfg); - if (err) { - brcmf_err("P2P initilisation failed (%d)\n", err); - goto cfg80211_p2p_attach_out; - } - err = brcmf_btcoex_attach(cfg); - if (err) { - brcmf_err("BT-coex initialisation failed (%d)\n", err); - brcmf_p2p_detach(&cfg->p2p); - goto cfg80211_p2p_attach_out; - } - - /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), - * setup 40MHz in 2GHz band and enable OBSS scanning. - */ - if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap & - IEEE80211_HT_CAP_SUP_WIDTH_20_40) { - err = brcmf_enable_bw40_2g(ifp); - if (!err) - err = brcmf_fil_iovar_int_set(ifp, "obss_coex", - BRCMF_OBSS_COEX_AUTO); - } - /* clear for now and rely on update later */ - wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false; - wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0; - - err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); - if (err) { - brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); - wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; - } - - err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, - &io_type); - if (err) { - brcmf_err("Failed to get D11 version (%d)\n", err); - goto cfg80211_p2p_attach_out; - } - cfg->d11inf.io_type = (u8)io_type; - brcmu_d11_attach(&cfg->d11inf); - - return cfg; - -cfg80211_p2p_attach_out: - wl_deinit_priv(cfg); - -cfg80211_attach_out: - brcmf_free_vif(vif); - return NULL; -} - -void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) -{ - if (!cfg) - return; - - WARN_ON(!list_empty(&cfg->vif_list)); - wiphy_unregister(cfg->wiphy); - brcmf_btcoex_detach(cfg); - wl_deinit_priv(cfg); - wiphy_free(cfg->wiphy); -} - static s32 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout) { @@ -5658,3 +5550,110 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, vif_event_equals(event, action), timeout); } +struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, + struct device *busdev) +{ + struct net_device *ndev = drvr->iflist[0]->ndev; + struct brcmf_cfg80211_info *cfg; + struct wiphy *wiphy; + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + s32 err = 0; + s32 io_type; + + if (!ndev) { + brcmf_err("ndev is invalid\n"); + return NULL; + } + + ifp = netdev_priv(ndev); + wiphy = brcmf_setup_wiphy(busdev); + if (IS_ERR(wiphy)) + return NULL; + + cfg = wiphy_priv(wiphy); + cfg->wiphy = wiphy; + cfg->pub = drvr; + init_vif_event(&cfg->vif_event); + INIT_LIST_HEAD(&cfg->vif_list); + + vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false); + if (IS_ERR(vif)) { + wiphy_free(wiphy); + return NULL; + } + + vif->ifp = ifp; + vif->wdev.netdev = ndev; + ndev->ieee80211_ptr = &vif->wdev; + SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy)); + + err = wl_init_priv(cfg); + if (err) { + brcmf_err("Failed to init iwm_priv (%d)\n", err); + goto cfg80211_attach_out; + } + ifp->vif = vif; + + err = brcmf_p2p_attach(cfg); + if (err) { + brcmf_err("P2P initilisation failed (%d)\n", err); + goto cfg80211_p2p_attach_out; + } + err = brcmf_btcoex_attach(cfg); + if (err) { + brcmf_err("BT-coex initialisation failed (%d)\n", err); + brcmf_p2p_detach(&cfg->p2p); + goto cfg80211_p2p_attach_out; + } + + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), + * setup 40MHz in 2GHz band and enable OBSS scanning. + */ + if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40) { + err = brcmf_enable_bw40_2g(ifp); + if (!err) + err = brcmf_fil_iovar_int_set(ifp, "obss_coex", + BRCMF_OBSS_COEX_AUTO); + } + /* clear for now and rely on update later */ + wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false; + wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0; + + err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); + if (err) { + brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); + wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; + } + + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, + &io_type); + if (err) { + brcmf_err("Failed to get D11 version (%d)\n", err); + goto cfg80211_p2p_attach_out; + } + cfg->d11inf.io_type = (u8)io_type; + brcmu_d11_attach(&cfg->d11inf); + + return cfg; + +cfg80211_p2p_attach_out: + wl_deinit_priv(cfg); + +cfg80211_attach_out: + brcmf_free_vif(vif); + return NULL; +} + +void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) +{ + if (!cfg) + return; + + WARN_ON(!list_empty(&cfg->vif_list)); + wiphy_unregister(cfg->wiphy); + brcmf_btcoex_detach(cfg); + wl_deinit_priv(cfg); + wiphy_free(cfg->wiphy); +} -- cgit v1.2.2 From c08437b4b5c89677a81b543644b2d0a99484d947 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:39 +0200 Subject: brcmfmac: introduce feature and quirk handling Introducing a new source module that will be responsible for identifying features and quirks related to the device being handled. Reviewed-by: Hante Meuleman Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 5 +- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 13 +- drivers/net/wireless/brcm80211/brcmfmac/feature.c | 136 +++++++++++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/feature.h | 86 +++++++++++++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 30 +++-- 6 files changed, 244 insertions(+), 27 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/feature.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/feature.h (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 4cffb2ee3673..de0cff3df389 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -34,6 +34,7 @@ brcmfmac-objs += \ dhd_common.o \ dhd_linux.o \ firmware.o \ + feature.o \ btcoex.o \ vendor.o brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index a8998eb60d22..7da6441bcfa8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -103,6 +103,10 @@ struct brcmf_pub { struct brcmf_ampdu_rx_reorder *reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS]; + + u32 feat_flags; + u32 chip_quirks; + #ifdef DEBUG struct dentry *dbgfs_dir; #endif @@ -175,7 +179,6 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); -u32 brcmf_get_chip_info(struct brcmf_if *ifp); void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, bool success); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 09dd8c13d844..bf448081d6fb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -30,6 +30,7 @@ #include "wl_cfg80211.h" #include "fwil.h" #include "fwsignal.h" +#include "feature.h" #include "proto.h" MODULE_AUTHOR("Broadcom Corporation"); @@ -936,6 +937,8 @@ int brcmf_bus_start(struct device *dev) if (ret < 0) goto fail; + brcmf_feat_attach(drvr); + ret = brcmf_fws_init(drvr); if (ret < 0) goto fail; @@ -1073,16 +1076,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) return !err; } -/* - * return chip id and rev of the device encoded in u32. - */ -u32 brcmf_get_chip_info(struct brcmf_if *ifp) -{ - struct brcmf_bus *bus = ifp->drvr->bus_if; - - return bus->chip << 4 | bus->chiprev; -} - static void brcmf_driver_register(struct work_struct *work) { #ifdef CONFIG_BRCMFMAC_SDIO diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c new file mode 100644 index 000000000000..50877e3c5d2f --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include "dhd.h" +#include "dhd_bus.h" +#include "dhd_dbg.h" +#include "fwil.h" +#include "feature.h" + +/* + * firmware error code received if iovar is unsupported. + */ +#define EBRCMF_FEAT_UNSUPPORTED 23 + +/* + * expand feature list to array of feature strings. + */ +#define BRCMF_FEAT_DEF(_f) \ + #_f, +static const char *brcmf_feat_names[] = { + BRCMF_FEAT_LIST +}; +#undef BRCMF_FEAT_DEF + +#ifdef DEBUG +/* + * expand quirk list to array of quirk strings. + */ +#define BRCMF_QUIRK_DEF(_q) \ + #_q, +static const char * const brcmf_quirk_names[] = { + BRCMF_QUIRK_LIST +}; +#undef BRCMF_QUIRK_DEF + +/** + * brcmf_feat_debugfs_read() - expose feature info to debugfs. + * + * @seq: sequence for debugfs entry. + * @data: raw data pointer. + */ +static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); + u32 feats = bus_if->drvr->feat_flags; + u32 quirks = bus_if->drvr->chip_quirks; + int id; + + seq_printf(seq, "Features: %08x\n", feats); + for (id = 0; id < BRCMF_FEAT_LAST; id++) + if (feats & BIT(id)) + seq_printf(seq, "\t%s\n", brcmf_feat_names[id]); + seq_printf(seq, "\nQuirks: %08x\n", quirks); + for (id = 0; id < BRCMF_FEAT_QUIRK_LAST; id++) + if (quirks & BIT(id)) + seq_printf(seq, "\t%s\n", brcmf_quirk_names[id]); + return 0; +} +#else +static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data) +{ + return 0; +} +#endif /* DEBUG */ + +/** + * brcmf_feat_iovar_int_get() - determine feature through iovar query. + * + * @ifp: interface to query. + * @id: feature id. + * @name: iovar name. + */ +static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp, + enum brcmf_feat_id id, char *name) +{ + u32 data; + int err; + + err = brcmf_fil_iovar_int_get(ifp, name, &data); + if (err == 0) { + brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); + ifp->drvr->feat_flags |= BIT(id); + } else { + brcmf_dbg(TRACE, "%s feature check failed: %d\n", + brcmf_feat_names[id], err); + } +} + +void brcmf_feat_attach(struct brcmf_pub *drvr) +{ + struct brcmf_if *ifp = drvr->iflist[0]; + + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); + + /* set chip related quirks */ + switch (drvr->bus_if->chip) { + case BRCM_CC_43236_CHIP_ID: + drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_AUTO_AUTH); + break; + case BRCM_CC_4329_CHIP_ID: + drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_NEED_MPC); + break; + default: + /* no quirks */ + break; + } + + brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); +} + +bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id) +{ + return (ifp->drvr->feat_flags & BIT(id)); +} + +bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp, + enum brcmf_feat_quirk quirk) +{ + return (ifp->drvr->chip_quirks & BIT(quirk)); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/brcm80211/brcmfmac/feature.h new file mode 100644 index 000000000000..961d175f8afb --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _BRCMF_FEATURE_H +#define _BRCMF_FEATURE_H + +/* + * Features: + * + * MCHAN: multi-channel for concurrent P2P. + */ +#define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MCHAN) +/* + * Quirks: + * + * AUTO_AUTH: workaround needed for automatic authentication type. + * NEED_MPC: driver needs to disable MPC during scanning operation. + */ +#define BRCMF_QUIRK_LIST \ + BRCMF_QUIRK_DEF(AUTO_AUTH) \ + BRCMF_QUIRK_DEF(NEED_MPC) + +#define BRCMF_FEAT_DEF(_f) \ + BRCMF_FEAT_ ## _f, +/* + * expand feature list to enumeration. + */ +enum brcmf_feat_id { + BRCMF_FEAT_LIST + BRCMF_FEAT_LAST +}; +#undef BRCMF_FEAT_DEF + +#define BRCMF_QUIRK_DEF(_q) \ + BRCMF_FEAT_QUIRK_ ## _q, +/* + * expand quirk list to enumeration. + */ +enum brcmf_feat_quirk { + BRCMF_QUIRK_LIST + BRCMF_FEAT_QUIRK_LAST +}; +#undef BRCMF_QUIRK_DEF + +/** + * brcmf_feat_attach() - determine features and quirks. + * + * @drvr: driver instance. + */ +void brcmf_feat_attach(struct brcmf_pub *drvr); + +/** + * brcmf_feat_is_enabled() - query feature. + * + * @ifp: interface instance. + * @id: feature id to check. + * + * Return: true is feature is enabled; otherwise false. + */ +bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id); + +/** + * brcmf_feat_is_quirk_enabled() - query chip quirk. + * + * @ifp: interface instance. + * @quirk: quirk id to check. + * + * Return: true is quirk is enabled; otherwise false. + */ +bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp, + enum brcmf_feat_quirk quirk); + +#endif /* _BRCMF_FEATURE_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index dd487e93141f..e3c1c71c5d2e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -33,6 +33,7 @@ #include "p2p.h" #include "btcoex.h" #include "wl_cfg80211.h" +#include "feature.h" #include "fwil.h" #include "vendor.h" @@ -592,7 +593,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc) { - if ((brcmf_get_chip_info(ifp) >> 4) == 0x4329) + if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC)) brcmf_set_mpc(ifp, mpc); } @@ -1619,17 +1620,10 @@ static enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp, enum nl80211_auth_type type) { - u32 ci; - if (type == NL80211_AUTHTYPE_AUTOMATIC) { - /* shift to ignore chip revision */ - ci = brcmf_get_chip_info(ifp) >> 4; - switch (ci) { - case 43236: - brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n"); - return NL80211_AUTHTYPE_OPEN_SYSTEM; - default: - break; - } + if (type == NL80211_AUTHTYPE_AUTOMATIC && + brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) { + brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n"); + type = NL80211_AUTHTYPE_OPEN_SYSTEM; } return type; } @@ -4310,10 +4304,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { .types = BIT(NL80211_IFTYPE_P2P_DEVICE) } }; -static const struct ieee80211_iface_combination brcmf_iface_combos[] = { +static struct ieee80211_iface_combination brcmf_iface_combos[] = { { .max_interfaces = BRCMF_IFACE_MAX_CNT, - .num_different_channels = 2, + .num_different_channels = 1, .n_limits = ARRAY_SIZE(brcmf_iface_limits), .limits = brcmf_iface_limits } @@ -4348,7 +4342,8 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { } }; -static struct wiphy *brcmf_setup_wiphy(struct device *phydev) +static +struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, struct device *phydev) { struct wiphy *wiphy; s32 err = 0; @@ -4368,6 +4363,9 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE); + /* need VSDB firmware feature for concurrent channels */ + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) + brcmf_iface_combos[0].num_different_channels = 2; wiphy->iface_combinations = brcmf_iface_combos; wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; @@ -5567,7 +5565,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, } ifp = netdev_priv(ndev); - wiphy = brcmf_setup_wiphy(busdev); + wiphy = brcmf_setup_wiphy(ifp, busdev); if (IS_ERR(wiphy)) return NULL; -- cgit v1.2.2 From aa70b4fa43dfe5dc3df2161d814ccaa7897d73c9 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:40 +0200 Subject: brcmfmac: moving some functions around Just reordering the functions in preparation of subsequent changes. Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 288 ++++++++++----------- 1 file changed, 144 insertions(+), 144 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index e3c1c71c5d2e..d0b48dd4f154 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4278,126 +4278,6 @@ static struct cfg80211_ops wl_cfg80211_ops = { .tdls_oper = brcmf_cfg80211_tdls_oper, }; -static void brcmf_wiphy_pno_params(struct wiphy *wiphy) -{ - /* scheduled scan settings */ - wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; -} - -static const struct ieee80211_iface_limit brcmf_iface_limits[] = { - { - .max = 2, - .types = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP) - }, - { - .max = 1, - .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO) - }, - { - .max = 1, - .types = BIT(NL80211_IFTYPE_P2P_DEVICE) - } -}; -static struct ieee80211_iface_combination brcmf_iface_combos[] = { - { - .max_interfaces = BRCMF_IFACE_MAX_CNT, - .num_different_channels = 1, - .n_limits = ARRAY_SIZE(brcmf_iface_limits), - .limits = brcmf_iface_limits - } -}; - -static const struct ieee80211_txrx_stypes -brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_STATION] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_P2P_CLIENT] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, - [NL80211_IFTYPE_P2P_GO] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4) | - BIT(IEEE80211_STYPE_ACTION >> 4) - }, - [NL80211_IFTYPE_P2P_DEVICE] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - } -}; - -static -struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, struct device *phydev) -{ - struct wiphy *wiphy; - s32 err = 0; - - wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); - if (!wiphy) { - brcmf_err("Could not allocate wiphy device\n"); - return ERR_PTR(-ENOMEM); - } - set_wiphy_dev(wiphy, phydev); - wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; - wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_DEVICE); - /* need VSDB firmware feature for concurrent channels */ - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) - brcmf_iface_combos[0].num_different_channels = 2; - wiphy->iface_combinations = brcmf_iface_combos; - wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); - wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->cipher_suites = __wl_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); - wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | - WIPHY_FLAG_OFFCHAN_TX | - WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_SUPPORTS_TDLS; - if (!brcmf_roamoff) - wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; - wiphy->mgmt_stypes = brcmf_txrx_stypes; - wiphy->max_remain_on_channel_duration = 5000; - brcmf_wiphy_pno_params(wiphy); - brcmf_dbg(INFO, "Registering custom regulatory\n"); - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; - wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); - - /* vendor commands/events support */ - wiphy->vendor_commands = brcmf_vendor_cmds; - wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1; - - err = wiphy_register(wiphy); - if (err < 0) { - brcmf_err("Could not register wiphy device (%d)\n", err); - wiphy_free(wiphy); - return ERR_PTR(err); - } - return wiphy; -} - struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type, bool pm_block) @@ -4941,30 +4821,6 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event) mutex_init(&event->vif_event_lock); } -static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) -{ - struct brcmf_fil_bwcap_le band_bwcap; - u32 val; - int err; - - /* verify support for bw_cap command */ - val = WLC_BAND_5G; - err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val); - - if (!err) { - /* only set 2G bandwidth using bw_cap command */ - band_bwcap.band = cpu_to_le32(WLC_BAND_2G); - band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ); - err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap, - sizeof(band_bwcap)); - } else { - brcmf_dbg(INFO, "fallback to mimo_bw_cap\n"); - val = WLC_N_BW_40ALL; - err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val); - } - return err; -} - static s32 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout) { @@ -5194,6 +5050,30 @@ exit: return err; } +static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) +{ + struct brcmf_fil_bwcap_le band_bwcap; + u32 val; + int err; + + /* verify support for bw_cap command */ + val = WLC_BAND_5G; + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val); + + if (!err) { + /* only set 2G bandwidth using bw_cap command */ + band_bwcap.band = cpu_to_le32(WLC_BAND_2G); + band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ); + err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap, + sizeof(band_bwcap)); + } else { + brcmf_dbg(INFO, "fallback to mimo_bw_cap\n"); + val = WLC_N_BW_40ALL; + err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val); + } + return err; +} + static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) { u32 band, mimo_bwcap; @@ -5377,6 +5257,126 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) return err; } +static const struct ieee80211_iface_limit brcmf_iface_limits[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE) + } +}; +static struct ieee80211_iface_combination brcmf_iface_combos[] = { + { + .max_interfaces = BRCMF_IFACE_MAX_CNT, + .num_different_channels = 1, + .n_limits = ARRAY_SIZE(brcmf_iface_limits), + .limits = brcmf_iface_limits + } +}; + +static const struct ieee80211_txrx_stypes +brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_DEVICE] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + } +}; + +static void brcmf_wiphy_pno_params(struct wiphy *wiphy) +{ + /* scheduled scan settings */ + wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; + wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; + wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; +} + +static struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, + struct device *phydev) +{ + struct wiphy *wiphy; + s32 err = 0; + + wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); + if (!wiphy) { + brcmf_err("Could not allocate wiphy device\n"); + return ERR_PTR(-ENOMEM); + } + set_wiphy_dev(wiphy, phydev); + wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; + wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); + /* need VSDB firmware feature for concurrent channels */ + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) + brcmf_iface_combos[0].num_different_channels = 2; + wiphy->iface_combinations = brcmf_iface_combos; + wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); + wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wiphy->cipher_suites = __wl_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | + WIPHY_FLAG_OFFCHAN_TX | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_SUPPORTS_TDLS; + if (!brcmf_roamoff) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + wiphy->mgmt_stypes = brcmf_txrx_stypes; + wiphy->max_remain_on_channel_duration = 5000; + brcmf_wiphy_pno_params(wiphy); + brcmf_dbg(INFO, "Registering custom regulatory\n"); + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); + + /* vendor commands/events support */ + wiphy->vendor_commands = brcmf_vendor_cmds; + wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1; + + err = wiphy_register(wiphy); + if (err < 0) { + brcmf_err("Could not register wiphy device (%d)\n", err); + wiphy_free(wiphy); + return ERR_PTR(err); + } + return wiphy; +} + static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) { -- cgit v1.2.2 From b48d891676f756d48b4d0ee131e4a7a5d43ca417 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:41 +0200 Subject: brcmfmac: rework wiphy structure setup Instead of waiting for IFF_UP of the primary net device to determine the band and channel information of the wiphy structure, this is now done during driver initialization in brcmf_cfg80211_attach(). The channel information is obtained from the device and the 2G band is updated when 40MHz bandwidth is enabled for that band. Before this change the band and channel objects were common between multiple brcmfmac devices in the system, which make that information rather unreliable. That is also fixed with this reworked implementation. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 566 +++++++++++---------- 1 file changed, 298 insertions(+), 268 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index d0b48dd4f154..d3bb4e0f4480 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -103,24 +103,6 @@ static bool check_vif_up(struct brcmf_cfg80211_vif *vif) return true; } -#define CHAN2G(_channel, _freq, _flags) { \ - .band = IEEE80211_BAND_2GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_channel), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - -#define CHAN5G(_channel, _flags) { \ - .band = IEEE80211_BAND_5GHZ, \ - .center_freq = 5000 + (5 * (_channel)), \ - .hw_value = (_channel), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) #define RATETAB_ENT(_rateid, _flags) \ { \ @@ -149,58 +131,17 @@ static struct ieee80211_rate __wl_rates[] = { #define wl_g_rates (__wl_rates + 0) #define wl_g_rates_size 12 -static struct ieee80211_channel __wl_2ghz_channels[] = { - CHAN2G(1, 2412, 0), - CHAN2G(2, 2417, 0), - CHAN2G(3, 2422, 0), - CHAN2G(4, 2427, 0), - CHAN2G(5, 2432, 0), - CHAN2G(6, 2437, 0), - CHAN2G(7, 2442, 0), - CHAN2G(8, 2447, 0), - CHAN2G(9, 2452, 0), - CHAN2G(10, 2457, 0), - CHAN2G(11, 2462, 0), - CHAN2G(12, 2467, 0), - CHAN2G(13, 2472, 0), - CHAN2G(14, 2484, 0), -}; - -static struct ieee80211_channel __wl_5ghz_a_channels[] = { - CHAN5G(34, 0), CHAN5G(36, 0), - CHAN5G(38, 0), CHAN5G(40, 0), - CHAN5G(42, 0), CHAN5G(44, 0), - CHAN5G(46, 0), CHAN5G(48, 0), - CHAN5G(52, 0), CHAN5G(56, 0), - CHAN5G(60, 0), CHAN5G(64, 0), - CHAN5G(100, 0), CHAN5G(104, 0), - CHAN5G(108, 0), CHAN5G(112, 0), - CHAN5G(116, 0), CHAN5G(120, 0), - CHAN5G(124, 0), CHAN5G(128, 0), - CHAN5G(132, 0), CHAN5G(136, 0), - CHAN5G(140, 0), CHAN5G(149, 0), - CHAN5G(153, 0), CHAN5G(157, 0), - CHAN5G(161, 0), CHAN5G(165, 0), - CHAN5G(184, 0), CHAN5G(188, 0), - CHAN5G(192, 0), CHAN5G(196, 0), - CHAN5G(200, 0), CHAN5G(204, 0), - CHAN5G(208, 0), CHAN5G(212, 0), - CHAN5G(216, 0), -}; - -static struct ieee80211_supported_band __wl_band_2ghz = { +/* Band templates duplicated per wiphy. The channel info + * is filled in after querying the device. + */ +static const struct ieee80211_supported_band __wl_band_2ghz = { .band = IEEE80211_BAND_2GHZ, - .channels = __wl_2ghz_channels, - .n_channels = ARRAY_SIZE(__wl_2ghz_channels), .bitrates = wl_g_rates, .n_bitrates = wl_g_rates_size, - .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true}, }; -static struct ieee80211_supported_band __wl_band_5ghz_a = { +static const struct ieee80211_supported_band __wl_band_5ghz_a = { .band = IEEE80211_BAND_5GHZ, - .channels = __wl_5ghz_a_channels, - .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), .bitrates = wl_a_rates, .n_bitrates = wl_a_rates_size, }; @@ -4913,25 +4854,77 @@ dongle_scantime_out: return err; } +/* Filter the list of channels received from firmware counting only + * the 20MHz channels. The wiphy band data only needs those which get + * flagged to indicate if they can take part in higher bandwidth. + */ +static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg, + struct brcmf_chanspec_list *chlist, + u32 chcnt[]) +{ + u32 total = le32_to_cpu(chlist->count); + struct brcmu_chan ch; + int i; + + for (i = 0; i <= total; i++) { + ch.chspec = (u16)le32_to_cpu(chlist->element[i]); + cfg->d11inf.decchspec(&ch); + + /* Firmware gives a ordered list. We skip non-20MHz + * channels is 2G. For 5G we can abort upon reaching + * a non-20MHz channel in the list. + */ + if (ch.bw != BRCMU_CHAN_BW_20) { + if (ch.band == BRCMU_CHAN_BAND_5G) + break; + else + continue; + } + + if (ch.band == BRCMU_CHAN_BAND_2G) + chcnt[0] += 1; + else if (ch.band == BRCMU_CHAN_BAND_5G) + chcnt[1] += 1; + } +} + +static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel, + struct brcmu_chan *ch) +{ + u32 ht40_flag; -static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, - u32 bw_cap[]) + ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40; + if (ch->sb == BRCMU_CHAN_SB_U) { + if (ht40_flag == IEEE80211_CHAN_NO_HT40) + channel->flags &= ~IEEE80211_CHAN_NO_HT40; + channel->flags |= IEEE80211_CHAN_NO_HT40PLUS; + } else { + /* It should be one of + * IEEE80211_CHAN_NO_HT40 or + * IEEE80211_CHAN_NO_HT40PLUS + */ + channel->flags &= ~IEEE80211_CHAN_NO_HT40; + if (ht40_flag == IEEE80211_CHAN_NO_HT40) + channel->flags |= IEEE80211_CHAN_NO_HT40MINUS; + } +} + +static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + u32 bw_cap[]) { struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); - struct ieee80211_channel *band_chan_arr; + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; + struct wiphy *wiphy; struct brcmf_chanspec_list *list; struct brcmu_chan ch; - s32 err; + int err; u8 *pbuf; u32 i, j; u32 total; - enum ieee80211_band band; - u32 channel; - u32 *n_cnt; + u32 chaninfo; + u32 chcnt[2] = { 0, 0 }; u32 index; - u32 ht40_flag; - bool update; - u32 array_size; pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); @@ -4944,11 +4937,45 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, BRCMF_DCMD_MEDLEN); if (err) { brcmf_err("get chanspecs error (%d)\n", err); - goto exit; + goto fail_pbuf; } - __wl_band_2ghz.n_channels = 0; - __wl_band_5ghz_a.n_channels = 0; + brcmf_count_20mhz_channels(cfg, list, chcnt); + wiphy = cfg_to_wiphy(cfg); + if (chcnt[0]) { + band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz), + GFP_KERNEL); + if (band == NULL) { + err = -ENOMEM; + goto fail_pbuf; + } + band->channels = kcalloc(chcnt[0], sizeof(*channel), + GFP_KERNEL); + if (band->channels == NULL) { + kfree(band); + err = -ENOMEM; + goto fail_pbuf; + } + band->n_channels = 0; + wiphy->bands[IEEE80211_BAND_2GHZ] = band; + } + if (chcnt[1]) { + band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a), + GFP_KERNEL); + if (band == NULL) { + err = -ENOMEM; + goto fail_band2g; + } + band->channels = kcalloc(chcnt[1], sizeof(*channel), + GFP_KERNEL); + if (band->channels == NULL) { + kfree(band); + err = -ENOMEM; + goto fail_band2g; + } + band->n_channels = 0; + wiphy->bands[IEEE80211_BAND_5GHZ] = band; + } total = le32_to_cpu(list->count); for (i = 0; i < total; i++) { @@ -4956,105 +4983,88 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, cfg->d11inf.decchspec(&ch); if (ch.band == BRCMU_CHAN_BAND_2G) { - band_chan_arr = __wl_2ghz_channels; - array_size = ARRAY_SIZE(__wl_2ghz_channels); - n_cnt = &__wl_band_2ghz.n_channels; - band = IEEE80211_BAND_2GHZ; + band = wiphy->bands[IEEE80211_BAND_2GHZ]; } else if (ch.band == BRCMU_CHAN_BAND_5G) { - band_chan_arr = __wl_5ghz_a_channels; - array_size = ARRAY_SIZE(__wl_5ghz_a_channels); - n_cnt = &__wl_band_5ghz_a.n_channels; - band = IEEE80211_BAND_5GHZ; + band = wiphy->bands[IEEE80211_BAND_5GHZ]; } else { brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); continue; } - if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && + if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) && ch.bw == BRCMU_CHAN_BW_40) continue; - if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) && + if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) && ch.bw == BRCMU_CHAN_BW_80) continue; - update = false; - for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { - if (band_chan_arr[j].hw_value == ch.chnum) { - update = true; + + channel = band->channels; + index = band->n_channels; + for (j = 0; j < band->n_channels; j++) { + if (channel[j].hw_value == ch.chnum) { + index = j; break; } } - if (update) - index = j; - else - index = *n_cnt; - if (index < array_size) { - band_chan_arr[index].center_freq = - ieee80211_channel_to_frequency(ch.chnum, band); - band_chan_arr[index].hw_value = ch.chnum; - - /* assuming the chanspecs order is HT20, - * HT40 upper, HT40 lower, and VHT80. + channel[index].center_freq = + ieee80211_channel_to_frequency(ch.chnum, band->band); + channel[index].hw_value = ch.chnum; + + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. + */ + if (ch.bw == BRCMU_CHAN_BW_80) { + channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ; + } else if (ch.bw == BRCMU_CHAN_BW_40) { + brcmf_update_bw40_channel_flag(&channel[index], &ch); + } else { + /* disable other bandwidths for now as mentioned + * order assure they are enabled for subsequent + * chanspecs. */ - if (ch.bw == BRCMU_CHAN_BW_80) { - band_chan_arr[index].flags &= - ~IEEE80211_CHAN_NO_80MHZ; - } else if (ch.bw == BRCMU_CHAN_BW_40) { - ht40_flag = band_chan_arr[index].flags & - IEEE80211_CHAN_NO_HT40; - if (ch.sb == BRCMU_CHAN_SB_U) { - if (ht40_flag == IEEE80211_CHAN_NO_HT40) - band_chan_arr[index].flags &= - ~IEEE80211_CHAN_NO_HT40; - band_chan_arr[index].flags |= - IEEE80211_CHAN_NO_HT40PLUS; - } else { - /* It should be one of - * IEEE80211_CHAN_NO_HT40 or - * IEEE80211_CHAN_NO_HT40PLUS - */ - band_chan_arr[index].flags &= - ~IEEE80211_CHAN_NO_HT40; - if (ht40_flag == IEEE80211_CHAN_NO_HT40) - band_chan_arr[index].flags |= - IEEE80211_CHAN_NO_HT40MINUS; - } - } else { - /* disable other bandwidths for now as mentioned - * order assure they are enabled for subsequent - * chanspecs. - */ - band_chan_arr[index].flags = - IEEE80211_CHAN_NO_HT40 | - IEEE80211_CHAN_NO_80MHZ; - ch.bw = BRCMU_CHAN_BW_20; - cfg->d11inf.encchspec(&ch); - channel = ch.chspec; - err = brcmf_fil_bsscfg_int_get(ifp, - "per_chan_info", - &channel); - if (!err) { - if (channel & WL_CHAN_RADAR) - band_chan_arr[index].flags |= - (IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IR); - if (channel & WL_CHAN_PASSIVE) - band_chan_arr[index].flags |= - IEEE80211_CHAN_NO_IR; - } + channel[index].flags = IEEE80211_CHAN_NO_HT40 | + IEEE80211_CHAN_NO_80MHZ; + ch.bw = BRCMU_CHAN_BW_20; + cfg->d11inf.encchspec(&ch); + chaninfo = ch.chspec; + err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info", + &chaninfo); + if (!err) { + if (chaninfo & WL_CHAN_RADAR) + channel[index].flags |= + (IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IR); + if (chaninfo & WL_CHAN_PASSIVE) + channel[index].flags |= + IEEE80211_CHAN_NO_IR; } - if (!update) - (*n_cnt)++; } + if (index == band->n_channels) + band->n_channels++; } -exit: + kfree(pbuf); + return 0; + +fail_band2g: + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]); + wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; +fail_pbuf: kfree(pbuf); return err; } -static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) +static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) { + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + struct ieee80211_supported_band *band; struct brcmf_fil_bwcap_le band_bwcap; + struct brcmf_chanspec_list *list; + u8 *pbuf; u32 val; int err; + struct brcmu_chan ch; + u32 num_chan; + int i, j; /* verify support for bw_cap command */ val = WLC_BAND_5G; @@ -5071,6 +5081,50 @@ static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) val = WLC_N_BW_40ALL; err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val); } + + if (!err) { + /* update channel info in 2G band */ + pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); + + if (pbuf == NULL) + return -ENOMEM; + + ch.band = BRCMU_CHAN_BAND_2G; + ch.bw = BRCMU_CHAN_BW_40; + ch.chnum = 0; + cfg->d11inf.encchspec(&ch); + + /* pass encoded chanspec in query */ + *(__le16 *)pbuf = cpu_to_le16(ch.chspec); + + err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, + BRCMF_DCMD_MEDLEN); + if (err) { + brcmf_err("get chanspecs error (%d)\n", err); + kfree(pbuf); + return err; + } + + band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ]; + list = (struct brcmf_chanspec_list *)pbuf; + num_chan = le32_to_cpu(list->count); + for (i = 0; i < num_chan; i++) { + ch.chspec = (u16)le32_to_cpu(list->element[i]); + cfg->d11inf.decchspec(&ch); + if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G)) + continue; + if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) + continue; + for (j = 0; j < band->n_channels; j++) { + if (band->channels[j].hw_value == ch.chnum) + break; + } + if (WARN_ON(j == band->n_channels)) + continue; + + brcmf_update_bw40_channel_flag(&band->channels[j], &ch); + } + } return err; } @@ -5164,44 +5218,19 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, band->vht_cap.vht_mcs.tx_mcs_map = mcs_map; } -static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) +static int brcmf_setup_wiphybands(struct wiphy *wiphy) { + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); - struct wiphy *wiphy; - s32 phy_list; - u32 band_list[3]; u32 nmode = 0; u32 vhtmode = 0; - u32 bw_cap[2] = { 0, 0 }; + u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; u32 rxchain; u32 nchain; - s8 phy; - s32 err; - u32 nband; + int err; s32 i; - struct ieee80211_supported_band *bands[2] = { NULL, NULL }; struct ieee80211_supported_band *band; - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, - &phy_list, sizeof(phy_list)); - if (err) { - brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err); - return err; - } - - phy = ((char *)&phy_list)[0]; - brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy); - - - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, - &band_list, sizeof(band_list)); - if (err) { - brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err); - return err; - } - brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n", - band_list[0], band_list[1], band_list[2]); - (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); if (err) { @@ -5223,38 +5252,25 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) } brcmf_dbg(INFO, "nchain=%d\n", nchain); - err = brcmf_construct_reginfo(cfg, bw_cap); + err = brcmf_construct_chaninfo(cfg, bw_cap); if (err) { - brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); + brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err); return err; } - nband = band_list[0]; - - for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { - band = NULL; - if ((band_list[i] == WLC_BAND_5G) && - (__wl_band_5ghz_a.n_channels > 0)) - band = &__wl_band_5ghz_a; - else if ((band_list[i] == WLC_BAND_2G) && - (__wl_band_2ghz.n_channels > 0)) - band = &__wl_band_2ghz; - else + wiphy = cfg_to_wiphy(cfg); + for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) { + band = wiphy->bands[i]; + if (band == NULL) continue; if (nmode) brcmf_update_ht_cap(band, bw_cap, nchain); if (vhtmode) brcmf_update_vht_cap(band, bw_cap, nchain); - bands[band->band] = band; } - wiphy = cfg_to_wiphy(cfg); - wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ]; - wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ]; - wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); - - return err; + return 0; } static const struct ieee80211_iface_limit brcmf_iface_limits[] = { @@ -5321,18 +5337,9 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy) wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; } -static struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, - struct device *phydev) +static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) { - struct wiphy *wiphy; - s32 err = 0; - - wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); - if (!wiphy) { - brcmf_err("Could not allocate wiphy device\n"); - return ERR_PTR(-ENOMEM); - } - set_wiphy_dev(wiphy, phydev); + struct ieee80211_iface_combination ifc_combo; wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; @@ -5343,11 +5350,13 @@ static struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE); /* need VSDB firmware feature for concurrent channels */ + ifc_combo = brcmf_iface_combos[0]; if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) - brcmf_iface_combos[0].num_different_channels = 2; - wiphy->iface_combinations = brcmf_iface_combos; + ifc_combo.num_different_channels = 2; + wiphy->iface_combinations = kmemdup(&ifc_combo, + sizeof(ifc_combo), + GFP_KERNEL); wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); - wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->cipher_suites = __wl_cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); @@ -5360,27 +5369,12 @@ static struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, wiphy->mgmt_stypes = brcmf_txrx_stypes; wiphy->max_remain_on_channel_duration = 5000; brcmf_wiphy_pno_params(wiphy); - brcmf_dbg(INFO, "Registering custom regulatory\n"); - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; - wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); /* vendor commands/events support */ wiphy->vendor_commands = brcmf_vendor_cmds; wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1; - err = wiphy_register(wiphy); - if (err < 0) { - brcmf_err("Could not register wiphy device (%d)\n", err); - wiphy_free(wiphy); - return ERR_PTR(err); - } - return wiphy; -} - - -static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) -{ - return brcmf_update_wiphybands(cfg); + return brcmf_setup_wiphybands(wiphy); } static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) @@ -5418,9 +5412,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) NULL, NULL); if (err) goto default_conf_out; - err = brcmf_dongle_probecap(cfg); - if (err) - goto default_conf_out; brcmf_configure_arp_offload(ifp, true); @@ -5548,6 +5539,20 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, vif_event_equals(event, action), timeout); } +static void brcmf_free_wiphy(struct wiphy *wiphy) +{ + kfree(wiphy->iface_combinations); + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]); + } + if (wiphy->bands[IEEE80211_BAND_5GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels); + kfree(wiphy->bands[IEEE80211_BAND_5GHZ]); + } + wiphy_free(wiphy); +} + struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, struct device *busdev) { @@ -5558,6 +5563,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, struct brcmf_if *ifp; s32 err = 0; s32 io_type; + u16 *cap = NULL; if (!ndev) { brcmf_err("ndev is invalid\n"); @@ -5565,9 +5571,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, } ifp = netdev_priv(ndev); - wiphy = brcmf_setup_wiphy(ifp, busdev); - if (IS_ERR(wiphy)) + wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); + if (!wiphy) { + brcmf_err("Could not allocate wiphy device\n"); return NULL; + } + set_wiphy_dev(wiphy, busdev); cfg = wiphy_priv(wiphy); cfg->wiphy = wiphy; @@ -5576,10 +5585,8 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, INIT_LIST_HEAD(&cfg->vif_list); vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false); - if (IS_ERR(vif)) { - wiphy_free(wiphy); - return NULL; - } + if (IS_ERR(vif)) + goto wiphy_out; vif->ifp = ifp; vif->wdev.netdev = ndev; @@ -5589,58 +5596,81 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, err = wl_init_priv(cfg); if (err) { brcmf_err("Failed to init iwm_priv (%d)\n", err); - goto cfg80211_attach_out; + brcmf_free_vif(vif); + goto wiphy_out; } ifp->vif = vif; - err = brcmf_p2p_attach(cfg); + /* determine d11 io type before wiphy setup */ + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type); if (err) { - brcmf_err("P2P initilisation failed (%d)\n", err); - goto cfg80211_p2p_attach_out; + brcmf_err("Failed to get D11 version (%d)\n", err); + goto priv_out; } - err = brcmf_btcoex_attach(cfg); - if (err) { - brcmf_err("BT-coex initialisation failed (%d)\n", err); - brcmf_p2p_detach(&cfg->p2p); - goto cfg80211_p2p_attach_out; + cfg->d11inf.io_type = (u8)io_type; + brcmu_d11_attach(&cfg->d11inf); + + err = brcmf_setup_wiphy(wiphy, ifp); + if (err < 0) + goto priv_out; + + brcmf_dbg(INFO, "Registering custom regulatory\n"); + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); + + /* firmware defaults to 40MHz disabled in 2G band. We signal + * cfg80211 here that we do and have it decide we can enable + * it. But first check if device does support 2G operation. + */ + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap; + *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + err = wiphy_register(wiphy); + if (err < 0) { + brcmf_err("Could not register wiphy device (%d)\n", err); + goto priv_out; } /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), * setup 40MHz in 2GHz band and enable OBSS scanning. */ - if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap & - IEEE80211_HT_CAP_SUP_WIDTH_20_40) { - err = brcmf_enable_bw40_2g(ifp); + if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) { + err = brcmf_enable_bw40_2g(cfg); if (!err) err = brcmf_fil_iovar_int_set(ifp, "obss_coex", BRCMF_OBSS_COEX_AUTO); + else + *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; } - /* clear for now and rely on update later */ - wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false; - wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0; - err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); + err = brcmf_p2p_attach(cfg); if (err) { - brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); - wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; + brcmf_err("P2P initilisation failed (%d)\n", err); + goto wiphy_unreg_out; + } + err = brcmf_btcoex_attach(cfg); + if (err) { + brcmf_err("BT-coex initialisation failed (%d)\n", err); + brcmf_p2p_detach(&cfg->p2p); + goto wiphy_unreg_out; } - err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, - &io_type); + err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); if (err) { - brcmf_err("Failed to get D11 version (%d)\n", err); - goto cfg80211_p2p_attach_out; + brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); + wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; } - cfg->d11inf.io_type = (u8)io_type; - brcmu_d11_attach(&cfg->d11inf); return cfg; -cfg80211_p2p_attach_out: +wiphy_unreg_out: + wiphy_unregister(cfg->wiphy); +priv_out: wl_deinit_priv(cfg); - -cfg80211_attach_out: brcmf_free_vif(vif); +wiphy_out: + brcmf_free_wiphy(wiphy); return NULL; } @@ -5653,5 +5683,5 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) wiphy_unregister(cfg->wiphy); brcmf_btcoex_detach(cfg); wl_deinit_priv(cfg); - wiphy_free(cfg->wiphy); + brcmf_free_wiphy(cfg->wiphy); } -- cgit v1.2.2 From c3da74bbbb8b230ad8bb84ca324c4e07607c9a7f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:42 +0200 Subject: brcmfmac: add brcmf_p2p_detach() call in brcmf_cfg80211_detach() The function brcmf_p2p_detach() was only called in error flow of the brcmf_cfg80211_attach() routine, but it also needs to be called upon brcmf_cfg80211_detach(). Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index d3bb4e0f4480..48078a321716 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -5682,6 +5682,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) WARN_ON(!list_empty(&cfg->vif_list)); wiphy_unregister(cfg->wiphy); brcmf_btcoex_detach(cfg); + brcmf_p2p_detach(&cfg->p2p); wl_deinit_priv(cfg); brcmf_free_wiphy(cfg->wiphy); } -- cgit v1.2.2 From d8aef3239e7d6a1bd550014ac766e5ec11c63ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 15 Jul 2014 16:54:47 +0200 Subject: bcma: extract antenna gains from SPROM correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just like in case of SSB SPROMs they are encoded in a bit tricky way. SPROM struct already uses s8 type and it's supposed to store decoded values. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 37 -------------------------- 1 file changed, 37 deletions(-) (limited to 'drivers/net/wireless/brcm80211') diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index af8ba64ace39..1b474828d5b8 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -4707,41 +4707,6 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, return err; } -static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc) -{ - uint unit; - unit = wlc->pub->unit; - - if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { - /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ - wlc->band->antgain = 8; - } else if (wlc->band->antgain == -1) { - wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" - " srom, using 2dB\n", unit, __func__); - wlc->band->antgain = 8; - } else { - s8 gain, fract; - /* Older sroms specified gain in whole dbm only. In order - * be able to specify qdbm granularity and remain backward - * compatible the whole dbms are now encoded in only - * low 6 bits and remaining qdbms are encoded in the hi 2 bits. - * 6 bit signed number ranges from -32 - 31. - * - * Examples: - * 0x1 = 1 db, - * 0xc1 = 1.75 db (1 + 3 quarters), - * 0x3f = -1 (-1 + 0 quarters), - * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm. - * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm. - */ - gain = wlc->band->antgain & 0x3f; - gain <<= 2; /* Sign extend */ - gain >>= 2; - fract = (wlc->band->antgain & 0xc0) >> 6; - wlc->band->antgain = 4 * gain + fract; - } -} - static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) { int aa; @@ -4780,8 +4745,6 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) else wlc->band->antgain = sprom->antenna_gain.a0; - brcms_c_attach_antgain_init(wlc); - return true; } -- cgit v1.2.2