diff options
Diffstat (limited to 'drivers/staging/brcm80211')
88 files changed, 6957 insertions, 13616 deletions
diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index b6f86354b69f..f4cf9b23481e 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -1,21 +1,26 @@ -menuconfig BRCM80211 - tristate "Broadcom IEEE802.11n WLAN drivers" - depends on WLAN +config BRCMUTIL + tristate + default n config BRCMSMAC - bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" + tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" + default n depends on PCI - depends on BRCM80211 && MAC80211 + depends on WLAN && MAC80211 + select BRCMUTIL select FW_LOADER + select CRC_CCITT ---help--- This module adds support for PCIe wireless adapters based on Broadcom IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll be called brcmsmac.ko. config BRCMFMAC - bool "Broadcom IEEE802.11n embedded FullMAC WLAN driver" + tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" + default n depends on MMC - depends on BRCM80211 && CFG80211 + depends on WLAN && CFG80211 + select BRCMUTIL select FW_LOADER select WIRELESS_EXT select WEXT_PRIV @@ -28,6 +33,6 @@ config BRCMFMAC config BRCMDBG bool "Broadcom driver debug functions" default n - depends on BRCM80211 + depends on BRCMSMAC || BRCMFMAC ---help--- Selecting this enables additional code for debug purposes. diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index c064cdf47f0d..e7b3f27847cf 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -19,5 +19,6 @@ subdir-ccflags-y := -DBCMDMA32 subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT +obj-$(CONFIG_BRCMUTIL) += util/ obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index f8facb0786ec..8ad558675bd3 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -1,90 +1,64 @@ -Broadcom Mac80211 driver +Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers. -This is a driver in progress. It has features still to be implemented well as -bugs in current code. +Completely open source host drivers, no binary object files. +Support for the following chips: +=============================== -What's here and not here -======================= -- Completely open source host driver, no binary object files -- Features Broadcom's OneDriver architecture (single source base for - supported chips and architectures) -- On-chip firmware loaded using standard request_firmware() -- Support for BCM43224, BCM43225, BCM4313 (PCIe NIC) -- Framework for supporting new chips, including mac80211-aware embedded chips -- Does not support older PCI/PCIe chips with SSB backplane -- Driver includes BMAC interface for transparent dongle support -- Uses minstrel_ht rate algorithm -- HW based encryption not enabled yet + brcmsmac (PCIe) + Name Device ID + BCM4313 0x4727 + BCM43224 0x4353 + BCM43225 0x4357 + brcmfmac (SDIO) + Name + BCM4329 -What's done -========== -- Integration with mac80211 stack -- A-MPDU single & dual stream rates -- BCM43224: Dualband, Dual stream, 20MHz channels - Throughput (in chamber): ~85-90 Mbits/sec (in both 2.4 & 5 GHz bands) -- BCM43225: 2.4 GHz, Dual Stream, 20MHz channels - Throughput (in chamber): ~85-90 Mbits/sec -- BCM4313: 2.4 GHz, Single Stream - Throughput (in chamber): ~40 Mbits/sec +Both brcmsmac and brcmfmac drivers require firmware files that need to be +separately downloaded. - -Things To Be Done -================= -See the TODO file - - -Firmware installation +Firmware ====================== Firmware is available from the Linux firmware repository at: - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git + git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git + http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git + https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git -For all chips, copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to -/lib/firmware/brcm (or wherever firmware is normally installed on your system). -Currently supported chips -============== -PCI -Name Device ID -BCM4313 0x4727 -BCM43224 0x4353 -BCM43225 0x4357 +=============================================================== +Broadcom brcmsmac driver +=============================================================== +- Support for both 32 and 64 bit Linux kernels -Bugs/Problems -============== -- Driver can get confused while scanning during high throughput, can cause - burping, hanging, and possible crashing. -- Occasional hangs & burps with BCM43224 on 2.4 GHz with dual stream rates. -- Occasional crashes with BCM43224 on multicore machines. +Firmware installation +====================== +Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to +/lib/firmware/brcm (or wherever firmware is normally installed +on your system). -Note on Regulatory Implementation -================================ -This generation of chips contain additional regulatory support independent of -the driver. The devices use a single worldwide regulatory domain, with channels -12-14 (2.4 GHz band) and channels 52-64 and 100-140 (5 GHz band) restricted to -passive operation. Transmission on those channels is suppressed until -appropriate other traffic is observed on those channels. +=============================================================== +Broadcom brcmfmac driver +=============================================================== +- Support for 32 bit Linux kernel, 64 bit untested -Within the driver, we use the fictitious country code "X2" to represent this -worldwide regulatory domain. There is currently no interface to configure a -different domain. -The driver reads the SROM country code from the chip and hands it up to -mac80211 as the regulatory hint, however this information is otherwise unused -with the driver. +Firmware installation +====================== +Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt +to /lib/firmware/brcm (or wherever firmware is normally installed on your +system). Contact Info: ============= Brett Rudley brudley@broadcom.com Henry Ptasinski henryp@broadcom.com -Dowan Kim dowan@broadcom.com +Dowan Kim dowan@broadcom.com Roland Vossen rvossen@broadcom.com Arend van Spriel arend@broadcom.com +For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index 24ebadbe4241..e9c1393a2b92 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -1,51 +1,15 @@ -To Do List for Broadcom Mac80211 driver - -Features to be added -===================== -- 40 MHz channels -- Power Save -- AP -- IBSS -- HW-based encryption -- LED support -- RFKILL -- Debugfs and debugability - -Code cleanup -============ -- Use proper kernel coding standards -- Remove overlap with system header files. (ie much of include/proto/*.h should - be removed) -- Purge unused variables/data structs/functions BUT keep code related to - features that are being added (ie AP mode, 40 Mhz channels, IBSS etc). -- Replace proprietary utility functions with public kernel versions. +To Do List for Broadcom Mac80211 driver before getting in mainline Bugs ==== -- Various occasional asserts/hangs -- Scanning during data transfer sometimes causes major slowdowns. Sometimes - revcovers when scan is done, other times not. -- Mac80211 API not completely implemented (ie ops_bss_info_changed, - ops_get_stats, etc) - -Other -===== -- wlc_mac80211.[ch], wl_mac80211.[ch] and linux_osl.c all need to be refactored - and combined. -- Merge files that are partially duplicated between the softmac and fullmac - drivers -- Replace driver's proprietary ssb interface with generic kernel ssb module - (only used when compiling for SDIO). -- PCI and SDIO support are currently #ifdef'ed exclusive of each other, which - leads to a separate wl.ko for each. This should be changed to runtime - handling of different interfaces so that a single binary driver can be built. -- Add support for new chips (obviously an ongoing item). +- Oops on AMPDU traffic, to be solved by new ucode (currently under test) -Contact -===== -Brett Rudley <brudley@broadcom.com> -Henry Ptasinski <henryp@broadcom.com> -Dowan Kim <dowan@broadcom.com> -Roland Vossen <rvossen@broadcom.com> -Arend van Spriel <arend@broadcom.com> +brcmfmac and brcmsmac +===================== +- ASSERTS not allowed in mainline, replace by warning + error handling +- Replace printk and WL_ERROR() with proper routines +brcmfmac +===================== +- Replace driver's proprietary ssb interface with generic kernel ssb module +- Build and test on 64 bit linux kernel diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index ac5a7d4ba806..c5ec562c3645 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -36,8 +36,7 @@ ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG ccflags-y += \ -Idrivers/staging/brcm80211/brcmfmac \ - -Idrivers/staging/brcm80211/include \ - -Idrivers/staging/brcm80211/util + -Idrivers/staging/brcm80211/include DHDOFILES = \ wl_cfg80211.o \ @@ -51,13 +50,7 @@ DHDOFILES = \ bcmsdh.o \ bcmsdh_linux.o \ bcmsdh_sdmmc.o \ - bcmsdh_sdmmc_linux.o \ - aiutils.o \ - siutils.o \ - sbutils.o \ - bcmutils.o \ - bcmwifi.o \ - hndpmu.o + bcmsdh_sdmmc_linux.o -obj-m += brcmfmac.o +obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += $(DHDOFILES) diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README index be29e4236920..139597f9cb07 100644 --- a/drivers/staging/brcm80211/brcmfmac/README +++ b/drivers/staging/brcm80211/brcmfmac/README @@ -1,37 +1,2 @@ -Broadcom fullmac driver -This is production driver. - -What's here -=========== -- Completely open source host driver, no binary object files -- Features Broadcom's OneDriver architecture (single source base for - supported chips and architectures) -- On-chip firmware loaded using standard request_firmware() -- Support for BCM4329(SDIO) - -What's done -========== -- Integration with cfg80211 stack -- Most of Mac functionality is performed in dongle -- A-MPDU single stream rates -- BCM4329: Dualband, Single stream, 20MHz channels - -Firmware installation -====================== -Firmware is available from the Linux firmware repository at: - - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - -For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt -to /lib/firmware/brcm (or wherever firmware is normally installed on your -system). - -Contact Info: -============= -Brett Rudley brudley@broadcom.com -Henry Ptasinski henryp@broadcom.com -Nohee Ko noheek@broadcom.com diff --git a/drivers/staging/brcm80211/util/siutils_priv.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h index a03ff617531a..c0d4c3bf6d42 100644 --- a/drivers/staging/brcm80211/util/siutils_priv.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmchip.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Broadcom Corporation + * Copyright (c) 2011 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 @@ -14,17 +14,22 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _siutils_priv_h_ -#define _siutils_priv_h_ +#ifndef _bcmchip_h_ +#define _bcmchip_h_ -/* Silicon Backplane externs */ -extern void sb_scan(si_t *sih, void *regs, uint devid); -uint sb_coreid(si_t *sih); -uint sb_corerev(si_t *sih); -extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, - uint val); -extern bool sb_iscoreup(si_t *sih); -void *sb_setcoreidx(si_t *sih, uint coreidx); -extern void sb_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void sb_core_disable(si_t *sih, u32 bits); -#endif /* _siutils_priv_h_ */ +/* Core reg address translation */ +#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field)) +#define CORE_BUS_REG(base, field) (base + offsetof(sdpcmd_regs_t, field)) +#define CORE_SB(base, field) \ + (base + SBCONFIGOFF + offsetof(sbconfig_t, field)) + +/* bcm4329 */ +/* SDIO device core, ID 0x829 */ +#define BCM4329_CORE_BUS_BASE 0x18011000 +/* internal memory core, ID 0x80e */ +#define BCM4329_CORE_SOCRAM_BASE 0x18003000 +/* ARM Cortex M3 core, ID 0x82a */ +#define BCM4329_CORE_ARM_BASE 0x18002000 +#define BCM4329_RAMSIZE 0x48000 + +#endif /* _bcmchip_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 473f57d9f00b..3750fcf5a871 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -17,11 +17,11 @@ #include <linux/types.h> #include <linux/netdevice.h> +#include <linux/pci_ids.h> #include <bcmdefs.h> #include <bcmdevs.h> #include <bcmutils.h> #include <hndsoc.h> -#include <siutils.h> #include <bcmsdh.h> /* BRCM API for SDIO clients (such as wl, dhd) */ @@ -29,6 +29,8 @@ #include <sbsdio.h> /* BRCM sdio device core */ #include <sdio.h> /* sdio spec */ +#include "dngl_stats.h" +#include "dhd.h" #define SDIOH_API_ACCESS_RETRY_LIMIT 2 const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; @@ -126,7 +128,7 @@ int bcmsdh_intr_enable(void *sdh) ASSERT(bcmsdh); status = sdioh_interrupt_set(bcmsdh->sdioh, true); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int bcmsdh_intr_disable(void *sdh) @@ -136,7 +138,7 @@ int bcmsdh_intr_disable(void *sdh) ASSERT(bcmsdh); status = sdioh_interrupt_set(bcmsdh->sdioh, false); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) @@ -146,7 +148,7 @@ int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) ASSERT(bcmsdh); status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int bcmsdh_intr_dereg(void *sdh) @@ -156,7 +158,7 @@ int bcmsdh_intr_dereg(void *sdh) ASSERT(bcmsdh); status = sdioh_interrupt_deregister(bcmsdh->sdioh); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } #if defined(DHD_DEBUG) @@ -174,7 +176,7 @@ int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) ASSERT(sdh); /* don't support yet */ - return BCME_UNSUPPORTED; + return -ENOTSUPP; } u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err) @@ -204,7 +206,7 @@ u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); #endif if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); + *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", __func__, fnc_num, addr, data)); @@ -239,7 +241,7 @@ bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); #endif if (err) - *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; + *err = SDIOH_API_SUCCESS(status) ? 0 : -EIO; BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", __func__, fnc_num, addr, data)); @@ -261,7 +263,7 @@ u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err) fnc_num, addr, &data, 4); if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); + *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", __func__, fnc_num, addr, data)); @@ -286,7 +288,7 @@ bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data, SDIOH_WRITE, fnc_num, addr, &data, 4); if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); + *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", __func__, fnc_num, addr, data)); @@ -317,7 +319,7 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length) tmp_buf = kmalloc(length, GFP_ATOMIC); if (tmp_buf == NULL) { BCMSDH_ERROR(("%s: out of memory\n", __func__)); - return BCME_NOMEM; + return -ENOMEM; } memcpy(tmp_buf, cis, length); for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); @@ -329,7 +331,7 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length) kfree(tmp_buf); } - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address) @@ -467,7 +469,7 @@ bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, /* Async not implemented yet */ ASSERT(!(flags & SDIO_REQ_ASYNC)); if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; + return -ENOTSUPP; if (bar0 != bcmsdh->sbwad) { err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0); @@ -488,7 +490,7 @@ bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, SDIOH_READ, fn, addr, width, nbytes, buf, pkt); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int @@ -512,7 +514,7 @@ bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, /* Async not implemented yet */ ASSERT(!(flags & SDIO_REQ_ASYNC)); if (flags & SDIO_REQ_ASYNC) - return BCME_UNSUPPORTED; + return -ENOTSUPP; if (bar0 != bcmsdh->sbwad) { err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0); @@ -533,7 +535,7 @@ bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes) @@ -553,7 +555,7 @@ int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes) (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, addr, 4, nbytes, buf, NULL); - return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR; + return SDIOH_API_SUCCESS(status) ? 0 : -EIO; } int bcmsdh_abort(void *sdh, uint fn) @@ -580,7 +582,7 @@ int bcmsdh_stop(void *sdh) int bcmsdh_query_device(void *sdh) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; + bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; return bcmsdh->vendevid; } diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index ac5bbc8722e5..465f623760f3 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -43,6 +43,9 @@ extern void dhdsdio_isr(void *args); #include <linux/platform_device.h> #endif /* CONFIG_MACH_SANDGATE2G */ +#include "dngl_stats.h" +#include "dhd.h" + /** * SDIO Host Controller info */ @@ -87,11 +90,11 @@ bool bcmsdh_chipmatch(u16 vendor, u16 device) return true; /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) + if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM) return true; /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) + if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) return true; /* Check for TI PCIxx21 Standard host controller */ @@ -111,8 +114,7 @@ bool bcmsdh_chipmatch(u16 vendor, u16 device) #endif /* BCMSDIOH_STD */ #ifdef BCMSDIOH_SPI /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { - WL_NONE("Found PCI SPI Host Controller\n"); + if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) { return true; } #endif /* BCMSDIOH_SPI */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 71c3571ee143..c0ffbd35e0ca 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -26,14 +26,11 @@ #include <linux/mmc/core.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include <linux/suspend.h> #include <dngl_stats.h> #include <dhd.h> -#if defined(CONFIG_PM_SLEEP) -#include <linux/suspend.h> -extern volatile bool dhd_mmc_suspend; -#endif #include "bcmsdh_sdmmc.h" extern int sdio_function_init(void); @@ -68,6 +65,13 @@ DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr, int regsize, u32 *data); +void sdioh_sdio_set_host_pm_flags(int flag) +{ + if (sdio_set_host_pm_flags(gInstance->func[1], flag)) + printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\ + __func__, (unsigned int)flag); +} + static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) { int err_ret; @@ -416,7 +420,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, vi = bcm_iovar_lookup(sdioh_iovars, name); if (vi == NULL) { - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; goto exit; } @@ -465,7 +469,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_BLOCKSIZE): if ((u32) int_val > si->num_funcs) { - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } int_val = (s32) si->client_block_size[int_val]; @@ -479,7 +483,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, uint maxsize; if (func > si->num_funcs) { - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } @@ -497,7 +501,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, maxsize = 0; } if (blksize > maxsize) { - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } if (!blksize) @@ -600,7 +604,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, || sd_ptr->offset > SD_MaxCurCap) { sd_err(("%s: bad offset 0x%x\n", __func__, sd_ptr->offset)); - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } @@ -630,7 +634,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, || sd_ptr->offset > SD_MaxCurCap) { sd_err(("%s: bad offset 0x%x\n", __func__, sd_ptr->offset)); - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } @@ -649,7 +653,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, if (sdioh_cfg_read (si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; break; } @@ -665,14 +669,14 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, if (sdioh_cfg_write (si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; break; } break; } default: - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; break; } exit: @@ -1006,17 +1010,16 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, /* * This function takes a buffer or packet, and fixes everything up - * so that in the - * end, a DMA-able packet is created. + * so that in the end, a DMA-able packet is created. * * A buffer does not have an associated packet pointer, * and may or may not be aligned. * A packet may consist of a single packet, or a packet chain. - * If it is a packet chain, - * then all the packets in the chain must be properly aligned. - * If the packet data is not - * aligned, then there may only be one packet, and in this case, - * it is copied to a new + * If it is a packet chain, then all the packets in the chain + * must be properly aligned. + * + * If the packet data is not aligned, then there may only be + * one packet, and in this case, it is copied to a new * aligned packet. * */ @@ -1036,9 +1039,9 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (pkt == NULL) { sd_data(("%s: Creating new %s Packet, len=%d\n", __func__, write ? "TX" : "RX", buflen_u)); - mypkt = pkt_buf_get_skb(buflen_u); + mypkt = bcm_pkt_buf_get_skb(buflen_u); if (!mypkt) { - sd_err(("%s: pkt_buf_get_skb failed: len %d\n", + sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n", __func__, buflen_u)); return SDIOH_API_RC_FAIL; } @@ -1054,7 +1057,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) memcpy(buffer, mypkt->data, buflen_u); - pkt_buf_free_skb(mypkt); + bcm_pkt_buf_free_skb(mypkt); } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { /* Case 2: We have a packet, but it is unaligned. */ @@ -1063,9 +1066,9 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, sd_data(("%s: Creating aligned %s Packet, len=%d\n", __func__, write ? "TX" : "RX", pkt->len)); - mypkt = pkt_buf_get_skb(pkt->len); + mypkt = bcm_pkt_buf_get_skb(pkt->len); if (!mypkt) { - sd_err(("%s: pkt_buf_get_skb failed: len %d\n", + sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n", __func__, pkt->len)); return SDIOH_API_RC_FAIL; } @@ -1081,7 +1084,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) memcpy(pkt->data, mypkt->data, mypkt->len); - pkt_buf_free_skb(mypkt); + bcm_pkt_buf_free_skb(mypkt); } else { /* case 3: We have a packet and it is aligned. */ sd_data(("%s: Aligned %s Packet, direct DMA\n", diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c index d738d4da5443..2792a4dfe651 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c @@ -27,6 +27,9 @@ #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include "dngl_stats.h" +#include "dhd.h" + #if !defined(SDIO_VENDOR_ID_BROADCOM) #define SDIO_VENDOR_ID_BROADCOM 0x02d0 #endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ @@ -151,11 +154,11 @@ int sdioh_sdmmc_osinit(sdioh_info_t *sd) sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC); sd->sdos_info = (void *)sdos; if (sdos == NULL) - return BCME_NOMEM; + return -ENOMEM; sdos->sd = sd; spin_lock_init(&sdos->lock); - return BCME_OK; + return 0; } void sdioh_sdmmc_osfree(sdioh_info_t *sd) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmutils.c b/drivers/staging/brcm80211/brcmfmac/bcmutils.c deleted file mode 100644 index 8e1296a0009e..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmutils.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/bcmutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/bcmwifi.c b/drivers/staging/brcm80211/brcmfmac/bcmwifi.c deleted file mode 100644 index 9fe988c1b940..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmwifi.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/bcmwifi.c" diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 60cf78213a07..a726b493ea8d 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -31,6 +31,7 @@ #include <linux/random.h> #include <linux/spinlock.h> #include <linux/ethtool.h> +#include <linux/suspend.h> #include <asm/uaccess.h> #include <asm/unaligned.h> /* The kernel threading is sdio-specific */ @@ -122,19 +123,22 @@ typedef struct dhd_pub { } dhd_pub_t; #if defined(CONFIG_PM_SLEEP) - +extern atomic_t dhd_mmc_suspend; #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -#define _DHD_PM_RESUME_WAIT(a, b) do {\ - int retry = 0; \ - while (dhd_mmc_suspend && retry++ != b) { \ - wait_event_timeout(a, false, HZ/100); \ - } \ - } while (0) +#define _DHD_PM_RESUME_WAIT(a, b) do { \ + int retry = 0; \ + while (atomic_read(&dhd_mmc_suspend) && retry++ != b) { \ + wait_event_timeout(a, false, HZ/100); \ + } \ + } while (0) #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30) #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) #define DHD_PM_RESUME_RETURN_ERROR(a) \ - do { if (dhd_mmc_suspend) return a; } while (0) -#define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) + do { if (atomic_read(&dhd_mmc_suspend)) return a; } while (0) +#define DHD_PM_RESUME_RETURN do { \ + if (atomic_read(&dhd_mmc_suspend)) \ + return; \ + } while (0) #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); #define SPINWAIT_SLEEP(a, exp, us) do { \ @@ -397,4 +401,14 @@ extern char nv_path[MOD_PARAM_PATHLEN]; extern void dhd_wait_for_event(dhd_pub_t *dhd, bool * lockvar); extern void dhd_wait_event_wakeup(dhd_pub_t *dhd); +extern u32 g_assert_type; + +#ifdef BCMDBG +#define ASSERT(exp) \ + do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) +extern void osl_assert(char *exp, char *file, int line); +#else +#define ASSERT(exp) do {} while (0) +#endif /* defined(BCMDBG) */ + #endif /* _dhd_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 39a4d001fbd0..ba5a5cb7eede 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -111,7 +111,7 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) /* Respond "bcmerror" and "bcmerrorstr" with local cache */ if (cmd == WLC_GET_VAR && buf) { if (!strcmp((char *)buf, "bcmerrorstr")) { - strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), + strncpy((char *)buf, "bcm_error", BCME_STRLEN); goto done; } else if (!strcmp((char *)buf, "bcmerror")) { @@ -253,9 +253,9 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) "lastcmd=0x%x (%lu)\n", ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, (unsigned long)prot->lastcmd)); - if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) { + if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) DHD_TRACE(("iovar cmd=%s\n", (char *)buf)); - } + goto done; } @@ -309,7 +309,7 @@ int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, void *params, int plen, void *arg, int len, bool set) { - return BCME_UNSUPPORTED; + return -ENOTSUPP; } void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) @@ -357,7 +357,7 @@ int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) if (pktbuf->len < BDC_HEADER_LEN) { DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__, pktbuf->len, BDC_HEADER_LEN)); - return BCME_ERROR; + return -EBADE; } h = (struct bdc_header *)(pktbuf->data); @@ -366,14 +366,14 @@ int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) if (*ifidx >= DHD_MAX_IFS) { DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", __func__, *ifidx)); - return BCME_ERROR; + return -EBADE; } if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n", dhd_ifname(dhd, *ifidx), h->flags)); - return BCME_ERROR; + return -EBADE; } if (h->flags & BDC_FLAG_SUM_GOOD) { @@ -416,7 +416,7 @@ int dhd_prot_attach(dhd_pub_t *dhd) fail: kfree(cdc); - return BCME_NOMEM; + return -ENOMEM; } /* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index aa171f6181e9..0bfb93c0075a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -189,7 +189,7 @@ static int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) /* Add any bus info */ dhd_bus_dump(dhdp, strbuf); - return !strbuf->size ? BCME_BUFTOOSHORT : 0; + return !strbuf->size ? -EOVERFLOW : 0; } static int @@ -225,7 +225,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_BCMERRORSTR): - strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror), + strncpy((char *)arg, "bcm_error", BCME_STRLEN); ((char *)arg)[BCME_STRLEN - 1] = 0x00; break; @@ -242,7 +242,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_WDTICK): if (!dhd_pub->up) { - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; break; } dhd_os_wd_timer(dhd_pub, (uint) int_val); @@ -289,7 +289,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_IOCTLTIMEOUT):{ if (int_val <= 0) - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; else dhd_os_set_ioctl_resp_timeout((unsigned int) int_val); @@ -297,7 +297,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, } default: - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; break; } @@ -316,7 +316,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, * exceeding total queue length */ if (!pktq_pfull(q, prec) && !pktq_full(q)) { - pktq_penq(q, prec, pkt); + bcm_pktq_penq(q, prec, pkt); return true; } @@ -324,7 +324,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); + p = bcm_pktq_peek_tail(q, &eprec); ASSERT(p); if (eprec > prec) return false; @@ -338,21 +338,21 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, if (eprec == prec && !discard_oldest) return false; /* refuse newer (incoming) packet */ /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, - eprec); + p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : + bcm_pktq_pdeq_tail(q, eprec); if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed, oldest %d.", + DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.", __func__, discard_oldest)); ASSERT(p); } - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); } /* Enqueue */ - p = pktq_penq(q, prec, pkt); + p = bcm_pktq_penq(q, prec, pkt); if (p == NULL) { - DHD_ERROR(("%s: pktq_penq() failed.", __func__)); + DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__)); ASSERT(p); } @@ -381,7 +381,7 @@ dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, vi = bcm_iovar_lookup(dhd_iovars, name); if (vi == NULL) { - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; goto exit; } @@ -420,19 +420,19 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) DHD_TRACE(("%s: Enter\n", __func__)); if (!buf) - return BCME_BADARG; + return -EINVAL; switch (ioc->cmd) { case DHD_GET_MAGIC: if (buflen < sizeof(int)) - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; else *(int *)buf = DHD_IOCTL_MAGIC; break; case DHD_GET_VERSION: if (buflen < sizeof(int)) - bcmerror = -BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; else *(int *)buf = DHD_IOCTL_VERSION; break; @@ -448,7 +448,7 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) ; if (*arg) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -464,7 +464,7 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) + if (bcmerror != -ENOTSUPP) break; /* not in generic table, try protocol module */ @@ -476,7 +476,7 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) bcmerror = dhd_prot_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); - if (bcmerror != BCME_UNSUPPORTED) + if (bcmerror != -ENOTSUPP) break; /* if still not found, try bus module */ @@ -493,7 +493,7 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) } default: - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; } return bcmerror; @@ -586,6 +586,8 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) } DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); + DHD_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", + flags, status, reason, auth_type, eabuf)); if (flags & WLC_EVENT_MSG_LINK) link = true; @@ -815,14 +817,14 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__)); - return BCME_ERROR; + return -EBADE; } /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__)); - return BCME_ERROR; + return -EBADE; } *data_ptr = &pvt_data[1]; @@ -902,7 +904,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, wl_show_host_event(event, event_data); #endif /* SHOW_EVENTS */ - return BCME_OK; + return 0; } /* Convert user's input in hex pattern to byte-size mask */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index dd0375793875..f356c564cfb9 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -166,7 +166,7 @@ void wifi_del_dev(void) #if defined(CONFIG_PM_SLEEP) #include <linux/suspend.h> -volatile bool dhd_mmc_suspend = false; +atomic_t dhd_mmc_suspend; DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); #endif /* defined(CONFIG_PM_SLEEP) */ @@ -325,7 +325,7 @@ uint dhd_roam = 1; uint dhd_radio_up = 1; /* Network inteface name */ -char iface_name[IFNAMSIZ]; +char iface_name[IFNAMSIZ] = "wlan"; module_param_string(iface_name, iface_name, IFNAMSIZ, 0); /* The following are specific to the SDIO dongle */ @@ -385,10 +385,6 @@ module_param(dhd_pktgen_len, uint, 0); #define DHD_COMPILED #endif -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -#endif /* defined(CONFIG_WIRELESS_EXT) */ - static void dhd_dpc(unsigned long data); /* forward decl */ extern int dhd_wait_pend8021x(struct net_device *dev); @@ -411,11 +407,11 @@ static int dhd_sleep_pm_callback(struct notifier_block *nfb, switch (action) { case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: - dhd_mmc_suspend = true; + atomic_set(&dhd_mmc_suspend, true); return NOTIFY_OK; case PM_POST_HIBERNATION: case PM_POST_SUSPEND: - dhd_mmc_suspend = false; + atomic_set(&dhd_mmc_suspend, false); return NOTIFY_OK; } return 0; @@ -1619,51 +1615,6 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) return 0; } -static s16 linuxbcmerrormap[] = { 0, /* 0 */ - -EINVAL, /* BCME_ERROR */ - -EINVAL, /* BCME_BADARG */ - -EINVAL, /* BCME_BADOPTION */ - -EINVAL, /* BCME_NOTUP */ - -EINVAL, /* BCME_NOTDOWN */ - -EINVAL, /* BCME_NOTAP */ - -EINVAL, /* BCME_NOTSTA */ - -EINVAL, /* BCME_BADKEYIDX */ - -EINVAL, /* BCME_RADIOOFF */ - -EINVAL, /* BCME_NOTBANDLOCKED */ - -EINVAL, /* BCME_NOCLK */ - -EINVAL, /* BCME_BADRATESET */ - -EINVAL, /* BCME_BADBAND */ - -E2BIG, /* BCME_BUFTOOSHORT */ - -E2BIG, /* BCME_BUFTOOLONG */ - -EBUSY, /* BCME_BUSY */ - -EINVAL, /* BCME_NOTASSOCIATED */ - -EINVAL, /* BCME_BADSSIDLEN */ - -EINVAL, /* BCME_OUTOFRANGECHAN */ - -EINVAL, /* BCME_BADCHAN */ - -EFAULT, /* BCME_BADADDR */ - -ENOMEM, /* BCME_NORESOURCE */ - -EOPNOTSUPP, /* BCME_UNSUPPORTED */ - -EMSGSIZE, /* BCME_BADLENGTH */ - -EINVAL, /* BCME_NOTREADY */ - -EPERM, /* BCME_NOTPERMITTED */ - -ENOMEM, /* BCME_NOMEM */ - -EINVAL, /* BCME_ASSOCIATED */ - -ERANGE, /* BCME_RANGE */ - -EINVAL, /* BCME_NOTFOUND */ - -EINVAL, /* BCME_WME_NOT_ENABLED */ - -EINVAL, /* BCME_TSPEC_NOTFOUND */ - -EINVAL, /* BCME_ACM_NOTSUPPORTED */ - -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ - -EIO, /* BCME_SDIO_ERROR */ - -ENODEV, /* BCME_DONGLE_DOWN */ - -EINVAL, /* BCME_VERSION */ - -EIO, /* BCME_TXFAIL */ - -EIO, /* BCME_RXFAIL */ - -EINVAL, /* BCME_NODEVICE */ - -EINVAL, /* BCME_NMODE_DISABLED */ - -ENODATA, /* BCME_NONRESIDENT */ -}; - static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) { dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); @@ -1699,7 +1650,7 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) /* Copy the ioc control structure part of ioctl request */ if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { - bcmerror = -BCME_BADADDR; + bcmerror = -EINVAL; goto done; } @@ -1715,11 +1666,11 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) { buf = kmalloc(buflen, GFP_ATOMIC); if (!buf) { - bcmerror = -BCME_NOMEM; + bcmerror = -ENOMEM; goto done; } if (copy_from_user(buf, ioc.buf, buflen)) { - bcmerror = -BCME_BADADDR; + bcmerror = -EINVAL; goto done; } } @@ -1728,12 +1679,12 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) /* To differentiate between wl and dhd read 4 more byes */ if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), sizeof(uint)) != 0)) { - bcmerror = -BCME_BADADDR; + bcmerror = -EINVAL; goto done; } if (!capable(CAP_NET_ADMIN)) { - bcmerror = -BCME_EPERM; + bcmerror = -EPERM; goto done; } @@ -1748,12 +1699,12 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) /* send to dongle (must be up, and wl) */ if ((dhd->pub.busstate != DHD_BUS_DATA)) { DHD_ERROR(("%s DONGLE_DOWN,__func__\n", __func__)); - bcmerror = BCME_DONGLE_DOWN; + bcmerror = -EIO; goto done; } if (!dhd->pub.iswl) { - bcmerror = BCME_DONGLE_DOWN; + bcmerror = -EIO; goto done; } @@ -1781,10 +1732,8 @@ done: if (bcmerror > 0) bcmerror = 0; - else if (bcmerror < BCME_LAST) - bcmerror = BCME_ERROR; - return linuxbcmerrormap[-bcmerror]; + return bcmerror; } static int dhd_stop(struct net_device *net) @@ -1997,7 +1946,6 @@ dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) strcpy(fw_path, wl_cfg80211_get_fwname()); strcpy(nv_path, wl_cfg80211_get_nvramname()); } - wl_cfg80211_dbg_level(DBG_CFG80211_GET()); } /* Set up the watchdog timer */ @@ -2062,7 +2010,9 @@ dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) g_bus = bus; #endif #if defined(CONFIG_PM_SLEEP) - register_pm_notifier(&dhd_sleep_pm_notifier); + atomic_set(&dhd_mmc_suspend, false); + if (!IS_CFG80211_FAVORITE()) + register_pm_notifier(&dhd_sleep_pm_notifier); #endif /* defined(CONFIG_PM_SLEEP) */ /* && defined(DHD_GPL) */ /* Init lock suspend to prevent kernel going to suspend */ @@ -2252,18 +2202,6 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; net->ethtool_ops = &dhd_ethtool_ops; -#if defined(CONFIG_WIRELESS_EXT) - if (!IS_CFG80211_FAVORITE()) { -#if WIRELESS_EXT < 19 - net->get_wireless_stats = dhd_get_wireless_stats; -#endif /* WIRELESS_EXT < 19 */ -#if WIRELESS_EXT > 12 - net->wireless_handlers = - (struct iw_handler_def *)&wl_iw_handler_def; -#endif /* WIRELESS_EXT > 12 */ - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen; memcpy(net->dev_addr, temp_addr, ETH_ALEN); @@ -2280,7 +2218,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) fail: net->netdev_ops = NULL; - return BCME_ERROR; + return -EBADE; } void dhd_bus_detach(dhd_pub_t *dhdp) @@ -2368,7 +2306,8 @@ void dhd_detach(dhd_pub_t *dhdp) wl_cfg80211_detach(); #if defined(CONFIG_PM_SLEEP) - unregister_pm_notifier(&dhd_sleep_pm_notifier); + if (!IS_CFG80211_FAVORITE()) + unregister_pm_notifier(&dhd_sleep_pm_notifier); #endif /* defined(CONFIG_PM_SLEEP) */ /* && defined(DHD_GPL) */ free_netdev(ifp->net); @@ -2670,21 +2609,6 @@ void dhd_os_sdtxunlock(dhd_pub_t *pub) dhd_os_sdunlock(pub); } -#if defined(CONFIG_WIRELESS_EXT) -struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev) -{ - int res = 0; - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev); - - res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats); - - if (res == 0) - return &dhd->iw.wstats; - else - return NULL; -} -#endif /* defined(CONFIG_WIRELESS_EXT) */ - static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, wl_event_msg_t *event, void **data) @@ -2694,7 +2618,7 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, ASSERT(dhd != NULL); bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data); - if (bcmerror != BCME_OK) + if (bcmerror != 0) return bcmerror; #if defined(CONFIG_WIRELESS_EXT) @@ -2894,6 +2818,13 @@ int dhd_wait_pend8021x(struct net_device *dev) return pend; } +void wl_os_wd_timer(struct net_device *ndev, uint wdtick) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev); + + dhd_os_wd_timer(&dhd->pub, wdtick); +} + #ifdef DHD_DEBUG int write_to_file(dhd_pub_t *dhd, u8 *buf, int size) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 464f52af1315..a71c6f8ee8a3 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -15,8 +15,11 @@ */ #include <linux/types.h> -#include <bcmdefs.h> +#include <linux/kernel.h> +#include <linux/printk.h> +#include <linux/pci_ids.h> #include <linux/netdevice.h> +#include <bcmdefs.h> #include <bcmsdh.h> #ifdef BCMEMBEDIMAGE @@ -27,8 +30,6 @@ #include <bcmutils.h> #include <bcmdevs.h> -#include <siutils.h> -#include <hndpmu.h> #include <hndsoc.h> #ifdef DHD_DEBUG #include <hndrte_armtrap.h> @@ -51,7 +52,7 @@ #include <dhd_dbg.h> #include <dhdioctl.h> #include <sdiovar.h> -#include <siutils_priv.h> +#include <bcmchip.h> #ifndef DHDSDIO_MEM_DUMP_FNAME #define DHDSDIO_MEM_DUMP_FNAME "mem_dump" @@ -136,12 +137,6 @@ /* Flags for SDH calls */ #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) -/* Packet free applicable unconditionally for sdio and sdspi. Conditional if - * bufpool was present for gspi bus. - */ -#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - pkt_buf_free_skb(pkt); - /* * Conversion of 802.1D priority to precedence level */ @@ -165,12 +160,28 @@ typedef struct dhd_console { } dhd_console_t; #endif /* DHD_DEBUG */ +/* misc chip info needed by some of the routines */ +struct chip_info { + u32 chip; + u32 chiprev; + u32 cccorebase; + u32 ccrev; + u32 cccaps; + u32 buscorebase; + u32 buscorerev; + u32 buscoretype; + u32 ramcorebase; + u32 armcorebase; + u32 pmurev; + u32 ramsize; +}; + /* Private data for SDIO bus interaction */ typedef struct dhd_bus { dhd_pub_t *dhd; bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ - si_t *sih; /* Handle for SI calls */ + struct chip_info *ci; /* Chip info struct */ char *vars; /* Variables (from CIS and/or other) */ uint varsz; /* Size of variables buffer */ u32 sbaddr; /* Current SB window pointer (-1, invalid) */ @@ -421,8 +432,6 @@ do { \ #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) -#define GSPI_PR55150_BAILOUT - #ifdef SDTEST static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start); @@ -447,10 +456,6 @@ static void dhdsdio_release_dongle(dhd_bus_t *bus); static uint process_nvram_vars(char *varbuf, uint len); static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes, - struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, - void *handle); static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, @@ -464,6 +469,23 @@ static int dhdsdio_download_nvram(struct dhd_bus *bus); #ifdef BCMEMBEDIMAGE static int dhdsdio_download_code_array(struct dhd_bus *bus); #endif +static void dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase); +static int dhdsdio_chip_attach(struct dhd_bus *bus, void *regs); +static void dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase); +static void dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, + u32 drivestrength); +static void dhdsdio_chip_detach(struct dhd_bus *bus); + +/* Packet free applicable unconditionally for sdio and sdspi. + * Conditional if bufpool was present for gspi bus. + */ +static void dhdsdio_pktfree2(dhd_bus_t *bus, struct sk_buff *pkt) +{ + dhd_os_sdlock_rxq(bus->dhd); + if ((bus->bus != SPI_BUS) || bus->usebufpool) + bcm_pkt_buf_free_skb(pkt); + dhd_os_sdunlock_rxq(bus->dhd); +} static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) { @@ -511,8 +533,8 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - if ((bus->sih->chip == BCM4329_CHIP_ID) - && (bus->sih->chiprev == 0)) + if ((bus->ci->chip == BCM4329_CHIP_ID) + && (bus->ci->chiprev == 0)) clkreq |= SBSDIO_FORCE_ALP; bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, @@ -520,11 +542,11 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (err) { DHD_ERROR(("%s: HT Avail request error: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } - if (pendok && ((bus->sih->buscoretype == PCMCIA_CORE_ID) - && (bus->sih->buscorerev == 9))) { + if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) + && (bus->ci->buscorerev == 9))) { u32 dummy, retries; R_SDREG(dummy, &bus->regs->clockctlstatus, retries); } @@ -536,7 +558,7 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (err) { DHD_ERROR(("%s: HT Avail read error: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } /* Go to pending and await interrupt if appropriate */ @@ -548,7 +570,7 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (err) { DHD_ERROR(("%s: Devctl error setting CA: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; @@ -557,7 +579,7 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) DHD_INFO(("CLKCTL: set PENDING\n")); bus->clkstate = CLK_PENDING; - return BCME_OK; + return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ devctl = @@ -581,12 +603,12 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (err) { DHD_ERROR(("%s: HT Avail request error: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n", __func__, PMU_MAX_TRANSITION_DLY, clkctl)); - return BCME_ERROR; + return -EBADE; } /* Mark clock available */ @@ -630,10 +652,10 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (err) { DHD_ERROR(("%s: Failed access turning clock off: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } - return BCME_OK; + return 0; } /* Change idle/active SD state */ @@ -653,7 +675,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error enabling sd_clock: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } iovalue = bus->sd_mode; @@ -662,7 +684,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error changing sd_mode: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } else if (bus->idleclock != DHD_IDLE_ACTIVE) { /* Restore clock speed */ @@ -672,7 +694,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error restoring sd_divisor: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } bus->clkstate = CLK_SDONLY; @@ -681,7 +703,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n", __func__, bus->sd_divisor, bus->sd_mode)); - return BCME_ERROR; + return -EBADE; } if (bus->idleclock == DHD_IDLE_STOP) { if (sd1idle) { @@ -694,7 +716,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error changing sd_clock: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } @@ -704,7 +726,7 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error disabling sd_clock: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } else if (bus->idleclock != DHD_IDLE_ACTIVE) { /* Set divisor to idle value */ @@ -714,13 +736,13 @@ static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) if (err) { DHD_ERROR(("%s: error changing sd_divisor: %d\n", __func__, err)); - return BCME_ERROR; + return -EBADE; } } bus->clkstate = CLK_NONE; } - return BCME_OK; + return 0; } /* Transition SD and backplane clock readiness */ @@ -738,7 +760,7 @@ static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); bus->activity = true; } - return BCME_OK; + return 0; } switch (target) { @@ -777,7 +799,7 @@ static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate)); #endif /* DHD_DEBUG */ - return BCME_OK; + return 0; } int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) @@ -792,13 +814,13 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) /* Done if we're already in the requested state */ if (sleep == bus->sleeping) - return BCME_OK; + return 0; /* Going to sleep: set the alarm and turn off the lights... */ if (sleep) { /* Don't sleep if something is pending */ if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) - return BCME_BUSY; + return -EBUSY; /* Disable SDIO interrupts (no longer interested) */ bcmsdh_intr_disable(bus->sdh); @@ -818,8 +840,8 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); /* Isolate the bus */ - if (bus->sih->chip != BCM4329_CHIP_ID - && bus->sih->chip != BCM4319_CHIP_ID) { + if (bus->ci->chip != BCM4329_CHIP_ID + && bus->ci->chip != BCM4319_CHIP_ID) { bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, SBSDIO_DEVCTL_PADS_ISO, NULL); } @@ -835,8 +857,8 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) /* Force pad isolation off if possible (in case power never toggled) */ - if ((bus->sih->buscoretype == PCMCIA_CORE_ID) - && (bus->sih->buscorerev >= 10)) + if ((bus->ci->buscoretype == PCMCIA_CORE_ID) + && (bus->ci->buscorerev >= 10)) bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); @@ -864,7 +886,7 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) } } - return BCME_OK; + return 0; } #if defined(OOB_INTR_ONLY) @@ -922,7 +944,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, sdh = bus->sdh; if (bus->dhd->dongle_reset) { - ret = BCME_NOTREADY; + ret = -EPERM; goto done; } @@ -935,19 +957,19 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, DHD_INFO(("%s: insufficient headroom %d for %d pad\n", __func__, skb_headroom(pkt), pad)); bus->dhd->tx_realloc++; - new = pkt_buf_get_skb(pkt->len + DHD_SDALIGN); + new = bcm_pkt_buf_get_skb(pkt->len + DHD_SDALIGN); if (!new) { DHD_ERROR(("%s: couldn't allocate new %d-byte " "packet\n", __func__, pkt->len + DHD_SDALIGN)); - ret = BCME_NOMEM; + ret = -ENOMEM; goto done; } PKTALIGN(new, pkt->len, DHD_SDALIGN); memcpy(new->data, pkt->data, pkt->len); if (free_pkt) - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); /* free the pkt if canned one is not used */ free_pkt = true; pkt = new; @@ -983,9 +1005,12 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, if (DHD_BYTES_ON() && (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - prhex("Tx Frame", frame, len); + printk(KERN_DEBUG "Tx Frame:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); } else if (DHD_HDRS_ON()) { - prhex("TxHdr", frame, min_t(u16, len, 16)); + printk(KERN_DEBUG "TxHdr:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + frame, min_t(u16, len, 16)); } #endif @@ -1019,7 +1044,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL); bus->f2txdata++; - ASSERT(ret != BCME_PENDING); + ASSERT(ret != -BCME_PENDING); if (ret < 0) { /* On failure, abort the command @@ -1061,14 +1086,14 @@ done: dhd_os_sdlock(bus->dhd); if (free_pkt) - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); return ret; } int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) { - int ret = BCME_ERROR; + int ret = -EBADE; uint datalen, prec; DHD_TRACE(("%s: Enter\n", __func__)); @@ -1110,11 +1135,11 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) { skb_pull(pkt, SDPCM_HDRLEN); dhd_txcomplete(bus->dhd, pkt, false); - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); DHD_ERROR(("%s: out of bus->txq !!!\n", __func__)); - ret = BCME_NORESOURCE; + ret = -ENOSR; } else { - ret = BCME_OK; + ret = 0; } dhd_os_sdunlock_txq(bus->dhd); @@ -1183,7 +1208,7 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) /* Send frames until the limit or some other event */ for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { dhd_os_sdlock_txq(bus->dhd); - pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); + pkt = bcm_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); if (pkt == NULL) { dhd_os_sdunlock_txq(bus->dhd); break; @@ -1313,10 +1338,15 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) if (ret == -1) { #ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) - prhex("Tx Frame", frame, len); - else if (DHD_HDRS_ON()) - prhex("TxHdr", frame, min_t(u16, len, 16)); + if (DHD_BYTES_ON() && DHD_CTL_ON()) { + printk(KERN_DEBUG "Tx Frame:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + frame, len); + } else if (DHD_HDRS_ON()) { + printk(KERN_DEBUG "TxHdr:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + frame, min_t(u16, len, 16)); + } #endif do { @@ -1326,7 +1356,7 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) SDIO_FUNC_2, F2SYNC, frame, len, NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); + ASSERT(ret != -BCME_PENDING); if (ret < 0) { /* On failure, abort the command and @@ -1669,7 +1699,7 @@ static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg) memcpy(&pktgen, arg, sizeof(pktgen)); if (pktgen.version != DHD_PKTGEN_VERSION) - return BCME_BADARG; + return -EINVAL; oldcnt = bus->pktgen_count; oldmode = bus->pktgen_mode; @@ -1778,7 +1808,7 @@ static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", __func__, addr)); - return BCME_ERROR; + return -EBADE; } /* Read hndrte_shared structure */ @@ -1801,10 +1831,10 @@ static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) "is different than sdpcm_shared version %d in dongle\n", __func__, SDPCM_SHARED_VERSION, sh->flags & SDPCM_SHARED_VERSION_MASK)); - return BCME_ERROR; + return -EBADE; } - return BCME_OK; + return 0; } static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) @@ -1830,7 +1860,7 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) if (mbuffer == NULL) { DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, msize)); - bcmerror = BCME_NOMEM; + bcmerror = -ENOMEM; goto done; } } @@ -1838,7 +1868,7 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) str = kmalloc(maxstrlen, GFP_ATOMIC); if (str == NULL) { DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen)); - bcmerror = BCME_NOMEM; + bcmerror = -ENOMEM; goto done; } @@ -2007,19 +2037,19 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) c->bufsize = le32_to_cpu(c->log.buf_size); c->buf = kmalloc(c->bufsize, GFP_ATOMIC); if (c->buf == NULL) - return BCME_NOMEM; + return -ENOMEM; } idx = le32_to_cpu(c->log.idx); /* Protect against corrupt value */ if (idx > c->bufsize) - return BCME_ERROR; + return -EBADE; /* Skip reading the console buffer if the index pointer has not moved */ if (idx == c->last) - return BCME_OK; + return 0; /* Read the console buffer */ addr = le32_to_cpu(c->log.buf); @@ -2057,23 +2087,23 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) } break2: - return BCME_OK; + return 0; } #endif /* DHD_DEBUG */ int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) { - int bcmerror = BCME_OK; + int bcmerror = 0; DHD_TRACE(("%s: Enter\n", __func__)); /* Basic sanity checks */ if (bus->dhd->up) { - bcmerror = BCME_NOTDOWN; + bcmerror = -EISCONN; goto err; } if (!len) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; goto err; } @@ -2083,7 +2113,7 @@ int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) bus->vars = kmalloc(len, GFP_ATOMIC); bus->varsz = bus->vars ? len : 0; if (bus->vars == NULL) { - bcmerror = BCME_NOMEM; + bcmerror = -ENOMEM; goto err; } @@ -2122,7 +2152,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || actionid == IOV_GVAL(IOV_DEVRESET))) { - bcmerror = BCME_NOTREADY; + bcmerror = -EPERM; goto exit; } @@ -2182,7 +2212,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_IDLETIME): if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; else bus->idletime = int_val; break; @@ -2228,7 +2258,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, "0x%08x size %d dsize %d\n", __func__, (set ? "set" : "get"), address, size, dsize)); - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } @@ -2243,7 +2273,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d " "bytes at 0x%08x\n", __func__, bus->orig_ramsize, size, address)); - bcmerror = BCME_BADARG; + bcmerror = -EINVAL; break; } @@ -2271,7 +2301,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_SDIOD_DRIVE): dhd_sdiod_drive_strength = int_val; - si_sdiod_drive_strength_init(bus->sih, + dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength); break; @@ -2301,7 +2331,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_SDRXCHAIN): if (bool_val && !bus->sd_rxchain) - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; else bus->use_rxchain = bool_val; break; @@ -2324,7 +2354,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, if (bus->varsz < (uint) len) memcpy(arg, bus->vars, bus->varsz); else - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; #endif /* DHD_DEBUG */ @@ -2340,7 +2370,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, size = sd_ptr->func; int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; } @@ -2356,7 +2386,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, size = sd_ptr->func; bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; break; } @@ -2373,7 +2403,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, size = sdreg.func; int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; } @@ -2389,7 +2419,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, size = sdreg.func; bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); if (bcmsdh_regfail(bus->sdh)) - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; break; } @@ -2488,7 +2518,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; default: - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; break; } @@ -2525,7 +2555,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) if (bus->vars) { vbuffer = kzalloc(varsize, GFP_ATOMIC); if (!vbuffer) - return BCME_NOMEM; + return -ENOMEM; memcpy(vbuffer, bus->vars, bus->varsz); @@ -2537,7 +2567,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); if (!nvram_ularray) - return BCME_NOMEM; + return -ENOMEM; /* Upload image to verify downloaded contents. */ memset(nvram_ularray, 0xaa, varsize); @@ -2596,42 +2626,18 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) static int dhdsdio_download_state(dhd_bus_t *bus, bool enter) { uint retries; + u32 regdata; int bcmerror = 0; /* To enter download state, disable ARM and reset SOCRAM. * To exit download state, simply reset ARM (default is RAM boot). */ if (enter) { - bus->alp_only = true; - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __func__)); - bcmerror = BCME_ERROR; - goto fail; - } + dhdsdio_chip_disablecore(bus->sdh, bus->ci->armcorebase); - si_core_disable(bus->sih, 0); - if (bcmsdh_regfail(bus->sdh)) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", - __func__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", - __func__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } + dhdsdio_chip_resetcore(bus->sdh, bus->ci->ramcorebase); /* Clear the top bit of memory */ if (bus->ramsize) { @@ -2640,17 +2646,14 @@ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter) (u8 *)&zeros, 4); } } else { - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", - __func__)); - bcmerror = BCME_ERROR; - goto fail; - } - - if (!si_iscoreup(bus->sih)) { + regdata = bcmsdh_reg_read(bus->sdh, + CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4); + regdata &= (SBTML_RESET | SBTML_REJ_MASK | + (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); + if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) { DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __func__)); - bcmerror = BCME_ERROR; + bcmerror = -EBADE; goto fail; } @@ -2660,41 +2663,16 @@ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter) bcmerror = 0; } - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && - !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { - DHD_ERROR(("%s: Can't change back to SDIO core?\n", - __func__)); - bcmerror = BCME_ERROR; - goto fail; - } W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __func__)); - bcmerror = BCME_ERROR; - goto fail; - } - - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying to reset ARM core?\n", - __func__)); - bcmerror = BCME_SDIO_ERROR; - goto fail; - } + dhdsdio_chip_resetcore(bus->sdh, bus->ci->armcorebase); /* Allow HT Clock now that the ARM is running. */ bus->alp_only = false; bus->dhd->busstate = DHD_BUS_LOAD; } - fail: - /* Always return to SDIOD core */ - if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) - si_setcore(bus->sih, SDIOD_CORE_ID, 0); - return bcmerror; } @@ -2739,7 +2717,7 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, if (set && strcmp(name, "sd_divisor") == 0) { if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, &bus->sd_divisor, sizeof(s32), - false) != BCME_OK) { + false) != 0) { bus->sd_divisor = -1; DHD_ERROR(("%s: fail on %s get\n", __func__, name)); @@ -2752,7 +2730,7 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, if (set && strcmp(name, "sd_mode") == 0) { if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, &bus->sd_mode, sizeof(s32), - false) != BCME_OK) { + false) != 0) { bus->sd_mode = -1; DHD_ERROR(("%s: fail on %s get\n", __func__, name)); @@ -2767,7 +2745,7 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, if (bcmsdh_iovar_op (bus->sdh, "sd_blocksize", &fnum, sizeof(s32), &bus->blocksize, sizeof(s32), - false) != BCME_OK) { + false) != 0) { bus->blocksize = 0; DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize")); @@ -2867,14 +2845,14 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) dhdsdio_clkctl(bus, CLK_SDONLY, false); /* Clear the data packet queues */ - pktq_flush(&bus->txq, true); + bcm_pktq_flush(&bus->txq, true, NULL, NULL); /* Clear any held glomming stuff */ if (bus->glomd) - pkt_buf_free_skb(bus->glomd); + bcm_pkt_buf_free_skb(bus->glomd); if (bus->glom) - pkt_buf_free_skb(bus->glom); + bcm_pkt_buf_free_skb(bus->glom); bus->glom = bus->glomd = NULL; @@ -2948,14 +2926,11 @@ int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) /* If F2 successfully enabled, set core and enable interrupts */ if (ready == enable) { - /* Make sure we're talking to the core. */ - bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0); - if (!(bus->regs)) - bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); - /* Set up the interrupt mask and enable interrupts */ bus->hostintmask = HOSTINTMASK; - W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); + W_SDREG(bus->hostintmask, + (unsigned int *)CORE_BUS_REG(bus->ci->buscorebase, + hostintmask), retries); bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (u8) watermark, &err); @@ -3134,12 +3109,11 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) } /* Read remainder of frame body into the rxctl buffer */ - sdret = - dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (bus->rxctl + firstread), rdlen, NULL, NULL, - NULL); + sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, + F2SYNC, (bus->rxctl + firstread), rdlen, + NULL, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); + ASSERT(sdret != -BCME_PENDING); /* Control frame failures need retransmission */ if (sdret < 0) { @@ -3153,8 +3127,10 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) gotpkt: #ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) - prhex("RxCtrl", bus->rxctl, len); + if (DHD_BYTES_ON() && DHD_CTL_ON()) { + printk(KERN_DEBUG "RxCtrl:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); + } #endif /* Point to valid data and indicate its length */ @@ -3228,10 +3204,11 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Allocate/chain packet for next subframe */ - pnext = pkt_buf_get_skb(sublen + DHD_SDALIGN); + pnext = bcm_pkt_buf_get_skb(sublen + DHD_SDALIGN); if (pnext == NULL) { - DHD_ERROR(("%s: pkt_buf_get_skb failed, num %d len %d\n", - __func__, num, sublen)); + DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed, " + "num %d len %d\n", __func__, + num, sublen)); break; } ASSERT(!(pnext->prev)); @@ -3264,13 +3241,13 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) pfirst = pnext = NULL; } else { if (pfirst) - pkt_buf_free_skb(pfirst); + bcm_pkt_buf_free_skb(pfirst); bus->glom = NULL; num = 0; } /* Done with descriptor packet */ - pkt_buf_free_skb(bus->glomd); + bcm_pkt_buf_free_skb(bus->glomd); bus->glomd = NULL; bus->nextlen = 0; @@ -3291,27 +3268,23 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } pfirst = bus->glom; - dlen = (u16) pkttotlen(pfirst); + dlen = (u16) bcm_pkttotlen(pfirst); /* Do an SDIO read for the superframe. Configurable iovar to * read directly into the chained packet, or allocate a large * packet and and copy into the chain. */ if (usechain) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad - (bus->sdh), SDIO_FUNC_2, - F2SYNC, - (u8 *) pfirst->data, - dlen, pfirst, NULL, NULL); + errcode = bcmsdh_recv_buf(bus, + bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, + F2SYNC, (u8 *) pfirst->data, dlen, + pfirst, NULL, NULL); } else if (bus->dataptr) { - errcode = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad - (bus->sdh), SDIO_FUNC_2, - F2SYNC, bus->dataptr, - dlen, NULL, NULL, NULL); - sublen = - (u16) pktfrombuf(pfirst, 0, dlen, + errcode = bcmsdh_recv_buf(bus, + bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, + F2SYNC, bus->dataptr, dlen, + NULL, NULL, NULL); + sublen = (u16) bcm_pktfrombuf(pfirst, 0, dlen, bus->dataptr); if (sublen != dlen) { DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", @@ -3325,7 +3298,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) errcode = -1; } bus->f2rxdata++; - ASSERT(errcode != BCME_PENDING); + ASSERT(errcode != -BCME_PENDING); /* On failure, kill the superframe, allow a couple retries */ if (errcode < 0) { @@ -3339,7 +3312,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->glom); + bcm_pkt_buf_free_skb(bus->glom); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3348,8 +3321,9 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } #ifdef DHD_DEBUG if (DHD_GLOM_ON()) { - prhex("SUPERFRAME", pfirst->data, - min_t(int, pfirst->len, 48)); + printk(KERN_DEBUG "SUPERFRAME:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + pfirst->data, min_t(int, pfirst->len, 48)); } #endif @@ -3430,8 +3404,11 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); #ifdef DHD_DEBUG - if (DHD_GLOM_ON()) - prhex("subframe", dptr, 32); + if (DHD_GLOM_ON()) { + printk(KERN_DEBUG "subframe:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + dptr, 32); + } #endif if ((u16)~(sublen ^ check)) { @@ -3468,7 +3445,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->glom); + bcm_pkt_buf_free_skb(bus->glom); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3508,15 +3485,18 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) rxseq = seq; } #ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) - prhex("Rx Subframe Data", dptr, dlen); + if (DHD_BYTES_ON() && DHD_DATA_ON()) { + printk(KERN_DEBUG "Rx Subframe Data:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + dptr, dlen); + } #endif __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); if (pfirst->len == 0) { - pkt_buf_free_skb(pfirst); + bcm_pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { @@ -3529,7 +3509,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) DHD_ERROR(("%s: rx protocol error\n", __func__)); bus->dhd->rx_errors++; - pkt_buf_free_skb(pfirst); + bcm_pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { @@ -3552,8 +3532,9 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) __func__, num, pfirst, pfirst->data, pfirst->len, pfirst->next, pfirst->prev)); - prhex("", (u8 *) pfirst->data, - min_t(int, pfirst->len, 32)); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + pfirst->data, + min_t(int, pfirst->len, 32)); } #endif /* DHD_DEBUG */ } @@ -3578,7 +3559,6 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) u16 len, check; /* Extracted hardware header fields */ u8 chan, seq, doff; /* Extracted software header fields */ u8 fcbits; /* Extracted fcbits from software header */ - u8 delta; struct sk_buff *pkt; /* Packet for event or data frames */ u16 pad; /* Number of pad bytes to read */ @@ -3667,7 +3647,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) */ /* Allocate a packet buffer */ dhd_os_sdlock_rxq(bus->dhd); - pkt = pkt_buf_get_skb(rdlen + DHD_SDALIGN); + pkt = bcm_pkt_buf_get_skb(rdlen + DHD_SDALIGN); if (!pkt) { if (bus->bus == SPI_BUS) { bus->usebufpool = false; @@ -3684,16 +3664,13 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) ASSERT(bus->rxctl >= bus->rxbuf); rxbuf = bus->rxctl; /* Read the entire frame */ - sdret = dhd_bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad - (sdh), - SDIO_FUNC_2, - F2SYNC, - rxbuf, - rdlen, NULL, - NULL, NULL); + sdret = bcmsdh_recv_buf(bus, + bcmsdh_cur_sbwad(sdh), + SDIO_FUNC_2, F2SYNC, + rxbuf, rdlen, + NULL, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); + ASSERT(sdret != -BCME_PENDING); /* Control frame failures need retransmission */ @@ -3713,8 +3690,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } else { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): pkt_buf_get_skb failed: len %d rdlen %d " "expected rxseq %d\n", - __func__, len, rdlen, rxseq)); + DHD_ERROR(("%s (nextlen): " + "bcm_pkt_buf_get_skb failed:" + " len %d rdlen %d expected" + " rxseq %d\n", __func__, + len, rdlen, rxseq)); /* Just go try again w/normal header read */ dhd_os_sdunlock_rxq(bus->dhd); @@ -3728,19 +3708,18 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) PKTALIGN(pkt, rdlen, DHD_SDALIGN); rxbuf = (u8 *) (pkt->data); /* Read the entire frame */ - sdret = - dhd_bcmsdh_recv_buf(bus, + sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - rxbuf, rdlen, pkt, NULL, - NULL); + rxbuf, rdlen, + pkt, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); + ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", __func__, rdlen, sdret)); - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); bus->dhd->rx_errors++; dhd_os_sdunlock_rxq(bus->dhd); /* Force retry w/normal header read. @@ -3767,23 +3746,19 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (!(len | check)) { DHD_INFO(("%s (nextlen): read zeros in HW " "header???\n", __func__)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; + dhdsdio_pktfree2(bus, pkt); continue; } /* Validate check bytes */ if ((u16)~(len ^ check)) { - DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" " 0x%04x/0x%04x/0x%04x\n", + DHD_ERROR(("%s (nextlen): HW hdr error:" + " nextlen/len/check" + " 0x%04x/0x%04x/0x%04x\n", __func__, nextlen, len, check)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); bus->rx_badhdr++; dhdsdio_rxfail(bus, false, false); - GSPI_PR55150_BAILOUT; + dhdsdio_pktfree2(bus, pkt); continue; } @@ -3791,10 +3766,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (len < SDPCM_HDRLEN) { DHD_ERROR(("%s (nextlen): HW hdr length " "invalid: %d\n", __func__, len)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - GSPI_PR55150_BAILOUT; + dhdsdio_pktfree2(bus, pkt); continue; } @@ -3803,31 +3775,25 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (len_consistent) { /* Mismatch, force retry w/normal header (may be >4K) */ - DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " "expected rxseq %d\n", + DHD_ERROR(("%s (nextlen): mismatch, " + "nextlen %d len %d rnd %d; " + "expected rxseq %d\n", __func__, nextlen, len, roundup(len, 16), rxseq)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, true, - (bus->bus == - SPI_BUS) ? false : true); - GSPI_PR55150_BAILOUT; + dhdsdio_rxfail(bus, true, (bus->bus != SPI_BUS)); + dhdsdio_pktfree2(bus, pkt); continue; } /* Extract software header fields */ - chan = - SDPCM_PACKET_CHANNEL(&bus->rxhdr - [SDPCM_FRAMETAG_LEN]); - seq = - SDPCM_PACKET_SEQUENCE(&bus->rxhdr - [SDPCM_FRAMETAG_LEN]); - doff = - SDPCM_DOFFSET_VALUE(&bus->rxhdr - [SDPCM_FRAMETAG_LEN]); - txmax = - SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); + chan = SDPCM_PACKET_CHANNEL( + &bus->rxhdr[SDPCM_FRAMETAG_LEN]); + seq = SDPCM_PACKET_SEQUENCE( + &bus->rxhdr[SDPCM_FRAMETAG_LEN]); + doff = SDPCM_DOFFSET_VALUE( + &bus->rxhdr[SDPCM_FRAMETAG_LEN]); + txmax = SDPCM_WINDOW_VALUE( + &bus->rxhdr[SDPCM_FRAMETAG_LEN]); bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + @@ -3839,21 +3805,18 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } bus->dhd->rx_readahead_cnt++; + /* Handle Flow Control */ - fcbits = - SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); + fcbits = SDPCM_FCMASK_VALUE( + &bus->rxhdr[SDPCM_FRAMETAG_LEN]); - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } + if (bus->flowcontrol != fcbits) { + if (~bus->flowcontrol & fcbits) + bus->fc_xoff++; + + if (bus->flowcontrol & ~fcbits) + bus->fc_xon++; - if (delta) { bus->fc_rcvd++; bus->flowcontrol = fcbits; } @@ -3876,33 +3839,30 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) bus->tx_max = txmax; #ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) - prhex("Rx Data", rxbuf, len); - else if (DHD_HDRS_ON()) - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); + if (DHD_BYTES_ON() && DHD_DATA_ON()) { + printk(KERN_DEBUG "Rx Data:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + rxbuf, len); + } else if (DHD_HDRS_ON()) { + printk(KERN_DEBUG "RxHdr:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + bus->rxhdr, SDPCM_HDRLEN); + } #endif if (chan == SDPCM_CONTROL_CHANNEL) { if (bus->bus == SPI_BUS) { dhdsdio_read_control(bus, rxbuf, len, doff); - if (bus->usebufpool) { - dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(pkt); - dhd_os_sdunlock_rxq(bus->dhd); - } - continue; } else { DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n", __func__, seq)); /* Force retry w/normal header read */ bus->nextlen = 0; dhdsdio_rxfail(bus, false, true); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - continue; } + dhdsdio_pktfree2(bus, pkt); + continue; } if ((bus->bus == SPI_BUS) && !bus->usebufpool) { @@ -3915,11 +3875,8 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if ((doff < SDPCM_HDRLEN) || (doff > len)) { DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n", __func__, doff, len, SDPCM_HDRLEN)); - dhd_os_sdlock_rxq(bus->dhd); - PKTFREE2(); - dhd_os_sdunlock_rxq(bus->dhd); - ASSERT(0); dhdsdio_rxfail(bus, false, false); + dhdsdio_pktfree2(bus, pkt); continue; } @@ -3931,12 +3888,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) break; /* Read frame header (hardware and software) */ - sdret = - dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, - F2SYNC, bus->rxhdr, firstread, NULL, - NULL, NULL); + sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), + SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread, + NULL, NULL, NULL); bus->f2rxhdrs++; - ASSERT(sdret != BCME_PENDING); + ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__, @@ -3946,8 +3902,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) continue; } #ifdef DHD_DEBUG - if (DHD_BYTES_ON() || DHD_HDRS_ON()) - prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN); + if (DHD_BYTES_ON() || DHD_HDRS_ON()) { + printk(KERN_DEBUG "RxHdr:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + bus->rxhdr, SDPCM_HDRLEN); + } #endif /* Extract hardware header fields */ @@ -4006,17 +3965,13 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Handle Flow Control */ fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); - delta = 0; - if (~bus->flowcontrol & fcbits) { - bus->fc_xoff++; - delta = 1; - } - if (bus->flowcontrol & ~fcbits) { - bus->fc_xon++; - delta = 1; - } + if (bus->flowcontrol != fcbits) { + if (~bus->flowcontrol & fcbits) + bus->fc_xoff++; + + if (bus->flowcontrol & ~fcbits) + bus->fc_xon++; - if (delta) { bus->fc_rcvd++; bus->flowcontrol = fcbits; } @@ -4077,11 +4032,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } dhd_os_sdlock_rxq(bus->dhd); - pkt = pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN); + pkt = bcm_pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN); if (!pkt) { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: pkt_buf_get_skb failed: rdlen %d chan %d\n", - __func__, rdlen, chan)); + DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed: rdlen %d " + "chan %d\n", __func__, rdlen, chan)); bus->dhd->rx_dropped++; dhd_os_sdunlock_rxq(bus->dhd); dhdsdio_rxfail(bus, false, RETRYCHAN(chan)); @@ -4097,12 +4052,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) PKTALIGN(pkt, rdlen, DHD_SDALIGN); /* Read the remaining frame data */ - sdret = - dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, + sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)), rdlen, pkt, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != BCME_PENDING); + ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { DHD_ERROR(("%s: read %d %s bytes failed: %d\n", @@ -4113,7 +4067,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) ? "data" : "test")), sdret)); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; dhdsdio_rxfail(bus, true, RETRYCHAN(chan)); @@ -4125,8 +4079,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) memcpy(pkt->data, bus->rxhdr, firstread); #ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) - prhex("Rx Data", pkt->data, len); + if (DHD_BYTES_ON() && DHD_DATA_ON()) { + printk(KERN_DEBUG "Rx Data:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + pkt->data, len); + } #endif deliver: @@ -4137,7 +4094,10 @@ deliver: __func__, len)); #ifdef DHD_DEBUG if (DHD_GLOM_ON()) { - prhex("Glom Data", pkt->data, len); + printk(KERN_DEBUG "Glom Data:\n"); + print_hex_dump_bytes("", + DUMP_PREFIX_OFFSET, + pkt->data, len); } #endif __skb_trim(pkt, len); @@ -4166,13 +4126,13 @@ deliver: if (pkt->len == 0) { dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); continue; } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { DHD_ERROR(("%s: rx protocol error\n", __func__)); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(pkt); + bcm_pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; continue; @@ -4245,16 +4205,16 @@ static u32 dhdsdio_hostmail(dhd_bus_t *bus) /* * Flow Control has been moved into the RX headers and this out of band - * method isn't used any more. Leae this here for possibly - * remaining backward - * compatible with older dongles + * method isn't used any more. + * remaining backward compatible with older dongles. */ if (hmb_data & HMB_DATA_FC) { - fcbits = - (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT; + fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> + HMB_DATA_FCDATA_SHIFT; if (fcbits & ~bus->flowcontrol) bus->fc_xoff++; + if (bus->flowcontrol & ~fcbits) bus->fc_xon++; @@ -4454,7 +4414,7 @@ clkwait: F2SYNC, (u8 *) bus->ctrl_frame_buf, (u32) bus->ctrl_frame_len, NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); + ASSERT(ret != -BCME_PENDING); if (ret < 0) { /* On failure, abort the command and @@ -4493,7 +4453,7 @@ clkwait: } /* Send queued frames (limit 1 if rx may still be pending) */ else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit + bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax); framecnt = dhdsdio_sendfromq(bus, framecnt); @@ -4514,7 +4474,7 @@ clkwait: "I_CHIPACTIVE interrupt\n", __func__)); resched = true; } else if (bus->intstatus || bus->ipend || - (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && + (!bus->fcstate && bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) || PKT_AVAILABLE()) { resched = true; } @@ -4648,11 +4608,12 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) /* Allocate an appropriate-sized packet */ len = bus->pktgen_len; - pkt = pkt_buf_get_skb( + pkt = bcm_pkt_buf_get_skb( (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), true); if (!pkt) { - DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); + DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", + __func__)); break; } PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), @@ -4679,7 +4640,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) default: DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - pkt_buf_free_skb(pkt, true); + bcm_pkt_buf_free_skb(pkt, true); bus->pktgen_count = 0; return; } @@ -4697,8 +4658,9 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) #ifdef DHD_DEBUG if (DHD_BYTES_ON() && DHD_DATA_ON()) { data = (u8 *) (pkt->data) + SDPCM_HDRLEN; - prhex("dhdsdio_pktgen: Tx Data", data, - pkt->len - SDPCM_HDRLEN); + printk(KERN_DEBUG "dhdsdio_pktgen: Tx Data:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, + pkt->len - SDPCM_HDRLEN); } #endif @@ -4727,10 +4689,10 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) u8 *data; /* Allocate the packet */ - pkt = pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, - true); + pkt = bcm_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + + DHD_SDALIGN, true); if (!pkt) { - DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); + DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", __func__)); return; } PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); @@ -4762,7 +4724,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) if (pktlen < SDPCM_TEST_HDRLEN) { DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); return; } @@ -4780,7 +4742,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); return; } } @@ -4795,14 +4757,14 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) bus->pktgen_sent++; } else { bus->pktgen_fail++; - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); } bus->pktgen_rcvd++; break; case SDPCM_TEST_ECHORSP: if (bus->ext_loop) { - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; } @@ -4815,12 +4777,12 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) break; } } - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; case SDPCM_TEST_DISCARD: - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; @@ -4830,7 +4792,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - pkt_buf_free_skb(pkt, false); + bcm_pkt_buf_free_skb(pkt, false); break; } @@ -4952,7 +4914,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Address could be zero if CONSOLE := 0 in dongle Makefile */ if (bus->console_addr == 0) - return BCME_UNSUPPORTED; + return -ENOTSUPP; /* Exclusive bus access */ dhd_os_sdlock(bus->dhd); @@ -4960,7 +4922,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Don't allow input if dongle is in reset */ if (bus->dhd->dongle_reset) { dhd_os_sdunlock(bus->dhd); - return BCME_NOTREADY; + return -EPERM; } /* Request clock to allow SDIO accesses */ @@ -4991,7 +4953,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Bump dongle by sending an empty event pkt. * sdpcm_sendup (RX) checks for virtual console input. */ - pkt = pkt_buf_get_skb(4 + SDPCM_RESERVE); + pkt = bcm_pkt_buf_get_skb(4 + SDPCM_RESERVE); if ((pkt != NULL) && bus->clkstate == CLK_AVAIL) dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true); @@ -5089,7 +5051,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, /* Check the Vendor ID */ switch (venid) { case 0x0000: - case VENDOR_BROADCOM: + case PCI_VENDOR_ID_BROADCOM: break; default: DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid)); @@ -5179,7 +5141,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, /* if firmware path present try to download and bring up bus */ ret = dhd_bus_start(bus->dhd); if (ret != 0) { - if (ret == BCME_NOTUP) { + if (ret == -ENOLINK) { DHD_ERROR(("%s: dongle is not responding\n", __func__)); goto fail; } @@ -5215,7 +5177,10 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) #endif /* DHD_DEBUG */ - /* Force PLL off until si_attach() programs PLL control regs */ + /* + * Force PLL off until dhdsdio_chip_attach() + * programs PLL control regs + */ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err); @@ -5281,34 +5246,26 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) } #endif /* DHD_DEBUG */ - /* si_attach() will provide an SI handle and scan the backplane */ - bus->sih = si_attach((uint) devid, regsva, DHD_BUS, sdh, - &bus->vars, &bus->varsz); - if (!(bus->sih)) { - DHD_ERROR(("%s: si_attach failed!\n", __func__)); + if (dhdsdio_chip_attach(bus, regsva)) { + DHD_ERROR(("%s: dhdsdio_chip_attach failed!\n", __func__)); goto fail; } - bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); + bcmsdh_chipinfo(sdh, bus->ci->chip, bus->ci->chiprev); - if (!dhdsdio_chipmatch((u16) bus->sih->chip)) { + if (!dhdsdio_chipmatch((u16) bus->ci->chip)) { DHD_ERROR(("%s: unsupported chip: 0x%04x\n", - __func__, bus->sih->chip)); + __func__, bus->ci->chip)); goto fail; } - si_sdiod_drive_strength_init(bus->sih, dhd_sdiod_drive_strength); + dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength); /* Get info on the ARM and SOCRAM cores... */ if (!DHD_NOPMU(bus)) { - if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) || - (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - bus->armrev = si_corerev(bus->sih); - } else { - DHD_ERROR(("%s: failed to find ARM core!\n", __func__)); - goto fail; - } - bus->orig_ramsize = si_socram_size(bus->sih); + bus->armrev = SBCOREREV(bcmsdh_reg_read(bus->sdh, + CORE_SB(bus->ci->armcorebase, sbidhigh), 4)); + bus->orig_ramsize = bus->ci->ramsize; if (!(bus->orig_ramsize)) { DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __func__)); @@ -5322,22 +5279,12 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) bus->ramsize, bus->orig_ramsize)); } - /* ...but normally deal with the SDPCMDEV core */ - bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0); - if (!bus->regs) { - bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); - if (!bus->regs) { - DHD_ERROR(("%s: failed to find SDIODEV core!\n", - __func__)); - goto fail; - } - } - bus->sdpcmrev = si_corerev(bus->sih); + bus->regs = (void *)bus->ci->buscorebase; /* Set core control so an SDIO reset does a backplane reset */ OR_REG(&bus->regs->corecontrol, CC_BPRESEN); - pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); + bcm_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); /* Locate an appropriately-aligned portion of hdrbuf */ bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN); @@ -5425,7 +5372,7 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) /* Query the SD clock speed */ if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, &bus->sd_divisor, sizeof(s32), - false) != BCME_OK) { + false) != 0) { DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor")); bus->sd_divisor = -1; } else { @@ -5435,7 +5382,7 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) /* Query the SD bus mode */ if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(s32), false) != BCME_OK) { + &bus->sd_mode, sizeof(s32), false) != 0) { DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode")); bus->sd_mode = -1; } else { @@ -5446,7 +5393,7 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) /* Query the F2 block size, set roundup accordingly */ fnum = 2; if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32), - &bus->blocksize, sizeof(s32), false) != BCME_OK) { + &bus->blocksize, sizeof(s32), false) != 0) { bus->blocksize = 0; DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize")); } else { @@ -5459,7 +5406,7 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) default to use if supported */ if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, &bus->sd_rxchain, sizeof(s32), - false) != BCME_OK) { + false) != 0) { bus->sd_rxchain = false; } else { DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n", @@ -5509,10 +5456,8 @@ static void dhdsdio_release(dhd_bus_t *bus) bcmsdh_intr_dereg(bus->sdh); if (bus->dhd) { - - dhdsdio_release_dongle(bus); - dhd_detach(bus->dhd); + dhdsdio_release_dongle(bus); bus->dhd = NULL; } @@ -5548,13 +5493,10 @@ static void dhdsdio_release_dongle(dhd_bus_t *bus) if (bus->dhd && bus->dhd->dongle_reset) return; - if (bus->sih) { + if (bus->ci) { dhdsdio_clkctl(bus, CLK_AVAIL, false); -#if !defined(BCMLXSDMMC) - si_watchdog(bus->sih, 4); -#endif /* !defined(BCMLXSDMMC) */ dhdsdio_clkctl(bus, CLK_NONE, false); - si_detach(bus->sih); + dhdsdio_chip_detach(bus); if (bus->vars && bus->varsz) kfree(bus->vars); bus->vars = NULL; @@ -5642,7 +5584,7 @@ static int dhdsdio_download_code_array(struct dhd_bus *bus) ularray = kmalloc(bus->ramsize, GFP_ATOMIC); if (!ularray) { - bcmerror = BCME_NOMEM; + bcmerror = -ENOMEM; goto err; } /* Upload image to verify downloaded contents. */ @@ -5865,7 +5807,7 @@ static int dhdsdio_download_nvram(struct dhd_bus *bus) } else { DHD_ERROR(("%s: error reading nvram file: %d\n", __func__, len)); - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; } err: @@ -5954,19 +5896,6 @@ err: return bcmerror; } -static int -dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, struct sk_buff *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) -{ - int status; - - /* 4329: GSPI check */ - status = - bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, - complete, handle); - return status; -} static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, @@ -5980,8 +5909,8 @@ dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, uint dhd_bus_chip(struct dhd_bus *bus) { - ASSERT(bus->sih != NULL); - return bus->sih->chip; + ASSERT(bus->ci != NULL); + return bus->ci->chip; } void *dhd_bus_pub(struct dhd_bus *bus) @@ -6023,7 +5952,7 @@ int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag) DHD_TRACE(("%s: WLAN OFF DONE\n", __func__)); /* App can now remove power from device */ } else - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; } else { /* App must have restored power to device before calling */ @@ -6058,15 +5987,404 @@ int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag) DHD_TRACE(("%s: WLAN ON DONE\n", __func__)); } else - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; } else - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; } else { - bcmerror = BCME_NOTDOWN; + bcmerror = -EISCONN; DHD_ERROR(("%s: Set DEVRESET=false invoked when device " "is on\n", __func__)); - bcmerror = BCME_SDIO_ERROR; + bcmerror = -EIO; } } return bcmerror; } + +static int +dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs) +{ + u32 regdata; + + /* + * Get CC core rev + * Chipid is assume to be at offset 0 from regs arg + * For different chiptypes or old sdio hosts w/o chipcommon, + * other ways of recognition should be added here. + */ + ci->cccorebase = (u32)regs; + regdata = bcmsdh_reg_read(sdh, CORE_CC_REG(ci->cccorebase, chipid), 4); + ci->chip = regdata & CID_ID_MASK; + ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; + + DHD_INFO(("%s: chipid=0x%x chiprev=%d\n", + __func__, ci->chip, ci->chiprev)); + + /* Address of cores for new chips should be added here */ + switch (ci->chip) { + case BCM4329_CHIP_ID: + ci->buscorebase = BCM4329_CORE_BUS_BASE; + ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE; + ci->armcorebase = BCM4329_CORE_ARM_BASE; + ci->ramsize = BCM4329_RAMSIZE; + break; + default: + DHD_ERROR(("%s: chipid 0x%x is not supported\n", + __func__, ci->chip)); + return -ENODEV; + } + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(ci->cccorebase, sbidhigh), 4); + ci->ccrev = SBCOREREV(regdata); + + regdata = bcmsdh_reg_read(sdh, + CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); + ci->pmurev = regdata & PCAP_REV_MASK; + + regdata = bcmsdh_reg_read(sdh, CORE_SB(ci->buscorebase, sbidhigh), 4); + ci->buscorerev = SBCOREREV(regdata); + ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; + + DHD_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", + __func__, ci->ccrev, ci->pmurev, + ci->buscorerev, ci->buscoretype)); + + /* get chipcommon capabilites */ + ci->cccaps = bcmsdh_reg_read(sdh, + CORE_CC_REG(ci->cccorebase, capabilities), 4); + + return 0; +} + +static void +dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase) +{ + u32 regdata; + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatelow), 4); + if (regdata & SBTML_RESET) + return; + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatelow), 4); + if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) { + /* + * set target reject and spin until busy is clear + * (preserve core-specific bits) + */ + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatelow), 4); + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + regdata | SBTML_REJ); + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatelow), 4); + udelay(1); + SPINWAIT((bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatehigh), 4) & + SBTMH_BUSY), 100000); + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatehigh), 4); + if (regdata & SBTMH_BUSY) + DHD_ERROR(("%s: ARM core still busy\n", __func__)); + + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbidlow), 4); + if (regdata & SBIDL_INIT) { + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbimstate), 4) | + SBIM_RJ; + bcmsdh_reg_write(sdh, + CORE_SB(corebase, sbimstate), 4, + regdata); + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbimstate), 4); + udelay(1); + SPINWAIT((bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbimstate), 4) & + SBIM_BY), 100000); + } + + /* set reset and reject while enabling the clocks */ + bcmsdh_reg_write(sdh, + CORE_SB(corebase, sbtmstatelow), 4, + (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | + SBTML_REJ | SBTML_RESET)); + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbtmstatelow), 4); + udelay(10); + + /* clear the initiator reject bit */ + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbidlow), 4); + if (regdata & SBIDL_INIT) { + regdata = bcmsdh_reg_read(sdh, + CORE_SB(corebase, sbimstate), 4) & + ~SBIM_RJ; + bcmsdh_reg_write(sdh, + CORE_SB(corebase, sbimstate), 4, + regdata); + } + } + + /* leave reset and reject asserted */ + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + (SBTML_REJ | SBTML_RESET)); + udelay(1); +} + +static int +dhdsdio_chip_attach(struct dhd_bus *bus, void *regs) +{ + struct chip_info *ci; + int err; + u8 clkval, clkset; + + DHD_TRACE(("%s: Enter\n", __func__)); + + /* alloc chip_info_t */ + ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC); + if (NULL == ci) { + DHD_ERROR(("%s: malloc failed!\n", __func__)); + return -ENOMEM; + } + + memset((unsigned char *)ci, 0, sizeof(struct chip_info)); + + /* bus/core/clk setup for register access */ + /* Try forcing SDIO core to do ALPAvail request only */ + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + clkset, &err); + if (err) { + DHD_ERROR(("%s: error writing for HT off\n", __func__)); + goto fail; + } + + /* If register supported, wait for ALPAvail and then force ALP */ + /* This may take up to 15 milliseconds */ + clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, NULL); + if ((clkval & ~SBSDIO_AVBITS) == clkset) { + SPINWAIT(((clkval = + bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + NULL)), + !SBSDIO_ALPAV(clkval)), + PMU_MAX_TRANSITION_DLY); + if (!SBSDIO_ALPAV(clkval)) { + DHD_ERROR(("%s: timeout on ALPAV wait, clkval 0x%02x\n", + __func__, clkval)); + err = -EBUSY; + goto fail; + } + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | + SBSDIO_FORCE_ALP; + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + clkset, &err); + udelay(65); + } else { + DHD_ERROR(("%s: ChipClkCSR access: wrote 0x%02x read 0x%02x\n", + __func__, clkset, clkval)); + err = -EACCES; + goto fail; + } + + /* Also, disable the extra SDIO pull-ups */ + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, + NULL); + + err = dhdsdio_chip_recognition(bus->sdh, ci, regs); + if (err) + goto fail; + + /* + * Make sure any on-chip ARM is off (in case strapping is wrong), + * or downloaded code was already running. + */ + dhdsdio_chip_disablecore(bus->sdh, ci->armcorebase); + + bcmsdh_reg_write(bus->sdh, + CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); + bcmsdh_reg_write(bus->sdh, + CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); + + /* Disable F2 to clear any intermediate frame state on the dongle */ + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, + SDIO_FUNC_ENABLE_1, NULL); + + /* WAR: cmd52 backplane read so core HW will drop ALPReq */ + clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + 0, NULL); + + /* Done with backplane-dependent accesses, can drop clock... */ + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, + NULL); + + bus->ci = ci; + return 0; +fail: + bus->ci = NULL; + kfree(ci); + return err; +} + +static void +dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase) +{ + u32 regdata; + + /* + * Must do the disable sequence first to work for + * arbitrary current core state. + */ + dhdsdio_chip_disablecore(sdh, corebase); + + /* + * Now do the initialization sequence. + * set reset while enabling the clock and + * forcing them on throughout the core + */ + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | + SBTML_RESET); + udelay(1); + + regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbtmstatehigh), 4); + if (regdata & SBTMH_SERR) + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatehigh), 4, 0); + + regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbimstate), 4); + if (regdata & (SBIM_IBE | SBIM_TO)) + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbimstate), 4, + regdata & ~(SBIM_IBE | SBIM_TO)); + + /* clear reset and allow it to propagate throughout the core */ + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + (SICF_FGC << SBTML_SICF_SHIFT) | + (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); + udelay(1); + + /* leave clock enabled */ + bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); + udelay(1); +} + +/* SDIO Pad drive strength to select value mappings */ +struct sdiod_drive_str { + u8 strength; /* Pad Drive Strength in mA */ + u8 sel; /* Chip-specific select value */ +}; + +/* SDIO Drive Strength to sel value table for PMU Rev 1 */ +static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = { + { + 4, 0x2}, { + 2, 0x3}, { + 1, 0x0}, { + 0, 0x0} + }; + +/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ +static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = { + { + 12, 0x7}, { + 10, 0x6}, { + 8, 0x5}, { + 6, 0x4}, { + 4, 0x2}, { + 2, 0x1}, { + 0, 0x0} + }; + +/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ +static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { + { + 32, 0x7}, { + 26, 0x6}, { + 22, 0x5}, { + 16, 0x4}, { + 12, 0x3}, { + 8, 0x2}, { + 4, 0x1}, { + 0, 0x0} + }; + +#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) + +static void +dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) { + struct sdiod_drive_str *str_tab = NULL; + u32 str_mask = 0; + u32 str_shift = 0; + char chn[8]; + + if (!(bus->ci->cccaps & CC_CAP_PMU)) + return; + + switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) { + case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): + str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1; + str_mask = 0x30000000; + str_shift = 28; + break; + case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): + case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): + str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2; + str_mask = 0x00003800; + str_shift = 11; + break; + case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): + str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3; + str_mask = 0x00003800; + str_shift = 11; + break; + default: + DHD_ERROR(("No SDIO Drive strength init" + "done for chip %s rev %d pmurev %d\n", + bcm_chipname(bus->ci->chip, chn, 8), + bus->ci->chiprev, bus->ci->pmurev)); + break; + } + + if (str_tab != NULL) { + u32 drivestrength_sel = 0; + u32 cc_data_temp; + int i; + + for (i = 0; str_tab[i].strength != 0; i++) { + if (drivestrength >= str_tab[i].strength) { + drivestrength_sel = str_tab[i].sel; + break; + } + } + + bcmsdh_reg_write(bus->sdh, + CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), + 4, 1); + cc_data_temp = bcmsdh_reg_read(bus->sdh, + CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4); + cc_data_temp &= ~str_mask; + drivestrength_sel <<= str_shift; + cc_data_temp |= drivestrength_sel; + bcmsdh_reg_write(bus->sdh, + CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), + 4, cc_data_temp); + + DHD_INFO(("SDIO: %dmA drive strength selected, set to 0x%08x\n", + drivestrength, cc_data_temp)); + } +} + +static void +dhdsdio_chip_detach(struct dhd_bus *bus) +{ + DHD_TRACE(("%s: Enter\n", __func__)); + + kfree(bus->ci); + bus->ci = NULL; +} diff --git a/drivers/staging/brcm80211/brcmfmac/hndpmu.c b/drivers/staging/brcm80211/brcmfmac/hndpmu.c deleted file mode 100644 index e841da6fb03d..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/hndpmu.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/hndpmu.c" diff --git a/drivers/staging/brcm80211/brcmfmac/sbutils.c b/drivers/staging/brcm80211/brcmfmac/sbutils.c deleted file mode 100644 index 64496b8ca2cd..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/sbutils.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/sbutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/siutils.c b/drivers/staging/brcm80211/brcmfmac/siutils.c deleted file mode 100644 index f428e992a11f..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/siutils.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/siutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 555b056b49b1..e3b409bb9847 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -39,11 +39,13 @@ #include <linux/firmware.h> #include <wl_cfg80211.h> +void sdioh_sdio_set_host_pm_flags(int flag); + static struct sdio_func *cfg80211_sdio_func; static struct wl_dev *wl_cfg80211_dev; static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; -u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO; +u32 wl_dbg_level = WL_DBG_ERR; #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin" #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt" @@ -180,41 +182,34 @@ static void wl_init_prof(struct wl_profile *prof); ** cfg80211 connect utilites */ static s32 wl_set_wpa_version(struct net_device *dev, - struct cfg80211_connect_params *sme); + struct cfg80211_connect_params *sme); static s32 wl_set_auth_type(struct net_device *dev, - struct cfg80211_connect_params *sme); + struct cfg80211_connect_params *sme); static s32 wl_set_set_cipher(struct net_device *dev, - struct cfg80211_connect_params *sme); + struct cfg80211_connect_params *sme); static s32 wl_set_key_mgmt(struct net_device *dev, - struct cfg80211_connect_params *sme); + struct cfg80211_connect_params *sme); static s32 wl_set_set_sharedkey(struct net_device *dev, - struct cfg80211_connect_params *sme); + struct cfg80211_connect_params *sme); static s32 wl_get_assoc_ies(struct wl_priv *wl); +static void wl_clear_assoc_ies(struct wl_priv *wl); static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, size_t *join_params_size); /* ** information element utilities */ -static void wl_rst_ie(struct wl_priv *wl); static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v); -static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size); -static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size); -static u32 wl_get_ielen(struct wl_priv *wl); - static s32 wl_mode_to_nl80211_iftype(s32 mode); - static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, - struct device *dev); + struct device *dev); static void wl_free_wdev(struct wl_priv *wl); - static s32 wl_inform_bss(struct wl_priv *wl); static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi); static s32 wl_update_bss_info(struct wl_priv *wl); - static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, - struct key_params *params); + u8 key_idx, const u8 *mac_addr, + struct key_params *params); /* ** key indianess swap utilities @@ -240,7 +235,6 @@ static void *wl_get_drvdata(struct wl_dev *dev); ** ibss mode utilities */ static bool wl_is_ibssmode(struct wl_priv *wl); -static bool wl_is_ibssstarter(struct wl_priv *wl); /* ** dongle up/down , default configuration utilities @@ -248,7 +242,6 @@ static bool wl_is_ibssstarter(struct wl_priv *wl); static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e); static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e); -static void wl_link_up(struct wl_priv *wl); static void wl_link_down(struct wl_priv *wl); static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype); static s32 __wl_cfg80211_up(struct wl_priv *wl); @@ -266,18 +259,19 @@ static s32 wl_dongle_up(struct net_device *ndev, u32 up); static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode); static s32 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align); -static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar, - u32 bcn_timeout); -static s32 wl_dongle_eventmsg(struct net_device *ndev); -static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, - s32 scan_unassoc_time); static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol); static s32 wl_pattern_atoh(s8 *src, s8 *dst); static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode); static s32 wl_update_wiphybands(struct wl_priv *wl); #endif /* !EMBEDDED_PLATFORM */ + +static s32 wl_dongle_eventmsg(struct net_device *ndev); +static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, + s32 scan_unassoc_time, s32 scan_passive_time); static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock); +static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar, + u32 bcn_timeout); /* ** iscan handler @@ -352,30 +346,6 @@ do { \ } while (0) extern int dhd_wait_pend8021x(struct net_device *dev); - -#if (WL_DBG_LEVEL > 0) -#define WL_DBG_ESTR_MAX 32 -static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = { - "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND", - "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC", - "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END", - "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM", - "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH", - "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND", - "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND", - "PFN_NET_LOST", - "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START", - "IBSS_ASSOC", - "RADIO", "PSM_WATCHDOG", - "PROBREQ_MSG", - "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED", - "EXCEEDED_MEDIUM_TIME", "ICV_ERROR", - "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE", - "IF", - "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE", -}; -#endif /* WL_DBG_LEVEL */ - #define CHAN2G(_channel, _freq, _flags) { \ .band = IEEE80211_BAND_2GHZ, \ .center_freq = (_freq), \ @@ -604,10 +574,11 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, struct wl_priv *wl = wiphy_to_wl(wiphy); struct wireless_dev *wdev; s32 infra = 0; - s32 ap = 0; s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + switch (type) { case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_WDS: @@ -616,32 +587,34 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, return -EOPNOTSUPP; case NL80211_IFTYPE_ADHOC: wl->conf->mode = WL_MODE_IBSS; + infra = 0; break; case NL80211_IFTYPE_STATION: wl->conf->mode = WL_MODE_BSS; infra = 1; break; default: - return -EINVAL; + err = -EINVAL; + goto done; } + infra = cpu_to_le32(infra); - ap = cpu_to_le32(ap); - wdev = ndev->ieee80211_ptr; - wdev->iftype = type; - WL_DBG("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra); err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); - return err; - } - err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)); - if (unlikely(err)) { - WL_ERR("WLC_SET_AP error (%d)\n", err); - return err; + err = -EAGAIN; + } else { + wdev = ndev->ieee80211_ptr; + wdev->iftype = type; } - /* -EINPROGRESS: Call commit handler */ - return -EINPROGRESS; + WL_INFO("IF Type = %s\n", + (wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra"); + +done: + WL_TRACE("Exit\n"); + + return err; } static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) @@ -740,7 +713,7 @@ static s32 wl_do_iscan(struct wl_priv *wl) err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); if (unlikely(err)) { - WL_DBG("error (%d)\n", err); + WL_ERR("error (%d)\n", err); return err; } wl_set_mpc(ndev, 0); @@ -774,26 +747,25 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, (int)wl->status); return -EAGAIN; } + if (test_bit(WL_STATUS_CONNECTING, &wl->status)) { + WL_ERR("Connecting : status (%d)\n", + (int)wl->status); + return -EAGAIN; + } iscan_req = false; spec_scan = false; - if (request) { /* scan bss */ + if (request) { + /* scan bss */ ssids = request->ssids; - if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for - * specific scan, - * ssids->ssid_len has - * non-zero(ssid string) - * length. - * Otherwise this is 0. - * we do not iscan for - * specific scan request - */ + if (wl->iscan_on && (!ssids || !ssids->ssid_len)) iscan_req = true; - } - } else { /* scan in ibss */ + } else { + /* scan in ibss */ /* we don't do iscan in ibss */ ssids = this_ssid; } + wl->scan_request = request; set_bit(WL_STATUS_SCANNING, &wl->status); if (iscan_req) { @@ -803,7 +775,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, else goto scan_out; } else { - WL_DBG("ssid \"%s\", ssid_len (%d)\n", + WL_SCAN("ssid \"%s\", ssid_len (%d)\n", ssids->ssid, ssids->ssid_len); memset(&sr->ssid, 0, sizeof(sr->ssid)); sr->ssid.SSID_len = @@ -811,13 +783,11 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if (sr->ssid.SSID_len) { memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len); - WL_DBG("Specific scan ssid=\"%s\" len=%d\n", - sr->ssid.SSID, sr->ssid.SSID_len); spec_scan = true; } else { - WL_DBG("Broadcast scan\n"); + WL_SCAN("Broadcast scan\n"); } - WL_DBG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len); + passive_scan = wl->active_scan ? 0 : 1; err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); @@ -854,13 +824,15 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, { s32 err = 0; + WL_TRACE("Enter\n"); + CHECK_SYS_UP(); + err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); - if (unlikely(err)) { - WL_DBG("scan error (%d)\n", err); - return err; - } + if (unlikely(err)) + WL_ERR("scan error (%d)\n", err); + WL_TRACE("Exit\n"); return err; } @@ -875,9 +847,8 @@ static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) BUG_ON(!len); err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("error (%d)\n", err); - } return err; } @@ -898,9 +869,9 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) sizeof(var.buf)); BUG_ON(!len); err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("error (%d)\n", err); - } + *retval = le32_to_cpu(var.val); return err; @@ -911,10 +882,9 @@ static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold) s32 err = 0; err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("Error (%d)\n", err); - return err; - } + return err; } @@ -923,10 +893,9 @@ static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold) s32 err = 0; err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("Error (%d)\n", err); - return err; - } + return err; } @@ -950,37 +919,40 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) struct net_device *ndev = wl_to_ndev(wl); s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + if (changed & WIPHY_PARAM_RTS_THRESHOLD && (wl->conf->rts_threshold != wiphy->rts_threshold)) { wl->conf->rts_threshold = wiphy->rts_threshold; err = wl_set_rts(ndev, wl->conf->rts_threshold); if (!err) - return err; + goto done; } if (changed & WIPHY_PARAM_FRAG_THRESHOLD && (wl->conf->frag_threshold != wiphy->frag_threshold)) { wl->conf->frag_threshold = wiphy->frag_threshold; err = wl_set_frag(ndev, wl->conf->frag_threshold); if (!err) - return err; + goto done; } if (changed & WIPHY_PARAM_RETRY_LONG && (wl->conf->retry_long != wiphy->retry_long)) { wl->conf->retry_long = wiphy->retry_long; err = wl_set_retry(ndev, wl->conf->retry_long, true); if (!err) - return err; + goto done; } if (changed & WIPHY_PARAM_RETRY_SHORT && (wl->conf->retry_short != wiphy->retry_short)) { wl->conf->retry_short = wiphy->retry_short; err = wl_set_retry(ndev, wl->conf->retry_short, false); - if (!err) { - return err; - } + if (!err) + goto done; } +done: + WL_TRACE("Exit\n"); return err; } @@ -989,68 +961,139 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { struct wl_priv *wl = wiphy_to_wl(wiphy); - struct cfg80211_bss *bss; - struct ieee80211_channel *chan; struct wl_join_params join_params; - struct cfg80211_ssid ssid; - s32 scan_retry = 0; + size_t join_params_size = 0; s32 err = 0; + s32 wsec = 0; + s32 bcnprd; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); - if (params->bssid) { - WL_ERR("Invalid bssid\n"); + + if (params->ssid) + WL_CONN("SSID: %s\n", params->ssid); + else { + WL_CONN("SSID: NULL, Not supported\n"); return -EOPNOTSUPP; } - bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); - if (!bss) { - memcpy(ssid.ssid, params->ssid, params->ssid_len); - ssid.ssid_len = params->ssid_len; - do { - if (unlikely - (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == - -EBUSY)) { - wl_delay(150); - } else { - break; - } - } while (++scan_retry < WL_SCAN_RETRY_MAX); - rtnl_unlock(); /* to allow scan_inform to paropagate - to cfg80211 plane */ - schedule_timeout_interruptible(4 * HZ); /* wait 4 secons - till scan done.... */ - rtnl_lock(); - bss = cfg80211_get_ibss(wiphy, NULL, - params->ssid, params->ssid_len); + + if (params->bssid) + WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n", + params->bssid[0], params->bssid[1], params->bssid[2], + params->bssid[3], params->bssid[4], params->bssid[5]); + else + WL_CONN("No BSSID specified\n"); + + if (params->channel) + WL_CONN("channel: %d\n", params->channel->center_freq); + else + WL_CONN("no channel specified\n"); + + if (params->channel_fixed) + WL_CONN("fixed channel required\n"); + else + WL_CONN("no fixed channel required\n"); + + if (params->ie && params->ie_len) + WL_CONN("ie len: %d\n", params->ie_len); + else + WL_CONN("no ie specified\n"); + + if (params->beacon_interval) + WL_CONN("beacon interval: %d\n", params->beacon_interval); + else + WL_CONN("no beacon interval specified\n"); + + if (params->basic_rates) + WL_CONN("basic rates: %08X\n", params->basic_rates); + else + WL_CONN("no basic rates specified\n"); + + if (params->privacy) + WL_CONN("privacy required\n"); + else + WL_CONN("no privacy required\n"); + + /* Configure Privacy for starter */ + if (params->privacy) + wsec |= WEP_ENABLED; + + err = wl_dev_intvar_set(dev, "wsec", wsec); + if (unlikely(err)) { + WL_ERR("wsec failed (%d)\n", err); + goto done; + } + + /* Configure Beacon Interval for starter */ + if (params->beacon_interval) + bcnprd = cpu_to_le32(params->beacon_interval); + else + bcnprd = cpu_to_le32(100); + + err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd)); + if (unlikely(err)) { + WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); + goto done; } - if (bss) { - wl->ibss_starter = false; - WL_DBG("Found IBSS\n"); + + /* Configure required join parameter */ + memset(&join_params, 0, sizeof(wl_join_params_t)); + + /* SSID */ + join_params.ssid.SSID_len = + (params->ssid_len > 32) ? 32 : params->ssid_len; + memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len); + join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); + join_params_size = sizeof(join_params.ssid); + wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); + + /* BSSID */ + if (params->bssid) { + memcpy(join_params.params.bssid, params->bssid, ETH_ALEN); + join_params_size = + sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE; } else { - wl->ibss_starter = true; + memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); } - chan = params->channel; - if (chan) - wl->channel = ieee80211_frequency_to_channel(chan->center_freq); - /* - ** Join with specific BSSID and cached SSID - ** If SSID is zero join based on BSSID only - */ - memset(&join_params, 0, sizeof(join_params)); - memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, - params->ssid_len); - join_params.ssid.SSID_len = cpu_to_le32(params->ssid_len); - if (params->bssid) - memcpy(&join_params.params.bssid, params->bssid, - ETH_ALEN); - else - memset(&join_params.params.bssid, 0, ETH_ALEN); + wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID); - err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, - sizeof(join_params)); + /* Channel */ + if (params->channel) { + u32 target_channel; + + wl->channel = + ieee80211_frequency_to_channel( + params->channel->center_freq); + if (params->channel_fixed) { + /* adding chanspec */ + wl_ch_to_chanspec(wl->channel, + &join_params, &join_params_size); + } + + /* set channel for starter */ + target_channel = cpu_to_le32(wl->channel); + err = wl_dev_ioctl(dev, WLC_SET_CHANNEL, + &target_channel, sizeof(target_channel)); + if (unlikely(err)) { + WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); + goto done; + } + } else + wl->channel = 0; + + wl->ibss_starter = false; + + + err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); if (unlikely(err)) { - WL_ERR("Error (%d)\n", err); - return err; + WL_ERR("WLC_SET_SSID failed (%d)\n", err); + goto done; } + + set_bit(WL_STATUS_CONNECTING, &wl->status); + +done: + WL_TRACE("Exit\n"); return err; } @@ -1059,9 +1102,13 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) struct wl_priv *wl = wiphy_to_wl(wiphy); s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + wl_link_down(wl); + WL_TRACE("Exit\n"); + return err; } @@ -1079,7 +1126,7 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; else val = WPA_AUTH_DISABLED; - WL_DBG("setting wpa_auth to 0x%0x\n", val); + WL_CONN("setting wpa_auth to 0x%0x\n", val); err = wl_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { WL_ERR("set wpa_auth failed (%d)\n", err); @@ -1101,18 +1148,18 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: val = 0; - WL_DBG("open system\n"); + WL_CONN("open system\n"); break; case NL80211_AUTHTYPE_SHARED_KEY: val = 1; - WL_DBG("shared key\n"); + WL_CONN("shared key\n"); break; case NL80211_AUTHTYPE_AUTOMATIC: val = 2; - WL_DBG("automatic\n"); + WL_CONN("automatic\n"); break; case NL80211_AUTHTYPE_NETWORK_EAP: - WL_DBG("network eap\n"); + WL_CONN("network eap\n"); default: val = 2; WL_ERR("invalid auth type (%d)\n", sme->auth_type); @@ -1181,7 +1228,7 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) } } - WL_DBG("pval (%d) gval (%d)\n", pval, gval); + WL_CONN("pval (%d) gval (%d)\n", pval, gval); err = wl_dev_intvar_set(dev, "wsec", pval | gval); if (unlikely(err)) { WL_ERR("error (%d)\n", err); @@ -1237,7 +1284,7 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) } } - WL_DBG("setting wpa_auth to %d\n", val); + WL_CONN("setting wpa_auth to %d\n", val); err = wl_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { WL_ERR("could not set wpa_auth (%d)\n", err); @@ -1260,10 +1307,10 @@ wl_set_set_sharedkey(struct net_device *dev, s32 val; s32 err = 0; - WL_DBG("key len (%d)\n", sme->key_len); + WL_CONN("key len (%d)\n", sme->key_len); if (sme->key_len) { sec = wl_read_prof(wl, WL_PROF_SEC); - WL_DBG("wpa_versions 0x%x cipher_pairwise 0x%x\n", + WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions, sec->cipher_pairwise); if (! (sec->wpa_versions & (NL80211_WPA_VERSION_1 | @@ -1292,9 +1339,9 @@ wl_set_set_sharedkey(struct net_device *dev, return -EINVAL; } /* Set the new key/index */ - WL_DBG("key length (%d) key index (%d) algo (%d)\n", + WL_CONN("key length (%d) key index (%d) algo (%d)\n", key.len, key.index, key.algo); - WL_DBG("key \"%s\"\n", key.data); + WL_CONN("key \"%s\"\n", key.data); swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); @@ -1303,7 +1350,7 @@ wl_set_set_sharedkey(struct net_device *dev, return err; } if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { - WL_DBG("set auth_type to shared key\n"); + WL_CONN("set auth_type to shared key\n"); val = 1; /* shared key */ err = wl_dev_intvar_set(dev, "auth", val); if (unlikely(err)) { @@ -1327,17 +1374,24 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + if (unlikely(!sme->ssid)) { WL_ERR("Invalid ssid\n"); return -EOPNOTSUPP; } + if (chan) { - wl->channel = ieee80211_frequency_to_channel(chan->center_freq); - WL_DBG("channel (%d), center_req (%d)\n", - wl->channel, chan->center_freq); - } - WL_DBG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); + wl->channel = + ieee80211_frequency_to_channel(chan->center_freq); + WL_CONN("channel (%d), center_req (%d)\n", + wl->channel, chan->center_freq); + } else + wl->channel = 0; + + WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); + err = wl_set_wpa_version(dev, sme); if (unlikely(err)) return err; @@ -1370,15 +1424,18 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); - memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); - wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - WL_DBG("join_param_size %zu\n", join_params_size); + if (sme->bssid) + memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN); + else + memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { - WL_DBG("ssid \"%s\", len (%d)\n", + WL_CONN("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, join_params.ssid.SSID_len); } + + wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); if (unlikely(err)) { WL_ERR("error (%d)\n", err); @@ -1386,6 +1443,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } set_bit(WL_STATUS_CONNECTING, &wl->status); + WL_TRACE("Exit\n"); return err; } @@ -1395,24 +1453,24 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, { struct wl_priv *wl = wiphy_to_wl(wiphy); scb_val_t scbval; - bool act = false; s32 err = 0; - WL_DBG("Reason %d\n", reason_code); + WL_TRACE("Enter. Reason code = %d\n", reason_code); CHECK_SYS_UP(); - act = *(bool *) wl_read_prof(wl, WL_PROF_ACT); - if (likely(act)) { - scbval.val = reason_code; - memcpy(&scbval.ea, &wl->bssid, ETH_ALEN); - scbval.val = cpu_to_le32(scbval.val); - err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); - if (unlikely(err)) { - WL_ERR("error (%d)\n", err); - return err; - } - } + clear_bit(WL_STATUS_CONNECTED, &wl->status); + + scbval.val = reason_code; + memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN); + scbval.val = cpu_to_le32(scbval.val); + err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, + sizeof(scb_val_t)); + if (unlikely(err)) + WL_ERR("error (%d)\n", err); + + wl->link_up = false; + + WL_TRACE("Exit\n"); return err; } @@ -1427,20 +1485,24 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, s32 err = 0; s32 disable = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + switch (type) { case NL80211_TX_POWER_AUTOMATIC: break; case NL80211_TX_POWER_LIMITED: if (dbm < 0) { WL_ERR("TX_POWER_LIMITED - dbm is negative\n"); - return -EINVAL; + err = -EINVAL; + goto done; } break; case NL80211_TX_POWER_FIXED: if (dbm < 0) { WL_ERR("TX_POWER_FIXED - dbm is negative\n"); - return -EINVAL; + err = -EINVAL; + goto done; } break; } @@ -1448,10 +1510,8 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, disable = WL_RADIO_SW_DISABLE << 16; disable = cpu_to_le32(disable); err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable)); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("WLC_SET_RADIO error (%d)\n", err); - return err; - } if (dbm > 0xffff) txpwrmw = 0xffff; @@ -1459,12 +1519,12 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, txpwrmw = (u16) dbm; err = wl_dev_intvar_set(ndev, "qtxpower", (s32) (bcm_mw_to_qdbm(txpwrmw))); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("qtxpower error (%d)\n", err); - return err; - } wl->conf->tx_power = dbm; +done: + WL_TRACE("Exit\n"); return err; } @@ -1476,15 +1536,20 @@ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) u8 result; s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); if (unlikely(err)) { WL_ERR("error (%d)\n", err); - return err; + goto done; } + result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); *dbm = (s32) bcm_qdbm_to_mw(result); +done: + WL_TRACE("Exit\n"); return err; } @@ -1496,14 +1561,16 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, s32 wsec; s32 err = 0; - WL_DBG("key index (%d)\n", key_idx); + WL_TRACE("Enter\n"); + WL_CONN("key index (%d)\n", key_idx); CHECK_SYS_UP(); err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); - return err; + goto done; } + wsec = le32_to_cpu(wsec); if (wsec & WEP_ENABLED) { /* Just select a new current key */ @@ -1511,10 +1578,11 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, index = cpu_to_le32(index); err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index)); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("error (%d)\n", err); - } } +done: + WL_TRACE("Exit\n"); return err; } @@ -1547,7 +1615,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; } - WL_DBG("Setting the key index %d\n", key.index); + WL_CONN("Setting the key index %d\n", key.index); memcpy(key.data, params->key, key.len); if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { @@ -1571,23 +1639,23 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; - WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; - WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); break; case WLAN_CIPHER_SUITE_TKIP: key.algo = CRYPTO_ALGO_TKIP; - WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); + WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); + WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; case WLAN_CIPHER_SUITE_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG("WLAN_CIPHER_SUITE_CCMP\n"); + WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); break; default: WL_ERR("Invalid cipher (0x%x)\n", params->cipher); @@ -1614,12 +1682,16 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, s32 val; s32 wsec; s32 err = 0; + u8 keybuf[8]; - WL_DBG("key index (%d)\n", key_idx); + WL_TRACE("Enter\n"); + WL_CONN("key index (%d)\n", key_idx); CHECK_SYS_UP(); - if (mac_addr) + if (mac_addr) { + WL_TRACE("Exit"); return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); + } memset(&key, 0, sizeof(key)); key.len = (u32) params->key_len; @@ -1627,7 +1699,8 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (unlikely(key.len > sizeof(key.data))) { WL_ERR("Too long key length (%u)\n", key.len); - return -EINVAL; + err = -EINVAL; + goto done; } memcpy(key.data, params->key, key.len); @@ -1635,27 +1708,31 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; - WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; - WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); break; case WLAN_CIPHER_SUITE_TKIP: + memcpy(keybuf, &key.data[24], sizeof(keybuf)); + memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); + memcpy(&key.data[16], keybuf, sizeof(keybuf)); key.algo = CRYPTO_ALGO_TKIP; - WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); + WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); + WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; case WLAN_CIPHER_SUITE_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG("WLAN_CIPHER_SUITE_CCMP\n"); + WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); break; default: WL_ERR("Invalid cipher (0x%x)\n", params->cipher); - return -EINVAL; + err = -EINVAL; + goto done; } /* Set the new key/index */ @@ -1663,30 +1740,30 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("WLC_SET_KEY error (%d)\n", err); - return err; + goto done; } val = WEP_ENABLED; err = wl_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { WL_ERR("get wsec error (%d)\n", err); - return err; + goto done; } wsec &= ~(WEP_ENABLED); wsec |= val; err = wl_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { WL_ERR("set wsec error (%d)\n", err); - return err; + goto done; } val = 1; /* assume shared key. otherwise 0 */ val = cpu_to_le32(val); err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("WLC_SET_AUTH error (%d)\n", err); - return err; - } +done: + WL_TRACE("Exit\n"); return err; } @@ -1699,6 +1776,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, s32 val; s32 wsec; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); memset(&key, 0, sizeof(key)); @@ -1706,34 +1784,39 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, key.flags = WL_PRIMARY_KEY; key.algo = CRYPTO_ALGO_OFF; - WL_DBG("key index (%d)\n", key_idx); + WL_CONN("key index (%d)\n", key_idx); /* Set the new key/index */ swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { if (err == -EINVAL) { - if (key.index >= DOT11_MAX_DEFAULT_KEYS) { + if (key.index >= DOT11_MAX_DEFAULT_KEYS) /* we ignore this key index in this case */ - WL_DBG("invalid key index (%d)\n", key_idx); - } - } else { + WL_ERR("invalid key index (%d)\n", key_idx); + } else WL_ERR("WLC_SET_KEY error (%d)\n", err); - } - return err; + + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; } val = 0; err = wl_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { WL_ERR("get wsec error (%d)\n", err); - return err; + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; } wsec &= ~(WEP_ENABLED); wsec |= val; err = wl_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { WL_ERR("set wsec error (%d)\n", err); - return err; + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; } val = 0; /* assume open key. otherwise 1 */ @@ -1741,8 +1824,11 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { WL_ERR("WLC_SET_AUTH error (%d)\n", err); - return err; + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; } +done: + WL_TRACE("Exit\n"); return err; } @@ -1758,7 +1844,8 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, s32 wsec; s32 err = 0; - WL_DBG("key index (%d)\n", key_idx); + WL_TRACE("Enter\n"); + WL_CONN("key index (%d)\n", key_idx); CHECK_SYS_UP(); memset(&key, 0, sizeof(key)); @@ -1771,7 +1858,9 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); - return err; + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; } wsec = le32_to_cpu(wsec); switch (wsec) { @@ -1779,26 +1868,29 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, sec = wl_read_prof(wl, WL_PROF_SEC); if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { params.cipher = WLAN_CIPHER_SUITE_WEP40; - WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) { params.cipher = WLAN_CIPHER_SUITE_WEP104; - WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); + WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); } break; case TKIP_ENABLED: params.cipher = WLAN_CIPHER_SUITE_TKIP; - WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); + WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); break; case AES_ENABLED: params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; - WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); + WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; default: WL_ERR("Invalid algo (0x%x)\n", wsec); - return -EINVAL; + err = -EINVAL; + goto done; } - callback(cookie, ¶ms); + +done: + WL_TRACE("Exit\n"); return err; } @@ -1807,6 +1899,7 @@ wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { WL_INFO("Not supported\n"); + CHECK_SYS_UP(); return -EOPNOTSUPP; } @@ -1820,12 +1913,20 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, int rssi; s32 rate; s32 err = 0; + u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID); + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + if (unlikely - (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN))) { - WL_ERR("Wrong Mac address\n"); - return -ENOENT; + (memcmp(mac, bssid, ETH_ALEN))) { + WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X" + "wl_bssid-%X:%X:%X:%X:%X:%X\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + bssid[0], bssid[1], bssid[2], bssid[3], + bssid[4], bssid[5]); + err = -ENOENT; + goto done; } /* Report the current tx rate */ @@ -1836,7 +1937,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, rate = le32_to_cpu(rate); sinfo->filled |= STATION_INFO_TX_BITRATE; sinfo->txrate.legacy = rate * 5; - WL_DBG("Rate %d Mbps\n", rate / 2); + WL_CONN("Rate %d Mbps\n", rate / 2); } if (test_bit(WL_STATUS_CONNECTED, &wl->status)) { @@ -1845,14 +1946,15 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, sizeof(scb_val_t)); if (unlikely(err)) { WL_ERR("Could not get rssi (%d)\n", err); - return err; } rssi = le32_to_cpu(scb_val.val); sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = rssi; - WL_DBG("RSSI %d dBm\n", rssi); + WL_CONN("RSSI %d dBm\n", rssi); } +done: + WL_TRACE("Exit\n"); return err; } @@ -1863,18 +1965,21 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, s32 pm; s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + pm = enabled ? PM_FAST : PM_OFF; pm = cpu_to_le32(pm); - WL_DBG("power save %s\n", (pm ? "enabled" : "disabled")); + WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); + err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); if (unlikely(err)) { if (err == -ENODEV) - WL_DBG("net_device is not ready yet\n"); + WL_ERR("net_device is not ready yet\n"); else WL_ERR("error (%d)\n", err); - return err; } + WL_TRACE("Exit\n"); return err; } @@ -1918,14 +2023,16 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, u32 legacy; s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + /* addr param is always NULL. ignore it */ /* Get current rateset */ err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)); if (unlikely(err)) { WL_ERR("could not get current rateset (%d)\n", err); - return err; + goto done; } rateset.count = le32_to_cpu(rateset.count); @@ -1936,15 +2043,14 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, val = wl_g_rates[legacy - 1].bitrate * 100000; - if (val < rateset.count) { + if (val < rateset.count) /* Select rate by rateset index */ rate = rateset.rates[val] & 0x7f; - } else { + else /* Specified rate in bps */ rate = val / 500000; - } - WL_DBG("rate %d mbps\n", rate / 2); + WL_CONN("rate %d mbps\n", rate / 2); /* * @@ -1955,40 +2061,105 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, err_a = wl_dev_intvar_set(dev, "a_rate", rate); if (unlikely(err_bg && err_a)) { WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); - return err_bg | err_a; + err = err_bg | err_a; } +done: + WL_TRACE("Exit\n"); return err; } static s32 wl_cfg80211_resume(struct wiphy *wiphy) { - s32 err = 0; + struct wl_priv *wl = wiphy_to_wl(wiphy); + struct net_device *ndev = wl_to_ndev(wl); - CHECK_SYS_UP(); - wl_invoke_iscan(wiphy_to_wl(wiphy)); + /* + * Check for WL_STATUS_READY before any function call which + * could result is bus access. Don't block the resume for + * any driver error conditions + */ + WL_TRACE("Enter\n"); - return err; +#if defined(CONFIG_PM_SLEEP) + atomic_set(&dhd_mmc_suspend, false); +#endif /* defined(CONFIG_PM_SLEEP) */ + + if (test_bit(WL_STATUS_READY, &wl->status)) { + /* Turn on Watchdog timer */ + wl_os_wd_timer(ndev, dhd_watchdog_ms); + wl_invoke_iscan(wiphy_to_wl(wiphy)); + } + + WL_TRACE("Exit\n"); + return 0; } static s32 wl_cfg80211_suspend(struct wiphy *wiphy) { struct wl_priv *wl = wiphy_to_wl(wiphy); struct net_device *ndev = wl_to_ndev(wl); - s32 err = 0; + + WL_TRACE("Enter\n"); + + /* + * Check for WL_STATUS_READY before any function call which + * could result is bus access. Don't block the suspend for + * any driver error conditions + */ + + /* + * While going to suspend if associated with AP disassociate + * from AP to save power while system is in suspended state + */ + if (test_bit(WL_STATUS_CONNECTED, &wl->status) && + test_bit(WL_STATUS_READY, &wl->status)) { + WL_INFO("Disassociating from AP" + " while entering suspend state\n"); + wl_link_down(wl); + + /* + * Make sure WPA_Supplicant receives all the event + * generated due to DISASSOC call to the fw to keep + * the state fw and WPA_Supplicant state consistent + */ + rtnl_unlock(); + wl_delay(500); + rtnl_lock(); + } set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); - wl_term_iscan(wl); + if (test_bit(WL_STATUS_READY, &wl->status)) + wl_term_iscan(wl); + if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, true); /* true means - abort */ - wl_set_mpc(ndev, 1); + /* Indidate scan abort to cfg80211 layer */ + WL_INFO("Terminating scan in progress\n"); + cfg80211_scan_done(wl->scan_request, true); wl->scan_request = NULL; } clear_bit(WL_STATUS_SCANNING, &wl->status); clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); + clear_bit(WL_STATUS_CONNECTING, &wl->status); + clear_bit(WL_STATUS_CONNECTED, &wl->status); - return err; + /* Inform SDIO stack not to switch off power to the chip */ + sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER); + + /* Turn off watchdog timer */ + if (test_bit(WL_STATUS_READY, &wl->status)) { + WL_INFO("Terminate watchdog timer and enable MPC\n"); + wl_set_mpc(ndev, 1); + wl_os_wd_timer(ndev, 0); + } + +#if defined(CONFIG_PM_SLEEP) + atomic_set(&dhd_mmc_suspend, true); +#endif /* defined(CONFIG_PM_SLEEP) */ + + WL_TRACE("Exit\n"); + + return 0; } static __used s32 @@ -1997,18 +2168,17 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, { int i, j; - WL_DBG("No of elements %d\n", pmk_list->pmkids.npmkid); + WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid); for (i = 0; i < pmk_list->pmkids.npmkid; i++) { - WL_DBG("PMKID[%d]: %pM =\n", i, + WL_CONN("PMKID[%d]: %pM =\n", i, &pmk_list->pmkids.pmkid[i].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) { - WL_DBG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]); - } + for (j = 0; j < WLAN_PMKID_LEN; j++) + WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]); } - if (likely(!err)) { - err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, + + if (likely(!err)) + wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, sizeof(*pmk_list)); - } return err; } @@ -2021,7 +2191,9 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, s32 err = 0; int i; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETH_ALEN)) @@ -2033,19 +2205,19 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, WLAN_PMKID_LEN); if (i == wl->pmk_list->pmkids.npmkid) wl->pmk_list->pmkids.npmkid++; - } else { + } else err = -EINVAL; - } - WL_DBG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", + + WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID); - for (i = 0; i < WLAN_PMKID_LEN; i++) { - WL_DBG("%02x\n", + for (i = 0; i < WLAN_PMKID_LEN; i++) + WL_CONN("%02x\n", wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid]. PMKID[i]); - } err = wl_update_pmklist(dev, wl->pmk_list, err); + WL_TRACE("Exit\n"); return err; } @@ -2058,15 +2230,15 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, s32 err = 0; int i; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); - WL_DBG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", + WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", &pmkid.pmkid[0].BSSID); - for (i = 0; i < WLAN_PMKID_LEN; i++) { - WL_DBG("%02x\n", pmkid.pmkid[0].PMKID[i]); - } + for (i = 0; i < WLAN_PMKID_LEN; i++) + WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]); for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) if (!memcmp @@ -2086,12 +2258,12 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, WLAN_PMKID_LEN); } wl->pmk_list->pmkids.npmkid--; - } else { + } else err = -EINVAL; - } err = wl_update_pmklist(dev, wl->pmk_list, err); + WL_TRACE("Exit\n"); return err; } @@ -2102,9 +2274,13 @@ wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) struct wl_priv *wl = wiphy_to_wl(wiphy); s32 err = 0; + WL_TRACE("Enter\n"); CHECK_SYS_UP(); + memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); err = wl_update_pmklist(dev, wl->pmk_list, err); + + WL_TRACE("Exit\n"); return err; } @@ -2235,7 +2411,7 @@ static s32 wl_inform_bss(struct wl_priv *wl) bss_list->version); return -EOPNOTSUPP; } - WL_DBG("scanned AP count (%d)\n", bss_list->count); + WL_SCAN("scanned AP count (%d)\n", bss_list->count); bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { err = wl_inform_single_bss(wl, bi); @@ -2245,89 +2421,137 @@ static s32 wl_inform_bss(struct wl_priv *wl) return err; } + static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) { struct wiphy *wiphy = wl_to_wiphy(wl); - struct ieee80211_mgmt *mgmt; - struct ieee80211_channel *channel; + struct ieee80211_channel *notify_channel; + struct cfg80211_bss *bss; struct ieee80211_supported_band *band; - struct wl_cfg80211_bss_info *notif_bss_info; - struct wl_scan_req *sr = wl_to_sr(wl); - struct beacon_proberesp *beacon_proberesp; - s32 mgmt_type; - u32 signal; - u32 freq; s32 err = 0; + u16 channel; + u32 freq; + u64 notify_timestamp; + u16 notify_capability; + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; + s32 notify_signal; if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) { - WL_DBG("Beacon is larger than buffer. Discarding\n"); - return err; - } - notif_bss_info = - kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) + - WL_BSS_INFO_MAX, GFP_KERNEL); - if (unlikely(!notif_bss_info)) { - WL_ERR("notif_bss_info alloc failed\n"); - return -ENOMEM; + WL_ERR("Bss info is larger than buffer. Discarding\n"); + return 0; } - mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf; - notif_bss_info->channel = - bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec); - if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) + channel = bi->ctl_ch ? bi->ctl_ch : + CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + + if (channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else band = wiphy->bands[IEEE80211_BAND_5GHZ]; - notif_bss_info->rssi = bi->RSSI; - memcpy(mgmt->bssid, &bi->BSSID, ETH_ALEN); - mgmt_type = wl->active_scan ? - IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON; - if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) { - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - mgmt_type); - } - beacon_proberesp = wl->active_scan ? - (struct beacon_proberesp *)&mgmt->u.probe_resp : - (struct beacon_proberesp *)&mgmt->u.beacon; - beacon_proberesp->timestamp = 0; - beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period); - beacon_proberesp->capab_info = cpu_to_le16(bi->capability); - wl_rst_ie(wl); - /* - * wl_add_ie is not necessary because it can only add duplicated - * SSID, rate information to frame_buf - */ - /* - * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID); - * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count, - * bi->rateset.rates); - */ - wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); - wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - - offsetof(struct wl_cfg80211_bss_info, frame_buf)); - notif_bss_info->frame_len = - offsetof(struct ieee80211_mgmt, - u.beacon.variable) + wl_get_ielen(wl); - freq = ieee80211_channel_to_frequency(notif_bss_info->channel, - band->band); - - channel = ieee80211_get_channel(wiphy, freq); - - WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", - bi->SSID, - notif_bss_info->rssi, notif_bss_info->channel, - mgmt->u.beacon.capab_info, &bi->BSSID); - - signal = notif_bss_info->rssi * 100; - if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt, - le16_to_cpu - (notif_bss_info->frame_len), - signal, GFP_KERNEL))) { + + freq = ieee80211_channel_to_frequency(channel, band->band); + notify_channel = ieee80211_get_channel(wiphy, freq); + + notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ + notify_capability = le16_to_cpu(bi->capability); + notify_interval = le16_to_cpu(bi->beacon_period); + notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); + notify_ielen = le16_to_cpu(bi->ie_length); + notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; + + WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + bi->BSSID[0], bi->BSSID[1], bi->BSSID[2], + bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]); + WL_CONN("Channel: %d(%d)\n", channel, freq); + WL_CONN("Capability: %X\n", notify_capability); + WL_CONN("Beacon interval: %d\n", notify_interval); + WL_CONN("Signal: %d\n", notify_signal); + WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); + + bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, + notify_timestamp, notify_capability, notify_interval, notify_ie, + notify_ielen, notify_signal, GFP_KERNEL); + + if (unlikely(!bss)) { WL_ERR("cfg80211_inform_bss_frame error\n"); - kfree(notif_bss_info); return -EINVAL; } - kfree(notif_bss_info); + + return err; +} + +static s32 +wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid) +{ + struct wiphy *wiphy = wl_to_wiphy(wl); + struct ieee80211_channel *notify_channel; + struct wl_bss_info *bi = NULL; + struct ieee80211_supported_band *band; + u8 *buf = NULL; + s32 err = 0; + u16 channel; + u32 freq; + u64 notify_timestamp; + u16 notify_capability; + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; + s32 notify_signal; + + WL_TRACE("Enter\n"); + + buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (buf == NULL) { + WL_ERR("kzalloc() failed\n"); + err = -ENOMEM; + goto CleanUp; + } + + *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); + + err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); + if (unlikely(err)) { + WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err); + goto CleanUp; + } + + bi = (wl_bss_info_t *)(buf + 4); + + channel = bi->ctl_ch ? bi->ctl_ch : + CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + + if (channel <= CH_MAX_2G_CHANNEL) + band = wiphy->bands[IEEE80211_BAND_2GHZ]; + else + band = wiphy->bands[IEEE80211_BAND_5GHZ]; + + freq = ieee80211_channel_to_frequency(channel, band->band); + notify_channel = ieee80211_get_channel(wiphy, freq); + + notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ + notify_capability = le16_to_cpu(bi->capability); + notify_interval = le16_to_cpu(bi->beacon_period); + notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); + notify_ielen = le16_to_cpu(bi->ie_length); + notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; + + WL_CONN("channel: %d(%d)\n", channel, freq); + WL_CONN("capability: %X\n", notify_capability); + WL_CONN("beacon interval: %d\n", notify_interval); + WL_CONN("signal: %d\n", notify_signal); + WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); + + cfg80211_inform_bss(wiphy, notify_channel, bssid, + notify_timestamp, notify_capability, notify_interval, + notify_ie, notify_ielen, notify_signal, GFP_KERNEL); + +CleanUp: + + kfree(buf); + + WL_TRACE("Exit\n"); return err; } @@ -2335,17 +2559,12 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e) { u32 event = be32_to_cpu(e->event_type); - u16 flags = be16_to_cpu(e->flags); + u32 status = be32_to_cpu(e->status); - if (event == WLC_E_LINK) { - if (flags & WLC_EVENT_MSG_LINK) { - if (wl_is_ibssmode(wl)) { - if (wl_is_ibssstarter(wl)) { - } - } else { - return true; - } - } + if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) { + WL_CONN("Processing set ssid\n"); + wl->link_up = true; + return true; } return false; @@ -2356,13 +2575,10 @@ static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) u32 event = be32_to_cpu(e->event_type); u16 flags = be16_to_cpu(e->flags); - if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) { + if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) { + WL_CONN("Processing link down\n"); return true; - } else if (event == WLC_E_LINK) { - if (!(flags & WLC_EVENT_MSG_LINK)) - return true; } - return false; } @@ -2370,10 +2586,17 @@ static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) { u32 event = be32_to_cpu(e->event_type); u32 status = be32_to_cpu(e->status); + u16 flags = be16_to_cpu(e->flags); + + if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) { + WL_CONN("Processing Link %s & no network found\n", + flags & WLC_EVENT_MSG_LINK ? "up" : "down"); + return true; + } - if (event == WLC_E_SET_SSID || event == WLC_E_LINK) { - if (status == WLC_E_STATUS_NO_NETWORKS) - return true; + if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) { + WL_CONN("Processing connecting & no network found\n"); + return true; } return false; @@ -2383,30 +2606,39 @@ static s32 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { - bool act; s32 err = 0; if (wl_is_linkup(wl, e)) { - wl_link_up(wl); + WL_CONN("Linkup\n"); if (wl_is_ibssmode(wl)) { - cfg80211_ibss_joined(ndev, (s8 *)&e->addr, - GFP_KERNEL); - WL_DBG("joined in IBSS network\n"); - } else { + wl_update_prof(wl, NULL, (void *)e->addr, + WL_PROF_BSSID); + wl_inform_ibss(wl, ndev, e->addr); + cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); + clear_bit(WL_STATUS_CONNECTING, &wl->status); + set_bit(WL_STATUS_CONNECTED, &wl->status); + } else wl_bss_connect_done(wl, ndev, e, data, true); - WL_DBG("joined in BSS network \"%s\"\n", - ((struct wlc_ssid *) - wl_read_prof(wl, WL_PROF_SSID))->SSID); - } - act = true; - wl_update_prof(wl, e, &act, WL_PROF_ACT); } else if (wl_is_linkdown(wl, e)) { - cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); - clear_bit(WL_STATUS_CONNECTED, &wl->status); - wl_link_down(wl); + WL_CONN("Linkdown\n"); + if (wl_is_ibssmode(wl)) { + if (test_and_clear_bit(WL_STATUS_CONNECTED, + &wl->status)) + wl_link_down(wl); + } else { + if (test_and_clear_bit(WL_STATUS_CONNECTED, + &wl->status)) { + cfg80211_disconnected(ndev, 0, NULL, 0, + GFP_KERNEL); + wl_link_down(wl); + } + } wl_init_prof(wl->profile); } else if (wl_is_nonetwork(wl, e)) { - wl_bss_connect_done(wl, ndev, e, data, false); + if (wl_is_ibssmode(wl)) + clear_bit(WL_STATUS_CONNECTING, &wl->status); + else + wl_bss_connect_done(wl, ndev, e, data, false); } return err; @@ -2416,12 +2648,16 @@ static s32 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { - bool act; s32 err = 0; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); - wl_bss_roaming_done(wl, ndev, e, data); - act = true; - wl_update_prof(wl, e, &act, WL_PROF_ACT); + if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) { + if (test_bit(WL_STATUS_CONNECTED, &wl->status)) + wl_bss_roaming_done(wl, ndev, e, data); + else + wl_bss_connect_done(wl, ndev, e, data, true); + } return err; } @@ -2468,6 +2704,8 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) u32 resp_len; s32 err = 0; + wl_clear_assoc_ies(wl); + err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, WL_ASSOC_INFO_MAX); if (unlikely(err)) { @@ -2505,12 +2743,25 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) conn_info->resp_ie_len = 0; conn_info->resp_ie = NULL; } - WL_DBG("req len (%d) resp len (%d)\n", + WL_CONN("req len (%d) resp len (%d)\n", conn_info->req_ie_len, conn_info->resp_ie_len); return err; } +static void wl_clear_assoc_ies(struct wl_priv *wl) +{ + struct wl_connect_info *conn_info = wl_to_conn(wl); + + kfree(conn_info->req_ie); + conn_info->req_ie = NULL; + conn_info->req_ie_len = 0; + kfree(conn_info->resp_ie); + conn_info->resp_ie = NULL; + conn_info->resp_ie_len = 0; +} + + static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, size_t *join_params_size) { @@ -2520,7 +2771,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_num = 1; join_params->params.chanspec_list[0] = ch; - if (join_params->params.chanspec_list[0]) + if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL) chanspec |= WL_CHANSPEC_BAND_2G; else chanspec |= WL_CHANSPEC_BAND_5G; @@ -2539,14 +2790,14 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_num = cpu_to_le32(join_params->params.chanspec_num); - WL_DBG("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n", + WL_CONN("join_params->params.chanspec_list[0]= %#X," + "channel %d, chanspec %#X\n", join_params->params.chanspec_list[0], ch, chanspec); } } static s32 wl_update_bss_info(struct wl_priv *wl) { - struct cfg80211_bss *bss; struct wl_bss_info *bi; struct wlc_ssid *ssid; struct bcm_tlv *tim; @@ -2556,67 +2807,52 @@ static s32 wl_update_bss_info(struct wl_priv *wl) u8 *ie; s32 err = 0; + WL_TRACE("Enter\n"); if (wl_is_ibssmode(wl)) return err; ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID); - bss = - cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid, - ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, - WLAN_CAPABILITY_ESS); - - rtnl_lock(); - if (unlikely(!bss)) { - WL_DBG("Could not find the AP\n"); - *(u32 *) wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); - err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, - wl->extra_buf, WL_EXTRA_BUF_MAX); - if (unlikely(err)) { - WL_ERR("Could not get bss info %d\n", err); - goto update_bss_info_out; - } - bi = (struct wl_bss_info *)(wl->extra_buf + 4); - if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETH_ALEN))) { - err = -EIO; - goto update_bss_info_out; - } - err = wl_inform_single_bss(wl, bi); - if (unlikely(err)) - goto update_bss_info_out; - ie = ((u8 *)bi) + bi->ie_offset; - ie_len = bi->ie_length; - beacon_interval = cpu_to_le16(bi->beacon_period); - } else { - WL_DBG("Found the AP in the list - BSSID %pM\n", bss->bssid); - ie = bss->information_elements; - ie_len = bss->len_information_elements; - beacon_interval = bss->beacon_interval; - cfg80211_put_bss(bss); + *(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); + err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, + wl->extra_buf, WL_EXTRA_BUF_MAX); + if (unlikely(err)) { + WL_ERR("Could not get bss info %d\n", err); + goto update_bss_info_out; } + bi = (struct wl_bss_info *)(wl->extra_buf + 4); + err = wl_inform_single_bss(wl, bi); + if (unlikely(err)) + goto update_bss_info_out; + + ie = ((u8 *)bi) + bi->ie_offset; + ie_len = bi->ie_length; + beacon_interval = cpu_to_le16(bi->beacon_period); + tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); - if (tim) { + if (tim) dtim_period = tim->data[1]; - } else { + else { /* * active scan was done so we could not get dtim * information out of probe response. * so we speficially query dtim information to dongle. */ - err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD, - &dtim_period, sizeof(dtim_period)); + u32 var; + err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var); if (unlikely(err)) { - WL_ERR("WLC_GET_DTIMPRD error (%d)\n", err); + WL_ERR("wl dtim_assoc failed (%d)\n", err); goto update_bss_info_out; } + dtim_period = (u8)var; } wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT); wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD); update_bss_info_out: - rtnl_unlock(); + WL_TRACE("Exit"); return err; } @@ -2627,17 +2863,20 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, struct wl_connect_info *conn_info = wl_to_conn(wl); s32 err = 0; + WL_TRACE("Enter\n"); + wl_get_assoc_ies(wl); - memcpy(&wl->bssid, &e->addr, ETH_ALEN); + wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID); wl_update_bss_info(wl); + cfg80211_roamed(ndev, - (u8 *)&wl->bssid, + (u8 *)wl_read_prof(wl, WL_PROF_BSSID), conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); - WL_DBG("Report roaming result\n"); + WL_CONN("Report roaming result\n"); set_bit(WL_STATUS_CONNECTED, &wl->status); - + WL_TRACE("Exit\n"); return err; } @@ -2648,30 +2887,28 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, struct wl_connect_info *conn_info = wl_to_conn(wl); s32 err = 0; - wl_get_assoc_ies(wl); - memcpy(&wl->bssid, &e->addr, ETH_ALEN); - wl_update_bss_info(wl); + WL_TRACE("Enter\n"); + if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) { + if (completed) { + wl_get_assoc_ies(wl); + wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID); + wl_update_bss_info(wl); + } cfg80211_connect_result(ndev, - (u8 *)&wl->bssid, + (u8 *)wl_read_prof(wl, WL_PROF_BSSID), conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); - WL_DBG("Report connect result - connection %s\n", - completed ? "succeeded" : "failed"); - } else { - cfg80211_roamed(ndev, - (u8 *)&wl->bssid, - conn_info->req_ie, conn_info->req_ie_len, - conn_info->resp_ie, conn_info->resp_ie_len, - GFP_KERNEL); - WL_DBG("Report roaming result\n"); + if (completed) + set_bit(WL_STATUS_CONNECTED, &wl->status); + WL_CONN("Report connect result - connection %s\n", + completed ? "succeeded" : "failed"); } - set_bit(WL_STATUS_CONNECTED, &wl->status); - + WL_TRACE("Exit\n"); return err; } @@ -2703,37 +2940,45 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, struct wl_scan_results *bss_list; u32 len = WL_SCAN_BUF_MAX; s32 err = 0; + bool scan_abort = false; + + WL_TRACE("Enter\n"); - if (wl->iscan_on && wl->iscan_kickstart) + if (wl->iscan_on && wl->iscan_kickstart) { + WL_TRACE("Exit\n"); return wl_wakeup_iscan(wl_to_iscan(wl)); + } if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { WL_ERR("Scan complete while device not scanning\n"); - return -EINVAL; - } - if (unlikely(!wl->scan_request)) { + scan_abort = true; + err = -EINVAL; + goto scan_done_out; } - rtnl_lock(); + err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, sizeof(channel_inform)); if (unlikely(err)) { WL_ERR("scan busy (%d)\n", err); + scan_abort = true; goto scan_done_out; } channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel); if (unlikely(channel_inform.scan_channel)) { - WL_DBG("channel_inform.scan_channel (%d)\n", + WL_CONN("channel_inform.scan_channel (%d)\n", channel_inform.scan_channel); } wl->bss_list = wl->scan_results; bss_list = wl->bss_list; memset(bss_list, 0, len); bss_list->buflen = cpu_to_le32(len); + err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len); if (unlikely(err)) { WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); err = -EINVAL; + scan_abort = true; goto scan_done_out; } bss_list->buflen = le32_to_cpu(bss_list->buflen); @@ -2741,16 +2986,21 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, bss_list->count = le32_to_cpu(bss_list->count); err = wl_inform_bss(wl); - if (err) + if (err) { + scan_abort = true; goto scan_done_out; + } scan_done_out: if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, false); + WL_SCAN("calling cfg80211_scan_done\n"); + cfg80211_scan_done(wl->scan_request, scan_abort); wl_set_mpc(ndev, 1); wl->scan_request = NULL; } - rtnl_unlock(); + + WL_TRACE("Exit\n"); + return err; } @@ -2773,12 +3023,7 @@ static void wl_init_eloop_handler(struct wl_event_loop *el) { memset(el, 0, sizeof(*el)); el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status; - el->handler[WLC_E_JOIN] = wl_notify_connect_status; el->handler[WLC_E_LINK] = wl_notify_connect_status; - el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status; - el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status; - el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status; - el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status; el->handler[WLC_E_ROAM] = wl_notify_roaming_status; el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status; el->handler[WLC_E_SET_SSID] = wl_notify_connect_status; @@ -2912,6 +3157,8 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) return; } if (likely(wl->scan_request)) { + WL_SCAN("ISCAN Completed scan: %s\n", + aborted ? "Aborted" : "Done"); cfg80211_scan_done(wl->scan_request, aborted); wl_set_mpc(ndev, 1); wl->scan_request = NULL; @@ -2922,7 +3169,7 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) { if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { - WL_DBG("wake up iscan\n"); + WL_SCAN("wake up iscan\n"); up(&iscan->sync); return 0; } @@ -2958,8 +3205,8 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, results->buflen = le32_to_cpu(results->buflen); results->version = le32_to_cpu(results->version); results->count = le32_to_cpu(results->count); - WL_DBG("results->count = %d\n", results->count); - WL_DBG("results->buflen = %d\n", results->buflen); + WL_SCAN("results->count = %d\n", results->count); + WL_SCAN("results->buflen = %d\n", results->buflen); *status = le32_to_cpu(list_buf->status); *bss_list = results; @@ -3053,7 +3300,7 @@ static s32 wl_iscan_thread(void *data) del_timer_sync(&iscan->timer); iscan->timer_on = 0; } - WL_DBG("%s was terminated\n", __func__); + WL_SCAN("ISCAN thread terminated\n"); return 0; } @@ -3064,7 +3311,7 @@ static void wl_iscan_timer(unsigned long data) if (iscan) { iscan->timer_on = 0; - WL_DBG("timer expired\n"); + WL_SCAN("timer expired\n"); wl_wakeup_iscan(iscan); } } @@ -3191,7 +3438,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) WL_ERR("wl_cfg80211_dev is invalid\n"); return -ENOMEM; } - WL_DBG("func %p\n", wl_cfg80211_get_sdio_func()); + WL_INFO("func %p\n", wl_cfg80211_get_sdio_func()); wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev); if (IS_ERR(wdev)) return -ENOMEM; @@ -3211,7 +3458,6 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) goto cfg80211_attach_out; } wl_set_drvdata(wl_cfg80211_dev, ci); - set_bit(WL_STATUS_READY, &wl->status); return err; @@ -3255,16 +3501,16 @@ static s32 wl_event_handler(void *data) WL_ERR("event queue empty...\n"); BUG(); } - WL_DBG("event type (%d)\n", e->etype); + WL_INFO("event type (%d)\n", e->etype); if (wl->el.handler[e->etype]) { wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg, e->edata); } else { - WL_DBG("Unknown Event (%d): ignoring\n", e->etype); + WL_INFO("Unknown Event (%d): ignoring\n", e->etype); } wl_put_event(e); } - WL_DBG("%s was terminated\n", __func__); + WL_INFO("was terminated\n"); return 0; } @@ -3273,11 +3519,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) { u32 event_type = be32_to_cpu(e->event_type); struct wl_priv *wl = ndev_to_wl(ndev); -#if (WL_DBG_LEVEL > 0) - s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ? - wl_dbg_estr[event_type] : (s8 *) "Unknown"; -#endif /* (WL_DBG_LEVEL > 0) */ - WL_DBG("event_type (%d):" "WLC_E_" "%s\n", event_type, estr); + if (likely(!wl_enq_event(wl, event_type, e, data))) wl_wakeup_event(wl); } @@ -3370,7 +3612,6 @@ struct sdio_func *wl_cfg80211_get_sdio_func(void) static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) { s32 infra = 0; - s32 ap = 0; s32 err = 0; switch (iftype) { @@ -3381,6 +3622,7 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) err = -EINVAL; return err; case NL80211_IFTYPE_ADHOC: + infra = 0; break; case NL80211_IFTYPE_STATION: infra = 1; @@ -3391,20 +3633,13 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) return err; } infra = cpu_to_le32(infra); - ap = cpu_to_le32(ap); - WL_DBG("%s ap (%d), infra (%d)\n", ndev->name, ap, infra); err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); return err; } - err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)); - if (unlikely(err)) { - WL_ERR("WLC_SET_AP error (%d)\n", err); - return err; - } - return -EINPROGRESS; + return 0; } #ifndef EMBEDDED_PLATFORM @@ -3465,116 +3700,6 @@ dongle_glom_out: } static s32 -wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - s32 err = 0; - - /* Setup timeout if Beacons are lost and roam is - off to report link down */ - if (roamvar) { - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, - sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("bcn_timeout error (%d)\n", err); - goto dongle_rom_out; - } - } - /* Enable/Disable built-in roaming to allow supplicant - to take care of roaming */ - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("roam_off error (%d)\n", err); - goto dongle_rom_out; - } -dongle_rom_out: - return err; -} - -static s32 wl_dongle_eventmsg(struct net_device *ndev) -{ - - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - s8 eventmask[WL_EVENTING_MASK_LEN]; - s32 err = 0; - - /* Setup event_msgs */ - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, - sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("Get event_msgs error (%d)\n", err); - goto dongle_eventmsg_out; - } - memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); - - setbit(eventmask, WLC_E_SET_SSID); - setbit(eventmask, WLC_E_PRUNE); - setbit(eventmask, WLC_E_AUTH); - setbit(eventmask, WLC_E_REASSOC); - setbit(eventmask, WLC_E_REASSOC_IND); - setbit(eventmask, WLC_E_DEAUTH_IND); - setbit(eventmask, WLC_E_DISASSOC_IND); - setbit(eventmask, WLC_E_DISASSOC); - setbit(eventmask, WLC_E_JOIN); - setbit(eventmask, WLC_E_ASSOC_IND); - setbit(eventmask, WLC_E_PSK_SUP); - setbit(eventmask, WLC_E_LINK); - setbit(eventmask, WLC_E_NDIS_LINK); - setbit(eventmask, WLC_E_MIC_ERROR); - setbit(eventmask, WLC_E_PMKID_CACHE); - setbit(eventmask, WLC_E_TXFAIL); - setbit(eventmask, WLC_E_JOIN_START); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, - sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("Set event_msgs error (%d)\n", err); - goto dongle_eventmsg_out; - } - -dongle_eventmsg_out: - return err; -} - -static s32 -wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, - s32 scan_unassoc_time) -{ - s32 err = 0; - - err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time, - sizeof(scan_assoc_time)); - if (err) { - if (err == -EOPNOTSUPP) { - WL_INFO("Scan assoc time is not supported\n"); - } else { - WL_ERR("Scan assoc time error (%d)\n", err); - } - goto dongle_scantime_out; - } - err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time, - sizeof(scan_unassoc_time)); - if (err) { - if (err == -EOPNOTSUPP) { - WL_INFO("Scan unassoc time is not supported\n"); - } else { - WL_ERR("Scan unassoc time error (%d)\n", err); - } - goto dongle_scantime_out; - } - -dongle_scantime_out: - return err; -} - -static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol) { s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + @@ -3722,6 +3847,154 @@ dongle_filter_out: } #endif /* !EMBEDDED_PLATFORM */ +static s32 wl_dongle_eventmsg(struct net_device *ndev) +{ + s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + + '\0' + bitvec */ + s8 eventmask[WL_EVENTING_MASK_LEN]; + s32 err = 0; + + WL_TRACE("Enter\n"); + + /* Setup event_msgs */ + bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, + sizeof(iovbuf)); + err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); + if (unlikely(err)) { + WL_ERR("Get event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; + } + memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); + + setbit(eventmask, WLC_E_SET_SSID); + setbit(eventmask, WLC_E_ROAM); + setbit(eventmask, WLC_E_PRUNE); + setbit(eventmask, WLC_E_AUTH); + setbit(eventmask, WLC_E_REASSOC); + setbit(eventmask, WLC_E_REASSOC_IND); + setbit(eventmask, WLC_E_DEAUTH_IND); + setbit(eventmask, WLC_E_DISASSOC_IND); + setbit(eventmask, WLC_E_DISASSOC); + setbit(eventmask, WLC_E_JOIN); + setbit(eventmask, WLC_E_ASSOC_IND); + setbit(eventmask, WLC_E_PSK_SUP); + setbit(eventmask, WLC_E_LINK); + setbit(eventmask, WLC_E_NDIS_LINK); + setbit(eventmask, WLC_E_MIC_ERROR); + setbit(eventmask, WLC_E_PMKID_CACHE); + setbit(eventmask, WLC_E_TXFAIL); + setbit(eventmask, WLC_E_JOIN_START); + setbit(eventmask, WLC_E_SCAN_COMPLETE); + + bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, + sizeof(iovbuf)); + err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + if (unlikely(err)) { + WL_ERR("Set event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; + } + +dongle_eventmsg_out: + WL_TRACE("Exit\n"); + return err; +} + +static s32 +wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) +{ + s8 iovbuf[32]; + s32 roamtrigger[2]; + s32 roam_delta[2]; + s32 err = 0; + + /* + * Setup timeout if Beacons are lost and roam is + * off to report link down + */ + if (roamvar) { + bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, + sizeof(bcn_timeout), iovbuf, sizeof(iovbuf)); + err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + if (unlikely(err)) { + WL_ERR("bcn_timeout error (%d)\n", err); + goto dongle_rom_out; + } + } + + /* + * Enable/Disable built-in roaming to allow supplicant + * to take care of roaming + */ + WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On"); + bcm_mkiovar("roam_off", (char *)&roamvar, + sizeof(roamvar), iovbuf, sizeof(iovbuf)); + err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + if (unlikely(err)) { + WL_ERR("roam_off error (%d)\n", err); + goto dongle_rom_out; + } + + roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL; + roamtrigger[1] = WLC_BAND_ALL; + err = wl_dev_ioctl(ndev, WLC_SET_ROAM_TRIGGER, + (void *)roamtrigger, sizeof(roamtrigger)); + if (unlikely(err)) { + WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err); + goto dongle_rom_out; + } + + roam_delta[0] = WL_ROAM_DELTA; + roam_delta[1] = WLC_BAND_ALL; + err = wl_dev_ioctl(ndev, WLC_SET_ROAM_DELTA, + (void *)roam_delta, sizeof(roam_delta)); + if (unlikely(err)) { + WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err); + goto dongle_rom_out; + } + +dongle_rom_out: + return err; +} + +static s32 +wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, + s32 scan_unassoc_time, s32 scan_passive_time) +{ + s32 err = 0; + + err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time, + sizeof(scan_assoc_time)); + if (err) { + if (err == -EOPNOTSUPP) + WL_INFO("Scan assoc time is not supported\n"); + else + WL_ERR("Scan assoc time error (%d)\n", err); + goto dongle_scantime_out; + } + err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time, + sizeof(scan_unassoc_time)); + if (err) { + if (err == -EOPNOTSUPP) + WL_INFO("Scan unassoc time is not supported\n"); + else + WL_ERR("Scan unassoc time error (%d)\n", err); + goto dongle_scantime_out; + } + + err = wl_dev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME, &scan_passive_time, + sizeof(scan_passive_time)); + if (err) { + if (err == -EOPNOTSUPP) + WL_INFO("Scan passive time is not supported\n"); + else + WL_ERR("Scan passive time error (%d)\n", err); + goto dongle_scantime_out; + } + +dongle_scantime_out: + return err; +} + s32 wl_config_dongle(struct wl_priv *wl, bool need_lock) { #ifndef DHD_SDALIGN @@ -3752,18 +4025,20 @@ s32 wl_config_dongle(struct wl_priv *wl, bool need_lock) err = wl_dongle_glom(ndev, 0, DHD_SDALIGN); if (unlikely(err)) goto default_conf_out; - err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3); - if (unlikely(err)) - goto default_conf_out; - err = wl_dongle_eventmsg(ndev); - if (unlikely(err)) - goto default_conf_out; - wl_dongle_scantime(ndev, 40, 80); wl_dongle_offload(ndev, 1, 0xf); wl_dongle_filter(ndev, 1); -#endif /* !EMBEDDED_PLATFORM */ +#endif /* !EMBEDDED_PLATFORM */ + wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, + WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); + + err = wl_dongle_eventmsg(ndev); + if (unlikely(err)) + goto default_conf_out; + err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); + if (unlikely(err)) + goto default_conf_out; err = wl_dongle_mode(ndev, wdev->iftype); if (unlikely(err && err != -EINPROGRESS)) goto default_conf_out; @@ -3798,7 +4073,7 @@ static s32 wl_update_wiphybands(struct wl_priv *wl) } phy = ((char *)&phy_list)[1]; - WL_DBG("%c phy\n", phy); + WL_INFO("%c phy\n", phy); if (phy == 'n' || phy == 'a') { wiphy = wl_to_wiphy(wl); wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; @@ -3811,6 +4086,8 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl) { s32 err = 0; + set_bit(WL_STATUS_READY, &wl->status); + wl_debugfs_add_netdev_params(wl); err = wl_config_dongle(wl, false); @@ -3818,41 +4095,29 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl) return err; wl_invoke_iscan(wl); - set_bit(WL_STATUS_READY, &wl->status); + return err; } static s32 __wl_cfg80211_down(struct wl_priv *wl) { - s32 err = 0; - - /* Check if cfg80211 interface is already down */ - if (!test_bit(WL_STATUS_READY, &wl->status)) - return err; /* it is even not ready */ - set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); wl_term_iscan(wl); if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, true); /* true - means abort */ - /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG - * this operation cannot help - * but here because sdio - * is already down through - * rmmod process. - * Need to figure out how to - * address this issue - */ + cfg80211_scan_done(wl->scan_request, true); + /* May need to perform this to cover rmmod */ + /* wl_set_mpc(wl_to_ndev(wl), 1); */ wl->scan_request = NULL; } clear_bit(WL_STATUS_READY, &wl->status); clear_bit(WL_STATUS_SCANNING, &wl->status); clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); + clear_bit(WL_STATUS_CONNECTING, &wl->status); clear_bit(WL_STATUS_CONNECTED, &wl->status); wl_debugfs_remove_netdev(wl); - return err; + return 0; } s32 wl_cfg80211_up(void) @@ -3897,8 +4162,6 @@ static void *wl_read_prof(struct wl_priv *wl, s32 item) switch (item) { case WL_PROF_SEC: return &wl->profile->sec; - case WL_PROF_ACT: - return &wl->profile->active; case WL_PROF_BSSID: return &wl->profile->bssid; case WL_PROF_SSID: @@ -3932,9 +4195,6 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, case WL_PROF_SEC: memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec)); break; - case WL_PROF_ACT: - wl->profile->active = *(bool *)data; - break; case WL_PROF_BEACONINT: wl->profile->beacon_interval = *(u16 *)data; break; @@ -3950,34 +4210,11 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, return err; } -void wl_cfg80211_dbg_level(u32 level) -{ - /* - * prohibit to change debug level - * by insmod parameter. - * eventually debug level will be configured - * in compile time by using CONFIG_XXX - */ - /* wl_dbg_level = level; */ -} - static bool wl_is_ibssmode(struct wl_priv *wl) { return wl->conf->mode == WL_MODE_IBSS; } -static bool wl_is_ibssstarter(struct wl_priv *wl) -{ - return wl->ibss_starter; -} - -static void wl_rst_ie(struct wl_priv *wl) -{ - struct wl_ie *ie = wl_to_ie(wl); - - ie->offset = 0; -} - static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) { struct wl_ie *ie = wl_to_ie(wl); @@ -3995,58 +4232,24 @@ static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) return err; } -static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size) -{ - struct wl_ie *ie = wl_to_ie(wl); - s32 err = 0; - - if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) { - WL_ERR("ei_stream crosses buffer boundary\n"); - return -ENOSPC; - } - memcpy(&ie->buf[ie->offset], ie_stream, ie_size); - ie->offset += ie_size; - return err; -} - -static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size) +static void wl_link_down(struct wl_priv *wl) { - struct wl_ie *ie = wl_to_ie(wl); + struct net_device *dev = NULL; s32 err = 0; - if (unlikely(ie->offset > dst_size)) { - WL_ERR("dst_size is not enough\n"); - return -ENOSPC; - } - memcpy(dst, &ie->buf[0], ie->offset); - - return err; -} - -static u32 wl_get_ielen(struct wl_priv *wl) -{ - struct wl_ie *ie = wl_to_ie(wl); - - return ie->offset; -} - -static void wl_link_up(struct wl_priv *wl) -{ - wl->link_up = true; -} - -static void wl_link_down(struct wl_priv *wl) -{ - struct wl_connect_info *conn_info = wl_to_conn(wl); + WL_TRACE("Enter\n"); + clear_bit(WL_STATUS_CONNECTED, &wl->status); - wl->link_up = false; - kfree(conn_info->req_ie); - conn_info->req_ie = NULL; - conn_info->req_ie_len = 0; - kfree(conn_info->resp_ie); - conn_info->resp_ie = NULL; - conn_info->resp_ie_len = 0; + if (wl->link_up) { + dev = wl_to_ndev(wl); + WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); + err = wl_dev_ioctl(dev, WLC_DISASSOC, NULL, 0); + if (unlikely(err)) + WL_ERR("WLC_DISASSOC failed (%d)\n", err); + wl->link_up = false; + } + WL_TRACE("Exit\n"); } static void wl_lock_eq(struct wl_priv *wl) @@ -4116,7 +4319,7 @@ void *wl_cfg80211_request_fw(s8 *file_name) const struct firmware *fw_entry = NULL; s32 err = 0; - WL_DBG("file name : \"%s\"\n", file_name); + WL_INFO("file name : \"%s\"\n", file_name); wl = WL_PRIV_GET(); if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) { @@ -4129,7 +4332,7 @@ void *wl_cfg80211_request_fw(s8 *file_name) set_bit(WL_FW_LOADING_DONE, &wl->fw->status); fw_entry = wl->fw->fw_entry; if (fw_entry) { - WL_DBG("fw size (%zd), data (%p)\n", + WL_INFO("fw size (%zd), data (%p)\n", fw_entry->size, fw_entry->data); } } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) { @@ -4142,11 +4345,11 @@ void *wl_cfg80211_request_fw(s8 *file_name) set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status); fw_entry = wl->fw->fw_entry; if (fw_entry) { - WL_DBG("nvram size (%zd), data (%p)\n", + WL_INFO("nvram size (%zd), data (%p)\n", fw_entry->size, fw_entry->data); } } else { - WL_DBG("Downloading already done. Nothing to do more\n"); + WL_INFO("Downloading already done. Nothing to do more\n"); err = -EPERM; } @@ -4179,13 +4382,16 @@ s8 *wl_cfg80211_get_nvramname(void) static void wl_set_mpc(struct net_device *ndev, int mpc) { s32 err = 0; + struct wl_priv *wl = ndev_to_wl(ndev); - err = wl_dev_intvar_set(ndev, "mpc", mpc); - if (unlikely(err)) { - WL_ERR("fail to set mpc\n"); - return; + if (test_bit(WL_STATUS_READY, &wl->status)) { + err = wl_dev_intvar_set(ndev, "mpc", mpc); + if (unlikely(err)) { + WL_ERR("fail to set mpc\n"); + return; + } + WL_INFO("MPC : %d\n", mpc); } - WL_DBG("MPC : %d\n", mpc); } static int wl_debugfs_add_netdev_params(struct wl_priv *wl) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index 5112160e0ae3..996033cf9b09 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -28,45 +28,73 @@ struct wl_priv; struct wl_security; struct wl_ibss; -#define WL_DBG_NONE 0 -#define WL_DBG_DBG (1 << 2) -#define WL_DBG_INFO (1 << 1) -#define WL_DBG_ERR (1 << 0) -#define WL_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1) - -#define WL_DBG_LEVEL 1 /* 0 invalidates all debug messages. - default is 1 */ +#define WL_DBG_NONE 0 +#define WL_DBG_CONN (1 << 5) +#define WL_DBG_SCAN (1 << 4) +#define WL_DBG_TRACE (1 << 3) +#define WL_DBG_INFO (1 << 1) +#define WL_DBG_ERR (1 << 0) +#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \ + (WL_DBG_SCAN) | (WL_DBG_CONN)) + #define WL_ERR(fmt, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ if (net_ratelimit()) { \ printk(KERN_ERR "ERROR @%s : " fmt, \ - __func__, ##args); \ + __func__, ##args); \ } \ } \ } while (0) +#if (defined BCMDBG) #define WL_INFO(fmt, args...) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ if (net_ratelimit()) { \ printk(KERN_ERR "INFO @%s : " fmt, \ - __func__, ##args); \ + __func__, ##args); \ + } \ + } \ +} while (0) + +#define WL_TRACE(fmt, args...) \ +do { \ + if (wl_dbg_level & WL_DBG_TRACE) { \ + if (net_ratelimit()) { \ + printk(KERN_ERR "TRACE @%s : " fmt, \ + __func__, ##args); \ } \ } \ } while (0) -#if (WL_DBG_LEVEL > 0) -#define WL_DBG(fmt, args...) \ +#define WL_SCAN(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "DEBUG @%s :" fmt, \ - __func__, ##args); \ + if (wl_dbg_level & WL_DBG_SCAN) { \ + if (net_ratelimit()) { \ + printk(KERN_ERR "SCAN @%s : " fmt, \ + __func__, ##args); \ + } \ } \ } while (0) -#else /* !(WL_DBG_LEVEL > 0) */ -#define WL_DBG(fmt, args...) noprintk(fmt, ##args) -#endif /* (WL_DBG_LEVEL > 0) */ + +#define WL_CONN(fmt, args...) \ +do { \ + if (wl_dbg_level & WL_DBG_CONN) { \ + if (net_ratelimit()) { \ + printk(KERN_ERR "CONN @%s : " fmt, \ + __func__, ##args); \ + } \ + } \ +} while (0) + +#else /* (defined BCMDBG) */ +#define WL_INFO(fmt, args...) +#define WL_TRACE(fmt, args...) +#define WL_SCAN(fmt, args...) +#define WL_CONN(fmt, args...) +#endif /* (defined BCMDBG) */ + #define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */ #define WL_NUM_SCAN_MAX 1 @@ -95,6 +123,14 @@ do { \ */ #define WL_FILE_NAME_MAX 256 +#define WL_ROAM_TRIGGER_LEVEL -75 +#define WL_ROAM_DELTA 20 +#define WL_BEACON_TIMEOUT 3 + +#define WL_SCAN_CHANNEL_TIME 40 +#define WL_SCAN_UNASSOC_TIME 40 +#define WL_SCAN_PASSIVE_TIME 120 + /* dongle status */ enum wl_status { WL_STATUS_READY, @@ -227,7 +263,6 @@ struct wl_profile { struct wl_security sec; struct wl_ibss ibss; s32 band; - bool active; }; /* dongle iscan event loop */ @@ -298,7 +333,6 @@ struct wl_priv { cfg80211 layer */ struct wl_ie ie; /* information element object for internal purpose */ - u8 bssid[ETH_ALEN]; /* bssid of currently engaged network */ struct semaphore event_sync; /* for synchronization of main event thread */ struct wl_profile *profile; /* holding dongle profile */ @@ -375,5 +409,6 @@ extern s8 *wl_cfg80211_get_fwname(void); /* get firmware name for the dongle */ extern s8 *wl_cfg80211_get_nvramname(void); /* get nvram name for the dongle */ +extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick); #endif /* _wl_cfg80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index b49957fb7586..929ceaf363be 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -69,8 +69,6 @@ uint wl_msg_level = WL_ERROR_VAL; #define MAX_WLIW_IOCTL_LEN 1024 #ifdef CONFIG_WIRELESS_EXT - -extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); extern int dhd_wait_pend8021x(struct net_device *dev); #endif @@ -119,6 +117,9 @@ iscan_info_t *g_iscan; static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; +/* Global ASSERT type flag */ +u32 g_assert_type; + static void wl_iw_timerfunc(unsigned long data); static void wl_iw_set_event_mask(struct net_device *dev); static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action); @@ -372,7 +373,7 @@ wl_iw_set_freq(struct net_device *dev, if (fwrq->m > 4000 && fwrq->m < 5000) sf = WF_CHAN_FACTOR_4_G; - chan = wf_mhz2channel(fwrq->m, sf); + chan = bcm_mhz2channel(fwrq->m, sf); } chan = cpu_to_le32(chan); @@ -495,9 +496,7 @@ wl_iw_get_range(struct net_device *dev, list = (wl_u32_list_t *) channels; dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(range)); - - range->min_nwid = range->max_nwid = 0; + memset(range, 0, sizeof(*range)); list->count = cpu_to_le32(MAXCHANNEL); error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, @@ -3131,7 +3130,7 @@ const struct iw_handler_def wl_iw_handler_def = { .private_args = 0, #if WIRELESS_EXT >= 19 - .get_wireless_stats = dhd_get_wireless_stats, + .get_wireless_stats = NULL, #endif }; #endif /* WIRELESS_EXT > 12 */ @@ -3548,103 +3547,6 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) #endif /* WIRELESS_EXT > 13 */ } -int -wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) -{ - int res = 0; - struct wl_cnt cnt; - int phy_noise; - int rssi; - scb_val_t scb_val; - - phy_noise = 0; - res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, - sizeof(phy_noise)); - if (res) - goto done; - - phy_noise = le32_to_cpu(phy_noise); - WL_TRACE("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise); - - memset(&scb_val, 0, sizeof(scb_val_t)); - res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (res) - goto done; - - rssi = le32_to_cpu(scb_val.val); - WL_TRACE("wl_iw_get_wireless_stats rssi=%d\n", rssi); - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - wstats->qual.qual = 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - wstats->qual.qual = 1; - else if (rssi <= WL_IW_RSSI_LOW) - wstats->qual.qual = 2; - else if (rssi <= WL_IW_RSSI_GOOD) - wstats->qual.qual = 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - wstats->qual.qual = 4; - else - wstats->qual.qual = 5; - - wstats->qual.level = 0x100 + rssi; - wstats->qual.noise = 0x100 + phy_noise; -#if WIRELESS_EXT > 18 - wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM); -#else - wstats->qual.updated |= 7; -#endif - -#if WIRELESS_EXT > 11 - WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n", - sizeof(struct wl_cnt)); - - memset(&cnt, 0, sizeof(struct wl_cnt)); - res = - dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, - sizeof(struct wl_cnt)); - if (res) { - WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n", - res); - goto done; - } - - cnt.version = le16_to_cpu(cnt.version); - if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE("\tIncorrect counter version: expected %d; got %d\n", - WL_CNT_T_VERSION, cnt.version); - goto done; - } - - wstats->discard.nwid = 0; - wstats->discard.code = le32_to_cpu(cnt.rxundec); - wstats->discard.fragment = le32_to_cpu(cnt.rxfragerr); - wstats->discard.retries = le32_to_cpu(cnt.txfail); - wstats->discard.misc = le32_to_cpu(cnt.rxrunt) + - le32_to_cpu(cnt.rxgiant); - wstats->miss.beacon = 0; - - WL_TRACE("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - le32_to_cpu(cnt.txframe), le32_to_cpu(cnt.txbyte)); - WL_TRACE("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", - le32_to_cpu(cnt.rxfrmtoolong)); - WL_TRACE("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", - le32_to_cpu(cnt.rxbadplcp)); - WL_TRACE("wl_iw_get_wireless_stats counters rxundec=%d\n", - le32_to_cpu(cnt.rxundec)); - WL_TRACE("wl_iw_get_wireless_stats counters rxfragerr=%d\n", - le32_to_cpu(cnt.rxfragerr)); - WL_TRACE("wl_iw_get_wireless_stats counters txfail=%d\n", - le32_to_cpu(cnt.txfail)); - WL_TRACE("wl_iw_get_wireless_stats counters rxrunt=%d\n", - le32_to_cpu(cnt.rxrunt)); - WL_TRACE("wl_iw_get_wireless_stats counters rxgiant=%d\n", - le32_to_cpu(cnt.rxgiant)); -#endif /* WIRELESS_EXT > 11 */ - -done: - return res; -} - int wl_iw_attach(struct net_device *dev, void *dhdp) { int params_size; @@ -3672,8 +3574,10 @@ int wl_iw_attach(struct net_device *dev, void *dhdp) return -ENOMEM; iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) + if (!iscan->iscan_ex_params_p) { + kfree(iscan); return -ENOMEM; + } iscan->iscan_ex_param_size = params_size; iscan->sysioc_tsk = NULL; @@ -3742,3 +3646,50 @@ void wl_iw_detach(void) g_scan = NULL; } + +#if defined(BCMDBG) +void osl_assert(char *exp, char *file, int line) +{ + char tempbuf[256]; + char *basename; + + basename = strrchr(file, '/'); + /* skip the '/' */ + if (basename) + basename++; + + if (!basename) + basename = file; + + snprintf(tempbuf, 256, + "assertion \"%s\" failed: file \"%s\", line %d\n", exp, + basename, line); + + /* + * Print assert message and give it time to + * be written to /var/log/messages + */ + if (!in_interrupt()) { + const int delay = 3; + printk(KERN_ERR "%s", tempbuf); + printk(KERN_ERR "panic in %d seconds\n", delay); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(delay * HZ); + } + + switch (g_assert_type) { + case 0: + panic(KERN_ERR "%s", tempbuf); + break; + case 1: + printk(KERN_ERR "%s", tempbuf); + BUG(); + break; + case 2: + printk(KERN_ERR "%s", tempbuf); + break; + default: + break; + } +} +#endif /* defined(BCMDBG) */ diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index c4aafe5cf7f5..8d75fe19ca9a 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -25,7 +25,6 @@ ccflags-y := \ -DBCMNVRAMR \ -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ - -Idrivers/staging/brcm80211/util \ -Idrivers/staging/brcm80211/include BRCMSMAC_OFILES := \ @@ -38,26 +37,23 @@ BRCMSMAC_OFILES := \ wlc_channel.o \ wlc_main.o \ wlc_phy_shim.o \ + wlc_pmu.o \ wlc_rate.o \ wlc_stf.o \ + aiutils.o \ phy/wlc_phy_cmn.o \ phy/wlc_phy_lcn.o \ phy/wlc_phy_n.o \ phy/wlc_phytbl_lcn.o \ phy/wlc_phytbl_n.o \ - ../util/aiutils.o \ - ../util/siutils.o \ - ../util/bcmutils.o \ - ../util/bcmwifi.o \ - ../util/bcmotp.o \ - ../util/bcmsrom.o \ - ../util/hnddma.o \ - ../util/hndpmu.o \ - ../util/nicpci.o \ - ../util/qmath.o \ - ../util/nvram/nvram_ro.o + phy/wlc_phy_qmath.o \ + bcmotp.o \ + bcmsrom.o \ + hnddma.o \ + nicpci.o \ + nvram.o MODULEPFX := brcmsmac -obj-m += $(MODULEPFX).o +obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o $(MODULEPFX)-objs = $(BRCMSMAC_OFILES) diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c index 6ebd7f58af81..a61185f70a7c 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c @@ -21,57 +21,533 @@ #include <linux/module.h> #include <linux/pci.h> #include <bcmutils.h> -#include <siutils.h> -#include <bcmdevs.h> +#include <aiutils.h> #include <hndsoc.h> #include <sbchipc.h> +#include <pcicfg.h> +#include <bcmdevs.h> + +/* ********** from siutils.c *********** */ #include <pci_core.h> #include <pcie_core.h> #include <nicpci.h> #include <bcmnvram.h> #include <bcmsrom.h> -#include <pcicfg.h> -#include <sbsocram.h> -#ifdef BCMSDIO -#include <bcmsdh.h> -#include <sdio.h> -#include <sbsdio.h> -#include <sbhnddma.h> -#include <sbsdpcmdev.h> -#include <bcmsdpcm.h> -#endif /* BCMSDIO */ -#include <hndpmu.h> - -/* this file now contains only definitions for sb functions, only necessary -*for devices using Sonics backplanes (bcm4329) -*/ +#include <wlc_pmu.h> + +#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ + (sih->chiprev == 0) && \ + (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) + +/* EROM parsing */ + +static u32 +get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) +{ + u32 ent; + uint inv = 0, nom = 0; + + while (true) { + ent = R_REG(*eromptr); + (*eromptr)++; + + if (mask == 0) + break; + + if ((ent & ER_VALID) == 0) { + inv++; + continue; + } + + if (ent == (ER_END | ER_VALID)) + break; + + if ((ent & mask) == match) + break; + + nom++; + } + + SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent)); + if (inv + nom) { + SI_VMSG((" after %d invalid and %d non-matching entries\n", + inv, nom)); + } + return ent; +} + +static u32 +get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st, + u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh) +{ + u32 asd, sz, szd; + + asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); + if (((asd & ER_TAG1) != ER_ADD) || + (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || + ((asd & AD_ST_MASK) != st)) { + /* This is not what we want, "push" it back */ + (*eromptr)--; + return 0; + } + *addrl = asd & AD_ADDR_MASK; + if (asd & AD_AG32) + *addrh = get_erom_ent(sih, eromptr, 0, 0); + else + *addrh = 0; + *sizeh = 0; + sz = asd & AD_SZ_MASK; + if (sz == AD_SZ_SZD) { + szd = get_erom_ent(sih, eromptr, 0, 0); + *sizel = szd & SD_SZ_MASK; + if (szd & SD_SG32) + *sizeh = get_erom_ent(sih, eromptr, 0, 0); + } else + *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); + + SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", + sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); + + return asd; +} + +static void ai_hwfixup(si_info_t *sii) +{ +} + +/* parse the enumeration rom to identify all cores */ +void ai_scan(si_t *sih, void *regs, uint devid) +{ + si_info_t *sii = SI_INFO(sih); + chipcregs_t *cc = (chipcregs_t *) regs; + u32 erombase, *eromptr, *eromlim; -/* if an amba SDIO device is supported, please further restrict the inclusion - * of this file + erombase = R_REG(&cc->eromptr); + + switch (sih->bustype) { + case SI_BUS: + eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE); + break; + + case PCI_BUS: + /* Set wrappers address */ + sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE); + + /* Now point the window at the erom */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase); + eromptr = regs; + break; + + case SPI_BUS: + case SDIO_BUS: + eromptr = (u32 *)(unsigned long)erombase; + break; + + default: + SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", + sih->bustype)); + return; + } + eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32)); + + SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim)); + while (eromptr < eromlim) { + u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; + u32 mpd, asd, addrl, addrh, sizel, sizeh; + u32 *base; + uint i, j, idx; + bool br; + + br = false; + + /* Grok a component */ + cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); + if (cia == (ER_END | ER_VALID)) { + SI_VMSG(("Found END of erom after %d cores\n", + sii->numcores)); + ai_hwfixup(sii); + return; + } + base = eromptr - 1; + cib = get_erom_ent(sih, &eromptr, 0, 0); + + if ((cib & ER_TAG) != ER_CI) { + SI_ERROR(("CIA not followed by CIB\n")); + goto error; + } + + cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; + mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; + crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; + nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; + nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; + nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; + nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; + + SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp)); + + if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) + continue; + if ((nmw + nsw == 0)) { + /* A component which is not a core */ + if (cid == OOB_ROUTER_CORE_ID) { + asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, + &addrl, &addrh, &sizel, &sizeh); + if (asd != 0) { + sii->oob_router = addrl; + } + } + continue; + } + + idx = sii->numcores; +/* sii->eromptr[idx] = base; */ + sii->cia[idx] = cia; + sii->cib[idx] = cib; + sii->coreid[idx] = cid; + + for (i = 0; i < nmp; i++) { + mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); + if ((mpd & ER_TAG) != ER_MP) { + SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); + goto error; + } + SI_VMSG((" Master port %d, mp: %d id: %d\n", i, + (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, + (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); + } + + /* First Slave Address Descriptor should be port 0: + * the main register space for the core + */ + asd = + get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, + &sizel, &sizeh); + if (asd == 0) { + /* Try again to see if it is a bridge */ + asd = + get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, + &addrh, &sizel, &sizeh); + if (asd != 0) + br = true; + else if ((addrh != 0) || (sizeh != 0) + || (sizel != SI_CORE_SIZE)) { + SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd)); + goto error; + } + } + sii->coresba[idx] = addrl; + sii->coresba_size[idx] = sizel; + /* Get any more ASDs in port 0 */ + j = 1; + do { + asd = + get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, + &addrh, &sizel, &sizeh); + if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { + sii->coresba2[idx] = addrl; + sii->coresba2_size[idx] = sizel; + } + j++; + } while (asd != 0); + + /* Go through the ASDs for other slave ports */ + for (i = 1; i < nsp; i++) { + j = 0; + do { + asd = + get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, + &addrl, &addrh, &sizel, &sizeh); + } while (asd != 0); + if (j == 0) { + SI_ERROR((" SP %d has no address descriptors\n", + i)); + goto error; + } + } + + /* Now get master wrappers */ + for (i = 0; i < nmw; i++) { + asd = + get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, + &addrh, &sizel, &sizeh); + if (asd == 0) { + SI_ERROR(("Missing descriptor for MW %d\n", i)); + goto error; + } + if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { + SI_ERROR(("Master wrapper %d is not 4KB\n", i)); + goto error; + } + if (i == 0) + sii->wrapba[idx] = addrl; + } + + /* And finally slave wrappers */ + for (i = 0; i < nsw; i++) { + uint fwp = (nsp == 1) ? 0 : 1; + asd = + get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, + &addrl, &addrh, &sizel, &sizeh); + if (asd == 0) { + SI_ERROR(("Missing descriptor for SW %d\n", i)); + goto error; + } + if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { + SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); + goto error; + } + if ((nmw == 0) && (i == 0)) + sii->wrapba[idx] = addrl; + } + + /* Don't record bridges */ + if (br) + continue; + + /* Done with core */ + sii->numcores++; + } + + SI_ERROR(("Reached end of erom without finding END")); + + error: + sii->numcores = 0; + return; +} + +/* This function changes the logical "focus" to the indicated core. + * Return the current core's virtual address. */ -#ifdef BCMSDIO -#include "siutils_priv.h" -#endif +void *ai_setcoreidx(si_t *sih, uint coreidx) +{ + si_info_t *sii = SI_INFO(sih); + u32 addr = sii->coresba[coreidx]; + u32 wrap = sii->wrapba[coreidx]; + void *regs; + + if (coreidx >= sii->numcores) + return NULL; + + switch (sih->bustype) { + case SI_BUS: + /* map new one */ + if (!sii->regs[coreidx]) { + sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); + } + sii->curmap = regs = sii->regs[coreidx]; + if (!sii->wrappers[coreidx]) { + sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); + } + sii->curwrap = sii->wrappers[coreidx]; + break; + + case PCI_BUS: + /* point bar0 window */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr); + regs = sii->curmap; + /* point bar0 2nd 4KB window */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap); + break; + + case SPI_BUS: + case SDIO_BUS: + sii->curmap = regs = (void *)(unsigned long)addr; + sii->curwrap = (void *)(unsigned long)wrap; + break; + + default: + regs = NULL; + break; + } + + sii->curmap = regs; + sii->curidx = coreidx; + + return regs; +} + +/* Return the number of address spaces in current core */ +int ai_numaddrspaces(si_t *sih) +{ + return 2; +} + +/* Return the address of the nth address space in the current core */ +u32 ai_addrspace(si_t *sih, uint asidx) +{ + si_info_t *sii; + uint cidx; + + sii = SI_INFO(sih); + cidx = sii->curidx; + + if (asidx == 0) + return sii->coresba[cidx]; + else if (asidx == 1) + return sii->coresba2[cidx]; + else { + SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); + return 0; + } +} + +/* Return the size of the nth address space in the current core */ +u32 ai_addrspacesize(si_t *sih, uint asidx) +{ + si_info_t *sii; + uint cidx; + + sii = SI_INFO(sih); + cidx = sii->curidx; + if (asidx == 0) + return sii->coresba_size[cidx]; + else if (asidx == 1) + return sii->coresba2_size[cidx]; + else { + SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); + return 0; + } +} + +uint ai_flag(si_t *sih) +{ + si_info_t *sii; + aidmp_t *ai; + + sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__)); + return sii->curidx; + } + ai = sii->curwrap; + + return R_REG(&ai->oobselouta30) & 0x1f; +} + +void ai_setint(si_t *sih, int siflag) +{ +} + +uint ai_corevendor(si_t *sih) +{ + si_info_t *sii; + u32 cia; + + sii = SI_INFO(sih); + cia = sii->cia[sii->curidx]; + return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; +} + +uint ai_corerev(si_t *sih) +{ + si_info_t *sii; + u32 cib; + + sii = SI_INFO(sih); + cib = sii->cib[sii->curidx]; + return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; +} + +bool ai_iscoreup(si_t *sih) +{ + si_info_t *sii; + aidmp_t *ai; + + sii = SI_INFO(sih); + ai = sii->curwrap; + + return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == + SICF_CLOCK_EN) + && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0)); +} + +void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) +{ + si_info_t *sii; + aidmp_t *ai; + u32 w; + + sii = SI_INFO(sih); + + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", + __func__)); + return; + } + + ai = sii->curwrap; + + if (mask || val) { + w = ((R_REG(&ai->ioctrl) & ~mask) | val); + W_REG(&ai->ioctrl, w); + } +} + +u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) +{ + si_info_t *sii; + aidmp_t *ai; + u32 w; + + sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", + __func__)); + return 0; + } + + ai = sii->curwrap; + + if (mask || val) { + w = ((R_REG(&ai->ioctrl) & ~mask) | val); + W_REG(&ai->ioctrl, w); + } + + return R_REG(&ai->ioctrl); +} + +u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) +{ + si_info_t *sii; + aidmp_t *ai; + u32 w; + + sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__)); + return 0; + } + + ai = sii->curwrap; + + if (mask || val) { + w = ((R_REG(&ai->iostatus) & ~mask) | val); + W_REG(&ai->iostatus, w); + } + + return R_REG(&ai->iostatus); +} + +/* *************** from siutils.c ************** */ /* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, +static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *sdh, char **vars, uint *varsz); -static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, +static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); -static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, +static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, u32 savewin, uint *origidx, void *regs); -static void si_nvram_process(si_info_t *sii, char *pvars); +static void ai_nvram_process(si_info_t *sii, char *pvars); /* dev path concatenation util */ -static char *si_devpathvar(si_t *sih, char *var, int len, const char *name); -static bool _si_clkctl_cc(si_info_t *sii, uint mode); -static bool si_ispcie(si_info_t *sii); -static uint socram_banksize(si_info_t *sii, sbsocramregs_t *r, - u8 idx, u8 mtype); +static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name); +static bool _ai_clkctl_cc(si_info_t *sii, uint mode); +static bool ai_ispcie(si_info_t *sii); /* global variable to indicate reservation/release of gpio's */ -static u32 si_gpioreservation; +static u32 ai_gpioreservation; /* * Allocate a si handle. @@ -82,7 +558,7 @@ static u32 si_gpioreservation; * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -si_t *si_attach(uint devid, void *regs, uint bustype, +si_t *ai_attach(uint devid, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { si_info_t *sii; @@ -94,7 +570,7 @@ si_t *si_attach(uint devid, void *regs, uint bustype, return NULL; } - if (si_doattach(sii, devid, regs, bustype, sdh, vars, varsz) == + if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) == NULL) { kfree(sii); return NULL; @@ -108,74 +584,26 @@ si_t *si_attach(uint devid, void *regs, uint bustype, /* global kernel resource */ static si_info_t ksii; -static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, +static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) { - -#ifndef BRCM_FULLMAC /* kludge to enable the clock on the 4306 which lacks a slowclock */ - if (bustype == PCI_BUS && !si_ispcie(sii)) - si_clkctl_xtal(&sii->pub, XTAL | PLL, ON); -#endif - -#if defined(BCMSDIO) - if (bustype == SDIO_BUS) { - int err; - u8 clkset; - - /* Try forcing SDIO core to do ALPAvail request only */ - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); - if (!err) { - u8 clkval; - - /* If register supported, wait for ALPAvail and then force ALP */ - clkval = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, NULL); - if ((clkval & ~SBSDIO_AVBITS) == clkset) { - SPINWAIT(((clkval = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, - NULL)), - !SBSDIO_ALPAV(clkval)), - PMU_MAX_TRANSITION_DLY); - if (!SBSDIO_ALPAV(clkval)) { - SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval)); - return false; - } - clkset = - SBSDIO_FORCE_HW_CLKREQ_OFF | - SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); - udelay(65); - } - } - - /* Also, disable the extra SDIO pull-ups */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, - NULL); - } -#endif /* defined(BCMSDIO) */ - + if (bustype == PCI_BUS && !ai_ispcie(sii)) + ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON); return true; } -static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, +static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, u32 savewin, uint *origidx, void *regs) { bool pci, pcie; uint i; uint pciidx, pcieidx, pcirev, pcierev; - cc = si_setcoreidx(&sii->pub, SI_CC_IDX); - ASSERT(cc); + cc = ai_setcoreidx(&sii->pub, SI_CC_IDX); /* get chipcommon rev */ - sii->pub.ccrev = (int)si_corerev(&sii->pub); + sii->pub.ccrev = (int)ai_corerev(&sii->pub); /* get chipcommon chipstatus */ if (sii->pub.ccrev >= 11) @@ -185,22 +613,15 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, sii->pub.cccaps = R_REG(&cc->capabilities); /* get chipcommon extended capabilities */ -#ifndef BRCM_FULLMAC if (sii->pub.ccrev >= 35) sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext); -#endif + /* get pmu rev and caps */ if (sii->pub.cccaps & CC_CAP_PMU) { sii->pub.pmucaps = R_REG(&cc->pmucapabilities); sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; } - /* - SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", - sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, - sii->pub.pmucaps)); - */ - /* figure out bus/orignal core idx */ sii->pub.buscoretype = NODEV_CORE_ID; sii->pub.buscorerev = NOREV; @@ -213,9 +634,9 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, for (i = 0; i < sii->numcores; i++) { uint cid, crev; - si_setcoreidx(&sii->pub, i); - cid = si_coreid(&sii->pub); - crev = si_corerev(&sii->pub); + ai_setcoreidx(&sii->pub, i); + cid = ai_coreid(&sii->pub); + crev = ai_corerev(&sii->pub); /* Display cores found */ SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", @@ -232,15 +653,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, pcie = true; } } -#ifdef BCMSDIO - else if (((bustype == SDIO_BUS) || - (bustype == SPI_BUS)) && - ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) { - sii->pub.buscorerev = crev; - sii->pub.buscoretype = cid; - sii->pub.buscoreidx = i; - } -#endif /* BCMSDIO */ /* find the core idx before entering this func. */ if ((savewin && (savewin == sii->coresba[i])) || @@ -248,22 +660,8 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, *origidx = i; } -#ifdef BRCM_FULLMAC - SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, - sii->pub.buscoretype, sii->pub.buscorerev)); - - /* Make sure any on-chip ARM is off (in case strapping is wrong), - * or downloaded code was - * already running. - */ - if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { - if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || - si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) - si_core_disable(&sii->pub, 0); - } -#else if (pci && pcie) { - if (si_ispcie(sii)) + if (ai_ispcie(sii)) pci = false; else pcie = false; @@ -292,19 +690,19 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, return false; } } - if (si_pci_fixcfg(&sii->pub)) { - SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n")); + if (ai_pci_fixcfg(&sii->pub)) { + SI_ERROR(("si_doattach: si_pci_fixcfg failed\n")); return false; } } -#endif + /* return to the original core */ - si_setcoreidx(&sii->pub, *origidx); + ai_setcoreidx(&sii->pub, *origidx); return true; } -static __used void si_nvram_process(si_info_t *sii, char *pvars) +static __used void ai_nvram_process(si_info_t *sii, char *pvars) { uint w = 0; @@ -312,39 +710,31 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) switch (sii->pub.bustype) { case PCI_BUS: /* do a pci config read to get subsystem id and subvendor id */ - pci_read_config_dword(sii->pbus, PCI_CFG_SVID, &w); + pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w); /* Let nvram variables override subsystem Vend/ID */ - sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub, + sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub, "boardvendor"); if (sii->pub.boardvendor == 0) sii->pub.boardvendor = w & 0xffff; else - SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff)); - sii->pub.boardtype = (u16)si_getdevpathintvar(&sii->pub, + SI_ERROR(("Overriding boardvendor: 0x%x instead of " + "0x%x\n", sii->pub.boardvendor, w & 0xffff)); + sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub, "boardtype"); if (sii->pub.boardtype == 0) sii->pub.boardtype = (w >> 16) & 0xffff; else - SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff)); + SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n" + , sii->pub.boardtype, (w >> 16) & 0xffff)); break; -#ifdef BCMSDIO - case SDIO_BUS: -#endif sii->pub.boardvendor = getintvar(pvars, "manfid"); sii->pub.boardtype = getintvar(pvars, "prodid"); break; -#ifdef BCMSDIO - case SPI_BUS: - sii->pub.boardvendor = VENDOR_BROADCOM; - sii->pub.boardtype = SPI_BOARD; - break; -#endif - case SI_BUS: case JTAG_BUS: - sii->pub.boardvendor = VENDOR_BROADCOM; + sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; sii->pub.boardtype = getintvar(pvars, "prodid"); if (pvars == NULL || (sii->pub.boardtype == 0)) { sii->pub.boardtype = getintvar(NULL, "boardtype"); @@ -356,16 +746,12 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) if (sii->pub.boardtype == 0) { SI_ERROR(("si_doattach: unknown board type\n")); - ASSERT(sii->pub.boardtype); } sii->pub.boardflags = getintvar(pvars, "boardflags"); } -/* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */ -/* this has been customized for the bcm 4329 ONLY */ -#ifdef BCMSDIO -static si_info_t *si_doattach(si_info_t *sii, uint devid, +static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { @@ -373,139 +759,9 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, u32 w, savewin; chipcregs_t *cc; char *pvars = NULL; + uint socitype; uint origidx; - ASSERT(GOODREGS(regs)); - - memset((unsigned char *) sii, 0, sizeof(si_info_t)); - - savewin = 0; - - sih->buscoreidx = BADIDX; - - sii->curmap = regs; - sii->pbus = pbus; - - /* find Chipcommon address */ - cc = (chipcregs_t *) sii->curmap; - sih->bustype = bustype; - - /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, pbus)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", - bustype)); - return NULL; - } - - /* ChipID recognition. - * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. - */ - w = R_REG(&cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - /* Might as wll fill in chip id rev & pkg */ - sih->chip = w & CID_ID_MASK; - sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; - sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - - if ((sih->chip == BCM4329_CHIP_ID) && - (sih->chippkg != BCM4329_289PIN_PKG_ID)) - sih->chippkg = BCM4329_182PIN_PKG_ID; - - sih->issim = IS_SIM(sih->chippkg); - - /* scan for cores */ - /* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */ - sb_scan(&sii->pub, regs, devid); - - /* no cores found, bail out */ - if (sii->numcores == 0) { - SI_ERROR(("si_doattach: could not find any cores\n")); - return NULL; - } - /* bus/core/clk setup */ - origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { - SI_ERROR(("si_doattach: si_buscore_setup failed\n")); - goto exit; - } - -#ifdef BRCM_FULLMAC - pvars = NULL; -#else - /* Init nvram from flash if it exists */ - nvram_init((void *)&(sii->pub)); - - /* Init nvram from sprom/otp if they exist */ - if (srom_var_init - (&sii->pub, bustype, regs, sii->osh, vars, varsz)) { - SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); - goto exit; - } - pvars = vars ? *vars : NULL; - si_nvram_process(sii, pvars); -#endif - - /* === NVRAM, clock is ready === */ - -#ifdef BRCM_FULLMAC - if (sii->pub.ccrev >= 20) { -#endif - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); - W_REG(&cc->gpiopullup, 0); - W_REG(&cc->gpiopulldown, 0); - sb_setcoreidx(sih, origidx); -#ifdef BRCM_FULLMAC - } -#endif - -#ifndef BRCM_FULLMAC - /* PMU specific initializations */ - if (PMUCTL_ENAB(sih)) { - u32 xtalfreq; - si_pmu_init(sih); - si_pmu_chip_init(sih); - xtalfreq = getintvar(pvars, "xtalfreq"); - /* If xtalfreq var not available, try to measure it */ - if (xtalfreq == 0) - xtalfreq = si_pmu_measure_alpclk(sih); - si_pmu_pll_init(sih, xtalfreq); - si_pmu_res_init(sih); - si_pmu_swreg_init(sih); - } - - /* setup the GPIO based LED powersave register */ - w = getintvar(pvars, "leddc"); - if (w == 0) - w = DEFAULT_GPIOTIMERVAL; - sb_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); - -#ifdef BCMDBG - /* clear any previous epidiag-induced target abort */ - sb_taclear(sih, false); -#endif /* BCMDBG */ -#endif - - return sii; - - exit: - return NULL; -} - -#else /* BCMSDIO */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, - void *regs, uint bustype, void *pbus, - char **vars, uint *varsz) -{ - struct si_pub *sih = &sii->pub; - u32 w, savewin; - chipcregs_t *cc; - char *pvars = NULL; - uint origidx; - - ASSERT(GOODREGS(regs)); - memset((unsigned char *) sii, 0, sizeof(si_info_t)); savewin = 0; @@ -541,19 +797,21 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, sih->bustype = bustype; /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, pbus)) { + if (!ai_buscore_prep(sii, bustype, devid, pbus)) { SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); return NULL; } - /* ChipID recognition. + /* + * ChipID recognition. * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. + * If we add other chiptypes (or if we need to support old sdio + * hosts w/o chipcommon), some way of recognizing them needs to + * be added here. */ w = R_REG(&cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; + socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; /* Might as wll fill in chip id rev & pkg */ sih->chip = w & CID_ID_MASK; sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; @@ -562,7 +820,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, sih->issim = IS_SIM(sih->chippkg); /* scan for cores */ - if (sii->pub.socitype == SOCI_AI) { + if (socitype == SOCI_AI) { SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ ai_scan(&sii->pub, (void *)cc, devid); @@ -577,7 +835,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, } /* bus/core/clk setup */ origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { + if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { SI_ERROR(("si_doattach: si_buscore_setup failed\n")); goto exit; } @@ -602,7 +860,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, } /* Init nvram from flash if it exists */ - nvram_init((void *)&(sii->pub)); + nvram_init(); /* Init nvram from sprom/otp if they exist */ if (srom_var_init @@ -611,13 +869,13 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, goto exit; } pvars = vars ? *vars : NULL; - si_nvram_process(sii, pvars); + ai_nvram_process(sii, pvars); /* === NVRAM, clock is ready === */ - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); W_REG(&cc->gpiopullup, 0); W_REG(&cc->gpiopulldown, 0); - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); /* PMU specific initializations */ if (PMUCTL_ENAB(sih)) { @@ -637,19 +895,21 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, w = getintvar(pvars, "leddc"); if (w == 0) w = DEFAULT_GPIOTIMERVAL; - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); if (PCIE(sii)) { - ASSERT(sii->pch != NULL); pcicore_attach(sii->pch, pvars, SI_DOATTACH); } if ((sih->chip == BCM43224_CHIP_ID) || (sih->chip == BCM43421_CHIP_ID)) { - /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */ + /* + * enable 12 mA drive strenth for 43224 and + * set chipControl register bit 15 + */ if (sih->chiprev == 0) { SI_MSG(("Applying 43224A0 WARs\n")); - si_corereg(sih, SI_CC_IDX, + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), CCTRL43224_GPIO_TOGGLE, CCTRL43224_GPIO_TOGGLE); @@ -664,7 +924,10 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, } if (sih->chip == BCM4313_CHIP_ID) { - /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */ + /* + * enable 12 mA drive strenth for 4313 and + * set chipControl register bit 1 + */ SI_MSG(("Applying 4313 WARs\n")); si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, CCTRL_4313_12MA_LED_DRIVE); @@ -672,7 +935,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, if (sih->chip == BCM4331_CHIP_ID) { /* Enable Ext PA lines depending on chip package option */ - si_chipcontrl_epa4331(sih, true); + ai_chipcontrl_epa4331(sih, true); } return sii; @@ -685,16 +948,15 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, return NULL; } -#endif /* BCMSDIO */ /* may be called with core in reset */ -void si_detach(si_t *sih) +void ai_detach(si_t *sih) { si_info_t *sii; uint idx; struct si_pub *si_local = NULL; - memcpy(&si_local, &sih, sizeof(si_t **)); + bcopy(&sih, &si_local, sizeof(si_t **)); sii = SI_INFO(sih); @@ -708,24 +970,21 @@ void si_detach(si_t *sih) sii->regs[idx] = NULL; } -#ifndef BRCM_FULLMAC - nvram_exit((void *)si_local); /* free up nvram buffers */ + nvram_exit(); /* free up nvram buffers */ if (sih->bustype == PCI_BUS) { if (sii->pch) pcicore_deinit(sii->pch); sii->pch = NULL; } -#endif -#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) + if (sii != &ksii) -#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ kfree(sii); } /* register driver interrupt disabling and restoring callback functions */ void -si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, +ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) { si_info_t *sii; @@ -741,7 +1000,7 @@ si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, sii->dev_coreid = sii->coreid[sii->curidx]; } -void si_deregister_intr_callback(si_t *sih) +void ai_deregister_intr_callback(si_t *sih) { si_info_t *sii; @@ -749,35 +1008,15 @@ void si_deregister_intr_callback(si_t *sih) sii->intrsoff_fn = NULL; } -uint si_flag(si_t *sih) -{ - if (sih->socitype == SOCI_AI) - return ai_flag(sih); - else { - ASSERT(0); - return 0; - } -} - -void si_setint(si_t *sih, int siflag) -{ - if (sih->socitype == SOCI_AI) - ai_setint(sih, siflag); - else - ASSERT(0); -} - -#ifndef BCMSDIO -uint si_coreid(si_t *sih) +uint ai_coreid(si_t *sih) { si_info_t *sii; sii = SI_INFO(sih); return sii->coreid[sii->curidx]; } -#endif -uint si_coreidx(si_t *sih) +uint ai_coreidx(si_t *sih) { si_info_t *sii; @@ -785,25 +1024,13 @@ uint si_coreidx(si_t *sih) return sii->curidx; } -bool si_backplane64(si_t *sih) +bool ai_backplane64(si_t *sih) { return (sih->cccaps & CC_CAP_BKPLN64) != 0; } -#ifndef BCMSDIO -uint si_corerev(si_t *sih) -{ - if (sih->socitype == SOCI_AI) - return ai_corerev(sih); - else { - ASSERT(0); - return 0; - } -} -#endif - /* return index of coreid or BADIDX if not found */ -uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit) +uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit) { si_info_t *sii; uint found; @@ -826,42 +1053,22 @@ uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit) /* * This function changes logical "focus" to the indicated core; * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core + * Moreover, callers should keep interrupts off during switching + * out of and back to d11 core. */ -void *si_setcore(si_t *sih, uint coreid, uint coreunit) +void *ai_setcore(si_t *sih, uint coreid, uint coreunit) { uint idx; - idx = si_findcoreidx(sih, coreid, coreunit); + idx = ai_findcoreidx(sih, coreid, coreunit); if (!GOODIDX(idx)) return NULL; - if (sih->socitype == SOCI_AI) - return ai_setcoreidx(sih, idx); - else { -#ifdef BCMSDIO - return sb_setcoreidx(sih, idx); -#else - ASSERT(0); - return NULL; -#endif - } -} - -#ifndef BCMSDIO -void *si_setcoreidx(si_t *sih, uint coreidx) -{ - if (sih->socitype == SOCI_AI) - return ai_setcoreidx(sih, coreidx); - else { - ASSERT(0); - return NULL; - } + return ai_setcoreidx(sih, idx); } -#endif -/* Turn off interrupt as required by sb_setcore, before switch core */ -void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) +/* Turn off interrupt as required by ai_setcore, before switch core */ +void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) { void *cc; si_info_t *sii; @@ -881,14 +1088,12 @@ void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) } INTR_OFF(sii, *intr_val); *origidx = sii->curidx; - cc = si_setcore(sih, coreid, 0); - ASSERT(cc != NULL); - + cc = ai_setcore(sih, coreid, 0); return cc; } /* restore coreidx and restore interrupt */ -void si_restore_core(si_t *sih, uint coreid, uint intr_val) +void ai_restore_core(si_t *sih, uint coreid, uint intr_val) { si_info_t *sii; @@ -897,183 +1102,173 @@ void si_restore_core(si_t *sih, uint coreid, uint intr_val) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) return; - si_setcoreidx(sih, coreid); + ai_setcoreidx(sih, coreid); INTR_RESTORE(sii, intr_val); } -u32 si_core_cflags(si_t *sih, u32 mask, u32 val) +void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val) { - if (sih->socitype == SOCI_AI) - return ai_core_cflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } + si_info_t *sii = SI_INFO(sih); + u32 *w = (u32 *) sii->curwrap; + W_REG(w + (offset / 4), val); + return; } -u32 si_core_sflags(si_t *sih, u32 mask, u32 val) +/* + * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set + * operation, switch back to the original core, and return the new value. + * + * When using the silicon backplane, no fiddling with interrupts or core + * switches is needed. + * + * Also, when using pci/pcie, we can optimize away the core switching for pci + * registers and (on newer pci cores) chipcommon registers. + */ +uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) { - if (sih->socitype == SOCI_AI) - return ai_core_sflags(sih, mask, val); - else { - ASSERT(0); + uint origidx = 0; + u32 *r = NULL; + uint w; + uint intr_val = 0; + bool fast = false; + si_info_t *sii; + + sii = SI_INFO(sih); + + if (coreidx >= SI_MAXCORES) return 0; - } -} -bool si_iscoreup(si_t *sih) -{ - if (sih->socitype == SOCI_AI) - return ai_iscoreup(sih); - else { -#ifdef BCMSDIO - return sb_iscoreup(sih); -#else - ASSERT(0); - return false; -#endif + if (sih->bustype == SI_BUS) { + /* If internal bus, we can always get at everything */ + fast = true; + /* map if does not exist */ + if (!sii->regs[coreidx]) { + sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], + SI_CORE_SIZE); + } + r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff); + } else if (sih->bustype == PCI_BUS) { + /* + * If pci/pcie, we can get at pci/pcie regs + * and on newer cores to chipc + */ + if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { + /* Chipc registers are mapped at 12KB */ + + fast = true; + r = (u32 *) ((char *)sii->curmap + + PCI_16KB0_CCREGS_OFFSET + regoff); + } else if (sii->pub.buscoreidx == coreidx) { + /* + * pci registers are at either in the last 2KB of + * an 8KB window or, in pcie and pci rev 13 at 8KB + */ + fast = true; + if (SI_FAST(sii)) + r = (u32 *) ((char *)sii->curmap + + PCI_16KB0_PCIREGS_OFFSET + + regoff); + else + r = (u32 *) ((char *)sii->curmap + + ((regoff >= SBCONFIGOFF) ? + PCI_BAR0_PCISBR_OFFSET : + PCI_BAR0_PCIREGS_OFFSET) + + regoff); + } } -} -void si_write_wrapperreg(si_t *sih, u32 offset, u32 val) -{ - /* only for 4319, no requirement for SOCI_SB */ - if (sih->socitype == SOCI_AI) { - ai_write_wrap_reg(sih, offset, val); - } -} + if (!fast) { + INTR_OFF(sii, intr_val); -uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ + /* save current core index */ + origidx = ai_coreidx(&sii->pub); - if (sih->socitype == SOCI_AI) - return ai_corereg(sih, coreidx, regoff, mask, val); - else { -#ifdef BCMSDIO - return sb_corereg(sih, coreidx, regoff, mask, val); -#else - ASSERT(0); - return 0; -#endif + /* switch core */ + r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx) + + regoff); } -} -void si_core_disable(si_t *sih, u32 bits) -{ + /* mask and set */ + if (mask || val) { + w = (R_REG(r) & ~mask) | val; + W_REG(r, w); + } - if (sih->socitype == SOCI_AI) - ai_core_disable(sih, bits); -#ifdef BCMSDIO - else - sb_core_disable(sih, bits); -#endif -} + /* readback */ + w = R_REG(r); -void si_core_reset(si_t *sih, u32 bits, u32 resetbits) -{ - if (sih->socitype == SOCI_AI) - ai_core_reset(sih, bits, resetbits); -#ifdef BCMSDIO - else - sb_core_reset(sih, bits, resetbits); -#endif -} + if (!fast) { + /* restore core index */ + if (origidx != coreidx) + ai_setcoreidx(&sii->pub, origidx); -u32 si_alp_clock(si_t *sih) -{ - if (PMUCTL_ENAB(sih)) - return si_pmu_alp_clock(sih); + INTR_RESTORE(sii, intr_val); + } - return ALP_CLOCK; + return w; } -u32 si_ilp_clock(si_t *sih) +void ai_core_disable(si_t *sih, u32 bits) { - if (PMUCTL_ENAB(sih)) - return si_pmu_ilp_clock(sih); - - return ILP_CLOCK; -} + si_info_t *sii; + u32 dummy; + aidmp_t *ai; -/* set chip watchdog reset timer to fire in 'ticks' */ -#ifdef BRCM_FULLMAC -void -si_watchdog(si_t *sih, uint ticks) -{ - if (PMUCTL_ENAB(sih)) { + sii = SI_INFO(sih); - if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) && - (ticks != 0)) { - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, - clk_ctl_st), ~0, 0x2); - si_setcore(sih, USB20D_CORE_ID, 0); - si_core_disable(sih, 1); - si_setcore(sih, CC_CORE_ID, 0); - } + ai = sii->curwrap; - if (ticks == 1) - ticks = 2; - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog), - ~0, ticks); - } else { - /* instant NMI */ - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), - ~0, ticks); - } -} -#else -void si_watchdog(si_t *sih, uint ticks) -{ - uint nb, maxt; + /* if core is already in reset, just return */ + if (R_REG(&ai->resetctrl) & AIRC_RESET) + return; - if (PMUCTL_ENAB(sih)) { + W_REG(&ai->ioctrl, bits); + dummy = R_REG(&ai->ioctrl); + udelay(10); - if ((sih->chip == BCM4319_CHIP_ID) && - (sih->chiprev == 0) && (ticks != 0)) { - si_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, clk_ctl_st), ~0, 0x2); - si_setcore(sih, USB20D_CORE_ID, 0); - si_core_disable(sih, 1); - si_setcore(sih, CC_CORE_ID, 0); - } + W_REG(&ai->resetctrl, AIRC_RESET); + udelay(1); +} - nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); - /* The mips compiler uses the sllv instruction, - * so we specially handle the 32-bit case. - */ - if (nb == 32) - maxt = 0xffffffff; - else - maxt = ((1 << nb) - 1); +/* reset and re-enable a core + * inputs: + * bits - core specific bits that are set during and after reset sequence + * resetbits - core specific bits that are set only during reset sequence + */ +void ai_core_reset(si_t *sih, u32 bits, u32 resetbits) +{ + si_info_t *sii; + aidmp_t *ai; + u32 dummy; - if (ticks == 1) - ticks = 2; - else if (ticks > maxt) - ticks = maxt; + sii = SI_INFO(sih); + ai = sii->curwrap; - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog), - ~0, ticks); - } else { - /* make sure we come up in fast clock mode; or if clearing, clear clock */ - si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC); - maxt = (1 << 28) - 1; - if (ticks > maxt) - ticks = maxt; + /* + * Must do the disable sequence first to work + * for arbitrary current core state. + */ + ai_core_disable(sih, (bits | resetbits)); - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), ~0, - ticks); - } + /* + * Now do the initialization sequence. + */ + W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); + dummy = R_REG(&ai->ioctrl); + W_REG(&ai->resetctrl, 0); + udelay(1); + + W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN)); + dummy = R_REG(&ai->ioctrl); + udelay(1); } -#endif /* return the slow clock source - LPO, XTAL, or PCI */ -static uint si_slowclk_src(si_info_t *sii) +static uint ai_slowclk_src(si_info_t *sii) { chipcregs_t *cc; u32 val; - ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); - if (sii->pub.ccrev < 6) { if (sii->pub.bustype == PCI_BUS) { pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, @@ -1083,24 +1278,22 @@ static uint si_slowclk_src(si_info_t *sii) } return SCC_SS_XTAL; } else if (sii->pub.ccrev < 10) { - cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx); + cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx); return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; } else /* Insta-clock */ return SCC_SS_XTAL; } -/* return the ILP (slowclock) min or max frequency */ -static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) +/* +* return the ILP (slowclock) min or max frequency +* precondition: we've established the chip has dynamic clk control +*/ +static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) { u32 slowclk; uint div; - ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); - - /* shouldn't be here unless we've established the chip has dynamic clk control */ - ASSERT(R_REG(&cc->capabilities) & CC_CAP_PWR_CTL); - - slowclk = si_slowclk_src(sii); + slowclk = ai_slowclk_src(sii); if (sii->pub.ccrev < 6) { if (slowclk == SCC_SS_PCI) return max_freq ? (PCIMAXFREQ / 64) @@ -1120,8 +1313,6 @@ static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) else if (slowclk == SCC_SS_PCI) return max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div); - else - ASSERT(0); } else { /* Chipc rev 10 is InstaClock */ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; @@ -1131,7 +1322,7 @@ static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) return 0; } -static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs) +static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs) { chipcregs_t *cc = (chipcregs_t *) chipcregs; uint slowmaxfreq, pll_delay, slowclk; @@ -1139,17 +1330,19 @@ static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs) pll_delay = PLL_DELAY; - /* If the slow clock is not sourced by the xtal then add the xtal_on_delay - * since the xtal will also be powered down by dynamic clk control logic. + /* + * If the slow clock is not sourced by the xtal then + * add the xtal_on_delay since the xtal will also be + * powered down by dynamic clk control logic. */ - slowclk = si_slowclk_src(sii); + slowclk = ai_slowclk_src(sii); if (slowclk != SCC_SS_XTAL) pll_delay += XTAL_ON_DELAY; /* Starting with 4318 it is ILP that is used for the delays */ slowmaxfreq = - si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc); + ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc); pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; @@ -1159,7 +1352,7 @@ static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs) } /* initialize power control delay registers */ -void si_clkctl_init(si_t *sih) +void ai_clkctl_init(si_t *sih) { si_info_t *sii; uint origidx = 0; @@ -1173,7 +1366,7 @@ void si_clkctl_init(si_t *sih) fast = SI_FAST(sii); if (!fast) { origidx = sii->curidx; - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); if (cc == NULL) return; } else { @@ -1181,21 +1374,23 @@ void si_clkctl_init(si_t *sih) if (cc == NULL) return; } - ASSERT(cc != NULL); /* set all Instaclk chip ILP to 1 MHz */ if (sih->ccrev >= 10) SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); - si_clkctl_setdelay(sii, (void *)cc); + ai_clkctl_setdelay(sii, (void *)cc); if (!fast) - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); } -/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ -u16 si_clkctl_fast_pwrup_delay(si_t *sih) +/* + * return the value suitable for writing to the + * dot11 core FAST_PWRUP_DELAY register + */ +u16 ai_clkctl_fast_pwrup_delay(si_t *sih) { si_info_t *sii; uint origidx = 0; @@ -1221,7 +1416,7 @@ u16 si_clkctl_fast_pwrup_delay(si_t *sih) if (!fast) { origidx = sii->curidx; INTR_OFF(sii, intr_val); - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); if (cc == NULL) goto done; } else { @@ -1229,22 +1424,21 @@ u16 si_clkctl_fast_pwrup_delay(si_t *sih) if (cc == NULL) goto done; } - ASSERT(cc != NULL); - slowminfreq = si_slowclk_freq(sii, false, cc); + slowminfreq = ai_slowclk_freq(sii, false, cc); fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; done: if (!fast) { - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); INTR_RESTORE(sii, intr_val); } return fpdelay; } /* turn primary xtal and/or pll off/on */ -int si_clkctl_xtal(si_t *sih, uint what, bool on) +int ai_clkctl_xtal(si_t *sih, uint what, bool on) { si_info_t *sii; u32 in, out, outen; @@ -1253,11 +1447,6 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) switch (sih->bustype) { -#ifdef BCMSDIO - case SDIO_BUS: - return -1; -#endif /* BCMSDIO */ - case PCI_BUS: /* pcie core doesn't have any mapping to control the xtal pu */ if (PCIE(sii)) @@ -1319,14 +1508,14 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) } /* - * clock control policy function through chipcommon + * clock control policy function throught chipcommon * * set dynamic clk control mode (forceslow, forcefast, dynamic) * returns true if we are forcing fast clock * this is a wrapper over the next internal function * to allow flexible policy settings for outside caller */ -bool si_clkctl_cc(si_t *sih, uint mode) +bool ai_clkctl_cc(si_t *sih, uint mode) { si_info_t *sii; @@ -1339,11 +1528,11 @@ bool si_clkctl_cc(si_t *sih, uint mode) if (PCI_FORCEHT(sii)) return mode == CLK_FAST; - return _si_clkctl_cc(sii, mode); + return _ai_clkctl_cc(sii, mode); } /* clk control mechanism through chipcommon, no policy checking */ -static bool _si_clkctl_cc(si_info_t *sii, uint mode) +static bool _ai_clkctl_cc(si_info_t *sii, uint mode) { uint origidx = 0; chipcregs_t *cc; @@ -1355,25 +1544,21 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) if (sii->pub.ccrev < 6) return false; - /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */ - ASSERT(sii->pub.ccrev != 10); - if (!fast) { INTR_OFF(sii, intr_val); origidx = sii->curidx; if ((sii->pub.bustype == SI_BUS) && - si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && - (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) + ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) && + (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) goto done; - cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0); } else { cc = (chipcregs_t *) CCREGS_FAST(sii); if (cc == NULL) goto done; } - ASSERT(cc != NULL); if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20)) goto done; @@ -1381,8 +1566,11 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) switch (mode) { case CLK_FAST: /* FORCEHT, fast (pll) clock */ if (sii->pub.ccrev < 10) { - /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ - si_clkctl_xtal(&sii->pub, XTAL, ON); + /* + * don't forget to force xtal back + * on before we clear SCC_DYN_XTAL.. + */ + ai_clkctl_xtal(&sii->pub, XTAL, ON); SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); } else if (sii->pub.ccrev < 20) { @@ -1396,7 +1584,6 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) u32 htavail = CCS_HTAVAIL; SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail) == 0), PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG(&cc->clk_ctl_st) & htavail); } else { udelay(PLL_DELAY); } @@ -1410,9 +1597,12 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) scc |= SCC_XC; W_REG(&cc->slow_clk_ctl, scc); - /* for dynamic control, we have to release our xtal_pu "force on" */ + /* + * for dynamic control, we have to + * release our xtal_pu "force on" + */ if (scc & SCC_XC) - si_clkctl_xtal(&sii->pub, XTAL, OFF); + ai_clkctl_xtal(&sii->pub, XTAL, OFF); } else if (sii->pub.ccrev < 20) { /* Instaclock */ AND_REG(&cc->system_clk_ctl, ~SYCC_HR); @@ -1422,50 +1612,39 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) break; default: - ASSERT(0); + break; } done: if (!fast) { - si_setcoreidx(&sii->pub, origidx); + ai_setcoreidx(&sii->pub, origidx); INTR_RESTORE(sii, intr_val); } return mode == CLK_FAST; } /* Build device path. Support SI, PCI, and JTAG for now. */ -int si_devpath(si_t *sih, char *path, int size) +int ai_devpath(si_t *sih, char *path, int size) { int slen; - ASSERT(path != NULL); - ASSERT(size >= SI_DEVPATH_BUFSZ); - if (!path || size <= 0) return -1; switch (sih->bustype) { case SI_BUS: case JTAG_BUS: - slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih)); + slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih)); break; case PCI_BUS: - ASSERT((SI_INFO(sih))->pbus != NULL); slen = snprintf(path, (size_t) size, "pci/%u/%u/", ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number, PCI_SLOT( ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); break; -#ifdef BCMSDIO - case SDIO_BUS: - SI_ERROR(("si_devpath: device 0 assumed\n")); - slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih)); - break; -#endif default: slen = -1; - ASSERT(0); break; } @@ -1478,47 +1657,47 @@ int si_devpath(si_t *sih, char *path, int size) } /* Get a variable, but only if it has a devpath prefix */ -char *si_getdevpathvar(si_t *sih, const char *name) +char *ai_getdevpathvar(si_t *sih, const char *name) { char varname[SI_DEVPATH_BUFSZ + 32]; - si_devpathvar(sih, varname, sizeof(varname), name); + ai_devpathvar(sih, varname, sizeof(varname), name); return getvar(NULL, varname); } /* Get a variable, but only if it has a devpath prefix */ -int si_getdevpathintvar(si_t *sih, const char *name) +int ai_getdevpathintvar(si_t *sih, const char *name) { #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) return getintvar(NULL, name); #else char varname[SI_DEVPATH_BUFSZ + 32]; - si_devpathvar(sih, varname, sizeof(varname), name); + ai_devpathvar(sih, varname, sizeof(varname), name); return getintvar(NULL, varname); #endif } -char *si_getnvramflvar(si_t *sih, const char *name) +char *ai_getnvramflvar(si_t *sih, const char *name) { return getvar(NULL, name); } /* Concatenate the dev path with a varname into the given 'var' buffer - * and return the 'var' pointer. - * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned. - * On overflow, the first char will be set to '\0'. + * and return the 'var' pointer. Nothing is done to the arguments if + * len == 0 or var is NULL, var is still returned. On overflow, the + * first char will be set to '\0'. */ -static char *si_devpathvar(si_t *sih, char *var, int len, const char *name) +static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name) { uint path_len; if (!var || len <= 0) return var; - if (si_devpath(sih, var, len) == 0) { + if (ai_devpath(sih, var, len) == 0) { path_len = strlen(var); if (strlen(name) + 1 > (uint) (len - path_len)) @@ -1531,7 +1710,7 @@ static char *si_devpathvar(si_t *sih, char *var, int len, const char *name) } /* return true if PCIE capability exists in the pci config space */ -static __used bool si_ispcie(si_info_t *sii) +static __used bool ai_ispcie(si_info_t *sii) { u8 cap_ptr; @@ -1539,7 +1718,7 @@ static __used bool si_ispcie(si_info_t *sii) return false; cap_ptr = - pcicore_find_pci_capability(sii->pbus, PCI_CAP_PCIECAP_ID, NULL, + pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL, NULL); if (!cap_ptr) return false; @@ -1547,46 +1726,7 @@ static __used bool si_ispcie(si_info_t *sii) return true; } -#ifdef BCMSDIO -/* initialize the sdio core */ -void si_sdio_init(si_t *sih) -{ - si_info_t *sii = SI_INFO(sih); - - if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) || - (sih->buscoretype == SDIOD_CORE_ID)) { - uint idx; - sdpcmd_regs_t *sdpregs; - - /* get the current core index */ - idx = sii->curidx; - ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0)); - - /* switch to sdio core */ - sdpregs = (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0); - if (!sdpregs) - sdpregs = - (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0); - ASSERT(sdpregs); - - SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs)); - - /* enable backplane error and core interrupts */ - W_REG(&sdpregs->hostintmask, I_SBINT); - W_REG(&sdpregs->sbintmask, - (I_SB_SERR | I_SB_RESPERR | (1 << idx))); - - /* switch back to previous core */ - si_setcoreidx(sih, idx); - } - - /* enable interrupts */ - bcmsdh_intr_enable(sii->pbus); - -} -#endif /* BCMSDIO */ - -bool si_pci_war16165(si_t *sih) +bool ai_pci_war16165(si_t *sih) { si_info_t *sii; @@ -1595,7 +1735,7 @@ bool si_pci_war16165(si_t *sih) return PCI(sii) && (sih->buscorerev <= 10); } -void si_pci_up(si_t *sih) +void ai_pci_up(si_t *sih) { si_info_t *sii; @@ -1606,7 +1746,7 @@ void si_pci_up(si_t *sih) return; if (PCI_FORCEHT(sii)) - _si_clkctl_cc(sii, CLK_FAST); + _ai_clkctl_cc(sii, CLK_FAST); if (PCIE(sii)) pcicore_up(sii->pch, SI_PCIUP); @@ -1614,7 +1754,7 @@ void si_pci_up(si_t *sih) } /* Unconfigure and/or apply various WARs when system is going to sleep mode */ -void si_pci_sleep(si_t *sih) +void ai_pci_sleep(si_t *sih) { si_info_t *sii; @@ -1624,7 +1764,7 @@ void si_pci_sleep(si_t *sih) } /* Unconfigure and/or apply various WARs when going down */ -void si_pci_down(si_t *sih) +void ai_pci_down(si_t *sih) { si_info_t *sii; @@ -1636,7 +1776,7 @@ void si_pci_down(si_t *sih) /* release FORCEHT since chip is going to "down" state */ if (PCI_FORCEHT(sii)) - _si_clkctl_cc(sii, CLK_DYNAMIC); + _ai_clkctl_cc(sii, CLK_DYNAMIC); pcicore_down(sii->pch, SI_PCIDOWN); } @@ -1645,7 +1785,7 @@ void si_pci_down(si_t *sih) * Configure the pci core for pci client (NIC) action * coremask is the bitvec of cores by index to be enabled. */ -void si_pci_setup(si_t *sih, uint coremask) +void ai_pci_setup(si_t *sih, uint coremask) { si_info_t *sii; struct sbpciregs *pciregs = NULL; @@ -1657,18 +1797,15 @@ void si_pci_setup(si_t *sih, uint coremask) if (sii->pub.bustype != PCI_BUS) return; - ASSERT(PCI(sii) || PCIE(sii)); - ASSERT(sii->pub.buscoreidx != BADIDX); - if (PCI(sii)) { /* get current core index */ idx = sii->curidx; /* we interrupt on this backplane flag number */ - siflag = si_flag(sih); + siflag = ai_flag(sih); /* switch over to pci core */ - pciregs = (struct sbpciregs *)si_setcoreidx(sih, sii->pub.buscoreidx); + pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx); } /* @@ -1682,7 +1819,7 @@ void si_pci_setup(si_t *sih, uint coremask) pci_write_config_dword(sii->pbus, PCI_INT_MASK, w); } else { /* set sbintvec bit for our flag number */ - si_setint(sih, siflag); + ai_setint(sih, siflag); } if (PCI(sii)) { @@ -1698,7 +1835,7 @@ void si_pci_setup(si_t *sih, uint coremask) } /* switch back to previous core */ - si_setcoreidx(sih, idx); + ai_setcoreidx(sih, idx); } } @@ -1706,7 +1843,7 @@ void si_pci_setup(si_t *sih, uint coremask) * Fixup SROMless PCI device's configuration. * The current core may be changed upon return. */ -int si_pci_fixcfg(si_t *sih) +int ai_pci_fixcfg(si_t *sih) { uint origidx, pciidx; struct sbpciregs *pciregs = NULL; @@ -1716,26 +1853,21 @@ int si_pci_fixcfg(si_t *sih) si_info_t *sii = SI_INFO(sih); - ASSERT(sii->pub.bustype == PCI_BUS); - /* Fixup PI in SROM shadow area to enable the correct PCI core access */ /* save the current index */ - origidx = si_coreidx(&sii->pub); + origidx = ai_coreidx(&sii->pub); /* check 'pi' is correct and fix it if not */ if (sii->pub.buscoretype == PCIE_CORE_ID) { - pcieregs = - (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0); + pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0); regs = pcieregs; - ASSERT(pcieregs != NULL); reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; } else if (sii->pub.buscoretype == PCI_CORE_ID) { - pciregs = (struct sbpciregs *)si_setcore(&sii->pub, PCI_CORE_ID, 0); + pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0); regs = pciregs; - ASSERT(pciregs != NULL); reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; } - pciidx = si_coreidx(&sii->pub); + pciidx = ai_coreidx(&sii->pub); val16 = R_REG(reg16); if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { val16 = @@ -1745,14 +1877,14 @@ int si_pci_fixcfg(si_t *sih) } /* restore the original index */ - si_setcoreidx(&sii->pub, origidx); + ai_setcoreidx(&sii->pub, origidx); pcicore_hwup(sii->pch); return 0; } /* mask&set gpiocontrol bits */ -u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) +u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) { uint regoff; @@ -1763,98 +1895,16 @@ u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) */ if ((priority != GPIO_HI_PRIORITY) && (sih->bustype == SI_BUS) && (val || mask)) { - mask = priority ? (si_gpioreservation & mask) : - ((si_gpioreservation | mask) & ~(si_gpioreservation)); + mask = priority ? (ai_gpioreservation & mask) : + ((ai_gpioreservation | mask) & ~(ai_gpioreservation)); val &= mask; } regoff = offsetof(chipcregs_t, gpiocontrol); - return si_corereg(sih, SI_CC_IDX, regoff, mask, val); -} - -/* Return the size of the specified SOCRAM bank */ -static uint -socram_banksize(si_info_t *sii, sbsocramregs_t *regs, u8 index, - u8 mem_type) -{ - uint banksize, bankinfo; - uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); - - ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); - - W_REG(®s->bankidx, bankidx); - bankinfo = R_REG(®s->bankinfo); - banksize = - SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1); - return banksize; -} - -/* Return the RAM size of the SOCRAM core */ -u32 si_socram_size(si_t *sih) -{ - si_info_t *sii; - uint origidx; - uint intr_val = 0; - - sbsocramregs_t *regs; - bool wasup; - uint corerev; - u32 coreinfo; - uint memsize = 0; - - sii = SI_INFO(sih); - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - regs = si_setcore(sih, SOCRAM_CORE_ID, 0); - if (!regs) - goto done; - - /* Get info for determining size */ - wasup = si_iscoreup(sih); - if (!wasup) - si_core_reset(sih, 0, 0); - corerev = si_corerev(sih); - coreinfo = R_REG(®s->coreinfo); - - /* Calculate size from coreinfo based on rev */ - if (corerev == 0) - memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); - else if (corerev < 3) { - memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); - memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - } else if ((corerev <= 7) || (corerev == 12)) { - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - uint bsz = (coreinfo & SRCI_SRBSZ_MASK); - uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; - if (lss != 0) - nb--; - memsize = nb * (1 << (bsz + SR_BSZ_BASE)); - if (lss != 0) - memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); - } else { - u8 i; - uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; - for (i = 0; i < nb; i++) - memsize += - socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - - done: - INTR_RESTORE(sii, intr_val); - - return memsize; + return ai_corereg(sih, SI_CC_IDX, regoff, mask, val); } -void si_chipcontrl_epa4331(si_t *sih, bool on) +void ai_chipcontrl_epa4331(si_t *sih, bool on) { si_info_t *sii; chipcregs_t *cc; @@ -1862,9 +1912,9 @@ void si_chipcontrl_epa4331(si_t *sih, bool on) u32 val; sii = SI_INFO(sih); - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); val = R_REG(&cc->chipcontrol); @@ -1884,30 +1934,30 @@ void si_chipcontrl_epa4331(si_t *sih, bool on) W_REG(&cc->chipcontrol, val); } - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); } /* Enable BT-COEX & Ex-PA for 4313 */ -void si_epa_4313war(si_t *sih) +void ai_epa_4313war(si_t *sih) { si_info_t *sii; chipcregs_t *cc; uint origidx; sii = SI_INFO(sih); - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); /* EPA Fix */ W_REG(&cc->gpiocontrol, R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); } /* check if the device is removed */ -bool si_deviceremoved(si_t *sih) +bool ai_deviceremoved(si_t *sih) { u32 w; si_info_t *sii; @@ -1916,16 +1966,15 @@ bool si_deviceremoved(si_t *sih) switch (sih->bustype) { case PCI_BUS: - ASSERT(sii->pbus != NULL); - pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w); - if ((w & 0xFFFF) != VENDOR_BROADCOM) + pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w); + if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) return true; break; } return false; } -bool si_is_sprom_available(si_t *sih) +bool ai_is_sprom_available(si_t *sih) { if (sih->ccrev >= 31) { si_info_t *sii; @@ -1938,9 +1987,9 @@ bool si_is_sprom_available(si_t *sih) sii = SI_INFO(sih); origidx = sii->curidx; - cc = si_setcoreidx(sih, SI_CC_IDX); + cc = ai_setcoreidx(sih, SI_CC_IDX); sromctrl = R_REG(&cc->sromcontrol); - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); return sromctrl & SRC_PRESENT; } @@ -1962,7 +2011,7 @@ bool si_is_sprom_available(si_t *sih) } } -bool si_is_otp_disabled(si_t *sih) +bool ai_is_otp_disabled(si_t *sih) { switch (sih->chip) { case BCM4329_CHIP_ID: @@ -1990,17 +2039,16 @@ bool si_is_otp_disabled(si_t *sih) } } -bool si_is_otp_powered(si_t *sih) +bool ai_is_otp_powered(si_t *sih) { if (PMUCTL_ENAB(sih)) return si_pmu_is_otp_powered(sih); return true; } -void si_otp_power(si_t *sih, bool on) +void ai_otp_power(si_t *sih, bool on) { if (PMUCTL_ENAB(sih)) si_pmu_otp_power(sih, on); udelay(1000); } - diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h new file mode 100644 index 000000000000..b98099eaa621 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.h @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2011 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 _aiutils_h_ +#define _aiutils_h_ + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif + +/* Include the soci specific files */ +#include <aidmp.h> + +/* + * SOC Interconnect Address Map. + * All regions may not exist on all chips. + */ +/* Physical SDRAM */ +#define SI_SDRAM_BASE 0x00000000 +/* Host Mode sb2pcitranslation0 (64 MB) */ +#define SI_PCI_MEM 0x08000000 +#define SI_PCI_MEM_SZ (64 * 1024 * 1024) +/* Host Mode sb2pcitranslation1 (64 MB) */ +#define SI_PCI_CFG 0x0c000000 +/* Byteswapped Physical SDRAM */ +#define SI_SDRAM_SWAPPED 0x10000000 +/* Region 2 for sdram (512 MB) */ +#define SI_SDRAM_R2 0x80000000 + +#ifdef SI_ENUM_BASE_VARIABLE +#define SI_ENUM_BASE (sii->pub.si_enum_base) +#else +#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ +#endif /* SI_ENUM_BASE_VARIABLE */ + +/* Wrapper space base */ +#define SI_WRAP_BASE 0x18100000 +/* each core gets 4Kbytes for registers */ +#define SI_CORE_SIZE 0x1000 +/* + * Max cores (this is arbitrary, for software + * convenience and could be changed if we + * make any larger chips + */ +#define SI_MAXCORES 16 + +/* On-chip RAM on chips that also have DDR */ +#define SI_FASTRAM 0x19000000 +#define SI_FASTRAM_SWAPPED 0x19800000 + +/* Flash Region 2 (region 1 shadowed here) */ +#define SI_FLASH2 0x1c000000 +/* Size of Flash Region 2 */ +#define SI_FLASH2_SZ 0x02000000 +/* ARM Cortex-M3 ROM */ +#define SI_ARMCM3_ROM 0x1e000000 +/* MIPS Flash Region 1 */ +#define SI_FLASH1 0x1fc00000 +/* MIPS Size of Flash Region 1 */ +#define SI_FLASH1_SZ 0x00400000 +/* ARM7TDMI-S ROM */ +#define SI_ARM7S_ROM 0x20000000 +/* ARM Cortex-M3 SRAM Region 2 */ +#define SI_ARMCM3_SRAM2 0x60000000 +/* ARM7TDMI-S SRAM Region 2 */ +#define SI_ARM7S_SRAM2 0x80000000 +/* ARM Flash Region 1 */ +#define SI_ARM_FLASH1 0xffff0000 +/* ARM Size of Flash Region 1 */ +#define SI_ARM_FLASH1_SZ 0x00010000 + +/* Client Mode sb2pcitranslation2 (1 GB) */ +#define SI_PCI_DMA 0x40000000 +/* Client Mode sb2pcitranslation2 (1 GB) */ +#define SI_PCI_DMA2 0x80000000 +/* Client Mode sb2pcitranslation2 size in bytes */ +#define SI_PCI_DMA_SZ 0x40000000 +/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ +#define SI_PCIE_DMA_L32 0x00000000 +/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ +#define SI_PCIE_DMA_H32 0x80000000 + +/* core codes */ +#define NODEV_CORE_ID 0x700 /* Invalid coreid */ +#define CC_CORE_ID 0x800 /* chipcommon core */ +#define ILINE20_CORE_ID 0x801 /* iline20 core */ +#define SRAM_CORE_ID 0x802 /* sram core */ +#define SDRAM_CORE_ID 0x803 /* sdram core */ +#define PCI_CORE_ID 0x804 /* pci core */ +#define MIPS_CORE_ID 0x805 /* mips core */ +#define ENET_CORE_ID 0x806 /* enet mac core */ +#define CODEC_CORE_ID 0x807 /* v90 codec core */ +#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ +#define ADSL_CORE_ID 0x809 /* ADSL core */ +#define ILINE100_CORE_ID 0x80a /* iline100 core */ +#define IPSEC_CORE_ID 0x80b /* ipsec core */ +#define UTOPIA_CORE_ID 0x80c /* utopia core */ +#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ +#define SOCRAM_CORE_ID 0x80e /* internal memory core */ +#define MEMC_CORE_ID 0x80f /* memc sdram core */ +#define OFDM_CORE_ID 0x810 /* OFDM phy core */ +#define EXTIF_CORE_ID 0x811 /* external interface core */ +#define D11_CORE_ID 0x812 /* 802.11 MAC core */ +#define APHY_CORE_ID 0x813 /* 802.11a phy core */ +#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ +#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ +#define MIPS33_CORE_ID 0x816 /* mips3302 core */ +#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ +#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ +#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ +#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ +#define SDIOH_CORE_ID 0x81b /* sdio host core */ +#define ROBO_CORE_ID 0x81c /* roboswitch core */ +#define ATA100_CORE_ID 0x81d /* parallel ATA core */ +#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ +#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ +#define PCIE_CORE_ID 0x820 /* pci express core */ +#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ +#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ +#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ +#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ +#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ +#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ +#define PMU_CORE_ID 0x827 /* PMU core */ +#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ +#define SDIOD_CORE_ID 0x829 /* SDIO device core */ +#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ +#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ +#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ +#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ +#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ +#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ +#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ +#define SC_CORE_ID 0x831 /* shared common core */ +#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ +#define SPIH_CORE_ID 0x833 /* SPI host core */ +#define I2S_CORE_ID 0x834 /* I2S core */ +#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ +#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ +#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ +#define DEF_AI_COMP 0xfff /* Default component, in ai chips it + * maps all unused address ranges + */ + +/* There are TWO constants on all HND chips: SI_ENUM_BASE above, + * and chipcommon being the first core: + */ +#define SI_CC_IDX 0 + +/* SOC Interconnect types (aka chip types) */ +#define SOCI_AI 1 + +/* Common core control flags */ +#define SICF_BIST_EN 0x8000 +#define SICF_PME_EN 0x4000 +#define SICF_CORE_BITS 0x3ffc +#define SICF_FGC 0x0002 +#define SICF_CLOCK_EN 0x0001 + +/* Common core status flags */ +#define SISF_BIST_DONE 0x8000 +#define SISF_BIST_ERROR 0x4000 +#define SISF_GATED_CLK 0x2000 +#define SISF_DMA64 0x1000 +#define SISF_CORE_BITS 0x0fff + +/* A register that is common to all cores to + * communicate w/PMU regarding clock control. + */ +#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ + +/* clk_ctl_st register */ +#define CCS_FORCEALP 0x00000001 /* force ALP request */ +#define CCS_FORCEHT 0x00000002 /* force HT request */ +#define CCS_FORCEILP 0x00000004 /* force ILP request */ +#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ +#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ +#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ +#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ +#define CCS_ERSRC_REQ_SHIFT 8 +#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ +#define CCS_HTAVAIL 0x00020000 /* HT is available */ +#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */ +#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */ +#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ +#define CCS_ERSRC_STS_SHIFT 24 + +/* HT avail in chipc and pcmcia on 4328a0 */ +#define CCS0_HTAVAIL 0x00010000 +/* ALP avail in chipc and pcmcia on 4328a0 */ +#define CCS0_ALPAVAIL 0x00020000 + +/* Not really related to SOC Interconnect, but a couple of software + * conventions for the use the flash space: + */ + +/* Minumum amount of flash we support */ +#define FLASH_MIN 0x00020000 /* Minimum flash size */ + +/* A boot/binary may have an embedded block that describes its size */ +#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ +#define BISZ_MAGIC 0x4249535a /* Marked with value: 'BISZ' */ +#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ +#define BISZ_TXTST_IDX 1 /* 1: text start */ +#define BISZ_TXTEND_IDX 2 /* 2: text end */ +#define BISZ_DATAST_IDX 3 /* 3: data start */ +#define BISZ_DATAEND_IDX 4 /* 4: data end */ +#define BISZ_BSSST_IDX 5 /* 5: bss start */ +#define BISZ_BSSEND_IDX 6 /* 6: bss end */ +#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ + +#define SI_INFO(sih) (si_info_t *)sih + +#define GOODCOREADDR(x, b) \ + (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ + IS_ALIGNED((x), SI_CORE_SIZE)) +#define GOODREGS(regs) \ + ((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE)) +#define BADCOREADDR 0 +#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) +#define NOREV -1 /* Invalid rev */ + +/* Newer chips can access PCI/PCIE and CC core without requiring to change + * PCI BAR0 WIN + */ +#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ + (((si)->pub.buscoretype == PCI_CORE_ID) && \ + (si)->pub.buscorerev >= 13)) + +#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) +#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) + +/* + * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts + * before after core switching to avoid invalid register accesss inside ISR. + */ +#define INTR_OFF(si, intr_val) \ + if ((si)->intrsoff_fn && \ + (si)->coreid[(si)->curidx] == (si)->dev_coreid) \ + intr_val = (*(si)->intrsoff_fn)((si)->intr_arg) +#define INTR_RESTORE(si, intr_val) \ + if ((si)->intrsrestore_fn && \ + (si)->coreid[(si)->curidx] == (si)->dev_coreid) \ + (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val) + +/* dynamic clock control defines */ +#define LPOMINFREQ 25000 /* low power oscillator min */ +#define LPOMAXFREQ 43000 /* low power oscillator max */ +#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ +#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ +#define PCIMINFREQ 25000000 /* 25 MHz */ +#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ + +#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ +#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ + +#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ + ((si)->pub.buscoretype == PCI_CORE_ID)) +#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ + ((si)->pub.buscoretype == PCIE_CORE_ID)) +#define PCI_FORCEHT(si) \ + (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) + +/* GPIO Based LED powersave defines */ +#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ +#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ + +#ifndef DEFAULT_GPIOTIMERVAL +#define DEFAULT_GPIOTIMERVAL \ + ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) +#endif + +/* + * Data structure to export all chip specific common variables + * public (read-only) portion of aiutils handle returned by si_attach() + */ +struct si_pub { + uint bustype; /* SI_BUS, PCI_BUS */ + uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ + uint buscorerev; /* buscore rev */ + uint buscoreidx; /* buscore index */ + int ccrev; /* chip common core rev */ + u32 cccaps; /* chip common capabilities */ + u32 cccaps_ext; /* chip common capabilities extension */ + int pmurev; /* pmu core rev */ + u32 pmucaps; /* pmu capabilities */ + uint boardtype; /* board type */ + uint boardvendor; /* board vendor */ + uint boardflags; /* board flags */ + uint boardflags2; /* board flags2 */ + uint chip; /* chip number */ + uint chiprev; /* chip revision */ + uint chippkg; /* chip package option */ + u32 chipst; /* chip status */ + bool issim; /* chip is in simulation or emulation */ + uint socirev; /* SOC interconnect rev */ + bool pci_pr32414; + +}; + +/* + * for HIGH_ONLY driver, the si_t must be writable to allow states sync from + * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident + * change + */ +typedef const struct si_pub si_t; + +/* + * Many of the routines below take an 'sih' handle as their first arg. + * Allocate this by calling si_attach(). Free it by calling si_detach(). + * At any one time, the sih is logically focused on one particular si core + * (the "current core"). + * Use si_setcore() or si_setcoreidx() to change the association to another core + */ + +#define BADIDX (SI_MAXCORES + 1) + +/* clkctl xtal what flags */ +#define XTAL 0x1 /* primary crystal oscillator (2050) */ +#define PLL 0x2 /* main chip pll */ + +/* clkctl clk mode */ +#define CLK_FAST 0 /* force fast (pll) clock */ +#define CLK_DYNAMIC 2 /* enable dynamic clock control */ + +/* GPIO usage priorities */ +#define GPIO_DRV_PRIORITY 0 /* Driver */ +#define GPIO_APP_PRIORITY 1 /* Application */ +#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO + * reservation + */ + +/* GPIO pull up/down */ +#define GPIO_PULLUP 0 +#define GPIO_PULLDN 1 + +/* GPIO event regtype */ +#define GPIO_REGEVT 0 /* GPIO register event */ +#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ +#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ + +/* device path */ +#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ + +/* SI routine enumeration: to be used by update function with multiple hooks */ +#define SI_DOATTACH 1 +#define SI_PCIDOWN 2 +#define SI_PCIUP 3 + +#define ISSIM_ENAB(sih) 0 + +/* PMU clock/power control */ +#if defined(BCMPMUCTL) +#define PMUCTL_ENAB(sih) (BCMPMUCTL) +#else +#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) +#endif + +/* chipcommon clock/power control (exclusive with PMU's) */ +#if defined(BCMPMUCTL) && BCMPMUCTL +#define CCCTL_ENAB(sih) (0) +#define CCPLL_ENAB(sih) (0) +#else +#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) +#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) +#endif + +typedef void (*gpio_handler_t) (u32 stat, void *arg); + +/* External PA enable mask */ +#define GPIO_CTRL_EPA_EN_MASK 0x40 + +#define SI_ERROR(args) + +#ifdef BCMDBG +#define SI_MSG(args) printk args +#else +#define SI_MSG(args) +#endif /* BCMDBG */ + +/* Define SI_VMSG to printf for verbose debugging, but don't check it in */ +#define SI_VMSG(args) + +#define IS_SIM(chippkg) \ + ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) + +typedef u32(*si_intrsoff_t) (void *intr_arg); +typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg); +typedef bool(*si_intrsenabled_t) (void *intr_arg); + +typedef struct gpioh_item { + void *arg; + bool level; + gpio_handler_t handler; + u32 event; + struct gpioh_item *next; +} gpioh_item_t; + +/* misc si info needed by some of the routines */ +typedef struct si_info { + struct si_pub pub; /* back plane public state (must be first) */ + void *pbus; /* handle to bus (pci/sdio/..) */ + uint dev_coreid; /* the core provides driver functions */ + void *intr_arg; /* interrupt callback function arg */ + si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ + si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ + si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ + + void *pch; /* PCI/E core handle */ + + gpioh_item_t *gpioh_head; /* GPIO event handlers list */ + + bool memseg; /* flag to toggle MEM_SEG register */ + + char *vars; + uint varsz; + + void *curmap; /* current regs va */ + void *regs[SI_MAXCORES]; /* other regs va */ + + uint curidx; /* current core index */ + uint numcores; /* # discovered cores */ + uint coreid[SI_MAXCORES]; /* id of each core */ + u32 coresba[SI_MAXCORES]; /* backplane address of each core */ + void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */ + u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */ + u32 coresba_size[SI_MAXCORES]; /* backplane address space size */ + u32 coresba2_size[SI_MAXCORES]; /* second address space size */ + + void *curwrap; /* current wrapper va */ + void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ + u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ + + u32 cia[SI_MAXCORES]; /* erom cia entry for each core */ + u32 cib[SI_MAXCORES]; /* erom cia entry for each core */ + u32 oob_router; /* oob router registers for axi */ +} si_info_t; + +/* AMBA Interconnect exported externs */ +extern void ai_scan(si_t *sih, void *regs, uint devid); + +extern uint ai_flag(si_t *sih); +extern void ai_setint(si_t *sih, int siflag); +extern uint ai_coreidx(si_t *sih); +extern uint ai_corevendor(si_t *sih); +extern uint ai_corerev(si_t *sih); +extern bool ai_iscoreup(si_t *sih); +extern void *ai_setcoreidx(si_t *sih, uint coreidx); +extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); +extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); +extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, + uint val); +extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(si_t *sih, u32 bits); +extern int ai_numaddrspaces(si_t *sih); +extern u32 ai_addrspace(si_t *sih, uint asidx); +extern u32 ai_addrspacesize(si_t *sih, uint asidx); +extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); + +/* === exported functions === */ +extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz); + +extern void ai_detach(si_t *sih); +extern bool ai_pci_war16165(si_t *sih); + +extern uint ai_coreid(si_t *sih); +extern uint ai_corerev(si_t *sih); +extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, + uint val); +extern void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val); +extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); +extern bool ai_iscoreup(si_t *sih); +extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit); +extern void *ai_setcoreidx(si_t *sih, uint coreidx); +extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit); +extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, + uint *intr_val); +extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val); +extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(si_t *sih, u32 bits); +extern u32 ai_alp_clock(si_t *sih); +extern u32 ai_ilp_clock(si_t *sih); +extern void ai_pci_setup(si_t *sih, uint coremask); +extern void ai_setint(si_t *sih, int siflag); +extern bool ai_backplane64(si_t *sih); +extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn, + void *intrsrestore_fn, + void *intrsenabled_fn, void *intr_arg); +extern void ai_deregister_intr_callback(si_t *sih); +extern void ai_clkctl_init(si_t *sih); +extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih); +extern bool ai_clkctl_cc(si_t *sih, uint mode); +extern int ai_clkctl_xtal(si_t *sih, uint what, bool on); +extern bool ai_deviceremoved(si_t *sih); +extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, + u8 priority); + +/* OTP status */ +extern bool ai_is_otp_disabled(si_t *sih); +extern bool ai_is_otp_powered(si_t *sih); +extern void ai_otp_power(si_t *sih, bool on); + +/* SPROM availability */ +extern bool ai_is_sprom_available(si_t *sih); + +/* + * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. + * The returned path is NULL terminated and has trailing '/'. + * Return 0 on success, nonzero otherwise. + */ +extern int ai_devpath(si_t *sih, char *path, int size); +/* Read variable with prepending the devpath to the name */ +extern char *ai_getdevpathvar(si_t *sih, const char *name); +extern int ai_getdevpathintvar(si_t *sih, const char *name); + +extern void ai_pci_sleep(si_t *sih); +extern void ai_pci_down(si_t *sih); +extern void ai_pci_up(si_t *sih); +extern int ai_pci_fixcfg(si_t *sih); + +extern void ai_chipcontrl_epa4331(si_t *sih, bool on); +/* Enable Ex-PA for 4313 */ +extern void ai_epa_4313war(si_t *sih); + +char *ai_getnvramflvar(si_t *sih, const char *name); + +#endif /* _aiutils_h_ */ diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/brcmsmac/bcmotp.c index 17991212a22d..d09628b5a88e 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/brcmsmac/bcmotp.c @@ -17,16 +17,17 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/string.h> -#include <bcmdefs.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/crc-ccitt.h> + +#include <bcmdefs.h> #include <bcmdevs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <hndsoc.h> #include <sbchipc.h> #include <bcmotp.h> -#include "siutils_priv.h" /* * There are two different OTP controllers so far: @@ -177,9 +178,6 @@ static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) oi = (otpinfo_t *) oh; - ASSERT(wn < oi->wsize); - ASSERT(cc != NULL); - return R_REG(&cc->sromotp[wn]); } @@ -229,7 +227,7 @@ static int ipxotp_max_rgnsz(si_t *sih, int osizew) ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; break; default: - ASSERT(0); /* Don't know about this chip */ + break; /* Don't know about this chip */ } return ret; @@ -313,19 +311,16 @@ static void *ipxotp_init(si_t *sih) otpinfo_t *oi; /* Make sure we're running IPX OTP */ - ASSERT(OTPTYPE_IPX(sih->ccrev)); if (!OTPTYPE_IPX(sih->ccrev)) return NULL; /* Make sure OTP is not disabled */ - if (si_is_otp_disabled(sih)) { + if (ai_is_otp_disabled(sih)) return NULL; - } /* Make sure OTP is powered up */ - if (!si_is_otp_powered(sih)) { + if (!ai_is_otp_powered(sih)) return NULL; - } oi = &otpinfo; @@ -360,13 +355,12 @@ static void *ipxotp_init(si_t *sih) } /* Retrieve OTP region info */ - idx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + idx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); _ipxotp_init(oi, cc); - si_setcoreidx(sih, idx); + ai_setcoreidx(sih, idx); return (void *)oi; } @@ -384,11 +378,11 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) sz = (uint) oi->hwlim - oi->hwbase; if (!(oi->status & OTPS_GUP_HW)) { *wlen = sz; - return BCME_NOTFOUND; + return -ENODATA; } if (*wlen < sz) { *wlen = sz; - return BCME_BUFTOOSHORT; + return -EOVERFLOW; } base = oi->hwbase; break; @@ -396,11 +390,11 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) sz = ((uint) oi->swlim - oi->swbase); if (!(oi->status & OTPS_GUP_SW)) { *wlen = sz; - return BCME_NOTFOUND; + return -ENODATA; } if (*wlen < sz) { *wlen = sz; - return BCME_BUFTOOSHORT; + return -EOVERFLOW; } base = oi->swbase; break; @@ -408,11 +402,11 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) sz = OTPGU_CI_SZ; if (!(oi->status & OTPS_GUP_CI)) { *wlen = sz; - return BCME_NOTFOUND; + return -ENODATA; } if (*wlen < sz) { *wlen = sz; - return BCME_BUFTOOSHORT; + return -EOVERFLOW; } base = oi->otpgu_base + OTPGU_CI_OFF; break; @@ -420,11 +414,11 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) sz = (uint) oi->flim - oi->fbase; if (!(oi->status & OTPS_GUP_FUSE)) { *wlen = sz; - return BCME_NOTFOUND; + return -ENODATA; } if (*wlen < sz) { *wlen = sz; - return BCME_BUFTOOSHORT; + return -EOVERFLOW; } base = oi->fbase; break; @@ -432,34 +426,33 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) sz = ((uint) oi->flim - oi->hwbase); if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) { *wlen = sz; - return BCME_NOTFOUND; + return -ENODATA; } if (*wlen < sz) { *wlen = sz; - return BCME_BUFTOOSHORT; + return -EOVERFLOW; } base = oi->hwbase; break; default: - return BCME_BADARG; + return -EINVAL; } - idx = si_coreidx(oi->sih); - cc = si_setcoreidx(oi->sih, SI_CC_IDX); - ASSERT(cc != NULL); + idx = ai_coreidx(oi->sih); + cc = ai_setcoreidx(oi->sih, SI_CC_IDX); /* Read the data */ for (i = 0; i < sz; i++) data[i] = ipxotp_otpr(oh, cc, base + i); - si_setcoreidx(oi->sih, idx); + ai_setcoreidx(oi->sih, idx); *wlen = sz; return 0; } static int ipxotp_nvread(void *oh, char *data, uint *len) { - return BCME_UNSUPPORTED; + return -ENOTSUPP; } static otp_fn_t ipxotp_fn = { @@ -567,14 +560,8 @@ static int hndotp_size(void *oh) static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) { -#ifdef BCMDBG - otpinfo_t *oi = (otpinfo_t *) oh; -#endif volatile u16 *ptr; - ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF)); - ASSERT(cc != NULL); - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); return R_REG(&ptr[wn]); } @@ -584,10 +571,6 @@ static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) otpinfo_t *oi = (otpinfo_t *) oh; volatile u16 *ptr; - ASSERT(woff >= (-((int)oi->size / 2))); - ASSERT(woff < OTP_LIM_OFF); - ASSERT(cc != NULL); - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); return R_REG(&ptr[(oi->size / 2) + woff]); @@ -631,10 +614,10 @@ static void *hndotp_init(si_t *sih) oi = &otpinfo; - idx = si_coreidx(sih); + idx = ai_coreidx(sih); /* Check for otp */ - cc = si_setcoreidx(sih, SI_CC_IDX); + cc = ai_setcoreidx(sih, SI_CC_IDX); if (cc != NULL) { cap = R_REG(&cc->capabilities); if ((cap & CC_CAP_OTPSIZE) == 0) { @@ -642,11 +625,7 @@ static void *hndotp_init(si_t *sih) goto out; } - /* As of right now, support only 4320a2, 4311a1 and 4312 */ - ASSERT((oi->ccrev == 12) || (oi->ccrev == 17) - || (oi->ccrev == 22)); - if (! - ((oi->ccrev == 12) || (oi->ccrev == 17) + if (!((oi->ccrev == 12) || (oi->ccrev == 17) || (oi->ccrev == 22))) return NULL; @@ -690,7 +669,7 @@ static void *hndotp_init(si_t *sih) } out: /* All done */ - si_setcoreidx(sih, idx); + ai_setcoreidx(sih, idx); return ret; } @@ -702,25 +681,30 @@ static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen) chipcregs_t *cc; int i; - /* Only support HW region (no active chips use HND OTP SW region) */ - ASSERT(region == OTP_HW_REGION); + + if (region != OTP_HW_REGION) { + /* + * Only support HW region + * (no active chips use HND OTP SW region) + * */ + return -ENOTSUPP; + } /* Region empty? */ st = oi->hwprot | oi->signvalid; if ((st & region) == 0) - return BCME_NOTFOUND; + return -ENODATA; *wlen = ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2; - idx = si_coreidx(oi->sih); - cc = si_setcoreidx(oi->sih, SI_CC_IDX); - ASSERT(cc != NULL); + idx = ai_coreidx(oi->sih); + cc = ai_setcoreidx(oi->sih, SI_CC_IDX); for (i = 0; i < (int)*wlen; i++) data[i] = hndotp_otpr(oh, cc, i); - si_setcoreidx(oi->sih, idx); + ai_setcoreidx(oi->sih, idx); return 0; } @@ -737,9 +721,8 @@ static int hndotp_nvread(void *oh, char *data, uint *len) u16 *rawotp = NULL; /* save the orig core */ - idx = si_coreidx(oi->sih); - cc = si_setcoreidx(oi->sih, SI_CC_IDX); - ASSERT(cc != NULL); + idx = ai_coreidx(oi->sih); + cc = ai_setcoreidx(oi->sih, SI_CC_IDX); st = hndotp_status(oh); if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) { @@ -797,8 +780,8 @@ static int hndotp_nvread(void *oh, char *data, uint *len) /* Bad length, try to find another chunk anyway */ rsz = 6; } - if (hndcrc16((u8 *) &rawotp[i], rsz, - CRC16_INIT_VALUE) == CRC16_GOOD_VALUE) { + if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) == + CRC16_GOOD_VALUE) { /* Good crc, copy the vars */ gchunks++; dsz = rsz - 6; @@ -831,7 +814,7 @@ static int hndotp_nvread(void *oh, char *data, uint *len) out: kfree(rawotp); - si_setcoreidx(oi->sih, idx); + ai_setcoreidx(oi->sih, idx); return rc; } @@ -876,10 +859,10 @@ int otp_size(void *oh) u16 otp_read_bit(void *oh, uint offset) { otpinfo_t *oi = (otpinfo_t *) oh; - uint idx = si_coreidx(oi->sih); - chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX); + uint idx = ai_coreidx(oi->sih); + chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX); u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset); - si_setcoreidx(oi->sih, idx); + ai_setcoreidx(oi->sih, idx); return readBit; } @@ -921,18 +904,18 @@ otp_read_region(si_t *sih, int region, u16 *data, void *oh; int err = 0; - wasup = si_is_otp_powered(sih); + wasup = ai_is_otp_powered(sih); if (!wasup) - si_otp_power(sih, true); + ai_otp_power(sih, true); - if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { - err = BCME_NOTREADY; + if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) { + err = -EPERM; goto out; } oh = otp_init(sih); if (oh == NULL) { - err = BCME_ERROR; + err = -EBADE; goto out; } @@ -940,7 +923,7 @@ otp_read_region(si_t *sih, int region, u16 *data, out: if (!wasup) - si_otp_power(sih, false); + ai_otp_power(sih, false); return err; } diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c new file mode 100644 index 000000000000..bbfc64204363 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2010 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 <linux/kernel.h> +#include <linux/string.h> +#include <linux/etherdevice.h> +#include <bcmdefs.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <stdarg.h> +#include <bcmutils.h> +#include <hndsoc.h> +#include <sbchipc.h> +#include <bcmdevs.h> +#include <pcicfg.h> +#include <aiutils.h> +#include <bcmsrom.h> +#include <bcmsrom_tbl.h> + +#include <bcmnvram.h> +#include <bcmotp.h> + +#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ + (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ + ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ + ((u8 *)curmap + PCI_BAR0_SPROM_OFFSET)) + +#if defined(BCMDBG) +#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ +#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ +#endif + +typedef struct varbuf { + char *base; /* pointer to buffer base */ + char *buf; /* pointer to current position */ + unsigned int size; /* current (residual) size in bytes */ +} varbuf_t; +extern char *_vars; +extern uint _varsz; + +static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); +static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); +static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); +static int initvars_flash_si(si_t *sih, char **vars, uint *count); +static int sprom_read_pci(si_t *sih, u16 *sprom, + uint wordoff, u16 *buf, uint nwords, bool check_crc); +#if defined(BCMNVRAMR) +static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz); +#endif +static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, + uint wordoff, u16 data); + +static int initvars_table(char *start, char *end, + char **vars, uint *count); +static int initvars_flash(si_t *sih, char **vp, + uint len); + +/* Initialization of varbuf structure */ +static void varbuf_init(varbuf_t *b, char *buf, uint size) +{ + b->size = size; + b->base = b->buf = buf; +} + +/* append a null terminated var=value string */ +static int varbuf_append(varbuf_t *b, const char *fmt, ...) +{ + va_list ap; + int r; + size_t len; + char *s; + + if (b->size < 2) + return 0; + + va_start(ap, fmt); + r = vsnprintf(b->buf, b->size, fmt, ap); + va_end(ap); + + /* C99 snprintf behavior returns r >= size on overflow, + * others return -1 on overflow. + * All return -1 on format error. + * We need to leave room for 2 null terminations, one for the current var + * string, and one for final null of the var table. So check that the + * strlen written, r, leaves room for 2 chars. + */ + if ((r == -1) || (r > (int)(b->size - 2))) { + b->size = 0; + return 0; + } + + /* Remove any earlier occurrence of the same variable */ + s = strchr(b->buf, '='); + if (s != NULL) { + len = (size_t) (s - b->buf); + for (s = b->base; s < b->buf;) { + if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') { + len = strlen(s) + 1; + memmove(s, (s + len), + ((b->buf + r + 1) - (s + len))); + b->buf -= len; + b->size += (unsigned int)len; + break; + } + + while (*s++) + ; + } + } + + /* skip over this string's null termination */ + r++; + b->size -= r; + b->buf += r; + + return r; +} + +/* + * Initialize local vars from the right source for this platform. + * Return 0 on success, nonzero on error. + */ +int srom_var_init(si_t *sih, uint bustype, void *curmap, + char **vars, uint *count) +{ + uint len; + + len = 0; + + if (vars == NULL || count == NULL) + return 0; + + *vars = NULL; + *count = 0; + + switch (bustype) { + case SI_BUS: + case JTAG_BUS: + return initvars_srom_si(sih, curmap, vars, count); + + case PCI_BUS: + if (curmap == NULL) + return -1; + + return initvars_srom_pci(sih, curmap, vars, count); + + default: + break; + } + return -1; +} + +/* In chips with chipcommon rev 32 and later, the srom is in chipcommon, + * not in the bus cores. + */ +static u16 +srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, + uint wordoff, u16 data) +{ + chipcregs_t *cc = (chipcregs_t *) ccregs; + uint wait_cnt = 1000; + + if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) { + W_REG(&cc->sromaddress, wordoff * 2); + if (cmd == SRC_OP_WRITE) + W_REG(&cc->sromdata, data); + } + + W_REG(&cc->sromcontrol, SRC_START | cmd); + + while (wait_cnt--) { + if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0) + break; + } + + if (!wait_cnt) { + return 0xffff; + } + if (cmd == SRC_OP_READ) + return (u16) R_REG(&cc->sromdata); + else + return 0xffff; +} + +static inline void ltoh16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = le16_to_cpu(*(buf + size)); +} + +static inline void htol16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = cpu_to_le16(*(buf + size)); +} + +/* + * Read in and validate sprom. + * Return 0 on success, nonzero on error. + */ +static int +sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, + u16 *buf, uint nwords, bool check_crc) +{ + int err = 0; + uint i; + void *ccregs = NULL; + + /* read the sprom */ + for (i = 0; i < nwords; i++) { + + if (sih->ccrev > 31 && ISSIM_ENAB(sih)) { + /* use indirect since direct is too slow on QT */ + if ((sih->cccaps & CC_CAP_SROM) == 0) + return 1; + + ccregs = (void *)((u8 *) sprom - CC_SROM_OTP); + buf[i] = + srom_cc_cmd(sih, ccregs, SRC_OP_READ, + wordoff + i, 0); + + } else { + if (ISSIM_ENAB(sih)) + buf[i] = R_REG(&sprom[wordoff + i]); + + buf[i] = R_REG(&sprom[wordoff + i]); + } + + } + + /* bypass crc checking for simulation to allow srom hack */ + if (ISSIM_ENAB(sih)) + return err; + + if (check_crc) { + + if (buf[0] == 0xffff) { + /* The hardware thinks that an srom that starts with 0xffff + * is blank, regardless of the rest of the content, so declare + * it bad. + */ + return 1; + } + + /* fixup the endianness so crc8 will pass */ + htol16_buf(buf, nwords * 2); + if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != + CRC8_GOOD_VALUE) { + /* DBG only pci always read srom4 first, then srom8/9 */ + err = 1; + } + /* now correct the endianness of the byte array */ + ltoh16_buf(buf, nwords * 2); + } + return err; +} + +#if defined(BCMNVRAMR) +static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) +{ + u8 *otp; + uint sz = OTP_SZ_MAX / 2; /* size in words */ + int err = 0; + + otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); + if (otp == NULL) { + return -EBADE; + } + + err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); + + memcpy(buf, otp, bufsz); + + kfree(otp); + + /* Check CRC */ + if (buf[0] == 0xffff) { + /* The hardware thinks that an srom that starts with 0xffff + * is blank, regardless of the rest of the content, so declare + * it bad. + */ + return 1; + } + + /* fixup the endianness so crc8 will pass */ + htol16_buf(buf, bufsz); + if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != + CRC8_GOOD_VALUE) { + err = 1; + } + /* now correct the endianness of the byte array */ + ltoh16_buf(buf, bufsz); + + return err; +} +#endif /* defined(BCMNVRAMR) */ +/* +* Create variable table from memory. +* Return 0 on success, nonzero on error. +*/ +static int initvars_table(char *start, char *end, + char **vars, uint *count) +{ + int c = (int)(end - start); + + /* do it only when there is more than just the null string */ + if (c > 1) { + char *vp = kmalloc(c, GFP_ATOMIC); + if (!vp) + return -ENOMEM; + memcpy(vp, start, c); + *vars = vp; + *count = c; + } else { + *vars = NULL; + *count = 0; + } + + return 0; +} + +/* + * Find variables with <devpath> from flash. 'base' points to the beginning + * of the table upon enter and to the end of the table upon exit when success. + * Return 0 on success, nonzero on error. + */ +static int initvars_flash(si_t *sih, char **base, uint len) +{ + char *vp = *base; + char *flash; + int err; + char *s; + uint l, dl, copy_len; + char devpath[SI_DEVPATH_BUFSZ]; + + /* allocate memory and read in flash */ + flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC); + if (!flash) + return -ENOMEM; + err = nvram_getall(flash, NVRAM_SPACE); + if (err) + goto exit; + + ai_devpath(sih, devpath, sizeof(devpath)); + + /* grab vars with the <devpath> prefix in name */ + dl = strlen(devpath); + for (s = flash; s && *s; s += l + 1) { + l = strlen(s); + + /* skip non-matching variable */ + if (strncmp(s, devpath, dl)) + continue; + + /* is there enough room to copy? */ + copy_len = l - dl + 1; + if (len < copy_len) { + err = -EOVERFLOW; + goto exit; + } + + /* no prefix, just the name=value */ + strncpy(vp, &s[dl], copy_len); + vp += copy_len; + len -= copy_len; + } + + /* add null string as terminator */ + if (len < 1) { + err = -EOVERFLOW; + goto exit; + } + *vp++ = '\0'; + + *base = vp; + + exit: kfree(flash); + return err; +} + +/* + * Initialize nonvolatile variable table from flash. + * Return 0 on success, nonzero on error. + */ +static int initvars_flash_si(si_t *sih, char **vars, uint *count) +{ + char *vp, *base; + int err; + + base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); + if (!vp) + return -ENOMEM; + + err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); + if (err == 0) + err = initvars_table(base, vp, vars, count); + + kfree(base); + + return err; +} + +/* Parse SROM and create name=value pairs. 'srom' points to + * the SROM word array. 'off' specifies the offset of the + * first word 'srom' points to, which should be either 0 or + * SROM3_SWRG_OFF (full SROM or software region). + */ + +static uint mask_shift(u16 mask) +{ + uint i; + for (i = 0; i < (sizeof(mask) << 3); i++) { + if (mask & (1 << i)) + return i; + } + return 0; +} + +static uint mask_width(u16 mask) +{ + int i; + for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) { + if (mask & (1 << i)) + return (uint) (i - mask_shift(mask) + 1); + } + return 0; +} + +static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b) +{ + u16 w; + u32 val; + const sromvar_t *srv; + uint width; + uint flags; + u32 sr = (1 << sromrev); + + varbuf_append(b, "sromrev=%d", sromrev); + + for (srv = pci_sromvars; srv->name != NULL; srv++) { + const char *name; + + if ((srv->revmask & sr) == 0) + continue; + + if (srv->off < off) + continue; + + flags = srv->flags; + name = srv->name; + + /* This entry is for mfgc only. Don't generate param for it, */ + if (flags & SRFL_NOVAR) + continue; + + if (flags & SRFL_ETHADDR) { + u8 ea[ETH_ALEN]; + + ea[0] = (srom[srv->off - off] >> 8) & 0xff; + ea[1] = srom[srv->off - off] & 0xff; + ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; + ea[3] = srom[srv->off + 1 - off] & 0xff; + ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; + ea[5] = srom[srv->off + 2 - off] & 0xff; + + varbuf_append(b, "%s=%pM", name, ea); + } else { + w = srom[srv->off - off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + while (srv->flags & SRFL_MORE) { + srv++; + if (srv->off == 0 || srv->off < off) + continue; + + w = srom[srv->off - off]; + val += + ((w & srv->mask) >> mask_shift(srv-> + mask)) << + width; + width += mask_width(srv->mask); + } + + if ((flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + if (flags & SRFL_CCODE) { + if (val == 0) + varbuf_append(b, "ccode="); + else + varbuf_append(b, "ccode=%c%c", + (val >> 8), (val & 0xff)); + } + /* LED Powersave duty cycle has to be scaled: + *(oncount >> 24) (offcount >> 8) + */ + else if (flags & SRFL_LEDDC) { + u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */ + (((val & 0xff)) << 8); /* offcount */ + varbuf_append(b, "leddc=%d", w32); + } else if (flags & SRFL_PRHEX) + varbuf_append(b, "%s=0x%x", name, val); + else if ((flags & SRFL_PRSIGN) + && (val & (1 << (width - 1)))) + varbuf_append(b, "%s=%d", name, + (int)(val | (~0 << width))); + else + varbuf_append(b, "%s=%u", name, val); + } + } + + if (sromrev >= 4) { + /* Do per-path variables */ + uint p, pb, psz; + + if (sromrev >= 8) { + pb = SROM8_PATH0; + psz = SROM8_PATH1 - SROM8_PATH0; + } else { + pb = SROM4_PATH0; + psz = SROM4_PATH1 - SROM4_PATH0; + } + + for (p = 0; p < MAX_PATH_SROM; p++) { + for (srv = perpath_pci_sromvars; srv->name != NULL; + srv++) { + if ((srv->revmask & sr) == 0) + continue; + + if (pb + srv->off < off) + continue; + + /* This entry is for mfgc only. Don't generate param for it, */ + if (srv->flags & SRFL_NOVAR) + continue; + + w = srom[pb + srv->off - off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + /* Cheating: no per-path var is more than 1 word */ + + if ((srv->flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + if (srv->flags & SRFL_PRHEX) + varbuf_append(b, "%s%d=0x%x", srv->name, + p, val); + else + varbuf_append(b, "%s%d=%d", srv->name, + p, val); + } + pb += psz; + } + } +} + +/* + * Initialize nonvolatile variable table from sprom. + * Return 0 on success, nonzero on error. + */ +static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) +{ + u16 *srom, *sromwindow; + u8 sromrev = 0; + u32 sr; + varbuf_t b; + char *vp, *base = NULL; + bool flash = false; + int err = 0; + + /* + * Apply CRC over SROM content regardless SROM is present or not, + * and use variable <devpath>sromrev's existence in flash to decide + * if we should return an error when CRC fails or read SROM variables + * from flash. + */ + srom = kmalloc(SROM_MAX, GFP_ATOMIC); + if (!srom) + return -2; + + sromwindow = (u16 *) SROM_OFFSET(sih); + if (ai_is_sprom_available(sih)) { + err = + sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, + true); + + if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || + (((sih->buscoretype == PCIE_CORE_ID) + && (sih->buscorerev >= 6)) + || ((sih->buscoretype == PCI_CORE_ID) + && (sih->buscorerev >= 0xe)))) { + /* sromrev >= 4, read more */ + err = + sprom_read_pci(sih, sromwindow, 0, srom, + SROM4_WORDS, true); + sromrev = srom[SROM4_CRCREV] & 0xff; + } else if (err == 0) { + /* srom is good and is rev < 4 */ + /* top word of sprom contains version and crc8 */ + sromrev = srom[SROM_CRCREV] & 0xff; + /* bcm4401 sroms misprogrammed */ + if (sromrev == 0x10) + sromrev = 1; + } + } +#if defined(BCMNVRAMR) + /* Use OTP if SPROM not available */ + else { + err = otp_read_pci(sih, srom, SROM_MAX); + if (err == 0) + /* OTP only contain SROM rev8/rev9 for now */ + sromrev = srom[SROM4_CRCREV] & 0xff; + else + err = 1; + } +#else + else + err = 1; +#endif + + /* + * We want internal/wltest driver to come up with default + * sromvars so we can program a blank SPROM/OTP. + */ + if (err) { + char *value; + u32 val; + val = 0; + + value = ai_getdevpathvar(sih, "sromrev"); + if (value) { + sromrev = (u8) simple_strtoul(value, NULL, 0); + flash = true; + goto varscont; + } + + value = ai_getnvramflvar(sih, "sromrev"); + if (value) { + err = 0; + goto errout; + } + + { + err = -1; + goto errout; + } + } + + varscont: + /* Bitmask for the sromrev */ + sr = 1 << sromrev; + + /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */ + if ((sr & 0x33e) == 0) { + err = -2; + goto errout; + } + + base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); + if (!vp) { + err = -2; + goto errout; + } + + /* read variables from flash */ + if (flash) { + err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); + if (err) + goto errout; + goto varsdone; + } + + varbuf_init(&b, base, MAXSZ_NVRAM_VARS); + + /* parse SROM into name=value pairs. */ + _initvars_srom_pci(sromrev, srom, 0, &b); + + /* final nullbyte terminator */ + vp = b.buf; + *vp++ = '\0'; + + varsdone: + err = initvars_table(base, vp, vars, count); + + errout: + if (base) + kfree(base); + + kfree(srom); + return err; +} + + +static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz) +{ + /* Search flash nvram section for srom variables */ + return initvars_flash_si(sih, vars, varsz); +} diff --git a/drivers/staging/brcm80211/util/bcmsrom_tbl.h b/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h index 22ae7c1c18fb..f4b3e61dc37d 100644 --- a/drivers/staging/brcm80211/util/bcmsrom_tbl.h +++ b/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h @@ -17,7 +17,6 @@ #ifndef _bcmsrom_tbl_h_ #define _bcmsrom_tbl_h_ -#include "sbpcmcia.h" #include "wlioctl.h" typedef struct { @@ -511,73 +510,4 @@ typedef struct { #define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ #define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ -static const cis_tuple_t cis_hnbuvars[] = { - {OTP_RAW1, 0, ""}, /* special case */ - {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */ - {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */ - {HNBU_SROMREV, 2, "1sromrev"}, - /* NOTE: subdevid is also written to boardtype. - * Need to write HNBU_BOARDTYPE to change it if it is different. - */ - {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"}, - {HNBU_BOARDREV, 3, "2boardrev"}, - {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"}, - {HNBU_AA, 3, "1aa2g 1aa5g"}, - {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */ - {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"}, - {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"}, - {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"}, - {HNBU_CCODE, 4, "2ccode 1cctl"}, - {HNBU_CCKPO, 3, "2cckpo"}, - {HNBU_OFDMPO, 5, "4ofdmpo"}, - {HNBU_RDLID, 3, "2rdlid"}, - {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */ - {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */ - {HNBU_XTALFREQ, 5, "4xtalfreq"}, - {HNBU_TRI2G, 2, "1tri2g"}, - {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"}, - {HNBU_RXPO2G, 2, "1rxpo2g"}, - {HNBU_RXPO5G, 2, "1rxpo5g"}, - {HNBU_BOARDNUM, 3, "2boardnum"}, - {HNBU_MACADDR, 7, "6macaddr"}, /* special case */ - {HNBU_RDLSN, 3, "2rdlsn"}, - {HNBU_BOARDTYPE, 3, "2boardtype"}, - {HNBU_LEDDC, 3, "2leddc"}, - {HNBU_RDLRNDIS, 2, "1rdlndis"}, - {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"}, - {HNBU_REGREV, 2, "1regrev"}, - {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */ - {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 " - "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 " - "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 " - "2pa5ghw1a0 2pa5ghw2a0"}, - {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 " - "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 " - "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 " - "2pa5ghw1a1 2pa5ghw2a1"}, - {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo " - "4ofdm5ghpo"}, - {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 " - "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"}, - {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 " - "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"}, - {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 " - "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 " - "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 " - "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"}, - {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"}, - {HNBU_PO_CDD, 3, "2cddpo"}, - {HNBU_PO_STBC, 3, "2stbcpo"}, - {HNBU_PO_40M, 3, "2bw40po"}, - {HNBU_PO_40MDUP, 3, "2bwduppo"}, - {HNBU_RDLRWU, 2, "1rdlrwu"}, - {HNBU_WPS, 3, "1wpsgpio 1wpsled"}, - {HNBU_USBFS, 2, "1usbfs"}, - {HNBU_CUSTOM1, 5, "4customvar1"}, - {OTP_RAW, 0, ""}, /* special case */ - {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"}, - {HNBU_USBEPNUM, 3, "2usbepnum"}, - {0xFF, 0, ""} -}; - #endif /* _bcmsrom_tbl_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index a9d182f49023..d91e4189a3e8 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -17,6 +17,8 @@ #ifndef _D11_H #define _D11_H +#include <sbconfig.h> + #ifndef WL_RSSI_ANT_MAX #define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ #elif WL_RSSI_ANT_MAX != 4 diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/brcmsmac/hnddma.c index be339feae77d..f607315f8143 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/brcmsmac/hnddma.c @@ -22,7 +22,7 @@ #include <bcmdevs.h> #include <hndsoc.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <sbhnddma.h> #include <hnddma.h> @@ -293,23 +293,10 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, di->msg_level = msg_level ? msg_level : &dma_msg_level; - /* old chips w/o sb is no longer supported */ - ASSERT(sih != NULL); - di->dma64 = ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); - - /* check arguments */ - ASSERT(ISPOWEROF2(ntxd)); - ASSERT(ISPOWEROF2(nrxd)); - - if (nrxd == 0) - ASSERT(dmaregsrx == NULL); - if (ntxd == 0) - ASSERT(dmaregstx == NULL); + di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); /* init dma reg pointer */ - ASSERT(ntxd <= D64MAXDD); - ASSERT(nrxd <= D64MAXDD); di->d64txregs = (dma64regs_t *) dmaregstx; di->d64rxregs = (dma64regs_t *) dmaregsrx; di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; @@ -369,11 +356,11 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED; #endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */ - if ((si_coreid(sih) == SDIOD_CORE_ID) - && ((si_corerev(sih) > 0) && (si_corerev(sih) <= 2))) + if ((ai_coreid(sih) == SDIOD_CORE_ID) + && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2))) di->addrext = 0; - else if ((si_coreid(sih) == I2S_CORE_ID) && - ((si_corerev(sih) == 0) || (si_corerev(sih) == 1))) + else if ((ai_coreid(sih) == I2S_CORE_ID) && + ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1))) di->addrext = 0; else di->addrext = _dma_isaddrext(di); @@ -488,7 +475,6 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, #else if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { #endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ - ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0); W_SM(&ddring[outidx].addrlow, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); @@ -499,11 +485,9 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, } else { /* address extension for 32-bit PCI */ u32 ae; - ASSERT(di->addrext); ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; - ASSERT(PHYSADDRHI(pa) == 0); ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; W_SM(&ddring[outidx].addrlow, @@ -544,10 +528,6 @@ static void _dma_detach(dma_info_t *di) DMA_TRACE(("%s: dma_detach\n", di->name)); - /* shouldn't be here if descriptors are unreclaimed */ - ASSERT(di->txin == di->txout); - ASSERT(di->rxin == di->rxout); - /* free dma descriptor rings */ if (di->txd64) pci_free_consistent(di->pbus, di->txdalloc, @@ -602,14 +582,12 @@ static bool _dma_isaddrext(dma_info_t *di) if (!_dma64_addrext(di->d64txregs)) { DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have " "AE set\n", di->name)); - ASSERT(0); } return true; } else if (di->d64rxregs != NULL) { if (!_dma64_addrext(di->d64rxregs)) { DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have " "AE set\n", di->name)); - ASSERT(0); } return true; } @@ -642,8 +620,6 @@ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) } else { /* DMA64 32bits address extension */ u32 ae; - ASSERT(di->addrext); - ASSERT(PHYSADDRHI(pa) == 0); /* shift the high bit(s) from pa to ae */ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> @@ -738,7 +714,7 @@ _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize) * After it reaches the max size of buffer, the data continues in next DMA descriptor * buffer WITHOUT DMA header */ -static void *BCMFASTPATH _dma_rx(dma_info_t *di) +static void *_dma_rx(dma_info_t *di) { struct sk_buff *p, *head, *tail; uint len; @@ -752,16 +728,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) len = le16_to_cpu(*(u16 *) (head->data)); DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); - -#if defined(__mips__) -#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) - if (!len) { - while (!(len = *(u16 *) OSL_UNCACHED(head->data))) - udelay(1); - - *(u16 *) (head->data) = cpu_to_le16((u16) len); - } -#endif /* defined(__mips__) */ + dma_spin_for_len(len, head); /* set actual length */ pkt_len = min((di->rxoffset + len), di->rxbufsize); @@ -783,7 +750,6 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) #ifdef BCMDBG if (resid > 0) { uint cur; - ASSERT(p == NULL); cur = B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - @@ -797,7 +763,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - pkt_buf_free_skb(head); + bcm_pkt_buf_free_skb(head); di->hnddma.rxgiants++; goto next_frame; } @@ -811,7 +777,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) * this will stall the rx dma and user might want to call rxfill again asap * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle */ -static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) +static bool _dma_rxfill(dma_info_t *di) { struct sk_buff *p; u16 rxin, rxout; @@ -845,7 +811,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) size to be allocated */ - p = pkt_buf_get_skb(di->rxbufsize + extra_offset); + p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", @@ -874,10 +840,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) pa = pci_map_single(di->pbus, p->data, di->rxbufsize, PCI_DMA_FROMDEVICE); - ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4)); - /* save the free packet pointer */ - ASSERT(di->rxp[rxout] == NULL); di->rxp[rxout] = p; /* reset flags for each descriptor */ @@ -946,10 +909,10 @@ static void _dma_rxreclaim(dma_info_t *di) DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); } -static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall) +static void *_dma_getnextrxp(dma_info_t *di, bool forceall) { if (di->nrxd == 0) return NULL; @@ -1019,8 +982,6 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) return 0; } - ASSERT((flags & ~mask) == 0); - dmactrlflags &= ~mask; dmactrlflags |= flags; @@ -1053,9 +1014,6 @@ static unsigned long _dma_getvar(dma_info_t *di, const char *name) { if (!strcmp(name, "&txavail")) return (unsigned long)&(di->hnddma.txavail); - else { - ASSERT(0); - } return 0; } @@ -1063,8 +1021,6 @@ static u8 dma_align_sizetobits(uint size) { u8 bitpos = 0; - ASSERT(size); - ASSERT(!(size & (size - 1))); while (size >>= 1) { bitpos++; } @@ -1171,7 +1127,7 @@ static bool dma64_txsuspended(dma_info_t *di) D64_XC_SE); } -static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) +static void dma64_txreclaim(dma_info_t *di, txd_range_t range) { void *p; @@ -1187,7 +1143,7 @@ static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) while ((p = dma64_getnexttxp(di, range))) { /* For unframed data, we don't have any packets to free */ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); } } @@ -1230,12 +1186,8 @@ static bool dma64_alloc(dma_info_t *di, uint direction) di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va); PHYSADDRLOSET(di->txdpa, PHYSADDRLO(di->txdpaorig) + di->txdalign); - /* Make sure that alignment didn't overflow */ - ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); - PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig)); di->txdalloc = alloced; - ASSERT(IS_ALIGNED((unsigned long)di->txd64, align)); } else { va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig); @@ -1248,12 +1200,8 @@ static bool dma64_alloc(dma_info_t *di, uint direction) di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va); PHYSADDRLOSET(di->rxdpa, PHYSADDRLO(di->rxdpaorig) + di->rxdalign); - /* Make sure that alignment didn't overflow */ - ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); - PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig)); di->rxdalloc = alloced; - ASSERT(IS_ALIGNED((unsigned long)di->rxd64, align)); } return true; @@ -1396,7 +1344,6 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) flags |= D64_CTRL1_EOT; dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); - ASSERT(di->txp[txout] == NULL); /* save the buffer pointer - used by dma_getpos */ di->txp[txout] = buf; @@ -1427,7 +1374,7 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) * WARNING: call must check the return value for error. * the error(toss frames) could be fatal and cause many subsequent hard to debug problems */ -static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, +static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) { struct sk_buff *p, *next; @@ -1451,9 +1398,6 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, data = p->data; len = p->len; -#ifdef BCM_DMAPAD - len += PKTDMAPAD(di->osh, p); -#endif /* BCM_DMAPAD */ next = p->next; /* return nonzero if out of tx descriptors */ @@ -1504,7 +1448,6 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, pa = map->segs[j - 1].addr; } dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); - ASSERT(di->txp[txout] == NULL); txout = NEXTTXD(txout); } @@ -1537,7 +1480,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); - pkt_buf_free_skb(p0); + bcm_pkt_buf_free_skb(p0); di->hnddma.txavail = 0; di->hnddma.txnobuf++; return -1; @@ -1553,7 +1496,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and * return associated packet regardless of the value of hardware pointers. */ -static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) +static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) { u16 start, end, i; u16 active_desc; @@ -1645,15 +1588,12 @@ static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) return NULL; } -static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) +static void *dma64_getnextrxp(dma_info_t *di, bool forceall) { uint i, curr; void *rxp; dmaaddr_t pa; - /* if forcing, dma engine must be disabled */ - ASSERT(!forceall || !dma64_rxenabled(di)); - i = di->rxin; /* return if no packets posted */ @@ -1670,7 +1610,6 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) /* get the packet pointer that corresponds to the rx descriptor */ rxp = di->rxp[i]; - ASSERT(rxp); di->rxp[i] = NULL; PHYSADDRLOSET(pa, @@ -1712,8 +1651,6 @@ static void dma64_txrotate(dma_info_t *di) u32 w; u16 first, last; - ASSERT(dma64_txsuspendedidle(di)); - nactive = _dma_txactive(di); ad = (u16) (B2I ((((R_REG(&di->d64txregs->status1) & @@ -1721,8 +1658,6 @@ static void dma64_txrotate(dma_info_t *di) - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t)); rot = TXD(ad - di->txin); - ASSERT(rot < di->ntxd); - /* full-ring case is a lot harder - don't worry about this */ if (rot >= (di->ntxd - nactive)) { DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); @@ -1756,7 +1691,6 @@ static void dma64_txrotate(dma_info_t *di) W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef)); /* move the corresponding txp[] entry */ - ASSERT(di->txp[new] == NULL); di->txp[new] = di->txp[old]; /* Move the map */ @@ -1783,16 +1717,16 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) { /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ /* DMA engine is 64-bit capable */ - if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { + if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { /* backplane are 64-bit capable */ - if (si_backplane64(sih)) + if (ai_backplane64(sih)) /* If bus is System Backplane or PCIE then we can access 64-bits */ if ((sih->bustype == SI_BUS) || ((sih->bustype == PCI_BUS) && (sih->buscoretype == PCIE_CORE_ID))) return DMADDRWIDTH_64; } - ASSERT(0); /* DMA hardware not supported by this driver*/ + /* DMA hardware not supported by this driver*/ return DMADDRWIDTH_64; } diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c index a1fb2f08984d..18b844a8d2fb 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.c @@ -19,7 +19,8 @@ #include <linux/pci.h> #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <bcmnvram.h> +#include <aiutils.h> #include <hndsoc.h> #include <bcmdevs.h> #include <sbchipc.h> @@ -83,8 +84,6 @@ void *pcicore_init(si_t *sih, void *pdev, void *regs) { pcicore_info_t *pi; - ASSERT(sih->bustype == PCI_BUS); - /* alloc pcicore_info_t */ pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC); if (pi == NULL) { @@ -98,10 +97,8 @@ void *pcicore_init(si_t *sih, void *pdev, void *regs) if (sih->buscoretype == PCIE_CORE_ID) { u8 cap_ptr; pi->regs.pcieregs = (sbpcieregs_t *) regs; - cap_ptr = - pcicore_find_pci_capability(pi->dev, PCI_CAP_PCIECAP_ID, - NULL, NULL); - ASSERT(cap_ptr); + cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP, + NULL, NULL); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; } else pi->regs.pciregs = (struct sbpciregs *) regs; @@ -130,16 +127,16 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, u8 byte_val; /* check for Header type 0 */ - pci_read_config_byte(dev, PCI_CFG_HDR, &byte_val); - if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) + pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val); + if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) goto end; /* check if the capability pointer field exists */ - pci_read_config_byte(dev, PCI_CFG_STAT, &byte_val); - if (!(byte_val & PCI_CAPPTR_PRESENT)) + pci_read_config_byte(dev, PCI_STATUS, &byte_val); + if (!(byte_val & PCI_STATUS_CAP_LIST)) goto end; - pci_read_config_byte(dev, PCI_CFG_CAPPTR, &cap_ptr); + pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr); /* check if the capability pointer is 0x00 */ if (cap_ptr == 0x00) goto end; @@ -167,8 +164,8 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, *buflen = 0; /* copy the cpability data excluding cap ID and next ptr */ cap_data = cap_ptr + 2; - if ((bufsize + cap_data) > SZPCR) - bufsize = SZPCR - cap_data; + if ((bufsize + cap_data) > PCI_SZPCR) + bufsize = PCI_SZPCR - cap_data; *buflen = bufsize; while (bufsize--) { pci_read_config_byte(dev, cap_data, buf); @@ -187,8 +184,6 @@ pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, { uint retval = 0xFFFFFFFF; - ASSERT(pcieregs != NULL); - switch (addrtype) { case PCIE_CONFIGREGS: W_REG((&pcieregs->configaddr), offset); @@ -201,7 +196,6 @@ pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, retval = R_REG(&(pcieregs->pcieinddata)); break; default: - ASSERT(0); break; } @@ -212,8 +206,6 @@ uint pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val) { - ASSERT(pcieregs != NULL); - switch (addrtype) { case PCIE_CONFIGREGS: W_REG((&pcieregs->configaddr), offset); @@ -224,7 +216,6 @@ pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, W_REG((&pcieregs->pcieinddata), val); break; default: - ASSERT(0); break; } return 0; @@ -384,7 +375,6 @@ static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) { si_t *sih = pi->sih; - ASSERT(PCIE_PUB(sih)); switch (state) { case SI_DOATTACH: @@ -393,10 +383,10 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) break; case SI_PCIDOWN: if (sih->buscorerev == 6) { /* turn on serdes PLL down */ - si_corereg(sih, SI_CC_IDX, + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); - si_corereg(sih, SI_CC_IDX, + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), ~0x40, 0); } else if (pi->pcie_pr42767) { @@ -405,10 +395,10 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) break; case SI_PCIUP: if (sih->buscorerev == 6) { /* turn off serdes PLL down */ - si_corereg(sih, SI_CC_IDX, + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); - si_corereg(sih, SI_CC_IDX, + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), ~0x40, 0x40); } else if (PCIE_ASPM(sih)) { /* disable clkreq */ @@ -416,7 +406,6 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) } break; default: - ASSERT(0); break; } } @@ -534,10 +523,8 @@ static void pcie_war_noplldown(pcicore_info_t *pi) sbpcieregs_t *pcieregs = pi->regs.pcieregs; u16 *reg16; - ASSERT(pi->sih->buscorerev == 7); - /* turn off serdes PLL down */ - si_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), + ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN); /* clear srom shadow backdoor */ @@ -693,16 +680,15 @@ bool pcicore_pmecap_fast(void *pch) u8 cap_ptr; u32 pmecap; - cap_ptr = - pcicore_find_pci_capability(pi->dev, PCI_CAP_POWERMGMTCAP_ID, NULL, - NULL); + cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_PM, NULL, + NULL); if (!cap_ptr) return false; pci_read_config_dword(pi->dev, cap_ptr, &pmecap); - return (pmecap & PME_CAP_PM_STATES) != 0; + return (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0; } /* return true if PM capability exists in the pci config space @@ -714,10 +700,9 @@ static bool pcicore_pmecap(pcicore_info_t *pi) u32 pmecap; if (!pi->pmecap_offset) { - cap_ptr = - pcicore_find_pci_capability(pi->dev, - PCI_CAP_POWERMGMTCAP_ID, NULL, - NULL); + cap_ptr = pcicore_find_pci_capability(pi->dev, + PCI_CAP_ID_PM, + NULL, NULL); if (!cap_ptr) return false; @@ -727,7 +712,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi) &pmecap); /* At least one state can generate PME */ - pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0; + pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0; } return pi->pmecap; @@ -743,11 +728,11 @@ void pcicore_pmeen(void *pch) if (!pcicore_pmecap(pi)) return; - pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, &w); - w |= (PME_CSR_PME_EN); + w |= (PCI_PM_CTRL_PME_ENABLE); pci_write_config_dword(pi->dev, - pi->pmecap_offset + PME_CSR_OFFSET, w); + pi->pmecap_offset + PCI_PM_CTRL, w); } /* @@ -761,10 +746,10 @@ bool pcicore_pmestat(void *pch) if (!pcicore_pmecap(pi)) return false; - pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, &w); - return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT; + return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS; } /* Disable PME generation, clear the PME status bit if set @@ -777,16 +762,16 @@ void pcicore_pmeclr(void *pch) if (!pcicore_pmecap(pi)) return; - pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, &w); PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w)); /* PMESTAT is cleared by writing 1 to it */ - w &= ~(PME_CSR_PME_EN); + w &= ~(PCI_PM_CTRL_PME_ENABLE); pci_write_config_dword(pi->dev, - pi->pmecap_offset + PME_CSR_OFFSET, w); + pi->pmecap_offset + PCI_PM_CTRL, w); } u32 pcie_lcreg(void *pch, u32 mask, u32 val) diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/brcmsmac/nvram.c index a697ff10ef36..085ec0b9224f 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/brcmsmac/nvram.c @@ -18,11 +18,8 @@ #include <linux/string.h> #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> #include <bcmnvram.h> #include <sbchipc.h> -#include <bcmsrom.h> -#include <bcmotp.h> #include <bcmdevs.h> #include <hndsoc.h> @@ -43,36 +40,7 @@ static vars_t *vars; static char *findvar(char *vars, char *lim, const char *name); -#if defined(FLASH) -/* copy flash to ram */ -static void get_flash_nvram(si_t *sih, struct nvram_header *nvh) -{ - uint nvs, bufsz; - vars_t *new; - - nvs = R_REG(&nvh->len) - sizeof(struct nvram_header); - bufsz = nvs + VARS_T_OH; - - new = kmalloc(bufsz, GFP_ATOMIC); - if (new == NULL) { - NVR_MSG(("Out of memory for flash vars\n")); - return; - } - new->vars = (char *)new + VARS_T_OH; - - new->bufsz = bufsz; - new->size = nvs; - new->next = vars; - vars = new; - - memcpy(new->vars, &nvh[1], nvs); - - NVR_MSG(("%s: flash nvram @ %p, copied %d bytes to %p\n", __func__, - nvh, nvs, new->vars)); -} -#endif /* FLASH */ - -int nvram_init(void *si) +int nvram_init(void) { /* Make sure we read nvram in flash just once before freeing the memory */ @@ -83,14 +51,14 @@ int nvram_init(void *si) return 0; } -int nvram_append(void *si, char *varlst, uint varsz) +int nvram_append(char *varlst, uint varsz) { uint bufsz = VARS_T_OH; vars_t *new; new = kmalloc(bufsz, GFP_ATOMIC); if (new == NULL) - return BCME_NOMEM; + return -ENOMEM; new->vars = varlst; new->bufsz = bufsz; @@ -98,17 +66,14 @@ int nvram_append(void *si, char *varlst, uint varsz) new->next = vars; vars = new; - return BCME_OK; + return 0; } -void nvram_exit(void *si) +void nvram_exit(void) { vars_t *this, *next; - si_t *sih; - sih = (si_t *) si; this = vars; - if (this) kfree(this->vars); @@ -138,6 +103,49 @@ static char *findvar(char *vars, char *lim, const char *name) return NULL; } +/* + * Search the name=value vars for a specific one and return its value. + * Returns NULL if not found. + */ +char *getvar(char *vars, const char *name) +{ + char *s; + int len; + + if (!name) + return NULL; + + len = strlen(name); + if (len == 0) + return NULL; + + /* first look in vars[] */ + for (s = vars; s && *s;) { + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) + return &s[len + 1]; + + while (*s++) + ; + } + /* then query nvram */ + return nvram_get(name); +} + +/* + * Search the vars for a specific one and return its value as + * an integer. Returns 0 if not found. + */ +int getintvar(char *vars, const char *name) +{ + char *val; + + val = getvar(vars, name); + if (val == NULL) + return 0; + + return simple_strtoul(val, NULL, 0); +} + char *nvram_get(const char *name) { char *v = NULL; @@ -162,7 +170,7 @@ int nvram_unset(const char *name) return 0; } -int nvram_reset(void *si) +int nvram_reset(void) { return 0; } @@ -189,7 +197,7 @@ int nvram_getall(char *buf, int count) while ((from < lim) && (*from)) { len = strlen(from) + 1; if (resid < (acc + len)) - return BCME_BUFTOOSHORT; + return -EOVERFLOW; memcpy(to, from, len); acc += len; from += len; @@ -201,7 +209,7 @@ int nvram_getall(char *buf, int count) this = this->next; } if (resid < 1) - return BCME_BUFTOOSHORT; + return -EOVERFLOW; *buf = '\0'; return 0; } diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 8f75af2ffc58..6cba4dfbc3dd 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -18,10 +18,12 @@ #include <linux/kernel.h> #include <linux/string.h> -#include <bcmdefs.h> +#include <linux/bitops.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> + +#include <bcmdefs.h> #include <bcmnvram.h> #include <sbchipc.h> #include <bcmdevs.h> @@ -155,8 +157,6 @@ char *phy_getvar(phy_info_t *pi, const char *name) char *s; int len; - ASSERT(pi->vars != (char *)&pi->vars); - if (!name) return NULL; @@ -241,7 +241,7 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) break; default: - ASSERT(VALID_PHYTYPE(pi->pubpi.phy_type)); + break; } if ((D11REV_GE(pi->sh->corerev, 24)) || @@ -391,16 +391,6 @@ void write_phy_channel_reg(phy_info_t *pi, uint val) W_REG(&pi->regs->phychannel, val); } -#if defined(BCMDBG) -static bool wlc_phy_war41476(phy_info_t *pi) -{ - u32 mc = R_REG(&pi->regs->maccontrol); - - return ((mc & MCTL_EN_MAC) == 0) - || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK); -} -#endif - u16 read_phy_reg(phy_info_t *pi, u16 addr) { d11regs_t *regs; @@ -412,10 +402,6 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) (void)R_REG(®s->phyregaddr); #endif - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - pi->phy_wreg = 0; return R_REG(®s->phyregdata); } @@ -455,10 +441,6 @@ void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) (void)R_REG(®s->phyregaddr); #endif - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(®s->phyregdata, (R_REG(®s->phyregdata) & val)); pi->phy_wreg = 0; } @@ -474,10 +456,6 @@ void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) (void)R_REG(®s->phyregaddr); #endif - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(®s->phyregdata, (R_REG(®s->phyregdata) | val)); pi->phy_wreg = 0; } @@ -493,10 +471,6 @@ void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) (void)R_REG(®s->phyregaddr); #endif - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(®s->phyregdata, ((R_REG(®s->phyregdata) & ~mask) | (val & mask))); pi->phy_wreg = 0; @@ -579,14 +553,12 @@ shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) void wlc_phy_shared_detach(shared_phy_t *phy_sh) { if (phy_sh) { - if (phy_sh->phy_head) { - ASSERT(!phy_sh->phy_head); - } kfree(phy_sh); } } -wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars) +wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, + char *vars, struct wiphy *wiphy) { phy_info_t *pi; u32 sflags = 0; @@ -596,7 +568,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars if (D11REV_IS(sh->corerev, 4)) sflags = SISF_2G_PHY | SISF_5G_PHY; else - sflags = si_core_sflags(sh->sih, 0, 0); + sflags = ai_core_sflags(sh->sih, 0, 0); if (BAND_5G(bandtype)) { if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) { @@ -616,6 +588,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars if (pi == NULL) { return NULL; } + pi->wiphy = wiphy; pi->regs = (d11regs_t *) regs; pi->sh = sh; pi->phy_init_por = true; @@ -781,8 +754,6 @@ void wlc_phy_detach(wlc_phy_t *pih) pi->sh->phy_head = pi->next; else if (pi->sh->phy_head->next == pi) pi->sh->phy_head->next = NULL; - else - ASSERT(0); if (pi->pi_fptr.detach) (pi->pi_fptr.detach) (pi); @@ -894,7 +865,6 @@ u32 wlc_phy_clk_bwbits(wlc_phy_t *pih) phy_bw_clkbits = SICF_BW40; break; default: - ASSERT(0); break; } } @@ -962,24 +932,20 @@ void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) pi->radio_chanspec = chanspec; mc = R_REG(&pi->regs->maccontrol); - if ((mc & MCTL_EN_MAC) != 0) { - ASSERT((const char *) - "wlc_phy_init: Called with the MAC running!" == NULL); - } - - ASSERT(pi != NULL); + if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init")) + return; if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; } - if (D11REV_GE(pi->sh->corerev, 5)) - ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA); + if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA), + "HW error SISF_FCLKA\n")) + return; phy_init = pi->pi_fptr.init; if (phy_init == NULL) { - ASSERT(phy_init != NULL); return; } @@ -1013,7 +979,9 @@ void wlc_phy_cal_init(wlc_phy_t *pih) phy_info_t *pi = (phy_info_t *) pih; initfn_t cal_init = NULL; - ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0); + if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0, + "HW error: MAC enabled during phy cal\n")) + return; if (!pi->initialized) { cal_init = pi->pi_fptr.calinit; @@ -1029,8 +997,6 @@ int wlc_phy_down(wlc_phy_t *pih) phy_info_t *pi = (phy_info_t *) pih; int callbacks = 0; - ASSERT(pi->phytest_on == false); - if (pi->phycal_timer && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer)) callbacks++; @@ -1070,8 +1036,6 @@ wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) { - ASSERT((width == 8) || (width == 16) || (width == 32)); - if ((pi->sh->chip == BCM43224_CHIP_ID || pi->sh->chip == BCM43421_CHIP_ID) && (pi->sh->chiprev == 1) && @@ -1105,8 +1069,6 @@ wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr; const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr; - ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); - write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); for (idx = 0; idx < ptbl_info->tbl_len; idx++) { @@ -1148,8 +1110,6 @@ wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr; u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr; - ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); - write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); for (idx = 0; idx < ptbl_info->tbl_len; idx++) { @@ -1243,8 +1203,6 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) }; u32 *dummypkt; - ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0); - dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt); wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN, dummypkt); @@ -1258,7 +1216,6 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) W_REG(®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); if (ISNPHY(pi) || ISLCNPHY(pi)) { - ASSERT(ofdm); W_REG(®s->txe_phyctl1, 0x1A02); } @@ -1317,7 +1274,6 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set) { phy_info_t *pi = (phy_info_t *) pih; - ASSERT(id); if (set) { mboolset(pi->measure_hold, id); @@ -1439,8 +1395,6 @@ void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec) u16 m_cur_channel; chansetfn_t chanspec_set = NULL; - ASSERT(!wf_chspec_malformed(chanspec)); - m_cur_channel = CHSPEC_CHANNEL(chanspec); if (CHSPEC_IS5G(chanspec)) m_cur_channel |= D11_CURCHANNEL_5G; @@ -1480,8 +1434,7 @@ int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec) range = wlc_phy_get_chan_freq_range_nphy(pi, channel); } else if (ISLCNPHY(pi)) { range = wlc_phy_chanspec_freq2bandrange_lpssn(freq); - } else - ASSERT(0); + } return range; } @@ -1511,8 +1464,6 @@ wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) uint i; uint channel; - ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); - memset(channels, 0, sizeof(chanvec_t)); for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { @@ -1535,8 +1486,6 @@ chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) uint channel; chanspec_t chspec; - ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); - for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { channel = chan_info_all[i].chan; @@ -1572,8 +1521,6 @@ chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) return chspec; } - ASSERT(0); - return (chanspec_t) INVCHANSPEC; } @@ -1581,7 +1528,6 @@ int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override) { phy_info_t *pi = (phy_info_t *) ppi; - ASSERT(qdbm != NULL); *qdbm = pi->tx_user_target[0]; if (override != NULL) *override = pi->txpwroverride; @@ -1703,7 +1649,6 @@ wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, break; } } - ASSERT(i < ARRAY_SIZE(chan_info_all)); if (pi->hwtxpwr) { *max_pwr = pi->hwtxpwr[i]; @@ -2134,7 +2079,6 @@ void wlc_phy_txpower_update_shm(phy_info_t *pi) { int j; if (ISNPHY(pi)) { - ASSERT(0); return; } @@ -2466,8 +2410,6 @@ void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1); mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0); } - } else { - ASSERT(0); } if (!suspend) @@ -2483,7 +2425,6 @@ wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) u8 i; memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm)); - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum); for (i = 0; i < pi->pubpi.phy_corenum; i++) { @@ -2529,7 +2470,6 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) break; default: - ASSERT(0); break; } @@ -2678,7 +2618,6 @@ static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; u8 idx, core; - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); @@ -2760,8 +2699,6 @@ void wlc_phy_noise_sample_intr(wlc_phy_t *pih) channel = jssi_aux & D11_CURCHANNEL_MAX; noise_dbm = wlc_phy_noise_read_shmem(pi); - } else { - ASSERT(0); } wlc_phy_noise_cb(pi, channel, noise_dbm); @@ -2811,25 +2748,20 @@ s8 lcnphy_gain_index_offset_for_pkt_rssi[] = { void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core) { - u8 shift_ct, lsb, msb, secondmsb, i; + u8 msb, secondmsb, i; u32 tmp; for (i = 0; i < core; i++) { + secondmsb = 0; tmp = cmplx_pwr[i]; - shift_ct = msb = secondmsb = 0; - while (tmp != 0) { - tmp = tmp >> 1; - shift_ct++; - lsb = (u8) (tmp & 1); - if (lsb == 1) - msb = shift_ct; - } - secondmsb = (u8) ((cmplx_pwr[i] >> (msb - 1)) & 1); + msb = fls(tmp); + if (msb) + secondmsb = (u8) ((tmp >> (--msb - 1)) & 1); p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb); } } -void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) +void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) { wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx; d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr; @@ -2871,10 +2803,7 @@ void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) rssi -= 256; } else if (radioid == BCM2055_ID || radioid == BCM2056_ID || radioid == BCM2057_ID) { - ASSERT(ISNPHY(pi)); rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr); - } else { - ASSERT((const char *)"Unknown radio" == NULL); } end: @@ -2900,9 +2829,6 @@ void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag) wlc_lcnphy_deaf_mode(pi, true); else if (ISNPHY(pi)) wlc_nphy_deaf_mode(pi, true); - else { - ASSERT(0); - } } void wlc_phy_watchdog(wlc_phy_t *pih) @@ -3163,13 +3089,9 @@ void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason) } else if (pi->nphy_perical == PHY_PERICAL_SPHASE) wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); - else { - ASSERT(0); - } } break; default: - ASSERT(0); break; } } @@ -3192,25 +3114,6 @@ u8 wlc_phy_nbits(s32 value) return nbits; } -u32 wlc_phy_sqrt_int(u32 value) -{ - u32 root = 0, shift = 0; - - for (shift = 0; shift < 32; shift += 2) { - if (((0x40000000 >> shift) + root) <= value) { - value -= ((0x40000000 >> shift) + root); - root = (root >> 1) | (0x40000000 >> shift); - } else { - root = root >> 1; - } - } - - if (root < value) - ++root; - - return root; -} - void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain) { phy_info_t *pi = (phy_info_t *) pih; @@ -3311,12 +3214,12 @@ void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2); } - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpiocontrol), ~0x0, 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioout), 0x40, 0x40); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioouten), 0x40, 0x40); } else { @@ -3324,11 +3227,11 @@ void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioout), 0x40, 0x00); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioouten), 0x40, 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpiocontrol), ~0x0, 0x40); } @@ -3387,33 +3290,6 @@ wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset) *ofdmoffset = 0; } -u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) -{ - u32 quotient, remainder, roundup, rbit; - - ASSERT(divisor); - - quotient = dividend / divisor; - remainder = dividend % divisor; - rbit = divisor & 1; - roundup = (divisor >> 1) + rbit; - - while (precision--) { - quotient <<= 1; - if (remainder >= roundup) { - quotient++; - remainder = ((remainder - roundup) << 1) + rbit; - } else { - remainder <<= 1; - } - } - - if (remainder >= roundup) - quotient++; - - return quotient; -} - s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec) { diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h index bf962d5b339a..8939153efa56 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h @@ -18,9 +18,10 @@ #define _wlc_phy_h_ #include <wlioctl.h> -#include <siutils.h> +#include <aiutils.h> #include <d11.h> #include <wlc_phy_shim.h> +#include <net/mac80211.h> /* struct wiphy */ #define IDCODE_VER_MASK 0x0000000f #define IDCODE_VER_SHIFT 0 @@ -149,7 +150,7 @@ typedef struct shared_phy_params { extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp); extern void wlc_phy_shared_detach(shared_phy_t *phy_sh); extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, - char *vars); + char *vars, struct wiphy *wiphy); extern void wlc_phy_detach(wlc_phy_t *ppi); extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h index 6e12a95c7360..10cbf520474f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h @@ -936,6 +936,7 @@ struct phy_info { u8 phycal_tempdelta; u32 mcs20_po; u32 mcs40_po; + struct wiphy *wiphy; }; typedef s32 fixed; @@ -1024,7 +1025,6 @@ extern void wlc_phy_txpower_update_shm(phy_info_t *pi); extern void wlc_phy_cordic(fixed theta, cs32 *val); extern u8 wlc_phy_nbits(s32 value); -extern u32 wlc_phy_sqrt_int(u32 value); extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi, @@ -1093,8 +1093,6 @@ extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode); extern void wlc_2064_vco_cal(phy_info_t *pi); extern void wlc_phy_txpower_recalc_target(phy_info_t *pi); -extern u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, - u8 precision); #define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 #define LCNPHY_TX_POWER_TABLE_SIZE 128 diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index a5a7bb82ab42..b8864c5b7a19 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -19,18 +19,19 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <wlc_cfg.h> -#include <qmath.h> #include <linux/pci.h> -#include <siutils.h> -#include <hndpmu.h> +#include <aiutils.h> +#include <wlc_pmu.h> +#include <bcmnvram.h> #include <bcmdevs.h> #include <sbhnddma.h> -#include <wlc_phy_radio.h> -#include <wlc_phy_int.h> -#include <wlc_phy_lcn.h> -#include <wlc_phytbl_lcn.h> +#include "wlc_phy_radio.h" +#include "wlc_phy_int.h" +#include "wlc_phy_qmath.h" +#include "wlc_phy_lcn.h" +#include "wlc_phytbl_lcn.h" #define PLL_2064_NDIV 90 #define PLL_2064_LOW_END_VCO 3000 @@ -1081,8 +1082,6 @@ wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) { u32 quotient, remainder, roundup, rbit; - ASSERT(divisor); - quotient = dividend / divisor; remainder = dividend % divisor; rbit = divisor & 1; @@ -1780,11 +1779,6 @@ void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode) s8 index; phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - ASSERT((LCNPHY_TX_PWR_CTRL_OFF == mode) || - (LCNPHY_TX_PWR_CTRL_SW == mode) || - (LCNPHY_TX_PWR_CTRL_HW == mode) || - (LCNPHY_TX_PWR_CTRL_TEMPBASED == mode)); - mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode); old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode); @@ -1904,16 +1898,14 @@ wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, break; case LCNPHY_CAL_RECAL: - ASSERT(pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid); - start_coeffs = syst_coeffs; - cal_cmds = commands_recal; n_cal_cmds = ARRAY_SIZE(commands_recal); command_nums = command_nums_recal; break; + default: - ASSERT(false); + break; } wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, @@ -2460,8 +2452,6 @@ void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index) lcnphy_txgains_t gains; phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - ASSERT(index <= LCNPHY_MAX_TX_POWER_INDEX); - pi_lcn->lcnphy_tx_power_idx_override = (s8) index; pi_lcn->lcnphy_current_index = (u8) index; @@ -2760,7 +2750,6 @@ wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, do { bw = phy_bw * 1000 * k; num_samps = bw / ABS(f_kHz); - ASSERT(num_samps <= ARRAY_SIZE(data_buf)); k++; } while ((num_samps * (u32) (ABS(f_kHz))) != bw); } else @@ -3255,7 +3244,7 @@ static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps) } b /= temp; b -= a * a; - b = (s32) wlc_phy_sqrt_int((u32) b); + b = (s32) int_sqrt((unsigned long) b); b -= (1 << 10); a0_new = (u16) (a & 0x3ff); b0_new = (u16) (b & 0x3ff); @@ -3298,8 +3287,6 @@ wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, return false; } if (module == 2) { - ASSERT(iqcomp_sz); - while (iqcomp_sz--) { if (iqcomp[iqcomp_sz].chan == CHSPEC_CHANNEL(pi->radio_chanspec)) { @@ -3313,7 +3300,6 @@ wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, break; } } - ASSERT(result); goto cal_done; } @@ -3584,9 +3570,6 @@ void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode) if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi); break; - default: - ASSERT(0); - break; } } @@ -5071,9 +5054,7 @@ bool wlc_phy_attach_lcnphy(phy_info_t *pi) pi->hwpwrctrl_capable = true; } - pi->xtalfreq = si_alp_clock(pi->sh->sih); - ASSERT(0 == (pi->xtalfreq % 1000)); - + pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih); pi_lcn->lcnphy_papd_rxGnCtrl_init = 0; pi->pi_fptr.init = wlc_phy_init_lcnphy; @@ -5293,9 +5274,7 @@ wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type) } } - if (filt_index == -1) { - ASSERT(false); - } else { + if (filt_index != -1) { for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { write_phy_reg(pi, addr[j], LCNPHY_txdigfiltcoeffs_cck @@ -5310,9 +5289,7 @@ wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type) } } - if (filt_index == -1) { - ASSERT(false); - } else { + if (filt_index != -1) { for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { write_phy_reg(pi, addr_ofdm[j], LCNPHY_txdigfiltcoeffs_ofdm diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index 7947c6028b6e..71275094e810 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -20,9 +20,9 @@ #include <wlc_cfg.h> #include <linux/delay.h> #include <linux/pci.h> -#include <siutils.h> +#include <aiutils.h> #include <sbchipc.h> -#include <hndpmu.h> +#include <wlc_pmu.h> #include <bcmdevs.h> #include <sbhnddma.h> @@ -14218,8 +14218,6 @@ static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi) { u16 addr, val; - ASSERT(ISNPHY(pi)); - val = 0x1e1f; for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT); addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) { @@ -14367,8 +14365,6 @@ static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) break; default: - - ASSERT(0); break; } @@ -14401,8 +14397,6 @@ static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) [idx]); break; default: - - ASSERT(0); break; } } else { @@ -14550,7 +14544,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) (pi->sh->chippkg == BCM4718_PKG_ID))) { if ((pi->sh->boardflags & BFL_EXTLNA) && (CHSPEC_IS2G(pi->radio_chanspec))) { - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), 0x40, 0x40); } @@ -14564,17 +14558,15 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && CHSPEC_IS40(pi->radio_chanspec)) { - regs = (d11regs_t *) si_switch_core(pi->sh->sih, D11_CORE_ID, + regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID, &origidx, &intr_val); - ASSERT(regs != NULL); - d11_clk_ctl_st = R_REG(®s->clk_ctl_st); AND_REG(®s->clk_ctl_st, ~(CCS_FORCEHT | CCS_HTAREQ)); W_REG(®s->clk_ctl_st, d11_clk_ctl_st); - si_restore_core(pi->sh->sih, origidx, intr_val); + ai_restore_core(pi->sh->sih, origidx, intr_val); } pi->use_int_tx_iqlo_cal_nphy = @@ -14783,10 +14775,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) rfpwr_offset = (s16) nphy_papd_padgain_dlt_2g_2057rev7 [pad_gn]; - } else { - ASSERT(0); } - } else { if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) || @@ -14800,8 +14789,6 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) rfpwr_offset = (s16) nphy_papd_pgagain_dlt_5g_2057rev7 [pga_gn]; - } else { - ASSERT(0); } } wlc_phy_table_write_nphy(pi, @@ -14905,10 +14892,10 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } if (wlc_phy_cal_txiqlo_nphy - (pi, target_gain, true, false) == BCME_OK) { + (pi, target_gain, true, false) == 0) { if (wlc_phy_cal_rxiq_nphy (pi, target_gain, 2, - false) == BCME_OK) { + false) == 0) { wlc_phy_savecal_nphy(pi); } @@ -14963,8 +14950,6 @@ static void wlc_phy_resetcca_nphy(phy_info_t *pi) { u16 val; - ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); val = read_phy_reg(pi, 0x01); @@ -16130,8 +16115,6 @@ static void wlc_phy_workarounds_nphy(phy_info_t *pi) 0x18, 16, bcm_adc_vmid); wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16, bcm_adc_gain); - } else { - ASSERT(0); } write_radio_reg(pi, @@ -17418,8 +17401,10 @@ static void wlc_phy_radio_postinit_2055(phy_info_t *pi) SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000); - ASSERT((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & - RADIO_2055_RCAL_DONE) == RADIO_2055_RCAL_DONE); + if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & + RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE, + "HW error: radio calibration1\n")) + return; and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, ~(RADIO_2055_CAL_LPO_ENABLE)); @@ -17510,7 +17495,6 @@ static void wlc_phy_radio_init_2056(phy_info_t *pi) break; default: - ASSERT(0); break; } } @@ -17571,7 +17555,6 @@ static void wlc_phy_radio_init_2057(phy_info_t *pi) regs_2057_ptr = regs_2057_rev5v1; } else { - ASSERT(0); break; } @@ -17586,11 +17569,8 @@ static void wlc_phy_radio_init_2057(phy_info_t *pi) break; default: - ASSERT(0); break; } - } else { - ASSERT(0); } wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); @@ -17708,7 +17688,6 @@ wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, } if (i >= tbl_len) { - ASSERT(i < tbl_len); goto fail; } if (pi->pubpi.radiorev == 5) { @@ -17765,7 +17744,6 @@ wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, } if (i >= tbl_len) { - ASSERT(i < tbl_len); goto fail; } *t1 = &chan_info_tbl_p_1[i]; @@ -17777,7 +17755,6 @@ wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, break; if (i >= ARRAY_SIZE(chan_info_nphy_2055)) { - ASSERT(i < ARRAY_SIZE(chan_info_nphy_2055)); goto fail; } *t3 = &chan_info_nphy_2055[i]; @@ -18276,7 +18253,9 @@ static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) udelay(100); } - ASSERT(i < MAX_205x_RCAL_WAITLOOPS); + if (WARN(i == MAX_205x_RCAL_WAITLOOPS, + "HW error: radio calib2")) + return 0; mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0); @@ -18325,7 +18304,9 @@ static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) udelay(100); } - ASSERT(i < MAX_205x_RCAL_WAITLOOPS); + if (WARN(i == MAX_205x_RCAL_WAITLOOPS, + "HW error: radio calib3")) + return 0; write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, 0x1); @@ -18572,8 +18553,6 @@ static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) udelay(500); } - ASSERT(rccal_valid & 0x2); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); rccal_valid = 0; @@ -18596,8 +18575,6 @@ static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) udelay(500); } - ASSERT(rccal_valid & 0x2); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); rccal_valid = 0; @@ -18621,7 +18598,8 @@ static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) udelay(500); } - ASSERT(rccal_valid & 0x2); + if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4")) + return 0; write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); @@ -19585,8 +19563,6 @@ void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) 1, 0x08, 16, &v2); wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, 1, 0x0C, 16, &v3); - } else { - ASSERT(0); } if (pi->srom_fem5g.antswctrllut == 0) { @@ -19598,15 +19574,13 @@ void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) 1, 0x18, 16, &v2); wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, 1, 0x1C, 16, &v3); - } else { - ASSERT(0); } } else { write_phy_reg(pi, 0xc8, 0x0); write_phy_reg(pi, 0xc9, 0x0); - si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); + ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); mc = R_REG(&pi->regs->maccontrol); mc &= ~MCTL_GPOUT_SEL_MASK; @@ -19703,8 +19677,7 @@ void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd) or_phy_reg(pi, 0xa3, trigger_mask); SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000); write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); - - ASSERT((read_phy_reg(pi, 0xa4) & status_mask) == 0); + WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf"); } static void @@ -19718,8 +19691,6 @@ wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys, 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END; u8 end_dly = 1; - ASSERT(len <= 16); - if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, true); @@ -21467,7 +21438,7 @@ static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type) wlc_phy_resetcca_nphy(pi); } -int BCMFASTPATH +int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) { d11rxhdr_t *rxh = &wlc_rxh->rxhdr; @@ -21503,8 +21474,6 @@ wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1; else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG) rxpwr = (rxpwr0 + rxpwr1) >> 1; - else - ASSERT(0); return rxpwr; } @@ -21588,8 +21557,9 @@ wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value, SPINWAIT(((read_phy_reg(pi, 0x78) & val) != 0), 10000); - ASSERT((read_phy_reg(pi, 0x78) & val) == - 0); + if (WARN(read_phy_reg(pi, 0x78) & val, + "HW error: override failed")) + return; mask = (0x1 << 0); val = 0 << 0; @@ -22233,8 +22203,6 @@ static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) static void wlc_phy_restore_rssical_nphy(phy_info_t *pi) { - ASSERT(NREV_GE(pi->pubpi.phy_rev, 3)); - if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->nphy_rssical_chanspec_2G == 0) return; @@ -22399,13 +22367,13 @@ wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode); if (num_samps == 0) { - return BCME_ERROR; + return -EBADE; } wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode, dac_test_mode, modify_bbmult); - return BCME_OK; + return 0; } static void @@ -22775,8 +22743,6 @@ wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no, } } - ASSERT(idx != -1); - params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; @@ -23855,8 +23821,6 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) if (PHY_MUTED(pi)) return; - ASSERT(pi->nphy_perical != PHY_PERICAL_DISABLE); - if (caltype == PHY_PERICAL_AUTO) fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec); else if (caltype == PHY_PERICAL_PARTIAL) @@ -23913,7 +23877,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) target_gain = pi->nphy_cal_target_gain; } - if (BCME_OK == + if (0 == wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) { if (PHY_IPA(pi)) wlc_phy_a4(pi, true); @@ -23925,7 +23889,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_phyreg_enter((wlc_phy_t *) pi); - if (BCME_OK == wlc_phy_cal_rxiq_nphy(pi, target_gain, + if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain, (pi-> first_cal_after_assoc || (pi-> @@ -23955,8 +23919,6 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) wlc_phy_radio205x_vcocal_nphy(pi); } } else { - ASSERT(pi->nphy_perical >= PHY_PERICAL_MPHASE); - switch (pi->mphase_cal_phase_id) { case MPHASE_CAL_STATE_INIT: pi->nphy_perical_last = pi->sh->now; @@ -23980,7 +23942,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) if (wlc_phy_cal_txiqlo_nphy (pi, pi->nphy_cal_target_gain, fullcal, - true) != BCME_OK) { + true) != 0) { wlc_phy_cal_perical_mphase_reset(pi); break; @@ -24012,7 +23974,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) (pi->first_cal_after_assoc || (pi->cal_type_override == PHY_PERICAL_FULL)) ? 2 : 0, - false) == BCME_OK) { + false) == 0) { wlc_phy_savecal_nphy(pi); } @@ -24052,7 +24014,6 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) break; default: - ASSERT(0); wlc_phy_cal_perical_mphase_reset(pi); break; } @@ -24116,7 +24077,7 @@ wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, void *tbl_ptr; bool ladder_updated[2]; u8 mphase_cal_lastphase = 0; - int bcmerror = BCME_OK; + int bcmerror = 0; bool phyhang_avoid_state = false; u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { @@ -24242,13 +24203,13 @@ wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false); - bcmerror = BCME_OK; + bcmerror = 0; } else { bcmerror = wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false); } - if (bcmerror == BCME_OK) { + if (bcmerror == 0) { if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { tbl_ptr = pi->mphase_txcal_bestcoeffs; @@ -24361,7 +24322,9 @@ wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0), 20000); - ASSERT((read_phy_reg(pi, 0xc0) & 0xc000) == 0); + if (WARN(read_phy_reg(pi, 0xc0) & 0xc000, + "HW error: txiq calib")) + return -EIO; wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 96, 16, tbl_buf); @@ -24468,8 +24431,6 @@ static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi) { u16 tbl_buf[7]; - ASSERT(NREV_LT(pi->pubpi.phy_rev, 2)); - if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) && (pi->nphy_txiqlocal_coeffsvalid)) { wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, @@ -24544,10 +24505,11 @@ wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps, SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0), 10000); - ASSERT((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0); + if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart, + "HW error: rxiq est")) + return; if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) { - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); for (core = 0; core < pi->pubpi.phy_corenum; core++) { est[core].i_pwr = (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16) @@ -24572,7 +24534,7 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) u32 ii = 0, qq = 0; s16 iq_nbits, qq_nbits, brsh, arsh; s32 a, b, temp; - int bcmerror = BCME_OK; + int bcmerror = 0; uint cal_retry = 0; if (core_mask == 0x0) @@ -24602,7 +24564,7 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) } if ((ii + qq) < NPHY_MIN_RXIQ_PWR) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } @@ -24614,14 +24576,14 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); temp = (s32) (ii >> arsh); if (temp == 0) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } } else { a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); temp = (s32) (ii << -arsh); if (temp == 0) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } } @@ -24633,20 +24595,20 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) b = (qq << (31 - qq_nbits)); temp = (s32) (ii >> brsh); if (temp == 0) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } } else { b = (qq << (31 - qq_nbits)); temp = (s32) (ii << -brsh); if (temp == 0) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } } b /= temp; b -= a * a; - b = (s32) wlc_phy_sqrt_int((u32) b); + b = (s32) int_sqrt((unsigned long) b); b -= (1 << 10); if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) { @@ -24671,7 +24633,7 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) } } - if (bcmerror != BCME_OK) { + if (bcmerror != 0) { printk("%s: Failed, cnt = %d\n", __func__, cal_retry); if (cal_retry < CAL_RETRY_CNT) { @@ -25451,7 +25413,7 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, break; default: - ASSERT(0); + break; } if ((curr_gaintbl_index < 0) || @@ -25916,7 +25878,7 @@ wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, wlc_phy_stay_in_carriersearch_nphy(pi, false); - return BCME_OK; + return 0; } static int @@ -25941,7 +25903,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, u16 cal_gain[2]; nphy_iqcal_params_t cal_params[2]; u8 phy_bw; - int bcmerror = BCME_OK; + int bcmerror = 0; bool first_playtone = true; wlc_phy_stay_in_carriersearch_nphy(pi, true); @@ -26091,7 +26053,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, 0, 0, 0, true); } - if (bcmerror == BCME_OK) { + if (bcmerror == 0) { if (gain_pass < 3) { wlc_phy_rx_iq_est_nphy(pi, est, @@ -26114,7 +26076,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, wlc_phy_stopplayback_nphy(pi); } - if (bcmerror != BCME_OK) + if (bcmerror != 0) break; } @@ -26130,7 +26092,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, 0xa7, orig_AfectrlCore); write_phy_reg(pi, 0xa2, orig_RfseqCoreActv); - if (bcmerror != BCME_OK) + if (bcmerror != 0) break; } @@ -26270,8 +26232,6 @@ static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_2g_2057rev7; - } else { - ASSERT(0); } } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { @@ -26303,8 +26263,6 @@ static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057rev7; - } else { - ASSERT(0); } } else { @@ -26347,8 +26305,6 @@ wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, || (pi->pubpi.radiorev == 6)) { mixgain = 0x00; - } else { - ASSERT(0); } } else { @@ -26361,8 +26317,6 @@ wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, || (pi->pubpi.radiorev == 8)) { mixgain = 0x0; - } else { - ASSERT(0); } } @@ -26464,8 +26418,6 @@ wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TXRXCOUPLE_2G_ATTEN, 0xf0); - } else { - ASSERT(0); } WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, @@ -26724,8 +26676,6 @@ wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start, u32 *buf, *src, *dst, sz; sz = end - start + 1; - ASSERT(end > start); - ASSERT(end < NPHY_PAPD_EPS_TBL_SIZE); buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC); if (NULL == buf) { @@ -26787,8 +26737,6 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, phy_a7 = (core == PHY_CORE_0) ? 1 : 0; - ASSERT((cal_mode == CAL_FULL) || (cal_mode == CAL_GCTRL) - || (cal_mode == CAL_SOFT)); phy_a6 = ((cal_mode == CAL_GCTRL) || (cal_mode == CAL_SOFT)) ? true : false; @@ -27333,8 +27281,6 @@ static void wlc_phy_a4(phy_info_t *pi, bool full_cal) nphy_papd_cal_gain_index [phy_b5], phy_b5); - } else { - ASSERT(0); } phy_b1[phy_b5].gains.pad[phy_b5] = @@ -27417,8 +27363,6 @@ static void wlc_phy_a4(phy_info_t *pi, bool full_cal) -(nphy_papd_padgain_dlt_2g_2057rev7 [phy_b8] + 1) / 2; - } else { - ASSERT(0); } } else { phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5]; @@ -27435,8 +27379,6 @@ static void wlc_phy_a4(phy_info_t *pi, bool full_cal) -(nphy_papd_pgagain_dlt_5g_2057rev7 [phy_b7] + 1) / 2; - } else { - ASSERT(0); } phy_b10 = -9; @@ -27536,8 +27478,6 @@ void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) u8 txpi[2], chan_freq_range; s32 rfpwr_offset; - ASSERT(pi->nphy_txpwrctrl == PHY_TPC_HW_OFF); - if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, true); @@ -29179,7 +29119,6 @@ wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr, *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx]; break; default: - ASSERT(0); *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; break; } @@ -29191,8 +29130,6 @@ void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) { u16 clip_off[] = { 0xffff, 0xffff }; - ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); - if (enable) { if (pi->nphy_deaf_count == 0) { pi->classifier_state = @@ -29207,8 +29144,6 @@ void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) wlc_phy_resetcca_nphy(pi); } else { - ASSERT(pi->nphy_deaf_count > 0); - pi->nphy_deaf_count--; if (pi->nphy_deaf_count == 0) { diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c new file mode 100644 index 000000000000..c98176fd0aae --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2010 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 <linux/types.h> + +#include "wlc_phy_qmath.h" + +/* +Description: This function make 16 bit unsigned multiplication. To fit the output into +16 bits the 32 bit multiplication result is right shifted by 16 bits. +*/ +u16 qm_mulu16(u16 op1, u16 op2) +{ + return (u16) (((u32) op1 * (u32) op2) >> 16); +} + +/* +Description: This function make 16 bit multiplication and return the result in 16 bits. +To fit the multiplication result into 16 bits the multiplication result is right shifted by +15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed +due to the multiplication. +When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff. +*/ +s16 qm_muls16(s16 op1, s16 op2) +{ + s32 result; + if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) { + result = 0x7fffffff; + } else { + result = ((s32) (op1) * (s32) (op2)); + } + return (s16) (result >> 15); +} + +/* +Description: This function add two 32 bit numbers and return the 32bit result. +If the result overflow 32 bits, the output will be saturated to 32bits. +*/ +s32 qm_add32(s32 op1, s32 op2) +{ + s32 result; + result = op1 + op2; + if (op1 < 0 && op2 < 0 && result > 0) { + result = 0x80000000; + } else if (op1 > 0 && op2 > 0 && result < 0) { + result = 0x7fffffff; + } + return result; +} + +/* +Description: This function add two 16 bit numbers and return the 16bit result. +If the result overflow 16 bits, the output will be saturated to 16bits. +*/ +s16 qm_add16(s16 op1, s16 op2) +{ + s16 result; + s32 temp = (s32) op1 + (s32) op2; + if (temp > (s32) 0x7fff) { + result = (s16) 0x7fff; + } else if (temp < (s32) 0xffff8000) { + result = (s16) 0xffff8000; + } else { + result = (s16) temp; + } + return result; +} + +/* +Description: This function make 16 bit subtraction and return the 16bit result. +If the result overflow 16 bits, the output will be saturated to 16bits. +*/ +s16 qm_sub16(s16 op1, s16 op2) +{ + s16 result; + s32 temp = (s32) op1 - (s32) op2; + if (temp > (s32) 0x7fff) { + result = (s16) 0x7fff; + } else if (temp < (s32) 0xffff8000) { + result = (s16) 0xffff8000; + } else { + result = (s16) temp; + } + return result; +} + +/* +Description: This function make a 32 bit saturated left shift when the specified shift +is +ve. This function will make a 32 bit right shift when the specified shift is -ve. +This function return the result after shifting operation. +*/ +s32 qm_shl32(s32 op, int shift) +{ + int i; + s32 result; + result = op; + if (shift > 31) + shift = 31; + else if (shift < -31) + shift = -31; + if (shift >= 0) { + for (i = 0; i < shift; i++) { + result = qm_add32(result, result); + } + } else { + result = result >> (-shift); + } + return result; +} + +/* +Description: This function make a 16 bit saturated left shift when the specified shift +is +ve. This function will make a 16 bit right shift when the specified shift is -ve. +This function return the result after shifting operation. +*/ +s16 qm_shl16(s16 op, int shift) +{ + int i; + s16 result; + result = op; + if (shift > 15) + shift = 15; + else if (shift < -15) + shift = -15; + if (shift > 0) { + for (i = 0; i < shift; i++) { + result = qm_add16(result, result); + } + } else { + result = result >> (-shift); + } + return result; +} + +/* +Description: This function make a 16 bit right shift when shift is +ve. +This function make a 16 bit saturated left shift when shift is -ve. This function +return the result of the shift operation. +*/ +s16 qm_shr16(s16 op, int shift) +{ + return qm_shl16(op, -shift); +} + +/* +Description: This function return the number of redundant sign bits in a 32 bit number. +Example: qm_norm32(0x00000080) = 23 +*/ +s16 qm_norm32(s32 op) +{ + u16 u16extraSignBits; + if (op == 0) { + return 31; + } else { + u16extraSignBits = 0; + while ((op >> 31) == (op >> 30)) { + u16extraSignBits++; + op = op << 1; + } + } + return u16extraSignBits; +} + +/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */ +static const s16 log_table[] = { + 0, + 1455, + 2866, + 4236, + 5568, + 6863, + 8124, + 9352, + 10549, + 11716, + 12855, + 13968, + 15055, + 16117, + 17156, + 18173, + 19168, + 20143, + 21098, + 22034, + 22952, + 23852, + 24736, + 25604, + 26455, + 27292, + 28114, + 28922, + 29717, + 30498, + 31267, + 32024 +}; + +#define LOG_TABLE_SIZE 32 /* log_table size */ +#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */ +#define Q_LOG_TABLE 15 /* qformat of log_table */ +#define LOG10_2 19728 /* log10(2) in q.16 */ + +/* +Description: +This routine takes the input number N and its q format qN and compute +the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format. +mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed. +From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed. +This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs. +As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. +Next 16 MSBs are used for interpolation. +Inputs: +N - number to which log10 has to be found. +qN - q format of N +log10N - address where log10(N) will be written. +qLog10N - address where log10N qformat will be written. +Note/Problem: +For accurate results input should be in normalized or near normalized form. +*/ +void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N) +{ + s16 s16norm, s16tableIndex, s16errorApproximation; + u16 u16offset; + s32 s32log; + + /* normalize the N. */ + s16norm = qm_norm32(N); + N = N << s16norm; + + /* The qformat of N after normalization. + * -30 is added to treat the no as between 1.0 to 2.0 + * i.e. after adding the -30 to the qformat the decimal point will be + * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e. + * at the right side of 30th bit. + */ + qN = qN + s16norm - 30; + + /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */ + s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE))); + + /* remove the MSB. the MSB is always 1 after normalization. */ + s16tableIndex = + s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1); + + /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */ + N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1); + + /* take the offset as the 16 MSBS after table index. + */ + u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16))); + + /* look the log value in the table. */ + s32log = log_table[s16tableIndex]; /* q.15 format */ + + /* interpolate using the offset. */ + s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */ + + s32log = qm_add16((s16) s32log, s16errorApproximation); /* q.15 format */ + + /* adjust for the qformat of the N as + * log2(mag * 2^x) = log2(mag) + x + */ + s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */ + + /* normalize the result. */ + s16norm = qm_norm32(s32log); + + /* bring all the important bits into lower 16 bits */ + s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */ + + /* compute the log10(N) by multiplying log2(N) with log10(2). + * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2) + * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16) + */ + *log10N = qm_muls16((s16) s32log, (s16) LOG10_2); + + /* write the q format of the result. */ + *qLog10N = 15 + s16norm - 16 + 1; + + return; +} diff --git a/drivers/staging/brcm80211/include/qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h index 5f525dbcd46e..3dcee1c4aa65 100644 --- a/drivers/staging/brcm80211/include/qmath.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h @@ -17,14 +17,6 @@ #ifndef __QMATH_H__ #define __QMATH_H__ -s16 qm_sat32(s32 op); - -s32 qm_mul321616(s16 op1, s16 op2); - -s16 qm_mul16(s16 op1, s16 op2); - -s32 qm_muls321616(s16 op1, s16 op2); - u16 qm_mulu16(u16 op1, u16 op2); s16 qm_muls16(s16 op1, s16 op2); @@ -35,44 +27,14 @@ s16 qm_add16(s16 op1, s16 op2); s16 qm_sub16(s16 op1, s16 op2); -s32 qm_sub32(s32 op1, s32 op2); - -s32 qm_mac321616(s32 acc, s16 op1, s16 op2); - s32 qm_shl32(s32 op, int shift); -s32 qm_shr32(s32 op, int shift); - s16 qm_shl16(s16 op, int shift); s16 qm_shr16(s16 op, int shift); -s16 qm_norm16(s16 op); - s16 qm_norm32(s32 op); -s16 qm_div_s(s16 num, s16 denom); - -s16 qm_abs16(s16 op); - -s16 qm_div16(s16 num, s16 denom, s16 *qQuotient); - -s32 qm_abs32(s32 op); - -s16 qm_div163232(s32 num, s32 denom, s16 *qquotient); - -s32 qm_mul323216(s32 op1, s16 op2); - -s32 qm_mulsu321616(s16 op1, u16 op2); - -s32 qm_muls323216(s32 op1, s16 op2); - -s32 qm_mul32(s32 a, s32 b); - -s32 qm_muls32(s32 a, s32 b); - void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N); -void qm_1byN(s32 N, s16 qN, s32 *result, s16 *qResult); - #endif /* #ifndef __QMATH_H__ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h index 54af257598c2..5582de3ee721 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h @@ -17,25 +17,19 @@ #ifndef _wl_dbg_h_ #define _wl_dbg_h_ +#include <linux/device.h> /* dev_err() */ + /* wl_msg_level is a bit vector with defs in wlioctl.h */ extern u32 wl_msg_level; -#define WL_NONE(fmt, args...) no_printk(fmt, ##args) - -#define WL_PRINT(level, fmt, args...) \ +#define BCMMSG(dev, fmt, args...) \ do { \ - if (wl_msg_level & level) \ - printk(fmt, ##args); \ + if (wl_msg_level & WL_TRACE_VAL) \ + wiphy_err(dev, "%s: " fmt, __func__, ##args); \ } while (0) #ifdef BCMDBG -#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) -#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) -#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) -#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) - -#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) /* Extra message control for AMPDU debugging */ #define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ @@ -78,12 +72,6 @@ do { \ #else /* BCMDBG */ -#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) -#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) - -#define WL_ERROR_ON() 0 #define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) #define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) @@ -99,4 +87,6 @@ do { \ #endif /* BCMDBG */ +#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) + #endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h index 9ff760f4c865..0fe0b24b586f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h @@ -42,5 +42,6 @@ extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, int periodic); extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); +extern void wl_msleep(struct wl_info *wl, uint ms); #endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index c1b07ae31674..6c6236c969b7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -30,6 +30,7 @@ #include <bcmdefs.h> #include <bcmwifi.h> #include <bcmutils.h> +#include <bcmnvram.h> #include <pcicfg.h> #include <wlioctl.h> #include <sbhnddma.h> @@ -48,6 +49,8 @@ #include "wl_ucode.h" #include "wl_mac80211.h" +#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ + static void wl_timer(unsigned long data); static void _wl_timer(struct wl_timer *t); @@ -81,6 +84,7 @@ static int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static void wl_remove(struct pci_dev *pdev); static void wl_free(struct wl_info *wl); +static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br); MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); @@ -129,7 +133,6 @@ static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); static int wl_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); static void wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, @@ -147,6 +150,7 @@ static int wl_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size); static void wl_ops_rfkill_poll(struct ieee80211_hw *hw); +static void wl_ops_flush(struct ieee80211_hw *hw, bool drop); static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { @@ -154,7 +158,7 @@ static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) WL_LOCK(wl); if (!wl->pub->up) { - WL_ERROR("ops->tx called while down\n"); + wiphy_err(wl->wiphy, "ops->tx called while down\n"); kfree_skb(skb); goto done; } @@ -169,7 +173,6 @@ static int wl_ops_start(struct ieee80211_hw *hw) bool blocked; /* struct ieee80211_channel *curchan = hw->conf.channel; - WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); */ ieee80211_wake_queues(hw); @@ -184,10 +187,6 @@ static int wl_ops_start(struct ieee80211_hw *hw) static void wl_ops_stop(struct ieee80211_hw *hw) { -#ifdef BRCMDBG - struct wl_info *wl = hw->priv; - ASSERT(wl); -#endif /*BRCMDBG*/ ieee80211_stop_queues(hw); } @@ -203,8 +202,8 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) vif->type != NL80211_IFTYPE_STATION && vif->type != NL80211_IFTYPE_WDS && vif->type != NL80211_IFTYPE_ADHOC) { - WL_ERROR("%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type); + wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" + " STA for now\n", __func__, vif->type); return -EOPNOTSUPP; } @@ -214,7 +213,8 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) WL_UNLOCK(wl); if (err != 0) { - WL_ERROR("%s: wl_up() returned %d\n", __func__, err); + wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__, + err); } return err; } @@ -249,7 +249,8 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, break; case NL80211_CHAN_HT40MINUS: case NL80211_CHAN_HT40PLUS: - WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); + wiphy_err(hw->wiphy, + "%s: Need to implement 40 Mhz Channels!\n", __func__); err = 1; break; } @@ -265,39 +266,41 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) struct wl_info *wl = HW_TO_WL(hw); int err = 0; int new_int; + struct wiphy *wiphy = hw->wiphy; WL_LOCK(wl); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { if (wlc_iovar_setint (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { - WL_ERROR("%s: Error setting listen_interval\n", - __func__); + wiphy_err(wiphy, "%s: Error setting listen_interval\n", + __func__); err = -EIO; goto config_out; } wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); - ASSERT(new_int == conf->listen_interval); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) - WL_ERROR("%s: change monitor mode: %s (implement)\n", __func__, - conf->flags & IEEE80211_CONF_MONITOR ? - "true" : "false"); + wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n", + __func__, conf->flags & IEEE80211_CONF_MONITOR ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_PS) - WL_ERROR("%s: change power-save mode: %s (implement)\n", - __func__, conf->flags & IEEE80211_CONF_PS ? - "true" : "false"); + wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", + __func__, conf->flags & IEEE80211_CONF_PS ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { if (wlc_iovar_setint (wl->wlc, "qtxpower", conf->power_level * 4)) { - WL_ERROR("%s: Error setting power_level\n", __func__); + wiphy_err(wiphy, "%s: Error setting power_level\n", + __func__); err = -EIO; goto config_out; } wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); if (new_int != (conf->power_level * 4)) - WL_ERROR("%s: Power level req != actual, %d %d\n", - __func__, conf->power_level * 4, new_int); + wiphy_err(wiphy, "%s: Power level req != actual, %d %d" + "\n", __func__, conf->power_level * 4, + new_int); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { err = ieee_set_channel(hw, conf->channel, conf->channel_type); @@ -306,13 +309,13 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) if (wlc_set (wl->wlc, WLC_SET_SRL, conf->short_frame_max_tx_count) < 0) { - WL_ERROR("%s: Error setting srl\n", __func__); + wiphy_err(wiphy, "%s: Error setting srl\n", __func__); err = -EIO; goto config_out; } if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) < 0) { - WL_ERROR("%s: Error setting lrl\n", __func__); + wiphy_err(wiphy, "%s: Error setting lrl\n", __func__); err = -EIO; goto config_out; } @@ -329,25 +332,18 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u32 changed) { struct wl_info *wl = HW_TO_WL(hw); + struct wiphy *wiphy = hw->wiphy; int val; if (changed & BSS_CHANGED_ASSOC) { /* association status changed (associated/disassociated) * also implies a change in the AID. */ - WL_ERROR("%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, - info->assoc ? "" : "dis"); + wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, + __func__, info->assoc ? "" : "dis"); + WL_LOCK(wl); wlc_associate_upd(wl->wlc, info->assoc); - } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - /* CTS protection changed */ - WL_ERROR("%s: use_cts_prot: %s (implement)\n", __func__, - info->use_cts_prot ? "true" : "false"); - } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - /* preamble changed */ - WL_ERROR("%s: short preamble: %s (implement)\n", __func__, - info->use_short_preamble ? "true" : "false"); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_ERP_SLOT) { /* slot timing changed */ @@ -363,29 +359,57 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_HT) { /* 802.11n parameters changed */ u16 mode = info->ht_operation_mode; - WL_NONE("%s: HT mode: 0x%04X\n", __func__, mode); + + WL_LOCK(wl); wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG, mode & IEEE80211_HT_OP_MODE_PROTECTION); wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF, mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS, mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_BASIC_RATES) { - /* Basic rateset changed */ - WL_ERROR("%s: Need to change Basic Rates: 0x%x (implement)\n", - __func__, (u32) info->basic_rates); + struct ieee80211_supported_band *bi; + u32 br_mask, i; + u16 rate; + struct wl_rateset rs; + int error; + + /* retrieve the current rates */ + WL_LOCK(wl); + error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET, + &rs, sizeof(rs), NULL); + WL_UNLOCK(wl); + if (error) { + wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n", + __func__, error); + return; + } + br_mask = info->basic_rates; + bi = hw->wiphy->bands[wlc_get_curband(wl->wlc)]; + for (i = 0; i < bi->n_bitrates; i++) { + /* convert to internal rate value */ + rate = (bi->bitrates[i].bitrate << 1) / 10; + + /* set/clear basic rate flag */ + wl_set_basic_rate(&rs, rate, br_mask & 1); + br_mask >>= 1; + } + + /* update the rate set */ + WL_LOCK(wl); + wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON_INT) { /* Beacon interval changed */ - WL_NONE("%s: Beacon Interval: %d\n", - __func__, info->beacon_int); + WL_LOCK(wl); wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_BSSID) { /* BSSID changed, for whatever reason (IBSS and managed mode) */ - WL_NONE("%s: new BSSID: aid %d bss:%pM\n", __func__, - info->aid, info->bssid); WL_LOCK(wl); wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); @@ -393,41 +417,42 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON) { /* Beacon data changed, retrieve new beacon (beaconing modes) */ - WL_ERROR("%s: beacon changed\n", __func__); + wiphy_err(wiphy, "%s: beacon changed\n", __func__); } if (changed & BSS_CHANGED_BEACON_ENABLED) { /* Beaconing should be enabled/disabled (beaconing modes) */ - WL_ERROR("%s: Beacon enabled: %s\n", __func__, - info->enable_beacon ? "true" : "false"); + wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, + info->enable_beacon ? "true" : "false"); } if (changed & BSS_CHANGED_CQM) { /* Connection quality monitor config changed */ - WL_ERROR("%s: cqm change: threshold %d, hys %d (implement)\n", - __func__, info->cqm_rssi_thold, info->cqm_rssi_hyst); + wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " + " (implement)\n", __func__, info->cqm_rssi_thold, + info->cqm_rssi_hyst); } if (changed & BSS_CHANGED_IBSS) { /* IBSS join status changed */ - WL_ERROR("%s: IBSS joined: %s (implement)\n", __func__, - info->ibss_joined ? "true" : "false"); + wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, + info->ibss_joined ? "true" : "false"); } if (changed & BSS_CHANGED_ARP_FILTER) { /* Hardware ARP filter address list or state changed */ - WL_ERROR("%s: arp filtering: enabled %s, count %d (implement)\n", - __func__, info->arp_filter_enabled ? "true" : "false", - info->arp_addr_cnt); + wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" + " (implement)\n", __func__, info->arp_filter_enabled ? + "true" : "false", info->arp_addr_cnt); } if (changed & BSS_CHANGED_QOS) { /* * QoS for this association was enabled/disabled. * Note that it is only ever disabled for station mode. */ - WL_ERROR("%s: qos enabled: %s (implement)\n", __func__, - info->qos ? "true" : "false"); + wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, + info->qos ? "true" : "false"); } if (changed & BSS_CHANGED_IDLE) { /* Idle changed for this BSS/interface */ - WL_ERROR("%s: BSS idle: %s (implement)\n", __func__, - info->idle ? "true" : "false"); + wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__, + info->idle ? "true" : "false"); } return; } @@ -438,23 +463,23 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { struct wl_info *wl = hw->priv; + struct wiphy *wiphy = hw->wiphy; changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; if (changed_flags & FIF_PROMISC_IN_BSS) - WL_ERROR("FIF_PROMISC_IN_BSS\n"); + wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n"); if (changed_flags & FIF_ALLMULTI) - WL_ERROR("FIF_ALLMULTI\n"); + wiphy_err(wiphy, "FIF_ALLMULTI\n"); if (changed_flags & FIF_FCSFAIL) - WL_ERROR("FIF_FCSFAIL\n"); + wiphy_err(wiphy, "FIF_FCSFAIL\n"); if (changed_flags & FIF_PLCPFAIL) - WL_ERROR("FIF_PLCPFAIL\n"); + wiphy_err(wiphy, "FIF_PLCPFAIL\n"); if (changed_flags & FIF_CONTROL) - WL_ERROR("FIF_CONTROL\n"); + wiphy_err(wiphy, "FIF_CONTROL\n"); if (changed_flags & FIF_OTHER_BSS) - WL_ERROR("FIF_OTHER_BSS\n"); + wiphy_err(wiphy, "FIF_OTHER_BSS\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); WL_LOCK(wl); if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; @@ -471,14 +496,12 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { - WL_NONE("%s: Enter\n", __func__); return 0; } static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) { struct wl_info *wl = hw->priv; - WL_NONE("Scan Start\n"); WL_LOCK(wl); wlc_scan_start(wl->wlc); WL_UNLOCK(wl); @@ -488,7 +511,6 @@ static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) { struct wl_info *wl = hw->priv; - WL_NONE("Scan Complete\n"); WL_LOCK(wl); wlc_scan_stop(wl->wlc); WL_UNLOCK(wl); @@ -497,7 +519,7 @@ static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) { - WL_ERROR("%s: Enter\n", __func__); + wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return; } @@ -510,20 +532,10 @@ wl_ops_get_stats(struct ieee80211_hw *hw, WL_LOCK(wl); cnt = wl->pub->_cnt; - stats->dot11ACKFailureCount = cnt->txnoack; - stats->dot11RTSFailureCount = cnt->txnocts; - stats->dot11FCSErrorCount = cnt->rxcrc; - stats->dot11RTSSuccessCount = cnt->txrts; - WL_UNLOCK(wl); - return 0; -} - -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct wl_info *wl = hw->priv; - - WL_LOCK(wl); - wlc_iovar_setint(wl->wlc, "rtsthresh", value & 0xFFFF); + stats->dot11ACKFailureCount = 0; + stats->dot11RTSFailureCount = 0; + stats->dot11FCSErrorCount = 0; + stats->dot11RTSSuccessCount = 0; WL_UNLOCK(wl); return 0; } @@ -532,10 +544,10 @@ static void wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { - WL_NONE("%s: Enter\n", __func__); switch (cmd) { default: - WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); + wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__, + cmd); break; } return; @@ -547,12 +559,8 @@ wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, { struct wl_info *wl = hw->priv; - WL_NONE("%s: Enter (WME config)\n", __func__); - WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, - params->txop, params->cw_min, params->cw_max, params->aifs); - WL_LOCK(wl); - wlc_wme_setparams(wl->wlc, queue, (void *)params, true); + wlc_wme_setparams(wl->wlc, queue, params, true); WL_UNLOCK(wl); return 0; @@ -560,7 +568,7 @@ wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) { - WL_ERROR("%s: Enter\n", __func__); + wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return 0; } @@ -585,7 +593,7 @@ wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wl->pub->global_ampdu = &(scb->scb_ampdu); wl->pub->global_ampdu->scb = scb; wl->pub->global_ampdu->max_pdu = 16; - pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, + bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); sta->ht_cap.ht_supported = true; @@ -603,7 +611,6 @@ static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - WL_NONE("%s: Enter\n", __func__); return 0; } @@ -614,27 +621,25 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { -#if defined(BCMDBG) struct scb *scb = (struct scb *)sta->drv_priv; -#endif struct wl_info *wl = hw->priv; int status; - ASSERT(scb->magic == SCB_MAGIC); + if (WARN_ON(scb->magic != SCB_MAGIC)) + return -EIDRM; switch (action) { case IEEE80211_AMPDU_RX_START: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); break; case IEEE80211_AMPDU_RX_STOP: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); break; case IEEE80211_AMPDU_TX_START: WL_LOCK(wl); status = wlc_aggregatable(wl->wlc, tid); WL_UNLOCK(wl); if (!status) { - /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ - return -1; + wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", + tid); + return -EINVAL; } /* XXX: Use the starting sequence number provided ... */ *ssn = 0; @@ -650,11 +655,10 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_OPERATIONAL: /* Not sure what to do here */ /* Power save wakeup */ - WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", - __func__); break; default: - WL_ERROR("%s: Invalid command, ignoring\n", __func__); + wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", + __func__); } return 0; @@ -669,10 +673,21 @@ static void wl_ops_rfkill_poll(struct ieee80211_hw *hw) blocked = wlc_check_radio_disabled(wl->wlc); WL_UNLOCK(wl); - WL_NONE("wl: rfkill_poll: %d\n", blocked); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); } +static void wl_ops_flush(struct ieee80211_hw *hw, bool drop) +{ + struct wl_info *wl = HW_TO_WL(hw); + + no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); + + /* wait for packet queue and dma fifos to run empty */ + WL_LOCK(wl); + wlc_wait_for_tx_completion(wl->wlc, drop); + WL_UNLOCK(wl); +} + static const struct ieee80211_ops wl_ops = { .tx = wl_ops_tx, .start = wl_ops_start, @@ -687,7 +702,6 @@ static const struct ieee80211_ops wl_ops = { .sw_scan_complete = wl_ops_sw_scan_complete, .set_tsf = wl_ops_set_tsf, .get_stats = wl_ops_get_stats, - .set_rts_threshold = wl_ops_set_rts_threshold, .sta_notify = wl_ops_sta_notify, .conf_tx = wl_ops_conf_tx, .get_tsf = wl_ops_get_tsf, @@ -695,6 +709,7 @@ static const struct ieee80211_ops wl_ops = { .sta_remove = wl_ops_sta_remove, .ampdu_action = wl_ops_ampdu_action, .rfkill_poll = wl_ops_rfkill_poll, + .flush = wl_ops_flush, }; /* @@ -702,8 +717,6 @@ static const struct ieee80211_ops wl_ops = { */ static int wl_set_hint(struct wl_info *wl, char *abbrev) { - WL_NONE("%s: Sending country code %c%c to MAC80211\n", - __func__, abbrev[0], abbrev[1]); return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); } @@ -724,7 +737,7 @@ static int wl_set_hint(struct wl_info *wl, char *abbrev) static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) { - struct wl_info *wl; + struct wl_info *wl = NULL; int unit, err; unsigned long base_addr; @@ -735,14 +748,16 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, err = 0; if (unit < 0) { - WL_ERROR("wl%d: unit number overflow, exiting\n", unit); return NULL; } /* allocate private info */ hw = pci_get_drvdata(btparam); /* btparam == pdev */ - wl = hw->priv; - ASSERT(wl); + if (hw != NULL) + wl = hw->priv; + if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL)) + return NULL; + wl->wiphy = hw->wiphy; atomic_set(&wl->callbacks, 0); @@ -759,13 +774,13 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, /* Do nothing */ } else { bustype = PCI_BUS; - WL_TRACE("force to PCI\n"); + BCMMSG(wl->wiphy, "force to PCI\n"); } wl->bcm_bustype = bustype; wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); if (wl->regsva == NULL) { - WL_ERROR("wl%d: ioremap() failed\n", unit); + wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit); goto fail; } spin_lock_init(&wl->lock); @@ -773,11 +788,11 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, /* prepare ucode */ if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) { - WL_ERROR("%s: Failed to find firmware usually in %s\n", - KBUILD_MODNAME, "/lib/firmware/brcm"); + wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " + "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); wl_release_fw(wl); wl_remove((struct pci_dev *)btparam); - goto fail1; + return NULL; } /* common load-time initialization */ @@ -785,24 +800,22 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, wl->regsva, wl->bcm_bustype, btparam, &err); wl_release_fw(wl); if (!wl->wlc) { - WL_ERROR("%s: wlc_attach() failed with code %d\n", - KBUILD_MODNAME, err); + wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n", + KBUILD_MODNAME, err); goto fail; } wl->pub = wlc_pub(wl->wlc); wl->pub->ieee_hw = hw; - ASSERT(wl->pub->ieee_hw); - ASSERT(wl->pub->ieee_hw->priv == wl); - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { - WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); + wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n", + unit); } /* register our interrupt handler */ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { - WL_ERROR("wl%d: request_irq() failed\n", unit); + wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = irq; @@ -812,18 +825,20 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, NULL); if (ieee_hw_init(hw)) { - WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); + wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, + __func__); goto fail; } memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); - ASSERT(is_valid_ether_addr(perm)); + if (WARN_ON(!is_valid_ether_addr(perm))) + goto fail; SET_IEEE80211_PERM_ADDR(hw, perm); err = ieee80211_register_hw(hw); if (err) { - WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", - __func__, err); + wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" + "%d\n", __func__, err); } if (wl->pub->srom_ccode[0]) @@ -831,8 +846,8 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, else err = wl_set_hint(wl, "US"); if (err) { - WL_ERROR("%s: regulatory_hint failed, status %d\n", - __func__, err); + wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", + __func__, err); } wl_found++; @@ -840,7 +855,6 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, fail: wl_free(wl); -fail1: return NULL; } @@ -1027,9 +1041,8 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { - WL_ERROR("Phy list failed\n"); + wiphy_err(hw->wiphy, "Phy list failed\n"); } - WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); if (phy_list[0] == 'n' || phy_list[0] == 'c') { if (phy_list[0] == 'c') { @@ -1039,8 +1052,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) } hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; } else { - BUG(); - return -1; + return -EPERM; } /* Assume all bands use the same phy. True for 11n devices. */ @@ -1050,12 +1062,9 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl_band_5GHz_nphy; } else { - return -1; + return -EPERM; } } - - WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); - return 0; } @@ -1070,8 +1079,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) | IEEE80211_HW_AMPDU_AGGREGATION; hw->extra_tx_headroom = wlc_get_header_len(); - /* FIXME: should get this from wlc->machwcap */ - hw->queues = 4; + hw->queues = N_TX_QUEUES; /* FIXME: this doesn't seem to be used properly in minstrel_ht. * mac80211/status.c:ieee80211_tx_status() checks this value, * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() @@ -1104,11 +1112,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ieee80211_hw *hw; u32 val; - ASSERT(pdev); - - WL_TRACE("%s: bus %d slot %d func %d irq %d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq); + dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n", + pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pdev->irq); if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || (((pdev->device & 0xff00) != 0x4300) && @@ -1118,9 +1124,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_enable_device(pdev); if (rc) { - WL_ERROR("%s: Cannot enable device %d-%d_%d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); + pr_err("%s: Cannot enable device %d-%d_%d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); return -ENODEV; } pci_set_master(pdev); @@ -1131,9 +1137,8 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); if (!hw) { - WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); - rc = -ENOMEM; - goto err_1; + pr_err("%s: ieee80211_alloc_hw failed\n", __func__); + return -ENOMEM; } SET_IEEE80211_DEV(hw, &pdev->dev); @@ -1146,14 +1151,11 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) PCI_BUS, pdev, pdev->irq); if (!wl) { - WL_ERROR("%s: %s: wl_attach failed!\n", - KBUILD_MODNAME, __func__); + pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME, + __func__); return -ENODEV; } return 0; - err_1: - WL_ERROR("%s: err_1: Major hoarkage\n", __func__); - return 0; } static int wl_suspend(struct pci_dev *pdev, pm_message_t state) @@ -1161,12 +1163,11 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state) struct wl_info *wl; struct ieee80211_hw *hw; - WL_TRACE("wl: wl_suspend\n"); - hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); + wiphy_err(wl->wiphy, + "wl_suspend: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1187,11 +1188,11 @@ static int wl_resume(struct pci_dev *pdev) int err = 0; u32 val; - WL_TRACE("wl: wl_resume\n"); hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); + wiphy_err(wl->wiphy, + "wl: wl_resume: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1231,7 +1232,7 @@ static void wl_remove(struct pci_dev *pdev) hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); + pr_err("wl: wl_remove: pci_get_drvdata failed\n"); return; } @@ -1239,7 +1240,7 @@ static void wl_remove(struct pci_dev *pdev) status = wlc_chipmatch(pdev->vendor, pdev->device); WL_UNLOCK(wl); if (!status) { - WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); + wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n"); return; } if (wl->wlc) { @@ -1249,7 +1250,6 @@ static void wl_remove(struct pci_dev *pdev) WL_LOCK(wl); wl_down(wl); WL_UNLOCK(wl); - WL_NONE("%s: Down\n", __func__); } pci_disable_device(pdev); @@ -1342,7 +1342,6 @@ static void wl_free(struct wl_info *wl) { struct wl_timer *t, *next; - ASSERT(wl); /* free ucode data */ if (wl->fw.fw_cnt) wl_ucode_data_free(); @@ -1389,13 +1388,30 @@ static void wl_free(struct wl_info *wl) wl->regsva = NULL; } +/* flags the given rate in rateset as requested */ +static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) +{ + u32 i; + + for (i = 0; i < rs->count; i++) { + if (rate != (rs->rates[i] & 0x7f)) + continue; + + if (is_br) + rs->rates[i] |= WLC_RATE_FLAG; + else + rs->rates[i] &= WLC_RATE_MASK; + return; + } +} + /* * precondition: perimeter lock has been acquired */ void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, int prio) { - WL_ERROR("Shouldn't be here %s\n", __func__); + wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); } /* @@ -1403,8 +1419,7 @@ void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, */ void wl_init(struct wl_info *wl) { - WL_TRACE("wl%d: wl_init\n", wl->pub->unit); - + BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); wl_reset(wl); wlc_init(wl->wlc); @@ -1415,8 +1430,7 @@ void wl_init(struct wl_info *wl) */ uint wl_reset(struct wl_info *wl) { - WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); - + BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); wlc_reset(wl->wlc); /* dpc will not be rescheduled */ @@ -1429,7 +1443,7 @@ uint wl_reset(struct wl_info *wl) * These are interrupt on/off entry points. Disable interrupts * during interrupt state transition. */ -void BCMFASTPATH wl_intrson(struct wl_info *wl) +void wl_intrson(struct wl_info *wl) { unsigned long flags; @@ -1446,7 +1460,7 @@ bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) return true; } -u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) +u32 wl_intrsoff(struct wl_info *wl) { unsigned long flags; u32 status; @@ -1503,7 +1517,7 @@ void wl_down(struct wl_info *wl) WL_LOCK(wl); } -static irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) +static irqreturn_t wl_isr(int irq, void *dev_id) { struct wl_info *wl; bool ours, wantdpc; @@ -1521,7 +1535,6 @@ static irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) /* ...and call the second level interrupt handler */ /* schedule dpc */ - ASSERT(wl->resched == false); tasklet_schedule(&wl->tasklet); } } @@ -1531,7 +1544,7 @@ static irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) return IRQ_RETVAL(ours); } -static void BCMFASTPATH wl_dpc(unsigned long data) +static void wl_dpc(unsigned long data) { struct wl_info *wl; @@ -1613,7 +1626,8 @@ struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC); if (!t) { - WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); + wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n", + wl->pub->unit); return 0; } @@ -1644,12 +1658,10 @@ void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) { #ifdef BCMDBG if (t->set) { - WL_ERROR("%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic); + wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); } #endif - ASSERT(!t->set); - t->ms = ms; t->periodic = (bool) periodic; t->set = true; @@ -1719,37 +1731,6 @@ void wl_free_timer(struct wl_info *wl, struct wl_timer *t) */ static int wl_linux_watchdog(void *ctx) { - struct wl_info *wl = (struct wl_info *) ctx; - struct wl_cnt *cnt; - struct net_device_stats *stats = NULL; - uint id; - /* refresh stats */ - if (wl->pub->up) { - ASSERT(wl->stats_id < 2); - - cnt = wl->pub->_cnt; - id = 1 - wl->stats_id; - stats = &wl->stats_watchdog[id]; - stats->rx_packets = cnt->rxframe; - stats->tx_packets = cnt->txframe; - stats->rx_bytes = cnt->rxbyte; - stats->tx_bytes = cnt->txbyte; - stats->rx_errors = cnt->rxerror; - stats->tx_errors = cnt->txerror; - stats->collisions = 0; - - stats->rx_length_errors = 0; - stats->rx_over_errors = cnt->rxoflo; - stats->rx_crc_errors = cnt->rxcrc; - stats->rx_frame_errors = 0; - stats->rx_fifo_errors = cnt->rxoflo; - stats->rx_missed_errors = 0; - - stats->tx_fifo_errors = cnt->txuflo; - - wl->stats_id = id; - } - return 0; } @@ -1780,8 +1761,8 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) pdata = wl->fw.fw_bin[i]->data + hdr->offset; *pbuf = kmalloc(hdr->len, GFP_ATOMIC); if (*pbuf == NULL) { - WL_ERROR("fail to alloc %d bytes\n", - hdr->len); + wiphy_err(wl->wiphy, "fail to alloc %d" + " bytes\n", hdr->len); goto fail; } memcpy(*pbuf, pdata, hdr->len); @@ -1789,10 +1770,11 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) } } } - WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx); + wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", + idx); *pbuf = NULL; fail: - return BCME_NOTFOUND; + return -ENODATA; } /* @@ -1810,14 +1792,18 @@ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) entry++, hdr++) { if (hdr->idx == idx) { pdata = wl->fw.fw_bin[i]->data + hdr->offset; - ASSERT(hdr->len == 4); + if (hdr->len != 4) { + wiphy_err(wl->wiphy, + "ERROR: fw hdr len\n"); + return -ENOMSG; + } *data = *((u32 *) pdata); return 0; } } } - WL_ERROR("ERROR: ucode tag:%d can not be found!\n", idx); - return -1; + wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); + return -ENOMSG; } /* @@ -1837,26 +1823,22 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) break; sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], UCODE_LOADER_API_VER); - WL_NONE("request fw %s\n", fw_name); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { - WL_ERROR("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); return status; } - WL_NONE("request fw %s\n", fw_name); sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); if (status) { - WL_ERROR("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); return status; } wl->fw.hdr_num_entries[i] = wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); - WL_NONE("request fw %s find: %d entries\n", - fw_name, wl->fw.hdr_num_entries[i]); } wl->fw.fw_cnt = i; return wl_ucode_data_init(wl); @@ -1904,16 +1886,17 @@ int wl_check_firmwares(struct wl_info *wl) if (fw == NULL && fw_hdr == NULL) { break; } else if (fw == NULL || fw_hdr == NULL) { - WL_ERROR("%s: invalid bin/hdr fw\n", __func__); + wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n", + __func__); rc = -EBADF; } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { - WL_ERROR("%s: non integral fw hdr file size %zu/%zu\n", - __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr)); + wiphy_err(wl->wiphy, "%s: non integral fw hdr file " + "size %zu/%zu\n", __func__, fw_hdr->size, + sizeof(struct wl_fw_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - WL_ERROR("%s: out of bounds fw file size %zu\n", - __func__, fw->size); + wiphy_err(wl->wiphy, "%s: out of bounds fw file size " + "%zu\n", __func__, fw->size); rc = -EBADF; } else { /* check if ucode section overruns firmware image */ @@ -1922,15 +1905,17 @@ int wl_check_firmwares(struct wl_info *wl) !rc; entry++, ucode_hdr++) { if (ucode_hdr->offset + ucode_hdr->len > fw->size) { - WL_ERROR("%s: conflicting bin/hdr\n", - __func__); + wiphy_err(wl->wiphy, + "%s: conflicting bin/hdr\n", + __func__); rc = -EBADF; } } } } if (rc == 0 && wl->fw.fw_cnt != i) { - WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); + wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__, + wl->fw.fw_cnt); rc = -EBADF; } return rc; @@ -1943,8 +1928,6 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl) { bool blocked = wlc_check_radio_disabled(wl->wlc); - WL_NONE("%s: update hw state: blocked=%s\n", __func__, - blocked ? "true" : "false"); WL_UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); if (blocked) @@ -1952,3 +1935,13 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl) WL_LOCK(wl); return blocked; } + +/* + * precondition: perimeter lock has been acquired + */ +void wl_msleep(struct wl_info *wl, uint ms) +{ + WL_UNLOCK(wl); + msleep(ms); + WL_LOCK(wl); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index f3198ccd5f58..e703d8bb94d6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -67,11 +67,8 @@ struct wl_info { #ifdef LINUXSTA_PS u32 pci_psstate[16]; /* pci ps-state save/restore */ #endif - /* RPC, handle, lock, txq, workitem */ - uint stats_id; /* the current set of stats */ - /* ping-pong stats counters updated by Linux watchdog */ - struct net_device_stats stats_watchdog[2]; struct wl_firmware fw; + struct wiphy *wiphy; }; #define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index e928fa10834e..82c64cd4486f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -18,7 +18,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> @@ -43,17 +43,7 @@ static struct wlc_pub *wlc_pub_malloc(uint unit, static void wlc_pub_mfree(struct wlc_pub *pub); static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); -void *wlc_calloc(uint unit, uint size) -{ - void *item; - - item = kzalloc(size, GFP_ATOMIC); - if (item == NULL) - WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); - return item; -} - -void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) +static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) { tunables->ntxd = NTXD; tunables->nrxd = NRXD; @@ -75,14 +65,13 @@ static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid) { struct wlc_pub *pub; - pub = wlc_calloc(unit, sizeof(struct wlc_pub)); + pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC); if (pub == NULL) { *err = 1001; goto fail; } - pub->tunables = wlc_calloc(unit, - sizeof(wlc_tunables_t)); + pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC); if (pub->tunables == NULL) { *err = 1028; goto fail; @@ -91,12 +80,7 @@ static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid) /* need to init the tunables now */ wlc_tunables_init(pub->tunables, devid); - pub->_cnt = wlc_calloc(unit, sizeof(struct wl_cnt)); - if (pub->_cnt == NULL) - goto fail; - - pub->multicast = (u8 *)wlc_calloc(unit, - (ETH_ALEN * MAXMULTILIST)); + pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC); if (pub->multicast == NULL) { *err = 1003; goto fail; @@ -115,7 +99,6 @@ static void wlc_pub_mfree(struct wlc_pub *pub) return; kfree(pub->multicast); - kfree(pub->_cnt); kfree(pub->tunables); kfree(pub); } @@ -124,12 +107,11 @@ static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit) { struct wlc_bsscfg *cfg; - cfg = (struct wlc_bsscfg *) wlc_calloc(unit, sizeof(struct wlc_bsscfg)); + cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC); if (cfg == NULL) goto fail; - cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(unit, - sizeof(wlc_bss_info_t)); + cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC); if (cfg->current_bss == NULL) goto fail; @@ -150,7 +132,8 @@ static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg) kfree(cfg); } -void wlc_bsscfg_ID_assign(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg) +static void wlc_bsscfg_ID_assign(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg) { bsscfg->ID = wlc->next_bsscfg_ID; wlc->next_bsscfg_ID++; @@ -163,7 +146,7 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) { struct wlc_info *wlc; - wlc = (struct wlc_info *) wlc_calloc(unit, sizeof(struct wlc_info)); + wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC); if (wlc == NULL) { *err = 1002; goto fail; @@ -181,16 +164,15 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) /* allocate struct wlc_hw_info state structure */ - wlc->hw = (struct wlc_hw_info *)wlc_calloc(unit, - sizeof(struct wlc_hw_info)); + wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC); if (wlc->hw == NULL) { *err = 1005; goto fail; } wlc->hw->wlc = wlc; - wlc->hw->bandstate[0] = wlc_calloc(unit, - (sizeof(struct wlc_hwband) * MAXBANDS)); + wlc->hw->bandstate[0] = + kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; goto fail; @@ -204,15 +186,14 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) } } - wlc->modulecb = wlc_calloc(unit, - sizeof(struct modulecb) * WLC_MAXMODULES); + wlc->modulecb = + kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC); if (wlc->modulecb == NULL) { *err = 1009; goto fail; } - wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(unit, - sizeof(wlc_bss_info_t)); + wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC); if (wlc->default_bss == NULL) { *err = 1010; goto fail; @@ -225,15 +206,16 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) } wlc_bsscfg_ID_assign(wlc, wlc->cfg); - wlc->pkt_callback = wlc_calloc(unit, - (sizeof(struct pkt_cb) * (wlc->pub->tunables->maxpktcb + 1))); + wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) * + (wlc->pub->tunables->maxpktcb + 1), + GFP_ATOMIC); if (wlc->pkt_callback == NULL) { *err = 1013; goto fail; } - wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(unit, - (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); + wlc->wsec_def_keys[0] = + kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC); if (wlc->wsec_def_keys[0] == NULL) { *err = 1015; goto fail; @@ -246,21 +228,20 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) } } - wlc->protection = wlc_calloc(unit, - sizeof(struct wlc_protection)); + wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = wlc_calloc(unit, sizeof(struct wlc_stf)); + wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC); if (wlc->stf == NULL) { *err = 1017; goto fail; } - wlc->bandstate[0] = (struct wlcband *)wlc_calloc(unit, - (sizeof(struct wlcband)*MAXBANDS)); + wlc->bandstate[0] = + kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; @@ -274,15 +255,14 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) } } - wlc->corestate = (struct wlccore *)wlc_calloc(unit, - sizeof(struct wlccore)); + wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC); if (wlc->corestate == NULL) { *err = 1026; goto fail; } wlc->corestate->macstat_snapshot = - (macstat_t *)wlc_calloc(unit, sizeof(macstat_t)); + kzalloc(sizeof(macstat_t), GFP_ATOMIC); if (wlc->corestate->macstat_snapshot == NULL) { *err = 1027; goto fail; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h index 1fb7430b26a9..95f951eb2b2f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h @@ -14,7 +14,5 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -extern void *wlc_calloc(uint unit, uint size); - extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid); extern void wlc_detach_mfree(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index f00865957881..85ad70096056 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -18,7 +18,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> #include <hnddma.h> @@ -38,12 +38,6 @@ #include "wlc_main.h" #include "wlc_ampdu.h" -/* - * Disable AMPDU statistics counters for now - */ -#define WLCNTINCR(a) -#define WLCNTADD(a, b) - #define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ #define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ @@ -76,16 +70,6 @@ AMPDU_DELIMITER_LEN + 3\ + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) -#ifdef BCMDBG -u32 wl_ampdu_dbg = - WL_AMPDU_UPDN_VAL | - WL_AMPDU_ERR_VAL | - WL_AMPDU_TX_VAL | - WL_AMPDU_RX_VAL | - WL_AMPDU_CTL_VAL | - WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL; -#endif - /* structure to hold tx fifo information and pre-loading state * counters specific to tx underflows of ampdus * some counters might be redundant with the ones in wlc or ampdu structures. @@ -130,6 +114,12 @@ struct ampdu_info { }; +/* used for flushing ampdu packets */ +struct cb_del_ampdu_pars { + struct ieee80211_sta *sta; + u16 tid; +}; + #define AMPDU_CLEANUPFLAG_RX (0x1) #define AMPDU_CLEANUPFLAG_TX (0x2) @@ -143,9 +133,6 @@ static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, bool override); -static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool force); static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); @@ -164,17 +151,10 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) struct ampdu_info *ampdu; int i; - /* some code depends on packed structures */ - ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16)); - ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE)); - ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE)); - ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); - ASSERT(wlc->pub->tunables->ampdunummpdu > 0); - ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); if (!ampdu) { - WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", - wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n", + wlc->pub->unit); return NULL; } ampdu->wlc = wlc; @@ -237,27 +217,6 @@ void wlc_ampdu_detach(struct ampdu_info *ampdu) kfree(ampdu); } -void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) -{ - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - u8 tid; - - WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); - ASSERT(scb_ampdu); - - for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { - ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false); - } -} - -/* reset the ampdu state machine so that it can gracefully handle packets that were - * freed from the dma and tx queues during reinit - */ -void wlc_ampdu_reset(struct ampdu_info *ampdu) -{ - WL_NONE("%s: Entering\n", __func__); -} - static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) { scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); @@ -284,11 +243,9 @@ static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) scb_ampdu->release = min(scb_ampdu->release, ampdu->fifo_tb[TX_AC_BE_FIFO]. mcs2ampdu_table[FFPLD_MAX_MCS]); - - ASSERT(scb_ampdu->release); } -void scb_ampdu_update_config_all(struct ampdu_info *ampdu) +static void scb_ampdu_update_config_all(struct ampdu_info *ampdu) { scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); } @@ -336,7 +293,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); if (new_txunfl == 0) { - WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); + BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); return -1; } fifo->prev_txfunfl = cur_txunfl; @@ -346,7 +303,6 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) /* check if fifo is big enough */ if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { - WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); return -1; } @@ -360,8 +316,8 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - WL_FFPLD("ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); + BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); /* compute the current ratio of tx unfl per ampdu. @@ -388,7 +344,6 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) */ if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) { - WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)")); fifo->accum_txfunfl = 0; return 0; } @@ -406,7 +361,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) /* compute a new dma xfer rate for max_mpdu @ max mcs. This is the minimum dma rate that - can achieve no unferflow condition for the current mpdu size. + can achieve no underflow condition for the current mpdu size. */ /* note : we divide/multiply by 100 to avoid integer overflows */ fifo->dmaxferrate = @@ -414,8 +369,9 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size); + BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " + "pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); } else { /* decrease ampdu size */ @@ -469,7 +425,7 @@ static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) } } -static void BCMFASTPATH +static void wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, uint prec) { @@ -487,7 +443,7 @@ wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, return; } -int BCMFASTPATH +int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, struct sk_buff **pdu, int prec) { @@ -521,35 +477,31 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, bool fbr_iscck; struct ieee80211_tx_info *tx_info; u16 qlen; + struct wiphy *wiphy; wlc = ampdu->wlc; + wiphy = wlc->wiphy; p = *pdu; - ASSERT(p); - tid = (u8) (p->priority); - ASSERT(tid < AMPDU_MAX_SCB_TID); f = ampdu->fifo_tb + prio2fifo[tid]; scb = wlc->pub->global_scb; - ASSERT(scb->magic == SCB_MAGIC); - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); ini = &scb_ampdu->ini[tid]; /* Let pressure continue to build ... */ qlen = pktq_plen(&qi->q, prec); if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { - return BCME_BUSY; + return -EBUSY; } wlc_ampdu_agg(ampdu, scb, p, tid); if (wlc->block_datafifo) { - WL_ERROR("%s: Fifo blocked\n", __func__); - return BCME_BUSY; + wiphy_err(wiphy, "%s: Fifo blocked\n", __func__); + return -EBUSY; } rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; ampdu_len = 0; @@ -563,32 +515,29 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { err = wlc_prep_pdu(wlc, p, &fifo); } else { - WL_ERROR("%s: AMPDU flag is off!\n", __func__); + wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); *pdu = NULL; err = 0; break; } if (err) { - if (err == BCME_BUSY) { - WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sduretry); + if (err == -EBUSY) { + wiphy_err(wiphy, "wl%d: wlc_sendampdu: " + "prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); *pdu = p; break; } /* error in the packet; reject it */ - WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sdurejected); - + wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu " + "rejected; seq 0x%x\n", wlc->pub->unit, seq); *pdu = NULL; break; } /* pkt is good to be aggregated */ - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); txh = (d11txh_t *) p->data; plcp = (u8 *) (txh + 1); h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); @@ -599,7 +548,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, mcl = le16_to_cpu(txh->MacTxControlLow); mcl &= ~TXC_AMPDU_MASK; fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); - ASSERT(!fbr_iscck); txh->PreloadSize = 0; /* always default to 0 */ /* Handle retry limits */ @@ -607,7 +555,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, txrate[0].count++; rr = true; fbr = false; - ASSERT(!fbr); } else { fbr = true; rr = false; @@ -622,8 +569,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; seg_cnt += 1; - WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", - wlc->pub->unit, count, len); + BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); /* * aggregateable mpdu. For ucode/hw agg, @@ -651,10 +598,11 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, len = roundup(len, 4); ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - dma_len += (u16) pkttotlen(p); + dma_len += (u16) bcm_pkttotlen(p); - WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", - wlc->pub->unit, ampdu_len, seg_cnt, ndelim); + BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" + " seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); txh->MacTxControlLow = cpu_to_le16(mcl); @@ -679,15 +627,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; mcs = plcp0 & ~MIMO_PLCP_40MHZ; - ASSERT(mcs < MCS_TABLE_SIZE); maxlen = min(scb_ampdu->max_rxlen, ampdu->max_txlen[mcs][is40][sgi]); - WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", - sgi, is40, mcs); - - maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ + /* XXX Fix me to honor real max_rxlen */ + /* can fix this as soon as ampdu_action() in mac80211.h + * gets extra u8buf_size par */ + maxlen = 64 * 1024; if (is40) mimo_ctlchbw = @@ -728,14 +675,13 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, /* test whether to add more */ if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && (count == f->mcs2ampdu_table[mcs])) { - WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", - wlc->pub->unit, count, mcs); + BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" + " ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); break; } if (count == scb_ampdu->max_pdu) { - WL_NONE("Stop taking from q, reached %d deep\n", - scb_ampdu->max_pdu); break; } @@ -748,26 +694,24 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, ((u8) (p->priority) == tid)) { plen = - pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD; + bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD; plen = max(scb_ampdu->min_len, plen); if ((plen + ampdu_len) > maxlen) { p = NULL; - WL_ERROR("%s: Bogus plen #1\n", - __func__); - ASSERT(3 == 4); + wiphy_err(wiphy, "%s: Bogus plen #1\n", + __func__); continue; } /* check if there are enough descriptors available */ if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { - WL_ERROR("%s: No fifo space !!!!!!\n", - __func__); + wiphy_err(wiphy, "%s: No fifo space " + "!!\n", __func__); p = NULL; continue; } - p = pktq_pdeq(&qi->q, prec); - ASSERT(p); + p = bcm_pktq_pdeq(&qi->q, prec); } else { p = NULL; } @@ -777,8 +721,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, ini->tx_in_transit += count; if (count) { - WLCNTADD(ampdu->cnt->txmpdu, count); - /* patch up the last txh */ txh = (d11txh_t *) pkt[count - 1]->data; mcl = le16_to_cpu(txh->MacTxControlLow); @@ -861,22 +803,20 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, /* set flag and plcp for fallback rate */ if (fbr) { - WLCNTADD(ampdu->cnt->txfbr_mpdu, count); - WLCNTINCR(ampdu->cnt->txfbr_ampdu); mch |= TXC_AMPDU_FBR; txh->MacTxControlHigh = cpu_to_le16(mch); WLC_SET_MIMO_PLCP_AMPDU(plcp); WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); } - WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", - wlc->pub->unit, count, ampdu_len); + BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); /* inform rate_sel if it this is a rate probe pkt */ frameid = le16_to_cpu(txh->TxFrameID); if (frameid & TXFID_RATE_PROBE_MASK) { - WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", - __func__); + wiphy_err(wiphy, "%s: XXX what to do with " + "TXFID_RATE_PROBE_MASK!?\n", __func__); } for (i = 0; i < count; i++) wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), @@ -887,7 +827,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, return err; } -void BCMFASTPATH +void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs) { @@ -898,8 +838,6 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct ieee80211_tx_info *tx_info; tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(txs->status & TX_STATUS_AMPDU); /* BMAC_NOTE: For the split driver, second level txstatus comes later * So if the ACK was received then wait for the second level else just @@ -913,22 +851,16 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, udelay(1); status_delay++; if (status_delay > 10) { - ASSERT(status_delay <= 10); - return; + return; /* error condition */ } } - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); s2 = R_REG(&wlc->regs->frmtxstatus2); } if (likely(scb)) { - ASSERT(scb->magic == SCB_MAGIC); scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); ini = SCB_AMPDU_INI(scb_ampdu, p->priority); - ASSERT(ini->scb == scb); wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); } else { /* loop through all pkts and free */ @@ -939,21 +871,19 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, tx_info = IEEE80211_SKB_CB(p); txh = (d11txh_t *) p->data; mcl = le16_to_cpu(txh->MacTxControlLow); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); /* break out if last packet of ampdu */ if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == TXC_AMPDU_LAST) break; p = GETNEXTTXP(wlc, queue); - ASSERT(p != NULL); } wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); } -void +static void rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, tx_status_t *txs, u8 mcs) { @@ -969,7 +899,7 @@ rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, #define SHORTNAME "AMPDU status" -static void BCMFASTPATH +static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs, u32 s1, u32 s2) @@ -991,30 +921,21 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u8 antselid = 0; u8 retry_limit, rr_retry_limit; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); + struct wiphy *wiphy = wlc->wiphy; #ifdef BCMDBG u8 hole[AMPDU_MAX_MPDU]; memset(hole, 0, sizeof(hole)); #endif - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(txs->status & TX_STATUS_AMPDU); - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - tid = (u8) (p->priority); ini = SCB_AMPDU_INI(scb_ampdu, tid); retry_limit = ampdu->retry_limit_tid[tid]; rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; - - ASSERT(ini->scb == scb); - memset(bitmap, 0, sizeof(bitmap)); queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < AC_COUNT); - supr_status = txs->status & TX_STATUS_SUPR_MASK; if (txs->status & TX_STATUS_ACK_RCV) { @@ -1022,13 +943,13 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, update_rate = false; } - ASSERT(txs->status & TX_STATUS_INTERMEDIATE); + WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE)); start_seq = txs->sequence >> SEQNUM_SHIFT; bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> TX_STATUS_BA_BMAP03_SHIFT; - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); + WARN_ON(s1 & TX_STATUS_INTERMEDIATE); + WARN_ON(!(s1 & TX_STATUS_AMPDU)); bitmap[0] |= (s1 & TX_STATUS_BA_BMAP47_MASK) << @@ -1044,30 +965,24 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ba_recd = true; } else { - WLCNTINCR(ampdu->cnt->noba); if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", - __func__, - CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + wiphy_err(wiphy, "%s: Pkt tx suppressed, " + "illegal channel possibly %d\n", + __func__, CHSPEC_CHANNEL( + wlc->default_bss->chanspec)); } else { - if (supr_status == TX_STATUS_SUPR_FRAG) - WL_NONE("%s: AMPDU frag err\n", - __func__); - else - WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", + if (supr_status != TX_STATUS_SUPR_FRAG) + wiphy_err(wiphy, "%s: wlc_ampdu_dotx" + "status:supr_status 0x%x\n", __func__, supr_status); } /* no need to retry for badch; will fail again */ if (supr_status == TX_STATUS_SUPR_BADCH || supr_status == TX_STATUS_SUPR_EXPTIME) { retry = false; - wlc->pub->_cnt->txchanrej++; } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { - - wlc->pub->_cnt->txexptime++; - /* TX underflow : try tuning pre-loading or ampdu size */ } else if (supr_status == TX_STATUS_SUPR_FRAG) { /* if there were underflows, but pre-loading is not active, @@ -1080,12 +995,12 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } } else if (txs->phyerr) { update_rate = false; - wlc->pub->_cnt->txphyerr++; - WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", - wlc->pub->unit, txs->phyerr); + wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy " + "error (0x%x)\n", wlc->pub->unit, + txs->phyerr); if (WL_ERROR_ON()) { - prpkt("txpkt (AMPDU)", p); + bcm_prpkt("txpkt (AMPDU)", p); wlc_print_txdesc((d11txh_t *) p->data); } wlc_print_txstatus(txs); @@ -1095,7 +1010,6 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* loop through all pkts and retry if not acked */ while (p) { tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); txh = (d11txh_t *) p->data; mcl = le16_to_cpu(txh->MacTxControlLow); plcp = (u8 *) (txh + 1); @@ -1111,11 +1025,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ack_recd = false; if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - - WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", - __func__, tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); - + BCMMSG(wlc->wiphy, "tid %d seq %d," + " start_seq %d, bindex %d set %d, index %d\n", + tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { @@ -1123,21 +1036,12 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ini->txretry[index] = 0; /* ampdu_ack_len: number of acked aggregated frames */ - /* ampdu_ack_map: block ack bit map for the aggregation */ /* ampdu_len: number of aggregated frames */ rate_status(wlc, tx_info, txs, mcs); tx_info->flags |= IEEE80211_TX_STAT_ACK; tx_info->flags |= IEEE80211_TX_STAT_AMPDU; - - /* XXX TODO: Make these accurate. */ tx_info->status.ampdu_ack_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; - tx_info->status.ampdu_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; + tx_info->status.ampdu_len = 1; skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); @@ -1163,12 +1067,15 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* Retry timeout */ ini->tx_in_transit--; ieee80211_tx_info_clear_status(tx_info); + tx_info->status.ampdu_ack_len = 0; + tx_info->status.ampdu_len = 1; tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); - WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", - SHORTNAME, seq, ini->tx_in_transit); + wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_" + "transit %d\n", SHORTNAME, seq, + ini->tx_in_transit); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } @@ -1181,12 +1088,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, break; p = GETNEXTTXP(wlc, queue); - if (p == NULL) { - ASSERT(p); - break; - } } - wlc_send_q(wlc, wlc->active_queue); + wlc_send_q(wlc); /* update rate state */ antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); @@ -1194,28 +1097,6 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } -static void -ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, - bool force) -{ - scb_ampdu_tid_ini_t *ini; - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (!ini) - return; - - WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", - ampdu->wlc->pub->unit, tid); - - if (ini->tx_in_transit && !force) - return; - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb); - ASSERT(ini == &scb_ampdu->ini[ini->tid]); - - /* free all buffered tx packets */ - pktq_pflush(&scb_ampdu->txq, ini->tid, true, NULL, 0); -} - /* initialize the initiator code for tid */ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, @@ -1223,14 +1104,10 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, { scb_ampdu_tid_ini_t *ini; - ASSERT(scb_ampdu); - ASSERT(scb_ampdu->scb); - ASSERT(SCB_AMPDU(scb_ampdu->scb)); - ASSERT(tid < AMPDU_MAX_SCB_TID); - /* check for per-tid control of ampdu */ if (!ampdu->ini_enable[tid]) { - WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); + wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", + __func__, tid); return NULL; } @@ -1238,8 +1115,6 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, ini->tid = tid; ini->scb = scb_ampdu->scb; ini->magic = INI_MAGIC; - WLCNTINCR(ampdu->cnt->txaddbareq); - return ini; } @@ -1251,14 +1126,14 @@ static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) if (on) { if (!N_ENAB(wlc->pub)) { - WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; + wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " + "nmode enabled\n", wlc->pub->unit); + return -ENOTSUPP; } if (!wlc_ampdu_cap(ampdu)) { - WL_AMPDU_ERR("wl%d: device not ampdu capable\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; + wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " + "ampdu capable\n", wlc->pub->unit); + return -ENOTSUPP; } wlc->pub->_ampdu = on; } @@ -1295,43 +1170,6 @@ static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) } } -u8 BCMFASTPATH -wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen) -{ - scb_ampdu_t *scb_ampdu; - int bytes, cnt, tmp; - u8 tx_density; - - ASSERT(scb); - ASSERT(SCB_AMPDU(scb)); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - - if (scb_ampdu->mpdu_density == 0) - return 0; - - /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec - density x is in 2^(x-4) usec - ==> # of bytes needed for req density = rate/2^(17-x) - ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4) - */ - - tx_density = scb_ampdu->mpdu_density; - - ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY); - tmp = 1 << (17 - tx_density); - bytes = CEIL(RSPEC2RATE(rspec), tmp); - - if (bytes > phylen) { - cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN); - ASSERT(cnt <= 255); - return (u8) cnt; - } else - return 0; -} - void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) { char template[T_RAM_ACCESS_SZ * 2]; @@ -1363,17 +1201,11 @@ void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) } } -struct cb_del_ampdu_pars { - struct ieee80211_sta *sta; - u16 tid; -}; - /* * callback function that helps flushing ampdu packets from a priority queue */ -static bool cb_del_ampdu_pkt(void *p, int arg_a) +static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) { - struct sk_buff *mpdu = (struct sk_buff *)p; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); struct cb_del_ampdu_pars *ampdu_pars = (struct cb_del_ampdu_pars *)arg_a; @@ -1406,7 +1238,7 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, u16 tid) { - struct wlc_txq_info *qi = wlc->active_queue; + struct wlc_txq_info *qi = wlc->pkt_queue; struct pktq *pq = &qi->q; int prec; struct cb_del_ampdu_pars ampdu_pars; @@ -1414,8 +1246,8 @@ void wlc_ampdu_flush(struct wlc_info *wlc, ampdu_pars.sta = sta; ampdu_pars.tid = tid; for (prec = 0; prec < pq->num_prec; prec++) { - pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, - (int)&du_pars); + bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + (void *)&du_pars); } wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h index 17e9ebc0dfe2..63d403b036f4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h @@ -23,10 +23,7 @@ extern int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, struct sk_buff **aggp, int prec); extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs); -extern void wlc_ampdu_reset(struct ampdu_info *ampdu); extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); -extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen); #endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 85a73a978d4f..111ef32b7ac4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -22,7 +22,8 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <bcmnvram.h> +#include <aiutils.h> #include <bcmdevs.h> #include <sbhnddma.h> #include <wlioctl.h> @@ -98,8 +99,8 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) { - WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", - wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n", + wlc->pub->unit); return NULL; } @@ -128,8 +129,8 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) asi->antsel_avail = false; } else { asi->antsel_avail = false; - WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); - ASSERT(0); + wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 " + "board cfg invalid\n"); } break; default: @@ -200,7 +201,7 @@ wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, } } -void BCMFASTPATH +void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, u8 antselid, u8 fbantselid, u8 *antcfg, u8 *fbantcfg) @@ -297,8 +298,6 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) u8 ant_cfg; u16 mimo_antsel; - ASSERT(asi->antsel_type != ANTSEL_NA); - /* 1) Update TX antconfig for all frames that are not unicast data * (aka default TX) */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 4b6e181c7dc9..453492610613 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -25,19 +25,20 @@ #include <bcmdefs.h> #include <bcmdevs.h> #include <bcmwifi.h> -#include <siutils.h> +#include <aiutils.h> #include <bcmsrom.h> #include <bcmotp.h> #include <bcmutils.h> +#include <bcmnvram.h> #include <wlioctl.h> #include <sbconfig.h> #include <sbchipc.h> #include <pcicfg.h> #include <sbhnddma.h> #include <hnddma.h> -#include <hndpmu.h> #include "wlc_types.h" +#include "wlc_pmu.h" #include "d11.h" #include "wlc_cfg.h" #include "wlc_rate.h" @@ -200,6 +201,8 @@ static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) { + struct wiphy *wiphy = wlc_hw->wlc->wiphy; + /* init microcode host flags */ wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); @@ -208,20 +211,21 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) if (WLCISNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11n0bsinitvals16); } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); } } else { if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, - wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in" + " core rev %d\n", __func__, + wlc_hw->unit, wlc_hw->corerev); } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -232,12 +236,9 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintmask; - WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); - ASSERT(bandunit != wlc_hw->band->bandunit); - ASSERT(si_iscoreup(wlc_hw->sih)); - ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); + WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); /* disable interrupts */ macintmask = wl_intrsoff(wlc->wl); @@ -245,8 +246,6 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) /* radio off */ wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - ASSERT(wlc_hw->clk); - wlc_bmac_core_phy_clk(wlc_hw, OFF); wlc_setxband(wlc_hw, bandunit); @@ -259,7 +258,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) * Return true if more frames need to be processed. false otherwise. * Param 'bound' indicates max. # frames to process before break out. */ -static bool BCMFASTPATH +static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) { struct sk_buff *p; @@ -267,10 +266,9 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) struct sk_buff *tail = NULL; uint n = 0; uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; - u32 tsf_h, tsf_l; wlc_d11rxhdr_t *wlc_rxhdr = NULL; - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* gather received frames */ while ((p = dma_rx(wlc_hw->di[fifo]))) { @@ -286,9 +284,6 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) break; } - /* get the TSF REG reading */ - wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h); - /* post more rbufs */ dma_rxfill(wlc_hw->di[fifo]); @@ -297,9 +292,7 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) head = head->prev; p->prev = NULL; - /* record the tsf_l in wlc_rxd11hdr */ wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; - wlc_rxhdr->tsf_l = cpu_to_le32(tsf_l); /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); @@ -314,15 +307,17 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) * Return true if another dpc needs to be re-scheduled. false otherwise. * Param 'bounded' indicates if applicable loops should be bounded. */ -bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) +bool wlc_dpc(struct wlc_info *wlc, bool bounded) { u32 macintstatus; struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; bool fatal = false; + struct wiphy *wiphy = wlc->wiphy; if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); wl_down(wlc->wl); return false; } @@ -331,13 +326,10 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) macintstatus = wlc->macintstatus; wlc->macintstatus = 0; - WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); + BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } + WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ /* BCN template is available */ /* ZZZ: Use AP_ACTIVE ? */ @@ -355,7 +347,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) wlc->macintstatus |= MI_TFS; if (fatal) { - WL_ERROR("MI_TFS: fatal\n"); + wiphy_err(wiphy, "MI_TFS: fatal\n"); goto fatal; } } @@ -365,17 +357,11 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* ATIM window end */ if (macintstatus & MI_ATIMWINEND) { - WL_TRACE("wlc_isr: end of ATIM window\n"); - + BCMMSG(wlc->wiphy, "end of ATIM window\n"); OR_REG(®s->maccommand, wlc->qvalid); wlc->qvalid = 0; } - /* phy tx error */ - if (macintstatus & MI_PHYTXERR) { - wlc->pub->_cnt->txphyerr++; - } - /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ if (macintstatus & MI_DMAINT) { if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { @@ -386,7 +372,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* TX FIFO suspend/flush completion */ if (macintstatus & MI_TXSTOP) { if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { - /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ + /* wiphy_err(wiphy, "dpc: fifo_suspend_comlete\n"); */ } } @@ -396,15 +382,12 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) } if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc_hw->unit, wlc_hw->now); + wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " + "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc_hw->sih->chip, wlc_hw->sih->chiprev); - - wlc->pub->_cnt->psmwds++; - /* big hammer */ wl_init(wlc->wl); } @@ -415,20 +398,14 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) } if (macintstatus & MI_RFDISABLE) { - WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit); - - wlc->pub->_cnt->rfdisable++; + BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" + " RF Disable Input\n", wlc_hw->unit); wl_rfkill_set_hw_state(wlc->wl); } /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); - - /* make sure the bound indication and the implementation are in sync */ - ASSERT(bounded == true || wlc->macintstatus == 0); + if (!pktq_empty(&wlc->pkt_queue->q)) + wlc_send_q(wlc); /* it isn't done and needs to be resched if macintstatus is non-zero */ return wlc->macintstatus != 0; @@ -444,7 +421,7 @@ void wlc_bmac_watchdog(void *arg) struct wlc_info *wlc = (struct wlc_info *) arg; struct wlc_hw_info *wlc_hw = wlc->hw; - WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); if (!wlc_hw->up) return; @@ -467,8 +444,7 @@ wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, { uint bandunit; - WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", - wlc_hw->unit, chanspec); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); wlc_hw->chanspec = chanspec; @@ -522,6 +498,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) struct wlc_hw_info *wlc_hw = wlc->hw; uint unit = wlc_hw->unit; wlc_tunables_t *tune = wlc->pub->tunables; + struct wiphy *wiphy = wlc->wiphy; /* name and offsets for dma_attach */ snprintf(name, sizeof(name), "wl%d", unit); @@ -537,8 +514,8 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { - WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_" + "resources failed\n", unit); return false; } @@ -547,8 +524,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * TX: TX_AC_BK_FIFO (TX AC Background data packets) * RX: RX_FIFO (RX data packets) */ - ASSERT(TX_AC_BK_FIFO == 0); - ASSERT(RX_FIFO == 0); wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, (wme ? DMAREG(wlc_hw, DMA_TX, 0) : NULL), DMAREG(wlc_hw, DMA_RX, 0), @@ -563,8 +538,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * (legacy) TX_DATA_FIFO (TX data packets) * RX: UNUSED */ - ASSERT(TX_AC_BE_FIFO == 1); - ASSERT(TX_DATA_FIFO == 1); wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 1), NULL, tune->ntxd, 0, 0, -1, 0, 0, @@ -576,7 +549,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * TX: TX_AC_VI_FIFO (TX AC Video data packets) * RX: UNUSED */ - ASSERT(TX_AC_VI_FIFO == 2); wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 2), NULL, tune->ntxd, 0, 0, -1, 0, 0, @@ -587,8 +559,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * TX: TX_AC_VO_FIFO (TX AC Voice data packets) * (legacy) TX_CTL_FIFO (TX control & mgmt packets) */ - ASSERT(TX_AC_VO_FIFO == 3); - ASSERT(TX_CTL_FIFO == 3); wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 3), NULL, tune->ntxd, 0, 0, -1, @@ -597,7 +567,8 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) /* Cleaner to leave this as if with AP defined */ if (dma_attach_err) { - WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); + wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" + "\n", unit); return false; } @@ -644,11 +615,10 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, uint j; bool wme = false; shared_phy_params_t sha_params; + struct wiphy *wiphy = wlc->wiphy; - WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", - unit, vendor, device); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor, + device); wme = true; @@ -666,10 +636,11 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, * Also initialize software state that depends on the particular hardware * we are running. */ - wlc_hw->sih = si_attach((uint) device, regsva, bustype, btparam, + wlc_hw->sih = ai_attach((uint) device, regsva, bustype, btparam, &wlc_hw->vars, &wlc_hw->vars_size); if (wlc_hw->sih == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: si_attach failed\n", + unit); err = 11; goto fail; } @@ -689,21 +660,23 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, var = getvar(vars, "vendid"); if (var) { vendor = (u16) simple_strtoul(var, NULL, 0); - WL_ERROR("Overriding vendor id = 0x%x\n", vendor); + wiphy_err(wiphy, "Overriding vendor id = 0x%x\n", + vendor); } var = getvar(vars, "devid"); if (var) { u16 devid = (u16) simple_strtoul(var, NULL, 0); if (devid != 0xffff) { device = devid; - WL_ERROR("Overriding device id = 0x%x\n", - device); + wiphy_err(wiphy, "Overriding device id = 0x%x" + "\n", device); } } /* verify again the device is supported */ if (!wlc_chipmatch(vendor, device)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported " + "vendor/device (0x%x/0x%x)\n", unit, vendor, device); err = 12; goto fail; @@ -714,8 +687,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->deviceid = device; /* set bar0 window to point at D11 core */ - wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); - wlc_hw->corerev = si_corerev(wlc_hw->sih); + wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); + wlc_hw->corerev = ai_corerev(wlc_hw->sih); regs = wlc_hw->regs; @@ -728,7 +701,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, } /* initialize power control registers */ - si_clkctl_init(wlc_hw->sih); + ai_clkctl_init(wlc_hw->sih); /* request fastclock and force fastclock for the rest of attach * bring the d11 core out of reset. @@ -739,8 +712,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); if (!wlc_bmac_validate_chip_access(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: validate_chip_access " + "failed\n", unit); err = 14; goto fail; } @@ -752,7 +725,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, j = BOARDREV_PROMOTED; wlc_hw->boardrev = (u16) j; if (!wlc_validboardtype(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported Broadcom " + "board type (0x%x)" " or revision level (0x%x)\n", unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); err = 15; goto fail; @@ -765,7 +739,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); if ((wlc_hw->sih->bustype == PCI_BUS) - && (si_pci_war16165(wlc_hw->sih))) + && (ai_pci_war16165(wlc_hw->sih))) wlc->war16165 = true; /* check device id(srom, nvram etc.) to set bands */ @@ -794,8 +768,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); if (wlc_hw->physhim == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_shim_attach " + "failed\n", unit); err = 25; goto fail; } @@ -844,23 +818,22 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; wlc->band->bandunit = j; wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->core->coreidx = si_coreidx(wlc_hw->sih); + wlc->core->coreidx = ai_coreidx(wlc_hw->sih); wlc_hw->machwcap = R_REG(®s->machwcap); wlc_hw->machwcap_backup = wlc_hw->machwcap; /* init tx fifo size */ - ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < - ARRAY_SIZE(xmtfifo_sz)); wlc_hw->xmtfifo_sz = xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; /* Get a phy for this band */ wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, wlc_bmac_bandtype(wlc_hw), vars); + (void *)regs, wlc_bmac_bandtype(wlc_hw), vars, + wlc->wiphy); if (wlc_hw->band->pi == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_" + "attach failed\n", unit); err = 17; goto fail; } @@ -890,9 +863,9 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, goto bad_phy; } else { bad_phy: - WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", - unit, - wlc_hw->band->phytype, wlc_hw->band->phyrev); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: unsupported " + "phy type/rev (%d/%d)\n", unit, + wlc_hw->band->phytype, wlc_hw->band->phyrev); err = 18; goto fail; } @@ -925,10 +898,10 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* Match driver "down" state */ if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); + ai_pci_down(wlc_hw->sih); /* register sb interrupt callback functions */ - si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, + ai_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, (void *)wlc_wlintrsrestore, NULL, wlc); /* turn off pll and xtal to match driver "down" state */ @@ -947,27 +920,30 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* init etheraddr state variables */ macaddr = wlc_get_macaddr(wlc_hw); if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: macaddr not found\n", + unit); err = 21; goto fail; } bcm_ether_atoe(macaddr, wlc_hw->etheraddr); if (is_broadcast_ether_addr(wlc_hw->etheraddr) || is_zero_ether_addr(wlc_hw->etheraddr)) { - WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", - unit, macaddr); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n", + unit, macaddr); err = 22; goto fail; } - WL_TRACE("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", - __func__, wlc_hw->deviceid, wlc_hw->_nbands, + BCMMSG(wlc->wiphy, + "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + wlc_hw->deviceid, wlc_hw->_nbands, wlc_hw->sih->boardtype, macaddr); return err; fail: - WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); + wiphy_err(wiphy, "wl%d: wlc_bmac_attach: failed with err %d\n", unit, + err); return err; } @@ -1011,10 +987,10 @@ int wlc_bmac_detach(struct wlc_info *wlc) /* detach interrupt sync mechanism since interrupt is disabled and per-port * interrupt object may has been freed. this must be done before sb core switch */ - si_deregister_intr_callback(wlc_hw->sih); + ai_deregister_intr_callback(wlc_hw->sih); if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_sleep(wlc_hw->sih); + ai_pci_sleep(wlc_hw->sih); } wlc_bmac_detach_dmapio(wlc_hw); @@ -1039,7 +1015,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) wlc_hw->vars = NULL; if (wlc_hw->sih) { - si_detach(wlc_hw->sih); + ai_detach(wlc_hw->sih); wlc_hw->sih = NULL; } @@ -1049,9 +1025,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) { - WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); - - wlc_hw->wlc->pub->_cnt->reset++; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset the core */ if (!DEVICEREMOVED(wlc_hw->wlc)) @@ -1070,7 +1044,7 @@ wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool fastclk; struct wlc_info *wlc = wlc_hw->wlc; - WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; @@ -1119,16 +1093,14 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) { uint coremask; - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, * and force fastclock for the remainder of wlc_up(). */ wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); + ai_clkctl_init(wlc_hw->sih); wlc_clkctl_clk(wlc_hw, CLK_FAST); /* @@ -1138,9 +1110,7 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) coremask = (1 << wlc_hw->wlc->core->coreidx); if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_setup(wlc_hw->sih, coremask); - - ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); + ai_pci_setup(wlc_hw->sih, coremask); /* * Need to read the hwradio status here to cover the case where the system @@ -1149,13 +1119,13 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { /* put SB PCI in down state again */ if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); + ai_pci_down(wlc_hw->sih); wlc_bmac_xtal(wlc_hw, OFF); - return BCME_RADIOOFF; + return -ENOMEDIUM; } if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_up(wlc_hw->sih); + ai_pci_up(wlc_hw->sih); /* reset the d11 core */ wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); @@ -1165,14 +1135,13 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) { - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); wlc_hw->up = true; wlc_phy_hw_state_upd(wlc_hw->band->pi, true); /* FULLY enable dynamic power control and d11 core interrupt */ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); - ASSERT(wlc_hw->wlc->macintmask == 0); wl_intrson(wlc_hw->wlc->wl); return 0; } @@ -1182,7 +1151,7 @@ int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) bool dev_gone; uint callbacks = 0; - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); if (!wlc_hw->up) return callbacks; @@ -1210,7 +1179,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) uint callbacks = 0; bool dev_gone; - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); if (!wlc_hw->up) return callbacks; @@ -1230,7 +1199,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) } else { /* Reset and disable the core */ - if (si_iscoreup(wlc_hw->sih)) { + if (ai_iscoreup(wlc_hw->sih)) { if (R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) wlc_suspend_mac_and_wait(wlc_hw->wlc); @@ -1241,7 +1210,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) /* turn off primary xtal and pll */ if (!wlc_hw->noreset) { if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); + ai_pci_down(wlc_hw->sih); wlc_bmac_xtal(wlc_hw, OFF); } } @@ -1257,8 +1226,6 @@ void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) /* wait until ucode is no longer asleep */ SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); - - ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); } void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) @@ -1292,9 +1259,9 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) (&wlc_hw->regs-> clk_ctl_st) & CCS_HTAVAIL) == 0), PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG - (&wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL); + WARN_ON(!(R_REG + (&wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL)); } else { if ((wlc_hw->sih->pmurev == 0) && (R_REG @@ -1316,11 +1283,12 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) * then use FCA to verify mac is running fast clock */ - wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); + wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode); /* check fast clock is available (if core is not in reset) */ if (wlc_hw->forcefastclk && wlc_hw->clk) - ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); + WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) & + SISF_FCLKA)); /* keep the ucode wake bit on if forcefastclk is on * since we do not want ucode to put us back to slow clock @@ -1382,9 +1350,8 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, }; struct wlc_hwband *band; - ASSERT((val & ~mask) == 0); - ASSERT(idx < MHFMAX); - ASSERT(ARRAY_SIZE(addr) == MHFMAX); + if ((val & ~mask) || idx >= MHFMAX) + return; /* error condition */ switch (bands) { /* Current band only or all bands, @@ -1401,8 +1368,7 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, band = wlc_hw->bandstate[BAND_2G_INDEX]; break; default: - ASSERT(0); - band = NULL; + band = NULL; /* error condition */ } if (band) { @@ -1429,8 +1395,9 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) { struct wlc_hwband *band; - ASSERT(idx < MHFMAX); + if (idx >= MHFMAX) + return 0; /* error condition */ switch (bands) { case WLC_BAND_AUTO: band = wlc_hw->band; @@ -1442,8 +1409,7 @@ u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) band = wlc_hw->bandstate[BAND_2G_INDEX]; break; default: - ASSERT(0); - band = NULL; + band = NULL; /* error condition */ } if (!band) @@ -1460,8 +1426,6 @@ static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) M_HOST_FLAGS5 }; - ASSERT(ARRAY_SIZE(addr) == MHFMAX); - for (idx = 0; idx < MHFMAX; idx++) { wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); } @@ -1486,8 +1450,8 @@ void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) u32 maccontrol; u32 new_maccontrol; - ASSERT((val & ~mask) == 0); - + if (val & ~mask) + return; /* error condition */ maccontrol = wlc_hw->maccontrol; new_maccontrol = (maccontrol & ~mask) | val; @@ -1522,8 +1486,6 @@ static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) { - ASSERT((wlc_hw->wake_override & override_bit) == 0); - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { mboolset(wlc_hw->wake_override, override_bit); return; @@ -1539,8 +1501,6 @@ void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) { - ASSERT(wlc_hw->wake_override & override_bit); - mboolclr(wlc_hw->wake_override, override_bit); if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) @@ -1591,33 +1551,6 @@ static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) } /* - * Write a MAC address to the rcmta structure - */ -void -wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata16 = (volatile u16 *)®s->objdata; - u32 mac_hm; - u16 mac_l; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - mac_hm = - (addr[3] << 24) | (addr[2] << 16) | - (addr[1] << 8) | addr[0]; - mac_l = (addr[5] << 8) | addr[4]; - - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, mac_hm); - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(®s->objaddr); - W_REG(objdata16, mac_l); -} - -/* * Write a MAC address to the given match reg offset in the RXE match engine. */ void @@ -1629,9 +1562,8 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, u16 mac_m; u16 mac_h; - WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); - - ASSERT(match_reg_offset < RCM_SIZE); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: wlc_bmac_set_addrmatch\n", + wlc_hw->unit); regs = wlc_hw->regs; mac_l = addr[0] | (addr[1] << 8); @@ -1653,17 +1585,9 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, d11regs_t *regs; u32 word; bool be_bit; -#ifdef IL_BIGENDIAN - volatile u16 *dptr = NULL; -#endif /* IL_BIGENDIAN */ - WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); regs = wlc_hw->regs; - - ASSERT(IS_ALIGNED(offset, sizeof(u32))); - ASSERT(IS_ALIGNED(len, sizeof(u32))); - ASSERT((offset & ~0xffff) == 0); - W_REG(®s->tplatewrptr, offset); /* if MCTL_BIGEND bit set in mac control register, @@ -1716,8 +1640,6 @@ void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) wlc_phy_bw_state_set(wlc_hw->band->pi, bw); - ASSERT(wlc_hw->clk); - wlc_bmac_phy_reset(wlc_hw); wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); @@ -1734,7 +1656,6 @@ wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, bcn); /* write beacon length to SCR */ - ASSERT(len < 65536); wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); /* mark beacon0 valid */ OR_REG(®s->maccommand, MCMD_BCN0VLD); @@ -1748,7 +1669,6 @@ wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, bcn); /* write beacon length to SCR */ - ASSERT(len < 65536); wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); /* mark beacon1 valid */ OR_REG(®s->maccommand, MCMD_BCN1VLD); @@ -1772,8 +1692,6 @@ wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, else if (! (R_REG(®s->maccommand) & MCMD_BCN1VLD)) wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); - else /* one template should always have been available */ - ASSERT(0); } } @@ -1800,15 +1718,8 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) { struct wlc_hw_info *wlc_hw = wlc->hw; - WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); - - /* sanity check */ - if (PHY_TYPE(R_REG(&wlc_hw->regs->phyversion)) != - PHY_TYPE_LCNXN) - ASSERT((uint) - PHY_TYPE(R_REG(&wlc_hw->regs->phyversion)) - == wlc_hw->band->phytype); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); wlc_ucode_bsinit(wlc_hw); @@ -1837,23 +1748,23 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) { - WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); wlc_hw->phyclk = clk; if (OFF == clk) { /* clear gmode bit, put phy into reset */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), (SICF_PRST | SICF_FGC)); udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); udelay(1); } else { /* take phy out of reset */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); + ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0); udelay(1); } @@ -1862,18 +1773,18 @@ static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) /* Perform a soft reset of the PHY PLL */ void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) { - WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); udelay(1); } @@ -1888,18 +1799,18 @@ void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) return; if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); + ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); else - si_core_cflags(wlc_hw->sih, SICF_FGC, 0); + ai_core_cflags(wlc_hw->sih, SICF_FGC, 0); } void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) { if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); else - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); } void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) @@ -1908,7 +1819,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) u32 phy_bw_clkbits; bool phy_in_reset = false; - WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); if (pih == NULL) return; @@ -1919,7 +1830,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && NREV_LE(wlc_hw->band->phyrev, 4)) { /* Set the PHY bandwidth */ - si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); + ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); udelay(1); @@ -1927,12 +1838,12 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) wlc_bmac_core_phypll_reset(wlc_hw); /* reset the PHY */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), (SICF_PRST | SICF_PCLKE)); phy_in_reset = true; } else { - si_core_cflags(wlc_hw->sih, + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE | SICF_BWMASK), (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); } @@ -1951,13 +1862,9 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, struct wlc_info *wlc = wlc_hw->wlc; u32 macintmask; - ASSERT(NBANDS_HW(wlc_hw) > 1); - ASSERT(bandunit != wlc_hw->band->bandunit); - /* Enable the d11 core before accessing it */ - if (!si_iscoreup(wlc_hw->sih)) { - si_core_reset(wlc_hw->sih, 0, 0); - ASSERT(si_iscoreup(wlc_hw->sih)); + if (!ai_iscoreup(wlc_hw->sih)) { + ai_core_reset(wlc_hw->sih, 0, 0); wlc_mctrl_reset(wlc_hw); } @@ -1983,14 +1890,14 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, wl_intrsrestore(wlc->wl, macintmask); /* ucode should still be suspended.. */ - ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); + WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); } /* low-level band switch utility routine */ void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) { - WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + bandunit); wlc_hw->band = wlc_hw->bandstate[bandunit]; @@ -1999,7 +1906,7 @@ void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) /* set gmode core flag */ if (wlc_hw->sbclk && !wlc_hw->noreset) { - si_core_cflags(wlc_hw->sih, SICF_GMODE, + ai_core_cflags(wlc_hw->sih, SICF_GMODE, ((bandunit == 0) ? SICF_GMODE : 0)); } } @@ -2009,7 +1916,8 @@ static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) /* reject unsupported corerev */ if (!VALID_COREREV(wlc_hw->corerev)) { - WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); + wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n", + wlc_hw->corerev); return false; } @@ -2034,7 +1942,7 @@ static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) goodboard = false; } - if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) + if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM) return goodboard; return goodboard; @@ -2057,8 +1965,8 @@ static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) macaddr = getvar(wlc_hw->vars, varname); if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", - wlc_hw->unit, varname); + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr " + "getvar(%s) not found\n", wlc_hw->unit, varname); } return macaddr; @@ -2094,9 +2002,9 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) (wlc_hw->sih->chip == BCM43225_CHIP_ID) || (wlc_hw->sih->chip == BCM43421_CHIP_ID)) wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); - si_core_reset(wlc_hw->sih, flags, resetbits); + ai_core_reset(wlc_hw->sih, flags, resetbits); wlc_mctrl_reset(wlc_hw); } @@ -2104,7 +2012,7 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) /* put core back into reset */ if (!clk) - si_core_disable(wlc_hw->sih, 0); + ai_core_disable(wlc_hw->sih, 0); if (!xtal) wlc_bmac_xtal(wlc_hw, OFF); @@ -2118,25 +2026,25 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) if (wlc_hw->wlc->pub->hw_up) return; - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, * and force fastclock for the remainder of wlc_up(). */ wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); + ai_clkctl_init(wlc_hw->sih); wlc_clkctl_clk(wlc_hw, CLK_FAST); if (wlc_hw->sih->bustype == PCI_BUS) { - si_pci_fixcfg(wlc_hw->sih); + ai_pci_fixcfg(wlc_hw->sih); /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || (wlc_hw->sih->chip == BCM43225_CHIP_ID) || (wlc_hw->sih->chip == BCM43421_CHIP_ID)) wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); } @@ -2151,7 +2059,7 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) if (! (wlc_hw->boardrev >= 0x1250 && (wlc_hw->boardflags & BFL_FEM_BT))) - si_epa_4313war(wlc_hw->sih); + ai_epa_4313war(wlc_hw->sih); } } @@ -2179,7 +2087,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) if (flags == WLC_USE_COREFLAGS) flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); regs = wlc_hw->regs; @@ -2189,17 +2097,19 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) wlc_clkctl_clk(wlc_hw, CLK_FAST); /* reset the dma engines except first time thru */ - if (si_iscoreup(wlc_hw->sih)) { + if (ai_iscoreup(wlc_hw->sih)) { for (i = 0; i < NFIFO; i++) if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, i); + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " + "dma_txreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, i); } if ((wlc_hw->di[RX_FIFO]) && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_FIFO); + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" + "[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_FIFO); } } /* if noreset, just stop the psm and return */ @@ -2224,7 +2134,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) * with other driver like mips/arm since they may touch chipcommon as well. */ wlc_hw->clk = false; - si_core_reset(wlc_hw->sih, flags, resetbits); + ai_core_reset(wlc_hw->sih, flags, resetbits); wlc_hw->clk = true; if (wlc_hw->band && wlc_hw->band->pi) wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); @@ -2315,10 +2225,11 @@ static void wlc_coreinit(struct wlc_info *wlc) bool fifosz_fixup = false; int err = 0; u16 buf[NFIFO]; + struct wiphy *wiphy = wlc->wiphy; regs = wlc_hw->regs; - WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset PSM */ wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); @@ -2338,29 +2249,31 @@ static void wlc_coreinit(struct wlc_info *wlc) SPINWAIT(((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0), 1000 * 1000); if ((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0) - WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", - wlc_hw->unit); + wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" + "suspend!\n", wlc_hw->unit); wlc_gpio_init(wlc); - sflags = si_core_sflags(wlc_hw->sih, 0, 0); + sflags = ai_core_sflags(wlc_hw->sih, 0, 0); if (D11REV_IS(wlc_hw->corerev, 23)) { if (WLCISNPHY(wlc_hw->band)) wlc_write_inits(wlc_hw, d11n0initvals16); else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11lcn0initvals24); } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); } } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } /* For old ucode, txfifo sizes needs to be modified(increased) */ @@ -2402,13 +2315,13 @@ static void wlc_coreinit(struct wlc_info *wlc) err = -1; } if (err != 0) { - WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", - buf[i], wlc_hw->xmtfifo_sz[i], i); - ASSERT(0); + wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" + " driver size %d index %d\n", buf[i], + wlc_hw->xmtfifo_sz[i], i); } /* make sure we can still talk to the mac */ - ASSERT(R_REG(®s->maccontrol) != 0xffffffff); + WARN_ON(R_REG(®s->maccontrol) == 0xffffffff); /* band-specific inits done by wlc_bsinit() */ @@ -2437,7 +2350,7 @@ static void wlc_coreinit(struct wlc_info *wlc) wlc_bmac_macphyclk_set(wlc_hw, ON); /* program dynamic clock control fast powerup delay register */ - wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); + wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih); W_REG(®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); /* tell the ucode the corerev */ @@ -2554,7 +2467,6 @@ static void wlc_gpio_init(struct wlc_info *wlc) wlc_phy_antsel_init(wlc_hw->band->pi, false); } else if (wlc_hw->antsel_type == ANTSEL_2x4) { - ASSERT((gm & BOARD_GPIO_12) == 0); gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); /* * The board itself is powered by these GPIOs @@ -2581,7 +2493,7 @@ static void wlc_gpio_init(struct wlc_info *wlc) gm |= gc |= BOARD_GPIO_PACTRL; /* apply to gpiocontrol register */ - si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); + ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); } static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) @@ -2598,16 +2510,18 @@ static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) bcm43xx_16_mimosz); wlc_hw->ucode_loaded = true; } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, bcm43xx_24_lcnsz); wlc_hw->ucode_loaded = true; } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -2618,9 +2532,7 @@ static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], uint i; uint count; - WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); - - ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); count = (nbytes / sizeof(u32)); @@ -2636,13 +2548,11 @@ static void wlc_write_inits(struct wlc_hw_info *wlc_hw, int i; volatile u8 *base; - WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); base = (volatile u8 *)wlc_hw->regs; for (i = 0; inits[i].addr != 0xffff; i++) { - ASSERT((inits[i].size == 2) || (inits[i].size == 4)); - if (inits[i].size == 2) W_REG((u16 *)(base + inits[i].addr), inits[i].value); @@ -2700,6 +2610,7 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) uint unit; uint intstatus, idx; d11regs_t *regs = wlc_hw->regs; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; unit = wlc_hw->unit; @@ -2710,46 +2621,41 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) if (!intstatus) continue; - WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", - unit, idx, intstatus); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", + unit, idx, intstatus); if (intstatus & I_RO) { - WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", - unit, idx); - wlc_hw->wlc->pub->_cnt->rxoflo++; + wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " + "overflow\n", unit, idx); fatal = true; } if (intstatus & I_PC) { - WL_ERROR("wl%d: fifo %d: descriptor error\n", + wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", unit, idx); - wlc_hw->wlc->pub->_cnt->dmade++; fatal = true; } if (intstatus & I_PD) { - WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); - wlc_hw->wlc->pub->_cnt->dmada++; + wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, + idx); fatal = true; } if (intstatus & I_DE) { - WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", - unit, idx); - wlc_hw->wlc->pub->_cnt->dmape++; + wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " + "error\n", unit, idx); fatal = true; } if (intstatus & I_RU) { - WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", - idx, unit); - wlc_hw->wlc->pub->_cnt->rxuflo[idx]++; + wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " + "underflow\n", idx, unit); } if (intstatus & I_XU) { - WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", - idx, unit); - wlc_hw->wlc->pub->_cnt->txuflo++; + wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " + "underflow\n", idx, unit); fatal = true; } @@ -2765,7 +2671,6 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) void wlc_intrson(struct wlc_info *wlc) { struct wlc_hw_info *wlc_hw = wlc->hw; - ASSERT(wlc->defmacintmask); wlc->macintmask = wlc->defmacintmask; W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } @@ -2859,7 +2764,7 @@ static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) { if (fifo >= NFIFO) - return BCME_RANGE; + return -EINVAL; *blocks = wlc_hw->xmtfifo_sz[fifo]; @@ -2962,7 +2867,8 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) /* macintstatus includes a DMA interrupt summary bit */ macintstatus = R_REG(®s->macintstatus); - WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); + BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, + macintstatus); /* detect cardbus removed, in power down(suspend) and in reset */ if (DEVICEREMOVED(wlc)) @@ -3013,8 +2919,6 @@ bool wlc_intrsupd(struct wlc_info *wlc) { u32 macintstatus; - ASSERT(wlc->macintstatus != 0); - /* read and clear macintstatus and intstatus registers */ macintstatus = wlc_intstatus(wlc, false); @@ -3034,7 +2938,7 @@ bool wlc_intrsupd(struct wlc_info *wlc) * *wantdpc will be set to true if further wlc_dpc() processing is required, * false otherwise. */ -bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) +bool wlc_isr(struct wlc_info *wlc, bool *wantdpc) { struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintstatus; @@ -3048,7 +2952,8 @@ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) macintstatus = wlc_intstatus(wlc, true); if (macintstatus == 0xffffffff) - WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); + wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" + " path\n"); /* it is not for us */ if (macintstatus == 0) @@ -3057,14 +2962,13 @@ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) *wantdpc = true; /* save interrupt status bits */ - ASSERT(wlc->macintstatus == 0); wlc->macintstatus = macintstatus; return true; } -static bool BCMFASTPATH +static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) { /* discard intermediate indications for ucode with one legitimate case: @@ -3083,7 +2987,7 @@ wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) /* process tx completion events in BMAC * Return true if more tx status need to be processed. false otherwise. */ -static bool BCMFASTPATH +static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) { bool morepending = false; @@ -3098,7 +3002,7 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) */ uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; - WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); txs = &txstatus; regs = wlc_hw->regs; @@ -3106,9 +3010,8 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) && (s1 = R_REG(®s->frmtxstatus)) & TXS_V) { if (s1 == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - ASSERT(s1 != 0xffffffff); return morepending; } @@ -3133,8 +3036,8 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) if (n >= max_tx_num) morepending = true; - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); + if (!pktq_empty(&wlc->pkt_queue->q)) + wlc_send_q(wlc); return morepending; } @@ -3144,9 +3047,10 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; + struct wiphy *wiphy = wlc->wiphy; - WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); /* * Track overlapping suspend requests @@ -3161,21 +3065,23 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) mc = R_REG(®s->maccontrol); if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); wl_down(wlc->wl); return; } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(mc & MCTL_EN_MAC); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_PSM_RUN)); + WARN_ON(!(mc & MCTL_EN_MAC)); mi = R_REG(®s->macintstatus); if (mi == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); wl_down(wlc->wl); return; } - ASSERT(!(mi & MI_MACSSPNDD)); + WARN_ON(mi & MI_MACSSPNDD); wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); @@ -3183,24 +3089,26 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) WLC_MAX_MAC_SUSPEND); if (!(R_REG(®s->macintstatus) & MI_MACSSPNDD)) { - WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, WLC_MAX_MAC_SUSPEND); - WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", - wlc_hw->unit, - R_REG(®s->psmdebug), - R_REG(®s->phydebug), - R_REG(®s->psm_brc)); + wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" + " and MI_MACSSPNDD is still not on.\n", + wlc_hw->unit, WLC_MAX_MAC_SUSPEND); + wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " + "psm_brc 0x%04x\n", wlc_hw->unit, + R_REG(®s->psmdebug), + R_REG(®s->phydebug), + R_REG(®s->psm_brc)); } mc = R_REG(®s->maccontrol); if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); wl_down(wlc->wl); return; } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(!(mc & MCTL_EN_MAC)); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_PSM_RUN)); + WARN_ON(mc & MCTL_EN_MAC); } void wlc_enable_mac(struct wlc_info *wlc) @@ -3209,32 +3117,31 @@ void wlc_enable_mac(struct wlc_info *wlc) d11regs_t *regs = wlc_hw->regs; u32 mc, mi; - WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", - wlc_hw->unit, wlc->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc->band->bandunit); /* * Track overlapping suspend requests */ - ASSERT(wlc_hw->mac_suspend_depth > 0); wlc_hw->mac_suspend_depth--; if (wlc_hw->mac_suspend_depth > 0) return; mc = R_REG(®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(!(mc & MCTL_EN_MAC)); - ASSERT(mc & MCTL_PSM_RUN); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(mc & MCTL_EN_MAC); + WARN_ON(!(mc & MCTL_PSM_RUN)); wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); W_REG(®s->macintstatus, MI_MACSSPNDD); mc = R_REG(®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_EN_MAC); - ASSERT(mc & MCTL_PSM_RUN); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_EN_MAC)); + WARN_ON(!(mc & MCTL_PSM_RUN)); mi = R_REG(®s->macintstatus); - ASSERT(!(mi & MI_MACSSPNDD)); + WARN_ON(mi & MI_MACSSPNDD); wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); } @@ -3314,7 +3221,7 @@ void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) wlc_upd_ofdm_pctl1_table(wlc_hw); } -void BCMFASTPATH +void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, u32 *tsf_h_ptr) { @@ -3331,8 +3238,9 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) { d11regs_t *regs; u32 w, val; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; - WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); + BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); regs = wlc_hw->regs; @@ -3351,8 +3259,8 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) (void)R_REG(®s->objaddr); val = R_REG(®s->objdata); if (val != (u32) 0xaa5555aa) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", - wlc_hw->unit, val); + wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " + "expected 0xaa5555aa\n", wlc_hw->unit, val); return false; } @@ -3364,8 +3272,8 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) (void)R_REG(®s->objaddr); val = R_REG(®s->objdata); if (val != (u32) 0x55aaaa55) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", - wlc_hw->unit, val); + wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " + "expected 0x55aaaa55\n", wlc_hw->unit, val); return false; } @@ -3379,10 +3287,10 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) w = R_REG(®s->maccontrol); if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { - WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", - wlc_hw->unit, w, - (MCTL_IHR_EN | MCTL_WAKE), - (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); + wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = " + "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, + (MCTL_IHR_EN | MCTL_WAKE), + (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); return false; } @@ -3396,7 +3304,7 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) d11regs_t *regs; u32 tmp; - WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); tmp = 0; regs = wlc_hw->regs; @@ -3413,9 +3321,8 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) tmp = R_REG(®s->clk_ctl_st); if ((tmp & (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" + " PLL failed\n", __func__); } } else { OR_REG(®s->clk_ctl_st, @@ -3431,9 +3338,8 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " + "PHY PLL failed\n", __func__); } } } else { @@ -3449,9 +3355,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) { bool dev_gone; - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - ASSERT(!wlc_hw->up); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); dev_gone = DEVICEREMOVED(wlc_hw->wlc); @@ -3477,24 +3381,24 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) /* remove gpio controls */ if (wlc_hw->ucode_dbgsel) - si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); + ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); wlc_hw->clk = false; - si_core_disable(wlc_hw->sih, 0); + ai_core_disable(wlc_hw->sih, 0); wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); } /* power both the pll and external oscillator on/off */ static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) { - WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); /* dont power down if plldown is false or we must poll hw radio disable */ if (!want && wlc_hw->pllreq) return; if (wlc_hw->sih) - si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); + ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); wlc_hw->sbclk = want; if (!wlc_hw->sbclk) { @@ -3516,8 +3420,7 @@ static void wlc_flushqueues(struct wlc_info *wlc) if (wlc_hw->di[i]) { dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); TXPKTPENDCLR(wlc, i); - WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", - i); + BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); } /* free any posted rx packets */ @@ -3534,26 +3437,6 @@ void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); } -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) -{ - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL); - } -} - static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) { @@ -3562,8 +3445,6 @@ wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) volatile u16 *objdata_hi = objdata_lo + 1; u16 v; - ASSERT((offset & 1) == 0); - W_REG(®s->objaddr, sel | (offset >> 2)); (void)R_REG(®s->objaddr); if (offset & 2) { @@ -3582,8 +3463,6 @@ wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; volatile u16 *objdata_hi = objdata_lo + 1; - ASSERT((offset & 1) == 0); - W_REG(®s->objaddr, sel | (offset >> 2)); (void)R_REG(®s->objaddr); if (offset & 2) { @@ -3606,11 +3485,7 @@ wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, const u8 *p = (const u8 *)buf; int i; - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) + if (len <= 0 || (offset & 1) || (len & 1)) return; for (i = 0; i < len; i += 2) { @@ -3632,11 +3507,7 @@ wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, u8 *p = (u8 *) buf; int i; - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) + if (len <= 0 || (offset & 1) || (len & 1)) return; for (i = 0; i < len; i += 2) { @@ -3648,8 +3519,8 @@ wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) { - WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", - wlc_hw->vars_size); + BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n", + wlc_hw->vars_size); *buf = wlc_hw->vars; *len = wlc_hw->vars_size; @@ -3673,15 +3544,8 @@ void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) } } -void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) -{ - wlc_hw->noreset = noreset_flag; -} - void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) { - ASSERT(req_bit); - if (set) { if (mboolisset(wlc_hw->pllreq, req_bit)) return; @@ -3709,12 +3573,6 @@ void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) return; } -/* this will be true for all ai chips */ -bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) -{ - return true; -} - u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) { u16 table_ptr; @@ -3730,7 +3588,7 @@ u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) /* for a given rate, the LS-nibble of the PLCP SIGNAL field is * the index into the rate table. */ - phy_rate = rate_info[rate] & RATE_MASK; + phy_rate = rate_info[rate] & WLC_RATE_MASK; index = phy_rate & 0xf; /* Find the SHM pointer to the rate table entry by looking in the diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index 9c2c658d05ab..a5dccc273ac5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -130,8 +130,6 @@ extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state); extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); -extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, - int len); extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, void *buf); extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, @@ -151,8 +149,6 @@ extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit); -extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr); extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, const u8 *addr); @@ -163,7 +159,6 @@ extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, u32 *tsf_h_ptr); extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); -extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL); @@ -176,7 +171,6 @@ extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit); -extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index bbcff4fb5147..2572541bde9b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -122,9 +122,6 @@ struct wlc_bsscfg { #define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) #define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) -extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg); - /* Extend N_ENAB to per-BSS */ #define BSS_N_ENAB(wlc, cfg) \ (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 96161c0ab65a..a3a2bf9b4f12 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -21,7 +21,8 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <bcmnvram.h> +#include <aiutils.h> #include <sbhnddma.h> #include <wlioctl.h> @@ -106,7 +107,8 @@ static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * *txpwr, u8 local_constraint_qdbm); -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels); +static void wlc_locale_add_channels(chanvec_t *target, + const chanvec_t *channels); static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); @@ -396,7 +398,8 @@ static const chanvec_t *g_table_locale_base[] = { &locale_5g_HIGH4 }; -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) +static void wlc_locale_add_channels(chanvec_t *target, + const chanvec_t *channels) { u8 i; for (i = 0; i < sizeof(chanvec_t); i++) { @@ -594,10 +597,7 @@ struct chan20_info chan20_info[] = { static const locale_info_t *wlc_get_locale_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { - WL_ERROR("%s: locale 2g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); - return NULL; + return NULL; /* error condition */ } return g_locale_2g_table[locale_idx]; } @@ -605,29 +605,22 @@ static const locale_info_t *wlc_get_locale_2g(u8 locale_idx) static const locale_info_t *wlc_get_locale_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { - WL_ERROR("%s: locale 5g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); - return NULL; + return NULL; /* error condition */ } return g_locale_5g_table[locale_idx]; } -const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) +static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { - WL_ERROR("%s: mimo 2g index size out of range %d\n", - __func__, locale_idx); return NULL; } return g_mimo_2g_table[locale_idx]; } -const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) +static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { - WL_ERROR("%s: mimo 5g index size out of range %d\n", - __func__, locale_idx); return NULL; } return g_mimo_5g_table[locale_idx]; @@ -641,11 +634,12 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) struct wlc_pub *pub = wlc->pub; char *ccode; - WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); if (wlc_cm == NULL) { - WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit, + __func__); return NULL; } wlc_cm->pub = pub; @@ -656,9 +650,6 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) ccode = getvar(wlc->pub->vars, "ccode"); if (ccode) { strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - WL_NONE("%s: SROM country code is %c%c\n", - __func__, - wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); } /* internal country information which must match regulatory constraints in firmware */ @@ -666,8 +657,6 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); country = wlc_country_lookup(wlc, country_abbrev); - ASSERT(country != NULL); - /* save default country for exiting 11d regulatory mode */ strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); @@ -708,10 +697,6 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, char mapped_ccode[WLC_CNTRY_BUF_SZ]; uint mapped_regrev; - WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", - __func__, country_abbrev, ccode, regrev, - wlc_cm->srom_ccode, wlc_cm->srom_regrev); - /* if regrev is -1, lookup the mapped country code, * otherwise use the ccode and regrev directly */ @@ -722,14 +707,13 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, &mapped_regrev); } else { /* find the matching built-in country definition */ - ASSERT(0); country = wlc_country_lookup_direct(ccode, regrev); strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); mapped_regrev = regrev; } if (country == NULL) - return BCME_BADARG; + return -EINVAL; /* set the driver state for the country */ wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, @@ -752,8 +736,6 @@ wlc_set_country_common(wlc_cm_info_t *wlc_cm, struct wlc_info *wlc = wlc_cm->wlc; char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; - ASSERT(country != NULL); - /* save current country state */ wlc_cm->country = country; @@ -821,8 +803,8 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, /* check for currently supported ccode size */ if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { - WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", - wlc->pub->unit, __func__, ccode); + wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for " + "match\n", wlc->pub->unit, __func__, ccode); return NULL; } @@ -837,8 +819,7 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, if (!strcmp(srom_ccode, ccode)) { *mapped_regrev = srom_regrev; mapped = 0; - WL_ERROR("srom_code == ccode %s\n", __func__); - ASSERT(0); + wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); } else { mapped = wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, @@ -851,7 +832,6 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, /* if there is not an exact rev match, default to rev zero */ if (country == NULL && *mapped_regrev != 0) { *mapped_regrev = 0; - ASSERT(0); country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); } @@ -888,9 +868,6 @@ static const country_info_t *wlc_country_lookup_direct(const char *ccode, return &cntry_locales[i].country; } } - - WL_ERROR("%s: Returning NULL\n", __func__); - ASSERT(0); return NULL; } @@ -911,12 +888,10 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) li = BAND_5G(band->bandtype) ? wlc_get_locale_5g(country->locale_5G) : wlc_get_locale_2g(country->locale_2G); - ASSERT(li); wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; li_mimo = BAND_5G(band->bandtype) ? wlc_get_mimo_5g(country->locale_mimo_5G) : wlc_get_mimo_2g(country->locale_mimo_2G); - ASSERT(li_mimo); /* merge the mimo non-mimo locale flags */ wlc_cm->bandstate[band->bandunit].locale_flags |= @@ -968,9 +943,10 @@ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) if (chan == INVCHANNEL) { /* country/locale with no valid channels, set the radio disable bit */ mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", - wlc->pub->unit, __func__, - wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); + wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " + "nbands %d bandlocked %d\n", wlc->pub->unit, + __func__, wlc_cm->country_abbrev, NBANDS(wlc), + wlc->bandlocked); } else if (mboolisset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE)) { @@ -1520,10 +1496,9 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) u8 channel = CHSPEC_CHANNEL(chspec); /* check the chanspec */ - if (wf_chspec_malformed(chspec)) { - WL_ERROR("wl%d: malformed chanspec 0x%x\n", - wlc->pub->unit, chspec); - ASSERT(0); + if (bcm_chspec_malformed(chspec)) { + wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); return false; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h index 50a4e38b4cca..cab10c737937 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_key.h @@ -115,7 +115,7 @@ typedef struct wsec_key { #define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ #define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ -#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR) +#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (-EBADE) #define wlc_key_update(a, b, c) do {} while (0) #define wlc_key_remove(a, b, c) do {} while (0) #define wlc_key_remove_all(a, b) do {} while (0) @@ -126,12 +126,12 @@ typedef struct wsec_key { #define wlc_key_hw_init(a, b, c) do {} while (0) #define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) #define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) -#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR) +#define wlc_key_sw_wowl_create(a, b, c) (-EBADE) #define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) #define wlc_key_iv_init(a, b, c) do {} while (0) -#define wlc_key_set_error(a, b, c) (BCME_ERROR) -#define wlc_key_dump_hw(a, b) (BCME_ERROR) -#define wlc_key_dump_sw(a, b) (BCME_ERROR) +#define wlc_key_set_error(a, b, c) (-EBADE) +#define wlc_key_dump_hw(a, b) (-EBADE) +#define wlc_key_dump_sw(a, b) (-EBADE) #define wlc_key_defkeyflag(a) (0) #define wlc_rcmta_add_bssid(a, b) do {} while (0) #define wlc_rcmta_del_bssid(a, b) do {} while (0) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index ab7ab850e199..4b4a31eff90c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -16,20 +16,22 @@ #include <linux/kernel.h> #include <linux/ctype.h> #include <linux/etherdevice.h> +#include <linux/pci_ids.h> #include <net/mac80211.h> #include <bcmdefs.h> #include <bcmdevs.h> #include <bcmutils.h> #include <bcmwifi.h> -#include <siutils.h> +#include <bcmnvram.h> +#include <aiutils.h> #include <pcicfg.h> #include <bcmsrom.h> #include <wlioctl.h> #include <sbhnddma.h> #include <hnddma.h> -#include <hndpmu.h> +#include "wlc_pmu.h" #include "d11.h" #include "wlc_types.h" #include "wlc_cfg.h" @@ -51,12 +53,7 @@ #include "wlc_alloc.h" #include "wl_dbg.h" -/* - * Disable statistics counting for WME - */ -#define WLCNTSET(a, b) -#define WLCNTINCR(a) -#define WLCNTADD(a, b) +#include "wl_mac80211.h" /* * WPA(2) definitions @@ -242,7 +239,7 @@ static const u8 acbitmap2maxprio[] = { #define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS /* local prototypes */ -static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, +static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, @@ -250,8 +247,6 @@ static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, uint next_frag_len, wsec_key_t *key, ratespec_t rspec_override); - -static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat); static void wlc_bss_default_init(struct wlc_info *wlc); static void wlc_ucode_mac_upd(struct wlc_info *wlc); static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, @@ -273,13 +268,13 @@ static void wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, int prio); static void wlc_txflowcontrol_reset(struct wlc_info *wlc); -static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, - uint length); -static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rate, + uint length, u8 *plcp); static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); +static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh); static void wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p); static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, @@ -320,35 +315,6 @@ static void wlc_ofdm_rateset_war(struct wlc_info *wlc); static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif); -#if defined(BCMDBG) -void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) -{ - d11regs_t *regs = wlc->regs; - u32 v32; - - WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(®s->objaddr); - v32 = R_REG(®s->objdata); - addr[0] = (u8) v32; - addr[1] = (u8) (v32 >> 8); - addr[2] = (u8) (v32 >> 16); - addr[3] = (u8) (v32 >> 24); - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(®s->objaddr); - v32 = R_REG(®s->objdata); - addr[4] = (u8) v32; - addr[5] = (u8) (v32 >> 8); -} -#endif /* defined(BCMDBG) */ - -/* keep the chip awake if needed */ -bool wlc_stay_awake(struct wlc_info *wlc) -{ - return true; -} - /* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful */ bool wlc_ps_allowed(struct wlc_info *wlc) @@ -380,7 +346,7 @@ bool wlc_ps_allowed(struct wlc_info *wlc) void wlc_reset(struct wlc_info *wlc) { - WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); wlc->check_for_unaligned_tbtt = false; @@ -392,14 +358,14 @@ void wlc_reset(struct wlc_info *wlc) sizeof(macstat_t)); wlc_bmac_reset(wlc->hw); - wlc_ampdu_reset(wlc->ampdu); wlc->txretried = 0; } void wlc_fatal_error(struct wlc_info *wlc) { - WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", + wlc->pub->unit); wl_init(wlc->wl); } @@ -414,11 +380,6 @@ static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | WL_CHANSPEC_BAND_2G; - /* make sure the channel is on the supported band if we are band-restricted */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - } - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); return chanspec; } @@ -440,7 +401,7 @@ void wlc_init(struct wlc_info *wlc) struct wlc_bsscfg *bsscfg; bool mute = false; - WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); regs = wlc->regs; @@ -463,7 +424,6 @@ void wlc_init(struct wlc_info *wlc) wlc_bcn_li_upd(wlc); wlc->bcn_wait_prd = (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); - ASSERT(wlc->bcn_wait_prd > 0); /* the world is new again, so is our reported rate */ wlc_reprate_init(wlc); @@ -524,7 +484,7 @@ void wlc_init(struct wlc_info *wlc) /* Enable EDCF mode (while the MAC is suspended) */ if (EDCF_ENAB(wlc->pub)) { OR_REG(®s->ifs_ctl, IFS_USEEDCF); - wlc_edcf_setparams(wlc->cfg, false); + wlc_edcf_setparams(wlc, false); } /* Init precedence maps for empty FIFOs */ @@ -559,7 +519,6 @@ void wlc_init(struct wlc_info *wlc) if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Uninitialized; read from HW */ int ac; - ASSERT(wlc->clk); for (ac = 0; ac < AC_COUNT; ac++) { wlc->wme_retries[ac] = wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); @@ -604,82 +563,27 @@ void wlc_mac_promisc(struct wlc_info *wlc) wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); } -/* check if hps and wake states of sw and hw are in sync */ -bool wlc_ps_check(struct wlc_info *wlc) -{ - bool res = true; - bool hps, wake; - bool wake_ok; - - if (!AP_ACTIVE(wlc)) { - u32 tmp; - tmp = R_REG(&wlc->regs->maccontrol); - - /* - * If deviceremoved is detected, then don't take any action as - * this can be called in any context. Assume that caller will - * take care of the condition. This is just to avoid assert - */ - if (tmp == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); - return DEVICEREMOVED(wlc); - } - - hps = PS_ALLOWED(wlc); - - if (hps != ((tmp & MCTL_HPS) != 0)) { - int idx; - struct wlc_bsscfg *cfg; - WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", - wlc->pub->unit, hps, tmp); - FOREACH_BSS(wlc, idx, cfg) { - if (!BSSCFG_STA(cfg)) - continue; - } - - res = false; - } - /* For a monolithic build the wake check can be exact since it looks at wake - * override bits. The MCTL_WAKE bit should match the 'wake' value. - */ - wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; - wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); - if (hps && !wake_ok) { - WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", - wlc->pub->unit, wake, tmp); - res = false; - } - } - ASSERT(res); - return res; -} - /* push sw hps and wake state through hardware */ void wlc_set_ps_ctrl(struct wlc_info *wlc) { u32 v1, v2; - bool hps, wake; + bool hps; bool awake_before; hps = PS_ALLOWED(wlc); - wake = hps ? (STAY_AWAKE(wlc)) : true; - WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", - wlc->pub->unit, hps, wake); + BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); v1 = R_REG(&wlc->regs->maccontrol); - v2 = 0; + v2 = MCTL_WAKE; if (hps) v2 |= MCTL_HPS; - if (wake) - v2 |= MCTL_WAKE; wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); - if (wake && !awake_before) + if (!awake_before) wlc_bmac_wait_for_wake(wlc->hw); } @@ -730,8 +634,6 @@ void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) int idx; struct wlc_bsscfg *cfg; - ASSERT(wlc->band->gmode); - /* use the override if it is set */ if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); @@ -762,8 +664,8 @@ static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) local = WLC_TXPWR_MAX; if (wlc->pub->associated && - (wf_chspec_ctlchan(wlc->chanspec) == - wf_chspec_ctlchan(wlc->home_chanspec))) { + (bcm_chspec_ctlchan(wlc->chanspec) == + bcm_chspec_ctlchan(wlc->home_chanspec))) { /* get the local power constraint if we are on the AP's * channel [802.11h, 7.3.2.13] @@ -826,9 +728,8 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) chanspec_t old_chanspec = wlc->chanspec; if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { - WL_ERROR("wl%d: %s: Bad channel %d\n", - wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", + wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; } @@ -838,9 +739,10 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { switchband = true; if (wlc->bandlocked) { - WL_ERROR("wl%d: %s: chspec %d band is locked!\n", - wlc->pub->unit, __func__, - CHSPEC_CHANNEL(chanspec)); + wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " + "band is locked!\n", + wlc->pub->unit, __func__, + CHSPEC_CHANNEL(chanspec)); return; } /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? @@ -852,8 +754,6 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) } } - ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); - /* sync up phy/radio chanspec */ wlc_set_phy_chanspec(wlc, chanspec); @@ -887,7 +787,7 @@ static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) if (len == sizeof(tx_power_legacy_t)) old_power = (tx_power_legacy_t *) pwr; else if (len < sizeof(tx_power_t)) - return BCME_BUFTOOSHORT; + return -EOVERFLOW; memset(&power, 0, sizeof(tx_power_t)); @@ -1098,10 +998,10 @@ ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) uint i; /* Use the lowest basic rate */ - lowest_basic_rspec = rs->rates[0] & RATE_MASK; + lowest_basic_rspec = rs->rates[0] & WLC_RATE_MASK; for (i = 0; i < rs->count; i++) { if (rs->rates[i] & WLC_RATE_FLAG) { - lowest_basic_rspec = rs->rates[i] & RATE_MASK; + lowest_basic_rspec = rs->rates[i] & WLC_RATE_MASK; break; } } @@ -1141,7 +1041,7 @@ void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) */ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) { - WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); + BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); switch (idx) { case WLC_PROT_G_SPEC: @@ -1179,7 +1079,6 @@ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) break; default: - ASSERT(0); break; } @@ -1252,14 +1151,12 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) uint parkband; uint i, band_order[2]; - WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* * We might have been bandlocked during down and the chip power-cycled (hibernate). * figure out the right band to park on */ if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ band_order[0] = band_order[1] = parkband; } else { @@ -1281,7 +1178,7 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) /* fill in hw_rate */ wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, - false, WLC_RATES_CCK_OFDM, RATE_MASK, + false, WLC_RATES_CCK_OFDM, WLC_RATE_MASK, (bool) N_ENAB(wlc->pub)); /* init basic rate lookup */ @@ -1295,7 +1192,7 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) /* band-specific init */ static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) { - WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc->pub->unit, wlc->band->bandunit); /* write ucode ACK/CTS rate table */ @@ -1315,10 +1212,6 @@ static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) int idx; struct wlc_bsscfg *cfg; - ASSERT(NBANDS(wlc) > 1); - ASSERT(!wlc->bandlocked); - ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); - wlc->band = wlc->bandstate[bandunit]; if (!wlc->pub->up) @@ -1355,41 +1248,28 @@ void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) cpu_to_le16(EDCF_AC_VO_TXOP_STA)} } }; - - ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); memcpy(pe, &stadef, sizeof(*pe)); } -void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) +void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, + const struct ieee80211_tx_queue_params *params, + bool suspend) { int i; shm_acparams_t acp_shm; u16 *shm_entry; - struct ieee80211_tx_queue_params *params = arg; - - ASSERT(wlc); /* Only apply params if the core is out of reset and has clocks */ if (!wlc->clk) { - WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, + __func__); return; } - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - wlc->wme_admctl = 0; do { memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ - /* fill in shm ac params struct */ acp_shm.txop = le16_to_cpu(params->txop); /* convert from units of 32us to us for ucode */ @@ -1403,8 +1283,8 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); + wiphy_err(wlc->wiphy, "wl%d: wlc_edcf_setparams: bad " + "aifs %d\n", wlc->pub->unit, acp_shm.aifs); continue; } @@ -1439,20 +1319,14 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) } -void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend) +void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) { - struct wlc_info *wlc = cfg->wlc; - uint aci, i, j; + u16 aci; + int i_ac; edcf_acparam_t *edcf_acp; - shm_acparams_t acp_shm; - u16 *shm_entry; - ASSERT(cfg); - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) - return; + struct ieee80211_tx_queue_params txq_pars; + struct ieee80211_tx_queue_params *params = &txq_pars; /* * AP uses AC params from wme_param_ie_ap. @@ -1462,59 +1336,24 @@ void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend) edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; - wlc->wme_admctl = 0; - - for (i = 0; i < AC_COUNT; i++, edcf_acp++) { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) { /* find out which ac this set of params applies to */ aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; - ASSERT(aci < AC_COUNT); /* set the admission control policy for this AC */ if (edcf_acp->ACI & EDCF_ACM_MASK) { wlc->wme_admctl |= 1 << aci; } /* fill in shm ac params struct */ - acp_shm.txop = le16_to_cpu(edcf_acp->TXOP); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } + params->txop = edcf_acp->TXOP; + params->aifs = edcf_acp->ACI; /* CWmin = 2^(ECWmin) - 1 */ - acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); + params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); /* CWmax = 2^(ECWmax) - 1 */ - acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) + params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT); - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + j, - *shm_entry++); + wlc_wme_setparams(wlc, aci, params, suspend); } if (suspend) @@ -1535,14 +1374,16 @@ bool wlc_timers_init(struct wlc_info *wlc, int unit) wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, wlc, "watchdog"); if (!wlc->wdtimer) { - WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); + wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer " + "failed\n", unit); goto fail; } wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, wlc, "radio"); if (!wlc->radio_timer) { - WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); + wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer " + "failed\n", unit); goto fail; } @@ -1689,20 +1530,23 @@ static uint wlc_attach_module(struct wlc_info *wlc) wlc->asi = wlc_antsel_attach(wlc); if (wlc->asi == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_antsel_attach " + "failed\n", unit); err = 44; goto fail; } wlc->ampdu = wlc_ampdu_attach(wlc); if (wlc->ampdu == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_ampdu_attach " + "failed\n", unit); err = 50; goto fail; } if ((wlc_stf_attach(wlc) != 0)) { - WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_stf_attach " + "failed\n", unit); err = 68; goto fail; } @@ -1720,56 +1564,21 @@ struct wlc_pub *wlc_pub(void *wlc) /* * The common driver entry routine. Error codes should be unique */ -void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - void *regsva, uint bustype, void *btparam, uint *perr) +void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, + bool piomode, void *regsva, uint bustype, void *btparam, + uint *perr) { struct wlc_info *wlc; uint err = 0; uint j; struct wlc_pub *pub; - struct wlc_txq_info *qi; uint n_disabled; - WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", - unit, __func__, vendor, device); - - ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); - ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); - - /* some code depends on packed structures */ - ASSERT(sizeof(struct ethhdr) == ETH_HLEN); - ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); - ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); - ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); - ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); - ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); - ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); -#ifdef BRCM_FULLMAC - ASSERT(offsetof(wl_scan_params_t, channel_list) == - WL_SCAN_PARAMS_FIXED_SIZE); -#endif - ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); - ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - /* - * Number of replay counters value used in WPA IE must match # rxivs - * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 - * 'RSN Information Element' figure 8 for this mapping. - */ - ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 16 == WLC_NUMRXIVS) - || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 4 == WLC_NUMRXIVS)); - /* allocate struct wlc_info state and its substructures */ wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); if (wlc == NULL) goto fail; + wlc->wiphy = wl->wiphy; pub = wlc->pub; #if defined(BCMDBG) @@ -1892,7 +1701,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* fill in hw_rateset (used early by WLC_SET_RATESET) */ wlc_rateset_filter(&wlc->band->defrateset, &wlc->band->hw_rateset, false, - WLC_RATES_CCK_OFDM, RATE_MASK, + WLC_RATES_CCK_OFDM, WLC_RATE_MASK, (bool) N_ENAB(wlc->pub)); } @@ -1905,7 +1714,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, goto fail; if (!wlc_timers_init(wlc, unit)) { - WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); + wiphy_err(wl->wiphy, "wl%d: %s: wlc_init_timer failed\n", unit, + __func__); err = 32; goto fail; } @@ -1913,8 +1723,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* depend on rateset, gmode */ wlc->cmi = wlc_channel_mgr_attach(wlc); if (!wlc->cmi) { - WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", - unit, __func__); + wiphy_err(wl->wiphy, "wl%d: %s: wlc_channel_mgr_attach failed" + "\n", unit, __func__); err = 33; goto fail; } @@ -1927,26 +1737,19 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, */ /* allocate our initial queue */ - qi = wlc_txq_alloc(wlc); - if (qi == NULL) { - WL_ERROR("wl%d: %s: failed to malloc tx queue\n", - unit, __func__); + wlc->pkt_queue = wlc_txq_alloc(wlc); + if (wlc->pkt_queue == NULL) { + wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", + unit, __func__); err = 100; goto fail; } - wlc->active_queue = qi; wlc->bsscfg[0] = wlc->cfg; wlc->cfg->_idx = 0; wlc->cfg->wlc = wlc; pub->txmaxpkts = MAXTXPKTS; - pub->_cnt->version = WL_CNT_T_VERSION; - pub->_cnt->length = sizeof(struct wl_cnt); - - WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); - WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); - wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); wlc->mimoft = FT_HT; @@ -2014,7 +1817,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, return (void *)wlc; fail: - WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); + wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n", + unit, __func__, err); if (wlc) wlc_detach(wlc); @@ -2032,8 +1836,8 @@ static void wlc_attach_antgain_init(struct wlc_info *wlc) /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ wlc->band->antgain = 8; } else if (wlc->band->antgain == -1) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", - unit, __func__); + 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; @@ -2072,8 +1876,8 @@ static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa1" : "aa0")); if ((aa < 1) || (aa > 15)) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", - unit, __func__, aa); + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" + " srom (0x%x), using 3\n", unit, __func__, aa); aa = 3; } @@ -2134,15 +1938,12 @@ static void wlc_detach_module(struct wlc_info *wlc) */ uint wlc_detach(struct wlc_info *wlc) { - uint i; uint callbacks = 0; if (wlc == NULL) return 0; - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - ASSERT(!wlc->pub->up); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); callbacks += wlc_bmac_detach(wlc); @@ -2182,13 +1983,6 @@ uint wlc_detach(struct wlc_info *wlc) while (wlc->tx_queues != NULL) wlc_txq_free(wlc, wlc->tx_queues); - /* - * consistency check: wlc_module_register/wlc_module_unregister calls - * should match therefore nothing should be left here. - */ - for (i = 0; i < WLC_MAXMODULES; i++) - ASSERT(wlc->modulecb[i].name[0] == '\0'); - wlc_detach_mfree(wlc); return callbacks; } @@ -2300,8 +2094,6 @@ static void wlc_radio_upd(struct wlc_info *wlc) /* maintain LED behavior in down state */ static void wlc_down_led_upd(struct wlc_info *wlc) { - ASSERT(!wlc->pub->up); - /* maintain LEDs while in down state, turn on sbclk if not available yet */ /* turn on sbclk if necessary */ if (!AP_ENAB(wlc->pub)) { @@ -2349,7 +2141,8 @@ static void wlc_radio_timer(void *arg) struct wlc_info *wlc = (struct wlc_info *) arg; if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); wl_down(wlc->wl); return; } @@ -2358,8 +2151,6 @@ static void wlc_radio_timer(void *arg) if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) wlc->mpc_offcnt++; - /* validate all the reasons driver could be down and running this radio_timer */ - ASSERT(wlc->pub->radio_disabled || wlc->down_override); wlc_radio_hwdisable_upd(wlc); wlc_radio_upd(wlc); } @@ -2381,56 +2172,11 @@ bool wlc_radio_monitor_stop(struct wlc_info *wlc) if (!wlc->radio_monitor) return true; - ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != - WL_SWFL_NOHWRADIO); - wlc->radio_monitor = false; wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); return wl_del_timer(wlc->wl, wlc->radio_timer); } -/* bring the driver down, but don't reset hardware */ -void wlc_out(struct wlc_info *wlc) -{ - wlc_bmac_set_noreset(wlc->hw, true); - wlc_radio_upd(wlc); - wl_down(wlc->wl); - wlc_bmac_set_noreset(wlc->hw, false); - - /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ - wlc->clk = true; - - /* This will make sure that when 'up' is done - * after 'out' it'll restore hardware (especially gpios) - */ - wlc->pub->hw_up = false; -} - -#if defined(BCMDBG) -/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that - * if there is no packet pending for the FIFO, then the corresponding prec bits should be set - * in prec_map. Of course, ignore this rule when block_datafifo is set - */ -static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) -{ - /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both - * fail the check. - */ - if (!EDCF_ENAB(wlc->pub)) { - if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || - WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) - return false; - else - return true; - } - - return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); -} -#endif /* BCMDBG */ - static void wlc_watchdog_by_timer(void *arg) { struct wlc_info *wlc = (struct wlc_info *) arg; @@ -2450,13 +2196,14 @@ static void wlc_watchdog(void *arg) int i; struct wlc_bsscfg *cfg; - WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); if (!wlc->pub->up) return; if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); wl_down(wlc->wl); return; } @@ -2480,9 +2227,6 @@ static void wlc_watchdog(void *arg) /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ wlc_radio_hwdisable_upd(wlc); wlc_radio_upd(wlc); - /* if ismpc, driver should be in down state if up/down is allowed */ - if (wlc->mpc && wlc_ismpc(wlc)) - ASSERT(!wlc->pub->up); /* if radio is disable, driver may be down, quit here */ if (wlc->pub->radio_disabled) return; @@ -2515,23 +2259,16 @@ static void wlc_watchdog(void *arg) wlc->tempsense_lasttime = wlc->pub->now; wlc_tempsense_upd(wlc); } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - ASSERT(wlc_bmac_taclear(wlc->hw, true)); - - /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ - ASSERT(wlc_tx_prec_map_verify(wlc)); - - ASSERT(wlc_ps_check(wlc)); } /* make interface operational */ int wlc_up(struct wlc_info *wlc) { - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* HW is turned off so don't try to access it */ if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) - return BCME_RADIOOFF; + return -ENOMEDIUM; if (!wlc->pub->hw_up) { wlc_bmac_hw_up(wlc->hw); @@ -2556,11 +2293,11 @@ int wlc_up(struct wlc_info *wlc) * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) * don't call radio_update to avoid looping wlc_up. * - * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only + * wlc_bmac_up_prep() returns either 0 or -BCME_RADIOOFF only */ if (!wlc->pub->radio_disabled) { int status = wlc_bmac_up_prep(wlc->hw); - if (status == BCME_RADIOOFF) { + if (status == -ENOMEDIUM) { if (!mboolisset (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { int idx; @@ -2572,12 +2309,13 @@ int wlc_up(struct wlc_info *wlc) if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) continue; - WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", - wlc->pub->unit, idx); + wiphy_err(wlc->wiphy, "wl%d.%d: wlc_up" + ": rfdisable -> " + "wlc_bsscfg_disable()\n", + wlc->pub->unit, idx); } } - } else - ASSERT(!status); + } } if (wlc->pub->radio_disabled) { @@ -2621,7 +2359,6 @@ int wlc_up(struct wlc_info *wlc) wlc_wme_retries_write(wlc); /* start one second watchdog timer */ - ASSERT(!wlc->WDarmed); wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); wlc->WDarmed = true; @@ -2673,12 +2410,12 @@ uint wlc_down(struct wlc_info *wlc) bool dev_gone = false; struct wlc_txq_info *qi; - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* check if we are already in the going down path */ if (wlc->going_down) { - WL_ERROR("wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" + "\n", wlc->pub->unit, __func__); return 0; } if (!wlc->pub->up) @@ -2707,9 +2444,6 @@ uint wlc_down(struct wlc_info *wlc) /* cancel all other timers */ callbacks += wlc_down_del_timer(wlc); - /* interrupt must have been blocked */ - ASSERT((wlc->macintmask == 0) || !wlc->pub->up); - wlc->pub->up = false; wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); @@ -2719,8 +2453,7 @@ uint wlc_down(struct wlc_info *wlc) /* flush tx queues */ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - pktq_flush(&qi->q, true, NULL, 0); - ASSERT(pktq_empty(&qi->q)); + bcm_pktq_flush(&qi->q, true, NULL, NULL); } callbacks += wlc_bmac_down_finish(wlc->hw); @@ -2728,13 +2461,6 @@ uint wlc_down(struct wlc_info *wlc) /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ wlc->clk = false; -#ifdef BCMDBG - /* Since all the packets should have been freed, - * all callbacks should have been called - */ - for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) - ASSERT(wlc->pkt_callback[i].fn == NULL); -#endif wlc->going_down = false; return callbacks; } @@ -2761,7 +2487,7 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) * Gmode is not GMODE_LEGACY_B */ if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) - return BCME_UNSUPPORTED; + return -ENOTSUPP; /* verify that we are dealing with 2G band and grab the band pointer */ if (wlc->band->bandtype == WLC_BAND_2G) @@ -2770,12 +2496,12 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) band = wlc->bandstate[OTHERBANDUNIT(wlc)]; else - return BCME_BADBAND; + return -EINVAL; /* Legacy or bust when no OFDM is supported by regulatory */ if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) - return BCME_RANGE; + return -EINVAL; /* update configuration value */ if (config == true) @@ -2823,9 +2549,9 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) default: /* Error */ - WL_ERROR("wl%d: %s: invalid gmode %d\n", - wlc->pub->unit, __func__, gmode); - return BCME_UNSUPPORTED; + wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", + wlc->pub->unit, __func__, gmode); + return -ENOTSUPP; } /* @@ -2904,11 +2630,11 @@ static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) case WL_11N_2x2: case WL_11N_3x3: if (!(WLC_PHY_11N_CAP(wlc->band))) - err = BCME_BADBAND; + err = -EINVAL; break; default: - err = BCME_RANGE; + err = -EINVAL; break; } @@ -2921,7 +2647,6 @@ int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) int err; err = wlc_nmode_validate(wlc, nmode); - ASSERT(err == 0); if (err) return err; @@ -2950,7 +2675,6 @@ int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) nmode = WL_11N_2x2; case WL_11N_2x2: case WL_11N_3x3: - ASSERT(WLC_PHY_11N_CAP(wlc->band)); /* force GMODE_AUTO if NMODE is ON */ wlc_set_gmode(wlc, GMODE_AUTO, true); if (nmode == WL_11N_3x3) @@ -2967,7 +2691,6 @@ int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) break; default: - ASSERT(0); break; } @@ -2983,7 +2706,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) /* check for bad count value */ if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) - return BCME_BADRATESET; + return -EINVAL; /* try the current band */ bandunit = wlc->band->bandunit; @@ -3005,7 +2728,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) goto good; } - return BCME_ERROR; + return -EBADE; good: /* apply new rateset */ @@ -3067,8 +2790,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wlc_bss_info_t *current_bss; /* update bsscfg pointer */ - bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ - current_bss = NULL; + bsscfg = wlc->cfg; + current_bss = bsscfg->current_bss; /* initialize the following to get rid of compiler warning */ nextscb = NULL; @@ -3078,13 +2801,12 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* If the device is turned off, then it's not "removed" */ if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); wl_down(wlc->wl); - return BCME_ERROR; + return -EBADE; } - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - /* default argument is generic integer */ pval = arg ? (int *)arg:NULL; @@ -3096,11 +2818,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* bool conversion to avoid duplication below */ bool_val = val != 0; - - if (cmd != WLC_SET_CHANNEL) - WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", - cmd, (uint)val, val, len); - bcmerror = 0; regs = wlc->regs; @@ -3118,9 +2835,10 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, default: if ((arg == NULL) || (len <= 0)) { - WL_ERROR("wl%d: %s: Command %d needs arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = BCME_BADARG; + wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs " + "arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = -EINVAL; goto done; } } @@ -3144,7 +2862,10 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_GET_CHANNEL:{ channel_info_t *ci = (channel_info_t *) arg; - ASSERT(len > (int)sizeof(ci)); + if (len <= (int)sizeof(ci)) { + bcmerror = EOVERFLOW; + goto done; + } ci->hw_channel = CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); @@ -3159,12 +2880,12 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, chanspec_t chspec = CH20MHZ_CHSPEC(val); if (val < 0 || val > MAXCHANNEL) { - bcmerror = BCME_OUTOFRANGECHAN; + bcmerror = -EINVAL; break; } if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { - bcmerror = BCME_BADCHAN; + bcmerror = -EINVAL; break; } @@ -3191,7 +2912,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, #if defined(BCMDBG) case WLC_GET_UCFLAGS: if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; break; } @@ -3206,7 +2927,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; if (val >= MHFMAX) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -3215,7 +2936,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_UCFLAGS: if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; break; } @@ -3231,7 +2952,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, i = (u16) val; if (i >= MHFMAX) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -3253,7 +2974,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; if (val & 1) { - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; } @@ -3274,7 +2995,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; if (val & 1) { - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; } @@ -3288,7 +3009,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, band = WLC_BAND_AUTO; if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3301,7 +3022,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; } if (r->size == sizeof(u32)) @@ -3313,7 +3034,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, R_REG((u16 *)((unsigned char *)(unsigned long)regs + r->byteoff)); else - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; case WLC_W_REG: @@ -3322,7 +3043,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, band = WLC_BAND_AUTO; if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3335,7 +3056,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; } if (r->size == sizeof(u32)) @@ -3345,7 +3066,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, W_REG((u16 *)((unsigned char *)(unsigned long) regs + r->byteoff), r->val); else - bcmerror = BCME_BADADDR; + bcmerror = -EINVAL; break; #endif /* BCMDBG */ @@ -3393,7 +3114,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_ANTDIV: /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ if ((val < -1) || (val > 3)) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -3408,13 +3129,13 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, u16 rxstatus; if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; break; } rxstatus = R_REG(&wlc->regs->phyrxstatus0); if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; } *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; @@ -3424,7 +3145,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, #if defined(BCMDBG) case WLC_GET_UCANTDIV: if (!wlc->clk) { - bcmerror = BCME_NOCLK; + bcmerror = -EIO; break; } @@ -3435,13 +3156,13 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_UCANTDIV:{ if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; break; } /* if multiband, band must be locked */ if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = BCME_NOTBANDLOCKED; + bcmerror = -ENOMEDIUM; break; } @@ -3467,7 +3188,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, } wlc_wme_retries_write(wlc); } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; case WLC_GET_LRL: @@ -3486,7 +3207,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, } wlc_wme_retries_write(wlc); } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; case WLC_GET_CWMIN: @@ -3495,14 +3216,14 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_CWMIN: if (!wlc->clk) { - bcmerror = BCME_NOCLK; + bcmerror = -EIO; break; } if (val >= 1 && val <= 255) { wlc_set_cwmin(wlc, (u16) val); } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; case WLC_GET_CWMAX: @@ -3511,14 +3232,14 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_CWMAX: if (!wlc->clk) { - bcmerror = BCME_NOCLK; + bcmerror = -EIO; break; } if (val >= 255 && val <= 2047) { wlc_set_cwmax(wlc, (u16) val); } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ @@ -3539,9 +3260,9 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if ((radiomask == 0) || (radiomask & ~validbits) || (radioval & ~validbits) || ((radioval & ~radiomask) != 0)) { - WL_ERROR("SET_RADIO with wrong bits 0x%x\n", - val); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "SET_RADIO with wrong " + "bits 0x%x\n", val); + bcmerror = -EINVAL; break; } @@ -3566,7 +3287,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wsec_key_t *src_key = wlc->wsec_keys[val]; if (len < (int)sizeof(key)) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3586,7 +3307,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, memcpy(arg, &key, sizeof(key)); } else - bcmerror = BCME_BADKEYIDX; + bcmerror = -EINVAL; break; #endif /* defined(BCMDBG) */ @@ -3600,7 +3321,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wsec_key_t *key; if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3637,7 +3358,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, memcpy(arg, seq, sizeof(seq)); } else { - bcmerror = BCME_BADKEYIDX; + bcmerror = -EINVAL; } break; } @@ -3646,13 +3367,13 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wl_rateset_t *ret_rs = (wl_rateset_t *) arg; wlc_rateset_t *rs; - if (bsscfg->associated) + if (wlc->pub->associated) rs = ¤t_bss->rateset; else rs = &wlc->default_bss->rateset; if (len < (int)(rs->count + sizeof(rs->count))) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3670,7 +3391,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3685,12 +3406,12 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wl_rateset_t *in_rs = (wl_rateset_t *) arg; if (len < (int)(in_rs->count + sizeof(in_rs->count))) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } if (in_rs->count > WLC_NUMRATES) { - bcmerror = BCME_BUFTOOLONG; + bcmerror = -ENOBUFS; break; } @@ -3733,7 +3454,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, && val <= DOT11_MAX_BEACON_PERIOD) { wlc->default_bss->beacon_period = (u16) val; } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; case WLC_GET_DTIMPRD: @@ -3749,7 +3470,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, && val <= DOT11_MAX_DTIM_PERIOD) { wlc->default_bss->dtim_period = (u8) val; } else - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; #ifdef SUPPORT_PS @@ -3765,7 +3486,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* Change watchdog driver to align watchdog with tbtt if possible */ wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); } else - bcmerror = BCME_ERROR; + bcmerror = -EBADE; break; #endif /* SUPPORT_PS */ @@ -3773,7 +3494,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, #ifdef BCMDBG case WLC_GET_WAKE: if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; + bcmerror = -BCME_NOTSTA; break; } *pval = wlc->wake; @@ -3781,7 +3502,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_WAKE: if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; + bcmerror = -BCME_NOTSTA; break; } @@ -3816,24 +3537,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wlc->default_bss->atim_window = (u32) val; break; - case WLC_GET_PKTCNTS:{ - get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; - wlc_statsupd(wlc); - pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe; - pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror; - pktcnt->tx_good_pkt = - wlc->pub->_cnt->txfrmsnt; - pktcnt->tx_bad_pkt = - wlc->pub->_cnt->txerror + - wlc->pub->_cnt->txfail; - if (len >= (int)sizeof(get_pktcnt_t)) { - /* Be backward compatible - only if buffer is large enough */ - pktcnt->rx_ocast_good_pkt = - wlc->pub->_cnt->rxmfrmocast; - } - break; - } - #ifdef SUPPORT_HWKEY case WLC_GET_WSEC: bcmerror = @@ -3876,7 +3579,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, { unsigned char *cp = arg; if (len < 3) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } @@ -3902,7 +3605,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_SHORTSLOT_OVERRIDE: if ((val != WLC_SHORTSLOT_AUTO) && (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -3959,7 +3662,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (!wlc->pub->associated) bcmerror = wlc_set_gmode(wlc, (u8) val, true); else { - bcmerror = BCME_ASSOCIATED; + bcmerror = -EISCONN; break; } break; @@ -3976,7 +3679,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if ((val != WLC_PROTECTION_CTL_OFF) && (val != WLC_PROTECTION_CTL_LOCAL) && (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -3995,7 +3698,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_GMODE_PROTECTION_OVERRIDE: if ((val != WLC_PROTECTION_AUTO) && (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } @@ -4008,14 +3711,14 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* copyin */ if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } memcpy(&rs, arg, sizeof(wlc_rateset_t)); /* check for bad count value */ if (rs.count > WLC_NUMRATES) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ + bcmerror = -EINVAL; break; } @@ -4023,7 +3726,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (!(wlc->band->gmode || ((NBANDS(wlc) > 1) && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + /* gmode only command when not in gmode */ + bcmerror = -EINVAL; break; } @@ -4034,15 +3738,19 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - /* validate rateset by comparing pre and post sorted against 11g hw rates */ - wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, - RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); + /* + * validate rateset by comparing pre and + * post sorted against 11g hw rates + */ + wlc_rateset_filter(&rs, &new, false, + WLC_RATES_CCK_OFDM, WLC_RATE_MASK, + BSS_N_ENAB(wlc, bsscfg)); wlc_rate_hwrs_filter_sort_validate(&new, &cck_ofdm_rates, false, wlc->stf->txstreams); if (rs.count != new.count) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ + bcmerror = -EINVAL; break; } @@ -4064,11 +3772,12 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (!(wlc->band->gmode || ((NBANDS(wlc) > 1) && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + /* gmode only command when not in gmode */ + bcmerror = -EINVAL; break; } if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); @@ -4081,11 +3790,11 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_PRB_RESP_TIMEOUT: if (wlc->pub->up) { - bcmerror = BCME_NOTDOWN; + bcmerror = -EISCONN; break; } if (val < 0 || val >= 0xFFFF) { - bcmerror = BCME_RANGE; /* bad value */ + bcmerror = -EINVAL; /* bad value */ break; } wlc->prb_resp_timeout = (u16) val; @@ -4099,7 +3808,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (key != NULL) { *pval = key->id == val ? true : false; } else { - bcmerror = BCME_BADKEYIDX; + bcmerror = -EINVAL; } break; } @@ -4107,7 +3816,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_SET_KEY_PRIMARY:{ wsec_key_t *key, *old_key; - bcmerror = BCME_BADKEYIDX; + bcmerror = -EINVAL; /* treat the 'val' parm as the key id */ for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { @@ -4119,7 +3828,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, ~WSEC_PRIMARY_KEY; key->flags |= WSEC_PRIMARY_KEY; bsscfg->wsec_index = i; - bcmerror = BCME_OK; + bcmerror = 0; } } break; @@ -4141,7 +3850,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, ; if (i == (uint) len) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; break; } i++; /* include the null in the string length */ @@ -4162,37 +3871,25 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, } case WLC_SET_WSEC_PMK: - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; break; #if defined(BCMDBG) case WLC_CURRENT_PWR: if (!wlc->pub->up) - bcmerror = BCME_NOTUP; + bcmerror = -ENOLINK; else bcmerror = wlc_get_current_txpwr(wlc, arg, len); break; #endif case WLC_LAST: - WL_ERROR("%s: WLC_LAST\n", __func__); + wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__); } done: - if (bcmerror) { - if (VALID_BCMERROR(bcmerror)) - wlc->pub->bcmerror = bcmerror; - else { - bcmerror = 0; - } - - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would - * certainly result in getting -1 for register reads. So skip ta_clear altogether - */ - if (!(wlc->pub->hw_off)) - ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); + if (bcmerror) + wlc->pub->bcmerror = bcmerror; return bcmerror; } @@ -4203,30 +3900,20 @@ int wlc_iocregchk(struct wlc_info *wlc, uint band) { /* if band is specified, it must be the current band */ if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) - return BCME_BADBAND; + return -EINVAL; /* if multiband and band is not specified, band must be locked */ if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return BCME_NOTBANDLOCKED; + return -ENOMEDIUM; /* must have core clocks */ if (!wlc->clk) - return BCME_NOCLK; + return -EIO; return 0; } #endif /* defined(BCMDBG) */ -#if defined(BCMDBG) -/* For some ioctls, make sure that the pi pointer matches the current phy */ -int wlc_iocpichk(struct wlc_info *wlc, uint phytype) -{ - if (wlc->band->phytype != phytype) - return BCME_BADBAND; - return 0; -} -#endif - /* Look up the given var name in the given table */ static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, const char *name) @@ -4241,8 +3928,6 @@ static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, else lookup_name = name; - ASSERT(table != NULL); - for (vi = table; vi->name; vi++) { if (!strcmp(vi->name, lookup_name)) return vi; @@ -4266,21 +3951,6 @@ int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) IOV_SET, NULL); } -/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) -{ - int iovar_int; - int err; - - err = - wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), - IOV_GET, NULL); - if (!err) - *arg = (s8) iovar_int; - - return err; -} - /* * register iovar table, watchdog and down handlers. * calling function must keep 'iovars' until wlc_module_unregister is called. @@ -4293,9 +3963,6 @@ int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, struct wlc_info *wlc = (struct wlc_info *) pub->wlc; int i; - ASSERT(name != NULL); - ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); - /* find an empty entry and just add, no duplication check! */ for (i = 0; i < WLC_MAXMODULES; i++) { if (wlc->modulecb[i].name[0] == '\0') { @@ -4310,9 +3977,7 @@ int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, } } - /* it is time to increase the capacity */ - ASSERT(i < WLC_MAXMODULES); - return BCME_NORESOURCE; + return -ENOSR; } /* unregister module callbacks */ @@ -4322,9 +3987,7 @@ int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) int i; if (wlc == NULL) - return BCME_NOTFOUND; - - ASSERT(name != NULL); + return -ENODATA; for (i = 0; i < WLC_MAXMODULES; i++) { if (!strcmp(wlc->modulecb[i].name, name) && @@ -4335,7 +3998,7 @@ int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) } /* table not found! */ - return BCME_NOTFOUND; + return -ENODATA; } /* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ @@ -4371,23 +4034,11 @@ wlc_iovar_op(struct wlc_info *wlc, const char *name, u32 actionid; int i; - ASSERT(name != NULL); - - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !p_len)); - if (!set && (len == sizeof(int)) && !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - WL_ERROR("wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name); - ASSERT(0); + wiphy_err(wlc->wiphy, "wl%d: %s unaligned get ptr for %s\n", + wlc->pub->unit, __func__, name); + return -ENOTSUPP; } /* find the given iovar name */ @@ -4400,8 +4051,7 @@ wlc_iovar_op(struct wlc_info *wlc, const char *name, } /* iovar name not found */ if (i >= WLC_MAXMODULES) { - err = BCME_UNSUPPORTED; - goto exit; + return -ENOTSUPP; } /* set up 'params' pointer in case this is a set command so that @@ -4426,8 +4076,6 @@ wlc_iovar_op(struct wlc_info *wlc, const char *name, err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, name, params, p_len, arg, len, val_size, wlcif); - - exit: return err; } @@ -4443,22 +4091,22 @@ wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, if (set) { if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + err = (wlc->pub->up ? -EISCONN : -ENOLINK); } else if ((vi->flags & IOVF_SET_BAND) && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; + err = -ENOMEDIUM; } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = BCME_NOCLK; + err = -EIO; } } else { if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + err = (wlc->pub->up ? -EISCONN : -ENOLINK); } else if ((vi->flags & IOVF_GET_BAND) && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; + err = -ENOMEDIUM; } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = BCME_NOCLK; + err = -EIO; } } @@ -4513,7 +4161,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, bool bool_val2; wlc_bss_info_t *current_bss; - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); bsscfg = NULL; current_bss = NULL; @@ -4537,8 +4185,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, bool_val = (int_val != 0) ? true : false; bool_val2 = (int_val2 != 0) ? true : false; - WL_TRACE("wl%d: %s: id %d\n", - wlc->pub->unit, __func__, IOV_ID(actionid)); + BCMMSG(wlc->wiphy, "wl%d: id %d\n", wlc->pub->unit, IOV_ID(actionid)); /* Do the actual parameter implementation */ switch (actionid) { case IOV_SVAL(IOV_RTSTHRESH): @@ -4551,7 +4198,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - if (err != BCME_OK) + if (err != 0) return err; /* Return qdbm units */ @@ -4599,8 +4246,9 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, break; default: - WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); - err = BCME_UNSUPPORTED; + wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n", + wlc->pub->unit, __func__); + err = -ENOTSUPP; break; } @@ -4635,7 +4283,7 @@ wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) /* Signed values are checked against max_val and min_val */ if ((s32) val < (s32) min_val || (s32) val > (s32) max_val) - err = BCME_RANGE; + err = -EINVAL; break; case IOVT_UINT32: @@ -4649,7 +4297,7 @@ wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) if (vi->flags & IOVF_NTRL) min_val = 1; if ((val < min_val) || (val > max_val)) - err = BCME_RANGE; + err = -EINVAL; break; } @@ -4708,24 +4356,6 @@ void wlc_print_txstatus(tx_status_t *txs) #endif /* defined(BCMDBG) */ } -static void -wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat) -{ - u16 v; - u16 delta; - - v = le16_to_cpu(cur_stat); - delta = (u16)(v - *macstat_snapshot); - - if (delta != 0) { - *macstat += delta; - *macstat_snapshot = v; - } -} - -#define MACSTATUPD(name) \ - wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) - void wlc_statsupd(struct wlc_info *wlc) { int i; @@ -4753,68 +4383,12 @@ void wlc_statsupd(struct wlc_info *wlc) wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, &macstats, sizeof(macstat_t)); - /* update mac stats */ - MACSTATUPD(txallfrm); - MACSTATUPD(txrtsfrm); - MACSTATUPD(txctsfrm); - MACSTATUPD(txackfrm); - MACSTATUPD(txdnlfrm); - MACSTATUPD(txbcnfrm); - for (i = 0; i < NFIFO; i++) - MACSTATUPD(txfunfl[i]); - MACSTATUPD(txtplunfl); - MACSTATUPD(txphyerr); - MACSTATUPD(rxfrmtoolong); - MACSTATUPD(rxfrmtooshrt); - MACSTATUPD(rxinvmachdr); - MACSTATUPD(rxbadfcs); - MACSTATUPD(rxbadplcp); - MACSTATUPD(rxcrsglitch); - MACSTATUPD(rxstrt); - MACSTATUPD(rxdfrmucastmbss); - MACSTATUPD(rxmfrmucastmbss); - MACSTATUPD(rxcfrmucast); - MACSTATUPD(rxrtsucast); - MACSTATUPD(rxctsucast); - MACSTATUPD(rxackucast); - MACSTATUPD(rxdfrmocast); - MACSTATUPD(rxmfrmocast); - MACSTATUPD(rxcfrmocast); - MACSTATUPD(rxrtsocast); - MACSTATUPD(rxctsocast); - MACSTATUPD(rxdfrmmcast); - MACSTATUPD(rxmfrmmcast); - MACSTATUPD(rxcfrmmcast); - MACSTATUPD(rxbeaconmbss); - MACSTATUPD(rxdfrmucastobss); - MACSTATUPD(rxbeaconobss); - MACSTATUPD(rxrsptmout); - MACSTATUPD(bcntxcancl); - MACSTATUPD(rxf0ovfl); - MACSTATUPD(rxf1ovfl); - MACSTATUPD(rxf2ovfl); - MACSTATUPD(txsfovfl); - MACSTATUPD(pmqovfl); - MACSTATUPD(rxcgprqfrm); - MACSTATUPD(rxcgprsqovfl); - MACSTATUPD(txcgprsfail); - MACSTATUPD(txcgprssuc); - MACSTATUPD(prs_timeout); - MACSTATUPD(rxnack); - MACSTATUPD(frmscons); - MACSTATUPD(txnack); - MACSTATUPD(txglitch_nack); - MACSTATUPD(txburst); - MACSTATUPD(phywatchdog); - MACSTATUPD(pktengrxducast); - MACSTATUPD(pktengrxdmcast); - #ifdef BCMDBG /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) - WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", - wlc->pub->unit, delta); + wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", + wlc->pub->unit, delta); /* check for tx fifo underflows */ for (i = 0; i < NFIFO; i++) { @@ -4822,57 +4396,23 @@ void wlc_statsupd(struct wlc_info *wlc) (u16) (wlc->core->macstat_snapshot->txfunfl[i] - txfunfl[i]); if (delta) - WL_ERROR("wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); + wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" + "\n", wlc->pub->unit, delta, i); } #endif /* BCMDBG */ - /* dot11 counter update */ - - WLCNTSET(wlc->pub->_cnt->txrts, - (wlc->pub->_cnt->rxctsucast - - wlc->pub->_cnt->d11cnt_txrts_off)); - WLCNTSET(wlc->pub->_cnt->rxcrc, - (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); - WLCNTSET(wlc->pub->_cnt->txnocts, - ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - - wlc->pub->_cnt->d11cnt_txnocts_off)); - /* merge counters from dma module */ for (i = 0; i < NFIFO; i++) { if (wlc->hw->di[i]) { - WLCNTADD(wlc->pub->_cnt->txnobuf, - (wlc->hw->di[i])->txnobuf); - WLCNTADD(wlc->pub->_cnt->rxnobuf, - (wlc->hw->di[i])->rxnobuf); - WLCNTADD(wlc->pub->_cnt->rxgiant, - (wlc->hw->di[i])->rxgiants); dma_counterreset(wlc->hw->di[i]); } } - - /* - * Aggregate transmit and receive errors that probably resulted - * in the loss of a frame are computed on the fly. - */ - WLCNTSET(wlc->pub->_cnt->txerror, - wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + - wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + - wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + - wlc->pub->_cnt->dmape); - WLCNTSET(wlc->pub->_cnt->rxerror, - wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + - wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + - wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + - wlc->pub->_cnt->rxbadsrcmac); - for (i = 0; i < NFIFO; i++) - wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i]; } bool wlc_chipmatch(u16 vendor, u16 device) { - if (vendor != VENDOR_BROADCOM) { - WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); + if (vendor != PCI_VENDOR_ID_BROADCOM) { + pr_err("wlc_chipmatch: unknown vendor id %04x\n", vendor); return false; } @@ -4884,7 +4424,7 @@ bool wlc_chipmatch(u16 vendor, u16 device) if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); + pr_err("wlc_chipmatch: unknown device id %04x\n", device); return false; } @@ -4923,7 +4463,9 @@ void wlc_print_txdesc(d11txh_t *txh) char hexbuf[256]; /* add plcp header along with txh descriptor */ - prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); + printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + txh, sizeof(d11txh_t) + 48); printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); @@ -4994,7 +4536,8 @@ void wlc_print_rxh(d11rxhdr_t *rxh) {0, NULL} }; - prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); + printk(KERN_DEBUG "Raw RxDesc:\n"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(d11rxhdr_t)); bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); @@ -5033,8 +4576,6 @@ int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) } } *p = '\0'; - ASSERT(p < endp); - return (int)(p - buf); } #endif /* defined(BCMDBG) */ @@ -5055,13 +4596,13 @@ static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) * * Returns true if packet consumed (queued), false if not. */ -bool BCMFASTPATH +bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) { return wlc_prec_enq_head(wlc, q, pkt, prec, false); } -bool BCMFASTPATH +bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, int prec, bool head) { @@ -5072,11 +4613,10 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p != NULL); + p = bcm_pktq_peek_tail(q, &eprec); if (eprec > prec) { - WL_ERROR("%s: Failing: eprec %d > prec %d\n", - __func__, eprec, prec); + wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" + "\n", __func__, eprec, prec); return false; } } @@ -5085,69 +4625,51 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, if (eprec >= 0) { bool discard_oldest; - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); /* Refuse newer packet unless configured to discard oldest */ if (eprec == prec && !discard_oldest) { - WL_ERROR("%s: No where to go, prec == %d\n", - __func__, prec); + wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d" + "\n", __func__, prec); return false; } /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, - eprec); - ASSERT(p != NULL); - - /* Increment wme stats */ - if (WME_ENAB(wlc->pub)) { - WLCNTINCR(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].packets); - WLCNTADD(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].bytes, - pkttotlen(p)); - } - pkt_buf_free_skb(p); - wlc->pub->_cnt->txnobuf++; + p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : + bcm_pktq_pdeq_tail(q, eprec); + bcm_pkt_buf_free_skb(p); } /* Enqueue */ if (head) - p = pktq_penq_head(q, prec, pkt); + p = bcm_pktq_penq_head(q, prec, pkt); else - p = pktq_penq(q, prec, pkt); - ASSERT(p != NULL); + p = bcm_pktq_penq(q, prec, pkt); return true; } -void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, +void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, uint prec) { struct wlc_info *wlc = (struct wlc_info *) ctx; - struct wlc_txq_info *qi = wlc->active_queue; /* Check me */ + struct wlc_txq_info *qi = wlc->pkt_queue; /* Check me */ struct pktq *q = &qi->q; int prio; prio = sdu->priority; - ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); - if (!wlc_prec_enq(wlc, q, sdu, prec)) { if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", - wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: wlc_txq_enq: txq overflow" + "\n", wlc->pub->unit); /* * XXX we might hit this condtion in case * packet flooding from mac80211 stack */ - pkt_buf_free_skb(sdu); - wlc->pub->_cnt->txnobuf++; + bcm_pkt_buf_free_skb(sdu); } /* Check if flow control needs to be turned on after enqueuing the packet @@ -5167,7 +4689,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, } } -bool BCMFASTPATH +bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw) { @@ -5177,43 +4699,30 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct scb *scb = &global_scb; struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - ASSERT(sdu); - /* 802.11 standard requires management traffic to go at highest priority */ prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : MAXPRIO; fifo = prio2fifo[prio]; - - ASSERT((uint) skb_headroom(sdu) >= TXOFF); - ASSERT(!(sdu->next)); - ASSERT(!(sdu->prev)); - ASSERT(fifo < NFIFO); - pkt = sdu; if (unlikely (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) return -EINVAL; wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); - wlc_send_q(wlc, wlc->active_queue); - - wlc->pub->_cnt->ieee_tx++; + wlc_send_q(wlc); return 0; } -void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) +void wlc_send_q(struct wlc_info *wlc) { struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; int prec; u16 prec_map; int err = 0, i, count; uint fifo; + struct wlc_txq_info *qi = wlc->pkt_queue; struct pktq *q = &qi->q; struct ieee80211_tx_info *tx_info; - /* only do work for the active queue */ - if (qi != wlc->active_queue) - return; - if (in_send_q) return; else @@ -5224,7 +4733,7 @@ void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) /* Send all the enq'd pkts that we can. * Dequeue packets with precedence with empty HW fifo only */ - while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { + while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) { tx_info = IEEE80211_SKB_CB(pkt[0]); if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); @@ -5238,8 +4747,8 @@ void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) } } - if (err == BCME_BUSY) { - pktq_penq_head(q, prec, pkt[0]); + if (err == -EBUSY) { + bcm_pktq_penq_head(q, prec, pkt[0]); /* If send failed due to any other reason than a change in * HW FIFO condition, quit. Otherwise, read the new prec_map! */ @@ -5290,14 +4799,13 @@ bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg, return frameid; } -void BCMFASTPATH +void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, s8 txpktpend) { u16 frameid = INVALIDFID; d11txh_t *txh; - ASSERT(fifo < NFIFO); txh = (d11txh_t *) (p->data); /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update @@ -5317,7 +4825,7 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, */ if (commit) { TXPKTPENDINC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", + BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n", txpktpend, TXPKTPENDGET(wlc, fifo)); } @@ -5326,57 +4834,11 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, BCMCFID(wlc, frameid); if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); + wiphy_err(wlc->wiphy, "wlc_txfifo: fatal, toss frames !!!\n"); } } -static u16 -wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) -{ - u16 usec = 0; - uint mac_rate = RSPEC2RATE(rspec); - uint nsyms; - - if (IS_MCS(rspec)) { - /* not supported yet */ - ASSERT(0); - } else if (IS_OFDM(rspec)) { - /* nsyms = Ceiling(Nbits / (Nbits/sym)) - * - * Nbits = length * 8 - * Nbits/sym = Mbps * 4 = mac_rate * 2 - */ - nsyms = CEIL((length * 8), (mac_rate * 2)); - - /* usec = symbols * usec/symbol */ - usec = (u16) (nsyms * APHY_SYMBOL_TIME); - return usec; - } else { - switch (mac_rate) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - break; - default: - WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", - wlc->pub->unit, rspec); - ASSERT((const char *)"Bad phy_rate" == NULL); - break; - } - } - - return usec; -} - -void BCMFASTPATH +void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) { if (IS_MCS(rspec)) { @@ -5384,7 +4846,7 @@ wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) } else if (IS_OFDM(rspec)) { wlc_compute_ofdm_plcp(rspec, length, plcp); } else { - wlc_compute_cck_plcp(rspec, length, plcp); + wlc_compute_cck_plcp(wlc, rspec, length, plcp); } return; } @@ -5393,7 +4855,6 @@ wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) { u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); - ASSERT(IS_MCS(rspec)); plcp[0] = mcs; if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) plcp[0] |= MIMO_PLCP_40MHZ; @@ -5405,19 +4866,15 @@ static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void BCMFASTPATH +static void wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) { u8 rate_signal; u32 tmp = 0; int rate = RSPEC2RATE(rspec); - ASSERT(IS_OFDM(rspec)); - /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ - rate_signal = rate_info[rate] & RATE_MASK; - ASSERT(rate_signal != 0); - + rate_signal = rate_info[rate] & WLC_RATE_MASK; memset(plcp, 0, D11_PHY_HDR_LEN); D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); @@ -5436,7 +4893,8 @@ wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) * Broken out for PRQ. */ -static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) +static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length, + u8 *plcp) { u16 usec = 0; u8 le = 0; @@ -5463,7 +4921,8 @@ static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) break; default: - WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); + wiphy_err(wlc->wiphy, "wlc_cck_plcp_set: unsupported rate %d" + "\n", rate_500); rate_500 = WLC_RATE_1M; usec = length << 3; break; @@ -5481,13 +4940,12 @@ static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) +static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec, + uint length, u8 *plcp) { int rate = RSPEC2RATE(rspec); - ASSERT(IS_CCK(rspec)); - - wlc_cck_plcp_set(rate, length, plcp); + wlc_cck_plcp_set(wlc, rate, length, plcp); } /* wlc_compute_frame_dur() @@ -5500,7 +4958,7 @@ static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) * next_frag_len next MPDU length in bytes * preamble_type use short/GF or long/MM PLCP header */ -static u16 BCMFASTPATH +static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len) { @@ -5534,7 +4992,7 @@ wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, * rate next MPDU rate in unit of 500kbps * frame_len next MPDU frame length in bytes */ -u16 BCMFASTPATH +u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, ratespec_t frame_rate, u8 rts_preamble_type, u8 frame_preamble_type, uint frame_len, bool ba) @@ -5566,33 +5024,7 @@ wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, return dur; } -static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) -{ - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - if (mcs < 8) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - } else if ((mcs >= 8) && (mcs <= 23)) { - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); - } else if (mcs == 32) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); - } - } else if (IS_OFDM(rspec)) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); - } else { - ASSERT(IS_CCK(rspec)); - - ASSERT((bw == PHY_TXC1_BW_20MHZ) - || (bw == PHY_TXC1_BW_20MHZ_UP)); - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); - } - - return true; -} - -u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) +u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) { u16 phyctl1 = 0; u16 bw; @@ -5603,12 +5035,10 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) bw = RSPEC_GET_BW(rspec); /* 10Mhz is not supported yet */ if (bw < PHY_TXC1_BW_20MHZ) { - WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", - bw); + wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: bw %d is " + "not supported yet, set to 20L\n", bw); bw = PHY_TXC1_BW_20MHZ; } - - wlc_phy_rspec_check(wlc, bw, rspec); } if (IS_MCS(rspec)) { @@ -5629,8 +5059,8 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) /* get the phyctl byte from rate phycfg table */ phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); if (phycfg == -1) { - WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); - ASSERT(0); + wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: wrong " + "legacy OFDM/CCK rate\n"); phycfg = 0; } /* set the upper byte of phyctl1 */ @@ -5638,18 +5068,10 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) (bw | (phycfg << 8) | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); } - -#ifdef BCMDBG - /* phy clock must support 40Mhz if tx descriptor uses it */ - if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { - ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); - ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); - } -#endif /* BCMDBG */ return phyctl1; } -ratespec_t BCMFASTPATH +ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, u16 mimo_ctlchbw) { @@ -5705,7 +5127,7 @@ wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) * */ -static u16 BCMFASTPATH +static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, @@ -5744,14 +5166,12 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, u16 mimo_txbw; u8 mimo_preamble_type; - ASSERT(queue < NFIFO); - /* locate 802.11 MAC header */ h = (struct ieee80211_hdr *)(p->data); qos = ieee80211_is_data_qos(h->frame_control); /* compute length of frame in bytes for use in PLCP computations */ - len = pkttotlen(p); + len = bcm_pkttotlen(p); phylen = len + FCS_LEN; /* If WEP enabled, add room in phylen for the additional bytes of @@ -5765,7 +5185,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* Get tx_info */ tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info); /* add PLCP */ plcp = skb_push(p, D11_PHY_HDR_LEN); @@ -5777,10 +5196,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* setup frameid */ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { /* non-AP STA should never use BCMC queue */ - ASSERT(queue != TX_BCMC_FIFO); if (queue == TX_BCMC_FIFO) { - WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", - WLCWLUNIT(wlc), __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " + "TX_BCMC!\n", WLCWLUNIT(wlc), __func__); frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ @@ -5803,13 +5221,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control)) mcl |= TXC_IGNOREPMQ; - ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); - ASSERT(hw->max_rates == 2); - txrate[0] = tx_info->control.rates; txrate[1] = txrate[0] + 1; - ASSERT(txrate[0]->idx >= 0); /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ if (txrate[1]->idx < 0) { txrate[1] = txrate[0]; @@ -5819,7 +5233,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, is_mcs[k] = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; if (!is_mcs[k]) { - ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); if ((txrate[k]->idx >= 0) && (txrate[k]->idx < hw->wiphy->bands[tx_info->band]->n_bitrates)) { @@ -5831,10 +5244,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? true : false; } else { - ASSERT((txrate[k]->idx >= 0) && - (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]-> - n_bitrates)); rate_val[k] = WLC_RATE_1M; } } else { @@ -5857,7 +5266,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* (1) RATE: determine and validate primary rate and fallback rates */ if (!RSPEC_ACTIVE(rspec[k])) { - ASSERT(RSPEC_ACTIVE(rspec[k])); rspec[k] = WLC_RATE_1M; } else { if (!is_multicast_ether_addr(h->addr1)) { @@ -5885,7 +5293,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, && WLC_STF_SS_STBC_TX(wlc, scb)) { u8 stc; - ASSERT(WLC_STBC_CAP_PHY(wlc)); stc = 1; /* Nss for single stream is always 1 */ rspec[k] |= (PHY_TXC1_MODE_STBC << @@ -5918,7 +5325,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (wlc->ofdm_40txbw != AUTO) mimo_txbw = wlc->ofdm_40txbw; } else { - ASSERT(IS_CCK(rspec[k])); if (wlc->cck_40txbw != AUTO) mimo_txbw = wlc->cck_40txbw; } @@ -5957,9 +5363,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) && (!IS_MCS(rspec[k]))) { - WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", - WLCWLUNIT(wlc), __func__); - ASSERT(0 && "Rate mismatch"); + wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" + "RC_MCS != IS_MCS(rspec)\n", + WLCWLUNIT(wlc), __func__); } if (IS_MCS(rspec[k])) { @@ -5973,22 +5379,15 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } } - /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ - ASSERT(VALID_RATE_DBG(wlc, rspec[0])); - /* should be better conditionalized */ if (!IS_MCS(rspec[0]) && (tx_info->control.rates[0]. flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) preamble_type[k] = WLC_SHORT_PREAMBLE; - - ASSERT(!IS_MCS(rspec[0]) - || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); } } else { for (k = 0; k < hw->max_rates; k++) { /* Set ctrlchbw as 20Mhz */ - ASSERT(!IS_MCS(rspec[k])); rspec[k] &= ~RSPEC_BW_MASK; rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); @@ -6080,8 +5479,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* Set fallback rate preamble type */ if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || (preamble_type[1] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || - (!IS_MCS(rspec[1]))); if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) mch |= TXC_PREAMBLE_DATA_FB_SHORT; } @@ -6146,7 +5543,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* RTS PLCP header */ - ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); rts_plcp = txh->RTSPhyHeader; if (use_cts) rts_phylen = DOT11_CTS_LEN + FCS_LEN; @@ -6229,11 +5625,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, phyctl = FRAMETYPE(rspec[0], wlc->mimoft); if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || (preamble_type[0] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) - || !IS_MCS(rspec[0])); if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) phyctl |= PHY_TXC_SHORT_HDR; - wlc->pub->_cnt->txprshort++; } /* phytxant is properly bit shifted */ @@ -6274,21 +5667,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } } - if (IS_MCS(rspec[0])) - ASSERT(IS_MCS(rspec[1])); - - ASSERT(!IS_MCS(rspec[0]) || - ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); - ASSERT(!IS_MCS(rspec[1]) || - ((preamble_type[1] == WLC_MM_PREAMBLE) == - (txh->MModeFbrLen != 0))); - ac = skb_get_queue_mapping(p); if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { uint frag_dur, dur, dur_fallback; - ASSERT(!is_multicast_ether_addr(h->addr1)); - /* WME: Update TXOP threshold */ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { frag_dur = @@ -6359,16 +5741,18 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } } } else - WL_ERROR("wl%d: %s txop invalid for rate %d\n", - wlc->pub->unit, fifo_names[queue], - RSPEC2RATE(rspec[0])); + wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " + "for rate %d\n", + wlc->pub->unit, fifo_names[queue], + RSPEC2RATE(rspec[0])); if (dur > wlc->edcf_txop[ac]) - WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", - wlc->pub->unit, __func__, - fifo_names[queue], - phylen, wlc->fragthresh[queue], - dur, wlc->edcf_txop[ac]); + wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " + "exceeded phylen %d/%d dur %d/%d\n", + wlc->pub->unit, __func__, + fifo_names[queue], + phylen, wlc->fragthresh[queue], + dur, wlc->edcf_txop[ac]); } } @@ -6379,8 +5763,6 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) { struct wlc_bsscfg *cfg = wlc->cfg; - wlc->pub->_cnt->tbtt++; - if (BSSCFG_STA(cfg)) { /* run watchdog here if the watchdog timer is not armed */ if (WLC_WATCHDOG_TBTT(wlc)) { @@ -6410,127 +5792,6 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) } } -/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ -void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) -{ - W_REG(&wlc->regs->gptimer, us); -} - -void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) -{ - W_REG(&wlc->regs->gptimer, 0); -} - -static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) -{ - /* when interrupt is generated, the counter is loaded with last value - * written and continue to decrement. So it has to be cleaned first - */ - W_REG(&wlc->regs->gptimer, 0); -} - -/* - * This fn has all the high level dpc processing from wlc_dpc. - * POLICY: no macinstatus change, no bounding loop. - * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint - */ -void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) -{ - d11regs_t *regs = wlc->regs; -#ifdef BCMDBG - char flagstr[128]; - static const bcm_bit_desc_t int_flags[] = { - {MI_MACSSPNDD, "MACSSPNDD"}, - {MI_BCNTPL, "BCNTPL"}, - {MI_TBTT, "TBTT"}, - {MI_BCNSUCCESS, "BCNSUCCESS"}, - {MI_BCNCANCLD, "BCNCANCLD"}, - {MI_ATIMWINEND, "ATIMWINEND"}, - {MI_PMQ, "PMQ"}, - {MI_NSPECGEN_0, "NSPECGEN_0"}, - {MI_NSPECGEN_1, "NSPECGEN_1"}, - {MI_MACTXERR, "MACTXERR"}, - {MI_NSPECGEN_3, "NSPECGEN_3"}, - {MI_PHYTXERR, "PHYTXERR"}, - {MI_PME, "PME"}, - {MI_GP0, "GP0"}, - {MI_GP1, "GP1"}, - {MI_DMAINT, "DMAINT"}, - {MI_TXSTOP, "TXSTOP"}, - {MI_CCA, "CCA"}, - {MI_BG_NOISE, "BG_NOISE"}, - {MI_DTIM_TBTT, "DTIM_TBTT"}, - {MI_PRQ, "PRQ"}, - {MI_PWRUP, "PWRUP"}, - {MI_RFDISABLE, "RFDISABLE"}, - {MI_TFS, "TFS"}, - {MI_PHYCHANGED, "PHYCHANGED"}, - {MI_TO, "TO"}, - {0, NULL} - }; - - if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { - bcm_format_flags(int_flags, macintstatus, flagstr, - sizeof(flagstr)); - WL_TRACE("wl%d: macintstatus 0x%x %s\n", - wlc->pub->unit, macintstatus, flagstr); - } -#endif /* BCMDBG */ - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* TBTT indication */ - /* ucode only gives either TBTT or DTIM_TBTT, not both */ - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc->pub->unit, wlc->pub->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc->pub->sih->chip, - wlc->pub->sih->chiprev); - - wlc->pub->_cnt->psmwds++; - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - wlc_hwtimer_gptimer_cb(wlc); - } - - if (macintstatus & MI_RFDISABLE) { - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc->pub->unit, - R_REG(®s->phydebug) & PDBG_RFD); - /* delay the cleanup to wl_down in IBSS case */ - if ((R_REG(®s->phydebug) & PDBG_RFD)) { - int idx; - struct wlc_bsscfg *bsscfg; - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) || !bsscfg->enable - || !bsscfg->BSS) - continue; - WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", - wlc->pub->unit); - } - } - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); -} - static void wlc_war16165(struct wlc_info *wlc, bool tx) { if (tx) { @@ -6546,7 +5807,7 @@ static void wlc_war16165(struct wlc_info *wlc, bool tx) /* process an individual tx_status_t */ /* WLC_HIGH_API */ -bool BCMFASTPATH +bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) { struct sk_buff *p; @@ -6572,16 +5833,12 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { - WLCNTADD(wlc->pub->_cnt->txnoack, - ((txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT)); - WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); + wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", + __func__); return false; } queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < NFIFO); if (queue >= NFIFO) { p = NULL; goto fatal; @@ -6598,41 +5855,31 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) if (txs->phyerr) { if (WL_ERROR_ON()) { - WL_ERROR("phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); + wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); wlc_print_txdesc(txh); } wlc_print_txstatus(txs); } - ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID)); if (txs->frameid != cpu_to_le16(txh->TxFrameID)) goto fatal; - tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); if (tx_info->control.sta) scb = (struct scb *)tx_info->control.sta->drv_priv; - if (N_ENAB(wlc->pub)) { - u8 *plcp = (u8 *) (txh + 1); - if (PLCP3_ISSGI(plcp[3])) - wlc->pub->_cnt->txmpdu_sgi++; - if (PLCP3_ISSTBC(plcp[3])) - wlc->pub->_cnt->txmpdu_stbc++; - } - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); return false; } supr_status = txs->status & TX_STATUS_SUPR_MASK; if (supr_status == TX_STATUS_SUPR_BADCH) - WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", - __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + BCMMSG(wlc->wiphy, + "%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS; tx_frame_count = @@ -6643,7 +5890,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) lastframe = !ieee80211_has_morefrags(h->frame_control); if (!lastframe) { - WL_ERROR("Not last frame!\n"); + wiphy_err(wlc->wiphy, "Not last frame!\n"); } else { u16 sfbl, lfbl; ieee80211_tx_info_clear_status(tx_info); @@ -6679,7 +5926,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info->flags |= IEEE80211_TX_STAT_ACK; } - totlen = pkttotlen(p); + totlen = bcm_pkttotlen(p); free_pdu = true; wlc_txfifo_complete(wlc, queue, 1); @@ -6692,33 +5939,30 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); - wlc->pub->_cnt->ieee_tx_status++; } else { - WL_ERROR("%s: Not last frame => not calling tx_status\n", - __func__); + wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " + "tx_status\n", __func__); } return false; fatal: - ASSERT(0); if (p) - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); return true; } -void BCMFASTPATH +void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) { TXPKTPENDDEC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); + BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, + TXPKTPENDGET(wlc, fifo)); /* There is more room; mark precedences related to this FIFO sendable */ WLC_TX_FIFO_ENAB(wlc, fifo); - ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); if (!TXPKTPENDTOT(wlc)) { if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) @@ -6735,84 +5979,6 @@ wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) /* figure out which bsscfg is being worked on... */ } -/* Given the beacon interval in kus, and a 64 bit TSF in us, - * return the offset (in us) of the TSF from the last TBTT - */ -u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) -{ - u32 k, btklo, btkhi, offset; - - /* TBTT is always an even multiple of the beacon_interval, - * so the TBTT less than or equal to the beacon timestamp is - * the beacon timestamp minus the beacon timestamp modulo - * the beacon interval. - * - * TBTT = BT - (BT % BIu) - * = (BTk - (BTk % BP)) * 2^10 - * - * BT = beacon timestamp (usec, 64bits) - * BTk = beacon timestamp (Kusec, 54bits) - * BP = beacon interval (Kusec, 16bits) - * BIu = BP * 2^10 = beacon interval (usec, 26bits) - * - * To keep the calculations in u32s, the modulo operation - * on the high part of BT needs to be done in parts using the - * relations: - * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z - * and - * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z - * - * So, if BTk[n] = u16 n [0,3] of BTk. - * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP - * and the SUM term can be broken down: - * (BTk[n] * 2^16n) % BP - * (BTk[n] * (2^16n % BP)) % BP - * - * Create a set of power of 2 mod BP constants: - * K[n] = 2^(16n) % BP - * = (K[n-1] * 2^16) % BP - * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP - * - * BTk % BP = BTk[0-1] % BP + - * (BTk[2] * K[2]) % BP + - * (BTk[3] * K[3]) % BP - * - * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 - */ - - /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ - btklo = (tsf_h << 22) | (tsf_l >> 10); - btkhi = tsf_h >> 10; - - /* offset = BTk % BP */ - offset = btklo % bp; - - /* K[2] = ((2^16 % BP) * 2^16) % BP */ - k = (u32) (1 << 16) % bp; - k = (u32) (k * 1 << 16) % (u32) bp; - - /* offset += (BTk[2] * K[2]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - /* BTk[3] */ - btkhi = btkhi >> 16; - - /* k[3] = (K[2] * 2^16) % BP */ - k = (k << 16) % bp; - - /* offset += (BTk[3] * K[3]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - offset = offset % bp; - - /* convert offset from kus to us by shifting up 10 bits and - * add in the low 10 bits of tsf that we ignored - */ - offset = (offset << 10) + (tsf_l & 0x3FF); - - return offset; -} - /* Update beacon listen interval in shared memory */ void wlc_bcn_li_upd(struct wlc_info *wlc) { @@ -6827,25 +5993,56 @@ void wlc_bcn_li_upd(struct wlc_info *wlc) (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); } +/* + * recover 64bit TSF value from the 16bit TSF value in the rx header + * given the assumption that the TSF passed in header is within 65ms + * of the current tsf. + * + * 6 5 4 4 3 2 1 + * 3.......6.......8.......0.......2.......4.......6.......8......0 + * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->| + * + * The RxTSFTime are the lowest 16 bits and provided by the ucode. The + * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the + * receive call sequence after rx interrupt. Only the higher 16 bits + * are used. Finally, the tsf_h is read from the tsf register. + */ +static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh) +{ + u32 tsf_h, tsf_l; + u16 rx_tsf_0_15, rx_tsf_16_31; + + wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h); + + rx_tsf_16_31 = (u16)(tsf_l >> 16); + rx_tsf_0_15 = rxh->rxhdr.RxTSFTime; + + /* + * a greater tsf time indicates the low 16 bits of + * tsf_l wrapped, so decrement the high 16 bits. + */ + if ((u16)tsf_l < rx_tsf_0_15) { + rx_tsf_16_31 -= 1; + if (rx_tsf_16_31 == 0xffff) + tsf_h -= 1; + } + + return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15); +} + static void prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, struct ieee80211_rx_status *rx_status) { - u32 tsf_l, tsf_h; wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; int preamble; int channel; ratespec_t rspec; unsigned char *plcp; -#if 0 - /* Clearly, this is bogus -- reading the TSF now is wrong */ - wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ - rx_status->mactime = tsf_h; - rx_status->mactime <<= 32; - rx_status->mactime |= tsf_l; - rx_status->flag |= RX_FLAG_MACTIME_MPDU; /* clearly wrong */ -#endif + /* fill in TSF and flag its presence */ + rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh); + rx_status->flag |= RX_FLAG_MACTIME_MPDU; channel = WLC_CHAN_CHANNEL(rxh->RxChan); @@ -6912,7 +6109,7 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, rx_status->rate_idx = 11; break; default: - WL_ERROR("%s: Unknown rate\n", __func__); + wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); } /* Determine short preamble and rate_idx */ @@ -6923,7 +6120,8 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, } else if (IS_OFDM(rspec)) { rx_status->flag |= RX_FLAG_SHORTPRE; } else { - WL_ERROR("%s: Unknown modulation\n", __func__); + wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", + __func__); } } @@ -6932,11 +6130,13 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, if (rxh->RxStatus1 & RXS_DECERR) { rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", + __func__); } if (rxh->RxStatus1 & RXS_FCSERR) { rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", + __func__); } } @@ -6945,14 +6145,6 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) { int len_mpdu; struct ieee80211_rx_status rx_status; -#if defined(BCMDBG) - struct sk_buff *skb = p; -#endif /* BCMDBG */ - /* Todo: - * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. - * Test for INTERMEDIATE like so: - * if (!(plcp[0] | plcp[1] | plcp[2])) - */ memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -6962,48 +6154,25 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); - ASSERT(!(p->next)); - ASSERT(!(p->prev)); - - ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); - - wlc->pub->_cnt->ieee_rx++; return; } -void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list) -{ - uint index; - - if (!bss_list) { - WL_ERROR("%s: Attempting to free NULL list\n", __func__); - return; - } - /* inspect all BSS descriptor */ - for (index = 0; index < bss_list->count; index++) { - kfree(bss_list->ptrs[index]); - bss_list->ptrs[index] = NULL; - } - bss_list->count = 0; -} - /* Process received frames */ /* * Return true if more frames need to be processed. false otherwise. * Param 'bound' indicates max. # frames to process before break out. */ /* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) +void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) { d11rxhdr_t *rxh; struct ieee80211_hdr *h; uint len; bool is_amsdu; - WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* frame starts with rxhdr */ rxh = (d11rxhdr_t *) (p->data); @@ -7027,9 +6196,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { - wlc->pub->_cnt->rxrunt++; - WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); + wiphy_err(wlc->wiphy, "wl%d: wlc_recv: rcvd runt of " + "len %d\n", wlc->pub->unit, p->len); goto toss; } skb_pull(p, 2); @@ -7040,17 +6208,17 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (rxh->RxStatus1 & RXS_FCSERR) { if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { - WL_ERROR("FCSERR while scanning******* - tossing\n"); + wiphy_err(wlc->wiphy, "FCSERR while scanning******* -" + " tossing\n"); goto toss; } else { - WL_ERROR("RCSERR!!!\n"); + wiphy_err(wlc->wiphy, "RCSERR!!!\n"); goto toss; } } /* check received pkt has at least frame control field */ if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - wlc->pub->_cnt->rxrunt++; goto toss; } @@ -7064,13 +6232,12 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) ieee80211_is_mgmt(h->frame_control)) { if ((is_zero_ether_addr(h->addr2) || is_multicast_ether_addr(h->addr2))) { - WL_ERROR("wl%d: %s: dropping a frame with " - "invalid src mac address, a2: %pM\n", + wiphy_err(wlc->wiphy, "wl%d: %s: dropping a " + "frame with invalid src mac address," + " a2: %pM\n", wlc->pub->unit, __func__, h->addr2); - wlc->pub->_cnt->rxbadsrcmac++; goto toss; } - wlc->pub->_cnt->rxfrag++; } } @@ -7085,7 +6252,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) return; toss: - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return @@ -7094,12 +6261,12 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) * Formula given by HT PHY Spec v 1.13 * len = 3(nsyms + nstream + 3) - 3 */ -u16 BCMFASTPATH +u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) { uint nsyms, len = 0, kNdps; - WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", + BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n", wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); if (IS_MCS(ratespec)) { @@ -7107,7 +6274,6 @@ wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) /* MCS_TXS(mcs) returns num tx streams - 1 */ int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); /* the payload duration calculation matches that of regular ofdm */ /* 1000Ndbps = kbps * 4 */ kNdps = @@ -7135,7 +6301,7 @@ wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) } /* calculate frame duration of a given rate and length, return time in usec unit */ -uint BCMFASTPATH +uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint mac_len) { @@ -7143,19 +6309,17 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint rate = RSPEC2RATE(ratespec); if (rate == 0) { - ASSERT(0); - WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", + wlc->pub->unit); rate = WLC_RATE_1M; } - WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", wlc->pub->unit, ratespec, preamble_type, mac_len); if (IS_MCS(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); if (preamble_type == WLC_MM_PREAMBLE) @@ -7213,13 +6377,12 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint nsyms, mac_len, Ndps, kNdps; uint rate = RSPEC2RATE(ratespec); - WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n", wlc->pub->unit, ratespec, preamble_type, dur); if (IS_MCS(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); /* payload calculation matches that of regular ofdm */ if (BAND_2G(wlc->band->bandtype)) @@ -7256,33 +6419,29 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { - WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " + "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ return wlc_calc_frame_time(wlc, rspec, preamble_type, (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + FCS_LEN)); } -static uint BCMFASTPATH +static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { uint dur = 0; - WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ dur = wlc_calc_frame_time(wlc, rspec, preamble_type, @@ -7293,8 +6452,8 @@ wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { - WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); + BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); return wlc_calc_ack_time(wlc, rspec, preamble_type); } @@ -7320,11 +6479,12 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) continue; /* mask off basic bit */ - rate = (rateset->rates[i] & RATE_MASK); + rate = (rateset->rates[i] & WLC_RATE_MASK); if (rate > WLC_MAXRATE) { - WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", - rateset->rates[i]); + wiphy_err(wlc->wiphy, "wlc_rate_lookup_init: invalid " + "rate 0x%X in rate set\n", + rateset->rates[i]); continue; } @@ -7347,7 +6507,6 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) for (i = 0; i < wlc->band->hw_rateset.count; i++) { rate = wlc->band->hw_rateset.rates[i]; - ASSERT(rate <= WLC_MAXRATE); if (br[rate] != 0) { /* This rate is a basic rate. @@ -7406,8 +6565,8 @@ static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) * for a given rate, the LS-nibble of the PLCP SIGNAL field is * the index into the rate table. */ - phy_rate = rate_info[rate] & RATE_MASK; - basic_phy_rate = rate_info[basic_rate] & RATE_MASK; + phy_rate = rate_info[rate] & WLC_RATE_MASK; + basic_phy_rate = rate_info[basic_rate] & WLC_RATE_MASK; index = phy_rate & 0xf; basic_index = basic_phy_rate & 0xf; @@ -7447,14 +6606,13 @@ void wlc_set_ratetable(struct wlc_info *wlc) uint i; rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); wlc_rateset_copy(rs_dflt, &rs); wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); /* walk the phy rate table and update SHM basic rate lookup table */ for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; + rate = rs.rates[i] & WLC_RATE_MASK; /* for a given rate WLC_BASIC_RATE returns the rate at * which a response ACK/CTS should be sent. @@ -7464,7 +6622,7 @@ void wlc_set_ratetable(struct wlc_info *wlc) /* This should only happen if we are using a * restricted rateset. */ - basic_rate = rs.rates[0] & RATE_MASK; + basic_rate = rs.rates[0] & WLC_RATE_MASK; } wlc_write_rate_shm(wlc, rate, basic_rate); @@ -7503,8 +6661,8 @@ bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, return true; error: if (verbose) { - WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", - wlc->pub->unit, rspec); + wiphy_err(wlc->wiphy, "wl%d: wlc_valid_rate: rate spec 0x%x " + "not in hw_rateset\n", wlc->pub->unit, rspec); } return false; @@ -7526,7 +6684,6 @@ static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) else band->mimo_cap_40 = false; } else { - ASSERT(band->bandtype == WLC_BAND_2G); if (bwcap == WLC_N_BW_40ALL) band->mimo_cap_40 = true; else @@ -7550,14 +6707,13 @@ void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) sifs = SIFS(wlc->band); rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); wlc_rateset_copy(rs_dflt, &rs); wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); /* walk the phy rate table and update MAC core SHM basic rate table entries */ for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; + rate = rs.rates[i] & WLC_RATE_MASK; entry_ptr = wlc_rate_shm_offset(wlc, rate); @@ -7579,41 +6735,6 @@ void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) } } -u16 -wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay) -{ - uint bcntsfoff = 0; - - if (IS_MCS(rspec)) { - WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", - wlc->pub->unit, rspec); - } else if (IS_OFDM(rspec)) { - /* tx delay from MAC through phy to air (2.1 usec) + - * phy header time (preamble + PLCP SIGNAL == 20 usec) + - * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 - * bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; - bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; - bcntsfoff += - wlc_compute_airtime(wlc, rspec, - APHY_SERVICE_NBITS / 8 + - DOT11_MAC_HDR_LEN); - } else { - /* tx delay from MAC through phy to air (3.4 usec) + - * phy header time (long preamble + PLCP == 192 usec) + - * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; - bcntsfoff += - short_preamble ? D11B_PHY_SPREHDR_TIME : - D11B_PHY_LPREHDR_TIME; - bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); - } - return (u16) (bcntsfoff); -} - /* Max buffering needed for beacon template/prb resp template is 142 bytes. * * PLCP header is 6 bytes. @@ -7635,10 +6756,6 @@ wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, struct ieee80211_mgmt *h; int hdr_len, body_len; - ASSERT(*len >= 142); - ASSERT(type == IEEE80211_STYPE_BEACON || - type == IEEE80211_STYPE_PROBE_RESP); - if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) hdr_len = DOT11_MAC_HDR_LEN; else @@ -7730,12 +6847,6 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg) wlc->bcn_rspec = wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); - ASSERT(wlc_valid_rate - (wlc, wlc->bcn_rspec, - CHSPEC_IS2G(cfg->current_bss-> - chanspec) ? WLC_BAND_2G : WLC_BAND_5G, - true)); - /* update the template and ucode shm */ wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, wlc->bcn_rspec, cfg, bcn, &len); @@ -7825,7 +6936,7 @@ wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg, if (suspend) wlc_enable_mac(wlc); } else { /* Generating probe resp in sw; update local template */ - ASSERT(0 && "No software probe response support without MBSS"); + /* error: No software probe response support without MBSS */ } } @@ -7837,11 +6948,8 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) struct ieee80211_hdr *h; struct scb *scb; - ASSERT(pdu); txh = (d11txh_t *) (pdu->data); - ASSERT(txh); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - ASSERT(h); /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; @@ -7854,12 +6962,8 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { /* Mark precedences related to this FIFO, unsendable */ WLC_TX_FIFO_CLEAR(wlc, fifo); - return BCME_BUSY; + return -EBUSY; } - - if (!ieee80211_is_data(txh->MacFrameControl)) - wlc->pub->_cnt->txctl++; - return 0; } @@ -7889,7 +6993,7 @@ int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; if (len < WL_REV_INFO_LEGACY_LENGTH) - return BCME_BUFTOOSHORT; + return -EOVERFLOW; rinfo->vendorid = wlc->vendorid; rinfo->deviceid = wlc->deviceid; @@ -7915,13 +7019,13 @@ int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) rinfo->chippkg = wlc->pub->sih->chippkg; } - return BCME_OK; + return 0; } void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) { wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), CHSPEC_WLC_BW(wlc->default_bss->chanspec), wlc->stf->txstreams); } @@ -7943,8 +7047,6 @@ static void wlc_bss_default_init(struct wlc_info *wlc) * starting from the 2G channels */ chanspec = CH20MHZ_CHSPEC(1); - ASSERT(chanspec != INVCHANSPEC); - wlc->home_chanspec = bi->chanspec = chanspec; /* find the band of our default channel */ @@ -7954,24 +7056,13 @@ static void wlc_bss_default_init(struct wlc_info *wlc) /* init bss rates to the band specific default rate set */ wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); if (N_ENAB(wlc->pub)) bi->flags |= WLC_BSS_HT; } -void -wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) -{ - if (b_low > *a_low) { - /* low half needs a carry */ - b_high += 1; - } - *a_low -= b_low; - *a_high -= b_high; -} - static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, u32 int_val) @@ -7993,9 +7084,9 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if (N_ENAB(wlc->pub) && ismcs) { /* mcs only allowed when nmode */ if (stf > PHY_TXC1_MODE_SDM) { - WL_ERROR("wl%d: %s: Invalid stf\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; goto done; } @@ -8004,17 +7095,18 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if (!CHSPEC_IS40(wlc->home_chanspec) || ((stf != PHY_TXC1_MODE_SISO) && (stf != PHY_TXC1_MODE_CDD))) { - WL_ERROR("wl%d: %s: Invalid mcs 32\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " + "32\n", WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } /* mcs > 7 must use stf SDM */ } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { /* mcs > 7 must use stf SDM */ if (stf != PHY_TXC1_MODE_SDM) { - WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", - WLCWLUNIT(wlc), __func__, rate); + BCMMSG(wlc->wiphy, "wl%d: enabling " + "SDM mode for mcs %d\n", + WLCWLUNIT(wlc), rate); stf = PHY_TXC1_MODE_SDM; } } else { @@ -8022,38 +7114,38 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if ((stf > PHY_TXC1_MODE_STBC) || (!WLC_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { - WL_ERROR("wl%d: %s: Invalid STBC\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" + "\n", WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } } } else if (IS_OFDM(rate)) { if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid OFDM\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", + WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } } else if (IS_CCK(rate)) { if ((cur_band->bandtype != WLC_BAND_2G) || (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid CCK\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", + WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } } else { - WL_ERROR("wl%d: %s: Unknown rate type\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", + WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } /* make sure multiple antennae are available for non-siso rates */ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " + "request\n", WLCWLUNIT(wlc), __func__); + bcmerror = -EINVAL; goto done; } @@ -8082,8 +7174,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, } return rspec; - done: - WL_ERROR("Hoark\n"); +done: return rate; } @@ -8097,8 +7188,9 @@ wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : M_TX_IDLE_BUSY_RATIO_X_16_CCK; if (duty_cycle > 100 || duty_cycle < 0) { - WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); - return BCME_RANGE; + wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", + wlc->pub->unit); + return -EINVAL; } if (duty_cycle) idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; @@ -8111,7 +7203,7 @@ wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, else wlc->tx_duty_cycle_cck = (u16) duty_cycle; - return BCME_OK; + return 0; } /* Read a single u16 from shared memory. @@ -8130,22 +7222,6 @@ void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) wlc_bmac_write_shm(wlc->hw, offset, v); } -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Range length 'len' must be an even number of bytes - */ -void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_set_shm(wlc->hw, offset, v, len); -} - /* Copy a buffer to shared memory. * SHM 'offset' needs to be an even address and * Buffer length 'len' must be an even number of bytes @@ -8153,29 +7229,11 @@ void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) { /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) + if (len <= 0 || (offset & 1) || (len & 1)) return; - wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); - -} -/* Copy from shared memory to a buffer. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; + wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); - wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); } /* wrapper BMAC functions to for HIGH driver access */ @@ -8184,21 +7242,11 @@ void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) wlc_bmac_mctrl(wlc->hw, mask, val); } -void wlc_corereset(struct wlc_info *wlc, u32 flags) -{ - wlc_bmac_corereset(wlc->hw, flags); -} - void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) { wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); } -u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) -{ - return wlc_bmac_mhf_get(wlc->hw, idx, bands); -} - int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) { return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); @@ -8225,16 +7273,6 @@ wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); } -void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) -{ - wlc_bmac_set_rcmta(wlc->hw, idx, addr); -} - -void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) -{ - wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); -} - void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) { wlc->band->CWmin = newmin; @@ -8247,12 +7285,6 @@ void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) wlc_bmac_set_cwmax(wlc->hw, newmax); } -void wlc_fifoerrors(struct wlc_info *wlc) -{ - - wlc_bmac_fifoerrors(wlc->hw); -} - /* Search mem rw utilities */ void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) @@ -8264,17 +7296,6 @@ void wlc_reset_bmac_done(struct wlc_info *wlc) { } -void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) -{ - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS; - wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - /* check for the particular priority flow control bit being set */ bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, @@ -8285,7 +7306,6 @@ wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, if (prio == ALLPRIO) { prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); prio_mask = NBITVAL(prio); } @@ -8299,12 +7319,11 @@ void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, uint prio_bits; uint cur_bits; - WL_TRACE("%s: flow control kicks in\n", __func__); + BCMMSG(wlc->wiphy, "flow control kicks in\n"); if (prio == ALLPRIO) { prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); prio_bits = NBITVAL(prio); } @@ -8341,9 +7360,6 @@ wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, { uint prev_override; - ASSERT(override != 0); - ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); - prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); /* Update the flow control bits and do an early return if there is @@ -8411,7 +7427,7 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) { struct wlc_txq_info *qi, *p; - qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info)); + qi = kzalloc(sizeof(struct wlc_txq_info), GFP_ATOMIC); if (qi != NULL) { /* * Have enough room for control packets along with HI watermark @@ -8419,7 +7435,7 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) * leave PS mode. The watermark for flowcontrol to OS packets * will remain the same */ - pktq_init(&qi->q, WLC_PREC_COUNT, + bcm_pktq_init(&qi->q, WLC_PREC_COUNT, (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + wlc->pub->psq_pkts_total); @@ -8450,7 +7466,6 @@ static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi) else { while (p != NULL && p->next != qi) p = p->next; - ASSERT(p->next == qi); if (p != NULL) p->next = p->next->next; } @@ -8494,3 +7509,21 @@ void wlc_inval_dma_pkts(struct wlc_hw_info *hw, dma_walk_packets(dmah, dma_callback_fn, sta); } } + +int wlc_get_curband(struct wlc_info *wlc) +{ + return wlc->band->bandunit; +} + +void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop) +{ + /* flush packet queue when requested */ + if (drop) + bcm_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); + + /* wait for queue and DMA fifos to run dry */ + while (!pktq_empty(&wlc->pkt_queue->q) || + TXPKTPENDTOT(wlc) > 0) { + wl_msleep(wlc->wl, 1); + } +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h index 960f82cbfbc9..fb48dfcb97d5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -98,7 +98,6 @@ struct wlc_bss_list { (cfg)->wsec_portopen : true) #define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) -#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) #define DATA_BLOCK_TX_SUPR (1 << 4) @@ -166,9 +165,6 @@ extern const u8 prio2fifo[]; #define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ #define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ -/* Do we support this rate? */ -#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) - /* * Macros to check if AP or STA is active. * AP Active means more than just configured: driver and BSS are "up"; @@ -196,7 +192,7 @@ extern const u8 prio2fifo[]; ((wlc->hw->clk) ? \ ((R_REG(&wlc->hw->regs->maccontrol) & \ (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ - (si_deviceremoved(wlc->hw->sih))) + (ai_deviceremoved(wlc->hw->sih))) #define WLCWLUNIT(wlc) ((wlc)->pub->unit) @@ -746,9 +742,7 @@ struct wlc_info { u16 next_bsscfg_ID; struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - struct wlc_txq_info *active_queue; /* txq for the currently active - * transmit context - */ + struct wlc_txq_info *pkt_queue; /* txq for transmit packets */ u32 mpc_dur; /* total time (ms) in mpc mode except for the * portion since radio is turned off last time */ @@ -757,6 +751,7 @@ struct wlc_info { */ bool pr80838_war; uint hwrxoff; + struct wiphy *wiphy; }; /* antsel module specific state */ @@ -794,7 +789,6 @@ struct antsel_info { #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) -extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); extern void wlc_fatal_error(struct wlc_info *wlc); extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); @@ -811,21 +805,10 @@ extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, void *buf); extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, bool both); -#if defined(BCMDBG) -extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, - u8 *addr); -#endif -extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, - const u8 *addr); -extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); -extern void wlc_fifoerrors(struct wlc_info *wlc); extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); extern void wlc_reset_bmac_done(struct wlc_info *wlc); -extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); -extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); #if defined(BCMDBG) extern void wlc_print_rxh(d11rxhdr_t *rxh); @@ -860,7 +843,7 @@ extern void wlc_txflowcontrol_override(struct wlc_info *wlc, bool on, uint override); extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi); +extern void wlc_send_q(struct wlc_info *wlc); extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, @@ -883,21 +866,14 @@ extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, struct bcmstrbuf *b); #endif -extern bool wlc_ps_check(struct wlc_info *wlc); extern void wlc_reprate_init(struct wlc_info *wlc); extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg); -extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, - u32 b_low); -extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); /* Shared memory access */ extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); -extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len); -extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, - int len); extern void wlc_update_beacon(struct wlc_info *wlc); extern void wlc_bss_update_beacon(struct wlc_info *wlc, @@ -935,14 +911,13 @@ extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); #endif extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg, u8 mimops_mode); extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); extern void wlc_set_bssid(struct wlc_bsscfg *cfg); -extern void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend); +extern void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend); extern void wlc_set_ratetable(struct wlc_info *wlc); extern int wlc_set_mac(struct wlc_bsscfg *cfg); @@ -951,20 +926,14 @@ extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs); -extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay); extern void wlc_radio_disable(struct wlc_info *wlc); extern void wlc_bcn_li_upd(struct wlc_info *wlc); extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); -extern void wlc_out(struct wlc_info *wlc); extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); extern bool wlc_ps_allowed(struct wlc_info *wlc); extern bool wlc_stay_awake(struct wlc_info *wlc); extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); -extern void wlc_bss_list_free(struct wlc_info *wlc, - struct wlc_bss_list *bss_list); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); #endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 96d36001f460..16fea021f4a5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -29,14 +29,14 @@ #include <bcmdefs.h> #include <bcmutils.h> #include <bcmwifi.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbconfig.h> #include <sbchipc.h> #include <pcicfg.h> #include <sbhnddma.h> #include <hnddma.h> -#include <hndpmu.h> +#include <wlc_pmu.h> #include "wlc_types.h" #include "wl_dbg.h" @@ -68,8 +68,9 @@ wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); if (!physhim) { - WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", - wlc_hw->unit); + wiphy_err(wlc_hw->wlc->wiphy, + "wl%d: wlc_phy_shim_attach: out of mem\n", + wlc_hw->unit); return NULL; } physhim->wlc_hw = wlc_hw; diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c index 59e3ede89fe7..82986bd1ccfa 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Broadcom Corporation + * Copyright (c) 2011 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 @@ -13,280 +13,124 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <linux/delay.h> #include <linux/kernel.h> -#include <linux/string.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <siutils.h> +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/io.h> + #include <bcmdevs.h> -#include <hndsoc.h> #include <sbchipc.h> -#include <hndpmu.h> -#include "siutils_priv.h" - -#define PMU_ERROR(args) - -#ifdef BCMDBG -#define PMU_MSG(args) printk args - -/* debug-only definitions */ -/* #define BCMDBG_FORCEHT */ -/* #define CHIPC_UART_ALWAYS_ON */ -#else -#define PMU_MSG(args) -#endif /* BCMDBG */ +#include <bcmutils.h> +#include <bcmnvram.h> +#include "wlc_pmu.h" -/* To check in verbose debugging messages not intended - * to be on except on private builds. +/* + * d11 slow to fast clock transition time in slow clock cycles */ -#define PMU_NONE(args) - -/* PLL controls/clocks */ -static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal); -static u32 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc); -static u32 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc); +#define D11SCC_SLOW2FAST_TRANSITION 2 -/* PMU resources */ -static bool si_pmu_res_depfltr_bb(si_t *sih); -static bool si_pmu_res_depfltr_ncb(si_t *sih); -static bool si_pmu_res_depfltr_paldo(si_t *sih); -static bool si_pmu_res_depfltr_npaldo(si_t *sih); -static u32 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, bool all); -static uint si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc); -static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax); -static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, - u8 spuravoid); +/* + * external LPO crystal frequency + */ +#define EXT_ILP_HZ 32768 -static void si_pmu_set_4330_plldivs(si_t *sih); +/* + * Duration for ILP clock frequency measurment in milliseconds + * + * remark: 1000 must be an integer multiple of this duration + */ +#define ILP_CALC_DUR 10 -/* FVCO frequency */ +/* + * FVCO frequency + */ #define FVCO_880 880000 /* 880MHz */ #define FVCO_1760 1760000 /* 1760MHz */ #define FVCO_1440 1440000 /* 1440MHz */ #define FVCO_960 960000 /* 960MHz */ -/* Read/write a chipcontrol reg */ -u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, - reg); - return si_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), mask, val); -} - -/* Read/write a regcontrol reg */ -u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, - reg); - return si_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, regcontrol_data), mask, val); -} - -/* Read/write a pllcontrol reg */ -u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, - reg); - return si_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, pllcontrol_data), mask, val); -} - -/* PMU PLL update */ -void si_pmu_pllupd(si_t *sih) -{ - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), - PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); -} - -/* Setup switcher voltage */ -void si_pmu_set_switcher_voltage(si_t *sih, u8 bb_voltage, u8 rf_voltage) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - W_REG(&cc->regcontrol_addr, 0x01); - W_REG(&cc->regcontrol_data, (u32) (bb_voltage & 0x1f) << 22); - - W_REG(&cc->regcontrol_addr, 0x00); - W_REG(&cc->regcontrol_data, (u32) (rf_voltage & 0x1f) << 14); - - /* Return to original core */ - si_setcoreidx(sih, origidx); -} - -void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) -{ - u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; - u8 addr = 0; +/* + * PMU crystal table indices for 1440MHz fvco + */ +#define PMU1_XTALTAB0_1440_12000K 0 +#define PMU1_XTALTAB0_1440_13000K 1 +#define PMU1_XTALTAB0_1440_14400K 2 +#define PMU1_XTALTAB0_1440_15360K 3 +#define PMU1_XTALTAB0_1440_16200K 4 +#define PMU1_XTALTAB0_1440_16800K 5 +#define PMU1_XTALTAB0_1440_19200K 6 +#define PMU1_XTALTAB0_1440_19800K 7 +#define PMU1_XTALTAB0_1440_20000K 8 +#define PMU1_XTALTAB0_1440_25000K 9 +#define PMU1_XTALTAB0_1440_26000K 10 +#define PMU1_XTALTAB0_1440_30000K 11 +#define PMU1_XTALTAB0_1440_37400K 12 +#define PMU1_XTALTAB0_1440_38400K 13 +#define PMU1_XTALTAB0_1440_40000K 14 +#define PMU1_XTALTAB0_1440_48000K 15 - ASSERT(sih->cccaps & CC_CAP_PMU); +/* + * PMU crystal table indices for 960MHz fvco + */ +#define PMU1_XTALTAB0_960_12000K 0 +#define PMU1_XTALTAB0_960_13000K 1 +#define PMU1_XTALTAB0_960_14400K 2 +#define PMU1_XTALTAB0_960_15360K 3 +#define PMU1_XTALTAB0_960_16200K 4 +#define PMU1_XTALTAB0_960_16800K 5 +#define PMU1_XTALTAB0_960_19200K 6 +#define PMU1_XTALTAB0_960_19800K 7 +#define PMU1_XTALTAB0_960_20000K 8 +#define PMU1_XTALTAB0_960_25000K 9 +#define PMU1_XTALTAB0_960_26000K 10 +#define PMU1_XTALTAB0_960_30000K 11 +#define PMU1_XTALTAB0_960_37400K 12 +#define PMU1_XTALTAB0_960_38400K 13 +#define PMU1_XTALTAB0_960_40000K 14 +#define PMU1_XTALTAB0_960_48000K 15 - switch (sih->chip) { - case BCM4336_CHIP_ID: - switch (ldo) { - case SET_LDO_VOLTAGE_CLDO_PWM: - addr = 4; - rc_shift = 1; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_CLDO_BURST: - addr = 4; - rc_shift = 5; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_LNLDO1: - addr = 4; - rc_shift = 17; - mask = 0xf; - break; - default: - ASSERT(false); - return; - } - break; - case BCM4330_CHIP_ID: - switch (ldo) { - case SET_LDO_VOLTAGE_CBUCK_PWM: - addr = 3; - rc_shift = 0; - mask = 0x1f; - break; - default: - ASSERT(false); - break; - } - break; - default: - ASSERT(false); - return; - } +/* + * PMU crystal table indices for 880MHz fvco + */ +#define PMU1_XTALTAB0_880_12000K 0 +#define PMU1_XTALTAB0_880_13000K 1 +#define PMU1_XTALTAB0_880_14400K 2 +#define PMU1_XTALTAB0_880_15360K 3 +#define PMU1_XTALTAB0_880_16200K 4 +#define PMU1_XTALTAB0_880_16800K 5 +#define PMU1_XTALTAB0_880_19200K 6 +#define PMU1_XTALTAB0_880_19800K 7 +#define PMU1_XTALTAB0_880_20000K 8 +#define PMU1_XTALTAB0_880_24000K 9 +#define PMU1_XTALTAB0_880_25000K 10 +#define PMU1_XTALTAB0_880_26000K 11 +#define PMU1_XTALTAB0_880_30000K 12 +#define PMU1_XTALTAB0_880_37400K 13 +#define PMU1_XTALTAB0_880_38400K 14 +#define PMU1_XTALTAB0_880_40000K 15 - shift = sr_cntl_shift + rc_shift; +/* + * crystal frequency values + */ +#define XTAL_FREQ_24000MHZ 24000 +#define XTAL_FREQ_30000MHZ 30000 +#define XTAL_FREQ_37400MHZ 37400 +#define XTAL_FREQ_48000MHZ 48000 - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), - ~0, addr); - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data), - mask << shift, (voltage & mask) << shift); -} +/* + * Resource dependancies mask change action + * + * @RES_DEPEND_SET: Override the dependancies mask + * @RES_DEPEND_ADD: Add to the dependancies mask + * @RES_DEPEND_REMOVE: Remove from the dependancies mask + */ +#define RES_DEPEND_SET 0 +#define RES_DEPEND_ADD 1 +#define RES_DEPEND_REMOVE -1 /* d11 slow to fast clock transition time in slow clock cycles */ #define D11SCC_SLOW2FAST_TRANSITION 2 -u16 si_pmu_fast_pwrup_delay(si_t *sih) -{ - uint delay = PMU_MAX_TRANSITION_DLY; - chipcregs_t *cc; - uint origidx; -#ifdef BCMDBG - char chn[8]; - chn[0] = 0; /* to suppress compile error */ -#endif - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - switch (sih->chip) { - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - case BCM4313_CHIP_ID: - delay = ISSIM_ENAB(sih) ? 70 : 3700; - break; - case BCM4329_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - case BCM4319_CHIP_ID: - delay = ISSIM_ENAB(sih) ? 70 : 3700; - break; - case BCM4336_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - case BCM4330_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - default: - break; - } - /* Return to original core */ - si_setcoreidx(sih, origidx); - - return (u16) delay; -} - -u32 si_pmu_force_ilp(si_t *sih, bool force) -{ - chipcregs_t *cc; - uint origidx; - u32 oldpmucontrol; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - oldpmucontrol = R_REG(&cc->pmucontrol); - if (force) - W_REG(&cc->pmucontrol, oldpmucontrol & - ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); - else - W_REG(&cc->pmucontrol, oldpmucontrol | - (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); - - /* Return to original core */ - si_setcoreidx(sih, origidx); - - return oldpmucontrol; -} - /* Setup resource up/down timers */ typedef struct { u8 resnum; @@ -301,10 +145,23 @@ typedef struct { bool(*filter) (si_t *sih); /* action is taken when filter is NULL or return true */ } pmu_res_depend_t; -/* Resource dependancies mask change action */ -#define RES_DEPEND_SET 0 /* Override the dependancies mask */ -#define RES_DEPEND_ADD 1 /* Add to the dependancies mask */ -#define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */ +/* setup pll and query clock speed */ +typedef struct { + u16 fref; + u8 xf; + u8 p1div; + u8 p2div; + u8 ndiv_int; + u32 ndiv_frac; +} pmu1_xtaltab0_t; + +/* + * prototypes used in resource tables + */ +static bool si_pmu_res_depfltr_bb(si_t *sih); +static bool si_pmu_res_depfltr_ncb(si_t *sih); +static bool si_pmu_res_depfltr_paldo(si_t *sih); +static bool si_pmu_res_depfltr_npaldo(si_t *sih); static const pmu_res_updown_t bcm4328a0_res_updown[] = { { @@ -561,6 +418,92 @@ static const pmu_res_depend_t bcm4330a0_res_depend[] = { PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL} }; +/* the following table is based on 1440Mhz fvco */ +static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = { + { + 12000, 1, 1, 1, 0x78, 0x0}, { + 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, { + 14400, 3, 1, 1, 0x64, 0x0}, { + 15360, 4, 1, 1, 0x5D, 0xC00000}, { + 16200, 5, 1, 1, 0x58, 0xE38E38}, { + 16800, 6, 1, 1, 0x55, 0xB6DB6D}, { + 19200, 7, 1, 1, 0x4B, 0}, { + 19800, 8, 1, 1, 0x48, 0xBA2E8B}, { + 20000, 9, 1, 1, 0x48, 0x0}, { + 25000, 10, 1, 1, 0x39, 0x999999}, { + 26000, 11, 1, 1, 0x37, 0x627627}, { + 30000, 12, 1, 1, 0x30, 0x0}, { + 37400, 13, 2, 1, 0x4D, 0x15E76}, { + 38400, 13, 2, 1, 0x4B, 0x0}, { + 40000, 14, 2, 1, 0x48, 0x0}, { + 48000, 15, 2, 1, 0x3c, 0x0}, { + 0, 0, 0, 0, 0, 0} +}; + +static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = { + { + 12000, 1, 1, 1, 0x50, 0x0}, { + 13000, 2, 1, 1, 0x49, 0xD89D89}, { + 14400, 3, 1, 1, 0x42, 0xAAAAAA}, { + 15360, 4, 1, 1, 0x3E, 0x800000}, { + 16200, 5, 1, 1, 0x39, 0x425ED0}, { + 16800, 6, 1, 1, 0x39, 0x249249}, { + 19200, 7, 1, 1, 0x32, 0x0}, { + 19800, 8, 1, 1, 0x30, 0x7C1F07}, { + 20000, 9, 1, 1, 0x30, 0x0}, { + 25000, 10, 1, 1, 0x26, 0x666666}, { + 26000, 11, 1, 1, 0x24, 0xEC4EC4}, { + 30000, 12, 1, 1, 0x20, 0x0}, { + 37400, 13, 2, 1, 0x33, 0x563EF9}, { + 38400, 14, 2, 1, 0x32, 0x0}, { + 40000, 15, 2, 1, 0x30, 0x0}, { + 48000, 16, 2, 1, 0x28, 0x0}, { + 0, 0, 0, 0, 0, 0} +}; + +static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = { + { + 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { + 13000, 2, 1, 6, 0xb, 0x483483}, { + 14400, 3, 1, 10, 0xa, 0x1C71C7}, { + 15360, 4, 1, 5, 0xb, 0x755555}, { + 16200, 5, 1, 10, 0x5, 0x6E9E06}, { + 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { + 19200, 7, 1, 4, 0xb, 0x755555}, { + 19800, 8, 1, 11, 0x4, 0xA57EB}, { + 20000, 9, 1, 11, 0x4, 0x0}, { + 24000, 10, 3, 11, 0xa, 0x0}, { + 25000, 11, 5, 16, 0xb, 0x0}, { + 26000, 12, 1, 1, 0x21, 0xD89D89}, { + 30000, 13, 3, 8, 0xb, 0x0}, { + 37400, 14, 3, 1, 0x46, 0x969696}, { + 38400, 15, 1, 1, 0x16, 0xEAAAAA}, { + 40000, 16, 1, 2, 0xb, 0}, { + 0, 0, 0, 0, 0, 0} +}; + +/* the following table is based on 880Mhz fvco */ +static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = { + { + 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { + 13000, 2, 1, 6, 0xb, 0x483483}, { + 14400, 3, 1, 10, 0xa, 0x1C71C7}, { + 15360, 4, 1, 5, 0xb, 0x755555}, { + 16200, 5, 1, 10, 0x5, 0x6E9E06}, { + 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { + 19200, 7, 1, 4, 0xb, 0x755555}, { + 19800, 8, 1, 11, 0x4, 0xA57EB}, { + 20000, 9, 1, 11, 0x4, 0x0}, { + 24000, 10, 3, 11, 0xa, 0x0}, { + 25000, 11, 5, 16, 0xb, 0x0}, { + 26000, 12, 1, 2, 0x10, 0xEC4EC4}, { + 30000, 13, 3, 8, 0xb, 0x0}, { + 33600, 14, 1, 2, 0xd, 0x186186}, { + 38400, 15, 1, 2, 0xb, 0x755555}, { + 40000, 16, 1, 2, 0xb, 0}, { + 0, 0, 0, 0, 0, 0} +}; + /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */ static bool si_pmu_res_depfltr_bb(si_t *sih) { @@ -586,8 +529,26 @@ static bool si_pmu_res_depfltr_npaldo(si_t *sih) return (sih->boardflags & BFL_PALDO) == 0; } -#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \ - sih->boardtype == BCM94325BGABU_BOARD) +/* Return dependancies (direct or all/indirect) for the given resources */ +static u32 +si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, + bool all) +{ + u32 deps = 0; + u32 i; + + for (i = 0; i <= PMURES_MAX_RESNUM; i++) { + if (!(rsrcs & PMURES_BIT(i))) + continue; + W_REG(&cc->res_table_sel, i); + deps |= R_REG(&cc->res_dep_mask); + } + + return !all ? deps : (deps + ? (deps | + si_pmu_res_deps(sih, cc, deps, + true)) : 0); +} /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) @@ -663,13 +624,11 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) /* Apply nvram override to min mask */ val = getvar(NULL, "rmin"); if (val != NULL) { - PMU_MSG(("Applying rmin=%s to min_mask\n", val)); min_mask = (u32) simple_strtoul(val, NULL, 0); } /* Apply nvram override to max mask */ val = getvar(NULL, "rmax"); if (val != NULL) { - PMU_MSG(("Applying rmax=%s to max_mask\n", val)); max_mask = (u32) simple_strtoul(val, NULL, 0); } @@ -677,453 +636,243 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) *pmax = max_mask; } -/* initialize PMU resources */ -void si_pmu_res_init(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - const pmu_res_updown_t *pmu_res_updown_table = NULL; - uint pmu_res_updown_table_sz = 0; - const pmu_res_depend_t *pmu_res_depend_table = NULL; - uint pmu_res_depend_table_sz = 0; +/* Return up time in ILP cycles for the given resource. */ +static uint +si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { + u32 deps; + uint up, i, dup, dmax; u32 min_mask = 0, max_mask = 0; - char name[8], *val; - uint i, rsrcs; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - switch (sih->chip) { - case BCM4329_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = NULL; - pmu_res_updown_table_sz = 0; - } else { - pmu_res_updown_table = bcm4329_res_updown; - pmu_res_updown_table_sz = ARRAY_SIZE(bcm4329_res_updown); - } - /* Optimize resources dependencies */ - pmu_res_depend_table = bcm4329_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend); - break; - - case BCM4319_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4319a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4319a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4319a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4319a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4319a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend); - break; - - case BCM4336_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4336a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4336a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4336a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4336a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4336a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend); - break; - - case BCM4330_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4330a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4330a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4330a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4330a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4330a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend); - break; - - default: - break; - } - /* # resources */ - rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; + /* uptime of resource 'rsrc' */ + W_REG(&cc->res_table_sel, rsrc); + up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff; - /* Program up/down timers */ - while (pmu_res_updown_table_sz--) { - ASSERT(pmu_res_updown_table != NULL); - PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n", - pmu_res_updown_table[pmu_res_updown_table_sz].resnum, - pmu_res_updown_table[pmu_res_updown_table_sz].updown)); - W_REG(&cc->res_table_sel, - pmu_res_updown_table[pmu_res_updown_table_sz].resnum); - W_REG(&cc->res_updn_timer, - pmu_res_updown_table[pmu_res_updown_table_sz].updown); - } - /* Apply nvram overrides to up/down timers */ - for (i = 0; i < rsrcs; i++) { - snprintf(name, sizeof(name), "r%dt", i); - val = getvar(NULL, name); - if (val == NULL) + /* direct dependancies of resource 'rsrc' */ + deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false); + for (i = 0; i <= PMURES_MAX_RESNUM; i++) { + if (!(deps & PMURES_BIT(i))) continue; - PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, - val, i)); - W_REG(&cc->res_table_sel, (u32) i); - W_REG(&cc->res_updn_timer, - (u32) simple_strtoul(val, NULL, 0)); + deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true); } + si_pmu_res_masks(sih, &min_mask, &max_mask); + deps &= ~min_mask; - /* Program resource dependencies table */ - while (pmu_res_depend_table_sz--) { - ASSERT(pmu_res_depend_table != NULL); - if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL - && !(pmu_res_depend_table[pmu_res_depend_table_sz]. - filter) (sih)) - continue; - for (i = 0; i < rsrcs; i++) { - if ((pmu_res_depend_table[pmu_res_depend_table_sz]. - res_mask & PMURES_BIT(i)) == 0) - continue; - W_REG(&cc->res_table_sel, i); - switch (pmu_res_depend_table[pmu_res_depend_table_sz]. - action) { - case RES_DEPEND_SET: - PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask)); - W_REG(&cc->res_dep_mask, - pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - case RES_DEPEND_ADD: - PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); - OR_REG(&cc->res_dep_mask, - pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - case RES_DEPEND_REMOVE: - PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); - AND_REG(&cc->res_dep_mask, - ~pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - default: - ASSERT(0); - break; - } - } - } - /* Apply nvram overrides to dependancies masks */ - for (i = 0; i < rsrcs; i++) { - snprintf(name, sizeof(name), "r%dd", i); - val = getvar(NULL, name); - if (val == NULL) + /* max uptime of direct dependancies */ + dmax = 0; + for (i = 0; i <= PMURES_MAX_RESNUM; i++) { + if (!(deps & PMURES_BIT(i))) continue; - PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, - i)); - W_REG(&cc->res_table_sel, (u32) i); - W_REG(&cc->res_dep_mask, - (u32) simple_strtoul(val, NULL, 0)); + dup = si_pmu_res_uptime(sih, cc, (u8) i); + if (dmax < dup) + dmax = dup; } - /* Determine min/max rsrc masks */ - si_pmu_res_masks(sih, &min_mask, &max_mask); - - /* It is required to program max_mask first and then min_mask */ + return up + dmax + PMURES_UP_TRANSITION; +} - /* Program max resource mask */ +static void +si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) +{ + u32 tmp = 0; + u8 phypll_offset = 0; + u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 }; + u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc }; - if (max_mask) { - PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); - W_REG(&cc->max_res_mask, max_mask); - } + switch (sih->chip) { + case BCM5357_CHIP_ID: + case BCM43235_CHIP_ID: + case BCM43236_CHIP_ID: + case BCM43238_CHIP_ID: - /* Program min resource mask */ + /* + * BCM5357 needs to touch PLL1_PLLCTL[02], + * so offset PLL0_PLLCTL[02] by 6 + */ + phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0; - if (min_mask) { - PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); - W_REG(&cc->min_res_mask, min_mask); - } + /* RMW only the P1 divider */ + W_REG(&cc->pllcontrol_addr, + PMU1_PLL0_PLLCTL0 + phypll_offset); + tmp = R_REG(&cc->pllcontrol_data); + tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); + tmp |= + (bcm5357_bcm43236_p1div[spuravoid] << + PMU1_PLL0_PC0_P1DIV_SHIFT); + W_REG(&cc->pllcontrol_data, tmp); - /* Add some delay; allow resources to come up and settle. */ - mdelay(2); + /* RMW only the int feedback divider */ + W_REG(&cc->pllcontrol_addr, + PMU1_PLL0_PLLCTL2 + phypll_offset); + tmp = R_REG(&cc->pllcontrol_data); + tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); + tmp |= + (bcm5357_bcm43236_ndiv[spuravoid]) << + PMU1_PLL0_PC2_NDIV_INT_SHIFT; + W_REG(&cc->pllcontrol_data, tmp); - /* Return to original core */ - si_setcoreidx(sih, origidx); -} + tmp = 1 << 10; + break; -/* setup pll and query clock speed */ -typedef struct { - u16 freq; - u8 xf; - u8 wbint; - u32 wbfrac; -} pmu0_xtaltab0_t; + case BCM4331_CHIP_ID: + if (spuravoid == 2) { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0FC00a08); + } else if (spuravoid == 1) { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600a08); + } else { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + } + tmp = 1 << 10; + break; -/* the following table is based on 880Mhz fvco */ -static const pmu0_xtaltab0_t pmu0_xtaltab0[] = { - { - 12000, 1, 73, 349525}, { - 13000, 2, 67, 725937}, { - 14400, 3, 61, 116508}, { - 15360, 4, 57, 305834}, { - 16200, 5, 54, 336579}, { - 16800, 6, 52, 399457}, { - 19200, 7, 45, 873813}, { - 19800, 8, 44, 466033}, { - 20000, 9, 44, 0}, { - 25000, 10, 70, 419430}, { - 26000, 11, 67, 725937}, { - 30000, 12, 58, 699050}, { - 38400, 13, 45, 873813}, { - 40000, 14, 45, 0}, { - 0, 0, 0, 0} -}; + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + case BCM43421_CHIP_ID: + case BCM6362_CHIP_ID: + if (spuravoid == 1) { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000C0C06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x2001E920); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } else { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000c0c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } + tmp = 1 << 10; + break; -#define PMU0_XTAL0_DEFAULT 8 + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100008); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x0c000c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888855); -/* setup pll and query clock speed */ -typedef struct { - u16 fref; - u8 xf; - u8 p1div; - u8 p2div; - u8 ndiv_int; - u32 ndiv_frac; -} pmu1_xtaltab0_t; + tmp = 1 << 10; + break; -static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = { - { - 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { - 13000, 2, 1, 6, 0xb, 0x483483}, { - 14400, 3, 1, 10, 0xa, 0x1C71C7}, { - 15360, 4, 1, 5, 0xb, 0x755555}, { - 16200, 5, 1, 10, 0x5, 0x6E9E06}, { - 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { - 19200, 7, 1, 4, 0xb, 0x755555}, { - 19800, 8, 1, 11, 0x4, 0xA57EB}, { - 20000, 9, 1, 11, 0x4, 0x0}, { - 24000, 10, 3, 11, 0xa, 0x0}, { - 25000, 11, 5, 16, 0xb, 0x0}, { - 26000, 12, 1, 1, 0x21, 0xD89D89}, { - 30000, 13, 3, 8, 0xb, 0x0}, { - 37400, 14, 3, 1, 0x46, 0x969696}, { - 38400, 15, 1, 1, 0x16, 0xEAAAAA}, { - 40000, 16, 1, 2, 0xb, 0}, { - 0, 0, 0, 0, 0, 0} -}; + case BCM4716_CHIP_ID: + case BCM4748_CHIP_ID: + case BCM47162_CHIP_ID: + if (spuravoid == 1) { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500060); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x080C0C06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x2001E924); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } else { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100060); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x080c0c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } -/* the following table is based on 880Mhz fvco */ -static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = { - { - 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { - 13000, 2, 1, 6, 0xb, 0x483483}, { - 14400, 3, 1, 10, 0xa, 0x1C71C7}, { - 15360, 4, 1, 5, 0xb, 0x755555}, { - 16200, 5, 1, 10, 0x5, 0x6E9E06}, { - 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { - 19200, 7, 1, 4, 0xb, 0x755555}, { - 19800, 8, 1, 11, 0x4, 0xA57EB}, { - 20000, 9, 1, 11, 0x4, 0x0}, { - 24000, 10, 3, 11, 0xa, 0x0}, { - 25000, 11, 5, 16, 0xb, 0x0}, { - 26000, 12, 1, 2, 0x10, 0xEC4EC4}, { - 30000, 13, 3, 8, 0xb, 0x0}, { - 33600, 14, 1, 2, 0xd, 0x186186}, { - 38400, 15, 1, 2, 0xb, 0x755555}, { - 40000, 16, 1, 2, 0xb, 0}, { - 0, 0, 0, 0, 0, 0} -}; + tmp = 3 << 9; + break; -#define PMU1_XTALTAB0_880_12000K 0 -#define PMU1_XTALTAB0_880_13000K 1 -#define PMU1_XTALTAB0_880_14400K 2 -#define PMU1_XTALTAB0_880_15360K 3 -#define PMU1_XTALTAB0_880_16200K 4 -#define PMU1_XTALTAB0_880_16800K 5 -#define PMU1_XTALTAB0_880_19200K 6 -#define PMU1_XTALTAB0_880_19800K 7 -#define PMU1_XTALTAB0_880_20000K 8 -#define PMU1_XTALTAB0_880_24000K 9 -#define PMU1_XTALTAB0_880_25000K 10 -#define PMU1_XTALTAB0_880_26000K 11 -#define PMU1_XTALTAB0_880_30000K 12 -#define PMU1_XTALTAB0_880_37400K 13 -#define PMU1_XTALTAB0_880_38400K 14 -#define PMU1_XTALTAB0_880_40000K 15 + case BCM4319_CHIP_ID: + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100070); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x1014140a); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888854); -/* the following table is based on 1760Mhz fvco */ -static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = { - { - 12000, 1, 3, 44, 0x9, 0xFFFFEF}, { - 13000, 2, 1, 12, 0xb, 0x483483}, { - 14400, 3, 1, 20, 0xa, 0x1C71C7}, { - 15360, 4, 1, 10, 0xb, 0x755555}, { - 16200, 5, 1, 20, 0x5, 0x6E9E06}, { - 16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, { - 19200, 7, 1, 18, 0x5, 0x17B425}, { - 19800, 8, 1, 22, 0x4, 0xA57EB}, { - 20000, 9, 1, 22, 0x4, 0x0}, { - 24000, 10, 3, 22, 0xa, 0x0}, { - 25000, 11, 5, 32, 0xb, 0x0}, { - 26000, 12, 1, 4, 0x10, 0xEC4EC4}, { - 30000, 13, 3, 16, 0xb, 0x0}, { - 38400, 14, 1, 10, 0x4, 0x955555}, { - 40000, 15, 1, 4, 0xb, 0}, { - 0, 0, 0, 0, 0, 0} -}; + if (spuravoid == 1) { + /* spur_avoid ON, so enable 41/82/164Mhz clock mode */ + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x05201828); + } else { + /* enable 40/80/160Mhz clock mode */ + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x05001828); + } + break; + case BCM4336_CHIP_ID: + /* Looks like these are only for default xtal freq 26MHz */ + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x02100020); -/* table index */ -#define PMU1_XTALTAB0_1760_12000K 0 -#define PMU1_XTALTAB0_1760_13000K 1 -#define PMU1_XTALTAB0_1760_14400K 2 -#define PMU1_XTALTAB0_1760_15360K 3 -#define PMU1_XTALTAB0_1760_16200K 4 -#define PMU1_XTALTAB0_1760_16800K 5 -#define PMU1_XTALTAB0_1760_19200K 6 -#define PMU1_XTALTAB0_1760_19800K 7 -#define PMU1_XTALTAB0_1760_20000K 8 -#define PMU1_XTALTAB0_1760_24000K 9 -#define PMU1_XTALTAB0_1760_25000K 10 -#define PMU1_XTALTAB0_1760_26000K 11 -#define PMU1_XTALTAB0_1760_30000K 12 -#define PMU1_XTALTAB0_1760_38400K 13 -#define PMU1_XTALTAB0_1760_40000K 14 + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x0C0C0C0C); -/* the following table is based on 1440Mhz fvco */ -static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = { - { - 12000, 1, 1, 1, 0x78, 0x0}, { - 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, { - 14400, 3, 1, 1, 0x64, 0x0}, { - 15360, 4, 1, 1, 0x5D, 0xC00000}, { - 16200, 5, 1, 1, 0x58, 0xE38E38}, { - 16800, 6, 1, 1, 0x55, 0xB6DB6D}, { - 19200, 7, 1, 1, 0x4B, 0}, { - 19800, 8, 1, 1, 0x48, 0xBA2E8B}, { - 20000, 9, 1, 1, 0x48, 0x0}, { - 25000, 10, 1, 1, 0x39, 0x999999}, { - 26000, 11, 1, 1, 0x37, 0x627627}, { - 30000, 12, 1, 1, 0x30, 0x0}, { - 37400, 13, 2, 1, 0x4D, 0x15E76}, { - 38400, 13, 2, 1, 0x4B, 0x0}, { - 40000, 14, 2, 1, 0x48, 0x0}, { - 48000, 15, 2, 1, 0x3c, 0x0}, { - 0, 0, 0, 0, 0, 0} -}; + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x01240C0C); -/* table index */ -#define PMU1_XTALTAB0_1440_12000K 0 -#define PMU1_XTALTAB0_1440_13000K 1 -#define PMU1_XTALTAB0_1440_14400K 2 -#define PMU1_XTALTAB0_1440_15360K 3 -#define PMU1_XTALTAB0_1440_16200K 4 -#define PMU1_XTALTAB0_1440_16800K 5 -#define PMU1_XTALTAB0_1440_19200K 6 -#define PMU1_XTALTAB0_1440_19800K 7 -#define PMU1_XTALTAB0_1440_20000K 8 -#define PMU1_XTALTAB0_1440_25000K 9 -#define PMU1_XTALTAB0_1440_26000K 10 -#define PMU1_XTALTAB0_1440_30000K 11 -#define PMU1_XTALTAB0_1440_37400K 12 -#define PMU1_XTALTAB0_1440_38400K 13 -#define PMU1_XTALTAB0_1440_40000K 14 -#define PMU1_XTALTAB0_1440_48000K 15 + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x202C2820); -#define XTAL_FREQ_24000MHZ 24000 -#define XTAL_FREQ_30000MHZ 30000 -#define XTAL_FREQ_37400MHZ 37400 -#define XTAL_FREQ_48000MHZ 48000 + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888825); -static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = { - { - 12000, 1, 1, 1, 0x50, 0x0}, { - 13000, 2, 1, 1, 0x49, 0xD89D89}, { - 14400, 3, 1, 1, 0x42, 0xAAAAAA}, { - 15360, 4, 1, 1, 0x3E, 0x800000}, { - 16200, 5, 1, 1, 0x39, 0x425ED0}, { - 16800, 6, 1, 1, 0x39, 0x249249}, { - 19200, 7, 1, 1, 0x32, 0x0}, { - 19800, 8, 1, 1, 0x30, 0x7C1F07}, { - 20000, 9, 1, 1, 0x30, 0x0}, { - 25000, 10, 1, 1, 0x26, 0x666666}, { - 26000, 11, 1, 1, 0x24, 0xEC4EC4}, { - 30000, 12, 1, 1, 0x20, 0x0}, { - 37400, 13, 2, 1, 0x33, 0x563EF9}, { - 38400, 14, 2, 1, 0x32, 0x0}, { - 40000, 15, 2, 1, 0x30, 0x0}, { - 48000, 16, 2, 1, 0x28, 0x0}, { - 0, 0, 0, 0, 0, 0} -}; + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + if (spuravoid == 1) + W_REG(&cc->pllcontrol_data, 0x00EC4EC4); + else + W_REG(&cc->pllcontrol_data, 0x00762762); -/* table index */ -#define PMU1_XTALTAB0_960_12000K 0 -#define PMU1_XTALTAB0_960_13000K 1 -#define PMU1_XTALTAB0_960_14400K 2 -#define PMU1_XTALTAB0_960_15360K 3 -#define PMU1_XTALTAB0_960_16200K 4 -#define PMU1_XTALTAB0_960_16800K 5 -#define PMU1_XTALTAB0_960_19200K 6 -#define PMU1_XTALTAB0_960_19800K 7 -#define PMU1_XTALTAB0_960_20000K 8 -#define PMU1_XTALTAB0_960_25000K 9 -#define PMU1_XTALTAB0_960_26000K 10 -#define PMU1_XTALTAB0_960_30000K 11 -#define PMU1_XTALTAB0_960_37400K 12 -#define PMU1_XTALTAB0_960_38400K 13 -#define PMU1_XTALTAB0_960_40000K 14 -#define PMU1_XTALTAB0_960_48000K 15 + tmp = PCTL_PLL_PLLCTL_UPD; + break; -/* select xtal table for each chip */ -static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) -{ -#ifdef BCMDBG - char chn[8]; -#endif - switch (sih->chip) { - case BCM4329_CHIP_ID: - return pmu1_xtaltab0_880_4329; - case BCM4319_CHIP_ID: - return pmu1_xtaltab0_1440; - case BCM4336_CHIP_ID: - return pmu1_xtaltab0_960; - case BCM4330_CHIP_ID: - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - return pmu1_xtaltab0_960; - else - return pmu1_xtaltab0_1440; default: - PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", - bcm_chipname(sih->chip, chn, 8))); - break; + /* bail out */ + return; } - ASSERT(0); - return NULL; + + tmp |= R_REG(&cc->pmucontrol); + W_REG(&cc->pmucontrol, tmp); } /* select default xtal frequency for each chip */ static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) { -#ifdef BCMDBG - char chn[8]; -#endif - switch (sih->chip) { case BCM4329_CHIP_ID: /* Default to 38400Khz */ @@ -1141,40 +890,30 @@ static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) else return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]; default: - PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", - bcm_chipname(sih->chip, chn, 8))); break; } - ASSERT(0); return NULL; } -/* select default pll fvco for each chip */ -static u32 si_pmu1_pllfvco0(si_t *sih) +/* select xtal table for each chip */ +static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) { -#ifdef BCMDBG - char chn[8]; -#endif - switch (sih->chip) { case BCM4329_CHIP_ID: - return FVCO_880; + return pmu1_xtaltab0_880_4329; case BCM4319_CHIP_ID: - return FVCO_1440; + return pmu1_xtaltab0_1440; case BCM4336_CHIP_ID: - return FVCO_960; + return pmu1_xtaltab0_960; case BCM4330_CHIP_ID: if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - return FVCO_960; + return pmu1_xtaltab0_960; else - return FVCO_1440; + return pmu1_xtaltab0_1440; default: - PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", - bcm_chipname(sih->chip, chn, 8))); break; } - ASSERT(0); - return 0; + return NULL; } /* query alp/xtal clock frequency */ @@ -1193,11 +932,58 @@ si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc) /* Could not find it so assign a default value */ if (xt == NULL || xt->fref == 0) xt = si_pmu1_xtaldef0(sih); - ASSERT(xt != NULL && xt->fref != 0); - return xt->fref * 1000; } +/* select default pll fvco for each chip */ +static u32 si_pmu1_pllfvco0(si_t *sih) +{ + switch (sih->chip) { + case BCM4329_CHIP_ID: + return FVCO_880; + case BCM4319_CHIP_ID: + return FVCO_1440; + case BCM4336_CHIP_ID: + return FVCO_960; + case BCM4330_CHIP_ID: + if (CST4330_CHIPMODE_SDIOD(sih->chipst)) + return FVCO_960; + else + return FVCO_1440; + default: + break; + } + return 0; +} + +static void si_pmu_set_4330_plldivs(si_t *sih) +{ + u32 FVCO = si_pmu1_pllfvco0(sih) / 1000; + u32 m1div, m2div, m3div, m4div, m5div, m6div; + u32 pllc1, pllc2; + + m2div = m3div = m4div = m6div = FVCO / 80; + m5div = FVCO / 160; + + if (CST4330_CHIPMODE_SDIOD(sih->chipst)) + m1div = FVCO / 80; + else + m1div = FVCO / 90; + pllc1 = + (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << + PMU1_PLL0_PC1_M2DIV_SHIFT) | + (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << + PMU1_PLL0_PC1_M4DIV_SHIFT); + si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1); + + pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0); + pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK); + pllc2 |= + ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | + (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT)); + si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2); +} + /* Set up PLL registers in the PMU as per the crystal speed. * XtalFreq field in pmucontrol register being 0 indicates the PLL * is not programmed and the h/w default is assumed to work, in which @@ -1213,7 +999,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) /* Use h/w default PLL config */ if (xtal == 0) { - PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n")); return; } @@ -1226,24 +1011,16 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) * we don't know how to program it. */ if (xt == NULL || xt->fref == 0) { - PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", xtal / 1000, xtal % 1000)); return; } - /* for 4319 bootloader already programs the PLL but bootloader does not program the - PLL4 and PLL5. So Skip this check for 4319 + /* for 4319 bootloader already programs the PLL but bootloader does not + * program the PLL4 and PLL5. So Skip this check for 4319 */ if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT) == xt->xf) && !((sih->chip == BCM4319_CHIP_ID) - || (sih->chip == BCM4330_CHIP_ID))) { - PMU_MSG(("PLL already programmed for %d.%d MHz\n", - xt->fref / 1000, xt->fref % 1000)); + || (sih->chip == BCM4330_CHIP_ID))) return; - } - - PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); - PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, - xt->fref % 1000)); switch (sih->chip) { case BCM4329_CHIP_ID: @@ -1257,7 +1034,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) PMURES_BIT(RES4329_HT_AVAIL))); SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); if (xt->fref == 38400) tmp = 0x200024C0; @@ -1302,7 +1078,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) udelay(100); SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); tmp = 0x200005c0; W_REG(&cc->pllcontrol_data, tmp); @@ -1318,7 +1093,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) udelay(100); SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); break; case BCM4330_CHIP_ID: @@ -1331,15 +1105,12 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) udelay(100); SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); break; default: - ASSERT(0); + break; } - PMU_MSG(("Done masking\n")); - /* Write p1div and p2div to pllcontrol[0] */ W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); tmp = R_REG(&cc->pllcontrol_data) & @@ -1391,9 +1162,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) /* Write clock driving strength to pllcontrol[5] */ if (buf_strength) { - PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", - buf_strength)); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; @@ -1401,8 +1169,6 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) W_REG(&cc->pllcontrol_data, tmp); } - PMU_MSG(("Done pll\n")); - /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs * to be updated. */ @@ -1444,130 +1210,91 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) W_REG(&cc->pmucontrol, tmp); } -/* query the CPU clock frequency */ -static u32 -si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc) +u32 si_pmu_ilp_clock(si_t *sih) { - u32 tmp, m1div; -#ifdef BCMDBG - u32 ndiv_int, ndiv_frac, p2div, p1div, fvco; - u32 fref; -#endif - u32 FVCO = si_pmu1_pllfvco0(sih); - - /* Read m1div from pllcontrol[1] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - tmp = R_REG(&cc->pllcontrol_data); - m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; - -#ifdef BCMDBG - /* Read p2div/p1div from pllcontrol[0] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG(&cc->pllcontrol_data); - p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT; - p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT; - - /* Calculate fvco based on xtal freq and ndiv and pdiv */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG(&cc->pllcontrol_data); - ndiv_int = - (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT; - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG(&cc->pllcontrol_data); - ndiv_frac = - (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> - PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; + static u32 ilpcycles_per_sec; - fref = si_pmu1_alpclk0(sih, cc) / 1000; - - fvco = (fref * ndiv_int) << 8; - fvco += (fref * (ndiv_frac >> 12)) >> 4; - fvco += (fref * (ndiv_frac & 0xfff)) >> 12; - fvco >>= 8; - fvco *= p2div; - fvco /= p1div; - fvco /= 1000; - fvco *= 1000; - - PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco)); + if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih)) + return ILP_CLOCK; - FVCO = fvco; -#endif /* BCMDBG */ + if (ilpcycles_per_sec == 0) { + u32 start, end, delta; + u32 origidx = ai_coreidx(sih); + chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX); + start = R_REG(&cc->pmutimer); + mdelay(ILP_CALC_DUR); + end = R_REG(&cc->pmutimer); + delta = end - start; + ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); + ai_setcoreidx(sih, origidx); + } - /* Return ARM/SB clock */ - return FVCO / m1div * 1000; + return ilpcycles_per_sec; } -/* initialize PLL */ -void si_pmu_pll_init(si_t *sih, uint xtalfreq) +void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) { - chipcregs_t *cc; - uint origidx; -#ifdef BCMDBG - char chn[8]; -#endif - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; + u8 addr = 0; switch (sih->chip) { - case BCM4329_CHIP_ID: - if (xtalfreq == 0) - xtalfreq = 38400; - si_pmu1_pllinit0(sih, cc, xtalfreq); - break; - case BCM4313_CHIP_ID: - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - /* ??? */ - break; - case BCM4319_CHIP_ID: case BCM4336_CHIP_ID: + switch (ldo) { + case SET_LDO_VOLTAGE_CLDO_PWM: + addr = 4; + rc_shift = 1; + mask = 0xf; + break; + case SET_LDO_VOLTAGE_CLDO_BURST: + addr = 4; + rc_shift = 5; + mask = 0xf; + break; + case SET_LDO_VOLTAGE_LNLDO1: + addr = 4; + rc_shift = 17; + mask = 0xf; + break; + default: + return; + } + break; case BCM4330_CHIP_ID: - si_pmu1_pllinit0(sih, cc, xtalfreq); + switch (ldo) { + case SET_LDO_VOLTAGE_CBUCK_PWM: + addr = 3; + rc_shift = 0; + mask = 0x1f; + break; + default: + return; + } break; default: - PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n", - bcm_chipname(sih->chip, chn, 8), sih->chiprev, - sih->pmurev)); - break; + return; } -#ifdef BCMDBG_FORCEHT - OR_REG(&cc->clk_ctl_st, CCS_FORCEHT); -#endif + shift = sr_cntl_shift + rc_shift; - /* Return to original core */ - si_setcoreidx(sih, origidx); + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), + ~0, addr); + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data), + mask << shift, (voltage & mask) << shift); } -/* query alp/xtal clock frequency */ -u32 si_pmu_alp_clock(si_t *sih) +u16 si_pmu_fast_pwrup_delay(si_t *sih) { + uint delay = PMU_MAX_TRANSITION_DLY; chipcregs_t *cc; uint origidx; - u32 clock = ALP_CLOCK; #ifdef BCMDBG char chn[8]; + chn[0] = 0; /* to suppress compile error */ #endif - ASSERT(sih->cccaps & CC_CAP_PMU); - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { case BCM43224_CHIP_ID: @@ -1578,396 +1305,188 @@ u32 si_pmu_alp_clock(si_t *sih) case BCM43238_CHIP_ID: case BCM4331_CHIP_ID: case BCM6362_CHIP_ID: - case BCM4716_CHIP_ID: - case BCM4748_CHIP_ID: - case BCM47162_CHIP_ID: case BCM4313_CHIP_ID: - case BCM5357_CHIP_ID: - /* always 20Mhz */ - clock = 20000 * 1000; + delay = ISSIM_ENAB(sih) ? 70 : 3700; break; case BCM4329_CHIP_ID: + if (ISSIM_ENAB(sih)) + delay = 70; + else { + u32 ilp = si_pmu_ilp_clock(sih); + delay = + (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) + + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - + 1) / ilp); + delay = (11 * delay) / 10; + } + break; case BCM4319_CHIP_ID: + delay = ISSIM_ENAB(sih) ? 70 : 3700; + break; case BCM4336_CHIP_ID: - case BCM4330_CHIP_ID: - - clock = si_pmu1_alpclk0(sih, cc); + if (ISSIM_ENAB(sih)) + delay = 70; + else { + u32 ilp = si_pmu_ilp_clock(sih); + delay = + (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) + + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - + 1) / ilp); + delay = (11 * delay) / 10; + } break; - case BCM5356_CHIP_ID: - /* always 25Mhz */ - clock = 25000 * 1000; + case BCM4330_CHIP_ID: + if (ISSIM_ENAB(sih)) + delay = 70; + else { + u32 ilp = si_pmu_ilp_clock(sih); + delay = + (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) + + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - + 1) / ilp); + delay = (11 * delay) / 10; + } break; default: - PMU_MSG(("No ALP clock specified " - "for chip %s rev %d pmurev %d, using default %d Hz\n", - bcm_chipname(sih->chip, chn, 8), sih->chiprev, - sih->pmurev, clock)); break; } - /* Return to original core */ - si_setcoreidx(sih, origidx); - return clock; -} - -/* Find the output of the "m" pll divider given pll controls that start with - * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. - */ -static u32 -si_pmu5_clock(si_t *sih, chipcregs_t *cc, uint pll0, uint m) { - u32 tmp, div, ndiv, p1, p2, fc; + ai_setcoreidx(sih, origidx); - if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) { - PMU_ERROR(("%s: Bad pll0: %d\n", __func__, pll0)); - return 0; - } - - /* Strictly there is an m5 divider, but I'm not sure we use it */ - if ((m == 0) || (m > 4)) { - PMU_ERROR(("%s: Bad m divider: %d\n", __func__, m)); - return 0; - } + return (u16) delay; +} - if (sih->chip == BCM5357_CHIP_ID) { - /* Detect failure in clock setting */ - if ((R_REG(&cc->chipstatus) & 0x40000) != 0) - return 133 * 1000000; - } +void si_pmu_sprom_enable(si_t *sih, bool enable) +{ + chipcregs_t *cc; + uint origidx; - W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF); - (void)R_REG(&cc->pllcontrol_addr); - tmp = R_REG(&cc->pllcontrol_data); - p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT; - p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT; + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); - W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF); - (void)R_REG(&cc->pllcontrol_addr); - tmp = R_REG(&cc->pllcontrol_data); - div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK; + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} - W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF); - (void)R_REG(&cc->pllcontrol_addr); - tmp = R_REG(&cc->pllcontrol_data); - ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT; +/* Read/write a chipcontrol reg */ +u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), mask, val); +} - /* Do calculation in Mhz */ - fc = si_pmu_alp_clock(sih) / 1000000; - fc = (p1 * ndiv * fc) / p2; +/* Read/write a regcontrol reg */ +u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, regcontrol_data), mask, val); +} - PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n", - __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div)); +/* Read/write a pllcontrol reg */ +u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, pllcontrol_data), mask, val); +} - /* Return clock in Hertz */ - return (fc / div) * 1000000; +/* PMU PLL update */ +void si_pmu_pllupd(si_t *sih) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), + PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); } -/* query backplane clock frequency */ -/* For designs that feed the same clock to both backplane - * and CPU just return the CPU clock speed. - */ -u32 si_pmu_si_clock(si_t *sih) +/* query alp/xtal clock frequency */ +u32 si_pmu_alp_clock(si_t *sih) { chipcregs_t *cc; uint origidx; - u32 clock = HT_CLOCK; -#ifdef BCMDBG - char chn[8]; -#endif + u32 clock = ALP_CLOCK; - ASSERT(sih->cccaps & CC_CAP_PMU); + /* bail out with default */ + if (!PMUCTL_ENAB(sih)) + return clock; /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: + case BCM43235_CHIP_ID: + case BCM43236_CHIP_ID: + case BCM43238_CHIP_ID: case BCM4331_CHIP_ID: case BCM6362_CHIP_ID: - /* 96MHz backplane clock */ - clock = 96000 * 1000; - break; case BCM4716_CHIP_ID: case BCM4748_CHIP_ID: case BCM47162_CHIP_ID: - clock = - si_pmu5_clock(sih, cc, PMU4716_MAINPLL_PLL0, - PMU5_MAINPLL_SI); + case BCM4313_CHIP_ID: + case BCM5357_CHIP_ID: + /* always 20Mhz */ + clock = 20000 * 1000; break; case BCM4329_CHIP_ID: - if (sih->chiprev == 0) - clock = 38400 * 1000; - else - clock = si_pmu1_cpuclk0(sih, cc); - break; case BCM4319_CHIP_ID: case BCM4336_CHIP_ID: case BCM4330_CHIP_ID: - clock = si_pmu1_cpuclk0(sih, cc); - break; - case BCM4313_CHIP_ID: - /* 80MHz backplane clock */ - clock = 80000 * 1000; - break; - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - clock = - (cc->chipstatus & CST43236_BP_CLK) ? (120000 * - 1000) : (96000 * - 1000); + + clock = si_pmu1_alpclk0(sih, cc); break; case BCM5356_CHIP_ID: - clock = - si_pmu5_clock(sih, cc, PMU5356_MAINPLL_PLL0, - PMU5_MAINPLL_SI); - break; - case BCM5357_CHIP_ID: - clock = - si_pmu5_clock(sih, cc, PMU5357_MAINPLL_PLL0, - PMU5_MAINPLL_SI); + /* always 25Mhz */ + clock = 25000 * 1000; break; default: - PMU_MSG(("No backplane clock specified " - "for chip %s rev %d pmurev %d, using default %d Hz\n", - bcm_chipname(sih->chip, chn, 8), sih->chiprev, - sih->pmurev, clock)); break; } /* Return to original core */ - si_setcoreidx(sih, origidx); - return clock; -} - -/* query CPU clock frequency */ -u32 si_pmu_cpu_clock(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - u32 clock; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - if ((sih->pmurev >= 5) && - !((sih->chip == BCM4329_CHIP_ID) || - (sih->chip == BCM4319_CHIP_ID) || - (sih->chip == BCM43236_CHIP_ID) || - (sih->chip == BCM4336_CHIP_ID) || - (sih->chip == BCM4330_CHIP_ID))) { - uint pll; - - switch (sih->chip) { - case BCM5356_CHIP_ID: - pll = PMU5356_MAINPLL_PLL0; - break; - case BCM5357_CHIP_ID: - pll = PMU5357_MAINPLL_PLL0; - break; - default: - pll = PMU4716_MAINPLL_PLL0; - break; - } - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_CPU); - - /* Return to original core */ - si_setcoreidx(sih, origidx); - } else - clock = si_pmu_si_clock(sih); - + ai_setcoreidx(sih, origidx); return clock; } -/* query memory clock frequency */ -u32 si_pmu_mem_clock(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - u32 clock; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - if ((sih->pmurev >= 5) && - !((sih->chip == BCM4329_CHIP_ID) || - (sih->chip == BCM4319_CHIP_ID) || - (sih->chip == BCM4330_CHIP_ID) || - (sih->chip == BCM4336_CHIP_ID) || - (sih->chip == BCM43236_CHIP_ID))) { - uint pll; - - switch (sih->chip) { - case BCM5356_CHIP_ID: - pll = PMU5356_MAINPLL_PLL0; - break; - case BCM5357_CHIP_ID: - pll = PMU5357_MAINPLL_PLL0; - break; - default: - pll = PMU4716_MAINPLL_PLL0; - break; - } - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_MEM); - - /* Return to original core */ - si_setcoreidx(sih, origidx); - } else { - clock = si_pmu_si_clock(sih); - } - - return clock; -} - -/* Measure ILP clock frequency */ -#define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */ - -static u32 ilpcycles_per_sec; - -u32 si_pmu_ilp_clock(si_t *sih) +void si_pmu_spuravoid(si_t *sih, u8 spuravoid) { - if (ISSIM_ENAB(sih)) - return ILP_CLOCK; - - if (ilpcycles_per_sec == 0) { - u32 start, end, delta; - u32 origidx = si_coreidx(sih); - chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - start = R_REG(&cc->pmutimer); - mdelay(ILP_CALC_DUR); - end = R_REG(&cc->pmutimer); - delta = end - start; - ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); - si_setcoreidx(sih, origidx); - } - - return ilpcycles_per_sec; -} - -/* SDIO Pad drive strength to select value mappings */ -typedef struct { - u8 strength; /* Pad Drive Strength in mA */ - u8 sel; /* Chip-specific select value */ -} sdiod_drive_str_t; - -/* SDIO Drive Strength to sel value table for PMU Rev 1 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { - { - 4, 0x2}, { - 2, 0x3}, { - 1, 0x0}, { - 0, 0x0} - }; - -/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ -static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { - { - 12, 0x7}, { - 10, 0x6}, { - 8, 0x5}, { - 6, 0x4}, { - 4, 0x2}, { - 2, 0x1}, { - 0, 0x0} - }; - -/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ -static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { - { - 32, 0x7}, { - 26, 0x6}, { - 22, 0x5}, { - 16, 0x4}, { - 12, 0x3}, { - 8, 0x2}, { - 4, 0x1}, { - 0, 0x0} - }; - -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) - -void -si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength) { chipcregs_t *cc; - uint origidx, intr_val = 0; - sdiod_drive_str_t *str_tab = NULL; - u32 str_mask = 0; - u32 str_shift = 0; -#ifdef BCMDBG - char chn[8]; -#endif - - if (!(sih->cccaps & CC_CAP_PMU)) { - return; - } + uint origidx, intr_val; + u32 tmp = 0; /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, + cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); - switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; - str_mask = 0x30000000; - str_shift = 28; - break; - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): - case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; - str_mask = 0x00003800; - str_shift = 11; - break; - case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): - str_tab = (sdiod_drive_str_t *) &sdiod_drive_strength_tab3; - str_mask = 0x00003800; - str_shift = 11; - break; - - default: - PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); - - break; + /* force the HT off */ + if (sih->chip == BCM4336_CHIP_ID) { + tmp = R_REG(&cc->max_res_mask); + tmp &= ~RES4336_HT_AVAIL; + W_REG(&cc->max_res_mask, tmp); + /* wait for the ht to really go away */ + SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0), + 10000); } - if (str_tab != NULL) { - u32 drivestrength_sel = 0; - u32 cc_data_temp; - int i; - - for (i = 0; str_tab[i].strength != 0; i++) { - if (drivestrength >= str_tab[i].strength) { - drivestrength_sel = str_tab[i].sel; - break; - } - } - - W_REG(&cc->chipcontrol_addr, 1); - cc_data_temp = R_REG(&cc->chipcontrol_data); - cc_data_temp &= ~str_mask; - drivestrength_sel <<= str_shift; - cc_data_temp |= drivestrength_sel; - W_REG(&cc->chipcontrol_data, cc_data_temp); + /* update the pll changes */ + si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); - PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n", - drivestrength, cc_data_temp)); + /* enable HT back on */ + if (sih->chip == BCM4336_CHIP_ID) { + tmp = R_REG(&cc->max_res_mask); + tmp |= RES4336_HT_AVAIL; + W_REG(&cc->max_res_mask, tmp); } /* Return to original core */ - si_restore_core(sih, origidx, intr_val); + ai_restore_core(sih, origidx, intr_val); } /* initialize PMU */ @@ -1976,12 +1495,9 @@ void si_pmu_init(si_t *sih) chipcregs_t *cc; uint origidx; - ASSERT(sih->cccaps & CC_CAP_PMU); - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); if (sih->pmurev == 1) AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); @@ -1998,446 +1514,312 @@ void si_pmu_init(si_t *sih) } /* Return to original core */ - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); } -/* Return up time in ILP cycles for the given resource. */ -static uint -si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { - u32 deps; - uint up, i, dup, dmax; - u32 min_mask = 0, max_mask = 0; - - /* uptime of resource 'rsrc' */ - W_REG(&cc->res_table_sel, rsrc); - up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff; - - /* direct dependancies of resource 'rsrc' */ - deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false); - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(deps & PMURES_BIT(i))) - continue; - deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true); - } - si_pmu_res_masks(sih, &min_mask, &max_mask); - deps &= ~min_mask; +/* initialize PMU chip controls and other chip level stuff */ +void si_pmu_chip_init(si_t *sih) +{ + uint origidx; - /* max uptime of direct dependancies */ - dmax = 0; - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(deps & PMURES_BIT(i))) - continue; - dup = si_pmu_res_uptime(sih, cc, (u8) i); - if (dmax < dup) - dmax = dup; - } + /* Gate off SPROM clock and chip select signals */ + si_pmu_sprom_enable(sih, false); - PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", rsrc, up, deps, dmax)); + /* Remember original core */ + origidx = ai_coreidx(sih); - return up + dmax + PMURES_UP_TRANSITION; + /* Return to original core */ + ai_setcoreidx(sih, origidx); } -/* Return dependancies (direct or all/indirect) for the given resources */ -static u32 -si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, - bool all) +/* initialize PMU switch/regulators */ +void si_pmu_swreg_init(si_t *sih) { - u32 deps = 0; - u32 i; + switch (sih->chip) { + case BCM4336_CHIP_ID: + /* Reduce CLDO PWM output voltage to 1.2V */ + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); + /* Reduce CLDO BURST output voltage to 1.2V */ + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST, + 0xe); + /* Reduce LNLDO1 output voltage to 1.2V */ + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe); + if (sih->chiprev == 0) + si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); + break; - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(rsrcs & PMURES_BIT(i))) - continue; - W_REG(&cc->res_table_sel, i); - deps |= R_REG(&cc->res_dep_mask); + case BCM4330_CHIP_ID: + /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0); + break; + default: + break; } - - return !all ? deps : (deps - ? (deps | - si_pmu_res_deps(sih, cc, deps, - true)) : 0); } -/* power up/down OTP through PMU resources */ -void si_pmu_otp_power(si_t *sih, bool on) +/* initialize PLL */ +void si_pmu_pll_init(si_t *sih, uint xtalfreq) { chipcregs_t *cc; uint origidx; - u32 rsrcs = 0; /* rsrcs to turn on/off OTP power */ - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Don't do anything if OTP is disabled */ - if (si_is_otp_disabled(sih)) { - PMU_MSG(("si_pmu_otp_power: OTP is disabled\n")); - return; - } /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { case BCM4329_CHIP_ID: - rsrcs = PMURES_BIT(RES4329_OTP_PU); + if (xtalfreq == 0) + xtalfreq = 38400; + si_pmu1_pllinit0(sih, cc, xtalfreq); break; - case BCM4319_CHIP_ID: - rsrcs = PMURES_BIT(RES4319_OTP_PU); + case BCM4313_CHIP_ID: + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + case BCM43421_CHIP_ID: + case BCM43235_CHIP_ID: + case BCM43236_CHIP_ID: + case BCM43238_CHIP_ID: + case BCM4331_CHIP_ID: + case BCM6362_CHIP_ID: + /* ??? */ break; + case BCM4319_CHIP_ID: case BCM4336_CHIP_ID: - rsrcs = PMURES_BIT(RES4336_OTP_PU); - break; case BCM4330_CHIP_ID: - rsrcs = PMURES_BIT(RES4330_OTP_PU); + si_pmu1_pllinit0(sih, cc, xtalfreq); break; default: break; } - if (rsrcs != 0) { - u32 otps; - - /* Figure out the dependancies (exclude min_res_mask) */ - u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true); - u32 min_mask = 0, max_mask = 0; - si_pmu_res_masks(sih, &min_mask, &max_mask); - deps &= ~min_mask; - /* Turn on/off the power */ - if (on) { - PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", - rsrcs | deps)); - OR_REG(&cc->min_res_mask, (rsrcs | deps)); - SPINWAIT(!(R_REG(&cc->res_state) & rsrcs), - PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG(&cc->res_state) & rsrcs); - } else { - PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", - rsrcs | deps)); - AND_REG(&cc->min_res_mask, ~(rsrcs | deps)); - } - - SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) != - (on ? OTPS_READY : 0)), 100); - ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0)); - if ((otps & OTPS_READY) != (on ? OTPS_READY : 0)) - PMU_MSG(("OTP ready bit not %s after wait\n", - (on ? "ON" : "OFF"))); - } - /* Return to original core */ - si_setcoreidx(sih, origidx); + ai_setcoreidx(sih, origidx); } -void si_pmu_rcal(si_t *sih) +/* initialize PMU resources */ +void si_pmu_res_init(si_t *sih) { chipcregs_t *cc; uint origidx; - - ASSERT(sih->cccaps & CC_CAP_PMU); + const pmu_res_updown_t *pmu_res_updown_table = NULL; + uint pmu_res_updown_table_sz = 0; + const pmu_res_depend_t *pmu_res_depend_table = NULL; + uint pmu_res_depend_table_sz = 0; + u32 min_mask = 0, max_mask = 0; + char name[8], *val; + uint i, rsrcs; /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { - case BCM4329_CHIP_ID:{ - u8 rcal_code; - u32 val; - - /* Kick RCal */ - W_REG(&cc->chipcontrol_addr, 1); - - /* Power Down RCAL Block */ - AND_REG(&cc->chipcontrol_data, ~0x04); - - /* Power Up RCAL block */ - OR_REG(&cc->chipcontrol_data, 0x04); - - /* Wait for completion */ - SPINWAIT(0 == (R_REG(&cc->chipstatus) & 0x08), - 10 * 1000 * 1000); - ASSERT(R_REG(&cc->chipstatus) & 0x08); - - /* Drop the LSB to convert from 5 bit code to 4 bit code */ - rcal_code = - (u8) (R_REG(&cc->chipstatus) >> 5) & 0x0f; - - PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", - R_REG(&cc->chipstatus), rcal_code)); - - /* Write RCal code into pmu_vreg_ctrl[32:29] */ - W_REG(&cc->regcontrol_addr, 0); - val = - R_REG(&cc->regcontrol_data) & ~((u32) 0x07 << 29); - val |= (u32) (rcal_code & 0x07) << 29; - W_REG(&cc->regcontrol_data, val); - W_REG(&cc->regcontrol_addr, 1); - val = R_REG(&cc->regcontrol_data) & ~(u32) 0x01; - val |= (u32) ((rcal_code >> 3) & 0x01); - W_REG(&cc->regcontrol_data, val); - - /* Write RCal code into pmu_chip_ctrl[33:30] */ - W_REG(&cc->chipcontrol_addr, 0); - val = - R_REG(&cc->chipcontrol_data) & ~((u32) 0x03 << 30); - val |= (u32) (rcal_code & 0x03) << 30; - W_REG(&cc->chipcontrol_data, val); - W_REG(&cc->chipcontrol_addr, 1); - val = - R_REG(&cc->chipcontrol_data) & ~(u32) 0x03; - val |= (u32) ((rcal_code >> 2) & 0x03); - W_REG(&cc->chipcontrol_data, val); - - /* Set override in pmu_chip_ctrl[29] */ - W_REG(&cc->chipcontrol_addr, 0); - OR_REG(&cc->chipcontrol_data, (0x01 << 29)); - - /* Power off RCal block */ - W_REG(&cc->chipcontrol_addr, 1); - AND_REG(&cc->chipcontrol_data, ~0x04); - - break; + case BCM4329_CHIP_ID: + /* Optimize resources up/down timers */ + if (ISSIM_ENAB(sih)) { + pmu_res_updown_table = NULL; + pmu_res_updown_table_sz = 0; + } else { + pmu_res_updown_table = bcm4329_res_updown; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4329_res_updown); } - default: + /* Optimize resources dependencies */ + pmu_res_depend_table = bcm4329_res_depend; + pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend); break; - } - /* Return to original core */ - si_setcoreidx(sih, origidx); -} + case BCM4319_CHIP_ID: + /* Optimize resources up/down timers */ + if (ISSIM_ENAB(sih)) { + pmu_res_updown_table = bcm4319a0_res_updown_qt; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4319a0_res_updown_qt); + } else { + pmu_res_updown_table = bcm4319a0_res_updown; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4319a0_res_updown); + } + /* Optimize resources dependancies masks */ + pmu_res_depend_table = bcm4319a0_res_depend; + pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend); + break; -void si_pmu_spuravoid(si_t *sih, u8 spuravoid) -{ - chipcregs_t *cc; - uint origidx, intr_val; - u32 tmp = 0; + case BCM4336_CHIP_ID: + /* Optimize resources up/down timers */ + if (ISSIM_ENAB(sih)) { + pmu_res_updown_table = bcm4336a0_res_updown_qt; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4336a0_res_updown_qt); + } else { + pmu_res_updown_table = bcm4336a0_res_updown; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4336a0_res_updown); + } + /* Optimize resources dependancies masks */ + pmu_res_depend_table = bcm4336a0_res_depend; + pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend); + break; - /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, - &intr_val); - ASSERT(cc != NULL); + case BCM4330_CHIP_ID: + /* Optimize resources up/down timers */ + if (ISSIM_ENAB(sih)) { + pmu_res_updown_table = bcm4330a0_res_updown_qt; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4330a0_res_updown_qt); + } else { + pmu_res_updown_table = bcm4330a0_res_updown; + pmu_res_updown_table_sz = + ARRAY_SIZE(bcm4330a0_res_updown); + } + /* Optimize resources dependancies masks */ + pmu_res_depend_table = bcm4330a0_res_depend; + pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend); + break; - /* force the HT off */ - if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(&cc->max_res_mask); - tmp &= ~RES4336_HT_AVAIL; - W_REG(&cc->max_res_mask, tmp); - /* wait for the ht to really go away */ - SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0), - 10000); - ASSERT((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0); + default: + break; } - /* update the pll changes */ - si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); + /* # resources */ + rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; - /* enable HT back on */ - if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(&cc->max_res_mask); - tmp |= RES4336_HT_AVAIL; - W_REG(&cc->max_res_mask, tmp); + /* Program up/down timers */ + while (pmu_res_updown_table_sz--) { + W_REG(&cc->res_table_sel, + pmu_res_updown_table[pmu_res_updown_table_sz].resnum); + W_REG(&cc->res_updn_timer, + pmu_res_updown_table[pmu_res_updown_table_sz].updown); + } + /* Apply nvram overrides to up/down timers */ + for (i = 0; i < rsrcs; i++) { + snprintf(name, sizeof(name), "r%dt", i); + val = getvar(NULL, name); + if (val == NULL) + continue; + W_REG(&cc->res_table_sel, (u32) i); + W_REG(&cc->res_updn_timer, + (u32) simple_strtoul(val, NULL, 0)); } - /* Return to original core */ - si_restore_core(sih, origidx, intr_val); -} - -static void -si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) -{ - u32 tmp = 0; - u8 phypll_offset = 0; - u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 }; - u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc }; - - switch (sih->chip) { - case BCM5357_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: + /* Program resource dependencies table */ + while (pmu_res_depend_table_sz--) { + if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL + && !(pmu_res_depend_table[pmu_res_depend_table_sz]. + filter) (sih)) + continue; + for (i = 0; i < rsrcs; i++) { + if ((pmu_res_depend_table[pmu_res_depend_table_sz]. + res_mask & PMURES_BIT(i)) == 0) + continue; + W_REG(&cc->res_table_sel, i); + switch (pmu_res_depend_table[pmu_res_depend_table_sz]. + action) { + case RES_DEPEND_SET: + W_REG(&cc->res_dep_mask, + pmu_res_depend_table + [pmu_res_depend_table_sz].depend_mask); + break; + case RES_DEPEND_ADD: + OR_REG(&cc->res_dep_mask, + pmu_res_depend_table + [pmu_res_depend_table_sz].depend_mask); + break; + case RES_DEPEND_REMOVE: + AND_REG(&cc->res_dep_mask, + ~pmu_res_depend_table + [pmu_res_depend_table_sz].depend_mask); + break; + default: + break; + } + } + } + /* Apply nvram overrides to dependancies masks */ + for (i = 0; i < rsrcs; i++) { + snprintf(name, sizeof(name), "r%dd", i); + val = getvar(NULL, name); + if (val == NULL) + continue; + W_REG(&cc->res_table_sel, (u32) i); + W_REG(&cc->res_dep_mask, + (u32) simple_strtoul(val, NULL, 0)); + } - /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */ - phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0; + /* Determine min/max rsrc masks */ + si_pmu_res_masks(sih, &min_mask, &max_mask); - /* RMW only the P1 divider */ - W_REG(&cc->pllcontrol_addr, - PMU1_PLL0_PLLCTL0 + phypll_offset); - tmp = R_REG(&cc->pllcontrol_data); - tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); - tmp |= - (bcm5357_bcm43236_p1div[spuravoid] << - PMU1_PLL0_PC0_P1DIV_SHIFT); - W_REG(&cc->pllcontrol_data, tmp); + /* It is required to program max_mask first and then min_mask */ - /* RMW only the int feedback divider */ - W_REG(&cc->pllcontrol_addr, - PMU1_PLL0_PLLCTL2 + phypll_offset); - tmp = R_REG(&cc->pllcontrol_data); - tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); - tmp |= - (bcm5357_bcm43236_ndiv[spuravoid]) << - PMU1_PLL0_PC2_NDIV_INT_SHIFT; - W_REG(&cc->pllcontrol_data, tmp); + /* Program max resource mask */ - tmp = 1 << 10; - break; + if (max_mask) + W_REG(&cc->max_res_mask, max_mask); - case BCM4331_CHIP_ID: - if (spuravoid == 2) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0FC00a08); - } else if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600a08); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - } - tmp = 1 << 10; - break; + /* Program min resource mask */ - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM6362_CHIP_ID: - if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500010); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x000C0C06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x2001E920); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100010); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x000c0c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } - tmp = 1 << 10; - break; + if (min_mask) + W_REG(&cc->min_res_mask, min_mask); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100008); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x0c000c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888855); + /* Add some delay; allow resources to come up and settle. */ + mdelay(2); - tmp = 1 << 10; - break; + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} - case BCM4716_CHIP_ID: - case BCM4748_CHIP_ID: - case BCM47162_CHIP_ID: - if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500060); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x080C0C06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x2001E924); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100060); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x080c0c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } +u32 si_pmu_measure_alpclk(si_t *sih) +{ + chipcregs_t *cc; + uint origidx; + u32 alp_khz; - tmp = 3 << 9; - break; + if (sih->pmurev < 10) + return 0; - case BCM4319_CHIP_ID: - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100070); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x1014140a); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888854); + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); - if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x05201828); - } else { /* enable 40/80/160Mhz clock mode */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x05001828); - } - break; - case BCM4336_CHIP_ID: - /* Looks like these are only for default xtal freq 26MHz */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x02100020); + if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) { + u32 ilp_ctr, alp_hz; - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x0C0C0C0C); + /* + * Enable the reg to measure the freq, + * in case it was disabled before + */ + W_REG(&cc->pmu_xtalfreq, + 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x01240C0C); + /* Delay for well over 4 ILP clocks */ + udelay(1000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x202C2820); + /* Read the latched number of ALP ticks per 4 ILP ticks */ + ilp_ctr = + R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888825); + /* + * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT + * bit to save power + */ + W_REG(&cc->pmu_xtalfreq, 0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - if (spuravoid == 1) { - W_REG(&cc->pllcontrol_data, 0x00EC4EC4); - } else { - W_REG(&cc->pllcontrol_data, 0x00762762); - } + /* Calculate ALP frequency */ + alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; - tmp = PCTL_PLL_PLLCTL_UPD; - break; + /* + * Round to nearest 100KHz, and at + * the same time convert to KHz + */ + alp_khz = (alp_hz + 50000) / 100000 * 100; + } else + alp_khz = 0; - default: - PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", __func__, bcm_chipname(sih->chip, chn, 8))); - break; - } + /* Return to original core */ + ai_setcoreidx(sih, origidx); - tmp |= R_REG(&cc->pmucontrol); - W_REG(&cc->pmucontrol, tmp); + return alp_khz; } bool si_pmu_is_otp_powered(si_t *sih) @@ -2447,9 +1829,8 @@ bool si_pmu_is_otp_powered(si_t *sih) bool st; /* Remember original core before switch to chipc */ - idx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); + idx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { case BCM4329_CHIP_ID: @@ -2486,190 +1867,63 @@ bool si_pmu_is_otp_powered(si_t *sih) } /* Return to original core */ - si_setcoreidx(sih, idx); + ai_setcoreidx(sih, idx); return st; } -void si_pmu_sprom_enable(si_t *sih, bool enable) +/* power up/down OTP through PMU resources */ +void si_pmu_otp_power(si_t *sih, bool on) { chipcregs_t *cc; uint origidx; + u32 rsrcs = 0; /* rsrcs to turn on/off OTP power */ - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - /* Return to original core */ - si_setcoreidx(sih, origidx); -} - -/* initialize PMU chip controls and other chip level stuff */ -void si_pmu_chip_init(si_t *sih) -{ - uint origidx; - - ASSERT(sih->cccaps & CC_CAP_PMU); - -#ifdef CHIPC_UART_ALWAYS_ON - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), - CCS_FORCEALP, CCS_FORCEALP); -#endif /* CHIPC_UART_ALWAYS_ON */ - - /* Gate off SPROM clock and chip select signals */ - si_pmu_sprom_enable(sih, false); - - /* Remember original core */ - origidx = si_coreidx(sih); - - /* Return to original core */ - si_setcoreidx(sih, origidx); -} + /* Don't do anything if OTP is disabled */ + if (ai_is_otp_disabled(sih)) + return; -/* initialize PMU switch/regulators */ -void si_pmu_swreg_init(si_t *sih) -{ - ASSERT(sih->cccaps & CC_CAP_PMU); + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); switch (sih->chip) { + case BCM4329_CHIP_ID: + rsrcs = PMURES_BIT(RES4329_OTP_PU); + break; + case BCM4319_CHIP_ID: + rsrcs = PMURES_BIT(RES4319_OTP_PU); + break; case BCM4336_CHIP_ID: - /* Reduce CLDO PWM output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); - /* Reduce CLDO BURST output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST, - 0xe); - /* Reduce LNLDO1 output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe); - if (sih->chiprev == 0) - si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); + rsrcs = PMURES_BIT(RES4336_OTP_PU); break; - case BCM4330_CHIP_ID: - /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0); + rsrcs = PMURES_BIT(RES4330_OTP_PU); break; default: break; } -} - -void si_pmu_radio_enable(si_t *sih, bool enable) -{ - ASSERT(sih->cccaps & CC_CAP_PMU); - - switch (sih->chip) { - case BCM4319_CHIP_ID: - if (enable) - si_write_wrapperreg(sih, AI_OOBSELOUTB74, - (u32) 0x868584); - else - si_write_wrapperreg(sih, AI_OOBSELOUTB74, - (u32) 0x060584); - break; - } -} - -/* Wait for a particular clock level to be on the backplane */ -u32 -si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - if (delay) - SPINWAIT(((R_REG(&cc->pmustatus) & clk) != clk), delay); - - /* Return to original core */ - si_setcoreidx(sih, origidx); - - return R_REG(&cc->pmustatus) & clk; -} - -/* - * Measures the ALP clock frequency in KHz. Returns 0 if not possible. - * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal. - */ - -#define EXT_ILP_HZ 32768 - -u32 si_pmu_measure_alpclk(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - u32 alp_khz; - - if (sih->pmurev < 10) - return 0; - - ASSERT(sih->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); - cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc != NULL); - - if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) { - u32 ilp_ctr, alp_hz; - - /* Enable the reg to measure the freq, in case disabled before */ - W_REG(&cc->pmu_xtalfreq, - 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); - - /* Delay for well over 4 ILP clocks */ - udelay(1000); - - /* Read the latched number of ALP ticks per 4 ILP ticks */ - ilp_ctr = - R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; - /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */ - W_REG(&cc->pmu_xtalfreq, 0); + if (rsrcs != 0) { + u32 otps; - /* Calculate ALP frequency */ - alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; + /* Figure out the dependancies (exclude min_res_mask) */ + u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true); + u32 min_mask = 0, max_mask = 0; + si_pmu_res_masks(sih, &min_mask, &max_mask); + deps &= ~min_mask; + /* Turn on/off the power */ + if (on) { + OR_REG(&cc->min_res_mask, (rsrcs | deps)); + SPINWAIT(!(R_REG(&cc->res_state) & rsrcs), + PMU_MAX_TRANSITION_DLY); + } else { + AND_REG(&cc->min_res_mask, ~(rsrcs | deps)); + } - /* Round to nearest 100KHz, and at the same time convert to KHz */ - alp_khz = (alp_hz + 50000) / 100000 * 100; - } else - alp_khz = 0; + SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) != + (on ? OTPS_READY : 0)), 100); + } /* Return to original core */ - si_setcoreidx(sih, origidx); - - return alp_khz; -} - -static void si_pmu_set_4330_plldivs(si_t *sih) -{ - u32 FVCO = si_pmu1_pllfvco0(sih) / 1000; - u32 m1div, m2div, m3div, m4div, m5div, m6div; - u32 pllc1, pllc2; - - m2div = m3div = m4div = m6div = FVCO / 80; - m5div = FVCO / 160; - - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - m1div = FVCO / 80; - else - m1div = FVCO / 90; - pllc1 = - (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << - PMU1_PLL0_PC1_M2DIV_SHIFT) | - (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << - PMU1_PLL0_PC1_M4DIV_SHIFT); - si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1); - - pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0); - pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK); - pllc2 |= - ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | - (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT)); - si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2); + ai_setcoreidx(sih, origidx); } diff --git a/drivers/staging/brcm80211/include/hndpmu.h b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h index 3eea1f9fbc39..bd5b809b2e31 100644 --- a/drivers/staging/brcm80211/include/hndpmu.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h @@ -14,9 +14,17 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _hndpmu_h_ -#define _hndpmu_h_ +#ifndef WLC_PMU_H_ +#define WLC_PMU_H_ + +#include <linux/types.h> + +#include <aiutils.h> + +/* + * LDO selections used in si_pmu_set_ldo_voltage + */ #define SET_LDO_VOLTAGE_LDO1 1 #define SET_LDO_VOLTAGE_LDO2 2 #define SET_LDO_VOLTAGE_LDO3 3 @@ -28,41 +36,23 @@ #define SET_LDO_VOLTAGE_LNLDO1 9 #define SET_LDO_VOLTAGE_LNLDO2_SEL 10 +extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage); +extern u16 si_pmu_fast_pwrup_delay(si_t *sih); +extern void si_pmu_sprom_enable(si_t *sih, bool enable); +extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_ilp_clock(si_t *sih); +extern u32 si_pmu_alp_clock(si_t *sih); +extern void si_pmu_pllupd(si_t *sih); +extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid); +extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern void si_pmu_init(si_t *sih); extern void si_pmu_chip_init(si_t *sih); extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq); extern void si_pmu_res_init(si_t *sih); extern void si_pmu_swreg_init(si_t *sih); - -extern u32 si_pmu_force_ilp(si_t *sih, bool force); - -extern u32 si_pmu_si_clock(si_t *sih); -extern u32 si_pmu_cpu_clock(si_t *sih); -extern u32 si_pmu_mem_clock(si_t *sih); -extern u32 si_pmu_alp_clock(si_t *sih); -extern u32 si_pmu_ilp_clock(si_t *sih); - -extern void si_pmu_set_switcher_voltage(si_t *sih, - u8 bb_voltage, u8 rf_voltage); -extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage); -extern u16 si_pmu_fast_pwrup_delay(si_t *sih); -extern void si_pmu_rcal(si_t *sih); -extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid); - -extern bool si_pmu_is_otp_powered(si_t *sih); extern u32 si_pmu_measure_alpclk(si_t *sih); - -extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_sprom_enable(si_t *sih, bool enable); - -extern void si_pmu_radio_enable(si_t *sih, bool enable); -extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay); - +extern bool si_pmu_is_otp_powered(si_t *sih); extern void si_pmu_otp_power(si_t *sih, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength); -#endif /* _hndpmu_h_ */ +#endif /* WLC_PMU_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index b956c23fa467..9334deacda12 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -59,6 +59,10 @@ */ #define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ +/* rate related definitions */ +#define WLC_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */ +#define WLC_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ + /* legacy rx Antenna diversity for SISO rates */ #define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ #define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ @@ -92,6 +96,8 @@ #define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ #endif /* AIDMAPSZ */ +struct ieee80211_tx_queue_params; + typedef struct wlc_tunables { int ntxd; /* size of tx descriptor table */ int nrxd; /* size of rx descriptor table */ @@ -478,7 +484,7 @@ extern const u8 wme_fifo2ac[]; #define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ /* common functions for every port */ -extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, +extern void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, bool piomode, void *regsva, uint bustype, void *btparam, uint *perr); extern uint wlc_detach(struct wlc_info *wlc); @@ -499,8 +505,6 @@ extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); extern bool wlc_intrsupd(struct wlc_info *wlc); extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); -extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, - void *p, uint ac); extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw); extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, @@ -508,6 +512,8 @@ extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, struct wlc_if *wlcif); extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif); +extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); + /* helper functions */ extern void wlc_statsupd(struct wlc_info *wlc); extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); @@ -515,24 +521,14 @@ extern int wlc_get_header_len(void); extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, const u8 *addr); -extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, +extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, + const struct ieee80211_tx_queue_params *arg, bool suspend); - extern struct wlc_pub *wlc_pub(void *wlc); /* common functions for every port */ -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); - -extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size); -extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size); -extern void wlc_corereset(struct wlc_info *wlc, u32 flags); extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands); -extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands); -extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); @@ -543,11 +539,8 @@ extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, /* wlc_phy.c helper functions */ extern void wlc_set_ps_ctrl(struct wlc_info *wlc); extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); -extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); /* ioctl */ -extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, - s8 *arg); extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, bool set); @@ -562,31 +555,12 @@ extern void wlc_enable_mac(struct wlc_info *wlc); extern void wlc_associate_upd(struct wlc_info *wlc, bool state); extern void wlc_scan_start(struct wlc_info *wlc); extern void wlc_scan_stop(struct wlc_info *wlc); - -static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, - uint *arg) -{ - return wlc_iovar_getint(wlc, name, (int *)arg); -} - -static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name, - u8 *arg) -{ - return wlc_iovar_gets8(wlc, name, (s8 *) arg); -} - -static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name, - uint arg) -{ - return wlc_iovar_setint(wlc, name, (int)arg); -} +extern int wlc_get_curband(struct wlc_info *wlc); +extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop); #if defined(BCMDBG) extern int wlc_iocregchk(struct wlc_info *wlc, uint band); #endif -#if defined(BCMDBG) -extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); -#endif /* helper functions */ extern bool wlc_check_radio_disabled(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index d284f1ac49cc..87b252d6a7f5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -19,7 +19,7 @@ #include <proto/802.11.h> #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> @@ -304,7 +304,7 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, for (i = 0; i < count; i++) { /* mask off "basic rate" bit, WLC_RATE_FLAG */ - r = (int)rs->rates[i] & RATE_MASK; + r = (int)rs->rates[i] & WLC_RATE_MASK; if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { continue; } @@ -314,8 +314,7 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, /* fill out the rates in order, looking at only supported rates */ count = 0; for (i = 0; i < hw_rs->count; i++) { - r = hw_rs->rates[i] & RATE_MASK; - ASSERT(r <= WLC_MAXRATE); + r = hw_rs->rates[i] & WLC_RATE_MASK; if (rateset[r]) rs->rates[count++] = rateset[r]; } @@ -333,7 +332,7 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, } /* calculate the rate of a rx'd frame and return it as a ratespec */ -ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) +ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) { int phy_type; ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; @@ -364,8 +363,7 @@ ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) case PRXS0_STDN: /* fallthru */ default: - /* not supported */ - ASSERT(0); + /* not supported, error condition */ break; } if (PLCP3_ISSGI(plcp[3])) @@ -407,9 +405,9 @@ wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, r = src->rates[i]; if (basic_only && !(r & WLC_RATE_FLAG)) continue; - if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK))) + if ((rates == WLC_RATES_CCK) && IS_OFDM((r & WLC_RATE_MASK))) continue; - if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK))) + if ((rates == WLC_RATES_OFDM) && IS_CCK((r & WLC_RATE_MASK))) continue; dst->rates[count++] = r & xmask; } @@ -451,7 +449,7 @@ wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) { rs_dflt = &cck_ofdm_rates; } else { - ASSERT(0); /* should not happen */ + /* should not happen, error condition */ rs_dflt = &cck_rates; /* force cck */ } @@ -468,7 +466,7 @@ wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, mcsallow ? txstreams : 1); } -s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate) +s16 wlc_rate_legacy_phyctl(uint rate) { uint i; for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h index 25ba2a423639..5575e83bdc69 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h @@ -54,11 +54,8 @@ extern const mcs_info_t mcs_table[]; (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) #define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) -#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */ - -/* Macros to use the rate_info table */ -#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ -#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ +/* Macro to use the rate_info table */ +#define WLC_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ #define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ @@ -115,9 +112,11 @@ typedef u32 ratespec_t; /* Rate info table; takes a legacy rate or ratespec_t */ #define IS_MCS(r) (r & RSPEC_MIMORATE) #define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) -#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \ - ((r) & RATE_MASK) == WLC_RATE_2M || \ - ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M)) +#define IS_CCK(r) (!IS_MCS(r) && ( \ + ((r) & WLC_RATE_MASK) == WLC_RATE_1M || \ + ((r) & WLC_RATE_MASK) == WLC_RATE_2M || \ + ((r) & WLC_RATE_MASK) == WLC_RATE_5M5 || \ + ((r) & WLC_RATE_MASK) == WLC_RATE_11M)) #define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) #define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) #define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h index 73260068898f..f07a891d5d27 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h @@ -17,8 +17,6 @@ #ifndef _wlc_scb_h_ #define _wlc_scb_h_ -extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); - #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ /* structure to store per-tid state for the ampdu initiator */ typedef struct scb_ampdu_tid_ini { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 098fd59ee153..c4f58172182d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -21,9 +21,10 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <bcmwifi.h> +#include <bcmnvram.h> #include <sbhnddma.h> #include "wlc_types.h" @@ -69,9 +70,6 @@ const u8 txcore_default[5] = { static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) { - ASSERT((val == HT_CAP_RX_STBC_NO) - || (val == HT_CAP_RX_STBC_ONE_STREAM)); - /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ if (WLC_STF_SS_STBC_RX(wlc)) { if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) @@ -193,10 +191,8 @@ bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) { - WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", - wlc->pub->unit, __func__, Nsts, core_mask); - - ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); + BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", + wlc->pub->unit, Nsts, core_mask); if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { core_mask = 0; @@ -208,8 +204,6 @@ static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) core_mask = wlc->stf->txchain; } - ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask)); - wlc->stf->txcore[Nsts] = core_mask; /* Nsts = 1..4, txcore index = 1..4 */ if (Nsts == 1) { @@ -225,7 +219,7 @@ static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) } } - return BCME_OK; + return 0; } static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) @@ -233,7 +227,7 @@ static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) int i; u8 core_mask = 0; - WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); + BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); wlc->stf->spatial_policy = (s8) val; for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { @@ -241,7 +235,7 @@ static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) wlc->stf->txchain : txcore_default[i]; wlc_stf_txcore_set(wlc, (u8) i, core_mask); } - return BCME_OK; + return 0; } int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) @@ -251,16 +245,16 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) uint i; if (wlc->stf->txchain == txchain) - return BCME_OK; + return 0; if ((txchain & ~wlc->stf->hw_txchain) || !(txchain & wlc->stf->hw_txchain)) - return BCME_RANGE; + return -EINVAL; /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ txstreams = (u8) WLC_BITSCNT(txchain); if (txstreams > MAX_STREAMS_SUPPORTED) - return BCME_RANGE; + return -EINVAL; if (txstreams == 1) { for (i = 0; i < NBANDS(wlc); i++) @@ -269,21 +263,25 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != PHY_TXC1_MODE_SISO)) { if (!force) - return BCME_ERROR; + return -EBADE; /* over-write the override rspec */ if (RSPEC_STF(wlc->bandstate[i]->rspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->rspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", - __func__); + wiphy_err(wlc->wiphy, "%s(): temp " + "sense override non-SISO " + "rspec_override\n", + __func__); } if (RSPEC_STF (wlc->bandstate[i]->mrspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->mrspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", - __func__); + wiphy_err(wlc->wiphy, "%s(): temp " + "sense override non-SISO " + "mrspec_override\n", + __func__); } } } @@ -303,7 +301,7 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); - return BCME_OK; + return 0; } /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ @@ -319,9 +317,6 @@ int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) if (WLC_STBC_CAP_PHY(wlc) && wlc->stf->ss_algosel_auto && (wlc->stf->ss_algo_channel != (u16) -1)) { - ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD) - || isset(&wlc->stf->ss_algo_channel, - PHY_TXC1_MODE_SISO)); upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) || isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO @@ -371,11 +366,11 @@ void wlc_stf_detach(struct wlc_info *wlc) int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) { - int bcmerror = BCME_OK; + int bcmerror = 0; /* when there is only 1 tx_streams, don't allow to change the txant */ if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE); + return ((val == wlc->stf->txant) ? bcmerror : -EINVAL); switch (val) { case -1: @@ -391,11 +386,11 @@ int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) val = ANT_TX_LAST_RX; break; default: - bcmerror = BCME_RANGE; + bcmerror = -EINVAL; break; } - if (bcmerror == BCME_OK) + if (bcmerror == 0) wlc->stf->txant = (s8) val; return bcmerror; @@ -421,9 +416,6 @@ static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) s8 txant; txant = (s8) wlc->stf->txant; - ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1 - || txant == ANT_TX_LAST_RX); - if (WLC_PHY_11N_CAP(wlc->band)) { if (txant == ANT_TX_FORCE_0) { wlc->stf->phytxant = PHY_TXC_ANT_0; @@ -439,8 +431,8 @@ static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; else { - /* keep this assert to catch out of sync wlc->stf->txcore */ - ASSERT(wlc->stf->txchain > 0); + /* catch out of sync wlc->stf->txcore */ + WARN_ON(wlc->stf->txchain <= 0); wlc->stf->phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; } @@ -504,7 +496,6 @@ static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) u16 phytxant = wlc->stf->phytxant; if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { - ASSERT(wlc->stf->txstreams > 1); phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; } else if (wlc->stf->txant == ANT_TX_DEF) phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; @@ -524,7 +515,6 @@ u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) /* for non-siso rates or default setting, use the available chains */ if (WLCISNPHY(wlc->band)) { - ASSERT(wlc->stf->txchain != 0); phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); mask = PHY_TXC_HTANT_MASK; } diff --git a/drivers/staging/brcm80211/include/aidmp.h b/drivers/staging/brcm80211/include/aidmp.h index d33f0202cec4..7e0ce8f24348 100644 --- a/drivers/staging/brcm80211/include/aidmp.h +++ b/drivers/staging/brcm80211/include/aidmp.h @@ -292,7 +292,7 @@ typedef volatile struct _aidmp { #define AI_OOBDINWIDTH 0x364 #define AI_OOBDOUTWIDTH 0x368 -#if defined(IL_BIGENDIAN) && defined(BCMHND74K) +#if defined(__BIG_ENDIAN) && defined(BCMHND74K) /* Selective swapped defines for those registers we need in * big-endian code. */ @@ -303,7 +303,7 @@ typedef volatile struct _aidmp { #define AI_RESETCTRL 0x804 #define AI_RESETSTATUS 0x800 -#else /* !IL_BIGENDIAN || !BCMHND74K */ +#else /* !__BIG_ENDIAN || !BCMHND74K */ #define AI_IOCTRLSET 0x400 #define AI_IOCTRLCLEAR 0x404 @@ -312,7 +312,7 @@ typedef volatile struct _aidmp { #define AI_RESETCTRL 0x800 #define AI_RESETSTATUS 0x804 -#endif /* IL_BIGENDIAN && BCMHND74K */ +#endif /* __BIG_ENDIAN && BCMHND74K */ #define AI_IOCTRLWIDTH 0x700 #define AI_IOSTATUSWIDTH 0x704 diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 22a389e1d511..55631f367436 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -36,12 +36,6 @@ #define AUTO (-1) /* Auto = -1 */ -#ifdef mips -#define BCMFASTPATH __attribute__ ((__section__(".text.fastpath"))) -#else -#define BCMFASTPATH -#endif - /* Bus types */ #define SI_BUS 0 /* SOC Interconnect */ #define PCI_BUS 1 /* PCI target */ @@ -114,12 +108,6 @@ typedef struct { #define BCMEXTRAHDROOM 172 -#ifdef BCMDBG -#ifndef BCMDBG_ASSERT -#define BCMDBG_ASSERT -#endif /* BCMDBG_ASSERT */ -#endif /* BCMDBG */ - /* Macros for doing definition and get/set of bitfields * Usage example, e.g. a three-bit field (bits 4-6): * #define <NAME>_M BITFIELD_MASK(3) diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h index 075883a93529..26947efa83e8 100644 --- a/drivers/staging/brcm80211/include/bcmdevs.h +++ b/drivers/staging/brcm80211/include/bcmdevs.h @@ -17,17 +17,10 @@ #ifndef _BCMDEVS_H #define _BCMDEVS_H -/* PCI vendor IDs */ -#define VENDOR_BROADCOM 0x14e4 - -/* DONGLE VID/PIDs */ -#define BCM_DNGL_VID 0x0a5c -#define BCM_DNGL_BDC_PID 0x0bdc - #define BCM4325_D11DUAL_ID 0x431b #define BCM4325_D11G_ID 0x431c #define BCM4325_D11A_ID 0x431d -#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */ + #define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ #define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ #define BCM4329_D11NDUAL_ID 0x432e @@ -37,22 +30,13 @@ #define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ #define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ + #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 */ -#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */ -#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */ #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ -#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */ -#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */ -#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ -#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ -#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ -#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ -#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ -#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ /* Chip IDs */ #define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ @@ -60,7 +44,6 @@ #define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ #define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ -#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */ #define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */ #define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ #define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ @@ -82,57 +65,23 @@ /* Package IDs */ #define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ #define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ -#define BCM4716_PKG_ID 8 /* 4716 package id */ #define BCM4717_PKG_ID 9 /* 4717 package id */ #define BCM4718_PKG_ID 10 /* 4718 package id */ -#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */ -#define BCM5358U_PKG_ID 8 /* 5358U package id */ -#define BCM5358_PKG_ID 9 /* 5358 package id */ -#define BCM47186_PKG_ID 10 /* 47186 package id */ -#define BCM5357_PKG_ID 11 /* 5357 package id */ -#define BCM5356U_PKG_ID 12 /* 5356U package id */ -#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ #define HDLSIM_PKG_ID 14 /* HDL simulator package id */ #define HWSIM_PKG_ID 15 /* Hardware simulator package id */ -#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */ #define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ -#define BCM4336_WLBGA_PKG_ID 0x8 /* boardflags */ -#define BFL_RESERVED1 0x00000001 #define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication */ -#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ -#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ #define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ -#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ -#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ -#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ #define BFL_FEM 0x00000800 /* Board supports the Front End Module */ #define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BFL_HGPA 0x00002000 /* Board has a high gain PA */ -#define BFL_RESERVED2 0x00004000 -#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ #define BFL_NOPA 0x00010000 /* Board has no PA */ -#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ -#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */ -#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */ -#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ #define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ #define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ #define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ #define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ -#define BFL_FASTPWR 0x08000000 -#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ #define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ -#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ -#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field - * when this flag is set - */ /* boardflags2 */ #define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ @@ -141,16 +90,12 @@ #define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ #define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ #define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ -#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */ #define BFL2_LEGACY 0x00000080 #define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ #define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ #define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */ #define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ #define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */ -#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* using 40Mhz LPF for 20Mhz bandedge channels */ #define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ #define BFL2_IPALVLSHIFT_3P3 0x00020000 #define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ @@ -160,32 +105,19 @@ */ /* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -#define BOARD_GPIO_RESERVED1 0x010 -#define BOARD_GPIO_RESERVED2 0x020 -#define BOARD_GPIO_RESERVED3 0x080 -#define BOARD_GPIO_RESERVED4 0x100 #define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ #define BOARD_GPIO_12 0x1000 /* gpio 12 */ #define BOARD_GPIO_13 0x2000 /* gpio 13 */ -#define BOARD_GPIO_RESERVED5 0x0800 -#define BOARD_GPIO_RESERVED6 0x2000 -#define BOARD_GPIO_RESERVED7 0x4000 -#define BOARD_GPIO_RESERVED8 0x8000 #define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ #define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ #define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ /* power control defines */ #define PLL_DELAY 150 /* us pll on delay */ #define FREF_DELAY 200 /* us fref change delay */ -#define MIN_SLOW_CLK 32 /* us Slow clock period */ #define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ -/* # of GPIO pins */ -#define GPIO_NUMPINS 16 - /* Reference board types */ #define SPI_BOARD 0x0402 diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h index e194131a750e..12645ddf000d 100644 --- a/drivers/staging/brcm80211/include/bcmnvram.h +++ b/drivers/staging/brcm80211/include/bcmnvram.h @@ -30,31 +30,26 @@ struct nvram_header { }; /* - * Get default value for an NVRAM variable - */ -extern char *nvram_default_get(const char *name); - -/* * Initialize NVRAM access. May be unnecessary or undefined on certain * platforms. */ -extern int nvram_init(void *sih); +extern int nvram_init(void); /* * Append a chunk of nvram variables to the global list */ -extern int nvram_append(void *si, char *vars, uint varsz); +extern int nvram_append(char *vars, uint varsz); /* * Check for reset button press for restoring factory defaults. */ -extern int nvram_reset(void *sih); +extern int nvram_reset(void); /* * Disable NVRAM access. May be unnecessary or undefined on certain * platforms. */ -extern void nvram_exit(void *sih); +extern void nvram_exit(void); /* * Get the value of an NVRAM variable. The pointer returned may be @@ -65,12 +60,6 @@ extern void nvram_exit(void *sih); extern char *nvram_get(const char *name); /* - * Read the reset GPIO value from the nvram and set the GPIO - * as input - */ -extern int nvram_resetgpio_init(void *sih); - -/* * Get the value of an NVRAM variable. * @param name name of variable to get * @return value of variable or NUL if undefined @@ -139,14 +128,12 @@ extern int nvram_commit(void); */ extern int nvram_getall(char *nvram_buf, int count); -/* - * returns the crc value of the nvram - * @param nvh nvram header pointer - */ -u8 nvram_calc_crc(struct nvram_header *nvh); - #endif /* _LANGUAGE_ASSEMBLY */ +/* variable access */ +extern char *getvar(char *vars, const char *name); +extern int getintvar(char *vars, const char *name); + /* The NVRAM version number stored as an NVRAM variable */ #define NVRAM_SOFTWARE_VERSION "1" diff --git a/drivers/staging/brcm80211/include/bcmsdpcm.h b/drivers/staging/brcm80211/include/bcmsdpcm.h index 48699471fac8..5175e67a6d28 100644 --- a/drivers/staging/brcm80211/include/bcmsdpcm.h +++ b/drivers/staging/brcm80211/include/bcmsdpcm.h @@ -186,7 +186,7 @@ typedef volatile struct { * Shared structure between dongle and the host. * The structure contains pointers to trap or assert information. */ -#define SDPCM_SHARED_VERSION 0x0001 +#define SDPCM_SHARED_VERSION 0x0002 #define SDPCM_SHARED_VERSION_MASK 0x00FF #define SDPCM_SHARED_ASSERT_BUILT 0x0100 #define SDPCM_SHARED_ASSERT 0x0200 @@ -200,6 +200,7 @@ typedef struct { u32 assert_line; u32 console_addr; /* Address of hndrte_cons_t */ u32 msgtrace_addr; + u8 tag[32]; } sdpcm_shared_t; extern sdpcm_shared_t sdpcm_shared; diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h index 4768968f910a..4666afd883a5 100644 --- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h +++ b/drivers/staging/brcm80211/include/bcmsrom_fmt.h @@ -105,7 +105,7 @@ /* SROM Rev 4: Reallocate the software part of the srom to accommodate * MIMO features. It assumes up to two PCIE functions and 440 bytes - * of useable srom i.e. the useable storage in chips with OTP that + * of usable srom i.e. the usable storage in chips with OTP that * implements hardware redundancy. */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index fc2a2a910129..17683f2f785f 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -74,7 +74,7 @@ #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) /* fn(pkt, arg). return true if pkt belongs to if */ - typedef bool(*ifpkt_cb_t) (void *, int); +typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *); /* operations on a specific precedence in packet queue */ @@ -87,30 +87,26 @@ #define pktq_ppeek(pq, prec) ((pq)->q[prec].head) #define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) -extern struct sk_buff *pktq_penq(struct pktq *pq, int prec, +extern struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p); -extern struct sk_buff *pktq_penq_head(struct pktq *pq, int prec, +extern struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p); -extern struct sk_buff *pktq_pdeq(struct pktq *pq, int prec); -extern struct sk_buff *pktq_pdeq_tail(struct pktq *pq, int prec); +extern struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec); +extern struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec); /* packet primitives */ -extern struct sk_buff *pkt_buf_get_skb(uint len); -extern void pkt_buf_free_skb(struct sk_buff *skb); +extern struct sk_buff *bcm_pkt_buf_get_skb(uint len); +extern void bcm_pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ -#ifdef BRCM_FULLMAC - extern void pktq_pflush(struct pktq *pq, int prec, - bool dir); -#else - extern void pktq_pflush(struct pktq *pq, int prec, - bool dir, ifpkt_cb_t fn, int arg); -#endif /* BRCM_FULLMAC */ +extern void bcm_pktq_pflush(struct pktq *pq, int prec, + bool dir, ifpkt_cb_t fn, void *arg); /* operations on a set of precedences in packet queue */ -extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); +extern int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp); +extern struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp, + int *prec_out); /* operations on packet queue as a whole */ @@ -121,46 +117,38 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #define pktq_empty(pq) ((pq)->len == 0) /* operations for single precedence queues */ -#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) +#define pktenq(pq, p) bcm_pktq_penq(((struct pktq *)pq), 0, (p)) +#define pktenq_head(pq, p) bcm_pktq_penq_head(((struct pktq *)pq), 0, (p)) +#define pktdeq(pq) bcm_pktq_pdeq(((struct pktq *)pq), 0) +#define pktdeq_tail(pq) bcm_pktq_pdeq_tail(((struct pktq *)pq), 0) +#define pktqinit(pq, len) bcm_pktq_init(((struct pktq *)pq), 1, len) - extern void pktq_init(struct pktq *pq, int num_prec, int max_len); +extern void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ - extern struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out); -#ifdef BRCM_FULLMAC - extern void pktq_flush(struct pktq *pq, bool dir); -#else - extern void pktq_flush(struct pktq *pq, bool dir, - ifpkt_cb_t fn, int arg); -#endif +extern struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out); +extern void bcm_pktq_flush(struct pktq *pq, bool dir, + ifpkt_cb_t fn, void *arg); /* externs */ /* packet */ - extern uint pktfrombuf(struct sk_buff *p, - uint offset, int len, unsigned char *buf); - extern uint pkttotlen(struct sk_buff *p); +extern uint bcm_pktfrombuf(struct sk_buff *p, + uint offset, int len, unsigned char *buf); +extern uint bcm_pkttotlen(struct sk_buff *p); /* ethernet address */ - extern int bcm_ether_atoe(char *p, u8 *ea); +extern int bcm_ether_atoe(char *p, u8 *ea); /* ip address */ struct ipv4_addr; extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); -/* variable access */ - extern char *getvar(char *vars, const char *name); - extern int getintvar(char *vars, const char *name); #ifdef BCMDBG - extern void prpkt(const char *msg, struct sk_buff *p0); +extern void bcm_prpkt(const char *msg, struct sk_buff *p0); #else -#define prpkt(a, b) +#define bcm_prpkt(a, b) #endif /* BCMDBG */ #define bcm_perf_enable() -#define bcmstats(fmt) #define bcmlog(fmt, a1, a2) #define bcmdumplog(buf, size) (*buf = '\0') #define bcmdumplogent(buf, idx) -1 @@ -241,107 +229,6 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* ** driver/apps-shared section ** */ #define BCME_STRLEN 64 /* Max string length for BCM errors */ -#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) - -/* - * error codes could be added but the defined ones shouldn't be changed/deleted - * these error codes are exposed to the user code - * when ever a new error code is added to this list - * please update errorstring table with the related error string and - * update osl files with os specific errorcode map -*/ - -#define BCME_OK 0 /* Success */ -#define BCME_ERROR -1 /* Error generic */ -#define BCME_BADARG -2 /* Bad Argument */ -#define BCME_BADOPTION -3 /* Bad option */ -#define BCME_NOTUP -4 /* Not up */ -#define BCME_NOTDOWN -5 /* Not down */ -#define BCME_NOTAP -6 /* Not AP */ -#define BCME_NOTSTA -7 /* Not STA */ -#define BCME_BADKEYIDX -8 /* BAD Key Index */ -#define BCME_RADIOOFF -9 /* Radio Off */ -#define BCME_NOTBANDLOCKED -10 /* Not band locked */ -#define BCME_NOCLK -11 /* No Clock */ -#define BCME_BADRATESET -12 /* BAD Rate valueset */ -#define BCME_BADBAND -13 /* BAD Band */ -#define BCME_BUFTOOSHORT -14 /* Buffer too short */ -#define BCME_BUFTOOLONG -15 /* Buffer too long */ -#define BCME_BUSY -16 /* Busy */ -#define BCME_NOTASSOCIATED -17 /* Not Associated */ -#define BCME_BADSSIDLEN -18 /* Bad SSID len */ -#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ -#define BCME_BADCHAN -20 /* Bad Channel */ -#define BCME_BADADDR -21 /* Bad Address */ -#define BCME_NORESOURCE -22 /* Not Enough Resources */ -#define BCME_UNSUPPORTED -23 /* Unsupported */ -#define BCME_BADLEN -24 /* Bad length */ -#define BCME_NOTREADY -25 /* Not Ready */ -#define BCME_EPERM -26 /* Not Permitted */ -#define BCME_NOMEM -27 /* No Memory */ -#define BCME_ASSOCIATED -28 /* Associated */ -#define BCME_RANGE -29 /* Not In Range */ -#define BCME_NOTFOUND -30 /* Not Found */ -#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ -#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ -#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ -#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ -#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ -#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ -#define BCME_VERSION -37 /* Incorrect version */ -#define BCME_TXFAIL -38 /* TX failure */ -#define BCME_RXFAIL -39 /* RX failure */ -#define BCME_NODEVICE -40 /* Device not present */ -#define BCME_NMODE_DISABLED -41 /* NMODE disabled */ -#define BCME_NONRESIDENT -42 /* access to nonresident overlay */ -#define BCME_LAST BCME_NONRESIDENT - -/* These are collection of BCME Error strings */ -#define BCMERRSTRINGTABLE { \ - "OK", \ - "Undefined error", \ - "Bad Argument", \ - "Bad Option", \ - "Not up", \ - "Not down", \ - "Not AP", \ - "Not STA", \ - "Bad Key Index", \ - "Radio Off", \ - "Not band locked", \ - "No clock", \ - "Bad Rate valueset", \ - "Bad Band", \ - "Buffer too short", \ - "Buffer too long", \ - "Busy", \ - "Not Associated", \ - "Bad SSID len", \ - "Out of Range Channel", \ - "Bad Channel", \ - "Bad Address", \ - "Not Enough Resources", \ - "Unsupported", \ - "Bad length", \ - "Not Ready", \ - "Not Permitted", \ - "No Memory", \ - "Associated", \ - "Not In Range", \ - "Not Found", \ - "WME Not Enabled", \ - "TSPEC Not Found", \ - "ACM Not Supported", \ - "Not WME Association", \ - "SDIO Bus Error", \ - "Dongle Not Accessible", \ - "Incorrect version", \ - "TX Failure", \ - "RX Failure", \ - "Device Not Present", \ - "NMODE Disabled", \ - "Nonresident overlay access", \ -} #ifndef ABS #define ABS(a) (((a) < 0) ? -(a) : (a)) @@ -358,16 +245,6 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #define REG_MAP(pa, size) (void *)(0) #endif -extern u32 g_assert_type; - -#if defined(BCMDBG_ASSERT) -#define ASSERT(exp) \ - do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); -#else -#define ASSERT(exp) do {} while (0) -#endif /* defined(BCMDBG_ASSERT) */ - /* register access macros */ #if defined(BCMSDIO) #ifdef BRCM_FULLMAC @@ -399,7 +276,7 @@ extern void osl_assert(char *exp, char *file, int line); #define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* register access macros */ -#ifndef IL_BIGENDIAN +#ifndef __BIG_ENDIAN #ifndef __mips__ #define R_REG(r) (\ SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ @@ -450,7 +327,7 @@ extern void osl_assert(char *exp, char *file, int line); }, \ (OSL_WRITE_REG(r, v))); \ } while (0) -#else /* IL_BIGENDIAN */ +#else /* __BIG_ENDIAN */ #define R_REG(r) (\ SELECT_BUS_READ( \ ({ \ @@ -487,7 +364,7 @@ extern void osl_assert(char *exp, char *file, int line); }, \ (OSL_WRITE_REG(r, v))); \ } while (0) -#endif /* IL_BIGENDIAN */ +#endif /* __BIG_ENDIAN */ #define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) #define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) @@ -590,8 +467,7 @@ extern void osl_assert(char *exp, char *file, int line); /* externs */ /* crc */ - extern u8 hndcrc8(u8 *p, uint nbytes, u8 crc); - extern u16 hndcrc16(u8 *p, uint nbytes, u16 crc); +extern u8 bcm_crc8(u8 *p, uint nbytes, u8 crc); /* format/print */ #if defined(BCMDBG) extern int bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, @@ -599,12 +475,9 @@ extern void osl_assert(char *exp, char *file, int line); extern int bcm_format_hex(char *str, const void *bytes, int len); #endif extern char *bcm_chipname(uint chipid, char *buf, uint len); - extern void prhex(const char *msg, unsigned char *buf, uint len); extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -/* bcmerror */ - extern const char *bcmerrorstr(int bcmerror); /* multi-bool data type: set of bools, mbool is true if any is set */ typedef u32 mbool; diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h index 4a0f976afaa4..a573ebff7680 100644 --- a/drivers/staging/brcm80211/include/bcmwifi.h +++ b/drivers/staging/brcm80211/include/bcmwifi.h @@ -134,14 +134,14 @@ typedef u16 chanspec_t; * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -extern bool wf_chspec_malformed(chanspec_t chanspec); +extern bool bcm_chspec_malformed(chanspec_t chanspec); /* * This function returns the channel number that control traffic is being sent on, for legacy * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ * sideband depending on the chanspec selected */ -extern u8 wf_chspec_ctlchan(chanspec_t chspec); +extern u8 bcm_chspec_ctlchan(chanspec_t chspec); /* * Return the channel number for a given frequency and base frequency. @@ -162,6 +162,6 @@ extern u8 wf_chspec_ctlchan(chanspec_t chspec); * * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 */ -extern int wf_mhz2channel(uint freq, uint start_factor); +extern int bcm_mhz2channel(uint freq, uint start_factor); #endif /* _bcmwifi_h_ */ diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 5d079e77490e..fbbcb9b5ae62 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -204,4 +204,23 @@ extern const di_fcn_t dma64proc; extern uint dma_addrwidth(si_t *sih, void *dmaregs); void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) (void *pkt, void *arg_a), void *arg_a); + +/* + * DMA(Bug) on some chips seems to declare that the packet is ready, but the + * packet length is not updated yet (by DMA) on the expected time. + * Workaround is to hold processor till DMA updates the length, and stay off + * the bus to allow DMA update the length in buffer + */ +static inline void dma_spin_for_len(uint len, struct sk_buff *head) +{ +#if defined(__mips__) + if (!len) { + while (!(len = *(u16 *) KSEG1ADDR(head->data))) + udelay(1); + + *(u16 *) (head->data) = cpu_to_le16((u16) len); + } +#endif /* defined(__mips__) */ +} + #endif /* _hnddma_h_ */ diff --git a/drivers/staging/brcm80211/util/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h index 9153dcb8160e..9153dcb8160e 100644 --- a/drivers/staging/brcm80211/util/pci_core.h +++ b/drivers/staging/brcm80211/include/pci_core.h diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h index 675554a1d341..d0c617a63c4f 100644 --- a/drivers/staging/brcm80211/include/pcicfg.h +++ b/drivers/staging/brcm80211/include/pcicfg.h @@ -17,508 +17,34 @@ #ifndef _h_pcicfg_ #define _h_pcicfg_ -/* The following inside ifndef's so we don't collide with NTDDK.H */ -#ifndef PCI_MAX_BUS -#define PCI_MAX_BUS 0x100 -#endif -#ifndef PCI_MAX_DEVICES -#define PCI_MAX_DEVICES 0x20 -#endif -#ifndef PCI_MAX_FUNCTION -#define PCI_MAX_FUNCTION 0x8 -#endif +#include <linux/pci_regs.h> -#ifndef PCI_INVALID_VENDORID -#define PCI_INVALID_VENDORID 0xffff -#endif -#ifndef PCI_INVALID_DEVICEID -#define PCI_INVALID_DEVICEID 0xffff -#endif - -/* Convert between bus-slot-function-register and config addresses */ - -#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -#define PCICFG_FUN_SHIFT 8 /* Function shift */ -#define PCICFG_OFF_SHIFT 0 /* Register shift */ - -#define PCICFG_BUS_MASK 0xff /* Bus mask */ -#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -#define PCICFG_FUN_MASK 7 /* Function mask */ -#define PCICFG_OFF_MASK 0xff /* Bus mask */ - -#define PCI_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ - | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ - | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ - | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) - -#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) - -/* PCIE Config space accessing MACROS */ - -#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -#define PCIECFG_OFF_SHIFT 0 /* Register shift */ - -#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -#define PCIECFG_FUN_MASK 7 /* Function mask */ -#define PCIECFG_OFF_MASK 0xfff /* Register mask */ - -#define PCIE_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ - | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ - | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ - | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) - -#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) - -/* The actual config space */ - -#define PCI_BAR_MAX 6 - -#define PCI_ROM_BAR 8 - -#define PCR_RSVDA_MAX 2 - -/* Bits in PCI bars' flags */ - -#define PCIBAR_FLAGS 0xf -#define PCIBAR_IO 0x1 -#define PCIBAR_MEM1M 0x2 -#define PCIBAR_MEM64 0x4 -#define PCIBAR_PREFETCH 0x8 -#define PCIBAR_MEM32_MASK 0xFFFFFF80 - -/* pci config status reg has a bit to indicate that capability ptr is present */ - -#define PCI_CAPPTR_PRESENT 0x0010 - -typedef struct _pci_config_regs { - u16 vendor; - u16 device; - u16 command; - u16 status; - u8 rev_id; - u8 prog_if; - u8 sub_class; - u8 base_class; - u8 cache_line_size; - u8 latency_timer; - u8 header_type; - u8 bist; - u32 base[PCI_BAR_MAX]; - u32 cardbus_cis; - u16 subsys_vendor; - u16 subsys_id; - u32 baserom; - u32 rsvd_a[PCR_RSVDA_MAX]; - u8 int_line; - u8 int_pin; - u8 min_gnt; - u8 max_lat; - u8 dev_dep[192]; -} pci_config_regs; - -#define SZPCR (sizeof (pci_config_regs)) -#define MINSZPCR 64 /* offsetof (dev_dep[0] */ - -/* A structure for the config registers is nice, but in most - * systems the config space is not memory mapped, so we need - * field offsetts. :-( - */ -#define PCI_CFG_VID 0 -#define PCI_CFG_DID 2 -#define PCI_CFG_CMD 4 -#define PCI_CFG_STAT 6 -#define PCI_CFG_REV 8 -#define PCI_CFG_PROGIF 9 -#define PCI_CFG_SUBCL 0xa -#define PCI_CFG_BASECL 0xb -#define PCI_CFG_CLSZ 0xc -#define PCI_CFG_LATTIM 0xd -#define PCI_CFG_HDR 0xe -#define PCI_CFG_BIST 0xf -#define PCI_CFG_BAR0 0x10 -#define PCI_CFG_BAR1 0x14 -#define PCI_CFG_BAR2 0x18 -#define PCI_CFG_BAR3 0x1c -#define PCI_CFG_BAR4 0x20 -#define PCI_CFG_BAR5 0x24 -#define PCI_CFG_CIS 0x28 -#define PCI_CFG_SVID 0x2c -#define PCI_CFG_SSID 0x2e -#define PCI_CFG_ROMBAR 0x30 -#define PCI_CFG_CAPPTR 0x34 -#define PCI_CFG_INT 0x3c -#define PCI_CFG_PIN 0x3d -#define PCI_CFG_MINGNT 0x3e -#define PCI_CFG_MAXLAT 0x3f - -/* Classes and subclasses */ - -typedef enum { - PCI_CLASS_OLD = 0, - PCI_CLASS_DASDI, - PCI_CLASS_NET, - PCI_CLASS_DISPLAY, - PCI_CLASS_MMEDIA, - PCI_CLASS_MEMORY, - PCI_CLASS_BRIDGE, - PCI_CLASS_COMM, - PCI_CLASS_BASE, - PCI_CLASS_INPUT, - PCI_CLASS_DOCK, - PCI_CLASS_CPU, - PCI_CLASS_SERIAL, - PCI_CLASS_INTELLIGENT = 0xe, - PCI_CLASS_SATELLITE, - PCI_CLASS_CRYPT, - PCI_CLASS_DSP, - PCI_CLASS_XOR = 0xfe -} pci_classes; - -typedef enum { - PCI_DASDI_SCSI, - PCI_DASDI_IDE, - PCI_DASDI_FLOPPY, - PCI_DASDI_IPI, - PCI_DASDI_RAID, - PCI_DASDI_OTHER = 0x80 -} pci_dasdi_subclasses; - -typedef enum { - PCI_NET_ETHER, - PCI_NET_TOKEN, - PCI_NET_FDDI, - PCI_NET_ATM, - PCI_NET_OTHER = 0x80 -} pci_net_subclasses; - -typedef enum { - PCI_DISPLAY_VGA, - PCI_DISPLAY_XGA, - PCI_DISPLAY_3D, - PCI_DISPLAY_OTHER = 0x80 -} pci_display_subclasses; - -typedef enum { - PCI_MMEDIA_VIDEO, - PCI_MMEDIA_AUDIO, - PCI_MMEDIA_PHONE, - PCI_MEDIA_OTHER = 0x80 -} pci_mmedia_subclasses; - -typedef enum { - PCI_MEMORY_RAM, - PCI_MEMORY_FLASH, - PCI_MEMORY_OTHER = 0x80 -} pci_memory_subclasses; - -typedef enum { - PCI_BRIDGE_HOST, - PCI_BRIDGE_ISA, - PCI_BRIDGE_EISA, - PCI_BRIDGE_MC, - PCI_BRIDGE_PCI, - PCI_BRIDGE_PCMCIA, - PCI_BRIDGE_NUBUS, - PCI_BRIDGE_CARDBUS, - PCI_BRIDGE_RACEWAY, - PCI_BRIDGE_OTHER = 0x80 -} pci_bridge_subclasses; - -typedef enum { - PCI_COMM_UART, - PCI_COMM_PARALLEL, - PCI_COMM_MULTIUART, - PCI_COMM_MODEM, - PCI_COMM_OTHER = 0x80 -} pci_comm_subclasses; - -typedef enum { - PCI_BASE_PIC, - PCI_BASE_DMA, - PCI_BASE_TIMER, - PCI_BASE_RTC, - PCI_BASE_PCI_HOTPLUG, - PCI_BASE_OTHER = 0x80 -} pci_base_subclasses; - -typedef enum { - PCI_INPUT_KBD, - PCI_INPUT_PEN, - PCI_INPUT_MOUSE, - PCI_INPUT_SCANNER, - PCI_INPUT_GAMEPORT, - PCI_INPUT_OTHER = 0x80 -} pci_input_subclasses; - -typedef enum { - PCI_DOCK_GENERIC, - PCI_DOCK_OTHER = 0x80 -} pci_dock_subclasses; - -typedef enum { - PCI_CPU_386, - PCI_CPU_486, - PCI_CPU_PENTIUM, - PCI_CPU_ALPHA = 0x10, - PCI_CPU_POWERPC = 0x20, - PCI_CPU_MIPS = 0x30, - PCI_CPU_COPROC = 0x40, - PCI_CPU_OTHER = 0x80 -} pci_cpu_subclasses; - -typedef enum { - PCI_SERIAL_IEEE1394, - PCI_SERIAL_ACCESS, - PCI_SERIAL_SSA, - PCI_SERIAL_USB, - PCI_SERIAL_FIBER, - PCI_SERIAL_SMBUS, - PCI_SERIAL_OTHER = 0x80 -} pci_serial_subclasses; - -typedef enum { - PCI_INTELLIGENT_I2O -} pci_intelligent_subclasses; - -typedef enum { - PCI_SATELLITE_TV, - PCI_SATELLITE_AUDIO, - PCI_SATELLITE_VOICE, - PCI_SATELLITE_DATA, - PCI_SATELLITE_OTHER = 0x80 -} pci_satellite_subclasses; - -typedef enum { - PCI_CRYPT_NETWORK, - PCI_CRYPT_ENTERTAINMENT, - PCI_CRYPT_OTHER = 0x80 -} pci_crypt_subclasses; - -typedef enum { - PCI_DSP_DPIO, - PCI_DSP_OTHER = 0x80 -} pci_dsp_subclasses; - -typedef enum { - PCI_XOR_QDMA, - PCI_XOR_OTHER = 0x80 -} pci_xor_subclasses; - -/* Header types */ -#define PCI_HEADER_MULTI 0x80 -#define PCI_HEADER_MASK 0x7f -typedef enum { - PCI_HEADER_NORMAL, - PCI_HEADER_BRIDGE, - PCI_HEADER_CARDBUS -} pci_header_types; - -/* Overlay for a PCI-to-PCI bridge */ - -#define PPB_RSVDA_MAX 2 -#define PPB_RSVDD_MAX 8 - -typedef struct _ppb_config_regs { - u16 vendor; - u16 device; - u16 command; - u16 status; - u8 rev_id; - u8 prog_if; - u8 sub_class; - u8 base_class; - u8 cache_line_size; - u8 latency_timer; - u8 header_type; - u8 bist; - u32 rsvd_a[PPB_RSVDA_MAX]; - u8 prim_bus; - u8 sec_bus; - u8 sub_bus; - u8 sec_lat; - u8 io_base; - u8 io_lim; - u16 sec_status; - u16 mem_base; - u16 mem_lim; - u16 pf_mem_base; - u16 pf_mem_lim; - u32 pf_mem_base_hi; - u32 pf_mem_lim_hi; - u16 io_base_hi; - u16 io_lim_hi; - u16 subsys_vendor; - u16 subsys_id; - u32 rsvd_b; - u8 rsvd_c; - u8 int_pin; - u16 bridge_ctrl; - u8 chip_ctrl; - u8 diag_ctrl; - u16 arb_ctrl; - u32 rsvd_d[PPB_RSVDD_MAX]; - u8 dev_dep[192]; -} ppb_config_regs; - -/* PCI CAPABILITY DEFINES */ -#define PCI_CAP_POWERMGMTCAP_ID 0x01 -#define PCI_CAP_MSICAP_ID 0x05 -#define PCI_CAP_VENDSPEC_ID 0x09 -#define PCI_CAP_PCIECAP_ID 0x10 - -/* Data structure to define the Message Signalled Interrupt facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_msi { - u8 capID; - u8 nextptr; - u16 msgctrl; - u32 msgaddr; -} pciconfig_cap_msi; - -/* Data structure to define the Power management facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_pwrmgmt { - u8 capID; - u8 nextptr; - u16 pme_cap; - u16 pme_sts_ctrl; - u8 pme_bridge_ext; - u8 data; -} pciconfig_cap_pwrmgmt; - -#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */ -#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */ -#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */ -#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */ - -/* Data structure to define the PCIE capability */ -typedef struct _pciconfig_cap_pcie { - u8 capID; - u8 nextptr; - u16 pcie_cap; - u32 dev_cap; - u16 dev_ctrl; - u16 dev_status; - u32 link_cap; - u16 link_ctrl; - u16 link_status; - u32 slot_cap; - u16 slot_ctrl; - u16 slot_status; - u16 root_ctrl; - u16 root_cap; - u32 root_status; -} pciconfig_cap_pcie; - -/* PCIE Enhanced CAPABILITY DEFINES */ -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCIE_ADVERRREP_CAPID 0x0001 -#define PCIE_VC_CAPID 0x0002 -#define PCIE_DEVSNUM_CAPID 0x0003 -#define PCIE_PWRBUDGET_CAPID 0x0004 - -/* PCIE Extended configuration */ -#define PCIE_ADV_CORR_ERR_MASK 0x114 -#define CORR_ERR_RE (1 << 0) /* Receiver */ -#define CORR_ERR_BT (1 << 6) /* Bad TLP */ -#define CORR_ERR_BD (1 << 7) /* Bad DLLP */ -#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */ -#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */ -#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \ - CORR_ERR_RR | CORR_ERR_RT) - -/* PCIE Root Control Register bits (Host mode only) */ -#define PCIE_RC_CORR_SERR_EN 0x0001 -#define PCIE_RC_NONFATAL_SERR_EN 0x0002 -#define PCIE_RC_FATAL_SERR_EN 0x0004 -#define PCIE_RC_PME_INT_EN 0x0008 -#define PCIE_RC_CRS_EN 0x0010 - -/* PCIE Root Capability Register bits (Host mode only) */ -#define PCIE_RC_CRS_VISIBILITY 0x0001 - -/* Header to define the PCIE specific capabilities in the extended config space */ -typedef struct _pcie_enhanced_caphdr { - u16 capID; - u16 cap_ver:4; - u16 next_ptr:12; -} pcie_enhanced_caphdr; +/* PCI configuration address space size */ +#define PCI_SZPCR 256 /* Everything below is BRCM HND proprietary */ /* Brcm PCI configuration registers */ -#define cap_list rsvd_a[0] -#define bar0_window dev_dep[0x80 - 0x40] -#define bar1_window dev_dep[0x84 - 0x40] -#define sprom_control dev_dep[0x88 - 0x40] -#define PCI_BAR0_WIN 0x80 /* backplane address space accessed by BAR0 */ -#define PCI_BAR1_WIN 0x84 /* backplane address space accessed by BAR1 */ -#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ -#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ -#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ -#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ -#define PCI_BAR0_WIN2 0xac /* backplane address space accessed by second 4KB of BAR0 */ -#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ - -#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ -#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ -#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the +#define PCI_BAR0_WIN 0x80 /* backplane address space accessed by BAR0 */ +#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ +#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ +#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ +#define PCI_BAR0_WIN2 0xac /* backplane address space accessed by second 4KB of BAR0 */ +#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ +#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ +#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ + +#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ +#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ +#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the * 8KB window, so their address is the "regular" * address plus 4K */ #define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */ /* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ -#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ -#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ -#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ - -/* On AI chips we have a second window to map DMP regs are mapped: */ -#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */ - -/* PCI_INT_STATUS */ -#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ - -/* PCI_INT_MASK */ -#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ +#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ +#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ -/* PCI_SPROM_CONTROL */ -#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ -#define SPROM_LOCKED 0x08 /* SPROM Locked */ -#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ -#define SPROM_WRITEEN 0x10 /* SPROM write enable */ -#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ -#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */ -#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ +#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ -/* Bits in PCI command and status regs */ -#define PCI_CMD_IO 0x00000001 /* I/O enable */ -#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */ -#define PCI_CMD_MASTER 0x00000004 /* Master enable */ -#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */ -#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */ -#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */ -#define PCI_STAT_TA 0x08000000 /* target abort status */ #endif /* _h_pcicfg_ */ diff --git a/drivers/staging/brcm80211/include/sbchipc.h b/drivers/staging/brcm80211/include/sbchipc.h index f608894b117c..8c01c638ab8d 100644 --- a/drivers/staging/brcm80211/include/sbchipc.h +++ b/drivers/staging/brcm80211/include/sbchipc.h @@ -225,7 +225,7 @@ typedef volatile struct { #endif /* _LANGUAGE_ASSEMBLY */ -#if defined(IL_BIGENDIAN) && defined(BCMHND74K) +#if defined(__BIG_ENDIAN) && defined(BCMHND74K) /* Selective swapped defines for those registers we need in * big-endian code. */ @@ -234,14 +234,14 @@ typedef volatile struct { #define CC_CHIPST 0x28 #define CC_EROMPTR 0xf8 -#else /* !IL_BIGENDIAN || !BCMHND74K */ +#else /* !__BIG_ENDIAN || !BCMHND74K */ #define CC_CHIPID 0 #define CC_CAPABILITIES 4 #define CC_CHIPST 0x2c #define CC_EROMPTR 0xfc -#endif /* IL_BIGENDIAN && BCMHND74K */ +#endif /* __BIG_ENDIAN && BCMHND74K */ #define CC_OTPST 0x10 #define CC_JTAGCMD 0x30 diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h deleted file mode 100644 index 101e9a4f807d..000000000000 --- a/drivers/staging/brcm80211/include/siutils.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2010 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 _siutils_h_ -#define _siutils_h_ - -#include <hndsoc.h> - -/* - * Data structure to export all chip specific common variables - * public (read-only) portion of siutils handle returned by si_attach() - */ -struct si_pub { - uint socitype; /* SOCI_SB, SOCI_AI */ - - uint bustype; /* SI_BUS, PCI_BUS */ - uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ - uint buscorerev; /* buscore rev */ - uint buscoreidx; /* buscore index */ - int ccrev; /* chip common core rev */ - u32 cccaps; /* chip common capabilities */ - u32 cccaps_ext; /* chip common capabilities extension */ - int pmurev; /* pmu core rev */ - u32 pmucaps; /* pmu capabilities */ - uint boardtype; /* board type */ - uint boardvendor; /* board vendor */ - uint boardflags; /* board flags */ - uint boardflags2; /* board flags2 */ - uint chip; /* chip number */ - uint chiprev; /* chip revision */ - uint chippkg; /* chip package option */ - u32 chipst; /* chip status */ - bool issim; /* chip is in simulation or emulation */ - uint socirev; /* SOC interconnect rev */ - bool pci_pr32414; - -}; - -/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver - * for monolithic driver, it is readonly to prevent accident change - */ -typedef const struct si_pub si_t; - -/* - * Many of the routines below take an 'sih' handle as their first arg. - * Allocate this by calling si_attach(). Free it by calling si_detach(). - * At any one time, the sih is logically focused on one particular si core - * (the "current core"). - * Use si_setcore() or si_setcoreidx() to change the association to another core. - */ - -#define BADIDX (SI_MAXCORES + 1) - -/* clkctl xtal what flags */ -#define XTAL 0x1 /* primary crystal oscillator (2050) */ -#define PLL 0x2 /* main chip pll */ - -/* clkctl clk mode */ -#define CLK_FAST 0 /* force fast (pll) clock */ -#define CLK_DYNAMIC 2 /* enable dynamic clock control */ - -/* GPIO usage priorities */ -#define GPIO_DRV_PRIORITY 0 /* Driver */ -#define GPIO_APP_PRIORITY 1 /* Application */ -#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */ - -/* GPIO pull up/down */ -#define GPIO_PULLUP 0 -#define GPIO_PULLDN 1 - -/* GPIO event regtype */ -#define GPIO_REGEVT 0 /* GPIO register event */ -#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ -#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ - -/* device path */ -#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ - -/* SI routine enumeration: to be used by update function with multiple hooks */ -#define SI_DOATTACH 1 -#define SI_PCIDOWN 2 -#define SI_PCIUP 3 - -#define ISSIM_ENAB(sih) 0 - -/* PMU clock/power control */ -#if defined(BCMPMUCTL) -#define PMUCTL_ENAB(sih) (BCMPMUCTL) -#else -#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -#endif - -/* chipcommon clock/power control (exclusive with PMU's) */ -#if defined(BCMPMUCTL) && BCMPMUCTL -#define CCCTL_ENAB(sih) (0) -#define CCPLL_ENAB(sih) (0) -#else -#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -#endif - -typedef void (*gpio_handler_t) (u32 stat, void *arg); - -/* External PA enable mask */ -#define GPIO_CTRL_EPA_EN_MASK 0x40 - -/* === exported functions === */ -extern si_t *si_attach(uint pcidev, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); - -extern void si_detach(si_t *sih); -extern bool si_pci_war16165(si_t *sih); - -extern uint si_coreid(si_t *sih); -extern uint si_flag(si_t *sih); -extern uint si_coreidx(si_t *sih); -extern uint si_corerev(si_t *sih); -extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, - uint val); -extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val); -extern u32 si_core_cflags(si_t *sih, u32 mask, u32 val); -extern u32 si_core_sflags(si_t *sih, u32 mask, u32 val); -extern bool si_iscoreup(si_t *sih); -extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -#ifndef BCMSDIO -extern void *si_setcoreidx(si_t *sih, uint coreidx); -#endif -extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, - uint *intr_val); -extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -extern void si_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void si_core_disable(si_t *sih, u32 bits); -extern u32 si_alp_clock(si_t *sih); -extern u32 si_ilp_clock(si_t *sih); -extern void si_pci_setup(si_t *sih, uint coremask); -extern void si_setint(si_t *sih, int siflag); -extern bool si_backplane64(si_t *sih); -extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, - void *intrsrestore_fn, - void *intrsenabled_fn, void *intr_arg); -extern void si_deregister_intr_callback(si_t *sih); -extern void si_clkctl_init(si_t *sih); -extern u16 si_clkctl_fast_pwrup_delay(si_t *sih); -extern bool si_clkctl_cc(si_t *sih, uint mode); -extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -extern bool si_deviceremoved(si_t *sih); -extern u32 si_socram_size(si_t *sih); - -extern void si_watchdog(si_t *sih, uint ticks); -extern u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, - u8 priority); - -#ifdef BCMSDIO -extern void si_sdio_init(si_t *sih); -#endif - -#define si_eci(sih) 0 -#define si_eci_init(sih) (0) -#define si_eci_notify_bt(sih, type, val) (0) -#define si_seci(sih) 0 - -/* OTP status */ -extern bool si_is_otp_disabled(si_t *sih); -extern bool si_is_otp_powered(si_t *sih); -extern void si_otp_power(si_t *sih, bool on); - -/* SPROM availability */ -extern bool si_is_sprom_available(si_t *sih); -#ifdef SI_SPROM_PROBE -extern void si_sprom_init(si_t *sih); -#endif /* SI_SPROM_PROBE */ - -#define SI_ERROR(args) - -#ifdef BCMDBG -#define SI_MSG(args) printk args -#else -#define SI_MSG(args) -#endif /* BCMDBG */ - -/* Define SI_VMSG to printf for verbose debugging, but don't check it in */ -#define SI_VMSG(args) - -#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) - -typedef u32(*si_intrsoff_t) (void *intr_arg); -typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg); -typedef bool(*si_intrsenabled_t) (void *intr_arg); - -typedef struct gpioh_item { - void *arg; - bool level; - gpio_handler_t handler; - u32 event; - struct gpioh_item *next; -} gpioh_item_t; - -/* misc si info needed by some of the routines */ -typedef struct si_info { - struct si_pub pub; /* back plane public state (must be first) */ - void *pbus; /* handle to bus (pci/sdio/..) */ - uint dev_coreid; /* the core provides driver functions */ - void *intr_arg; /* interrupt callback function arg */ - si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ - si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ - si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ - - void *pch; /* PCI/E core handle */ - - gpioh_item_t *gpioh_head; /* GPIO event handlers list */ - - bool memseg; /* flag to toggle MEM_SEG register */ - - char *vars; - uint varsz; - - void *curmap; /* current regs va */ - void *regs[SI_MAXCORES]; /* other regs va */ - - uint curidx; /* current core index */ - uint numcores; /* # discovered cores */ - uint coreid[SI_MAXCORES]; /* id of each core */ - u32 coresba[SI_MAXCORES]; /* backplane address of each core */ - void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ - u32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ - u32 coresba_size[SI_MAXCORES]; /* backplane address space size */ - u32 coresba2_size[SI_MAXCORES]; /* second address space size */ - - void *curwrap; /* current wrapper va */ - void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ - u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ - - u32 cia[SI_MAXCORES]; /* erom cia entry for each core */ - u32 cib[SI_MAXCORES]; /* erom cia entry for each core */ - u32 oob_router; /* oob router registers for axi */ -} si_info_t; - -#define SI_INFO(sih) ((si_info_t *)(sih)) - -#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ - IS_ALIGNED((x), SI_CORE_SIZE)) -#define GOODREGS(regs) ((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE)) -#define BADCOREADDR 0 -#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -#define NOREV -1 /* Invalid rev */ - -/* Newer chips can access PCI/PCIE and CC core without requiring to change - * PCI BAR0 WIN - */ -#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ - (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) - -#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) - -/* - * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts - * before after core switching to avoid invalid register access inside ISR. - */ -#define INTR_OFF(si, intr_val) \ - if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -#define INTR_RESTORE(si, intr_val) \ - if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } - -/* dynamic clock control defines */ -#define LPOMINFREQ 25000 /* low power oscillator min */ -#define LPOMAXFREQ 43000 /* low power oscillator max */ -#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -#define PCIMINFREQ 25000000 /* 25 MHz */ -#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ - -#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ - -#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ - ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ - ((si)->pub.buscoretype == PCIE_CORE_ID)) -#define PCI_FORCEHT(si) \ - (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) - -/* GPIO Based LED powersave defines */ -#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ - -#ifndef DEFAULT_GPIOTIMERVAL -#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -#endif - -/* - * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. - * The returned path is NULL terminated and has trailing '/'. - * Return 0 on success, nonzero otherwise. - */ -extern int si_devpath(si_t *sih, char *path, int size); -/* Read variable with prepending the devpath to the name */ -extern char *si_getdevpathvar(si_t *sih, const char *name); -extern int si_getdevpathintvar(si_t *sih, const char *name); - -extern void si_war42780_clkreq(si_t *sih, bool clkreq); -extern void si_pci_sleep(si_t *sih); -extern void si_pci_down(si_t *sih); -extern void si_pci_up(si_t *sih); -extern void si_pcie_extendL1timer(si_t *sih, bool extend); -extern int si_pci_fixcfg(si_t *sih); - -extern void si_chipcontrl_epa4331(si_t *sih, bool on); -/* Enable Ex-PA for 4313 */ -extern void si_epa_4313war(si_t *sih); - -char *si_getnvramflvar(si_t *sih, const char *name); - -/* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(void); -extern void ai_scan(si_t *sih, void *regs, uint devid); - -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); -extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); -extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, - uint val); -extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void ai_core_disable(si_t *sih, u32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern u32 ai_addrspace(si_t *sih, uint asidx); -extern u32 ai_addrspacesize(si_t *sih, uint asidx); -extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); - -#ifdef BCMSDIO -#define si_setcoreidx(sih, idx) sb_setcoreidx(sih, idx) -#define si_coreid(sih) sb_coreid(sih) -#define si_corerev(sih) sb_corerev(sih) -#endif - -#endif /* _siutils_h_ */ diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 5e2b11bcfc6f..2876bd9eff85 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -259,6 +259,7 @@ typedef struct wl_u32_list { /* used for association with a specific BSSID and chanspec list */ typedef struct wl_assoc_params { u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ + u16 bssid_cnt; s32 chanspec_num; /* 0: all available channels, * otherwise count of chanspecs in chanspec_list */ @@ -585,15 +586,6 @@ struct maclist { u8 ea[1][ETH_ALEN]; /* variable length array of MAC addresses */ }; -/* get pkt count struct passed through ioctl */ -typedef struct get_pktcnt { - uint rx_good_pkt; - uint rx_bad_pkt; - uint tx_good_pkt; - uint tx_bad_pkt; - uint rx_ocast_good_pkt; /* unicast packets destined for others */ -} get_pktcnt_t; - #ifdef BRCM_FULLMAC /* Linux network driver ioctl encoding */ typedef struct wl_ioctl { @@ -1247,8 +1239,6 @@ typedef struct tx_inst_power { /* Message levels */ #define WL_ERROR_VAL 0x00000001 #define WL_TRACE_VAL 0x00000002 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 /* maximum channels returned by the get valid channels iovar */ #define WL_NUMCHANNELS 64 @@ -1260,348 +1250,11 @@ struct tsinfo_arg { #define NFIFO 6 /* # tx/rx fifopairs */ -#define WL_CNT_T_VERSION 7 /* current version of wl_cnt_t struct */ - -struct wl_cnt { - u16 version; /* see definition of WL_CNT_T_VERSION */ - u16 length; /* length of entire structure */ - - /* transmit stat counters */ - u32 txframe; /* tx data frames */ - u32 txbyte; /* tx data bytes */ - u32 txretrans; /* tx mac retransmits */ - u32 txerror; /* tx data errors (derived: sum of others) */ - u32 txctl; /* tx management frames */ - u32 txprshort; /* tx short preamble frames */ - u32 txserr; /* tx status errors */ - u32 txnobuf; /* tx out of buffers errors */ - u32 txnoassoc; /* tx discard because we're not associated */ - u32 txrunt; /* tx runt frames */ - u32 txchit; /* tx header cache hit (fastpath) */ - u32 txcmiss; /* tx header cache miss (slowpath) */ - u32 ieee_tx_status; /* calls to ieee80211_tx_status */ - u32 ieee_tx; /* tx calls frm mac0211 */ - u32 ieee_rx; /* calls to ieee_rx */ - - /* transmit chip error counters */ - u32 txuflo; /* tx fifo underflows */ - u32 txphyerr; /* tx phy errors (indicated in tx status) */ - u32 txphycrs; - - /* receive stat counters */ - u32 rxframe; /* rx data frames */ - u32 rxbyte; /* rx data bytes */ - u32 rxerror; /* rx data errors (derived: sum of others) */ - u32 rxctl; /* rx management frames */ - u32 rxnobuf; /* rx out of buffers errors */ - u32 rxnondata; /* rx non data frames in the data channel errors */ - u32 rxbadds; /* rx bad DS errors */ - u32 rxbadcm; /* rx bad control or management frames */ - u32 rxfragerr; /* rx fragmentation errors */ - u32 rxrunt; /* rx runt frames */ - u32 rxgiant; /* rx giant frames */ - u32 rxnoscb; /* rx no scb error */ - u32 rxbadproto; /* rx invalid frames */ - u32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ - u32 rxbadda; /* rx frames tossed for invalid da */ - u32 rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - u32 rxoflo; /* rx fifo overflow errors */ - u32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - u32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - u32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - u32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - u32 dmade; /* tx/rx dma descriptor errors */ - u32 dmada; /* tx/rx dma data errors */ - u32 dmape; /* tx/rx dma descriptor protocol errors */ - u32 reset; /* reset count */ - u32 tbtt; /* cnts the TBTT int's */ - u32 txdmawar; - u32 pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - u32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, - * Control Management (includes retransmissions) - */ - u32 txrtsfrm; /* number of RTS sent out by the MAC */ - u32 txctsfrm; /* number of CTS sent out by the MAC */ - u32 txackfrm; /* number of ACK frames sent out */ - u32 txdnlfrm; /* Not used */ - u32 txbcnfrm; /* beacons transmitted */ - u32 txfunfl[8]; /* per-fifo tx underflows */ - u32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS - * or BCN) - */ - u32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for - * driver enqueued frames - */ - u32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - u32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - u32 rxinvmachdr; /* Either the protocol version != 0 or frame type not - * data/control/management - */ - u32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - u32 rxbadplcp; /* parity check of the PLCP header failed */ - u32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - u32 rxstrt; /* Number of received frames with a good PLCP - * (i.e. passing parity check) - */ - u32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - u32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - u32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - u32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - u32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - u32 rxackucast; /* number of ucast ACKS received (good FCS) */ - u32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - u32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - u32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - u32 rxrtsocast; /* number of received RTS not addressed to the MAC */ - u32 rxctsocast; /* number of received CTS not addressed to the MAC */ - u32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - u32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - u32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC - * (unlikely to see these) - */ - u32 rxbeaconmbss; /* beacons received from member of BSS */ - u32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from - * other BSS (WDS FRAME) - */ - u32 rxbeaconobss; /* beacons received from other BSS */ - u32 rxrsptmout; /* Number of response timeouts for transmitted frames - * expecting a response - */ - u32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - u32 rxf0ovfl; /* Number of receive fifo 0 overflows */ - u32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - u32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - u32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - u32 pmqovfl; /* Number of PMQ overflows */ - u32 rxcgprqfrm; /* Number of received Probe requests that made it into - * the PRQ fifo - */ - u32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - u32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did - * not get ACK - */ - u32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - u32 prs_timeout; /* Number of probe requests that were dropped from the PRQ - * fifo because a probe response could not be sent out within - * the time limit defined in M_PRS_MAXTIME - */ - u32 rxnack; - u32 frmscons; - u32 txnack; - u32 txglitch_nack; /* obsolete */ - u32 txburst; /* obsolete */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - u32 txfrag; /* dot11TransmittedFragmentCount */ - u32 txmulti; /* dot11MulticastTransmittedFrameCount */ - u32 txfail; /* dot11FailedCount */ - u32 txretry; /* dot11RetryCount */ - u32 txretrie; /* dot11MultipleRetryCount */ - u32 rxdup; /* dot11FrameduplicateCount */ - u32 txrts; /* dot11RTSSuccessCount */ - u32 txnocts; /* dot11RTSFailureCount */ - u32 txnoack; /* dot11ACKFailureCount */ - u32 rxfrag; /* dot11ReceivedFragmentCount */ - u32 rxmulti; /* dot11MulticastReceivedFrameCount */ - u32 rxcrc; /* dot11FCSErrorCount */ - u32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - u32 rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - u32 tkipmicfaill; /* TKIPLocalMICFailures */ - u32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - u32 tkipreplay; /* TKIPReplays */ - u32 ccmpfmterr; /* CCMPFormatErrors */ - u32 ccmpreplay; /* CCMPReplays */ - u32 ccmpundec; /* CCMPDecryptErrors */ - u32 fourwayfail; /* FourWayHandshakeFailures */ - u32 wepundec; /* dot11WEPUndecryptableCount */ - u32 wepicverr; /* dot11WEPICVErrorCount */ - u32 decsuccess; /* DecryptSuccessCount */ - u32 tkipicverr; /* TKIPICVErrorCount */ - u32 wepexcluded; /* dot11WEPExcludedCount */ - - u32 rxundec_mcst; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - u32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ - u32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ - u32 tkipreplay_mcst; /* TKIPReplays */ - u32 ccmpfmterr_mcst; /* CCMPFormatErrors */ - u32 ccmpreplay_mcst; /* CCMPReplays */ - u32 ccmpundec_mcst; /* CCMPDecryptErrors */ - u32 fourwayfail_mcst; /* FourWayHandshakeFailures */ - u32 wepundec_mcst; /* dot11WEPUndecryptableCount */ - u32 wepicverr_mcst; /* dot11WEPICVErrorCount */ - u32 decsuccess_mcst; /* DecryptSuccessCount */ - u32 tkipicverr_mcst; /* TKIPICVErrorCount */ - u32 wepexcluded_mcst; /* dot11WEPExcludedCount */ - - u32 txchanrej; /* Tx frames suppressed due to channel rejection */ - u32 txexptime; /* Tx frames suppressed due to timer expiration */ - u32 psmwds; /* Count PSM watchdogs */ - u32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - u32 prq_entries_handled; /* PRQ entries read in */ - u32 prq_undirected_entries; /* which were bcast bss & ssid */ - u32 prq_bad_entries; /* which could not be translated to info */ - u32 atim_suppress_count; /* TX suppressions on ATIM fifo */ - u32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ - u32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ - u32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - u32 rx1mbps; /* packets rx at 1Mbps */ - u32 rx2mbps; /* packets rx at 2Mbps */ - u32 rx5mbps5; /* packets rx at 5.5Mbps */ - u32 rx6mbps; /* packets rx at 6Mbps */ - u32 rx9mbps; /* packets rx at 9Mbps */ - u32 rx11mbps; /* packets rx at 11Mbps */ - u32 rx12mbps; /* packets rx at 12Mbps */ - u32 rx18mbps; /* packets rx at 18Mbps */ - u32 rx24mbps; /* packets rx at 24Mbps */ - u32 rx36mbps; /* packets rx at 36Mbps */ - u32 rx48mbps; /* packets rx at 48Mbps */ - u32 rx54mbps; /* packets rx at 54Mbps */ - u32 rx108mbps; /* packets rx at 108mbps */ - u32 rx162mbps; /* packets rx at 162mbps */ - u32 rx216mbps; /* packets rx at 216 mbps */ - u32 rx270mbps; /* packets rx at 270 mbps */ - u32 rx324mbps; /* packets rx at 324 mbps */ - u32 rx378mbps; /* packets rx at 378 mbps */ - u32 rx432mbps; /* packets rx at 432 mbps */ - u32 rx486mbps; /* packets rx at 486 mbps */ - u32 rx540mbps; /* packets rx at 540 mbps */ - - /* pkteng rx frame stats */ - u32 pktengrxducast; /* unicast frames rxed by the pkteng code */ - u32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ - - u32 rfdisable; /* count of radio disables */ - u32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ - - u32 txmpdu_sgi; /* count for sgi transmit */ - u32 rxmpdu_sgi; /* count for sgi received */ - u32 txmpdu_stbc; /* count for stbc transmit */ - u32 rxmpdu_stbc; /* count for stbc received */ -}; - -#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ - -typedef struct { - u16 version; /* see definition of WL_DELTA_STATS_T_VERSION */ - u16 length; /* length of entire structure */ - - /* transmit stat counters */ - u32 txframe; /* tx data frames */ - u32 txbyte; /* tx data bytes */ - u32 txretrans; /* tx mac retransmits */ - u32 txfail; /* tx failures */ - - /* receive stat counters */ - u32 rxframe; /* rx data frames */ - u32 rxbyte; /* rx data bytes */ - - /* per-rate receive stat counters */ - u32 rx1mbps; /* packets rx at 1Mbps */ - u32 rx2mbps; /* packets rx at 2Mbps */ - u32 rx5mbps5; /* packets rx at 5.5Mbps */ - u32 rx6mbps; /* packets rx at 6Mbps */ - u32 rx9mbps; /* packets rx at 9Mbps */ - u32 rx11mbps; /* packets rx at 11Mbps */ - u32 rx12mbps; /* packets rx at 12Mbps */ - u32 rx18mbps; /* packets rx at 18Mbps */ - u32 rx24mbps; /* packets rx at 24Mbps */ - u32 rx36mbps; /* packets rx at 36Mbps */ - u32 rx48mbps; /* packets rx at 48Mbps */ - u32 rx54mbps; /* packets rx at 54Mbps */ - u32 rx108mbps; /* packets rx at 108mbps */ - u32 rx162mbps; /* packets rx at 162mbps */ - u32 rx216mbps; /* packets rx at 216 mbps */ - u32 rx270mbps; /* packets rx at 270 mbps */ - u32 rx324mbps; /* packets rx at 324 mbps */ - u32 rx378mbps; /* packets rx at 378 mbps */ - u32 rx432mbps; /* packets rx at 432 mbps */ - u32 rx486mbps; /* packets rx at 486 mbps */ - u32 rx540mbps; /* packets rx at 540 mbps */ -} wl_delta_stats_t; - -#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ - -typedef struct { - u32 packets; - u32 bytes; -} wl_traffic_stats_t; - -typedef struct { - u16 version; /* see definition of WL_WME_CNT_VERSION */ - u16 length; /* length of entire structure */ - - wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ - wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ - wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ - wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ - - wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ - - wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ - -} wl_wme_cnt_t; - struct wl_msglevel2 { u32 low; u32 high; }; -#ifdef WLBA - -#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ - -/* block ack related stats */ -typedef struct wlc_ba_cnt { - u16 version; /* WLC_BA_CNT_VERSION */ - u16 length; /* length of entire structure */ - - /* transmit stat counters */ - u32 txpdu; /* pdus sent */ - u32 txsdu; /* sdus sent */ - u32 txfc; /* tx side flow controlled packets */ - u32 txfci; /* tx side flow control initiated */ - u32 txretrans; /* retransmitted pdus */ - u32 txbatimer; /* ba resend due to timer */ - u32 txdrop; /* dropped packets */ - u32 txaddbareq; /* addba req sent */ - u32 txaddbaresp; /* addba resp sent */ - u32 txdelba; /* delba sent */ - u32 txba; /* ba sent */ - u32 txbar; /* bar sent */ - u32 txpad[4]; /* future */ - - /* receive side counters */ - u32 rxpdu; /* pdus recd */ - u32 rxqed; /* pdus buffered before sending up */ - u32 rxdup; /* duplicate pdus */ - u32 rxnobuf; /* pdus discarded due to no buf */ - u32 rxaddbareq; /* addba req recd */ - u32 rxaddbaresp; /* addba resp recd */ - u32 rxdelba; /* delba recd */ - u32 rxba; /* ba recd */ - u32 rxbar; /* bar recd */ - u32 rxinvba; /* invalid ba recd */ - u32 rxbaholes; /* ba recd with holes */ - u32 rxunexp; /* unexpected packets */ - u32 rxpad[4]; /* future */ -} wlc_ba_cnt_t; -#endif /* WLBA */ - /* structure for per-tid ampdu control */ struct ampdu_tid_control { u8 tid; /* tid */ diff --git a/drivers/staging/brcm80211/util/Makefile b/drivers/staging/brcm80211/util/Makefile new file mode 100644 index 000000000000..f9b36cafdc87 --- /dev/null +++ b/drivers/staging/brcm80211/util/Makefile @@ -0,0 +1,29 @@ +# +# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities +# +# Copyright (c) 2011 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. + +ccflags-y := \ + -Idrivers/staging/brcm80211/util \ + -Idrivers/staging/brcm80211/include + +BRCMUTIL_OFILES := \ + bcmutils.o \ + bcmwifi.o + +MODULEPFX := brcmutil + +obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o +$(MODULEPFX)-objs = $(BRCMUTIL_OFILES) diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c deleted file mode 100644 index 570869032d88..000000000000 --- a/drivers/staging/brcm80211/util/aiutils.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Copyright (c) 2010 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 <linux/delay.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <bcmdefs.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <bcmutils.h> -#include <siutils.h> -#include <hndsoc.h> -#include <sbchipc.h> -#include <pcicfg.h> -#include <bcmdevs.h> - -#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ - (sih->chiprev == 0) && \ - (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) - -/* EROM parsing */ - -static u32 -get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) -{ - u32 ent; - uint inv = 0, nom = 0; - - while (true) { - ent = R_REG(*eromptr); - (*eromptr)++; - - if (mask == 0) - break; - - if ((ent & ER_VALID) == 0) { - inv++; - continue; - } - - if (ent == (ER_END | ER_VALID)) - break; - - if ((ent & mask) == match) - break; - - nom++; - } - - SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent)); - if (inv + nom) { - SI_VMSG((" after %d invalid and %d non-matching entries\n", - inv, nom)); - } - return ent; -} - -static u32 -get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st, - u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh) -{ - u32 asd, sz, szd; - - asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); - if (((asd & ER_TAG1) != ER_ADD) || - (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || - ((asd & AD_ST_MASK) != st)) { - /* This is not what we want, "push" it back */ - (*eromptr)--; - return 0; - } - *addrl = asd & AD_ADDR_MASK; - if (asd & AD_AG32) - *addrh = get_erom_ent(sih, eromptr, 0, 0); - else - *addrh = 0; - *sizeh = 0; - sz = asd & AD_SZ_MASK; - if (sz == AD_SZ_SZD) { - szd = get_erom_ent(sih, eromptr, 0, 0); - *sizel = szd & SD_SZ_MASK; - if (szd & SD_SG32) - *sizeh = get_erom_ent(sih, eromptr, 0, 0); - } else - *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); - - SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", - sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); - - return asd; -} - -static void ai_hwfixup(si_info_t *sii) -{ -} - -/* parse the enumeration rom to identify all cores */ -void ai_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii = SI_INFO(sih); - chipcregs_t *cc = (chipcregs_t *) regs; - u32 erombase, *eromptr, *eromlim; - - erombase = R_REG(&cc->eromptr); - - switch (sih->bustype) { - case SI_BUS: - eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE); - break; - - case PCI_BUS: - /* Set wrappers address */ - sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE); - - /* Now point the window at the erom */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase); - eromptr = regs; - break; - - case SPI_BUS: - case SDIO_BUS: - eromptr = (u32 *)(unsigned long)erombase; - break; - - default: - SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", - sih->bustype)); - ASSERT(0); - return; - } - eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32)); - - SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim)); - while (eromptr < eromlim) { - u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; - u32 mpd, asd, addrl, addrh, sizel, sizeh; - u32 *base; - uint i, j, idx; - bool br; - - br = false; - - /* Grok a component */ - cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); - if (cia == (ER_END | ER_VALID)) { - SI_VMSG(("Found END of erom after %d cores\n", - sii->numcores)); - ai_hwfixup(sii); - return; - } - base = eromptr - 1; - cib = get_erom_ent(sih, &eromptr, 0, 0); - - if ((cib & ER_TAG) != ER_CI) { - SI_ERROR(("CIA not followed by CIB\n")); - goto error; - } - - cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; - mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; - crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; - nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; - nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; - nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; - nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; - - SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp)); - - if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) - continue; - if ((nmw + nsw == 0)) { - /* A component which is not a core */ - if (cid == OOB_ROUTER_CORE_ID) { - asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, - &addrl, &addrh, &sizel, &sizeh); - if (asd != 0) { - sii->oob_router = addrl; - } - } - continue; - } - - idx = sii->numcores; -/* sii->eromptr[idx] = base; */ - sii->cia[idx] = cia; - sii->cib[idx] = cib; - sii->coreid[idx] = cid; - - for (i = 0; i < nmp; i++) { - mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); - if ((mpd & ER_TAG) != ER_MP) { - SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); - goto error; - } - SI_VMSG((" Master port %d, mp: %d id: %d\n", i, - (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, - (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); - } - - /* First Slave Address Descriptor should be port 0: - * the main register space for the core - */ - asd = - get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, - &sizel, &sizeh); - if (asd == 0) { - /* Try again to see if it is a bridge */ - asd = - get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, - &addrh, &sizel, &sizeh); - if (asd != 0) - br = true; - else if ((addrh != 0) || (sizeh != 0) - || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd)); - goto error; - } - } - sii->coresba[idx] = addrl; - sii->coresba_size[idx] = sizel; - /* Get any more ASDs in port 0 */ - j = 1; - do { - asd = - get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, - &addrh, &sizel, &sizeh); - if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { - sii->coresba2[idx] = addrl; - sii->coresba2_size[idx] = sizel; - } - j++; - } while (asd != 0); - - /* Go through the ASDs for other slave ports */ - for (i = 1; i < nsp; i++) { - j = 0; - do { - asd = - get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, - &addrl, &addrh, &sizel, &sizeh); - } while (asd != 0); - if (j == 0) { - SI_ERROR((" SP %d has no address descriptors\n", - i)); - goto error; - } - } - - /* Now get master wrappers */ - for (i = 0; i < nmw; i++) { - asd = - get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, - &addrh, &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for MW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Master wrapper %d is not 4KB\n", i)); - goto error; - } - if (i == 0) - sii->wrapba[idx] = addrl; - } - - /* And finally slave wrappers */ - for (i = 0; i < nsw; i++) { - uint fwp = (nsp == 1) ? 0 : 1; - asd = - get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, - &addrl, &addrh, &sizel, &sizeh); - if (asd == 0) { - SI_ERROR(("Missing descriptor for SW %d\n", i)); - goto error; - } - if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); - goto error; - } - if ((nmw == 0) && (i == 0)) - sii->wrapba[idx] = addrl; - } - - /* Don't record bridges */ - if (br) - continue; - - /* Done with core */ - sii->numcores++; - } - - SI_ERROR(("Reached end of erom without finding END")); - - error: - sii->numcores = 0; - return; -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -void *ai_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii = SI_INFO(sih); - u32 addr = sii->coresba[coreidx]; - u32 wrap = sii->wrapba[coreidx]; - void *regs; - - if (coreidx >= sii->numcores) - return NULL; - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) - || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg)); - - switch (sih->bustype) { - case SI_BUS: - /* map new one */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - sii->curmap = regs = sii->regs[coreidx]; - if (!sii->wrappers[coreidx]) { - sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); - ASSERT(GOODREGS(sii->wrappers[coreidx])); - } - sii->curwrap = sii->wrappers[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr); - regs = sii->curmap; - /* point bar0 2nd 4KB window */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap); - break; - - case SPI_BUS: - case SDIO_BUS: - sii->curmap = regs = (void *)(unsigned long)addr; - sii->curwrap = (void *)(unsigned long)wrap; - break; - - default: - ASSERT(0); - regs = NULL; - break; - } - - sii->curmap = regs; - sii->curidx = coreidx; - - return regs; -} - -/* Return the number of address spaces in current core */ -int ai_numaddrspaces(si_t *sih) -{ - return 2; -} - -/* Return the address of the nth address space in the current core */ -u32 ai_addrspace(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->coresba[cidx]; - else if (asidx == 1) - return sii->coresba2[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); - return 0; - } -} - -/* Return the size of the nth address space in the current core */ -u32 ai_addrspacesize(si_t *sih, uint asidx) -{ - si_info_t *sii; - uint cidx; - - sii = SI_INFO(sih); - cidx = sii->curidx; - - if (asidx == 0) - return sii->coresba_size[cidx]; - else if (asidx == 1) - return sii->coresba2_size[cidx]; - else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); - return 0; - } -} - -uint ai_flag(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - if (BCM47162_DMP()) { - SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__)); - return sii->curidx; - } - ai = sii->curwrap; - - return R_REG(&ai->oobselouta30) & 0x1f; -} - -void ai_setint(si_t *sih, int siflag) -{ -} - -void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val) -{ - si_info_t *sii = SI_INFO(sih); - u32 *w = (u32 *) sii->curwrap; - W_REG(w + (offset / 4), val); - return; -} - -uint ai_corevendor(si_t *sih) -{ - si_info_t *sii; - u32 cia; - - sii = SI_INFO(sih); - cia = sii->cia[sii->curidx]; - return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; -} - -uint ai_corerev(si_t *sih) -{ - si_info_t *sii; - u32 cib; - - sii = SI_INFO(sih); - cib = sii->cib[sii->curidx]; - return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; -} - -bool ai_iscoreup(si_t *sih) -{ - si_info_t *sii; - aidmp_t *ai; - - sii = SI_INFO(sih); - ai = sii->curwrap; - - return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == - SICF_CLOCK_EN) - && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0)); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fiddling with interrupts or core switches is needed. - * - * Also, when using pci/pcie, we can optimize away the core switching for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - u32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = false; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (sih->bustype == SI_BUS) { - /* If internal bus, we can always get at everything */ - fast = true; - /* map if does not exist */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], - SI_CORE_SIZE); - ASSERT(GOODREGS(sii->regs[coreidx])); - } - r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff); - } else if (sih->bustype == PCI_BUS) { - /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ - - if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = true; - r = (u32 *) ((char *)sii->curmap + - PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* pci registers are at either in the last 2KB of an 8KB window - * or, in pcie and pci rev 13 at 8KB - */ - fast = true; - if (SI_FAST(sii)) - r = (u32 *) ((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + - regoff); - else - r = (u32 *) ((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : - PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } - } - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx) + - regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - w = (R_REG(r) & ~mask) | val; - W_REG(r, w); - } - - /* readback */ - w = R_REG(r); - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - ai_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return w; -} - -void ai_core_disable(si_t *sih, u32 bits) -{ - si_info_t *sii; - volatile u32 dummy; - aidmp_t *ai; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* if core is already in reset, just return */ - if (R_REG(&ai->resetctrl) & AIRC_RESET) - return; - - W_REG(&ai->ioctrl, bits); - dummy = R_REG(&ai->ioctrl); - udelay(10); - - W_REG(&ai->resetctrl, AIRC_RESET); - udelay(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void ai_core_reset(si_t *sih, u32 bits, u32 resetbits) -{ - si_info_t *sii; - aidmp_t *ai; - volatile u32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - ai_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); - dummy = R_REG(&ai->ioctrl); - W_REG(&ai->resetctrl, 0); - udelay(1); - - W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN)); - dummy = R_REG(&ai->ioctrl); - udelay(1); -} - -void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) -{ - si_info_t *sii; - aidmp_t *ai; - u32 w; - - sii = SI_INFO(sih); - - if (BCM47162_DMP()) { - SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", - __func__)); - return; - } - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(&ai->ioctrl) & ~mask) | val); - W_REG(&ai->ioctrl, w); - } -} - -u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) -{ - si_info_t *sii; - aidmp_t *ai; - u32 w; - - sii = SI_INFO(sih); - if (BCM47162_DMP()) { - SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", - __func__)); - return 0; - } - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - - if (mask || val) { - w = ((R_REG(&ai->ioctrl) & ~mask) | val); - W_REG(&ai->ioctrl, w); - } - - return R_REG(&ai->ioctrl); -} - -u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) -{ - si_info_t *sii; - aidmp_t *ai; - u32 w; - - sii = SI_INFO(sih); - if (BCM47162_DMP()) { - SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__)); - return 0; - } - - ASSERT(GOODREGS(sii->curwrap)); - ai = sii->curwrap; - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SISF_CORE_BITS) == 0); - - if (mask || val) { - w = ((R_REG(&ai->iostatus) & ~mask) | val); - W_REG(&ai->iostatus, w); - } - - return R_REG(&ai->iostatus); -} - diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c deleted file mode 100644 index 850bfa6593e0..000000000000 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ /dev/null @@ -1,2088 +0,0 @@ -/* - * Copyright (c) 2010 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 <linux/kernel.h> -#include <linux/string.h> -#include <linux/etherdevice.h> -#include <bcmdefs.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <stdarg.h> -#include <bcmutils.h> -#include <hndsoc.h> -#include <sbchipc.h> -#include <bcmdevs.h> -#include <pcicfg.h> -#include <siutils.h> -#include <bcmsrom.h> -#include <bcmsrom_tbl.h> -#ifdef BCMSDIO -#include <bcmsdh.h> -#include <sdio.h> -#endif - -#include <bcmnvram.h> -#include <bcmotp.h> - -#if defined(BCMSDIO) -#include <sbsdio.h> -#include <sbhnddma.h> -#include <sbsdpcmdev.h> -#endif - -#include <linux/if_ether.h> - -#define BS_ERROR(args) - -#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ - (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ - ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ - ((u8 *)curmap + PCI_BAR0_SPROM_OFFSET)) - -#if defined(BCMDBG) -#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ -#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ -#endif - -typedef struct varbuf { - char *base; /* pointer to buffer base */ - char *buf; /* pointer to current position */ - unsigned int size; /* current (residual) size in bytes */ -} varbuf_t; -extern char *_vars; -extern uint _varsz; - -#define SROM_CIS_SINGLE 1 - -static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); -static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); -static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); -static int initvars_flash_si(si_t *sih, char **vars, uint *count); -#ifdef BCMSDIO -static int initvars_cis_sdio(char **vars, uint *count); -static int sprom_cmd_sdio(u8 cmd); -static int sprom_read_sdio(u16 addr, u16 *data); -#endif /* BCMSDIO */ -static int sprom_read_pci(si_t *sih, u16 *sprom, - uint wordoff, u16 *buf, uint nwords, bool check_crc); -#if defined(BCMNVRAMR) -static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz); -#endif -static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, - uint wordoff, u16 data); - -static int initvars_table(char *start, char *end, - char **vars, uint *count); -static int initvars_flash(si_t *sih, char **vp, - uint len); - -/* Initialization of varbuf structure */ -static void varbuf_init(varbuf_t *b, char *buf, uint size) -{ - b->size = size; - b->base = b->buf = buf; -} - -/* append a null terminated var=value string */ -static int varbuf_append(varbuf_t *b, const char *fmt, ...) -{ - va_list ap; - int r; - size_t len; - char *s; - - if (b->size < 2) - return 0; - - va_start(ap, fmt); - r = vsnprintf(b->buf, b->size, fmt, ap); - va_end(ap); - - /* C99 snprintf behavior returns r >= size on overflow, - * others return -1 on overflow. - * All return -1 on format error. - * We need to leave room for 2 null terminations, one for the current var - * string, and one for final null of the var table. So check that the - * strlen written, r, leaves room for 2 chars. - */ - if ((r == -1) || (r > (int)(b->size - 2))) { - b->size = 0; - return 0; - } - - /* Remove any earlier occurrence of the same variable */ - s = strchr(b->buf, '='); - if (s != NULL) { - len = (size_t) (s - b->buf); - for (s = b->base; s < b->buf;) { - if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') { - len = strlen(s) + 1; - memmove(s, (s + len), - ((b->buf + r + 1) - (s + len))); - b->buf -= len; - b->size += (unsigned int)len; - break; - } - - while (*s++) - ; - } - } - - /* skip over this string's null termination */ - r++; - b->size -= r; - b->buf += r; - - return r; -} - -/* - * Initialize local vars from the right source for this platform. - * Return 0 on success, nonzero on error. - */ -int srom_var_init(si_t *sih, uint bustype, void *curmap, - char **vars, uint *count) -{ - uint len; - - len = 0; - - ASSERT(bustype == bustype); - if (vars == NULL || count == NULL) - return 0; - - *vars = NULL; - *count = 0; - - switch (bustype) { - case SI_BUS: - case JTAG_BUS: - return initvars_srom_si(sih, curmap, vars, count); - - case PCI_BUS: - ASSERT(curmap != NULL); - if (curmap == NULL) - return -1; - - return initvars_srom_pci(sih, curmap, vars, count); - -#ifdef BCMSDIO - case SDIO_BUS: - return initvars_cis_sdio(vars, count); -#endif /* BCMSDIO */ - - default: - ASSERT(0); - } - return -1; -} - -/* support only 16-bit word read from srom */ -int -srom_read(si_t *sih, uint bustype, void *curmap, - uint byteoff, uint nbytes, u16 *buf, bool check_crc) -{ - uint off, nw; -#ifdef BCMSDIO - uint i; -#endif /* BCMSDIO */ - - ASSERT(bustype == bustype); - - /* check input - 16-bit access only */ - if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX) - return 1; - - off = byteoff / 2; - nw = nbytes / 2; - - if (bustype == PCI_BUS) { - if (!curmap) - return 1; - - if (si_is_sprom_available(sih)) { - u16 *srom; - - srom = (u16 *) SROM_OFFSET(sih); - if (srom == NULL) - return 1; - - if (sprom_read_pci - (sih, srom, off, buf, nw, check_crc)) - return 1; - } -#if defined(BCMNVRAMR) - else { - if (otp_read_pci(sih, buf, SROM_MAX)) - return 1; - } -#endif -#ifdef BCMSDIO - } else if (bustype == SDIO_BUS) { - off = byteoff / 2; - nw = nbytes / 2; - for (i = 0; i < nw; i++) { - if (sprom_read_sdio - ((u16) (off + i), (u16 *) (buf + i))) - return 1; - } -#endif /* BCMSDIO */ - } else if (bustype == SI_BUS) { - return 1; - } else { - return 1; - } - - return 0; -} - -static const char vstr_manf[] = "manf=%s"; -static const char vstr_productname[] = "productname=%s"; -static const char vstr_manfid[] = "manfid=0x%x"; -static const char vstr_prodid[] = "prodid=0x%x"; -#ifdef BCMSDIO -static const char vstr_sdmaxspeed[] = "sdmaxspeed=%d"; -static const char vstr_sdmaxblk[][13] = { -"sdmaxblk0=%d", "sdmaxblk1=%d", "sdmaxblk2=%d"}; -#endif -static const char vstr_regwindowsz[] = "regwindowsz=%d"; -static const char vstr_sromrev[] = "sromrev=%d"; -static const char vstr_chiprev[] = "chiprev=%d"; -static const char vstr_subvendid[] = "subvendid=0x%x"; -static const char vstr_subdevid[] = "subdevid=0x%x"; -static const char vstr_boardrev[] = "boardrev=0x%x"; -static const char vstr_aa2g[] = "aa2g=0x%x"; -static const char vstr_aa5g[] = "aa5g=0x%x"; -static const char vstr_ag[] = "ag%d=0x%x"; -static const char vstr_cc[] = "cc=%d"; -static const char vstr_opo[] = "opo=%d"; -static const char vstr_pa0b[][9] = { -"pa0b0=%d", "pa0b1=%d", "pa0b2=%d"}; - -static const char vstr_pa0itssit[] = "pa0itssit=%d"; -static const char vstr_pa0maxpwr[] = "pa0maxpwr=%d"; -static const char vstr_pa1b[][9] = { -"pa1b0=%d", "pa1b1=%d", "pa1b2=%d"}; - -static const char vstr_pa1lob[][11] = { -"pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d"}; - -static const char vstr_pa1hib[][11] = { -"pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d"}; - -static const char vstr_pa1itssit[] = "pa1itssit=%d"; -static const char vstr_pa1maxpwr[] = "pa1maxpwr=%d"; -static const char vstr_pa1lomaxpwr[] = "pa1lomaxpwr=%d"; -static const char vstr_pa1himaxpwr[] = "pa1himaxpwr=%d"; -static const char vstr_oem[] = - "oem=%02x%02x%02x%02x%02x%02x%02x%02x"; -static const char vstr_boardflags[] = "boardflags=0x%x"; -static const char vstr_boardflags2[] = "boardflags2=0x%x"; -static const char vstr_ledbh[] = "ledbh%d=0x%x"; -static const char vstr_noccode[] = "ccode=0x0"; -static const char vstr_ccode[] = "ccode=%c%c"; -static const char vstr_cctl[] = "cctl=0x%x"; -static const char vstr_cckpo[] = "cckpo=0x%x"; -static const char vstr_ofdmpo[] = "ofdmpo=0x%x"; -static const char vstr_rdlid[] = "rdlid=0x%x"; -static const char vstr_rdlrndis[] = "rdlrndis=%d"; -static const char vstr_rdlrwu[] = "rdlrwu=%d"; -static const char vstr_usbfs[] = "usbfs=%d"; -static const char vstr_wpsgpio[] = "wpsgpio=%d"; -static const char vstr_wpsled[] = "wpsled=%d"; -static const char vstr_rdlsn[] = "rdlsn=%d"; -static const char vstr_rssismf2g[] = "rssismf2g=%d"; -static const char vstr_rssismc2g[] = "rssismc2g=%d"; -static const char vstr_rssisav2g[] = "rssisav2g=%d"; -static const char vstr_bxa2g[] = "bxa2g=%d"; -static const char vstr_rssismf5g[] = "rssismf5g=%d"; -static const char vstr_rssismc5g[] = "rssismc5g=%d"; -static const char vstr_rssisav5g[] = "rssisav5g=%d"; -static const char vstr_bxa5g[] = "bxa5g=%d"; -static const char vstr_tri2g[] = "tri2g=%d"; -static const char vstr_tri5gl[] = "tri5gl=%d"; -static const char vstr_tri5g[] = "tri5g=%d"; -static const char vstr_tri5gh[] = "tri5gh=%d"; -static const char vstr_rxpo2g[] = "rxpo2g=%d"; -static const char vstr_rxpo5g[] = "rxpo5g=%d"; -static const char vstr_boardtype[] = "boardtype=0x%x"; -static const char vstr_leddc[] = "leddc=0x%04x"; -static const char vstr_vendid[] = "vendid=0x%x"; -static const char vstr_devid[] = "devid=0x%x"; -static const char vstr_xtalfreq[] = "xtalfreq=%d"; -static const char vstr_txchain[] = "txchain=0x%x"; -static const char vstr_rxchain[] = "rxchain=0x%x"; -static const char vstr_antswitch[] = "antswitch=0x%x"; -static const char vstr_regrev[] = "regrev=0x%x"; -static const char vstr_antswctl2g[] = "antswctl2g=0x%x"; -static const char vstr_triso2g[] = "triso2g=0x%x"; -static const char vstr_pdetrange2g[] = "pdetrange2g=0x%x"; -static const char vstr_extpagain2g[] = "extpagain2g=0x%x"; -static const char vstr_tssipos2g[] = "tssipos2g=0x%x"; -static const char vstr_antswctl5g[] = "antswctl5g=0x%x"; -static const char vstr_triso5g[] = "triso5g=0x%x"; -static const char vstr_pdetrange5g[] = "pdetrange5g=0x%x"; -static const char vstr_extpagain5g[] = "extpagain5g=0x%x"; -static const char vstr_tssipos5g[] = "tssipos5g=0x%x"; -static const char vstr_maxp2ga0[] = "maxp2ga0=0x%x"; -static const char vstr_itt2ga0[] = "itt2ga0=0x%x"; -static const char vstr_pa[] = "pa%dgw%da%d=0x%x"; -static const char vstr_pahl[] = "pa%dg%cw%da%d=0x%x"; -static const char vstr_maxp5ga0[] = "maxp5ga0=0x%x"; -static const char vstr_itt5ga0[] = "itt5ga0=0x%x"; -static const char vstr_maxp5gha0[] = "maxp5gha0=0x%x"; -static const char vstr_maxp5gla0[] = "maxp5gla0=0x%x"; -static const char vstr_maxp2ga1[] = "maxp2ga1=0x%x"; -static const char vstr_itt2ga1[] = "itt2ga1=0x%x"; -static const char vstr_maxp5ga1[] = "maxp5ga1=0x%x"; -static const char vstr_itt5ga1[] = "itt5ga1=0x%x"; -static const char vstr_maxp5gha1[] = "maxp5gha1=0x%x"; -static const char vstr_maxp5gla1[] = "maxp5gla1=0x%x"; -static const char vstr_cck2gpo[] = "cck2gpo=0x%x"; -static const char vstr_ofdm2gpo[] = "ofdm2gpo=0x%x"; -static const char vstr_ofdm5gpo[] = "ofdm5gpo=0x%x"; -static const char vstr_ofdm5glpo[] = "ofdm5glpo=0x%x"; -static const char vstr_ofdm5ghpo[] = "ofdm5ghpo=0x%x"; -static const char vstr_cddpo[] = "cddpo=0x%x"; -static const char vstr_stbcpo[] = "stbcpo=0x%x"; -static const char vstr_bw40po[] = "bw40po=0x%x"; -static const char vstr_bwduppo[] = "bwduppo=0x%x"; -static const char vstr_mcspo[] = "mcs%dgpo%d=0x%x"; -static const char vstr_mcspohl[] = "mcs%dg%cpo%d=0x%x"; -static const char vstr_custom[] = "customvar%d=0x%x"; -static const char vstr_cckdigfilttype[] = "cckdigfilttype=%d"; -static const char vstr_boardnum[] = "boardnum=%d"; -static const char vstr_macaddr[] = "macaddr=%s"; -static const char vstr_usbepnum[] = "usbepnum=0x%x"; -static const char vstr_end[] = "END\0"; - -u8 patch_pair; - -/* For dongle HW, accept partial calibration parameters */ -#define BCMDONGLECASE(n) - -int srom_parsecis(u8 *pcis[], uint ciscnt, char **vars, - uint *count) -{ - char eabuf[32]; - char *base; - varbuf_t b; - u8 *cis, tup, tlen, sromrev = 1; - int i, j; - bool ag_init = false; - u32 w32; - uint funcid; - uint cisnum; - s32 boardnum; - int err; - bool standard_cis; - - ASSERT(vars != NULL); - ASSERT(count != NULL); - - boardnum = -1; - - base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - ASSERT(base != NULL); - if (!base) - return -2; - - varbuf_init(&b, base, MAXSZ_NVRAM_VARS); - memset(base, 0, MAXSZ_NVRAM_VARS); - eabuf[0] = '\0'; - for (cisnum = 0; cisnum < ciscnt; cisnum++) { - cis = *pcis++; - i = 0; - funcid = 0; - standard_cis = true; - do { - if (standard_cis) { - tup = cis[i++]; - if (tup == CISTPL_NULL || tup == CISTPL_END) - tlen = 0; - else - tlen = cis[i++]; - } else { - if (cis[i] == CISTPL_NULL - || cis[i] == CISTPL_END) { - tlen = 0; - tup = cis[i]; - } else { - tlen = cis[i]; - tup = CISTPL_BRCM_HNBU; - } - ++i; - } - if ((i + tlen) >= CIS_SIZE) - break; - - switch (tup) { - case CISTPL_VERS_1: - /* assume the strings are good if the version field checks out */ - if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) { - varbuf_append(&b, vstr_manf, - &cis[i + 2]); - varbuf_append(&b, vstr_productname, - &cis[i + 3 + - strlen((char *) - &cis[i + - 2])]); - break; - } - - case CISTPL_MANFID: - varbuf_append(&b, vstr_manfid, - (cis[i + 1] << 8) + cis[i]); - varbuf_append(&b, vstr_prodid, - (cis[i + 3] << 8) + cis[i + 2]); - break; - - case CISTPL_FUNCID: - funcid = cis[i]; - break; - - case CISTPL_FUNCE: - switch (funcid) { - case CISTPL_FID_SDIO: -#ifdef BCMSDIO - if (cis[i] == 0) { - u8 spd = cis[i + 3]; - static int base[] = { - -1, 10, 12, 13, 15, 20, - 25, 30, - 35, 40, 45, 50, 55, 60, - 70, 80 - }; - static int mult[] = { - 10, 100, 1000, 10000, - -1, -1, -1, -1 - }; - ASSERT((mult[spd & 0x7] != -1) - && - (base - [(spd >> 3) & 0x0f])); - varbuf_append(&b, - vstr_sdmaxblk[0], - (cis[i + 2] << 8) - + cis[i + 1]); - varbuf_append(&b, - vstr_sdmaxspeed, - (mult[spd & 0x7] * - base[(spd >> 3) & - 0x0f])); - } else if (cis[i] == 1) { - varbuf_append(&b, - vstr_sdmaxblk - [cisnum], - (cis[i + 13] << 8) - | cis[i + 12]); - } -#endif /* BCMSDIO */ - funcid = 0; - break; - default: - /* set macaddr if HNBU_MACADDR not seen yet */ - if (eabuf[0] == '\0' && - cis[i] == LAN_NID && - !is_zero_ether_addr(&cis[i + 2]) && - !is_multicast_ether_addr(&cis[i + 2])) { - ASSERT(cis[i + 1] == - ETH_ALEN); - snprintf(eabuf, sizeof(eabuf), - "%pM", &cis[i + 2]); - - /* set boardnum if HNBU_BOARDNUM not seen yet */ - if (boardnum == -1) - boardnum = - (cis[i + 6] << 8) + - cis[i + 7]; - } - break; - } - break; - - case CISTPL_CFTABLE: - varbuf_append(&b, vstr_regwindowsz, - (cis[i + 7] << 8) | cis[i + 6]); - break; - - case CISTPL_BRCM_HNBU: - switch (cis[i]) { - case HNBU_SROMREV: - sromrev = cis[i + 1]; - varbuf_append(&b, vstr_sromrev, - sromrev); - break; - - case HNBU_XTALFREQ: - varbuf_append(&b, vstr_xtalfreq, - (cis[i + 4] << 24) | - (cis[i + 3] << 16) | - (cis[i + 2] << 8) | - cis[i + 1]); - break; - - case HNBU_CHIPID: - varbuf_append(&b, vstr_vendid, - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_devid, - (cis[i + 4] << 8) + - cis[i + 3]); - if (tlen >= 7) { - varbuf_append(&b, vstr_chiprev, - (cis[i + 6] << 8) - + cis[i + 5]); - } - if (tlen >= 9) { - varbuf_append(&b, - vstr_subvendid, - (cis[i + 8] << 8) - + cis[i + 7]); - } - if (tlen >= 11) { - varbuf_append(&b, vstr_subdevid, - (cis[i + 10] << 8) - + cis[i + 9]); - /* subdevid doubles for boardtype */ - varbuf_append(&b, - vstr_boardtype, - (cis[i + 10] << 8) - + cis[i + 9]); - } - break; - - case HNBU_BOARDNUM: - boardnum = - (cis[i + 2] << 8) + cis[i + 1]; - break; - - case HNBU_PATCH: - { - char vstr_paddr[16]; - char vstr_pdata[16]; - - /* retrieve the patch pairs - * from tlen/6; where 6 is - * sizeof(patch addr(2)) + - * sizeof(patch data(4)). - */ - patch_pair = tlen / 6; - - for (j = 0; j < patch_pair; j++) { - snprintf(vstr_paddr, - sizeof - (vstr_paddr), - "pa%d=0x%%x", - j); - snprintf(vstr_pdata, - sizeof - (vstr_pdata), - "pd%d=0x%%x", - j); - - varbuf_append(&b, - vstr_paddr, - (cis - [i + - (j * - 6) + - 2] << 8) - | cis[i + - (j * - 6) - + - 1]); - - varbuf_append(&b, - vstr_pdata, - (cis - [i + - (j * - 6) + - 6] << - 24) | - (cis - [i + - (j * - 6) + - 5] << - 16) | - (cis - [i + - (j * - 6) + - 4] << 8) - | cis[i + - (j * - 6) - + - 3]); - } - } - break; - - case HNBU_BOARDREV: - if (tlen == 2) - varbuf_append(&b, vstr_boardrev, - cis[i + 1]); - else - varbuf_append(&b, vstr_boardrev, - (cis[i + 2] << 8) - + cis[i + 1]); - break; - - case HNBU_BOARDFLAGS: - w32 = (cis[i + 2] << 8) + cis[i + 1]; - if (tlen >= 5) - w32 |= - ((cis[i + 4] << 24) + - (cis[i + 3] << 16)); - varbuf_append(&b, vstr_boardflags, w32); - - if (tlen >= 7) { - w32 = - (cis[i + 6] << 8) + cis[i + - 5]; - if (tlen >= 9) - w32 |= - ((cis[i + 8] << 24) - + - (cis[i + 7] << - 16)); - varbuf_append(&b, - vstr_boardflags2, - w32); - } - break; - - case HNBU_USBFS: - varbuf_append(&b, vstr_usbfs, - cis[i + 1]); - break; - - case HNBU_BOARDTYPE: - varbuf_append(&b, vstr_boardtype, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_HNBUCIS: - /* - * what follows is a nonstandard HNBU CIS - * that lacks CISTPL_BRCM_HNBU tags - * - * skip 0xff (end of standard CIS) - * after this tuple - */ - tlen++; - standard_cis = false; - break; - - case HNBU_USBEPNUM: - varbuf_append(&b, vstr_usbepnum, - (cis[i + 2] << 8) | cis[i - + - 1]); - break; - - case HNBU_AA: - varbuf_append(&b, vstr_aa2g, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_aa5g, - cis[i + 2]); - break; - - case HNBU_AG: - varbuf_append(&b, vstr_ag, 0, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_ag, 1, - cis[i + 2]); - if (tlen >= 4) - varbuf_append(&b, vstr_ag, 2, - cis[i + 3]); - if (tlen >= 5) - varbuf_append(&b, vstr_ag, 3, - cis[i + 4]); - ag_init = true; - break; - - case HNBU_ANT5G: - varbuf_append(&b, vstr_aa5g, - cis[i + 1]); - varbuf_append(&b, vstr_ag, 1, - cis[i + 2]); - break; - - case HNBU_CC: - ASSERT(sromrev == 1); - varbuf_append(&b, vstr_cc, cis[i + 1]); - break; - - case HNBU_PAPARMS: - switch (tlen) { - case 2: - ASSERT(sromrev == 1); - varbuf_append(&b, - vstr_pa0maxpwr, - cis[i + 1]); - break; - case 10: - ASSERT(sromrev >= 2); - varbuf_append(&b, vstr_opo, - cis[i + 9]); - /* FALLTHROUGH */ - case 9: - varbuf_append(&b, - vstr_pa0maxpwr, - cis[i + 8]); - /* FALLTHROUGH */ - BCMDONGLECASE(8) - varbuf_append(&b, - vstr_pa0itssit, - cis[i + 7]); - /* FALLTHROUGH */ - BCMDONGLECASE(7) - for (j = 0; j < 3; j++) { - varbuf_append(&b, - vstr_pa0b - [j], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - break; - default: - ASSERT((tlen == 2) - || (tlen == 9) - || (tlen == 10)); - break; - } - break; - - case HNBU_PAPARMS5G: - ASSERT((sromrev == 2) - || (sromrev == 3)); - switch (tlen) { - case 23: - varbuf_append(&b, - vstr_pa1himaxpwr, - cis[i + 22]); - varbuf_append(&b, - vstr_pa1lomaxpwr, - cis[i + 21]); - varbuf_append(&b, - vstr_pa1maxpwr, - cis[i + 20]); - /* FALLTHROUGH */ - case 20: - varbuf_append(&b, - vstr_pa1itssit, - cis[i + 19]); - /* FALLTHROUGH */ - case 19: - for (j = 0; j < 3; j++) { - varbuf_append(&b, - vstr_pa1b - [j], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - for (j = 3; j < 6; j++) { - varbuf_append(&b, - vstr_pa1lob - [j - 3], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - for (j = 6; j < 9; j++) { - varbuf_append(&b, - vstr_pa1hib - [j - 6], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - break; - default: - ASSERT((tlen == 19) || - (tlen == 20) - || (tlen == 23)); - break; - } - break; - - case HNBU_OEM: - ASSERT(sromrev == 1); - varbuf_append(&b, vstr_oem, - cis[i + 1], cis[i + 2], - cis[i + 3], cis[i + 4], - cis[i + 5], cis[i + 6], - cis[i + 7], cis[i + 8]); - break; - - case HNBU_LEDS: - for (j = 1; j <= 4; j++) { - if (cis[i + j] != 0xff) { - varbuf_append(&b, - vstr_ledbh, - j - 1, - cis[i + - j]); - } - } - break; - - case HNBU_CCODE: - ASSERT(sromrev > 1); - if ((cis[i + 1] == 0) - || (cis[i + 2] == 0)) - varbuf_append(&b, vstr_noccode); - else - varbuf_append(&b, vstr_ccode, - cis[i + 1], - cis[i + 2]); - varbuf_append(&b, vstr_cctl, - cis[i + 3]); - break; - - case HNBU_CCKPO: - ASSERT(sromrev > 2); - varbuf_append(&b, vstr_cckpo, - (cis[i + 2] << 8) | cis[i - + - 1]); - break; - - case HNBU_OFDMPO: - ASSERT(sromrev > 2); - varbuf_append(&b, vstr_ofdmpo, - (cis[i + 4] << 24) | - (cis[i + 3] << 16) | - (cis[i + 2] << 8) | - cis[i + 1]); - break; - - case HNBU_WPS: - varbuf_append(&b, vstr_wpsgpio, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_wpsled, - cis[i + 2]); - break; - - case HNBU_RSSISMBXA2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rssismf2g, - cis[i + 1] & 0xf); - varbuf_append(&b, vstr_rssismc2g, - (cis[i + 1] >> 4) & 0xf); - varbuf_append(&b, vstr_rssisav2g, - cis[i + 2] & 0x7); - varbuf_append(&b, vstr_bxa2g, - (cis[i + 2] >> 3) & 0x3); - break; - - case HNBU_RSSISMBXA5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rssismf5g, - cis[i + 1] & 0xf); - varbuf_append(&b, vstr_rssismc5g, - (cis[i + 1] >> 4) & 0xf); - varbuf_append(&b, vstr_rssisav5g, - cis[i + 2] & 0x7); - varbuf_append(&b, vstr_bxa5g, - (cis[i + 2] >> 3) & 0x3); - break; - - case HNBU_TRI2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_tri2g, - cis[i + 1]); - break; - - case HNBU_TRI5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_tri5gl, - cis[i + 1]); - varbuf_append(&b, vstr_tri5g, - cis[i + 2]); - varbuf_append(&b, vstr_tri5gh, - cis[i + 3]); - break; - - case HNBU_RXPO2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rxpo2g, - cis[i + 1]); - break; - - case HNBU_RXPO5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rxpo5g, - cis[i + 1]); - break; - - case HNBU_MACADDR: - if (!is_zero_ether_addr(&cis[i + 1]) && - !is_multicast_ether_addr(&cis[i + 1])) { - snprintf(eabuf, sizeof(eabuf), - "%pM", &cis[i + 1]); - - /* set boardnum if HNBU_BOARDNUM not seen yet */ - if (boardnum == -1) - boardnum = - (cis[i + 5] << 8) + - cis[i + 6]; - } - break; - - case HNBU_LEDDC: - /* CIS leddc only has 16bits, convert it to 32bits */ - w32 = ((cis[i + 2] << 24) | /* oncount */ - (cis[i + 1] << 8)); /* offcount */ - varbuf_append(&b, vstr_leddc, w32); - break; - - case HNBU_CHAINSWITCH: - varbuf_append(&b, vstr_txchain, - cis[i + 1]); - varbuf_append(&b, vstr_rxchain, - cis[i + 2]); - varbuf_append(&b, vstr_antswitch, - (cis[i + 4] << 8) + - cis[i + 3]); - break; - - case HNBU_REGREV: - varbuf_append(&b, vstr_regrev, - cis[i + 1]); - break; - - case HNBU_FEM:{ - u16 fem = - (cis[i + 2] << 8) + cis[i + - 1]; - varbuf_append(&b, - vstr_antswctl2g, - (fem & - SROM8_FEM_ANTSWLUT_MASK) - >> - SROM8_FEM_ANTSWLUT_SHIFT); - varbuf_append(&b, vstr_triso2g, - (fem & - SROM8_FEM_TR_ISO_MASK) - >> - SROM8_FEM_TR_ISO_SHIFT); - varbuf_append(&b, - vstr_pdetrange2g, - (fem & - SROM8_FEM_PDET_RANGE_MASK) - >> - SROM8_FEM_PDET_RANGE_SHIFT); - varbuf_append(&b, - vstr_extpagain2g, - (fem & - SROM8_FEM_EXTPA_GAIN_MASK) - >> - SROM8_FEM_EXTPA_GAIN_SHIFT); - varbuf_append(&b, - vstr_tssipos2g, - (fem & - SROM8_FEM_TSSIPOS_MASK) - >> - SROM8_FEM_TSSIPOS_SHIFT); - if (tlen < 5) - break; - - fem = - (cis[i + 4] << 8) + cis[i + - 3]; - varbuf_append(&b, - vstr_antswctl5g, - (fem & - SROM8_FEM_ANTSWLUT_MASK) - >> - SROM8_FEM_ANTSWLUT_SHIFT); - varbuf_append(&b, vstr_triso5g, - (fem & - SROM8_FEM_TR_ISO_MASK) - >> - SROM8_FEM_TR_ISO_SHIFT); - varbuf_append(&b, - vstr_pdetrange5g, - (fem & - SROM8_FEM_PDET_RANGE_MASK) - >> - SROM8_FEM_PDET_RANGE_SHIFT); - varbuf_append(&b, - vstr_extpagain5g, - (fem & - SROM8_FEM_EXTPA_GAIN_MASK) - >> - SROM8_FEM_EXTPA_GAIN_SHIFT); - varbuf_append(&b, - vstr_tssipos5g, - (fem & - SROM8_FEM_TSSIPOS_MASK) - >> - SROM8_FEM_TSSIPOS_SHIFT); - break; - } - - case HNBU_PAPARMS_C0: - varbuf_append(&b, vstr_maxp2ga0, - cis[i + 1]); - varbuf_append(&b, vstr_itt2ga0, - cis[i + 2]); - varbuf_append(&b, vstr_pa, 2, 0, 0, - (cis[i + 4] << 8) + - cis[i + 3]); - varbuf_append(&b, vstr_pa, 2, 1, 0, - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_pa, 2, 2, 0, - (cis[i + 8] << 8) + - cis[i + 7]); - if (tlen < 31) - break; - - varbuf_append(&b, vstr_maxp5ga0, - cis[i + 9]); - varbuf_append(&b, vstr_itt5ga0, - cis[i + 10]); - varbuf_append(&b, vstr_maxp5gha0, - cis[i + 11]); - varbuf_append(&b, vstr_maxp5gla0, - cis[i + 12]); - varbuf_append(&b, vstr_pa, 5, 0, 0, - (cis[i + 14] << 8) + - cis[i + 13]); - varbuf_append(&b, vstr_pa, 5, 1, 0, - (cis[i + 16] << 8) + - cis[i + 15]); - varbuf_append(&b, vstr_pa, 5, 2, 0, - (cis[i + 18] << 8) + - cis[i + 17]); - varbuf_append(&b, vstr_pahl, 5, 'l', 0, - 0, - (cis[i + 20] << 8) + - cis[i + 19]); - varbuf_append(&b, vstr_pahl, 5, 'l', 1, - 0, - (cis[i + 22] << 8) + - cis[i + 21]); - varbuf_append(&b, vstr_pahl, 5, 'l', 2, - 0, - (cis[i + 24] << 8) + - cis[i + 23]); - varbuf_append(&b, vstr_pahl, 5, 'h', 0, - 0, - (cis[i + 26] << 8) + - cis[i + 25]); - varbuf_append(&b, vstr_pahl, 5, 'h', 1, - 0, - (cis[i + 28] << 8) + - cis[i + 27]); - varbuf_append(&b, vstr_pahl, 5, 'h', 2, - 0, - (cis[i + 30] << 8) + - cis[i + 29]); - break; - - case HNBU_PAPARMS_C1: - varbuf_append(&b, vstr_maxp2ga1, - cis[i + 1]); - varbuf_append(&b, vstr_itt2ga1, - cis[i + 2]); - varbuf_append(&b, vstr_pa, 2, 0, 1, - (cis[i + 4] << 8) + - cis[i + 3]); - varbuf_append(&b, vstr_pa, 2, 1, 1, - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_pa, 2, 2, 1, - (cis[i + 8] << 8) + - cis[i + 7]); - if (tlen < 31) - break; - - varbuf_append(&b, vstr_maxp5ga1, - cis[i + 9]); - varbuf_append(&b, vstr_itt5ga1, - cis[i + 10]); - varbuf_append(&b, vstr_maxp5gha1, - cis[i + 11]); - varbuf_append(&b, vstr_maxp5gla1, - cis[i + 12]); - varbuf_append(&b, vstr_pa, 5, 0, 1, - (cis[i + 14] << 8) + - cis[i + 13]); - varbuf_append(&b, vstr_pa, 5, 1, 1, - (cis[i + 16] << 8) + - cis[i + 15]); - varbuf_append(&b, vstr_pa, 5, 2, 1, - (cis[i + 18] << 8) + - cis[i + 17]); - varbuf_append(&b, vstr_pahl, 5, 'l', 0, - 1, - (cis[i + 20] << 8) + - cis[i + 19]); - varbuf_append(&b, vstr_pahl, 5, 'l', 1, - 1, - (cis[i + 22] << 8) + - cis[i + 21]); - varbuf_append(&b, vstr_pahl, 5, 'l', 2, - 1, - (cis[i + 24] << 8) + - cis[i + 23]); - varbuf_append(&b, vstr_pahl, 5, 'h', 0, - 1, - (cis[i + 26] << 8) + - cis[i + 25]); - varbuf_append(&b, vstr_pahl, 5, 'h', 1, - 1, - (cis[i + 28] << 8) + - cis[i + 27]); - varbuf_append(&b, vstr_pahl, 5, 'h', 2, - 1, - (cis[i + 30] << 8) + - cis[i + 29]); - break; - - case HNBU_PO_CCKOFDM: - varbuf_append(&b, vstr_cck2gpo, - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_ofdm2gpo, - (cis[i + 6] << 24) + - (cis[i + 5] << 16) + - (cis[i + 4] << 8) + - cis[i + 3]); - if (tlen < 19) - break; - - varbuf_append(&b, vstr_ofdm5gpo, - (cis[i + 10] << 24) + - (cis[i + 9] << 16) + - (cis[i + 8] << 8) + - cis[i + 7]); - varbuf_append(&b, vstr_ofdm5glpo, - (cis[i + 14] << 24) + - (cis[i + 13] << 16) + - (cis[i + 12] << 8) + - cis[i + 11]); - varbuf_append(&b, vstr_ofdm5ghpo, - (cis[i + 18] << 24) + - (cis[i + 17] << 16) + - (cis[i + 16] << 8) + - cis[i + 15]); - break; - - case HNBU_PO_MCS2G: - for (j = 0; j <= (tlen / 2); j++) { - varbuf_append(&b, vstr_mcspo, 2, - j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - break; - - case HNBU_PO_MCS5GM: - for (j = 0; j <= (tlen / 2); j++) { - varbuf_append(&b, vstr_mcspo, 5, - j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - break; - - case HNBU_PO_MCS5GLH: - for (j = 0; j <= (tlen / 4); j++) { - varbuf_append(&b, vstr_mcspohl, - 5, 'l', j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - - for (j = 0; j <= (tlen / 4); j++) { - varbuf_append(&b, vstr_mcspohl, - 5, 'h', j, - (cis - [i + - ((tlen / 2) + - 2) + - 2 * j] << 8) + - cis[i + - ((tlen / 2) + - 1) + 2 * j]); - } - - break; - - case HNBU_PO_CDD: - varbuf_append(&b, vstr_cddpo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_STBC: - varbuf_append(&b, vstr_stbcpo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_40M: - varbuf_append(&b, vstr_bw40po, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_40MDUP: - varbuf_append(&b, vstr_bwduppo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_OFDMPO5G: - varbuf_append(&b, vstr_ofdm5gpo, - (cis[i + 4] << 24) + - (cis[i + 3] << 16) + - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_ofdm5glpo, - (cis[i + 8] << 24) + - (cis[i + 7] << 16) + - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_ofdm5ghpo, - (cis[i + 12] << 24) + - (cis[i + 11] << 16) + - (cis[i + 10] << 8) + - cis[i + 9]); - break; - - case HNBU_CUSTOM1: - varbuf_append(&b, vstr_custom, 1, - ((cis[i + 4] << 24) + - (cis[i + 3] << 16) + - (cis[i + 2] << 8) + - cis[i + 1])); - break; - -#if defined(BCMSDIO) - case HNBU_SROM3SWRGN: - if (tlen >= 73) { - u16 srom[35]; - u8 srev = cis[i + 1 + 70]; - ASSERT(srev == 3); - /* make tuple value 16-bit aligned and parse it */ - memcpy(srom, &cis[i + 1], - sizeof(srom)); - _initvars_srom_pci(srev, srom, - SROM3_SWRGN_OFF, - &b); - /* 2.4G antenna gain is included in SROM */ - ag_init = true; - /* Ethernet MAC address is included in SROM */ - eabuf[0] = 0; - boardnum = -1; - } - /* create extra variables */ - if (tlen >= 75) - varbuf_append(&b, vstr_vendid, - (cis[i + 1 + 73] - << 8) + cis[i + - 1 + - 72]); - if (tlen >= 77) - varbuf_append(&b, vstr_devid, - (cis[i + 1 + 75] - << 8) + cis[i + - 1 + - 74]); - if (tlen >= 79) - varbuf_append(&b, vstr_xtalfreq, - (cis[i + 1 + 77] - << 8) + cis[i + - 1 + - 76]); - break; -#endif /* defined(BCMSDIO) */ - - case HNBU_CCKFILTTYPE: - varbuf_append(&b, vstr_cckdigfilttype, - (cis[i + 1])); - break; - } - - break; - } - i += tlen; - } while (tup != CISTPL_END); - } - - if (boardnum != -1) { - varbuf_append(&b, vstr_boardnum, boardnum); - } - - if (eabuf[0]) { - varbuf_append(&b, vstr_macaddr, eabuf); - } - - /* if there is no antenna gain field, set default */ - if (getvar(NULL, "ag0") == NULL && ag_init == false) { - varbuf_append(&b, vstr_ag, 0, 0xff); - } - - /* final nullbyte terminator */ - ASSERT(b.size >= 1); - *b.buf++ = '\0'; - - ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS); - err = initvars_table(base, b.buf, vars, count); - - kfree(base); - return err; -} - -/* In chips with chipcommon rev 32 and later, the srom is in chipcommon, - * not in the bus cores. - */ -static u16 -srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, - uint wordoff, u16 data) -{ - chipcregs_t *cc = (chipcregs_t *) ccregs; - uint wait_cnt = 1000; - - if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) { - W_REG(&cc->sromaddress, wordoff * 2); - if (cmd == SRC_OP_WRITE) - W_REG(&cc->sromdata, data); - } - - W_REG(&cc->sromcontrol, SRC_START | cmd); - - while (wait_cnt--) { - if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0) - break; - } - - if (!wait_cnt) { - BS_ERROR(("%s: Command 0x%x timed out\n", __func__, cmd)); - return 0xffff; - } - if (cmd == SRC_OP_READ) - return (u16) R_REG(&cc->sromdata); - else - return 0xffff; -} - -static inline void ltoh16_buf(u16 *buf, unsigned int size) -{ - for (size /= 2; size; size--) - *(buf + size) = le16_to_cpu(*(buf + size)); -} - -static inline void htol16_buf(u16 *buf, unsigned int size) -{ - for (size /= 2; size; size--) - *(buf + size) = cpu_to_le16(*(buf + size)); -} - -/* - * Read in and validate sprom. - * Return 0 on success, nonzero on error. - */ -static int -sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, - u16 *buf, uint nwords, bool check_crc) -{ - int err = 0; - uint i; - void *ccregs = NULL; - - /* read the sprom */ - for (i = 0; i < nwords; i++) { - - if (sih->ccrev > 31 && ISSIM_ENAB(sih)) { - /* use indirect since direct is too slow on QT */ - if ((sih->cccaps & CC_CAP_SROM) == 0) - return 1; - - ccregs = (void *)((u8 *) sprom - CC_SROM_OTP); - buf[i] = - srom_cc_cmd(sih, ccregs, SRC_OP_READ, - wordoff + i, 0); - - } else { - if (ISSIM_ENAB(sih)) - buf[i] = R_REG(&sprom[wordoff + i]); - - buf[i] = R_REG(&sprom[wordoff + i]); - } - - } - - /* bypass crc checking for simulation to allow srom hack */ - if (ISSIM_ENAB(sih)) - return err; - - if (check_crc) { - - if (buf[0] == 0xffff) { - /* The hardware thinks that an srom that starts with 0xffff - * is blank, regardless of the rest of the content, so declare - * it bad. - */ - BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", - __func__, buf[0])); - return 1; - } - - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, nwords * 2); - if (hndcrc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { - /* DBG only pci always read srom4 first, then srom8/9 */ - /* BS_ERROR(("%s: bad crc\n", __func__)); */ - err = 1; - } - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, nwords * 2); - } - return err; -} - -#if defined(BCMNVRAMR) -static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) -{ - u8 *otp; - uint sz = OTP_SZ_MAX / 2; /* size in words */ - int err = 0; - - ASSERT(bufsz <= OTP_SZ_MAX); - - otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); - if (otp == NULL) { - return BCME_ERROR; - } - - err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); - - memcpy(buf, otp, bufsz); - - kfree(otp); - - /* Check CRC */ - if (buf[0] == 0xffff) { - /* The hardware thinks that an srom that starts with 0xffff - * is blank, regardless of the rest of the content, so declare - * it bad. - */ - BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __func__, - buf[0])); - return 1; - } - - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, bufsz); - if (hndcrc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { - BS_ERROR(("%s: bad crc\n", __func__)); - err = 1; - } - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, bufsz); - - return err; -} -#endif /* defined(BCMNVRAMR) */ -/* -* Create variable table from memory. -* Return 0 on success, nonzero on error. -*/ -static int initvars_table(char *start, char *end, - char **vars, uint *count) -{ - int c = (int)(end - start); - - /* do it only when there is more than just the null string */ - if (c > 1) { - char *vp = kmalloc(c, GFP_ATOMIC); - ASSERT(vp != NULL); - if (!vp) - return BCME_NOMEM; - memcpy(vp, start, c); - *vars = vp; - *count = c; - } else { - *vars = NULL; - *count = 0; - } - - return 0; -} - -/* - * Find variables with <devpath> from flash. 'base' points to the beginning - * of the table upon enter and to the end of the table upon exit when success. - * Return 0 on success, nonzero on error. - */ -static int initvars_flash(si_t *sih, char **base, uint len) -{ - char *vp = *base; - char *flash; - int err; - char *s; - uint l, dl, copy_len; - char devpath[SI_DEVPATH_BUFSZ]; - - /* allocate memory and read in flash */ - flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC); - if (!flash) - return BCME_NOMEM; - err = nvram_getall(flash, NVRAM_SPACE); - if (err) - goto exit; - - si_devpath(sih, devpath, sizeof(devpath)); - - /* grab vars with the <devpath> prefix in name */ - dl = strlen(devpath); - for (s = flash; s && *s; s += l + 1) { - l = strlen(s); - - /* skip non-matching variable */ - if (strncmp(s, devpath, dl)) - continue; - - /* is there enough room to copy? */ - copy_len = l - dl + 1; - if (len < copy_len) { - err = BCME_BUFTOOSHORT; - goto exit; - } - - /* no prefix, just the name=value */ - strncpy(vp, &s[dl], copy_len); - vp += copy_len; - len -= copy_len; - } - - /* add null string as terminator */ - if (len < 1) { - err = BCME_BUFTOOSHORT; - goto exit; - } - *vp++ = '\0'; - - *base = vp; - - exit: kfree(flash); - return err; -} - -/* - * Initialize nonvolatile variable table from flash. - * Return 0 on success, nonzero on error. - */ -static int initvars_flash_si(si_t *sih, char **vars, uint *count) -{ - char *vp, *base; - int err; - - ASSERT(vars != NULL); - ASSERT(count != NULL); - - base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - ASSERT(vp != NULL); - if (!vp) - return BCME_NOMEM; - - err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); - if (err == 0) - err = initvars_table(base, vp, vars, count); - - kfree(base); - - return err; -} - -/* Parse SROM and create name=value pairs. 'srom' points to - * the SROM word array. 'off' specifies the offset of the - * first word 'srom' points to, which should be either 0 or - * SROM3_SWRG_OFF (full SROM or software region). - */ - -static uint mask_shift(u16 mask) -{ - uint i; - for (i = 0; i < (sizeof(mask) << 3); i++) { - if (mask & (1 << i)) - return i; - } - ASSERT(mask); - return 0; -} - -static uint mask_width(u16 mask) -{ - int i; - for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) { - if (mask & (1 << i)) - return (uint) (i - mask_shift(mask) + 1); - } - ASSERT(mask); - return 0; -} - -#if defined(BCMDBG) -static bool mask_valid(u16 mask) -{ - uint shift = mask_shift(mask); - uint width = mask_width(mask); - return mask == ((~0 << shift) & ~(~0 << (shift + width))); -} -#endif /* BCMDBG */ - -static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b) -{ - u16 w; - u32 val; - const sromvar_t *srv; - uint width; - uint flags; - u32 sr = (1 << sromrev); - - varbuf_append(b, "sromrev=%d", sromrev); - - for (srv = pci_sromvars; srv->name != NULL; srv++) { - const char *name; - - if ((srv->revmask & sr) == 0) - continue; - - if (srv->off < off) - continue; - - flags = srv->flags; - name = srv->name; - - /* This entry is for mfgc only. Don't generate param for it, */ - if (flags & SRFL_NOVAR) - continue; - - if (flags & SRFL_ETHADDR) { - u8 ea[ETH_ALEN]; - - ea[0] = (srom[srv->off - off] >> 8) & 0xff; - ea[1] = srom[srv->off - off] & 0xff; - ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; - ea[3] = srom[srv->off + 1 - off] & 0xff; - ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; - ea[5] = srom[srv->off + 2 - off] & 0xff; - - varbuf_append(b, "%s=%pM", name, ea); - } else { - ASSERT(mask_valid(srv->mask)); - ASSERT(mask_width(srv->mask)); - - w = srom[srv->off - off]; - val = (w & srv->mask) >> mask_shift(srv->mask); - width = mask_width(srv->mask); - - while (srv->flags & SRFL_MORE) { - srv++; - ASSERT(srv->name != NULL); - - if (srv->off == 0 || srv->off < off) - continue; - - ASSERT(mask_valid(srv->mask)); - ASSERT(mask_width(srv->mask)); - - w = srom[srv->off - off]; - val += - ((w & srv->mask) >> mask_shift(srv-> - mask)) << - width; - width += mask_width(srv->mask); - } - - if ((flags & SRFL_NOFFS) - && ((int)val == (1 << width) - 1)) - continue; - - if (flags & SRFL_CCODE) { - if (val == 0) - varbuf_append(b, "ccode="); - else - varbuf_append(b, "ccode=%c%c", - (val >> 8), (val & 0xff)); - } - /* LED Powersave duty cycle has to be scaled: - *(oncount >> 24) (offcount >> 8) - */ - else if (flags & SRFL_LEDDC) { - u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */ - (((val & 0xff)) << 8); /* offcount */ - varbuf_append(b, "leddc=%d", w32); - } else if (flags & SRFL_PRHEX) - varbuf_append(b, "%s=0x%x", name, val); - else if ((flags & SRFL_PRSIGN) - && (val & (1 << (width - 1)))) - varbuf_append(b, "%s=%d", name, - (int)(val | (~0 << width))); - else - varbuf_append(b, "%s=%u", name, val); - } - } - - if (sromrev >= 4) { - /* Do per-path variables */ - uint p, pb, psz; - - if (sromrev >= 8) { - pb = SROM8_PATH0; - psz = SROM8_PATH1 - SROM8_PATH0; - } else { - pb = SROM4_PATH0; - psz = SROM4_PATH1 - SROM4_PATH0; - } - - for (p = 0; p < MAX_PATH_SROM; p++) { - for (srv = perpath_pci_sromvars; srv->name != NULL; - srv++) { - if ((srv->revmask & sr) == 0) - continue; - - if (pb + srv->off < off) - continue; - - /* This entry is for mfgc only. Don't generate param for it, */ - if (srv->flags & SRFL_NOVAR) - continue; - - w = srom[pb + srv->off - off]; - - ASSERT(mask_valid(srv->mask)); - val = (w & srv->mask) >> mask_shift(srv->mask); - width = mask_width(srv->mask); - - /* Cheating: no per-path var is more than 1 word */ - - if ((srv->flags & SRFL_NOFFS) - && ((int)val == (1 << width) - 1)) - continue; - - if (srv->flags & SRFL_PRHEX) - varbuf_append(b, "%s%d=0x%x", srv->name, - p, val); - else - varbuf_append(b, "%s%d=%d", srv->name, - p, val); - } - pb += psz; - } - } -} - -/* - * Initialize nonvolatile variable table from sprom. - * Return 0 on success, nonzero on error. - */ -static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) -{ - u16 *srom, *sromwindow; - u8 sromrev = 0; - u32 sr; - varbuf_t b; - char *vp, *base = NULL; - bool flash = false; - int err = 0; - - /* - * Apply CRC over SROM content regardless SROM is present or not, - * and use variable <devpath>sromrev's existence in flash to decide - * if we should return an error when CRC fails or read SROM variables - * from flash. - */ - srom = kmalloc(SROM_MAX, GFP_ATOMIC); - ASSERT(srom != NULL); - if (!srom) - return -2; - - sromwindow = (u16 *) SROM_OFFSET(sih); - if (si_is_sprom_available(sih)) { - err = - sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, - true); - - if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || - (((sih->buscoretype == PCIE_CORE_ID) - && (sih->buscorerev >= 6)) - || ((sih->buscoretype == PCI_CORE_ID) - && (sih->buscorerev >= 0xe)))) { - /* sromrev >= 4, read more */ - err = - sprom_read_pci(sih, sromwindow, 0, srom, - SROM4_WORDS, true); - sromrev = srom[SROM4_CRCREV] & 0xff; - if (err) - BS_ERROR(("%s: srom %d, bad crc\n", __func__, - sromrev)); - - } else if (err == 0) { - /* srom is good and is rev < 4 */ - /* top word of sprom contains version and crc8 */ - sromrev = srom[SROM_CRCREV] & 0xff; - /* bcm4401 sroms misprogrammed */ - if (sromrev == 0x10) - sromrev = 1; - } - } -#if defined(BCMNVRAMR) - /* Use OTP if SPROM not available */ - else { - err = otp_read_pci(sih, srom, SROM_MAX); - if (err == 0) - /* OTP only contain SROM rev8/rev9 for now */ - sromrev = srom[SROM4_CRCREV] & 0xff; - else - err = 1; - } -#else - else - err = 1; -#endif - - /* - * We want internal/wltest driver to come up with default - * sromvars so we can program a blank SPROM/OTP. - */ - if (err) { - char *value; - u32 val; - val = 0; - - BS_ERROR(("Neither SPROM nor OTP has valid image\n")); - value = si_getdevpathvar(sih, "sromrev"); - if (value) { - sromrev = (u8) simple_strtoul(value, NULL, 0); - flash = true; - goto varscont; - } - - BS_ERROR(("%s, SROM CRC Error\n", __func__)); - - value = si_getnvramflvar(sih, "sromrev"); - if (value) { - err = 0; - goto errout; - } - - { - err = -1; - goto errout; - } - } - - varscont: - /* Bitmask for the sromrev */ - sr = 1 << sromrev; - - /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */ - if ((sr & 0x33e) == 0) { - err = -2; - goto errout; - } - - ASSERT(vars != NULL); - ASSERT(count != NULL); - - base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - ASSERT(vp != NULL); - if (!vp) { - err = -2; - goto errout; - } - - /* read variables from flash */ - if (flash) { - err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); - if (err) - goto errout; - goto varsdone; - } - - varbuf_init(&b, base, MAXSZ_NVRAM_VARS); - - /* parse SROM into name=value pairs. */ - _initvars_srom_pci(sromrev, srom, 0, &b); - - /* final nullbyte terminator */ - ASSERT(b.size >= 1); - vp = b.buf; - *vp++ = '\0'; - - ASSERT((vp - base) <= MAXSZ_NVRAM_VARS); - - varsdone: - err = initvars_table(base, vp, vars, count); - - errout: - if (base) - kfree(base); - - kfree(srom); - return err; -} - -#ifdef BCMSDIO -/* - * Read the SDIO cis and call parsecis to initialize the vars. - * Return 0 on success, nonzero on error. - */ -static int initvars_cis_sdio(char **vars, uint *count) -{ - u8 *cis[SBSDIO_NUM_FUNCTION + 1]; - uint fn, numfn; - int rc = 0; - - numfn = bcmsdh_query_iofnum(NULL); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - for (fn = 0; fn <= numfn; fn++) { - cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC); - if (cis[fn] == NULL) { - rc = -1; - break; - } - - if (bcmsdh_cis_read(NULL, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT) != - 0) { - kfree(cis[fn]); - rc = -2; - break; - } - } - - if (!rc) - rc = srom_parsecis(cis, fn, vars, count); - - while (fn-- > 0) - kfree(cis[fn]); - - return rc; -} - -/* set SDIO sprom command register */ -static int sprom_cmd_sdio(u8 cmd) -{ - u8 status = 0; - uint wait_cnt = 1000; - - /* write sprom command register */ - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, cmd, NULL); - - /* wait status */ - while (wait_cnt--) { - status = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, NULL); - if (status & SBSDIO_SPROM_DONE) - return 0; - } - - return 1; -} - -/* read a word from the SDIO srom */ -static int sprom_read_sdio(u16 addr, u16 *data) -{ - u8 addr_l, addr_h, data_l, data_h; - - addr_l = (u8) ((addr * 2) & 0xff); - addr_h = (u8) (((addr * 2) >> 8) & 0xff); - - /* set address */ - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h, - NULL); - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l, - NULL); - - /* do read */ - if (sprom_cmd_sdio(SBSDIO_SPROM_READ)) - return 1; - - /* read data */ - data_h = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, NULL); - data_l = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, NULL); - - *data = (data_h << 8) | data_l; - return 0; -} -#endif /* BCMSDIO */ - -static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz) -{ - /* Search flash nvram section for srom variables */ - return initvars_flash_si(sih, vars, varsz); -} diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index fb0bcccfda44..43e5bb3aec02 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -21,18 +21,20 @@ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/sched.h> +#include <linux/printk.h> #include <bcmdefs.h> #include <stdarg.h> #include <bcmutils.h> -#include <siutils.h> #include <bcmnvram.h> #include <bcmdevs.h> #include <proto/802.11.h> -/* Global ASSERT type flag */ -u32 g_assert_type; +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); +MODULE_LICENSE("Dual BSD/GPL"); -struct sk_buff *BCMFASTPATH pkt_buf_get_skb(uint len) +struct sk_buff *bcm_pkt_buf_get_skb(uint len) { struct sk_buff *skb; @@ -44,15 +46,14 @@ struct sk_buff *BCMFASTPATH pkt_buf_get_skb(uint len) return skb; } +EXPORT_SYMBOL(bcm_pkt_buf_get_skb); /* Free the driver packet. Free the tag if present */ -void BCMFASTPATH pkt_buf_free_skb(struct sk_buff *skb) +void bcm_pkt_buf_free_skb(struct sk_buff *skb) { struct sk_buff *nskb; int nest = 0; - ASSERT(skb); - /* perversion: we use skb->next to chain multi-skb packets */ while (skb) { nskb = skb->next; @@ -73,9 +74,11 @@ void BCMFASTPATH pkt_buf_free_skb(struct sk_buff *skb) skb = nskb; } } +EXPORT_SYMBOL(bcm_pkt_buf_free_skb); + /* copy a buffer into a pkt buffer chain */ -uint pktfrombuf(struct sk_buff *p, uint offset, int len, +uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len, unsigned char *buf) { uint n, ret = 0; @@ -102,8 +105,10 @@ uint pktfrombuf(struct sk_buff *p, uint offset, int len, return ret; } +EXPORT_SYMBOL(bcm_pktfrombuf); + /* return total length of buffer chain */ -uint BCMFASTPATH pkttotlen(struct sk_buff *p) +uint bcm_pkttotlen(struct sk_buff *p) { uint total; @@ -112,21 +117,19 @@ uint BCMFASTPATH pkttotlen(struct sk_buff *p) total += p->len; return total; } +EXPORT_SYMBOL(bcm_pkttotlen); /* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ -struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, +struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(p->prev == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); + if (pktq_full(pq) || pktq_pfull(pq, prec)) + return NULL; q = &pq->q[prec]; @@ -145,17 +148,15 @@ struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, return p; } +EXPORT_SYMBOL(bcm_pktq_penq); -struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, +struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; - ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(p->prev == NULL); /* queueing chains not allowed */ - - ASSERT(!pktq_full(pq)); - ASSERT(!pktq_pfull(pq, prec)); + if (pktq_full(pq) || pktq_pfull(pq, prec)) + return NULL; q = &pq->q[prec]; @@ -173,14 +174,13 @@ struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, return p; } +EXPORT_SYMBOL(bcm_pktq_penq_head); -struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) +struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec) { struct pktq_prec *q; struct sk_buff *p; - ASSERT(prec >= 0 && prec < pq->num_prec); - q = &pq->q[prec]; p = q->head; @@ -199,14 +199,13 @@ struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) return p; } +EXPORT_SYMBOL(bcm_pktq_pdeq); -struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) +struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec) { struct pktq_prec *q; struct sk_buff *p, *prev; - ASSERT(prec >= 0 && prec < pq->num_prec); - q = &pq->q[prec]; p = q->head; @@ -228,38 +227,11 @@ struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) return p; } +EXPORT_SYMBOL(bcm_pktq_pdeq_tail); -#ifdef BRCM_FULLMAC -void pktq_pflush(struct pktq *pq, int prec, bool dir) -{ - struct pktq_prec *q; - struct sk_buff *p; - - q = &pq->q[prec]; - p = q->head; - while (p) { - q->head = p->prev; - p->prev = NULL; - pkt_buf_free_skb(p); - q->len--; - pq->len--; - p = q->head; - } - ASSERT(q->len == 0); - q->tail = NULL; -} - -void pktq_flush(struct pktq *pq, bool dir) -{ - int prec; - for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(pq, prec, dir); - ASSERT(pq->len == 0); -} -#else /* !BRCM_FULLMAC */ void -pktq_pflush(struct pktq *pq, int prec, bool dir, - ifpkt_cb_t fn, int arg) +bcm_pktq_pflush(struct pktq *pq, int prec, bool dir, + ifpkt_cb_t fn, void *arg) { struct pktq_prec *q; struct sk_buff *p, *prev = NULL; @@ -274,7 +246,7 @@ pktq_pflush(struct pktq *pq, int prec, bool dir, else prev->prev = p->prev; p->prev = NULL; - pkt_buf_free_skb(p); + bcm_pkt_buf_free_skb(p); q->len--; pq->len--; p = (head ? q->head : prev->prev); @@ -285,28 +257,24 @@ pktq_pflush(struct pktq *pq, int prec, bool dir, } if (q->head == NULL) { - ASSERT(q->len == 0); q->tail = NULL; } } +EXPORT_SYMBOL(bcm_pktq_pflush); -void pktq_flush(struct pktq *pq, bool dir, - ifpkt_cb_t fn, int arg) +void bcm_pktq_flush(struct pktq *pq, bool dir, + ifpkt_cb_t fn, void *arg) { int prec; for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(pq, prec, dir, fn, arg); - if (fn == NULL) - ASSERT(pq->len == 0); + bcm_pktq_pflush(pq, prec, dir, fn, arg); } -#endif /* BRCM_FULLMAC */ +EXPORT_SYMBOL(bcm_pktq_flush); -void pktq_init(struct pktq *pq, int num_prec, int max_len) +void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len) { int prec; - ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); - /* pq is variable size; only zero out what's requested */ memset(pq, 0, offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); @@ -318,8 +286,9 @@ void pktq_init(struct pktq *pq, int num_prec, int max_len) for (prec = 0; prec < num_prec; prec++) pq->q[prec].max = pq->max; } +EXPORT_SYMBOL(bcm_pktq_init); -struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out) +struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out) { int prec; @@ -335,9 +304,10 @@ struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out) return pq->q[prec].tail; } +EXPORT_SYMBOL(bcm_pktq_peek_tail); /* Return sum of lengths of a specific set of precedences */ -int pktq_mlen(struct pktq *pq, uint prec_bmp) +int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp) { int prec, len; @@ -349,8 +319,10 @@ int pktq_mlen(struct pktq *pq, uint prec_bmp) return len; } +EXPORT_SYMBOL(bcm_pktq_mlen); + /* Priority dequeue from a specific set of precedences */ -struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, +struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) { struct pktq_prec *q; @@ -388,6 +360,7 @@ struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, return p; } +EXPORT_SYMBOL(bcm_pktq_mdeq); /* parse a xx:xx:xx:xx:xx:xx format ethernet address */ int bcm_ether_atoe(char *p, u8 *ea) @@ -402,57 +375,11 @@ int bcm_ether_atoe(char *p, u8 *ea) return i == 6; } - -/* - * Search the name=value vars for a specific one and return its value. - * Returns NULL if not found. - */ -char *getvar(char *vars, const char *name) -{ - char *s; - int len; - - if (!name) - return NULL; - - len = strlen(name); - if (len == 0) - return NULL; - - /* first look in vars[] */ - for (s = vars; s && *s;) { - if ((memcmp(s, name, len) == 0) && (s[len] == '=')) - return &s[len + 1]; - - while (*s++) - ; - } -#ifdef BRCM_FULLMAC - return NULL; -#else - /* then query nvram */ - return nvram_get(name); -#endif -} - -/* - * Search the vars for a specific one and return its value as - * an integer. Returns 0 if not found. - */ -int getintvar(char *vars, const char *name) -{ - char *val; - - val = getvar(vars, name); - if (val == NULL) - return 0; - - return simple_strtoul(val, NULL, 0); -} +EXPORT_SYMBOL(bcm_ether_atoe); #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ -void prpkt(const char *msg, struct sk_buff *p0) +void bcm_prpkt(const char *msg, struct sk_buff *p0) { struct sk_buff *p; @@ -460,32 +387,11 @@ void prpkt(const char *msg, struct sk_buff *p0) printk(KERN_DEBUG "%s:\n", msg); for (p = p0; p; p = p->next) - prhex(NULL, p->data, p->len); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } +EXPORT_SYMBOL(bcm_prpkt); #endif /* defined(BCMDBG) */ -static char bcm_undeferrstr[BCME_STRLEN]; - -static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; - -/* Convert the error codes into related error strings */ -const char *bcmerrorstr(int bcmerror) -{ - /* check if someone added a bcmerror code but - forgot to add errorstring */ - ASSERT(ABS(BCME_LAST) == (ARRAY_SIZE(bcmerrorstrtable) - 1)); - - if (bcmerror > 0 || bcmerror < BCME_LAST) { - snprintf(bcm_undeferrstr, BCME_STRLEN, "Undefined error %d", - bcmerror); - return bcm_undeferrstr; - } - - ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); - - return bcmerrorstrtable[-bcmerror]; -} - /* iovar table lookup */ const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) { @@ -499,8 +405,6 @@ const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) else lookup_name = name; - ASSERT(table != NULL); - for (vi = table; vi->name; vi++) { if (!strcmp(vi->name, lookup_name)) return vi; @@ -509,6 +413,7 @@ const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) return NULL; /* var name not found */ } +EXPORT_SYMBOL(bcm_iovar_lookup); int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) { @@ -525,35 +430,35 @@ int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) case IOVT_UINT32: /* all integers are s32 sized args at the ioctl interface */ if (len < (int)sizeof(int)) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; } break; case IOVT_BUFFER: /* buffer must meet minimum length requirement */ if (len < vi->minlen) { - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -EOVERFLOW; } break; case IOVT_VOID: if (!set) { /* Cannot return nil... */ - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; } else if (len) { /* Set is an action w/o parameters */ - bcmerror = BCME_BUFTOOLONG; + bcmerror = -ENOBUFS; } break; default: /* unknown type for length check in iovar info */ - ASSERT(0); - bcmerror = BCME_UNSUPPORTED; + bcmerror = -ENOTSUPP; } return bcmerror; } +EXPORT_SYMBOL(bcm_iovar_lencheck); /******************************************************************************* * crc8 @@ -612,195 +517,18 @@ static const u8 crc8_table[256] = { 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F }; -#define CRC_INNER_LOOP(n, c, x) \ - ((c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]) - -u8 hndcrc8(u8 *pdata, /* pointer to array of data to process */ +u8 bcm_crc8(u8 *pdata, /* pointer to array of data to process */ uint nbytes, /* number of input data bytes to process */ u8 crc /* either CRC8_INIT_VALUE or previous return value */ ) { - /* hard code the crc loop instead of using CRC_INNER_LOOP macro - * to avoid the undefined and unnecessary (u8 >> 8) operation. - */ + /* loop over the buffer data */ while (nbytes-- > 0) crc = crc8_table[(crc ^ *pdata++) & 0xff]; return crc; } +EXPORT_SYMBOL(bcm_crc8); -/******************************************************************************* - * crc16 - * - * Computes a crc16 over the input data using the polynomial: - * - * x^16 + x^12 +x^5 + 1 - * - * The caller provides the initial value (either CRC16_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC16_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const u16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -}; - -u16 hndcrc16(u8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - u16 crc /* either CRC16_INIT_VALUE or previous return value */ - ) { - while (nbytes-- > 0) - CRC_INNER_LOOP(16, crc, *pdata++); - return crc; -} - -static const u32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -u32 hndcrc32(u8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - u32 crc /* either CRC32_INIT_VALUE or previous - return value */ -) -{ - u8 *pend; -#ifdef __mips__ - u8 tmp[4]; - unsigned long *tptr = (unsigned long *) tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (u8 *) ((uint) (pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = *(unsigned long *) pdata; - pdata += sizeof(unsigned long *); - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else - pend = pdata + nbytes; - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#endif /* __mips__ */ - - return crc; -} /* * Traverse a string of 1-byte tag/1-byte length/variable-length value * triples, returning a pointer to the substring whose first element @@ -828,6 +556,7 @@ bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key) return NULL; } +EXPORT_SYMBOL(bcm_parse_tlvs); #if defined(BCMDBG) @@ -883,6 +612,7 @@ bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, char *buf, int len) return (int)(p - buf); } +EXPORT_SYMBOL(bcm_format_flags); /* print bytes formatted as hex to a string. return the resulting string length */ int bcm_format_hex(char *str, const void *bytes, int len) @@ -897,44 +627,9 @@ int bcm_format_hex(char *str, const void *bytes, int len) } return (int)(p - str); } +EXPORT_SYMBOL(bcm_format_hex); #endif /* defined(BCMDBG) */ -/* pretty hex print a contiguous buffer */ -void prhex(const char *msg, unsigned char *buf, uint nbytes) -{ - char line[128], *p; - int len = sizeof(line); - int nchar; - uint i; - - if (msg && (msg[0] != '\0')) - printk(KERN_DEBUG "%s:\n", msg); - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ - p += nchar; - len -= nchar; - } - if (len > 0) { - nchar = snprintf(p, len, "%02x ", buf[i]); - p += nchar; - len -= nchar; - } - - if (i % 16 == 15) { - printk(KERN_DEBUG "%s\n", line); /* flush line */ - p = line; - len = sizeof(line); - } - } - - /* flush last partial line */ - if (p != line) - printk(KERN_DEBUG "%s\n", line); -} - char *bcm_chipname(uint chipid, char *buf, uint len) { const char *fmt; @@ -943,6 +638,7 @@ char *bcm_chipname(uint chipid, char *buf, uint len) snprintf(buf, len, fmt, chipid); return buf; } +EXPORT_SYMBOL(bcm_chipname); uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) { @@ -961,6 +657,7 @@ uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) return len; } +EXPORT_SYMBOL(bcm_mkiovar); /* Quarter dBm units to mW * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 @@ -1015,6 +712,8 @@ u16 bcm_qdbm_to_mw(u8 qdbm) */ return (nqdBm_to_mW_map[idx] + factor / 2) / factor; } +EXPORT_SYMBOL(bcm_qdbm_to_mw); + u8 bcm_mw_to_qdbm(u16 mw) { u8 qdbm; @@ -1045,6 +744,8 @@ u8 bcm_mw_to_qdbm(u16 mw) return qdbm; } +EXPORT_SYMBOL(bcm_mw_to_qdbm); + uint bcm_bitcount(u8 *bitmap, uint length) { uint bitcount = 0, i; @@ -1058,12 +759,15 @@ uint bcm_bitcount(u8 *bitmap, uint length) } return bitcount; } +EXPORT_SYMBOL(bcm_bitcount); + /* Initialization of bcmstrbuf structure */ void bcm_binit(struct bcmstrbuf *b, char *buf, uint size) { b->origsize = b->size = size; b->origbuf = b->buf = buf; } +EXPORT_SYMBOL(bcm_binit); /* Buffer sprintf wrapper to guard against buffer overflow */ int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) @@ -1089,50 +793,4 @@ int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) return r; } - -#if defined(BCMDBG_ASSERT) -void osl_assert(char *exp, char *file, int line) -{ - char tempbuf[256]; - char *basename; - - basename = strrchr(file, '/'); - /* skip the '/' */ - if (basename) - basename++; - - if (!basename) - basename = file; - - snprintf(tempbuf, 256, - "assertion \"%s\" failed: file \"%s\", line %d\n", exp, - basename, line); - - /* - * Print assert message and give it time to - * be written to /var/log/messages - */ - if (!in_interrupt()) { - const int delay = 3; - printk(KERN_ERR "%s", tempbuf); - printk(KERN_ERR "panic in %d seconds\n", delay); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay * HZ); - } - - switch (g_assert_type) { - case 0: - panic(KERN_ERR "%s", tempbuf); - break; - case 1: - printk(KERN_ERR "%s", tempbuf); - BUG(); - break; - case 2: - printk(KERN_ERR "%s", tempbuf); - break; - default: - break; - } -} -#endif /* defined(BCMDBG_ASSERT) */ +EXPORT_SYMBOL(bcm_bprintf); diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index d82c2b29816d..955a3ab1a827 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -15,6 +15,7 @@ */ #include <linux/ctype.h> #include <linux/kernel.h> +#include <linux/module.h> #include <bcmdefs.h> #include <bcmutils.h> #include <bcmwifi.h> @@ -25,7 +26,7 @@ * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -bool wf_chspec_malformed(chanspec_t chanspec) +bool bcm_chspec_malformed(chanspec_t chanspec) { /* must be 2G or 5G band */ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) @@ -45,13 +46,14 @@ bool wf_chspec_malformed(chanspec_t chanspec) return false; } +EXPORT_SYMBOL(bcm_chspec_malformed); /* * This function returns the channel number that control traffic is being sent on, for legacy * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ * sideband depending on the chanspec selected */ -u8 wf_chspec_ctlchan(chanspec_t chspec) +u8 bcm_chspec_ctlchan(chanspec_t chspec) { u8 ctl_chan; @@ -60,7 +62,6 @@ u8 wf_chspec_ctlchan(chanspec_t chspec) return CHSPEC_CHANNEL(chspec); } else { /* we only support 40MHZ with sidebands */ - ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40); /* chanspec channel holds the centre frequency, use that and the * side band information to reconstruct the control channel number */ @@ -68,8 +69,6 @@ u8 wf_chspec_ctlchan(chanspec_t chspec) /* control chan is the upper 20 MHZ SB of the 40MHZ channel */ ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); } else { - ASSERT(CHSPEC_CTL_SB(chspec) == - WL_CHANSPEC_CTL_SB_LOWER); /* control chan is the lower 20 MHZ SB of the 40MHZ channel */ ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); } @@ -77,6 +76,7 @@ u8 wf_chspec_ctlchan(chanspec_t chspec) return ctl_chan; } +EXPORT_SYMBOL(bcm_chspec_ctlchan); /* * Return the channel number for a given frequency and base frequency. @@ -97,7 +97,7 @@ u8 wf_chspec_ctlchan(chanspec_t chspec) * * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 */ -int wf_mhz2channel(uint freq, uint start_factor) +int bcm_mhz2channel(uint freq, uint start_factor) { int ch = -1; uint base; @@ -133,4 +133,5 @@ int wf_mhz2channel(uint freq, uint start_factor) return ch; } +EXPORT_SYMBOL(bcm_mhz2channel); diff --git a/drivers/staging/brcm80211/util/qmath.c b/drivers/staging/brcm80211/util/qmath.c deleted file mode 100644 index 40c9929de2bb..000000000000 --- a/drivers/staging/brcm80211/util/qmath.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) 2010 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 <linux/types.h> -#include "qmath.h" - -/* -Description: This function saturate input 32 bit number into a 16 bit number. -If input number is greater than 0x7fff then output is saturated to 0x7fff. -else if input number is less than 0xffff8000 then output is saturated to 0xffff8000 -else output is same as input. -*/ -s16 qm_sat32(s32 op) -{ - s16 result; - if (op > (s32) 0x7fff) { - result = 0x7fff; - } else if (op < (s32) 0xffff8000) { - result = (s16) (0x8000); - } else { - result = (s16) op; - } - return result; -} - -/* -Description: This function multiply two input 16 bit numbers and return the 32 bit result. -This multiplication is similar to compiler multiplication. This operation is defined if -16 bit multiplication on the processor platform is cheaper than 32 bit multiplication (as -the most of qmath functions can be replaced with processor intrinsic instructions). -*/ -s32 qm_mul321616(s16 op1, s16 op2) -{ - return (s32) (op1) * (s32) (op2); -} - -/* -Description: This function make 16 bit multiplication and return the result in 16 bits. -To fit the result into 16 bits the 32 bit multiplication result is right -shifted by 16 bits. -*/ -s16 qm_mul16(s16 op1, s16 op2) -{ - s32 result; - result = ((s32) (op1) * (s32) (op2)); - return (s16) (result >> 16); -} - -/* -Description: This function multiply two 16 bit numbers and return the result in 32 bits. -This function remove the extra sign bit created by the multiplication by leftshifting the -32 bit multiplication result by 1 bit before returning the result. So the output is -twice that of compiler multiplication. (i.e. qm_muls321616(2,3)=12). -When both input 16 bit numbers are 0x8000, then the result is saturated to 0x7fffffff. -*/ -s32 qm_muls321616(s16 op1, s16 op2) -{ - s32 result; - if (op1 == (s16) (0x8000) && op2 == (s16) (0x8000)) { - result = 0x7fffffff; - } else { - result = ((s32) (op1) * (s32) (op2)); - result = result << 1; - } - return result; -} - -/* -Description: This function make 16 bit unsigned multiplication. To fit the output into -16 bits the 32 bit multiplication result is right shifted by 16 bits. -*/ -u16 qm_mulu16(u16 op1, u16 op2) -{ - return (u16) (((u32) op1 * (u32) op2) >> 16); -} - -/* -Description: This function make 16 bit multiplication and return the result in 16 bits. -To fit the multiplication result into 16 bits the multiplication result is right shifted by -15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed -due to the multiplication. -When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff. -*/ -s16 qm_muls16(s16 op1, s16 op2) -{ - s32 result; - if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) { - result = 0x7fffffff; - } else { - result = ((s32) (op1) * (s32) (op2)); - } - return (s16) (result >> 15); -} - -/* -Description: This function add two 32 bit numbers and return the 32bit result. -If the result overflow 32 bits, the output will be saturated to 32bits. -*/ -s32 qm_add32(s32 op1, s32 op2) -{ - s32 result; - result = op1 + op2; - if (op1 < 0 && op2 < 0 && result > 0) { - result = 0x80000000; - } else if (op1 > 0 && op2 > 0 && result < 0) { - result = 0x7fffffff; - } - return result; -} - -/* -Description: This function add two 16 bit numbers and return the 16bit result. -If the result overflow 16 bits, the output will be saturated to 16bits. -*/ -s16 qm_add16(s16 op1, s16 op2) -{ - s16 result; - s32 temp = (s32) op1 + (s32) op2; - if (temp > (s32) 0x7fff) { - result = (s16) 0x7fff; - } else if (temp < (s32) 0xffff8000) { - result = (s16) 0xffff8000; - } else { - result = (s16) temp; - } - return result; -} - -/* -Description: This function make 16 bit subtraction and return the 16bit result. -If the result overflow 16 bits, the output will be saturated to 16bits. -*/ -s16 qm_sub16(s16 op1, s16 op2) -{ - s16 result; - s32 temp = (s32) op1 - (s32) op2; - if (temp > (s32) 0x7fff) { - result = (s16) 0x7fff; - } else if (temp < (s32) 0xffff8000) { - result = (s16) 0xffff8000; - } else { - result = (s16) temp; - } - return result; -} - -/* -Description: This function make 32 bit subtraction and return the 32bit result. -If the result overflow 32 bits, the output will be saturated to 32bits. -*/ -s32 qm_sub32(s32 op1, s32 op2) -{ - s32 result; - result = op1 - op2; - if (op1 >= 0 && op2 < 0 && result < 0) { - result = 0x7fffffff; - } else if (op1 < 0 && op2 > 0 && result > 0) { - result = 0x80000000; - } - return result; -} - -/* -Description: This function multiply input 16 bit numbers and accumulate the result -into the input 32 bit number and return the 32 bit accumulated result. -If the accumulation result in overflow, then the output will be saturated. -*/ -s32 qm_mac321616(s32 acc, s16 op1, s16 op2) -{ - s32 result; - result = qm_add32(acc, qm_mul321616(op1, op2)); - return result; -} - -/* -Description: This function make a 32 bit saturated left shift when the specified shift -is +ve. This function will make a 32 bit right shift when the specified shift is -ve. -This function return the result after shifting operation. -*/ -s32 qm_shl32(s32 op, int shift) -{ - int i; - s32 result; - result = op; - if (shift > 31) - shift = 31; - else if (shift < -31) - shift = -31; - if (shift >= 0) { - for (i = 0; i < shift; i++) { - result = qm_add32(result, result); - } - } else { - result = result >> (-shift); - } - return result; -} - -/* -Description: This function make a 32 bit right shift when shift is +ve. -This function make a 32 bit saturated left shift when shift is -ve. This function -return the result of the shift operation. -*/ -s32 qm_shr32(s32 op, int shift) -{ - return qm_shl32(op, -shift); -} - -/* -Description: This function make a 16 bit saturated left shift when the specified shift -is +ve. This function will make a 16 bit right shift when the specified shift is -ve. -This function return the result after shifting operation. -*/ -s16 qm_shl16(s16 op, int shift) -{ - int i; - s16 result; - result = op; - if (shift > 15) - shift = 15; - else if (shift < -15) - shift = -15; - if (shift > 0) { - for (i = 0; i < shift; i++) { - result = qm_add16(result, result); - } - } else { - result = result >> (-shift); - } - return result; -} - -/* -Description: This function make a 16 bit right shift when shift is +ve. -This function make a 16 bit saturated left shift when shift is -ve. This function -return the result of the shift operation. -*/ -s16 qm_shr16(s16 op, int shift) -{ - return qm_shl16(op, -shift); -} - -/* -Description: This function return the number of redundant sign bits in a 16 bit number. -Example: qm_norm16(0x0080) = 7. -*/ -s16 qm_norm16(s16 op) -{ - u16 u16extraSignBits; - if (op == 0) { - return 15; - } else { - u16extraSignBits = 0; - while ((op >> 15) == (op >> 14)) { - u16extraSignBits++; - op = op << 1; - } - } - return u16extraSignBits; -} - -/* -Description: This function return the number of redundant sign bits in a 32 bit number. -Example: qm_norm32(0x00000080) = 23 -*/ -s16 qm_norm32(s32 op) -{ - u16 u16extraSignBits; - if (op == 0) { - return 31; - } else { - u16extraSignBits = 0; - while ((op >> 31) == (op >> 30)) { - u16extraSignBits++; - op = op << 1; - } - } - return u16extraSignBits; -} - -/* -Description: This function divide two 16 bit unsigned numbers. -The numerator should be less than denominator. So the quotient is always less than 1. -This function return the quotient in q.15 format. -*/ -s16 qm_div_s(s16 num, s16 denom) -{ - s16 var_out; - s16 iteration; - s32 L_num; - s32 L_denom; - L_num = (num) << 15; - L_denom = (denom) << 15; - for (iteration = 0; iteration < 15; iteration++) { - L_num <<= 1; - if (L_num >= L_denom) { - L_num = qm_sub32(L_num, L_denom); - L_num = qm_add32(L_num, 1); - } - } - var_out = (s16) (L_num & 0x7fff); - return var_out; -} - -/* -Description: This function compute the absolute value of a 16 bit number. -*/ -s16 qm_abs16(s16 op) -{ - if (op < 0) { - if (op == (s16) 0xffff8000) { - return 0x7fff; - } else { - return -op; - } - } else { - return op; - } -} - -/* -Description: This function divide two 16 bit numbers. -The quotient is returned through return value. -The qformat of the quotient is returned through the pointer (qQuotient) passed -to this function. The qformat of quotient is adjusted appropriately such that -the quotient occupies all 16 bits. -*/ -s16 qm_div16(s16 num, s16 denom, s16 *qQuotient) -{ - s16 sign; - s16 nNum, nDenom; - sign = num ^ denom; - num = qm_abs16(num); - denom = qm_abs16(denom); - nNum = qm_norm16(num); - nDenom = qm_norm16(denom); - num = qm_shl16(num, nNum - 1); - denom = qm_shl16(denom, nDenom); - *qQuotient = nNum - 1 - nDenom + 15; - if (sign >= 0) { - return qm_div_s(num, denom); - } else { - return -qm_div_s(num, denom); - } -} - -/* -Description: This function compute absolute value of a 32 bit number. -*/ -s32 qm_abs32(s32 op) -{ - if (op < 0) { - if (op == (s32) 0x80000000) { - return 0x7fffffff; - } else { - return -op; - } - } else { - return op; - } -} - -/* -Description: This function divide two 32 bit numbers. The division is performed -by considering only important 16 bits in 32 bit numbers. -The quotient is returned through return value. -The qformat of the quotient is returned through the pointer (qquotient) passed -to this function. The qformat of quotient is adjusted appropriately such that -the quotient occupies all 16 bits. -*/ -s16 qm_div163232(s32 num, s32 denom, s16 *qquotient) -{ - s32 sign; - s16 nNum, nDenom; - sign = num ^ denom; - num = qm_abs32(num); - denom = qm_abs32(denom); - nNum = qm_norm32(num); - nDenom = qm_norm32(denom); - num = qm_shl32(num, nNum - 1); - denom = qm_shl32(denom, nDenom); - *qquotient = nNum - 1 - nDenom + 15; - if (sign >= 0) { - return qm_div_s((s16) (num >> 16), (s16) (denom >> 16)); - } else { - return -qm_div_s((s16) (num >> 16), (s16) (denom >> 16)); - } -} - -/* -Description: This function multiply a 32 bit number with a 16 bit number. -The multiplicaton result is right shifted by 16 bits to fit the result -into 32 bit output. -*/ -s32 qm_mul323216(s32 op1, s16 op2) -{ - s16 hi; - u16 lo; - s32 result; - hi = op1 >> 16; - lo = (s16) (op1 & 0xffff); - result = qm_mul321616(hi, op2); - result = result + (qm_mulsu321616(op2, lo) >> 16); - return result; -} - -/* -Description: This function multiply signed 16 bit number with unsigned 16 bit number and return -the result in 32 bits. -*/ -s32 qm_mulsu321616(s16 op1, u16 op2) -{ - return (s32) (op1) * op2; -} - -/* -Description: This function multiply 32 bit number with 16 bit number. The multiplication result is -right shifted by 15 bits to fit the result into 32 bits. Right shifting by only 15 bits instead of -16 bits is done to remove the extra sign bit formed by multiplication from the return value. -When the input numbers are 0x80000000, 0x8000 the return value is saturated to 0x7fffffff. -*/ -s32 qm_muls323216(s32 op1, s16 op2) -{ - s16 hi; - u16 lo; - s32 result; - hi = op1 >> 16; - lo = (s16) (op1 & 0xffff); - result = qm_muls321616(hi, op2); - result = qm_add32(result, (qm_mulsu321616(op2, lo) >> 15)); - return result; -} - -/* -Description: This function multiply two 32 bit numbers. The multiplication result is right -shifted by 32 bits to fit the multiplication result into 32 bits. The right shifted -multiplication result is returned as output. -*/ -s32 qm_mul32(s32 a, s32 b) -{ - s16 hi1, hi2; - u16 lo1, lo2; - s32 result; - hi1 = a >> 16; - hi2 = b >> 16; - lo1 = (u16) (a & 0xffff); - lo2 = (u16) (b & 0xffff); - result = qm_mul321616(hi1, hi2); - result = result + (qm_mulsu321616(hi1, lo2) >> 16); - result = result + (qm_mulsu321616(hi2, lo1) >> 16); - return result; -} - -/* -Description: This function multiply two 32 bit numbers. The multiplication result is -right shifted by 31 bits to fit the multiplication result into 32 bits. The right -shifted multiplication result is returned as output. Right shifting by only 31 bits -instead of 32 bits is done to remove the extra sign bit formed by multiplication. -When the input numbers are 0x80000000, 0x80000000 the return value is saturated to -0x7fffffff. -*/ -s32 qm_muls32(s32 a, s32 b) -{ - s16 hi1, hi2; - u16 lo1, lo2; - s32 result; - hi1 = a >> 16; - hi2 = b >> 16; - lo1 = (u16) (a & 0xffff); - lo2 = (u16) (b & 0xffff); - result = qm_muls321616(hi1, hi2); - result = qm_add32(result, (qm_mulsu321616(hi1, lo2) >> 15)); - result = qm_add32(result, (qm_mulsu321616(hi2, lo1) >> 15)); - result = qm_add32(result, (qm_mulu16(lo1, lo2) >> 15)); - return result; -} - -/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */ -static const s16 log_table[] = { - 0, - 1455, - 2866, - 4236, - 5568, - 6863, - 8124, - 9352, - 10549, - 11716, - 12855, - 13968, - 15055, - 16117, - 17156, - 18173, - 19168, - 20143, - 21098, - 22034, - 22952, - 23852, - 24736, - 25604, - 26455, - 27292, - 28114, - 28922, - 29717, - 30498, - 31267, - 32024 -}; - -#define LOG_TABLE_SIZE 32 /* log_table size */ -#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */ -#define Q_LOG_TABLE 15 /* qformat of log_table */ -#define LOG10_2 19728 /* log10(2) in q.16 */ - -/* -Description: -This routine takes the input number N and its q format qN and compute -the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format. -mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed. -From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed. -This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs. -As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. -Next 16 MSBs are used for interpolation. -Inputs: -N - number to which log10 has to be found. -qN - q format of N -log10N - address where log10(N) will be written. -qLog10N - address where log10N qformat will be written. -Note/Problem: -For accurate results input should be in normalized or near normalized form. -*/ -void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N) -{ - s16 s16norm, s16tableIndex, s16errorApproximation; - u16 u16offset; - s32 s32log; - - /* Logerithm of negative values is undefined. - * assert N is greater than 0. - */ - /* ASSERT(N > 0); */ - - /* normalize the N. */ - s16norm = qm_norm32(N); - N = N << s16norm; - - /* The qformat of N after normalization. - * -30 is added to treat the no as between 1.0 to 2.0 - * i.e. after adding the -30 to the qformat the decimal point will be - * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e. - * at the right side of 30th bit. - */ - qN = qN + s16norm - 30; - - /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */ - s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE))); - - /* remove the MSB. the MSB is always 1 after normalization. */ - s16tableIndex = - s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1); - - /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */ - N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1); - - /* take the offset as the 16 MSBS after table index. - */ - u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16))); - - /* look the log value in the table. */ - s32log = log_table[s16tableIndex]; /* q.15 format */ - - /* interpolate using the offset. */ - s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */ - - s32log = qm_add16((s16) s32log, s16errorApproximation); /* q.15 format */ - - /* adjust for the qformat of the N as - * log2(mag * 2^x) = log2(mag) + x - */ - s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */ - - /* normalize the result. */ - s16norm = qm_norm32(s32log); - - /* bring all the important bits into lower 16 bits */ - s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */ - - /* compute the log10(N) by multiplying log2(N) with log10(2). - * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2) - * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16) - */ - *log10N = qm_muls16((s16) s32log, (s16) LOG10_2); - - /* write the q format of the result. */ - *qLog10N = 15 + s16norm - 16 + 1; - - return; -} - -/* -Description: -This routine compute 1/N. -This routine reformates the given no N as N * 2^qN where N is in between 0.5 and 1.0 -in q.15 format in 16 bits. So the problem now boils down to finding the inverse of a -q.15 no in 16 bits which is in the range of 0.5 to 1.0. The output is always between -2.0 to 1. So the output is 2.0 to 1.0 in q.30 format. Once the final output format is found -by taking the qN into account. Inverse is found with newton rapson method. Initially -inverse (x) is guessed as 1/0.75 (with appropriate sign). The new guess is calculated -using the formula x' = 2*x - N*x*x. After 4 or 5 iterations the inverse is very close to -inverse of N. -Inputs: -N - number to which 1/N has to be found. -qn - q format of N. -sqrtN - address where 1/N has to be written. -qsqrtN - address where q format of 1/N has to be written. -*/ -#define qx 29 -void qm_1byN(s32 N, s16 qN, s32 *result, s16 *qResult) -{ - s16 normN; - s32 s32firstTerm, s32secondTerm, x; - int i; - - normN = qm_norm32(N); - - /* limit N to least significant 16 bits. 15th bit is the sign bit. */ - N = qm_shl32(N, normN - 16); - qN = qN + normN - 16 - 15; - /* -15 is added to treat N as 16 bit q.15 number in the range from 0.5 to 1 */ - - /* Take the initial guess as 1/0.75 in qx format with appropriate sign. */ - if (N >= 0) { - x = (s32) ((1 / 0.75) * (1 << qx)); - /* input no is in the range 0.5 to 1. So 1/0.75 is taken as initial guess. */ - } else { - x = (s32) ((1 / -0.75) * (1 << qx)); - /* input no is in the range -0.5 to -1. So 1/-0.75 is taken as initial guess. */ - } - - /* iterate the equation x = 2*x - N*x*x for 4 times. */ - for (i = 0; i < 4; i++) { - s32firstTerm = qm_shl32(x, 1); /* s32firstTerm = 2*x in q.29 */ - s32secondTerm = - qm_muls321616((s16) (s32firstTerm >> 16), - (s16) (s32firstTerm >> 16)); - /* s32secondTerm = x*x in q.(29+1-16)*2+1 */ - s32secondTerm = - qm_muls321616((s16) (s32secondTerm >> 16), (s16) N); - /* s32secondTerm = N*x*x in q.((29+1-16)*2+1)-16+15+1 i.e. in q.29 */ - x = qm_sub32(s32firstTerm, s32secondTerm); - /* can be added directly as both are in q.29 */ - } - - /* Bring the x to q.30 format. */ - *result = qm_shl32(x, 1); - /* giving the output in q.30 format for q.15 input in 16 bits. */ - - /* compute the final q format of the result. */ - *qResult = -qN + 30; /* adjusting the q format of actual output */ - - return; -} - -#undef qx diff --git a/drivers/staging/brcm80211/util/sbpcmcia.h b/drivers/staging/brcm80211/util/sbpcmcia.h deleted file mode 100644 index d4c156586e81..000000000000 --- a/drivers/staging/brcm80211/util/sbpcmcia.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2010 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 _SBPCMCIA_H -#define _SBPCMCIA_H - -/* All the addresses that are offsets in attribute space are divided - * by two to account for the fact that odd bytes are invalid in - * attribute space and our read/write routines make the space appear - * as if they didn't exist. Still we want to show the original numbers - * as documented in the hnd_pcmcia core manual. - */ - -/* PCMCIA Function Configuration Registers */ -#define PCMCIA_FCR (0x700 / 2) - -#define FCR0_OFF 0 -#define FCR1_OFF (0x40 / 2) -#define FCR2_OFF (0x80 / 2) -#define FCR3_OFF (0xc0 / 2) - -#define PCMCIA_FCR0 (0x700 / 2) -#define PCMCIA_FCR1 (0x740 / 2) -#define PCMCIA_FCR2 (0x780 / 2) -#define PCMCIA_FCR3 (0x7c0 / 2) - -/* Standard PCMCIA FCR registers */ - -#define PCMCIA_COR 0 - -#define COR_RST 0x80 -#define COR_LEV 0x40 -#define COR_IRQEN 0x04 -#define COR_BLREN 0x01 -#define COR_FUNEN 0x01 - -#define PCICIA_FCSR (2 / 2) -#define PCICIA_PRR (4 / 2) -#define PCICIA_SCR (6 / 2) -#define PCICIA_ESR (8 / 2) - -#define PCM_MEMOFF 0x0000 -#define F0_MEMOFF 0x1000 -#define F1_MEMOFF 0x2000 -#define F2_MEMOFF 0x3000 -#define F3_MEMOFF 0x4000 - -/* Memory base in the function fcr's */ -#define MEM_ADDR0 (0x728 / 2) -#define MEM_ADDR1 (0x72a / 2) -#define MEM_ADDR2 (0x72c / 2) - -/* PCMCIA base plus Srom access in fcr0: */ -#define PCMCIA_ADDR0 (0x072e / 2) -#define PCMCIA_ADDR1 (0x0730 / 2) -#define PCMCIA_ADDR2 (0x0732 / 2) - -#define MEM_SEG (0x0734 / 2) -#define SROM_CS (0x0736 / 2) -#define SROM_DATAL (0x0738 / 2) -#define SROM_DATAH (0x073a / 2) -#define SROM_ADDRL (0x073c / 2) -#define SROM_ADDRH (0x073e / 2) -#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */ -#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */ - -/* Values for srom_cs: */ -#define SROM_IDLE 0 -#define SROM_WRITE 1 -#define SROM_READ 2 -#define SROM_WEN 4 -#define SROM_WDS 7 -#define SROM_DONE 8 - -/* Fields in srom_info: */ -#define SRI_SZ_MASK 0x03 -#define SRI_BLANK 0x04 -#define SRI_OTP 0x80 - -#if !defined(ESTA_POSTMOGRIFY_REMOVAL) -/* CIS stuff */ - -/* The CIS stops where the FCRs start */ -#define CIS_SIZE PCMCIA_FCR - -/* CIS tuple length field max */ -#define CIS_TUPLE_LEN_MAX 0xff - -/* Standard tuples we know about */ - -#define CISTPL_NULL 0x00 -#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */ -#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ -#define CISTPL_FUNCID 0x21 /* Function identification */ -#define CISTPL_FUNCE 0x22 /* Function extensions */ -#define CISTPL_CFTABLE 0x1b /* Config table entry */ -#define CISTPL_END 0xff /* End of the CIS tuple chain */ - -/* Function identifier provides context for the function extensions tuple */ -#define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */ - -/* Function extensions for LANs (assumed for extensions other than SDIO) */ -#define LAN_TECH 1 /* Technology type */ -#define LAN_SPEED 2 /* Raw bit rate */ -#define LAN_MEDIA 3 /* Transmission media */ -#define LAN_NID 4 /* Node identification (aka MAC addr) */ -#define LAN_CONN 5 /* Connector standard */ - -/* CFTable */ -#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ -#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ -#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ - -/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll - * take one for HNBU, and use "extensions" (a la FUNCE) within it. - */ - -#define CISTPL_BRCM_HNBU 0x80 - -/* Subtypes of BRCM_HNBU: */ - -#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ -#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */ -#define HNBU_BOARDREV 0x02 /* One byte board revision */ -#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1) - * or 9 (sromrev > 1) bytes - */ -#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ -#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ -#define HNBU_AA 0x06 /* Antennas available */ -#define HNBU_AG 0x07 /* Antenna gain */ -#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ -#define HNBU_LEDS 0x09 /* LED set */ -#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) - * in rev 2 - */ -#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ -#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ -#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */ -#define HNBU_PAPARMS5G 0x0e /* 5G PA params */ -#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */ -#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */ -#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */ -#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */ -#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */ -#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */ -#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */ -#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */ -#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */ -#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */ -#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */ -#define HNBU_LEDDC 0x1c /* 2 bytes; LED duty cycle */ -#define HNBU_HNBUCIS 0x1d /* what follows is proprietary HNBU CIS format */ -#define HNBU_PAPARMS_SSLPNPHY 0x1e /* SSLPNPHY PA params */ -#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f /* SSLPNPHY RSSI mid pt sel & board switch arch */ -#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */ -#define HNBU_CHAINSWITCH 0x21 /* 2 byte; txchain, rxchain */ -#define HNBU_REGREV 0x22 /* 1 byte; */ -#define HNBU_FEM 0x23 /* 2 or 4 byte: 11n frontend specification */ -#define HNBU_PAPARMS_C0 0x24 /* 8 or 30 bytes: 11n pa paramater for chain 0 */ -#define HNBU_PAPARMS_C1 0x25 /* 8 or 30 bytes: 11n pa paramater for chain 1 */ -#define HNBU_PAPARMS_C2 0x26 /* 8 or 30 bytes: 11n pa paramater for chain 2 */ -#define HNBU_PAPARMS_C3 0x27 /* 8 or 30 bytes: 11n pa paramater for chain 3 */ -#define HNBU_PO_CCKOFDM 0x28 /* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */ -#define HNBU_PO_MCS2G 0x29 /* 8 bytes: mcs2g power offset */ -#define HNBU_PO_MCS5GM 0x2a /* 8 bytes: mcs5g mid band power offset */ -#define HNBU_PO_MCS5GLH 0x2b /* 16 bytes: mcs5g low-high band power offset */ -#define HNBU_PO_CDD 0x2c /* 2 bytes: cdd2g/5g power offset */ -#define HNBU_PO_STBC 0x2d /* 2 bytes: stbc2g/5g power offset */ -#define HNBU_PO_40M 0x2e /* 2 bytes: 40Mhz channel 2g/5g power offset */ -#define HNBU_PO_40MDUP 0x2f /* 2 bytes: 40Mhz channel dup 2g/5g power offset */ - -#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */ -#define HNBU_WPS 0x31 /* 1 byte; GPIO pin for WPS button */ -#define HNBU_USBFS 0x32 /* 1 byte; 1 = USB advertises FS mode only */ -#define HNBU_BRMIN 0x33 /* 4 byte bootloader min resource mask */ -#define HNBU_BRMAX 0x34 /* 4 byte bootloader max resource mask */ -#define HNBU_PATCH 0x35 /* bootloader patch addr(2b) & data(4b) pair */ -#define HNBU_CCKFILTTYPE 0x36 /* CCK digital filter selection options */ -#define HNBU_OFDMPO5G 0x37 /* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */ - -#define HNBU_USBEPNUM 0x40 /* USB endpoint numbers */ -#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8 - * plus extra info appended. - */ -#define HNBU_RESERVED 0x81 /* Reserved for non-BRCM post-mfg additions */ -#define HNBU_CUSTOM1 0x82 /* 4 byte; For non-BRCM post-mfg additions */ -#define HNBU_CUSTOM2 0x83 /* Reserved; For non-BRCM post-mfg additions */ -#endif /* !defined(ESTA_POSTMOGRIFY_REMOVAL) */ - -/* sbtmstatelow */ -#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ -#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ - -/* sbtmstatehigh */ -#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ - -#endif /* _SBPCMCIA_H */ diff --git a/drivers/staging/brcm80211/util/sbsocram.h b/drivers/staging/brcm80211/util/sbsocram.h deleted file mode 100644 index 0cfe9852b27f..000000000000 --- a/drivers/staging/brcm80211/util/sbsocram.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010 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 _SBSOCRAM_H -#define _SBSOCRAM_H - -#ifndef _LANGUAGE_ASSEMBLY - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -/* Memcsocram core registers */ -typedef volatile struct sbsocramregs { - u32 coreinfo; - u32 bwalloc; - u32 extracoreinfo; - u32 biststat; - u32 bankidx; - u32 standbyctrl; - - u32 errlogstatus; /* rev 6 */ - u32 errlogaddr; /* rev 6 */ - /* used for patching rev 3 & 5 */ - u32 cambankidx; - u32 cambankstandbyctrl; - u32 cambankpatchctrl; - u32 cambankpatchtblbaseaddr; - u32 cambankcmdreg; - u32 cambankdatareg; - u32 cambankmaskreg; - u32 PAD[1]; - u32 bankinfo; /* corev 8 */ - u32 PAD[15]; - u32 extmemconfig; - u32 extmemparitycsr; - u32 extmemparityerrdata; - u32 extmemparityerrcnt; - u32 extmemwrctrlandsize; - u32 PAD[84]; - u32 workaround; - u32 pwrctl; /* corerev >= 2 */ -} sbsocramregs_t; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* Register offsets */ -#define SR_COREINFO 0x00 -#define SR_BWALLOC 0x04 -#define SR_BISTSTAT 0x0c -#define SR_BANKINDEX 0x10 -#define SR_BANKSTBYCTL 0x14 -#define SR_PWRCTL 0x1e8 - -/* Coreinfo register */ -#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ -#define SRCI_PT_SHIFT 16 -/* port types : SRCI_PT_<processorPT>_<backplanePT> */ -#define SRCI_PT_OCP_OCP 0 -#define SRCI_PT_AXI_OCP 1 -#define SRCI_PT_ARM7AHB_OCP 2 -#define SRCI_PT_CM3AHB_OCP 3 -#define SRCI_PT_AXI_AXI 4 -#define SRCI_PT_AHB_AXI 5 -/* corerev >= 3 */ -#define SRCI_LSS_MASK 0x00f00000 -#define SRCI_LSS_SHIFT 20 -#define SRCI_LRS_MASK 0x0f000000 -#define SRCI_LRS_SHIFT 24 - -/* In corerev 0, the memory size is 2 to the power of the - * base plus 16 plus to the contents of the memsize field plus 1. - */ -#define SRCI_MS0_MASK 0xf -#define SR_MS0_BASE 16 - -/* - * In corerev 1 the bank size is 2 ^ the bank size field plus 14, - * the memory size is number of banks times bank size. - * The same applies to rom size. - */ -#define SRCI_ROMNB_MASK 0xf000 -#define SRCI_ROMNB_SHIFT 12 -#define SRCI_ROMBSZ_MASK 0xf00 -#define SRCI_ROMBSZ_SHIFT 8 -#define SRCI_SRNB_MASK 0xf0 -#define SRCI_SRNB_SHIFT 4 -#define SRCI_SRBSZ_MASK 0xf -#define SRCI_SRBSZ_SHIFT 0 - -#define SR_BSZ_BASE 14 - -/* Standby control register */ -#define SRSC_SBYOVR_MASK 0x80000000 -#define SRSC_SBYOVR_SHIFT 31 -#define SRSC_SBYOVRVAL_MASK 0x60000000 -#define SRSC_SBYOVRVAL_SHIFT 29 -#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ -#define SRSC_SBYEN_SHIFT 24 - -/* Power control register */ -#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ -#define SRPC_PMU_STBYDIS_SHIFT 4 -#define SRPC_STBYOVRVAL_MASK 0x00000008 -#define SRPC_STBYOVRVAL_SHIFT 3 -#define SRPC_STBYOVR_MASK 0x00000007 -#define SRPC_STBYOVR_SHIFT 0 - -/* Extra core capability register */ -#define SRECC_NUM_BANKS_MASK 0x000000F0 -#define SRECC_NUM_BANKS_SHIFT 4 -#define SRECC_BANKSIZE_MASK 0x0000000F -#define SRECC_BANKSIZE_SHIFT 0 - -#define SRECC_BANKSIZE(value) (1 << (value)) - -/* CAM bank patch control */ -#define SRCBPC_PATCHENABLE 0x80000000 - -#define SRP_ADDRESS 0x0001FFFC -#define SRP_VALID 0x8000 - -/* CAM bank command reg */ -#define SRCMD_WRITE 0x00020000 -#define SRCMD_READ 0x00010000 -#define SRCMD_DONE 0x80000000 - -#define SRCMD_DONE_DLY 1000 - -/* bankidx and bankinfo reg defines corerev >= 8 */ -#define SOCRAM_BANKINFO_SZMASK 0x3f -#define SOCRAM_BANKIDX_ROM_MASK 0x100 - -#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 -/* socram bankinfo memtype */ -#define SOCRAM_MEMTYPE_RAM 0 -#define SOCRAM_MEMTYPE_R0M 1 -#define SOCRAM_MEMTYPE_DEVRAM 2 - -#define SOCRAM_BANKINFO_REG 0x40 -#define SOCRAM_BANKIDX_REG 0x10 -#define SOCRAM_BANKINFO_STDBY_MASK 0x400 -#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 - -/* bankinfo rev >= 10 */ -#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 - -/* extracoreinfo register */ -#define SOCRAM_DEVRAMBANK_MASK 0xF000 -#define SOCRAM_DEVRAMBANK_SHIFT 12 - -/* bank info to calculate bank size */ -#define SOCRAM_BANKINFO_SZBASE 8192 -#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ - -#endif /* _SBSOCRAM_H */ diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c deleted file mode 100644 index 21dde8e508dd..000000000000 --- a/drivers/staging/brcm80211/util/sbutils.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (c) 2010 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 <linux/types.h> -#include <bcmdefs.h> -#ifdef BRCM_FULLMAC -#include <linux/netdevice.h> -#endif -#include <bcmutils.h> -#include <siutils.h> -#include <bcmdevs.h> -#include <hndsoc.h> -#include <sbchipc.h> -#include <pci_core.h> -#include <pcicfg.h> -#include <sbpcmcia.h> -#include "siutils_priv.h" - -/* local prototypes */ -static uint _sb_coreidx(si_info_t *sii, u32 sba); -static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, - u32 sbba, uint ncores); -static u32 _sb_coresba(si_info_t *sii); -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); - -#define SET_SBREG(sii, r, mask, val) \ - W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) -#define REGS2SB(va) (sbconfig_t *) ((s8 *)(va) + SBCONFIGOFF) - -/* sonicsrev */ -#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) - -#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr)) -#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v)) -#define AND_SBREG(sii, sbr, v) \ - W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v))) -#define OR_SBREG(sii, sbr, v) \ - W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v))) - -static u32 sb_read_sbreg(si_info_t *sii, volatile u32 *sbr) -{ - return R_REG(sbr); -} - -static void sb_write_sbreg(si_info_t *sii, volatile u32 *sbr, u32 v) -{ - W_REG(sbr, v); -} - -uint sb_coreid(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return (R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> - SBIDH_CC_SHIFT; -} - -/* return core index of the core with address 'sba' */ -static uint _sb_coreidx(si_info_t *sii, u32 sba) -{ - uint i; - - for (i = 0; i < sii->numcores; i++) - if (sba == sii->coresba[i]) - return i; - return BADIDX; -} - -/* return core address of the current core */ -static u32 _sb_coresba(si_info_t *sii) -{ - u32 sbaddr = 0; - - switch (sii->pub.bustype) { - case SPI_BUS: - case SDIO_BUS: - sbaddr = (u32)(unsigned long)sii->curmap; - break; - default: - ASSERT(0); - break; - } - - return sbaddr; -} - -uint sb_corerev(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - uint sbidh; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - sbidh = R_SBREG(sii, &sb->sbidhigh); - - return SBCOREREV(sbidh); -} - -bool sb_iscoreup(si_t *sih) -{ - si_info_t *sii; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - return (R_SBREG(sii, &sb->sbtmstatelow) & - (SBTML_RESET | SBTML_REJ_MASK | - (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) == - (SICF_CLOCK_EN << SBTML_SICF_SHIFT); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit - * register mask&set operation, - * switch back to the original core, and return the new value. - * - * When using the silicon backplane, no fidleing with interrupts - * or core switches are needed. - * - * Also, when using pci/pcie, we can optimize away the core switching - * for pci registers - * and (on newer pci cores) chipcommon registers. - */ -uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -{ - uint origidx = 0; - u32 *r = NULL; - uint w; - uint intr_val = 0; - bool fast = false; - si_info_t *sii; - - sii = SI_INFO(sih); - - ASSERT(GOODIDX(coreidx)); - ASSERT(regoff < SI_CORE_SIZE); - ASSERT((val & ~mask) == 0); - - if (coreidx >= SI_MAXCORES) - return 0; - - if (!fast) { - INTR_OFF(sii, intr_val); - - /* save current core index */ - origidx = si_coreidx(&sii->pub); - - /* switch core */ - r = (u32 *) ((unsigned char *) sb_setcoreidx(&sii->pub, coreidx) + - regoff); - } - ASSERT(r != NULL); - - /* mask and set */ - if (mask || val) { - if (regoff >= SBCONFIGOFF) { - w = (R_SBREG(sii, r) & ~mask) | val; - W_SBREG(sii, r, w); - } else { - w = (R_REG(r) & ~mask) | val; - W_REG(r, w); - } - } - - /* readback */ - if (regoff >= SBCONFIGOFF) - w = R_SBREG(sii, r); - else - w = R_REG(r); - - if (!fast) { - /* restore core index */ - if (origidx != coreidx) - sb_setcoreidx(&sii->pub, origidx); - - INTR_RESTORE(sii, intr_val); - } - - return w; -} - -/* Scan the enumeration space to find all cores starting from the given - * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba' - * is the default core address at chip POR time and 'regs' is the virtual - * address that the default core is mapped at. 'ncores' is the number of - * cores expected on bus 'sbba'. It returns the total number of cores - * starting from bus 'sbba', inclusive. - */ -#define SB_MAXBUSES 2 -static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, u32 sbba, - uint numcores) -{ - uint next; - uint ncc = 0; - uint i; - - if (bus >= SB_MAXBUSES) { - SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to " - "scan\n", sbba, bus)); - return 0; - } - SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n", - sbba, numcores)); - - /* Scan all cores on the bus starting from core 0. - * Core addresses must be contiguous on each bus. - */ - for (i = 0, next = sii->numcores; - i < numcores && next < SB_BUS_MAXCORES; i++, next++) { - sii->coresba[next] = sbba + (i * SI_CORE_SIZE); - - /* change core to 'next' and read its coreid */ - sii->curmap = _sb_setcoreidx(sii, next); - sii->curidx = next; - - sii->coreid[next] = sb_coreid(&sii->pub); - - /* core specific processing... */ - /* chipc provides # cores */ - if (sii->coreid[next] == CC_CORE_ID) { - chipcregs_t *cc = (chipcregs_t *) sii->curmap; - u32 ccrev = sb_corerev(&sii->pub); - - /* determine numcores - this is the - total # cores in the chip */ - if (((ccrev == 4) || (ccrev >= 6))) - numcores = - (R_REG(&cc->chipid) & CID_CC_MASK) - >> CID_CC_SHIFT; - else { - /* Older chips */ - SI_ERROR(("sb_chip2numcores: unsupported chip " - "0x%x\n", sii->pub.chip)); - ASSERT(0); - numcores = 1; - } - - SI_VMSG(("_sb_scan: %u cores in the chip %s\n", - numcores, sii->pub.issim ? "QT" : "")); - } - /* scan bridged SB(s) and add results to the end of the list */ - else if (sii->coreid[next] == OCP_CORE_ID) { - sbconfig_t *sb = REGS2SB(sii->curmap); - u32 nsbba = R_SBREG(sii, &sb->sbadmatch1); - uint nsbcc; - - sii->numcores = next + 1; - - if ((nsbba & 0xfff00000) != SI_ENUM_BASE) - continue; - nsbba &= 0xfffff000; - if (_sb_coreidx(sii, nsbba) != BADIDX) - continue; - - nsbcc = - (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> - 16; - nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); - if (sbba == SI_ENUM_BASE) - numcores -= nsbcc; - ncc += nsbcc; - } - } - - SI_MSG(("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba)); - - sii->numcores = i + ncc; - return sii->numcores; -} - -/* scan the sb enumerated space to identify all cores */ -void sb_scan(si_t *sih, void *regs, uint devid) -{ - si_info_t *sii; - u32 origsba; - sbconfig_t *sb; - - sii = SI_INFO(sih); - sb = REGS2SB(sii->curmap); - - sii->pub.socirev = - (R_SBREG(sii, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; - - /* Save the current core info and validate it later till we know - * for sure what is good and what is bad. - */ - origsba = _sb_coresba(sii); - - /* scan all SB(s) starting from SI_ENUM_BASE */ - sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); -} - -/* - * This function changes logical "focus" to the indicated core; - * must be called with interrupts off. - * Moreover, callers should keep interrupts off during switching out of - * and back to d11 core - */ -void *sb_setcoreidx(si_t *sih, uint coreidx) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - - if (coreidx >= sii->numcores) - return NULL; - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((sii->intrsenabled_fn == NULL) - || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg)); - - sii->curmap = _sb_setcoreidx(sii, coreidx); - sii->curidx = coreidx; - - return sii->curmap; -} - -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. - */ -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx) -{ - u32 sbaddr = sii->coresba[coreidx]; - void *regs; - - switch (sii->pub.bustype) { -#ifdef BCMSDIO - case SPI_BUS: - case SDIO_BUS: - /* map new one */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = (void *)sbaddr; - ASSERT(GOODREGS(sii->regs[coreidx])); - } - regs = sii->regs[coreidx]; - break; -#endif /* BCMSDIO */ - default: - ASSERT(0); - regs = NULL; - break; - } - - return regs; -} - -void sb_core_disable(si_t *sih, u32 bits) -{ - si_info_t *sii; - volatile u32 dummy; - sbconfig_t *sb; - - sii = SI_INFO(sih); - - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* if core is already in reset, just return */ - if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET) - return; - - /* if clocks are not enabled, put into reset and return */ - if ((R_SBREG(sii, &sb->sbtmstatelow) & - (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0) - goto disable; - - /* set target reject and spin until busy is clear - (preserve core-specific bits) */ - OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - udelay(1); - SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) - SI_ERROR(("%s: target state still busy\n", __func__)); - - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { - OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); - dummy = R_SBREG(sii, &sb->sbimstate); - udelay(1); - SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); - } - - /* set reset and reject while enabling the clocks */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | - SBTML_REJ | SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - udelay(10); - - /* don't forget to clear the initiator reject bit */ - if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) - AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ); - -disable: - /* leave reset and reject asserted */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - udelay(1); -} - -/* reset and re-enable a core - * inputs: - * bits - core specific bits that are set during and after reset sequence - * resetbits - core specific bits that are set only during reset sequence - */ -void sb_core_reset(si_t *sih, u32 bits, u32 resetbits) -{ - si_info_t *sii; - sbconfig_t *sb; - volatile u32 dummy; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curmap)); - sb = REGS2SB(sii->curmap); - - /* - * Must do the disable sequence first to work for - * arbitrary current core state. - */ - sb_core_disable(sih, (bits | resetbits)); - - /* - * Now do the initialization sequence. - */ - - /* set reset while enabling the clock and - forcing them on throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << - SBTML_SICF_SHIFT) | SBTML_RESET)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - udelay(1); - - if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) - W_SBREG(sii, &sb->sbtmstatehigh, 0); - - dummy = R_SBREG(sii, &sb->sbimstate); - if (dummy & (SBIM_IBE | SBIM_TO)) - AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - - /* clear reset and allow it to propagate throughout the core */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << - SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - udelay(1); - - /* leave clock enabled */ - W_SBREG(sii, &sb->sbtmstatelow, - ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); - dummy = R_SBREG(sii, &sb->sbtmstatelow); - udelay(1); -} |