diff options
Diffstat (limited to 'drivers/staging/brcm80211/brcmsmac')
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/Makefile | 45 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/aiutils.c | 508 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/aiutils.h | 218 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/alloc.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_alloc.c) | 38 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/alloc.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_alloc.h) | 0 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/ampdu.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c) | 48 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/ampdu.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/antsel.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_antsel.c) | 39 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/antsel.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_antsel.h) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/bcmsrom.c | 714 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/bmac.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_bmac.c) | 110 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/bmac.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_bmac.h) | 17 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/channel.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_channel.c) | 31 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/channel.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_channel.h) | 11 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/d11.h | 49 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/dma.c (renamed from drivers/staging/brcm80211/brcmsmac/hnddma.c) | 293 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/dma.h | 255 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/mac80211_if.c (renamed from drivers/staging/brcm80211/brcmsmac/wl_mac80211.c) | 704 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/mac80211_if.h (renamed from drivers/staging/brcm80211/brcmsmac/wl_mac80211.h) | 74 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/main.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_main.c) | 2102 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/main.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_main.h) | 322 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/nicpci.c | 393 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/nicpci.h | 85 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/nvram.c | 215 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/otp.c (renamed from drivers/staging/brcm80211/brcmsmac/bcmotp.c) | 464 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/otp.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_types.h) | 40 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c) | 106 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h) | 51 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_int.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h) | 31 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c) | 25 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_n.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c) | 24 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c) | 2 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h) | 0 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h) | 0 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c) | 6 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h) | 0 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy_shim.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c) | 62 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/phy_shim.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h) | 61 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/pmu.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_pmu.c) | 552 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/pmu.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_pmu.h) | 42 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/pub.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_pub.h) | 160 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/rate.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_rate.c) | 18 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/rate.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_rate.h) | 0 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/scb.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_scb.h) | 9 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/srom.c (renamed from drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h) | 983 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/srom.h (renamed from drivers/staging/brcm80211/brcmsmac/phy/phy_version.h) | 30 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/stf.c (renamed from drivers/staging/brcm80211/brcmsmac/wlc_stf.c) | 67 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/stf.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_stf.h) | 8 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/types.h (renamed from drivers/staging/brcm80211/brcmsmac/wlc_cfg.h) | 284 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/ucode_loader.c (renamed from drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c) | 78 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/ucode_loader.h (renamed from drivers/staging/brcm80211/brcmsmac/wl_ucode.h) | 15 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/wl_dbg.h | 92 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/wl_export.h | 47 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 135 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmsmac/wlc_key.h | 140 |
59 files changed, 4514 insertions, 5325 deletions
diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 8d75fe19ca9a..1ea3e0c48f3e 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -28,30 +28,29 @@ ccflags-y := \ -Idrivers/staging/brcm80211/include BRCMSMAC_OFILES := \ - wl_mac80211.o \ - wl_ucode_loader.o \ - wlc_alloc.o \ - wlc_ampdu.o \ - wlc_antsel.o \ - wlc_bmac.o \ - wlc_channel.o \ - wlc_main.o \ - wlc_phy_shim.o \ - wlc_pmu.o \ - wlc_rate.o \ - wlc_stf.o \ + mac80211_if.o \ + ucode_loader.o \ + alloc.o \ + ampdu.o \ + antsel.o \ + bmac.o \ + channel.o \ + main.o \ + phy_shim.o \ + pmu.o \ + rate.o \ + 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 \ - phy/wlc_phy_qmath.o \ - bcmotp.o \ - bcmsrom.o \ - hnddma.o \ - nicpci.o \ - nvram.o + phy/phy_cmn.o \ + phy/phy_lcn.o \ + phy/phy_n.o \ + phy/phytbl_lcn.o \ + phy/phytbl_n.o \ + phy/phy_qmath.o \ + otp.o \ + srom.o \ + dma.o \ + nicpci.o MODULEPFX := brcmsmac diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c index a61185f70a7c..fee89669c392 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.c +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c @@ -17,32 +17,357 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/string.h> -#include <bcmdefs.h> +#include <defs.h> +#include "types.h" #include <linux/module.h> #include <linux/pci.h> -#include <bcmutils.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <hndsoc.h> -#include <sbchipc.h> -#include <pcicfg.h> -#include <bcmdevs.h> +#include <soc.h> +#include <chipcommon.h> +#include <brcm_hw_ids.h> /* ********** from siutils.c *********** */ -#include <pci_core.h> -#include <pcie_core.h> #include <nicpci.h> -#include <bcmnvram.h> -#include <bcmsrom.h> -#include <wlc_pmu.h> +#include "srom.h" +#include <pmu.h> +#include <scb.h> +#include <pub.h> + +/* slow_clk_ctl */ +#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ +#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ +#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ +#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ +#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ +#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, + * 0: LPO is enabled + */ +#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, + * 0: power logic control + */ +#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors + * PLL clock disable requests from core + */ +#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't + * disable crystal when appropriate + */ +#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ +#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ +#define SCC_CD_SHIFT 16 + +/* system_clk_ctl */ +#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ +#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ +#define SYCC_FP 0x00000004 /* ForcePLLOn */ +#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ +#define SYCC_HR 0x00000010 /* Force HT */ +#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ +#define SYCC_CD_SHIFT 16 + +#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 +#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ +#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ +#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ +#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ +#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 +#define CST4329_SPI_SDIO_MODE_SHIFT 2 + +/* 43224 chip-specific ChipControl register bits */ +#define CCTRL43224_GPIO_TOGGLE 0x8000 +#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ +#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ + +/* 43236 Chip specific ChipStatus register bits */ +#define CST43236_SFLASH_MASK 0x00000040 +#define CST43236_OTP_MASK 0x00000080 +#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ +#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ +#define CST43236_BOOT_MASK 0x00001800 +#define CST43236_BOOT_SHIFT 11 +#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ +#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ +#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ +#define CST43236_BOOT_FROM_INVALID 3 + +/* 4331 chip-specific ChipControl register bits */ +#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ +#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ +#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */ +#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ +#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ +#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ +#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ +#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ +#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ +#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ +#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ +#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ +#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ +#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ + +/* 4331 Chip specific ChipStatus register bits */ +#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ +#define CST4331_SPROM_PRESENT 0x00000002 +#define CST4331_OTP_PRESENT 0x00000004 +#define CST4331_LDO_RF 0x00000008 +#define CST4331_LDO_PAR 0x00000010 + +/* 4319 chip-specific ChipStatus register bits */ +#define CST4319_SPI_CPULESSUSB 0x00000001 +#define CST4319_SPI_CLK_POL 0x00000002 +#define CST4319_SPI_CLK_PH 0x00000008 +#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ +#define CST4319_SPROM_OTP_SEL_SHIFT 6 +#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ +#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ +#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ +#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ +#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ +#define CST4319_REMAP_SEL_MASK 0x00000600 +#define CST4319_ILPDIV_EN 0x00000800 +#define CST4319_XTAL_PD_POL 0x00001000 +#define CST4319_LPO_SEL 0x00002000 +#define CST4319_RES_INIT_MODE 0x0000c000 +#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ +#define CST4319_CBUCK_MODE_MASK 0x00060000 +#define CST4319_CBUCK_MODE_BURST 0x00020000 +#define CST4319_CBUCK_MODE_LPBURST 0x00060000 +#define CST4319_RCAL_VALID 0x01000000 +#define CST4319_RCAL_VALUE_MASK 0x3e000000 +#define CST4319_RCAL_VALUE_SHIFT 25 + +/* 4336 chip-specific ChipStatus register bits */ +#define CST4336_SPI_MODE_MASK 0x00000001 +#define CST4336_SPROM_PRESENT 0x00000002 +#define CST4336_OTP_PRESENT 0x00000004 +#define CST4336_ARMREMAP_0 0x00000008 +#define CST4336_ILPDIV_EN_MASK 0x00000010 +#define CST4336_ILPDIV_EN_SHIFT 4 +#define CST4336_XTAL_PD_POL_MASK 0x00000020 +#define CST4336_XTAL_PD_POL_SHIFT 5 +#define CST4336_LPO_SEL_MASK 0x00000040 +#define CST4336_LPO_SEL_SHIFT 6 +#define CST4336_RES_INIT_MODE_MASK 0x00000180 +#define CST4336_RES_INIT_MODE_SHIFT 7 +#define CST4336_CBUCK_MODE_MASK 0x00000600 +#define CST4336_CBUCK_MODE_SHIFT 9 + +/* 4313 chip-specific ChipStatus register bits */ +#define CST4313_SPROM_PRESENT 1 +#define CST4313_OTP_PRESENT 2 +#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 +#define CST4313_SPROM_OTP_SEL_SHIFT 0 + +/* 4313 Chip specific ChipControl register bits */ +#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ (sih->chiprev == 0) && \ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) +/* Manufacturer Ids */ +#define MFGID_ARM 0x43b +#define MFGID_BRCM 0x4bf +#define MFGID_MIPS 0x4a7 + +/* Enumeration ROM registers */ +#define ER_EROMENTRY 0x000 +#define ER_REMAPCONTROL 0xe00 +#define ER_REMAPSELECT 0xe04 +#define ER_MASTERSELECT 0xe10 +#define ER_ITCR 0xf00 +#define ER_ITIP 0xf04 + +/* Erom entries */ +#define ER_TAG 0xe +#define ER_TAG1 0x6 +#define ER_VALID 1 +#define ER_CI 0 +#define ER_MP 2 +#define ER_ADD 4 +#define ER_END 0xe +#define ER_BAD 0xffffffff + +/* EROM CompIdentA */ +#define CIA_MFG_MASK 0xfff00000 +#define CIA_MFG_SHIFT 20 +#define CIA_CID_MASK 0x000fff00 +#define CIA_CID_SHIFT 8 +#define CIA_CCL_MASK 0x000000f0 +#define CIA_CCL_SHIFT 4 + +/* EROM CompIdentB */ +#define CIB_REV_MASK 0xff000000 +#define CIB_REV_SHIFT 24 +#define CIB_NSW_MASK 0x00f80000 +#define CIB_NSW_SHIFT 19 +#define CIB_NMW_MASK 0x0007c000 +#define CIB_NMW_SHIFT 14 +#define CIB_NSP_MASK 0x00003e00 +#define CIB_NSP_SHIFT 9 +#define CIB_NMP_MASK 0x000001f0 +#define CIB_NMP_SHIFT 4 + +/* EROM AddrDesc */ +#define AD_ADDR_MASK 0xfffff000 +#define AD_SP_MASK 0x00000f00 +#define AD_SP_SHIFT 8 +#define AD_ST_MASK 0x000000c0 +#define AD_ST_SHIFT 6 +#define AD_ST_SLAVE 0x00000000 +#define AD_ST_BRIDGE 0x00000040 +#define AD_ST_SWRAP 0x00000080 +#define AD_ST_MWRAP 0x000000c0 +#define AD_SZ_MASK 0x00000030 +#define AD_SZ_SHIFT 4 +#define AD_SZ_4K 0x00000000 +#define AD_SZ_8K 0x00000010 +#define AD_SZ_16K 0x00000020 +#define AD_SZ_SZD 0x00000030 +#define AD_AG32 0x00000008 +#define AD_ADDR_ALIGN 0x00000fff +#define AD_SZ_BASE 0x00001000 /* 4KB */ + +/* EROM SizeDesc */ +#define SD_SZ_MASK 0xfffff000 +#define SD_SG32 0x00000008 +#define SD_SZ_ALIGN 0x00000fff + +#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ +#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 XTAL_ON_DELAY 1000 /* us crystal power-on delay */ + +/* resetctrl */ +#define AIRC_RESET 1 + +typedef volatile struct _aidmp { + u32 oobselina30; /* 0x000 */ + u32 oobselina74; /* 0x004 */ + u32 PAD[6]; + u32 oobselinb30; /* 0x020 */ + u32 oobselinb74; /* 0x024 */ + u32 PAD[6]; + u32 oobselinc30; /* 0x040 */ + u32 oobselinc74; /* 0x044 */ + u32 PAD[6]; + u32 oobselind30; /* 0x060 */ + u32 oobselind74; /* 0x064 */ + u32 PAD[38]; + u32 oobselouta30; /* 0x100 */ + u32 oobselouta74; /* 0x104 */ + u32 PAD[6]; + u32 oobseloutb30; /* 0x120 */ + u32 oobseloutb74; /* 0x124 */ + u32 PAD[6]; + u32 oobseloutc30; /* 0x140 */ + u32 oobseloutc74; /* 0x144 */ + u32 PAD[6]; + u32 oobseloutd30; /* 0x160 */ + u32 oobseloutd74; /* 0x164 */ + u32 PAD[38]; + u32 oobsynca; /* 0x200 */ + u32 oobseloutaen; /* 0x204 */ + u32 PAD[6]; + u32 oobsyncb; /* 0x220 */ + u32 oobseloutben; /* 0x224 */ + u32 PAD[6]; + u32 oobsyncc; /* 0x240 */ + u32 oobseloutcen; /* 0x244 */ + u32 PAD[6]; + u32 oobsyncd; /* 0x260 */ + u32 oobseloutden; /* 0x264 */ + u32 PAD[38]; + u32 oobaextwidth; /* 0x300 */ + u32 oobainwidth; /* 0x304 */ + u32 oobaoutwidth; /* 0x308 */ + u32 PAD[5]; + u32 oobbextwidth; /* 0x320 */ + u32 oobbinwidth; /* 0x324 */ + u32 oobboutwidth; /* 0x328 */ + u32 PAD[5]; + u32 oobcextwidth; /* 0x340 */ + u32 oobcinwidth; /* 0x344 */ + u32 oobcoutwidth; /* 0x348 */ + u32 PAD[5]; + u32 oobdextwidth; /* 0x360 */ + u32 oobdinwidth; /* 0x364 */ + u32 oobdoutwidth; /* 0x368 */ + u32 PAD[37]; + u32 ioctrlset; /* 0x400 */ + u32 ioctrlclear; /* 0x404 */ + u32 ioctrl; /* 0x408 */ + u32 PAD[61]; + u32 iostatus; /* 0x500 */ + u32 PAD[127]; + u32 ioctrlwidth; /* 0x700 */ + u32 iostatuswidth; /* 0x704 */ + u32 PAD[62]; + u32 resetctrl; /* 0x800 */ + u32 resetstatus; /* 0x804 */ + u32 resetreadid; /* 0x808 */ + u32 resetwriteid; /* 0x80c */ + u32 PAD[60]; + u32 errlogctrl; /* 0x900 */ + u32 errlogdone; /* 0x904 */ + u32 errlogstatus; /* 0x908 */ + u32 errlogaddrlo; /* 0x90c */ + u32 errlogaddrhi; /* 0x910 */ + u32 errlogid; /* 0x914 */ + u32 errloguser; /* 0x918 */ + u32 errlogflags; /* 0x91c */ + u32 PAD[56]; + u32 intstatus; /* 0xa00 */ + u32 PAD[127]; + u32 config; /* 0xe00 */ + u32 PAD[63]; + u32 itcr; /* 0xf00 */ + u32 PAD[3]; + u32 itipooba; /* 0xf10 */ + u32 itipoobb; /* 0xf14 */ + u32 itipoobc; /* 0xf18 */ + u32 itipoobd; /* 0xf1c */ + u32 PAD[4]; + u32 itipoobaout; /* 0xf30 */ + u32 itipoobbout; /* 0xf34 */ + u32 itipoobcout; /* 0xf38 */ + u32 itipoobdout; /* 0xf3c */ + u32 PAD[4]; + u32 itopooba; /* 0xf50 */ + u32 itopoobb; /* 0xf54 */ + u32 itopoobc; /* 0xf58 */ + u32 itopoobd; /* 0xf5c */ + u32 PAD[4]; + u32 itopoobain; /* 0xf70 */ + u32 itopoobbin; /* 0xf74 */ + u32 itopoobcin; /* 0xf78 */ + u32 itopoobdin; /* 0xf7c */ + u32 PAD[4]; + u32 itopreset; /* 0xf90 */ + u32 PAD[15]; + u32 peripherialid4; /* 0xfd0 */ + u32 peripherialid5; /* 0xfd4 */ + u32 peripherialid6; /* 0xfd8 */ + u32 peripherialid7; /* 0xfdc */ + u32 peripherialid0; /* 0xfe0 */ + u32 peripherialid1; /* 0xfe4 */ + u32 peripherialid2; /* 0xfe8 */ + u32 peripherialid3; /* 0xfec */ + u32 componentid0; /* 0xff0 */ + u32 componentid1; /* 0xff4 */ + u32 componentid2; /* 0xff8 */ + u32 componentid3; /* 0xffc */ +} aidmp_t; + /* EROM parsing */ static u32 -get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) +get_erom_ent(struct si_pub *sih, u32 **eromptr, u32 mask, u32 match) { u32 ent; uint inv = 0, nom = 0; @@ -77,7 +402,7 @@ get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) } static u32 -get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st, +get_asd(struct si_pub *sih, u32 **eromptr, uint sp, uint ad, uint st, u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh) { u32 asd, sz, szd; @@ -116,7 +441,7 @@ 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) +void ai_scan(struct si_pub *sih, void *regs, uint devid) { si_info_t *sii = SI_INFO(sih); chipcregs_t *cc = (chipcregs_t *) regs; @@ -319,7 +644,7 @@ void ai_scan(si_t *sih, void *regs, uint devid) /* 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) +void *ai_setcoreidx(struct si_pub *sih, uint coreidx) { si_info_t *sii = SI_INFO(sih); u32 addr = sii->coresba[coreidx]; @@ -368,13 +693,13 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) } /* Return the number of address spaces in current core */ -int ai_numaddrspaces(si_t *sih) +int ai_numaddrspaces(struct si_pub *sih) { return 2; } /* Return the address of the nth address space in the current core */ -u32 ai_addrspace(si_t *sih, uint asidx) +u32 ai_addrspace(struct si_pub *sih, uint asidx) { si_info_t *sii; uint cidx; @@ -393,7 +718,7 @@ u32 ai_addrspace(si_t *sih, uint asidx) } /* Return the size of the nth address space in the current core */ -u32 ai_addrspacesize(si_t *sih, uint asidx) +u32 ai_addrspacesize(struct si_pub *sih, uint asidx) { si_info_t *sii; uint cidx; @@ -411,7 +736,7 @@ u32 ai_addrspacesize(si_t *sih, uint asidx) } } -uint ai_flag(si_t *sih) +uint ai_flag(struct si_pub *sih) { si_info_t *sii; aidmp_t *ai; @@ -426,11 +751,11 @@ uint ai_flag(si_t *sih) return R_REG(&ai->oobselouta30) & 0x1f; } -void ai_setint(si_t *sih, int siflag) +void ai_setint(struct si_pub *sih, int siflag) { } -uint ai_corevendor(si_t *sih) +uint ai_corevendor(struct si_pub *sih) { si_info_t *sii; u32 cia; @@ -440,7 +765,7 @@ uint ai_corevendor(si_t *sih) return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; } -uint ai_corerev(si_t *sih) +uint ai_corerev(struct si_pub *sih) { si_info_t *sii; u32 cib; @@ -450,7 +775,7 @@ uint ai_corerev(si_t *sih) return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; } -bool ai_iscoreup(si_t *sih) +bool ai_iscoreup(struct si_pub *sih) { si_info_t *sii; aidmp_t *ai; @@ -463,7 +788,7 @@ bool ai_iscoreup(si_t *sih) && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0)); } -void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) +void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val) { si_info_t *sii; aidmp_t *ai; @@ -485,7 +810,7 @@ void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) } } -u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) +u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val) { si_info_t *sii; aidmp_t *ai; @@ -508,7 +833,7 @@ u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) return R_REG(&ai->ioctrl); } -u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) +u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val) { si_info_t *sii; aidmp_t *ai; @@ -542,7 +867,8 @@ static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, static void ai_nvram_process(si_info_t *sii, char *pvars); /* dev path concatenation util */ -static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name); +static char *ai_devpathvar(struct si_pub *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); @@ -558,7 +884,7 @@ static u32 ai_gpioreservation; * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -si_t *ai_attach(uint devid, void *regs, uint bustype, +struct si_pub *ai_attach(uint devid, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { si_info_t *sii; @@ -578,7 +904,7 @@ si_t *ai_attach(uint devid, void *regs, uint bustype, sii->vars = vars ? *vars : NULL; sii->varsz = varsz ? *varsz : 0; - return (si_t *) sii; + return (struct si_pub *) sii; } /* global kernel resource */ @@ -859,9 +1185,6 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, udelay(10); } - /* Init nvram from flash if it exists */ - nvram_init(); - /* Init nvram from sprom/otp if they exist */ if (srom_var_init (&sii->pub, bustype, regs, vars, varsz)) { @@ -950,13 +1273,13 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, } /* may be called with core in reset */ -void ai_detach(si_t *sih) +void ai_detach(struct si_pub *sih) { si_info_t *sii; uint idx; struct si_pub *si_local = NULL; - bcopy(&sih, &si_local, sizeof(si_t **)); + memcpy(&si_local, &sih, sizeof(struct si_pub **)); sii = SI_INFO(sih); @@ -970,8 +1293,6 @@ void ai_detach(si_t *sih) sii->regs[idx] = NULL; } - nvram_exit(); /* free up nvram buffers */ - if (sih->bustype == PCI_BUS) { if (sii->pch) pcicore_deinit(sii->pch); @@ -984,7 +1305,8 @@ void ai_detach(si_t *sih) /* register driver interrupt disabling and restoring callback functions */ void -ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, +ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn, + void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) { si_info_t *sii; @@ -1000,7 +1322,7 @@ ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, sii->dev_coreid = sii->coreid[sii->curidx]; } -void ai_deregister_intr_callback(si_t *sih) +void ai_deregister_intr_callback(struct si_pub *sih) { si_info_t *sii; @@ -1008,7 +1330,7 @@ void ai_deregister_intr_callback(si_t *sih) sii->intrsoff_fn = NULL; } -uint ai_coreid(si_t *sih) +uint ai_coreid(struct si_pub *sih) { si_info_t *sii; @@ -1016,7 +1338,7 @@ uint ai_coreid(si_t *sih) return sii->coreid[sii->curidx]; } -uint ai_coreidx(si_t *sih) +uint ai_coreidx(struct si_pub *sih) { si_info_t *sii; @@ -1024,13 +1346,13 @@ uint ai_coreidx(si_t *sih) return sii->curidx; } -bool ai_backplane64(si_t *sih) +bool ai_backplane64(struct si_pub *sih) { return (sih->cccaps & CC_CAP_BKPLN64) != 0; } /* return index of coreid or BADIDX if not found */ -uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit) +uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit) { si_info_t *sii; uint found; @@ -1056,7 +1378,7 @@ uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit) * Moreover, callers should keep interrupts off during switching * out of and back to d11 core. */ -void *ai_setcore(si_t *sih, uint coreid, uint coreunit) +void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit) { uint idx; @@ -1068,7 +1390,8 @@ void *ai_setcore(si_t *sih, uint coreid, uint coreunit) } /* 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 *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx, + uint *intr_val) { void *cc; si_info_t *sii; @@ -1093,7 +1416,7 @@ void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) } /* restore coreidx and restore interrupt */ -void ai_restore_core(si_t *sih, uint coreid, uint intr_val) +void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val) { si_info_t *sii; @@ -1106,7 +1429,7 @@ void ai_restore_core(si_t *sih, uint coreid, uint intr_val) INTR_RESTORE(sii, intr_val); } -void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val) +void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val) { si_info_t *sii = SI_INFO(sih); u32 *w = (u32 *) sii->curwrap; @@ -1124,7 +1447,8 @@ void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val) * 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 ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask, + uint val) { uint origidx = 0; u32 *r = NULL; @@ -1208,7 +1532,7 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) return w; } -void ai_core_disable(si_t *sih, u32 bits) +void ai_core_disable(struct si_pub *sih, u32 bits) { si_info_t *sii; u32 dummy; @@ -1235,7 +1559,7 @@ void ai_core_disable(si_t *sih, u32 bits) * 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) +void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits) { si_info_t *sii; aidmp_t *ai; @@ -1352,7 +1676,7 @@ static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs) } /* initialize power control delay registers */ -void ai_clkctl_init(si_t *sih) +void ai_clkctl_init(struct si_pub *sih) { si_info_t *sii; uint origidx = 0; @@ -1390,7 +1714,7 @@ void ai_clkctl_init(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) +u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) { si_info_t *sii; uint origidx = 0; @@ -1438,7 +1762,7 @@ u16 ai_clkctl_fast_pwrup_delay(si_t *sih) } /* turn primary xtal and/or pll off/on */ -int ai_clkctl_xtal(si_t *sih, uint what, bool on) +int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on) { si_info_t *sii; u32 in, out, outen; @@ -1515,7 +1839,7 @@ int ai_clkctl_xtal(si_t *sih, uint what, bool on) * this is a wrapper over the next internal function * to allow flexible policy settings for outside caller */ -bool ai_clkctl_cc(si_t *sih, uint mode) +bool ai_clkctl_cc(struct si_pub *sih, uint mode) { si_info_t *sii; @@ -1624,7 +1948,7 @@ static bool _ai_clkctl_cc(si_info_t *sii, uint mode) } /* Build device path. Support SI, PCI, and JTAG for now. */ -int ai_devpath(si_t *sih, char *path, int size) +int ai_devpath(struct si_pub *sih, char *path, int size) { int slen; @@ -1657,7 +1981,7 @@ int ai_devpath(si_t *sih, char *path, int size) } /* Get a variable, but only if it has a devpath prefix */ -char *ai_getdevpathvar(si_t *sih, const char *name) +char *ai_getdevpathvar(struct si_pub *sih, const char *name) { char varname[SI_DEVPATH_BUFSZ + 32]; @@ -1667,7 +1991,7 @@ char *ai_getdevpathvar(si_t *sih, const char *name) } /* Get a variable, but only if it has a devpath prefix */ -int ai_getdevpathintvar(si_t *sih, const char *name) +int ai_getdevpathintvar(struct si_pub *sih, const char *name) { #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) return getintvar(NULL, name); @@ -1680,7 +2004,7 @@ int ai_getdevpathintvar(si_t *sih, const char *name) #endif } -char *ai_getnvramflvar(si_t *sih, const char *name) +char *ai_getnvramflvar(struct si_pub *sih, const char *name) { return getvar(NULL, name); } @@ -1690,7 +2014,8 @@ char *ai_getnvramflvar(si_t *sih, const char *name) * len == 0 or var is NULL, var is still returned. On overflow, the * first char will be set to '\0'. */ -static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name) +static char *ai_devpathvar(struct si_pub *sih, char *var, int len, + const char *name) { uint path_len; @@ -1726,7 +2051,7 @@ static __used bool ai_ispcie(si_info_t *sii) return true; } -bool ai_pci_war16165(si_t *sih) +bool ai_pci_war16165(struct si_pub *sih) { si_info_t *sii; @@ -1735,7 +2060,7 @@ bool ai_pci_war16165(si_t *sih) return PCI(sii) && (sih->buscorerev <= 10); } -void ai_pci_up(si_t *sih) +void ai_pci_up(struct si_pub *sih) { si_info_t *sii; @@ -1754,7 +2079,7 @@ void ai_pci_up(si_t *sih) } /* Unconfigure and/or apply various WARs when system is going to sleep mode */ -void ai_pci_sleep(si_t *sih) +void ai_pci_sleep(struct si_pub *sih) { si_info_t *sii; @@ -1764,7 +2089,7 @@ void ai_pci_sleep(si_t *sih) } /* Unconfigure and/or apply various WARs when going down */ -void ai_pci_down(si_t *sih) +void ai_pci_down(struct si_pub *sih) { si_info_t *sii; @@ -1785,10 +2110,10 @@ void ai_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 ai_pci_setup(si_t *sih, uint coremask) +void ai_pci_setup(struct si_pub *sih, uint coremask) { si_info_t *sii; - struct sbpciregs *pciregs = NULL; + void *regs = NULL; u32 siflag = 0, w; uint idx = 0; @@ -1805,7 +2130,7 @@ void ai_pci_setup(si_t *sih, uint coremask) siflag = ai_flag(sih); /* switch over to pci core */ - pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx); + regs = ai_setcoreidx(sih, sii->pub.buscoreidx); } /* @@ -1823,16 +2148,7 @@ void ai_pci_setup(si_t *sih, uint coremask) } if (PCI(sii)) { - OR_REG(&pciregs->sbtopci2, - (SBTOPCI_PREF | SBTOPCI_BURST)); - if (sii->pub.buscorerev >= 11) { - OR_REG(&pciregs->sbtopci2, - SBTOPCI_RC_READMULTI); - w = R_REG(&pciregs->clkrun); - W_REG(&pciregs->clkrun, - (w | PCI_CLKRUN_DSBL)); - w = R_REG(&pciregs->clkrun); - } + pcicore_pci_setup(sii->pch, regs); /* switch back to previous core */ ai_setcoreidx(sih, idx); @@ -1843,13 +2159,10 @@ void ai_pci_setup(si_t *sih, uint coremask) * Fixup SROMless PCI device's configuration. * The current core may be changed upon return. */ -int ai_pci_fixcfg(si_t *sih) +int ai_pci_fixcfg(struct si_pub *sih) { - uint origidx, pciidx; - struct sbpciregs *pciregs = NULL; - sbpcieregs_t *pcieregs = NULL; + uint origidx; void *regs = NULL; - u16 val16, *reg16 = NULL; si_info_t *sii = SI_INFO(sih); @@ -1858,23 +2171,8 @@ int ai_pci_fixcfg(si_t *sih) origidx = ai_coreidx(&sii->pub); /* check 'pi' is correct and fix it if not */ - if (sii->pub.buscoretype == PCIE_CORE_ID) { - pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0); - regs = pcieregs; - reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; - } else if (sii->pub.buscoretype == PCI_CORE_ID) { - pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0); - regs = pciregs; - reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; - } - pciidx = ai_coreidx(&sii->pub); - val16 = R_REG(reg16); - if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { - val16 = - (u16) (pciidx << SRSH_PI_SHIFT) | (val16 & - ~SRSH_PI_MASK); - W_REG(reg16, val16); - } + regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0); + pcicore_fixcfg(sii->pch, regs); /* restore the original index */ ai_setcoreidx(&sii->pub, origidx); @@ -1884,7 +2182,7 @@ int ai_pci_fixcfg(si_t *sih) } /* mask&set gpiocontrol bits */ -u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) +u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority) { uint regoff; @@ -1904,7 +2202,7 @@ u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) return ai_corereg(sih, SI_CC_IDX, regoff, mask, val); } -void ai_chipcontrl_epa4331(si_t *sih, bool on) +void ai_chipcontrl_epa4331(struct si_pub *sih, bool on) { si_info_t *sii; chipcregs_t *cc; @@ -1938,7 +2236,7 @@ void ai_chipcontrl_epa4331(si_t *sih, bool on) } /* Enable BT-COEX & Ex-PA for 4313 */ -void ai_epa_4313war(si_t *sih) +void ai_epa_4313war(struct si_pub *sih) { si_info_t *sii; chipcregs_t *cc; @@ -1957,7 +2255,7 @@ void ai_epa_4313war(si_t *sih) } /* check if the device is removed */ -bool ai_deviceremoved(si_t *sih) +bool ai_deviceremoved(struct si_pub *sih) { u32 w; si_info_t *sii; @@ -1974,7 +2272,7 @@ bool ai_deviceremoved(si_t *sih) return false; } -bool ai_is_sprom_available(si_t *sih) +bool ai_is_sprom_available(struct si_pub *sih) { if (sih->ccrev >= 31) { si_info_t *sii; @@ -2011,7 +2309,7 @@ bool ai_is_sprom_available(si_t *sih) } } -bool ai_is_otp_disabled(si_t *sih) +bool ai_is_otp_disabled(struct si_pub *sih) { switch (sih->chip) { case BCM4329_CHIP_ID: @@ -2039,14 +2337,14 @@ bool ai_is_otp_disabled(si_t *sih) } } -bool ai_is_otp_powered(si_t *sih) +bool ai_is_otp_powered(struct si_pub *sih) { if (PMUCTL_ENAB(sih)) return si_pmu_is_otp_powered(sih); return true; } -void ai_otp_power(si_t *sih, bool on) +void ai_otp_power(struct si_pub *sih, bool on) { if (PMUCTL_ENAB(sih)) si_pmu_otp_power(sih, on); diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h index b98099eaa621..b007facbef1f 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.h +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.h @@ -14,18 +14,8 @@ * 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> +#ifndef _BRCM_AIUTILS_H_ +#define _BRCM_AIUTILS_H_ /* * SOC Interconnect Address Map. @@ -158,9 +148,7 @@ * maps all unused address ranges */ -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ +/* chipcommon being the first core: */ #define SI_CC_IDX 0 /* SOC Interconnect types (aka chip types) */ @@ -225,7 +213,70 @@ #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 CC_SROM_OTP 0x800 /* SROM/OTP address space */ + +/* gpiotimerval */ +#define GPIO_ONTIME_SHIFT 16 + +/* Fields in clkdiv */ +#define CLKD_OTP 0x000f0000 +#define CLKD_OTP_SHIFT 16 + +/* When Srom support present, fields in sromcontrol */ +#define SRC_START 0x80000000 +#define SRC_BUSY 0x80000000 +#define SRC_OPCODE 0x60000000 +#define SRC_OP_READ 0x00000000 +#define SRC_OP_WRITE 0x20000000 +#define SRC_OP_WRDIS 0x40000000 +#define SRC_OP_WREN 0x60000000 +#define SRC_OTPSEL 0x00000010 +#define SRC_LOCK 0x00000008 +#define SRC_SIZE_MASK 0x00000006 +#define SRC_SIZE_1K 0x00000000 +#define SRC_SIZE_4K 0x00000002 +#define SRC_SIZE_16K 0x00000004 +#define SRC_SIZE_SHIFT 1 +#define SRC_PRESENT 0x00000001 + +/* 4330 chip-specific ChipStatus register bits */ +#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ +#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ +#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ +#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ +#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ +#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ +#define CST4330_OTP_PRESENT 0x00000010 +#define CST4330_LPO_AUTODET_EN 0x00000020 +#define CST4330_ARMREMAP_0 0x00000040 +#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ +#define CST4330_ILPDIV_EN 0x00000100 +#define CST4330_LPO_SEL 0x00000200 +#define CST4330_RES_INIT_MODE_SHIFT 10 +#define CST4330_RES_INIT_MODE_MASK 0x00000c00 +#define CST4330_CBUCK_MODE_SHIFT 12 +#define CST4330_CBUCK_MODE_MASK 0x00003000 +#define CST4330_CBUCK_POWER_OK 0x00004000 +#define CST4330_BB_PLL_LOCKED 0x00008000 + +/* 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 BCM4717_PKG_ID 9 /* 4717 package id */ +#define BCM4718_PKG_ID 10 /* 4718 package id */ +#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ +#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ +#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ + +/* these are router chips */ +#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ +#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ +#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ +#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ +#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ + + +#define SI_INFO(sih) ((si_info_t *)sih) #define GOODCOREADDR(x, b) \ (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ @@ -315,13 +366,6 @@ struct si_pub { }; /* - * 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 @@ -453,94 +497,94 @@ typedef struct si_info { } 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, +extern void ai_scan(struct si_pub *sih, void *regs, uint devid); + +extern uint ai_flag(struct si_pub *sih); +extern void ai_setint(struct si_pub *sih, int siflag); +extern uint ai_coreidx(struct si_pub *sih); +extern uint ai_corevendor(struct si_pub *sih); +extern uint ai_corerev(struct si_pub *sih); +extern bool ai_iscoreup(struct si_pub *sih); +extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx); +extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val); +extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val); +extern uint ai_corereg(struct si_pub *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); +extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(struct si_pub *sih, u32 bits); +extern int ai_numaddrspaces(struct si_pub *sih); +extern u32 ai_addrspace(struct si_pub *sih, uint asidx); +extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx); +extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val); /* === exported functions === */ -extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, +extern struct si_pub *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 void ai_detach(struct si_pub *sih); +extern bool ai_pci_war16165(struct si_pub *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, +extern uint ai_coreid(struct si_pub *sih); +extern uint ai_corerev(struct si_pub *sih); +extern uint ai_corereg(struct si_pub *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, +extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val); +extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val); +extern bool ai_iscoreup(struct si_pub *sih); +extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit); +extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx); +extern void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit); +extern void *ai_switch_core(struct si_pub *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, +extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val); +extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(struct si_pub *sih, u32 bits); +extern u32 ai_alp_clock(struct si_pub *sih); +extern u32 ai_ilp_clock(struct si_pub *sih); +extern void ai_pci_setup(struct si_pub *sih, uint coremask); +extern void ai_setint(struct si_pub *sih, int siflag); +extern bool ai_backplane64(struct si_pub *sih); +extern void ai_register_intr_callback(struct si_pub *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, +extern void ai_deregister_intr_callback(struct si_pub *sih); +extern void ai_clkctl_init(struct si_pub *sih); +extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); +extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); +extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on); +extern bool ai_deviceremoved(struct si_pub *sih); +extern u32 ai_gpiocontrol(struct si_pub *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); +extern bool ai_is_otp_disabled(struct si_pub *sih); +extern bool ai_is_otp_powered(struct si_pub *sih); +extern void ai_otp_power(struct si_pub *sih, bool on); /* SPROM availability */ -extern bool ai_is_sprom_available(si_t *sih); +extern bool ai_is_sprom_available(struct si_pub *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); +extern int ai_devpath(struct si_pub *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 char *ai_getdevpathvar(struct si_pub *sih, const char *name); +extern int ai_getdevpathintvar(struct si_pub *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_pci_sleep(struct si_pub *sih); +extern void ai_pci_down(struct si_pub *sih); +extern void ai_pci_up(struct si_pub *sih); +extern int ai_pci_fixcfg(struct si_pub *sih); -extern void ai_chipcontrl_epa4331(si_t *sih, bool on); +extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on); /* Enable Ex-PA for 4313 */ -extern void ai_epa_4313war(si_t *sih); +extern void ai_epa_4313war(struct si_pub *sih); -char *ai_getnvramflvar(si_t *sih, const char *name); +char *ai_getnvramflvar(struct si_pub *sih, const char *name); -#endif /* _aiutils_h_ */ +#endif /* _BRCM_AIUTILS_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/alloc.c index 82c64cd4486f..a884ae4e48bb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/alloc.c @@ -16,25 +16,20 @@ #include <linux/kernel.h> #include <linux/types.h> -#include <bcmdefs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <wlioctl.h> -#include <sbhnddma.h> +#include "dma.h" #include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" -#include "wlc_rate.h" -#include "wlc_bsscfg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" +#include "types.h" +#include "scb.h" +#include "pub.h" +#include "alloc.h" +#include "rate.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit); static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg); @@ -152,8 +147,6 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) goto fail; } - wlc->hwrxoff = WL_HWRXOFF; - /* allocate struct wlc_pub state structure */ wlc->pub = wlc_pub_malloc(unit, err, devid); if (wlc->pub == NULL) { @@ -206,14 +199,6 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) } wlc_bsscfg_ID_assign(wlc, wlc->cfg); - 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] = kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC); if (wlc->wsec_def_keys[0] == NULL) { @@ -284,7 +269,6 @@ void wlc_detach_mfree(struct wlc_info *wlc) wlc_pub_mfree(wlc->pub); kfree(wlc->modulecb); kfree(wlc->default_bss); - kfree(wlc->pkt_callback); kfree(wlc->wsec_def_keys[0]); kfree(wlc->protection); kfree(wlc->stf); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/alloc.h index 95f951eb2b2f..95f951eb2b2f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h +++ b/drivers/staging/brcm80211/brcmsmac/alloc.h diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/ampdu.c index 85ad70096056..7cf0018f58c5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/ampdu.c @@ -16,27 +16,21 @@ #include <linux/kernel.h> #include <net/mac80211.h> -#include <bcmdefs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <wlioctl.h> -#include <sbhnddma.h> -#include <hnddma.h> +#include "dma.h" #include <d11.h> -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_antsel.h" -#include "wl_export.h" -#include "wl_dbg.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_ampdu.h" +#include "types.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "antsel.h" +#include "channel.h" +#include "main.h" +#include "ampdu.h" #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 */ @@ -499,10 +493,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, wlc_ampdu_agg(ampdu, scb, p, tid); - if (wlc->block_datafifo) { - wiphy_err(wiphy, "%s: Fifo blocked\n", __func__); - return -EBUSY; - } rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; ampdu_len = 0; dma_len = 0; @@ -598,7 +588,7 @@ 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) bcm_pkttotlen(p); + dma_len += (u16) brcmu_pkttotlen(p); BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" " seg_cnt %d null delim %d\n", @@ -693,8 +683,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && ((u8) (p->priority) == tid)) { - plen = - bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD; + plen = brcmu_pkttotlen(p) + + AMPDU_MAX_MPDU_OVERHEAD; plen = max(scb_ampdu->min_len, plen); if ((plen + ampdu_len) > maxlen) { @@ -711,7 +701,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, p = NULL; continue; } - p = bcm_pktq_pdeq(&qi->q, prec); + p = brcmu_pktq_pdeq(&qi->q, prec); } else { p = NULL; } @@ -871,7 +861,7 @@ 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); - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); /* break out if last packet of ampdu */ if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == TXC_AMPDU_LAST) @@ -1000,7 +990,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, txs->phyerr); if (WL_ERROR_ON()) { - bcm_prpkt("txpkt (AMPDU)", p); + brcmu_prpkt("txpkt (AMPDU)", p); wlc_print_txdesc((d11txh_t *) p->data); } wlc_print_txstatus(txs); @@ -1246,7 +1236,7 @@ void wlc_ampdu_flush(struct wlc_info *wlc, ampdu_pars.sta = sta; ampdu_pars.tid = tid; for (prec = 0; prec < pq->num_prec; prec++) { - bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + brcmu_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/ampdu.h index 63d403b036f4..df7d7d969348 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h +++ b/drivers/staging/brcm80211/brcmsmac/ampdu.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_ampdu_h_ -#define _wlc_ampdu_h_ +#ifndef _BRCM_AMPDU_H_ +#define _BRCM_AMPDU_H_ extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); extern void wlc_ampdu_detach(struct ampdu_info *ampdu); @@ -26,4 +26,4 @@ extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); -#endif /* _wlc_ampdu_h_ */ +#endif /* _BRCM_AMPDU_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/antsel.c index 111ef32b7ac4..f967c592cae7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/antsel.c @@ -14,33 +14,32 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <wlc_cfg.h> - #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <bcmnvram.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <bcmdevs.h> -#include <sbhnddma.h> -#include <wlioctl.h> +#include <brcm_hw_ids.h> +#include "dma.h" #include "d11.h" -#include "wlc_rate.h" -#include "wlc_key.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wl_dbg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_bmac.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wlc_phy_shim.h" -#include "wlc_antsel.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "bmac.h" +#include "channel.h" +#include "main.h" +#include "antsel.h" + +#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ +#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ +#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ +#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ +#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ +#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ /* useful macros */ #define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/antsel.h index 2470c73fc4ed..c1b9cef980c6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h +++ b/drivers/staging/brcm80211/brcmsmac/antsel.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_antsel_h_ -#define _wlc_antsel_h_ +#ifndef _BRCM_ANTSEL_H_ +#define _BRCM_ANTSEL_H_ extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc); extern void wlc_antsel_detach(struct antsel_info *asi); @@ -26,4 +26,4 @@ extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, u8 *fbantcfg); extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); -#endif /* _wlc_antsel_h_ */ +#endif /* _BRCM_ANTSEL_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c deleted file mode 100644 index bbfc64204363..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c +++ /dev/null @@ -1,714 +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 <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/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/bmac.c index 453492610613..417cf544de3f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/bmac.c @@ -21,41 +21,31 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> -#include <proto/802.11.h> -#include <bcmdefs.h> -#include <bcmdevs.h> -#include <bcmwifi.h> +#include <defs.h> +#include <brcm_hw_ids.h> +#include <brcmu_wifi.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 "wlc_types.h" -#include "wlc_pmu.h" +#include "srom.h" +#include "otp.h" +#include <brcmu_utils.h> +#include <chipcommon.h> +#include <nicpci.h> +#include "dma.h" + +#include "types.h" +#include "pmu.h" #include "d11.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_phy_shim.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wl_ucode.h" -#include "wlc_antsel.h" -#include "pcie_core.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" -#include "wlc_bmac.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" +#include "ucode_loader.h" +#include "antsel.h" +#include "alloc.h" +#include "bmac.h" +#include "mac80211_if.h" #define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ @@ -78,6 +68,9 @@ (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \ (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv)) +#define APHY_SLOT_TIME 9 +#define BPHY_SLOT_TIME 20 + /* * The following table lists the buffer memory allocated to xmt fifos in HW. * the size is in units of 256bytes(one block), total size is HW dependent @@ -241,7 +234,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); + macintmask = brcms_intrsoff(wlc->wl); /* radio off */ wlc_phy_switch_radio(wlc_hw->band->pi, OFF); @@ -318,7 +311,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) if (DEVICEREMOVED(wlc)) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return false; } @@ -333,7 +326,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) /* BCN template is available */ /* ZZZ: Use AP_ACTIVE ? */ - if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) + if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub)) && (macintstatus & MI_BCNTPL)) { wlc_update_beacon(wlc); } @@ -389,7 +382,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) __func__, wlc_hw->sih->chip, wlc_hw->sih->chiprev); /* big hammer */ - wl_init(wlc->wl); + brcms_init(wlc->wl); } /* gptimer timeout */ @@ -400,7 +393,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) if (macintstatus & MI_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); + brcms_rfkill_set_hw_state(wlc->wl); } /* send any enq'd tx packets. Just makes sure to jump start tx */ @@ -411,7 +404,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) return wlc->macintstatus != 0; fatal: - wl_init(wlc->wl); + brcms_init(wlc->wl); return wlc->macintstatus != 0; } @@ -529,7 +522,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) NULL), DMAREG(wlc_hw, DMA_RX, 0), (wme ? tune->ntxd : 0), tune->nrxd, tune->rxbufsz, -1, tune->nrxbufpost, - WL_HWRXOFF, &wl_msg_level); + WL_HWRXOFF, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[0]); /* @@ -541,7 +534,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 1), NULL, tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[1]); /* @@ -552,7 +545,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 2), NULL, tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[2]); /* * FIFO 3 @@ -562,7 +555,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 3), NULL, tune->ntxd, 0, 0, -1, - 0, 0, &wl_msg_level); + 0, 0, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[3]); /* Cleaner to leave this as if with AP defined */ @@ -743,7 +736,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc->war16165 = true; /* check device id(srom, nvram etc.) to set bands */ - if (wlc_hw->deviceid == BCM43224_D11N_ID) { + if (wlc_hw->deviceid == BCM43224_D11N_ID || + wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) { /* Dualband boards */ wlc_hw->_nbands = 2; } else @@ -925,7 +919,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, err = 21; goto fail; } - bcm_ether_atoe(macaddr, wlc_hw->etheraddr); + brcmu_ether_atoe(macaddr, wlc_hw->etheraddr); if (is_broadcast_ether_addr(wlc_hw->etheraddr) || is_zero_ether_addr(wlc_hw->etheraddr)) { wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n", @@ -1052,7 +1046,7 @@ wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, wlc_clkctl_clk(wlc_hw, CLK_FAST); /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); + macintmask = brcms_intrsoff(wlc->wl); /* set up the specified band and chanspec */ wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); @@ -1072,7 +1066,7 @@ wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, wlc_bmac_bsinit(wlc, chanspec); /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended * and wlc_enable_mac() will clear this override bit. @@ -1142,7 +1136,7 @@ int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) /* FULLY enable dynamic power control and d11 core interrupt */ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); - wl_intrson(wlc_hw->wlc->wl); + brcms_intrson(wlc_hw->wlc->wl); return 0; } @@ -1163,7 +1157,7 @@ int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) wlc_hw->wlc->macintmask = 0; else { /* now disable interrupts */ - wl_intrsoff(wlc_hw->wlc->wl); + brcms_intrsoff(wlc_hw->wlc->wl); /* ensure we're running on the pll clock again */ wlc_clkctl_clk(wlc_hw, CLK_FAST); @@ -1203,7 +1197,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) if (R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) wlc_suspend_mac_and_wait(wlc_hw->wlc); - callbacks += wl_reset(wlc_hw->wlc->wl); + callbacks += brcms_reset(wlc_hw->wlc->wl); wlc_coredisable(wlc_hw); } @@ -1887,7 +1881,7 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, wlc->macintstatus = MI_DMAINT; /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); /* ucode should still be suspended.. */ WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); @@ -2065,7 +2059,7 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) { - struct hnddma_pub *di = wlc_hw->di[fifo]; + struct dma_pub *di = wlc_hw->di[fifo]; return dma_rxreset(di); } @@ -2685,7 +2679,7 @@ static u32 wlc_wlintrsoff(struct wlc_info *wlc) if (!wlc->hw->up) return 0; - return wl_intrsoff(wlc->wl); + return brcms_intrsoff(wlc->wl); } static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) @@ -2693,7 +2687,7 @@ static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) if (!wlc->hw->up) return; - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); } u32 wlc_intrsoff(struct wlc_info *wlc) @@ -3067,7 +3061,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (mc == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mc & MCTL_PSM_JMP_0); @@ -3078,7 +3072,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (mi == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mi & MI_MACSSPNDD); @@ -3103,7 +3097,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (mc == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mc & MCTL_PSM_JMP_0); @@ -3418,7 +3412,7 @@ static void wlc_flushqueues(struct wlc_info *wlc) /* free any posted tx packets */ for (i = 0; i < NFIFO; i++) if (wlc_hw->di[i]) { - dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); + dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); TXPKTPENDCLR(wlc, i); BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/bmac.h index a5dccc273ac5..af8af69fc1e9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/bmac.h @@ -13,19 +13,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_bmac_h_ -#define _wlc_bmac_h_ - -/* XXXXX this interface is under wlc.c by design - * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign - * - * high driver files(e.g. wlc_ampdu.c etc) - * wlc.h/wlc.c - * wlc_bmac.h/wlc_bmac.c - * - * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c - * create wrappers in wlc.c if needed - */ +#ifndef _BRCM_BOTTOM_MAC_H_ +#define _BRCM_BOTTOM_MAC_H_ /* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) driver */ @@ -175,4 +164,4 @@ 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); -#endif /* _wlc_bmac_h_ */ +#endif /* _BRCM_BOTTOM_MAC_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/channel.c index a3a2bf9b4f12..9583140b0ff6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/channel.c @@ -19,26 +19,21 @@ #include <linux/module.h> #include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <bcmnvram.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <sbhnddma.h> -#include <wlioctl.h> +#include "dma.h" -#include "wlc_types.h" +#include "types.h" #include "d11.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_bmac.h" -#include "wlc_rate.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_stf.h" -#include "wl_dbg.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "bmac.h" +#include "rate.h" +#include "channel.h" +#include "main.h" +#include "stf.h" #define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) #define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ @@ -1496,7 +1491,7 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) u8 channel = CHSPEC_CHANNEL(chspec); /* check the chanspec */ - if (bcm_chspec_malformed(chspec)) { + if (brcmu_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_channel.h b/drivers/staging/brcm80211/brcmsmac/channel.h index b8dec5b39d85..30178390b5d6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h +++ b/drivers/staging/brcm80211/brcmsmac/channel.h @@ -14,11 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _WLC_CHANNEL_H_ -#define _WLC_CHANNEL_H_ +#ifndef _BRCM_CHANNEL_H_ +#define _BRCM_CHANNEL_H_ #define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ + struct wlc_info; /* maxpwr mapping to 5GHz band channels: @@ -50,6 +51,12 @@ struct wlc_info; #define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ #define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ +#define NBANDS(wlc) ((wlc)->pub->_nbands) +#define NBANDS_PUB(pub) ((pub)->_nbands) +#define NBANDS_HW(hw) ((hw)->_nbands) + +#define IS_SINGLEBAND_5G(device) 0 + /* locale channel and power info. */ typedef struct { u32 valid_channels; diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index d91e4189a3e8..855f1d341e1d 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -14,23 +14,10 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _D11_H -#define _D11_H +#ifndef _BRCM_D11_H_ +#define _BRCM_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 -#error "WL_RSSI_ANT_MAX does not match" -#endif - -/* 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 <linux/ieee80211.h> #define BCN_TMPL_LEN 512 /* length of the BCN template area */ @@ -56,6 +43,12 @@ #define TX_DATA_FIFO TX_AC_BE_FIFO #define TX_CTL_FIFO TX_AC_VO_FIFO +#ifndef WL_RSSI_ANT_MAX +#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ +#elif WL_RSSI_ANT_MAX != 4 +#error "WL_RSSI_ANT_MAX does not match" +#endif + typedef volatile struct { u32 intstatus; u32 intmask; @@ -112,8 +105,6 @@ typedef volatile struct { /* * Host Interface Registers - * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h - * - but definitely not complete */ typedef volatile struct _d11regs { /* Device Control ("semi-standard host registers") */ @@ -439,9 +430,6 @@ typedef volatile struct _d11regs { /* SHM *//* 0x800 - 0xEFE */ u16 PAD[0x380]; /* 0x800 - 0xEFE */ - - /* SB configuration registers: 0xF00 */ - sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */ } d11regs_t; #define PIHR_BASE 0x0400 /* byte address of packed IHR region */ @@ -1770,4 +1758,21 @@ typedef struct macstat { #define SHM_BYT_CNT 0x2 /* IHR location */ #define MAX_BYT_CNT 0x600 /* Maximum frame len */ -#endif /* _D11_H */ +typedef struct d11cnt { + u32 txfrag; + u32 txmulti; + u32 txfail; + u32 txretry; + u32 txretrie; + u32 rxdup; + u32 txrts; + u32 txnocts; + u32 txnoack; + u32 rxfrag; + u32 rxmulti; + u32 rxcrc; + u32 txfrmsnt; + u32 rxundec; +} d11cnt_t; + +#endif /* _BRCM_D11_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/hnddma.c b/drivers/staging/brcm80211/brcmsmac/dma.c index f607315f8143..ce023249dd7c 100644 --- a/drivers/staging/brcm80211/brcmsmac/hnddma.c +++ b/drivers/staging/brcm80211/brcmsmac/dma.c @@ -18,22 +18,148 @@ #include <linux/string.h> #include <linux/netdevice.h> #include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmdevs.h> -#include <hndsoc.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcm_hw_ids.h> +#include <soc.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <sbhnddma.h> -#include <hnddma.h> +#include "types.h" +#include "dma.h" #if defined(__mips__) #include <asm/addrspace.h> #endif -#ifdef BRCM_FULLMAC -#error "hnddma.c shouldn't be needed for FULLMAC" -#endif +/* + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address. + */ +#define D64RINGALIGN_BITS 13 +#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) +#define D64RINGALIGN (1 << D64RINGALIGN_BITS) + +#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + +/* transmit channel control */ +#define D64_XC_XE 0x00000001 /* transmit enable */ +#define D64_XC_SE 0x00000002 /* transmit suspend request */ +#define D64_XC_LE 0x00000004 /* loopback enable */ +#define D64_XC_FL 0x00000010 /* flush request */ +#define D64_XC_PD 0x00000800 /* parity check disable */ +#define D64_XC_AE 0x00030000 /* address extension bits */ +#define D64_XC_AE_SHIFT 16 + +/* transmit descriptor table pointer */ +#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* transmit channel status */ +#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ +#define D64_XS0_XS_SHIFT 28 +#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ +#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ +#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ +#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ +#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + +#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ +#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ +#define D64_XS1_XE_SHIFT 28 +#define D64_XS1_XE_NOERR 0x00000000 /* no error */ +#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ +#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ +#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ +#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ +#define D64_XS1_XE_COREE 0x50000000 /* core error */ + +/* receive channel control */ +#define D64_RC_RE 0x00000001 /* receive enable */ +#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ +#define D64_RC_RO_SHIFT 1 +#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ +#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ +#define D64_RC_OC 0x00000400 /* overflow continue */ +#define D64_RC_PD 0x00000800 /* parity check disable */ +#define D64_RC_AE 0x00030000 /* address extension bits */ +#define D64_RC_AE_SHIFT 16 + +/* flags for dma controller */ +#define DMA_CTRL_PEN (1 << 0) /* partity enable */ +#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ +#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ +#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ + +/* receive descriptor table pointer */ +#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* receive channel status */ +#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ +#define D64_RS0_RS_SHIFT 28 +#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ +#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ +#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ +#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ +#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + +#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ +#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ +#define D64_RS1_RE_SHIFT 28 +#define D64_RS1_RE_NOERR 0x00000000 /* no error */ +#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ +#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ +#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ +#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ +#define D64_RS1_RE_COREE 0x50000000 /* core error */ + +/* fifoaddr */ +#define D64_FA_OFF_MASK 0xffff /* offset */ +#define D64_FA_SEL_MASK 0xf0000 /* select */ +#define D64_FA_SEL_SHIFT 16 +#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ +#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ +#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ +#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ +#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ +#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ +#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ +#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ +#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ +#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + +/* descriptor control flags 1 */ +#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ +#define D64_CTRL1_EOT ((u32)1 << 28) /* end of descriptor table */ +#define D64_CTRL1_IOC ((u32)1 << 29) /* interrupt on completion */ +#define D64_CTRL1_EOF ((u32)1 << 30) /* end of frame */ +#define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */ + +/* descriptor control flags 2 */ +#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ +#define D64_CTRL2_AE 0x00030000 /* address extension bits */ +#define D64_CTRL2_AE_SHIFT 16 +#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ + +/* control flags in the range [27:20] are core-specific and not defined here */ +#define D64_CTRL_CORE_MASK 0x0ff00000 + +#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ +#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ +#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */ +#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ + +#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ +#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ +#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ +#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ + +/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). + * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. + * There is a compile time check in wlc.c which ensure that this value is at least as big + * as TXOFF. This value is used in dma_rxfill (dma.c). + */ + +#define BCMEXTRAHDROOM 172 /* debug/trace */ #ifdef BCMDBG @@ -58,6 +184,15 @@ #define DMA_NONE(args) +typedef unsigned long dmaaddr_t; +#define PHYSADDRHI(_pa) (0) +#define PHYSADDRHISET(_pa, _val) +#define PHYSADDRLO(_pa) ((_pa)) +#define PHYSADDRLOSET(_pa, _val) \ + do { \ + (_pa) = (_val); \ + } while (0) + #define d64txregs dregs.d64_u.txregs_64 #define d64rxregs dregs.d64_u.rxregs_64 #define txd64 dregs.d64_u.txd_64 @@ -73,9 +208,33 @@ static uint dma_msg_level; #define R_SM(r) (*(r)) #define W_SM(r, v) (*(r) = (v)) +/* One physical DMA segment */ +typedef struct { + dmaaddr_t addr; + u32 length; +} dma_seg_t; + +typedef struct { + void *oshdmah; /* Opaque handle for OSL to store its information */ + uint origsize; /* Size of the virtual packet */ + uint nsegs; + dma_seg_t segs[MAX_DMA_SEGS]; +} dma_seg_map_t; + +/* + * DMA Descriptor + * Descriptors are only read by the hardware, never written back. + */ +typedef volatile struct { + u32 ctrl1; /* misc control bits & bufcount */ + u32 ctrl2; /* buffer count and address extension */ + u32 addrlow; /* memory address of the date buffer, bits 31:0 */ + u32 addrhigh; /* memory address of the date buffer, bits 63:32 */ +} dma64dd_t; + /* dma engine software state */ typedef struct dma_info { - struct hnddma_pub hnddma; /* exported structure */ + struct dma_pub dma; /* exported structure */ uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ @@ -99,7 +258,7 @@ typedef struct dma_info { u16 txin; /* index of next descriptor to reclaim */ u16 txout; /* index of next descriptor to post */ void **txp; /* pointer to parallel array of pointers to packets */ - hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ + dma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ u16 txdalign; /* #bytes added to alloc'd mem to align txd */ @@ -113,7 +272,7 @@ typedef struct dma_info { u16 rxin; /* index of next descriptor to reclaim */ u16 rxout; /* index of next descriptor to post */ void **rxp; /* pointer to parallel array of pointers to packets */ - hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ + dma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ u16 rxdalign; /* #bytes added to alloc'd mem to align rxd */ @@ -274,7 +433,7 @@ const di_fcn_t dma64proc = { 39 }; -struct hnddma_pub *dma_attach(char *name, si_t *sih, +struct dma_pub *dma_attach(char *name, struct si_pub *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level) @@ -299,20 +458,20 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, /* init dma reg pointer */ di->d64txregs = (dma64regs_t *) dmaregstx; di->d64rxregs = (dma64regs_t *) dmaregsrx; - di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; + di->dma.di_fn = (const di_fcn_t *)&dma64proc; /* Default flags (which can be changed by the driver calling dma_ctrlflags * before enable): For backwards compatibility both Rx Overflow Continue * and Parity are DISABLED. * supports it. */ - di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, - 0); + di->dma.di_fn->ctrlflags(&di->dma, DMA_CTRL_ROC | DMA_CTRL_PEN, + 0); DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d " "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " "dmaregstx %p dmaregsrx %p\n", name, "DMA64", - di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, + di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); /* make a private copy of our callers name */ @@ -427,21 +586,21 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, /* allocate DMA mapping vectors */ if (DMASGLIST_ENAB) { if (ntxd) { - size = ntxd * sizeof(hnddma_seg_map_t); + size = ntxd * sizeof(dma_seg_map_t); di->txp_dmah = kzalloc(size, GFP_ATOMIC); if (di->txp_dmah == NULL) goto fail; } if (nrxd) { - size = nrxd * sizeof(hnddma_seg_map_t); + size = nrxd * sizeof(dma_seg_map_t); di->rxp_dmah = kzalloc(size, GFP_ATOMIC); if (di->rxp_dmah == NULL) goto fail; } } - return (struct hnddma_pub *) di; + return (struct dma_pub *) di; fail: _dma_detach(di); @@ -497,7 +656,7 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); } - if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) { + if (di->dma.dmactrlflags & DMA_CTRL_PEN) { if (DMA64_DD_PARITY(&ddring[outidx])) { W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY)); @@ -678,7 +837,7 @@ static void _dma_rxinit(dma_info_t *di) static void _dma_rxenable(dma_info_t *di) { - uint dmactrlflags = di->hnddma.dmactrlflags; + uint dmactrlflags = di->dma.dmactrlflags; u32 control; DMA_TRACE(("%s: dma_rxenable\n", di->name)); @@ -760,11 +919,11 @@ static void *_dma_rx(dma_info_t *di) } #endif /* BCMDBG */ - if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { + if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - bcm_pkt_buf_free_skb(head); - di->hnddma.rxgiants++; + brcmu_pkt_buf_free_skb(head); + di->dma.rxgiants++; goto next_frame; } } @@ -811,7 +970,7 @@ static bool _dma_rxfill(dma_info_t *di) size to be allocated */ - p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset); + p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", @@ -821,7 +980,7 @@ static bool _dma_rxfill(dma_info_t *di) di->name)); ring_empty = true; } - di->hnddma.rxnobuf++; + di->dma.rxnobuf++; break; } /* reserve an extra headroom, if applicable */ @@ -835,7 +994,7 @@ static bool _dma_rxfill(dma_info_t *di) if (DMASGLIST_ENAB) memset(&di->rxp_dmah[rxout], 0, - sizeof(hnddma_seg_map_t)); + sizeof(dma_seg_map_t)); pa = pci_map_single(di->pbus, p->data, di->rxbufsize, PCI_DMA_FROMDEVICE); @@ -909,7 +1068,7 @@ static void _dma_rxreclaim(dma_info_t *di) DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } static void *_dma_getnextrxp(dma_info_t *di, bool forceall) @@ -922,12 +1081,12 @@ static void *_dma_getnextrxp(dma_info_t *di, bool forceall) static void _dma_txblock(dma_info_t *di) { - di->hnddma.txavail = 0; + di->dma.txavail = 0; } static void _dma_txunblock(dma_info_t *di) { - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; } static uint _dma_txactive(dma_info_t *di) @@ -968,14 +1127,14 @@ static uint _dma_rxactive(dma_info_t *di) static void _dma_counterreset(dma_info_t *di) { /* reset all software counter */ - di->hnddma.rxgiants = 0; - di->hnddma.rxnobuf = 0; - di->hnddma.txnobuf = 0; + di->dma.rxgiants = 0; + di->dma.rxnobuf = 0; + di->dma.txnobuf = 0; } static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) { - uint dmactrlflags = di->hnddma.dmactrlflags; + uint dmactrlflags = di->dma.dmactrlflags; if (di == NULL) { DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); @@ -1004,7 +1163,7 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) } } - di->hnddma.dmactrlflags = dmactrlflags; + di->dma.dmactrlflags = dmactrlflags; return dmactrlflags; } @@ -1013,7 +1172,7 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) static unsigned long _dma_getvar(dma_info_t *di, const char *name) { if (!strcmp(name, "&txavail")) - return (unsigned long)&(di->hnddma.txavail); + return (unsigned long)&(di->dma.txavail); return 0; } @@ -1069,7 +1228,7 @@ static void dma64_txinit(dma_info_t *di) return; di->txin = di->txout = 0; - di->hnddma.txavail = di->ntxd - 1; + di->dma.txavail = di->ntxd - 1; /* clear tx descriptor ring */ memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t))); @@ -1080,7 +1239,7 @@ static void dma64_txinit(dma_info_t *di) if (!di->aligndesc_4k) _dma_ddtable_init(di, DMA_TX, di->txdpa); - if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) + if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0) control |= D64_XC_PD; OR_REG(&di->d64txregs->control, control); @@ -1132,9 +1291,9 @@ static void dma64_txreclaim(dma_info_t *di, txd_range_t range) void *p; DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : + (range == DMA_RANGE_ALL) ? "all" : ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : + DMA_RANGE_TRANSMITTED) ? "transmitted" : "transferred"))); if (di->txin == di->txout) @@ -1142,8 +1301,8 @@ static void 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)) - bcm_pkt_buf_free_skb(p); + if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED)) + brcmu_pkt_buf_free_skb(p); } } @@ -1316,7 +1475,7 @@ static void *dma64_getpos(dma_info_t *di, bool direction) /* TX of unframed data * * Adds a DMA ring descriptor for the data pointed to by "buf". - * This is for DMA of a buffer of data and is unlike other hnddma TX functions + * This is for DMA of a buffer of data and is unlike other dma TX functions * that take a pointer to a "packet" * Each call to this is results in a single descriptor being added for "len" bytes of * data starting at "buf", it doesn't handle chained buffers. @@ -1359,14 +1518,14 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) } /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return 0; outoftxd: DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__)); - di->hnddma.txavail = 0; - di->hnddma.txnobuf++; + di->dma.txavail = 0; + di->dma.txnobuf++; return -1; } @@ -1394,7 +1553,7 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, */ for (p = p0; p; p = next) { uint nsegs, j; - hnddma_seg_map_t *map; + dma_seg_map_t *map; data = p->data; len = p->len; @@ -1410,7 +1569,7 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, /* get physical address of buffer start */ if (DMASGLIST_ENAB) memset(&di->txp_dmah[txout], 0, - sizeof(hnddma_seg_map_t)); + sizeof(dma_seg_map_t)); pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE); @@ -1474,26 +1633,26 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, di->xmtptrbase + I2B(txout, dma64dd_t)); /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return 0; outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); - bcm_pkt_buf_free_skb(p0); - di->hnddma.txavail = 0; - di->hnddma.txnobuf++; + brcmu_pkt_buf_free_skb(p0); + di->dma.txavail = 0; + di->dma.txnobuf++; return -1; } /* * Reclaim next completed txd (txds if using chained buffers) in the range * specified and return associated packet. - * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be + * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be * transmitted as noted by the hardware "CurrDescr" pointer. - * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be + * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be * transferred by the DMA as noted by the hardware "ActiveDescr" pointer. - * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and + * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and * return associated packet regardless of the value of hardware pointers. */ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) @@ -1503,9 +1662,9 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) void *txp; DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : + (range == DMA_RANGE_ALL) ? "all" : ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : + DMA_RANGE_TRANSMITTED) ? "transmitted" : "transferred"))); if (di->ntxd == 0) @@ -1514,7 +1673,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) txp = NULL; start = di->txin; - if (range == HNDDMA_RANGE_ALL) + if (range == DMA_RANGE_ALL) end = di->txout; else { dma64regs_t *dregs = di->d64txregs; @@ -1525,7 +1684,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t)); - if (range == HNDDMA_RANGE_TRANSFERED) { + if (range == DMA_RANGE_TRANSFERED) { active_desc = (u16) (R_REG(&dregs->status1) & D64_XS1_AD_MASK); @@ -1542,7 +1701,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) for (i = start; i != end && !txp; i = NEXTTXD(i)) { dmaaddr_t pa; - hnddma_seg_map_t *map = NULL; + dma_seg_map_t *map = NULL; uint size, j, nsegs; PHYSADDRLOSET(pa, @@ -1579,7 +1738,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) di->txin = i; /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return txp; @@ -1696,8 +1855,8 @@ static void dma64_txrotate(dma_info_t *di) /* Move the map */ if (DMASGLIST_ENAB) { memcpy(&di->txp_dmah[new], &di->txp_dmah[old], - sizeof(hnddma_seg_map_t)); - memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); + sizeof(dma_seg_map_t)); + memset(&di->txp_dmah[old], 0, sizeof(dma_seg_map_t)); } di->txp[old] = NULL; @@ -1706,14 +1865,14 @@ static void dma64_txrotate(dma_info_t *di) /* update txin and txout */ di->txin = ad; di->txout = TXD(di->txout + rot); - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; /* kick the chip */ W_REG(&di->d64txregs->ptr, di->xmtptrbase + I2B(di->txout, dma64dd_t)); } -uint dma_addrwidth(si_t *sih, void *dmaregs) +uint dma_addrwidth(struct si_pub *sih, void *dmaregs) { /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ /* DMA engine is 64-bit capable */ @@ -1736,7 +1895,7 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) * engine. This function calls a caller-supplied function for each packet in * the caller specified dma chain. */ -void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) +void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) (void *pkt, void *arg_a), void *arg_a) { dma_info_t *di = (dma_info_t *) dmah; diff --git a/drivers/staging/brcm80211/brcmsmac/dma.h b/drivers/staging/brcm80211/brcmsmac/dma.h new file mode 100644 index 000000000000..70c9ad6c4952 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/dma.h @@ -0,0 +1,255 @@ +/* + * 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 _BRCM_DMA_H_ +#define _BRCM_DMA_H_ + +#include "types.h" /* forward structure declarations */ + +#ifndef _dma_pub_ +#define _dma_pub_ +struct dma_pub; +#endif /* _dma_pub_ */ + +/* DMA structure: + * support two DMA engines: 32 bits address or 64 bit addressing + * basic DMA register set is per channel(transmit or receive) + * a pair of channels is defined for convenience + */ + +/* 32 bits addressing */ + +typedef volatile struct { /* diag access */ + u32 fifoaddr; /* diag address */ + u32 fifodatalow; /* low 32bits of data */ + u32 fifodatahigh; /* high 32bits of data */ + u32 pad; /* reserved */ +} dma32diag_t; + +/* 64 bits addressing */ + +/* dma registers per channel(xmt or rcv) */ +typedef volatile struct { + u32 control; /* enable, et al */ + u32 ptr; /* last descriptor posted to chip */ + u32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ + u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ + u32 status0; /* current descriptor, xmt state */ + u32 status1; /* active descriptor, xmt error */ +} dma64regs_t; + +/* map/unmap direction */ +#define DMA_TX 1 /* TX direction for DMA */ +#define DMA_RX 2 /* RX direction for DMA */ +#define BUS_SWAP32(v) (v) + +/* range param for dma_getnexttxp() and dma_txreclaim */ +typedef enum txd_range { + DMA_RANGE_ALL = 1, + DMA_RANGE_TRANSMITTED, + DMA_RANGE_TRANSFERED +} txd_range_t; + +/* dma function type */ +typedef void (*di_detach_t) (struct dma_pub *dmah); +typedef bool(*di_txreset_t) (struct dma_pub *dmah); +typedef bool(*di_rxreset_t) (struct dma_pub *dmah); +typedef bool(*di_rxidle_t) (struct dma_pub *dmah); +typedef void (*di_txinit_t) (struct dma_pub *dmah); +typedef bool(*di_txenabled_t) (struct dma_pub *dmah); +typedef void (*di_rxinit_t) (struct dma_pub *dmah); +typedef void (*di_txsuspend_t) (struct dma_pub *dmah); +typedef void (*di_txresume_t) (struct dma_pub *dmah); +typedef bool(*di_txsuspended_t) (struct dma_pub *dmah); +typedef bool(*di_txsuspendedidle_t) (struct dma_pub *dmah); +typedef int (*di_txfast_t) (struct dma_pub *dmah, struct sk_buff *p, + bool commit); +typedef int (*di_txunframed_t) (struct dma_pub *dmah, void *p, uint len, + bool commit); +typedef void *(*di_getpos_t) (struct dma_pub *di, bool direction); +typedef void (*di_fifoloopbackenable_t) (struct dma_pub *dmah); +typedef bool(*di_txstopped_t) (struct dma_pub *dmah); +typedef bool(*di_rxstopped_t) (struct dma_pub *dmah); +typedef bool(*di_rxenable_t) (struct dma_pub *dmah); +typedef bool(*di_rxenabled_t) (struct dma_pub *dmah); +typedef void *(*di_rx_t) (struct dma_pub *dmah); +typedef bool(*di_rxfill_t) (struct dma_pub *dmah); +typedef void (*di_txreclaim_t) (struct dma_pub *dmah, txd_range_t range); +typedef void (*di_rxreclaim_t) (struct dma_pub *dmah); +typedef unsigned long (*di_getvar_t) (struct dma_pub *dmah, + const char *name); +typedef void *(*di_getnexttxp_t) (struct dma_pub *dmah, txd_range_t range); +typedef void *(*di_getnextrxp_t) (struct dma_pub *dmah, bool forceall); +typedef void *(*di_peeknexttxp_t) (struct dma_pub *dmah); +typedef void *(*di_peeknextrxp_t) (struct dma_pub *dmah); +typedef void (*di_rxparam_get_t) (struct dma_pub *dmah, u16 *rxoffset, + u16 *rxbufsize); +typedef void (*di_txblock_t) (struct dma_pub *dmah); +typedef void (*di_txunblock_t) (struct dma_pub *dmah); +typedef uint(*di_txactive_t) (struct dma_pub *dmah); +typedef void (*di_txrotate_t) (struct dma_pub *dmah); +typedef void (*di_counterreset_t) (struct dma_pub *dmah); +typedef uint(*di_ctrlflags_t) (struct dma_pub *dmah, uint mask, uint flags); +typedef char *(*di_dump_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, + bool dumpring); +typedef char *(*di_dumptx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, + bool dumpring); +typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, + bool dumpring); +typedef uint(*di_rxactive_t) (struct dma_pub *dmah); +typedef uint(*di_txpending_t) (struct dma_pub *dmah); +typedef uint(*di_txcommitted_t) (struct dma_pub *dmah); + +/* dma opsvec */ +typedef struct di_fcn_s { + di_detach_t detach; + di_txinit_t txinit; + di_txreset_t txreset; + di_txenabled_t txenabled; + di_txsuspend_t txsuspend; + di_txresume_t txresume; + di_txsuspended_t txsuspended; + di_txsuspendedidle_t txsuspendedidle; + di_txfast_t txfast; + di_txunframed_t txunframed; + di_getpos_t getpos; + di_txstopped_t txstopped; + di_txreclaim_t txreclaim; + di_getnexttxp_t getnexttxp; + di_peeknexttxp_t peeknexttxp; + di_txblock_t txblock; + di_txunblock_t txunblock; + di_txactive_t txactive; + di_txrotate_t txrotate; + + di_rxinit_t rxinit; + di_rxreset_t rxreset; + di_rxidle_t rxidle; + di_rxstopped_t rxstopped; + di_rxenable_t rxenable; + di_rxenabled_t rxenabled; + di_rx_t rx; + di_rxfill_t rxfill; + di_rxreclaim_t rxreclaim; + di_getnextrxp_t getnextrxp; + di_peeknextrxp_t peeknextrxp; + di_rxparam_get_t rxparam_get; + + di_fifoloopbackenable_t fifoloopbackenable; + di_getvar_t d_getvar; + di_counterreset_t counterreset; + di_ctrlflags_t ctrlflags; + di_dump_t dump; + di_dumptx_t dumptx; + di_dumprx_t dumprx; + di_rxactive_t rxactive; + di_txpending_t txpending; + di_txcommitted_t txcommitted; + uint endnum; +} di_fcn_t; + +/* + * Exported data structure (read-only) + */ +/* export structure */ +struct dma_pub { + const di_fcn_t *di_fn; /* DMA function pointers */ + uint txavail; /* # free tx descriptors */ + uint dmactrlflags; /* dma control flags */ + + /* rx error counters */ + uint rxgiants; /* rx giant frames */ + uint rxnobuf; /* rx out of dma descriptors */ + /* tx error counters */ + uint txnobuf; /* tx out of dma descriptors */ +}; + +extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, + void *dmaregstx, void *dmaregsrx, uint ntxd, + uint nrxd, uint rxbufsize, int rxextheadroom, + uint nrxpost, uint rxoffset, uint *msg_level); + +extern const di_fcn_t dma64proc; + +#define dma_detach(di) (dma64proc.detach(di)) +#define dma_txreset(di) (dma64proc.txreset(di)) +#define dma_rxreset(di) (dma64proc.rxreset(di)) +#define dma_rxidle(di) (dma64proc.rxidle(di)) +#define dma_txinit(di) (dma64proc.txinit(di)) +#define dma_txenabled(di) (dma64proc.txenabled(di)) +#define dma_rxinit(di) (dma64proc.rxinit(di)) +#define dma_txsuspend(di) (dma64proc.txsuspend(di)) +#define dma_txresume(di) (dma64proc.txresume(di)) +#define dma_txsuspended(di) (dma64proc.txsuspended(di)) +#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di)) +#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit)) +#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit)) +#define dma_getpos(di, dir) (dma64proc.getpos(di, dir)) +#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di)) +#define dma_txstopped(di) (dma64proc.txstopped(di)) +#define dma_rxstopped(di) (dma64proc.rxstopped(di)) +#define dma_rxenable(di) (dma64proc.rxenable(di)) +#define dma_rxenabled(di) (dma64proc.rxenabled(di)) +#define dma_rx(di) (dma64proc.rx(di)) +#define dma_rxfill(di) (dma64proc.rxfill(di)) +#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range)) +#define dma_rxreclaim(di) (dma64proc.rxreclaim(di)) +#define dma_getvar(di, name) (dma64proc.d_getvar(di, name)) +#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range)) +#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall)) +#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di)) +#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di)) +#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs)) + +#define dma_txblock(di) (dma64proc.txblock(di)) +#define dma_txunblock(di) (dma64proc.txunblock(di)) +#define dma_txactive(di) (dma64proc.txactive(di)) +#define dma_rxactive(di) (dma64proc.rxactive(di)) +#define dma_txrotate(di) (dma64proc.txrotate(di)) +#define dma_counterreset(di) (dma64proc.counterreset(di)) +#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags))) +#define dma_txpending(di) (dma64proc.txpending(di)) +#define dma_txcommitted(di) (dma64proc.txcommitted(di)) + + +/* return addresswidth allowed + * This needs to be done after SB attach but before dma attach. + * SB attach provides ability to probe backplane and dma core capabilities + * This info is needed by DMA_ALLOC_CONSISTENT in dma attach + */ +extern uint dma_addrwidth(struct si_pub *sih, void *dmaregs); +void dma_walk_packets(struct dma_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 /* _BRCM_DMA_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c index 82612290b99b..43a6a759bf6b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c @@ -26,34 +26,45 @@ #include <linux/firmware.h> #include <linux/interrupt.h> #include <net/mac80211.h> +#include <defs.h> +#include <brcmu_wifi.h> +#include <brcmu_utils.h> +#include <nicpci.h> +#include "dma.h" -#include <proto/802.11.h> -#include <bcmdefs.h> -#include <bcmwifi.h> -#include <bcmutils.h> -#include <bcmnvram.h> -#include <pcicfg.h> -#include <wlioctl.h> -#include <sbhnddma.h> - -#include "phy/wlc_phy_int.h" +#include "phy/phy_int.h" #include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "phy/phy_version.h" -#include "wlc_key.h" -#include "wlc_channel.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wl_dbg.h" -#include "wl_export.h" -#include "wl_ucode.h" -#include "wl_mac80211.h" +#include "types.h" +#include "channel.h" +#include "scb.h" +#include "pub.h" +#include "ucode_loader.h" +#include "mac80211_if.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); +#define LOCK(wl) spin_lock_bh(&(wl)->lock) +#define UNLOCK(wl) spin_unlock_bh(&(wl)->lock) + +/* locking from inside brcms_isr */ +#define ISR_LOCK(wl, flags)\ + do {\ + spin_lock(&(wl)->isr_lock);\ + (void)(flags); } \ + while (0) + +#define ISR_UNLOCK(wl, flags)\ + do {\ + spin_unlock(&(wl)->isr_lock);\ + (void)(flags); } \ + while (0) + +/* locking under LOCK() to synchronize with brcms_isr */ +#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) +#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) + +static void brcms_timer(unsigned long data); +static void _brcms_timer(struct brcms_timer *t); static int ieee_hw_init(struct ieee80211_hw *hw); @@ -70,22 +81,20 @@ static int wl_linux_watchdog(void *ctx); FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC) -static int wl_found; +static int n_adapters_found; -#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) -#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); -static void wl_release_fw(struct wl_info *wl); +static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev); +static void brcms_release_fw(struct brcms_info *wl); /* local prototypes */ -static void wl_dpc(unsigned long data); -static irqreturn_t wl_isr(int irq, void *dev_id); +static void brcms_dpc(unsigned long data); +static irqreturn_t brcms_isr(int irq, void *dev_id); -static int __devinit wl_pci_probe(struct pci_dev *pdev, +static int __devinit brcms_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); +static void brcms_remove(struct pci_dev *pdev); +static void brcms_free(struct brcms_info *wl); +static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br); MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); @@ -93,14 +102,16 @@ MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); /* recognized PCI IDs */ -static struct pci_device_id wl_id_table[] = { +static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = { {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ + /* 43224 Ven */ + {PCI_VENDOR_ID_BROADCOM, 0x0576, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, {0} }; -MODULE_DEVICE_TABLE(pci, wl_id_table); +MODULE_DEVICE_TABLE(pci, brcms_pci_id_table); #ifdef BCMDBG static int msglevel = 0xdeadbeef; @@ -113,51 +124,52 @@ module_param(phymsglevel, int, 0); #define WL_TO_HW(wl) (wl->pub->ieee_hw) /* MAC80211 callback functions */ -static int wl_ops_start(struct ieee80211_hw *hw); -static void wl_ops_stop(struct ieee80211_hw *hw); -static int wl_ops_add_interface(struct ieee80211_hw *hw, +static int brcms_ops_start(struct ieee80211_hw *hw); +static void brcms_ops_stop(struct ieee80211_hw *hw); +static int brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -static void wl_ops_remove_interface(struct ieee80211_hw *hw, +static void brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); -static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, +static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed); +static void brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed); -static void wl_ops_configure_filter(struct ieee80211_hw *hw, +static void brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast); -static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, +static int brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); -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, +static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw); +static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw); +static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); +static int brcms_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); -static void wl_ops_sta_notify(struct ieee80211_hw *hw, +static void brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta); -static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, +static int brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); -static int wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw); +static int brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_ops_ampdu_action(struct ieee80211_hw *hw, +static int brcms_ops_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int brcms_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, 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 brcms_ops_rfkill_poll(struct ieee80211_hw *hw); +static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop); -static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; - WL_LOCK(wl); + LOCK(wl); if (!wl->pub->up) { wiphy_err(wl->wiphy, "ops->tx called while down\n"); kfree_skb(skb); @@ -165,36 +177,36 @@ static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) } wlc_sendpkt_mac80211(wl->wlc, skb, hw); done: - WL_UNLOCK(wl); + UNLOCK(wl); } -static int wl_ops_start(struct ieee80211_hw *hw) +static int brcms_ops_start(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; bool blocked; /* struct ieee80211_channel *curchan = hw->conf.channel; */ ieee80211_wake_queues(hw); - WL_LOCK(wl); - blocked = wl_rfkill_set_hw_state(wl); - WL_UNLOCK(wl); + LOCK(wl); + blocked = brcms_rfkill_set_hw_state(wl); + UNLOCK(wl); if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); return 0; } -static void wl_ops_stop(struct ieee80211_hw *hw) +static void brcms_ops_stop(struct ieee80211_hw *hw) { ieee80211_stop_queues(hw); } static int -wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct wl_info *wl; + struct brcms_info *wl; int err; /* Just STA for now */ @@ -209,28 +221,28 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) } wl = HW_TO_WL(hw); - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); + LOCK(wl); + err = brcms_up(wl); + UNLOCK(wl); if (err != 0) { - wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__, + wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, err); } return err; } static void -wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct wl_info *wl; + struct brcms_info *wl; wl = HW_TO_WL(hw); /* put driver in down state */ - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); + LOCK(wl); + brcms_down(wl); + UNLOCK(wl); } /* @@ -240,7 +252,7 @@ static int ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, enum nl80211_channel_type type) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int err = 0; switch (type) { @@ -261,24 +273,24 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, return err; } -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) +static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) { struct ieee80211_conf *conf = &hw->conf; - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int err = 0; int new_int; struct wiphy *wiphy = hw->wiphy; - WL_LOCK(wl); + LOCK(wl); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - if (wlc_iovar_setint - (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { + if (wlc_set_par(wl->wlc, IOV_BCN_LI_BCN, conf->listen_interval) + < 0) { 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); + wlc_get_par(wl->wlc, IOV_BCN_LI_BCN, &new_int); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n", @@ -290,14 +302,14 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { - if (wlc_iovar_setint - (wl->wlc, "qtxpower", conf->power_level * 4)) { + if (wlc_set_par(wl->wlc, IOV_QTXPOWER, conf->power_level * 4) + < 0) { wiphy_err(wiphy, "%s: Error setting power_level\n", __func__); err = -EIO; goto config_out; } - wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); + wlc_get_par(wl->wlc, IOV_QTXPOWER, &new_int); if (new_int != (conf->power_level * 4)) wiphy_err(wiphy, "%s: Power level req != actual, %d %d" "\n", __func__, conf->power_level * 4, @@ -323,16 +335,16 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) } config_out: - WL_UNLOCK(wl); + UNLOCK(wl); return err; } static void -wl_ops_bss_info_changed(struct ieee80211_hw *hw, +brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); struct wiphy *wiphy = hw->wiphy; int val; @@ -342,9 +354,9 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, */ wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, info->assoc ? "" : "dis"); - WL_LOCK(wl); + LOCK(wl); wlc_associate_upd(wl->wlc, info->assoc); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_ERP_SLOT) { /* slot timing changed */ @@ -352,23 +364,23 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, val = 1; else val = 0; - WL_LOCK(wl); + LOCK(wl); wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_HT) { /* 802.11n parameters changed */ u16 mode = info->ht_operation_mode; - WL_LOCK(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); + UNLOCK(wl); } if (changed & BSS_CHANGED_BASIC_RATES) { struct ieee80211_supported_band *bi; @@ -378,10 +390,10 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, int error; /* retrieve the current rates */ - WL_LOCK(wl); + LOCK(wl); error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET, &rs, sizeof(rs), NULL); - WL_UNLOCK(wl); + UNLOCK(wl); if (error) { wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n", __func__, error); @@ -394,27 +406,27 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, rate = (bi->bitrates[i].bitrate << 1) / 10; /* set/clear basic rate flag */ - wl_set_basic_rate(&rs, rate, br_mask & 1); + brcms_set_basic_rate(&rs, rate, br_mask & 1); br_mask >>= 1; } /* update the rate set */ - WL_LOCK(wl); + LOCK(wl); wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON_INT) { /* Beacon interval changed */ - WL_LOCK(wl); + LOCK(wl); wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_BSSID) { /* BSSID changed, for whatever reason (IBSS and managed mode) */ - WL_LOCK(wl); + LOCK(wl); wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON) { /* Beacon data changed, retrieve new beacon (beaconing modes) */ @@ -459,11 +471,11 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } static void -wl_ops_configure_filter(struct ieee80211_hw *hw, +brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; struct wiphy *wiphy = hw->wiphy; changed_flags &= MAC_FILTERS; @@ -481,7 +493,7 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, if (changed_flags & FIF_OTHER_BSS) wiphy_err(wiphy, "FIF_OTHER_BSS\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_LOCK(wl); + LOCK(wl); if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; wlc_mac_bcn_promisc_change(wl->wlc, 1); @@ -489,60 +501,60 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, wlc_mac_bcn_promisc_change(wl->wlc, 0); wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; } - WL_UNLOCK(wl); + UNLOCK(wl); } return; } static int -wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { return 0; } -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; - WL_LOCK(wl); + struct brcms_info *wl = hw->priv; + LOCK(wl); wlc_scan_start(wl->wlc); - WL_UNLOCK(wl); + UNLOCK(wl); return; } -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; - WL_LOCK(wl); + struct brcms_info *wl = hw->priv; + LOCK(wl); wlc_scan_stop(wl->wlc); - WL_UNLOCK(wl); + UNLOCK(wl); return; } -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) +static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) { wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return; } static int -wl_ops_get_stats(struct ieee80211_hw *hw, +brcms_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; struct wl_cnt *cnt; - WL_LOCK(wl); + LOCK(wl); cnt = wl->pub->_cnt; stats->dot11ACKFailureCount = 0; stats->dot11RTSFailureCount = 0; stats->dot11FCSErrorCount = 0; stats->dot11RTSSuccessCount = 0; - WL_UNLOCK(wl); + UNLOCK(wl); return 0; } static void -wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { switch (cmd) { @@ -555,32 +567,32 @@ wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } static int -wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, +brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; - WL_LOCK(wl); + LOCK(wl); wlc_wme_setparams(wl->wlc, queue, params, true); - WL_UNLOCK(wl); + UNLOCK(wl); return 0; } -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) +static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw) { wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return 0; } static int -wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct scb *scb; int i; - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; /* Init the scb */ scb = (struct scb *)sta->drv_priv; @@ -594,7 +606,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; - bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, + brcmu_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); sta->ht_cap.ht_supported = true; @@ -609,21 +621,21 @@ wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } static int -wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { return 0; } static int -wl_ops_ampdu_action(struct ieee80211_hw *hw, +brcms_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { struct scb *scb = (struct scb *)sta->drv_priv; - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; int status; if (WARN_ON(scb->magic != SCB_MAGIC)) @@ -634,9 +646,9 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: - WL_LOCK(wl); + LOCK(wl); status = wlc_aggregatable(wl->wlc, tid); - WL_UNLOCK(wl); + UNLOCK(wl); if (!status) { wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", tid); @@ -648,9 +660,9 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_STOP: - WL_LOCK(wl); + LOCK(wl); wlc_ampdu_flush(wl->wlc, sta, tid); - WL_UNLOCK(wl); + UNLOCK(wl); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: @@ -665,58 +677,58 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, return 0; } -static void wl_ops_rfkill_poll(struct ieee80211_hw *hw) +static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); bool blocked; - WL_LOCK(wl); + LOCK(wl); blocked = wlc_check_radio_disabled(wl->wlc); - WL_UNLOCK(wl); + UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); } -static void wl_ops_flush(struct ieee80211_hw *hw, bool drop) +static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_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); + LOCK(wl); wlc_wait_for_tx_completion(wl->wlc, drop); - WL_UNLOCK(wl); + UNLOCK(wl); } -static const struct ieee80211_ops wl_ops = { - .tx = wl_ops_tx, - .start = wl_ops_start, - .stop = wl_ops_stop, - .add_interface = wl_ops_add_interface, - .remove_interface = wl_ops_remove_interface, - .config = wl_ops_config, - .bss_info_changed = wl_ops_bss_info_changed, - .configure_filter = wl_ops_configure_filter, - .set_tim = wl_ops_set_tim, - .sw_scan_start = wl_ops_sw_scan_start, - .sw_scan_complete = wl_ops_sw_scan_complete, - .set_tsf = wl_ops_set_tsf, - .get_stats = wl_ops_get_stats, - .sta_notify = wl_ops_sta_notify, - .conf_tx = wl_ops_conf_tx, - .get_tsf = wl_ops_get_tsf, - .sta_add = wl_ops_sta_add, - .sta_remove = wl_ops_sta_remove, - .ampdu_action = wl_ops_ampdu_action, - .rfkill_poll = wl_ops_rfkill_poll, - .flush = wl_ops_flush, +static const struct ieee80211_ops brcms_ops = { + .tx = brcms_ops_tx, + .start = brcms_ops_start, + .stop = brcms_ops_stop, + .add_interface = brcms_ops_add_interface, + .remove_interface = brcms_ops_remove_interface, + .config = brcms_ops_config, + .bss_info_changed = brcms_ops_bss_info_changed, + .configure_filter = brcms_ops_configure_filter, + .set_tim = brcms_ops_set_tim, + .sw_scan_start = brcms_ops_sw_scan_start, + .sw_scan_complete = brcms_ops_sw_scan_complete, + .set_tsf = brcms_ops_set_tsf, + .get_stats = brcms_ops_get_stats, + .sta_notify = brcms_ops_sta_notify, + .conf_tx = brcms_ops_conf_tx, + .get_tsf = brcms_ops_get_tsf, + .sta_add = brcms_ops_sta_add, + .sta_remove = brcms_ops_sta_remove, + .ampdu_action = brcms_ops_ampdu_action, + .rfkill_poll = brcms_ops_rfkill_poll, + .flush = brcms_ops_flush, }; /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ -static int wl_set_hint(struct wl_info *wl, char *abbrev) +static int brcms_set_hint(struct brcms_info *wl, char *abbrev) { return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); } @@ -727,25 +739,25 @@ static int wl_set_hint(struct wl_info *wl, char *abbrev) * Attach to the WL device identified by vendor and device parameters. * regs is a host accessible memory address pointing to WL device registers. * - * wl_attach is not defined as static because in the case where no bus + * brcms_attach is not defined as static because in the case where no bus * is defined, wl_attach will never be called, and thus, gcc will issue * a warning that this function is defined but not used if we declare * it as static. * * - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ -static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, +static struct brcms_info *brcms_attach(u16 vendor, u16 device, + unsigned long regs, uint bustype, void *btparam, uint irq) { - struct wl_info *wl = NULL; + struct brcms_info *wl = NULL; int unit, err; - unsigned long base_addr; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; - unit = wl_found; + unit = n_adapters_found; err = 0; if (unit < 0) { @@ -763,15 +775,13 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, atomic_set(&wl->callbacks, 0); /* setup the bottom half handler */ - tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); + tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); base_addr = regs; - if (bustype == PCI_BUS) { - wl->piomode = false; - } else if (bustype == RPC_BUS) { + if (bustype == PCI_BUS || bustype == RPC_BUS) { /* Do nothing */ } else { bustype = PCI_BUS; @@ -788,18 +798,18 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, spin_lock_init(&wl->isr_lock); /* prepare ucode */ - if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) { + if (brcms_request_fw(wl, (struct pci_dev *)btparam) < 0) { 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); + brcms_release_fw(wl); + brcms_remove((struct pci_dev *)btparam); return NULL; } /* common load-time initialization */ - wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, + wl->wlc = wlc_attach((void *)wl, vendor, device, unit, false, wl->regsva, wl->bcm_bustype, btparam, &err); - wl_release_fw(wl); + brcms_release_fw(wl); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n", KBUILD_MODNAME, err); @@ -809,21 +819,20 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, wl->pub->ieee_hw = hw; - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { + if (wlc_set_par(wl->wlc, IOV_MPC, 0) < 0) { 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)) { + if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = irq; /* register module */ - wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, - NULL); + wlc_module_register(wl->pub, "linux", wl, wl_linux_watchdog, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, @@ -843,19 +852,19 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, } if (wl->pub->srom_ccode[0]) - err = wl_set_hint(wl, wl->pub->srom_ccode); + err = brcms_set_hint(wl, wl->pub->srom_ccode); else - err = wl_set_hint(wl, "US"); + err = brcms_set_hint(wl, "US"); if (err) { wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", __func__, err); } - wl_found++; + n_adapters_found++; return wl; fail: - wl_free(wl); + brcms_free(wl); return NULL; } @@ -870,7 +879,7 @@ fail: .max_power = 19, \ } -static struct ieee80211_channel wl_2ghz_chantable[] = { +static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), @@ -902,7 +911,7 @@ static struct ieee80211_channel wl_2ghz_chantable[] = { .max_power = 21, \ } -static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { +static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { /* UNII-1 */ CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), @@ -970,7 +979,7 @@ static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { .hw_value = (rate100m / 5), \ } -static struct ieee80211_rate wl_legacy_ratetable[] = { +static struct ieee80211_rate legacy_ratetable[] = { RATE(10, 0), RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), @@ -985,12 +994,12 @@ static struct ieee80211_rate wl_legacy_ratetable[] = { RATE(540, 0), }; -static struct ieee80211_supported_band wl_band_2GHz_nphy = { +static struct ieee80211_supported_band brcms_band_2GHz_nphy = { .band = IEEE80211_BAND_2GHZ, - .channels = wl_2ghz_chantable, - .n_channels = ARRAY_SIZE(wl_2ghz_chantable), - .bitrates = wl_legacy_ratetable, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), + .channels = brcms_2ghz_chantable, + .n_channels = ARRAY_SIZE(brcms_2ghz_chantable), + .bitrates = legacy_ratetable, + .n_bitrates = ARRAY_SIZE(legacy_ratetable), .ht_cap = { /* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | @@ -1007,12 +1016,12 @@ static struct ieee80211_supported_band wl_band_2GHz_nphy = { } }; -static struct ieee80211_supported_band wl_band_5GHz_nphy = { +static struct ieee80211_supported_band brcms_band_5GHz_nphy = { .band = IEEE80211_BAND_5GHZ, - .channels = wl_5ghz_nphy_chantable, - .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), - .bitrates = wl_legacy_ratetable + 4, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, + .channels = brcms_5ghz_nphy_chantable, + .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable), + .bitrates = legacy_ratetable + 4, + .n_bitrates = ARRAY_SIZE(legacy_ratetable) - 4, .ht_cap = { /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ @@ -1028,11 +1037,11 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = { }; /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ static int ieee_hw_rate_init(struct ieee80211_hw *hw) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int has_5g; char phy_list[4]; @@ -1048,10 +1057,10 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) if (phy_list[0] == 'n' || phy_list[0] == 'c') { if (phy_list[0] == 'c') { /* Single stream */ - wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; - wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; + brcms_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; + brcms_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; } - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &brcms_band_2GHz_nphy; } else { return -EPERM; } @@ -1061,7 +1070,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) has_5g++; if (phy_list[0] == 'n' || phy_list[0] == 'c') { hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &wl_band_5GHz_nphy; + &brcms_band_5GHz_nphy; } else { return -EPERM; } @@ -1070,7 +1079,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) } /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ static int ieee_hw_init(struct ieee80211_hw *hw) { @@ -1101,15 +1110,15 @@ static int ieee_hw_init(struct ieee80211_hw *hw) * determines if a device is a WL device, and if so, attaches it. * * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. + * and if so, performs a brcms_attach() on it. * * Perimeter lock is initialized in the course of this function. */ static int __devinit -wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; u32 val; @@ -1118,7 +1127,8 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) PCI_FUNC(pdev->devfn), pdev->irq); if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || - (((pdev->device & 0xff00) != 0x4300) && + ((pdev->device != 0x0576) && + ((pdev->device & 0xff00) != 0x4300) && ((pdev->device & 0xff00) != 0x4700) && ((pdev->device < 43000) || (pdev->device > 43999)))) return -ENODEV; @@ -1136,7 +1146,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); + hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops); if (!hw) { pr_err("%s: ieee80211_alloc_hw failed\n", __func__); return -ENOMEM; @@ -1148,43 +1158,44 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) memset(hw->priv, 0, sizeof(*wl)); - wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), - PCI_BUS, pdev, pdev->irq); + wl = brcms_attach(pdev->vendor, pdev->device, + pci_resource_start(pdev, 0), PCI_BUS, pdev, + pdev->irq); if (!wl) { - pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME, + pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME, __func__); return -ENODEV; } return 0; } -static int wl_suspend(struct pci_dev *pdev, pm_message_t state) +static int brcms_suspend(struct pci_dev *pdev, pm_message_t state) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { wiphy_err(wl->wiphy, - "wl_suspend: pci_get_drvdata failed\n"); + "brcms_suspend: pci_get_drvdata failed\n"); return -ENODEV; } /* only need to flag hw is down for proper resume */ - WL_LOCK(wl); + LOCK(wl); wl->pub->hw_up = false; - WL_UNLOCK(wl); + UNLOCK(wl); pci_save_state(pdev); pci_disable_device(pdev); return pci_set_power_state(pdev, PCI_D3hot); } -static int wl_resume(struct pci_dev *pdev) +static int brcms_resume(struct pci_dev *pdev) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; int err = 0; u32 val; @@ -1193,7 +1204,7 @@ static int wl_resume(struct pci_dev *pdev) wl = HW_TO_WL(hw); if (!wl) { wiphy_err(wl->wiphy, - "wl: wl_resume: pci_get_drvdata failed\n"); + "wl: brcms_resume: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1215,97 +1226,80 @@ static int wl_resume(struct pci_dev *pdev) /* * done. driver will be put in up state - * in wl_ops_add_interface() call. + * in brcms_ops_add_interface() call. */ return err; } /* -* called from both kernel as from wl_*() +* called from both kernel as from this kernel module. * precondition: perimeter lock is not acquired. */ -static void wl_remove(struct pci_dev *pdev) +static void brcms_remove(struct pci_dev *pdev) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; int status; hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - pr_err("wl: wl_remove: pci_get_drvdata failed\n"); + pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); return; } - WL_LOCK(wl); + LOCK(wl); status = wlc_chipmatch(pdev->vendor, pdev->device); - WL_UNLOCK(wl); + UNLOCK(wl); if (!status) { - wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n"); + wiphy_err(wl->wiphy, "wl: brcms_remove: wlc_chipmatch " + "failed\n"); return; } if (wl->wlc) { wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); ieee80211_unregister_hw(hw); - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); + LOCK(wl); + brcms_down(wl); + UNLOCK(wl); } pci_disable_device(pdev); - wl_free(wl); + brcms_free(wl); pci_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); } -static struct pci_driver wl_pci_driver = { +static struct pci_driver brcms_pci_driver = { .name = KBUILD_MODNAME, - .probe = wl_pci_probe, - .suspend = wl_suspend, - .resume = wl_resume, - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, + .probe = brcms_pci_probe, + .suspend = brcms_suspend, + .resume = brcms_resume, + .remove = __devexit_p(brcms_remove), + .id_table = brcms_pci_id_table, }; /** * This is the main entry point for the WL driver. * * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. + * and if so, performs a brcms_attach() on it. * */ -static int __init wl_module_init(void) +static int __init brcms_module_init(void) { int error = -ENODEV; #ifdef BCMDBG if (msglevel != 0xdeadbeef) - wl_msg_level = msglevel; - else { - char *var = getvar(NULL, "wl_msglevel"); - if (var) { - unsigned long value; - - (void)strict_strtoul(var, 0, &value); - wl_msg_level = value; - } - } + brcm_msg_level = msglevel; if (phymsglevel != 0xdeadbeef) phyhal_msg_level = phymsglevel; - else { - char *var = getvar(NULL, "phy_msglevel"); - if (var) { - unsigned long value; - - (void)strict_strtoul(var, 0, &value); - phyhal_msg_level = value; - } - } #endif /* BCMDBG */ - error = pci_register_driver(&wl_pci_driver); + error = pci_register_driver(&brcms_pci_driver); if (!error) return 0; @@ -1321,14 +1315,14 @@ static int __init wl_module_init(void) * system. * */ -static void __exit wl_module_exit(void) +static void __exit brcms_module_exit(void) { - pci_unregister_driver(&wl_pci_driver); + pci_unregister_driver(&brcms_pci_driver); } -module_init(wl_module_init); -module_exit(wl_module_exit); +module_init(brcms_module_init); +module_exit(brcms_module_exit); /** * This function frees the WL per-device resources. @@ -1339,13 +1333,13 @@ module_exit(wl_module_exit); * precondition: can both be called locked and unlocked * */ -static void wl_free(struct wl_info *wl) +static void brcms_free(struct brcms_info *wl) { - struct wl_timer *t, *next; + struct brcms_timer *t, *next; /* free ucode data */ if (wl->fw.fw_cnt) - wl_ucode_data_free(); + brcms_ucode_data_free(); if (wl->irq) free_irq(wl->irq, wl); @@ -1390,7 +1384,7 @@ static void wl_free(struct wl_info *wl) } /* flags the given rate in rateset as requested */ -static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) +static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) { u32 i; @@ -1409,8 +1403,8 @@ static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) /* * precondition: perimeter lock has been acquired */ -void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio) +void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio) { wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); } @@ -1418,10 +1412,10 @@ void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, /* * precondition: perimeter lock has been acquired */ -void wl_init(struct wl_info *wl) +void brcms_init(struct brcms_info *wl) { BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); - wl_reset(wl); + brcms_reset(wl); wlc_init(wl->wlc); } @@ -1429,7 +1423,7 @@ void wl_init(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -uint wl_reset(struct wl_info *wl) +uint brcms_reset(struct brcms_info *wl) { BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); wlc_reset(wl->wlc); @@ -1444,7 +1438,7 @@ uint wl_reset(struct wl_info *wl) * These are interrupt on/off entry points. Disable interrupts * during interrupt state transition. */ -void wl_intrson(struct wl_info *wl) +void brcms_intrson(struct brcms_info *wl) { unsigned long flags; @@ -1456,12 +1450,12 @@ void wl_intrson(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) +bool wl_alloc_dma_resources(struct brcms_info *wl, uint addrwidth) { return true; } -u32 wl_intrsoff(struct wl_info *wl) +u32 brcms_intrsoff(struct brcms_info *wl) { unsigned long flags; u32 status; @@ -1472,7 +1466,7 @@ u32 wl_intrsoff(struct wl_info *wl) return status; } -void wl_intrsrestore(struct wl_info *wl, u32 macintmask) +void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask) { unsigned long flags; @@ -1484,7 +1478,7 @@ void wl_intrsrestore(struct wl_info *wl, u32 macintmask) /* * precondition: perimeter lock has been acquired */ -int wl_up(struct wl_info *wl) +int brcms_up(struct brcms_info *wl) { int error = 0; @@ -1499,7 +1493,7 @@ int wl_up(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -void wl_down(struct wl_info *wl) +void brcms_down(struct brcms_info *wl) { uint callbacks, ret_val = 0; @@ -1508,25 +1502,25 @@ void wl_down(struct wl_info *wl) callbacks = atomic_read(&wl->callbacks) - ret_val; /* wait for down callbacks to complete */ - WL_UNLOCK(wl); + UNLOCK(wl); /* For HIGH_only driver, it's important to actually schedule other work, * not just spin wait since everything runs at schedule level */ SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); - WL_LOCK(wl); + LOCK(wl); } -static irqreturn_t wl_isr(int irq, void *dev_id) +static irqreturn_t brcms_isr(int irq, void *dev_id) { - struct wl_info *wl; + struct brcms_info *wl; bool ours, wantdpc; unsigned long flags; - wl = (struct wl_info *) dev_id; + wl = (struct brcms_info *) dev_id; - WL_ISRLOCK(wl, flags); + ISR_LOCK(wl, flags); /* call common first level interrupt handler */ ours = wlc_isr(wl->wlc, &wantdpc); @@ -1540,18 +1534,18 @@ static irqreturn_t wl_isr(int irq, void *dev_id) } } - WL_ISRUNLOCK(wl, flags); + ISR_UNLOCK(wl, flags); return IRQ_RETVAL(ours); } -static void wl_dpc(unsigned long data) +static void brcms_dpc(unsigned long data) { - struct wl_info *wl; + struct brcms_info *wl; - wl = (struct wl_info *) data; + wl = (struct brcms_info *) data; - WL_LOCK(wl); + LOCK(wl); /* call the common second level interrupt handler */ if (wl->pub->up) { @@ -1575,27 +1569,27 @@ static void wl_dpc(unsigned long data) tasklet_schedule(&wl->tasklet); else { /* re-enable interrupts */ - wl_intrson(wl); + brcms_intrson(wl); } done: - WL_UNLOCK(wl); + UNLOCK(wl); } /* * is called by the kernel from software irq context */ -static void wl_timer(unsigned long data) +static void brcms_timer(unsigned long data) { - _wl_timer((struct wl_timer *) data); + _brcms_timer((struct brcms_timer *) data); } /* * precondition: perimeter lock is not acquired */ -static void _wl_timer(struct wl_timer *t) +static void _brcms_timer(struct brcms_timer *t) { - WL_LOCK(t->wl); + LOCK(t->wl); if (t->set) { if (t->periodic) { @@ -1611,7 +1605,7 @@ static void _wl_timer(struct wl_timer *t) atomic_dec(&t->wl->callbacks); - WL_UNLOCK(t->wl); + UNLOCK(t->wl); } /* @@ -1620,21 +1614,22 @@ static void _wl_timer(struct wl_timer *t) * * precondition: perimeter lock has been acquired */ -struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), - void *arg, const char *name) +struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), + void *arg, const char *name) { - struct wl_timer *t; + struct brcms_timer *t; - t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC); + t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC); if (!t) { - wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n", + wiphy_err(wl->wiphy, "wl%d: brcms_init_timer: out of memory\n", wl->pub->unit); return 0; } init_timer(&t->timer); t->timer.data = (unsigned long) t; - t->timer.function = wl_timer; + t->timer.function = brcms_timer; t->wl = wl; t->fn = fn; t->arg = arg; @@ -1655,7 +1650,8 @@ struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), * * precondition: perimeter lock has been acquired */ -void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) +void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms, + int periodic) { #ifdef BCMDBG if (t->set) { @@ -1677,7 +1673,7 @@ void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) * * precondition: perimeter lock has been acquired */ -bool wl_del_timer(struct wl_info *wl, struct wl_timer *t) +bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t) { if (t->set) { t->set = false; @@ -1693,12 +1689,12 @@ bool wl_del_timer(struct wl_info *wl, struct wl_timer *t) /* * precondition: perimeter lock has been acquired */ -void wl_free_timer(struct wl_info *wl, struct wl_timer *t) +void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *t) { - struct wl_timer *tmp; + struct brcms_timer *tmp; /* delete the timer in case it is active */ - wl_del_timer(wl, t); + brcms_del_timer(wl, t); if (wl->timers == t) { wl->timers = wl->timers->next; @@ -1735,13 +1731,13 @@ static int wl_linux_watchdog(void *ctx) return 0; } -struct wl_fw_hdr { +struct firmware_hdr { u32 offset; u32 len; u32 idx; }; -char *wl_firmwares[WL_MAX_FW] = { +char *brcms_firmwares[MAX_FW_IMAGES] = { "brcm/bcm43xx", NULL }; @@ -1749,13 +1745,13 @@ char *wl_firmwares[WL_MAX_FW] = { /* * precondition: perimeter lock has been acquired */ -int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) +int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) { int i, entry; const u8 *pdata; - struct wl_fw_hdr *hdr; + struct firmware_hdr *hdr; for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { if (hdr->idx == idx) { @@ -1779,16 +1775,16 @@ fail: } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) +int brcms_ucode_init_uint(struct brcms_info *wl, u32 *data, u32 idx) { int i, entry; const u8 *pdata; - struct wl_fw_hdr *hdr; + struct firmware_hdr *hdr; for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { if (hdr->idx == idx) { @@ -1808,21 +1804,21 @@ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) +static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev) { int status; struct device *device = &pdev->dev; char fw_name[100]; int i; - memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); - for (i = 0; i < WL_MAX_FW; i++) { - if (wl_firmwares[i] == NULL) + memset((void *)&wl->fw, 0, sizeof(struct brcms_firmware)); + for (i = 0; i < MAX_FW_IMAGES; i++) { + if (brcms_firmwares[i] == NULL) break; - sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { @@ -1830,7 +1826,7 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) KBUILD_MODNAME, fw_name); return status; } - sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); if (status) { @@ -1839,28 +1835,28 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) return status; } wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); } wl->fw.fw_cnt = i; - return wl_ucode_data_init(wl); + return brcms_ucode_data_init(wl); } /* * precondition: can both be called locked and unlocked */ -void wl_ucode_free_buf(void *p) +void brcms_ucode_free_buf(void *p) { kfree(p); } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -static void wl_release_fw(struct wl_info *wl) +static void brcms_release_fw(struct brcms_info *wl) { int i; - for (i = 0; i < WL_MAX_FW; i++) { + for (i = 0; i < MAX_FW_IMAGES; i++) { release_firmware(wl->fw.fw_bin[i]); release_firmware(wl->fw.fw_hdr[i]); } @@ -1870,18 +1866,18 @@ static void wl_release_fw(struct wl_info *wl) /* * checks validity of all firmware images loaded from user space * - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -int wl_check_firmwares(struct wl_info *wl) +int brcms_check_firmwares(struct brcms_info *wl) { int i; int entry; int rc = 0; const struct firmware *fw; const struct firmware *fw_hdr; - struct wl_fw_hdr *ucode_hdr; - for (i = 0; i < WL_MAX_FW && rc == 0; i++) { + struct firmware_hdr *ucode_hdr; + for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) { fw = wl->fw.fw_bin[i]; fw_hdr = wl->fw.fw_hdr[i]; if (fw == NULL && fw_hdr == NULL) { @@ -1890,10 +1886,10 @@ int wl_check_firmwares(struct wl_info *wl) wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n", __func__); rc = -EBADF; - } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { + } else if (fw_hdr->size % sizeof(struct firmware_hdr)) { wiphy_err(wl->wiphy, "%s: non integral fw hdr file " "size %zu/%zu\n", __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr)); + sizeof(struct firmware_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { wiphy_err(wl->wiphy, "%s: out of bounds fw file size " @@ -1901,7 +1897,7 @@ int wl_check_firmwares(struct wl_info *wl) rc = -EBADF; } else { /* check if ucode section overruns firmware image */ - ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; + ucode_hdr = (struct firmware_hdr *)fw_hdr->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i] && !rc; entry++, ucode_hdr++) { if (ucode_hdr->offset + ucode_hdr->len > @@ -1925,24 +1921,24 @@ int wl_check_firmwares(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -bool wl_rfkill_set_hw_state(struct wl_info *wl) +bool brcms_rfkill_set_hw_state(struct brcms_info *wl) { bool blocked = wlc_check_radio_disabled(wl->wlc); - WL_UNLOCK(wl); + UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); if (blocked) wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy); - WL_LOCK(wl); + LOCK(wl); return blocked; } /* * precondition: perimeter lock has been acquired */ -void wl_msleep(struct wl_info *wl, uint ms) +void brcms_msleep(struct brcms_info *wl, uint ms) { - WL_UNLOCK(wl); + UNLOCK(wl); msleep(ms); - WL_LOCK(wl); + LOCK(wl); } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h index f7a58b7a550a..e1c6420b45f6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h @@ -14,8 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wl_mac80211_h_ -#define _wl_mac80211_h_ +#ifndef _BRCM_MAC80211_IF_H_ +#define _BRCM_MAC80211_IF_H_ + +/* softmac ioctl definitions */ +#define WLC_SET_SHORTSLOT_OVERRIDE 146 + #include <linux/interrupt.h> @@ -23,34 +27,34 @@ * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be * submitted to workqueue instead of being on kernel timer */ -struct wl_timer { +struct brcms_timer { struct timer_list timer; - struct wl_info *wl; + struct brcms_info *wl; void (*fn) (void *); void *arg; /* argument to fn */ uint ms; bool periodic; bool set; - struct wl_timer *next; + struct brcms_timer *next; #ifdef BCMDBG char *name; /* Description of the timer */ #endif }; -struct wl_if { +struct brcms_if { uint subunit; /* WDS/BSS unit */ struct pci_dev *pci_dev; }; -#define WL_MAX_FW 4 -struct wl_firmware { +#define MAX_FW_IMAGES 4 +struct brcms_firmware { u32 fw_cnt; - const struct firmware *fw_bin[WL_MAX_FW]; - const struct firmware *fw_hdr[WL_MAX_FW]; - u32 hdr_num_entries[WL_MAX_FW]; + const struct firmware *fw_bin[MAX_FW_IMAGES]; + const struct firmware *fw_hdr[MAX_FW_IMAGES]; + u32 hdr_num_entries[MAX_FW_IMAGES]; }; -struct wl_info { +struct brcms_info { struct wlc_pub *pub; /* pointer to public wlc state */ void *wlc; /* pointer to private common os-independent data */ u32 magic; @@ -59,29 +63,49 @@ struct wl_info { spinlock_t lock; /* per-device perimeter lock */ spinlock_t isr_lock; /* per-device ISR synchronization lock */ + + /* bus type and regsva for unmap in brcms_free() */ uint bcm_bustype; /* bus type */ - bool piomode; /* set from insmod argument */ void *regsva; /* opaque chip registers virtual address */ + + /* timer related fields */ atomic_t callbacks; /* # outstanding callback functions */ - struct wl_timer *timers; /* timer cleanup queue */ + struct brcms_timer *timers; /* timer cleanup queue */ + struct tasklet_struct tasklet; /* dpc tasklet */ bool resched; /* dpc needs to be and is rescheduled */ #ifdef LINUXSTA_PS u32 pci_psstate[16]; /* pci ps-state save/restore */ #endif - struct wl_firmware fw; + struct brcms_firmware fw; struct wiphy *wiphy; }; -#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) -#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) - -/* locking from inside wl_isr */ -#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) -#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) +/* misc callbacks */ +struct brcms_info; +struct brcms_if; +struct wlc_if; +extern void brcms_init(struct brcms_info *wl); +extern uint brcms_reset(struct brcms_info *wl); +extern void brcms_intrson(struct brcms_info *wl); +extern u32 brcms_intrsoff(struct brcms_info *wl); +extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); +extern int brcms_up(struct brcms_info *wl); +extern void brcms_down(struct brcms_info *wl); +extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio); +extern bool wl_alloc_dma_resources(struct brcms_info *wl, uint dmaddrwidth); +extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl); -/* locking under WL_LOCK() to synchronize with wl_isr */ -#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) -#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) +/* timer functions */ +struct brcms_timer; +extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer); +extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer, + uint ms, int periodic); +extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer); +extern void brcms_msleep(struct brcms_info *wl, uint ms); -#endif /* _wl_mac80211_h_ */ +#endif /* _BRCM_MAC80211_IF_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/main.c index 4b4a31eff90c..3613900cf291 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/main.c @@ -19,41 +19,30 @@ #include <linux/pci_ids.h> #include <net/mac80211.h> -#include <bcmdefs.h> -#include <bcmdevs.h> -#include <bcmutils.h> -#include <bcmwifi.h> -#include <bcmnvram.h> +#include <defs.h> +#include <brcm_hw_ids.h> +#include <brcmu_utils.h> +#include <brcmu_wifi.h> #include <aiutils.h> -#include <pcicfg.h> -#include <bcmsrom.h> -#include <wlioctl.h> -#include <sbhnddma.h> -#include <hnddma.h> +#include "srom.h" +#include "dma.h" -#include "wlc_pmu.h" +#include "pmu.h" #include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_bsscfg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_bmac.h" -#include "wlc_phy_hal.h" -#include "wlc_phy_shim.h" -#include "wlc_antsel.h" -#include "wlc_stf.h" -#include "wlc_ampdu.h" -#include "wl_export.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" - -#include "wl_mac80211.h" +#include "types.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" +#include "bmac.h" +#include "phy_hal.h" +#include "antsel.h" +#include "stf.h" +#include "ampdu.h" +#include "alloc.h" +#include "mac80211_if.h" /* * WPA(2) definitions @@ -71,7 +60,6 @@ #define ALLPRIO -1 /* - * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) @@ -94,6 +82,94 @@ #define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ +/* Software feature flag defines used by wlfeatureflag */ +#define WL_SWFL_NOHWRADIO 0x0004 +#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ +#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ + +/* n-mode support capability */ +/* 2x2 includes both 1x1 & 2x2 devices + * reserved #define 2 for future when we want to separate 1x1 & 2x2 and + * control it independently + */ +#define WL_11N_2x2 1 +#define WL_11N_3x3 3 +#define WL_11N_4x4 4 + +/* define 11n feature disable flags */ +#define WLFEATURE_DISABLE_11N 0x00000001 +#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 +#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 +#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 +#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 +#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 +#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 +#define WLFEATURE_DISABLE_11N_GF 0x00000080 + +#define EDCF_ACI_MASK 0x60 +#define EDCF_ACI_SHIFT 5 +#define EDCF_ECWMIN_MASK 0x0f +#define EDCF_ECWMAX_SHIFT 4 +#define EDCF_AIFSN_MASK 0x0f +#define EDCF_AIFSN_MAX 15 +#define EDCF_ECWMAX_MASK 0xf0 + +#define EDCF_AC_BE_TXOP_STA 0x0000 +#define EDCF_AC_BK_TXOP_STA 0x0000 +#define EDCF_AC_VO_ACI_STA 0x62 +#define EDCF_AC_VO_ECW_STA 0x32 +#define EDCF_AC_VI_ACI_STA 0x42 +#define EDCF_AC_VI_ECW_STA 0x43 +#define EDCF_AC_BK_ECW_STA 0xA4 +#define EDCF_AC_VI_TXOP_STA 0x005e +#define EDCF_AC_VO_TXOP_STA 0x002f +#define EDCF_AC_BE_ACI_STA 0x03 +#define EDCF_AC_BE_ECW_STA 0xA4 +#define EDCF_AC_BK_ACI_STA 0x27 +#define EDCF_AC_VO_TXOP_AP 0x002f + +#define EDCF_TXOP2USEC(txop) ((txop) << 5) +#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) + +#define APHY_SYMBOL_TIME 4 +#define APHY_PREAMBLE_TIME 16 +#define APHY_SIGNAL_TIME 4 +#define APHY_SIFS_TIME 16 +#define APHY_SERVICE_NBITS 16 +#define APHY_TAIL_NBITS 6 +#define BPHY_SIFS_TIME 10 +#define BPHY_PLCP_SHORT_TIME 96 + +#define PREN_PREAMBLE 24 +#define PREN_MM_EXT 12 +#define PREN_PREAMBLE_EXT 4 + +#define DOT11_MAC_HDR_LEN 24 +#define DOT11_ACK_LEN 10 +#define DOT11_BA_LEN 4 +#define DOT11_OFDM_SIGNAL_EXTENSION 6 +#define DOT11_MIN_FRAG_LEN 256 +#define DOT11_RTS_LEN 16 +#define DOT11_CTS_LEN 10 +#define DOT11_BA_BITMAP_LEN 128 +#define DOT11_MIN_BEACON_PERIOD 1 +#define DOT11_MAX_BEACON_PERIOD 0xFFFF +#define DOT11_MAXNUMFRAGS 16 +#define DOT11_MAX_FRAG_LEN 2346 + +#define BPHY_PLCP_TIME 192 +#define RIFS_11N_TIME 2 + +#define WME_VER 1 +#define WME_SUBTYPE_PARAM_IE 1 +#define WME_TYPE 2 +#define WME_OUI "\x00\x50\xf2" + +#define AC_BE 0 +#define AC_BK 1 +#define AC_VI 2 +#define AC_VO 3 + /* * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft * watchdog) it is not a wall clock and won't increment when driver is in "down" state @@ -101,10 +177,6 @@ * calibration and scb update */ -/* watchdog trigger mode: OSL timer or TBTT */ -#define WLC_WATCHDOG_TBTT(wlc) \ - (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) - /* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ #define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) @@ -112,11 +184,11 @@ (!AP_ENAB(wlc->pub)) && (wlc->war16165)) /* debug/trace */ -uint wl_msg_level = +uint brcm_msg_level = #if defined(BCMDBG) - WL_ERROR_VAL; + LOG_ERROR_VAL; #else - 0; + 0; #endif /* BCMDBG */ /* Find basic rate for a given rate */ @@ -139,28 +211,6 @@ uint wl_msg_level = static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); #endif -/* IOVar table */ - -/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars - * table and by the wlc_doiovar() function. No ordering is imposed: - * the table is keyed by name, and the function uses a switch. - */ -enum { - IOV_MPC = 1, - IOV_RTSTHRESH, - IOV_QTXPOWER, - IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ - IOV_LAST /* In case of a need to check max ID number */ -}; - -const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (0), IOVT_BOOL, 0}, - {"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0}, - {NULL, 0, 0, 0, 0} -}; - const u8 prio2fifo[NUMPRIO] = { TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ @@ -186,6 +236,18 @@ const u8 prio2fifo[NUMPRIO] = { #define _WLC_PREC_VO 12 /* Vo - Voice */ #define _WLC_PREC_NC 14 /* NC - Network Control */ +#define MAXMACLIST 64 /* max # source MAC matches */ +#define BCN_TEMPLATE_COUNT 2 + +#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ + +#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) +#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) + +#define MBSS_BCN_ENAB(cfg) 0 +#define MBSS_PRB_ENAB(cfg) 0 +#define SOFTBCN_ENAB(pub) (0) + /* 802.1D Priority to precedence queue mapping */ const u8 wlc_prio2prec_map[] = { _WLC_PREC_BE, /* 0 BE - Best-effort */ @@ -198,6 +260,22 @@ const u8 wlc_prio2prec_map[] = { _WLC_PREC_NC, /* 7 NC - Network Control */ }; +/* Check if a particular BSS config is AP or STA */ +#define BSSCFG_AP(cfg) (0) +#define BSSCFG_STA(cfg) (1) +#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) + +/* Iterator for "associated" STA bss configs: + (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */ +#define FOREACH_AS_STA(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) + +/* As above for all non-NULL BSS configs */ +#define FOREACH_BSS(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx])) + /* Sanity check for tx_prec_map and fifo synchup * Either there are some packets pending for the fifo, else if fifo is empty then * all the corresponding precmap bits should be set @@ -256,8 +334,6 @@ static void wlc_watchdog(void *arg); static void wlc_watchdog_by_timer(void *arg); static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, - const bcm_iovar_t *vi); static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); /* send and receive */ @@ -323,14 +399,12 @@ bool wlc_ps_allowed(struct wlc_info *wlc) struct wlc_bsscfg *cfg; /* disallow PS when one of the following global conditions meets */ - if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) + if (!wlc->pub->associated) return false; /* disallow PS when one of these meets when not scanning */ - if (!wlc->PMblocked) { - if (AP_ACTIVE(wlc) || wlc->monitor) - return false; - } + if (AP_ACTIVE(wlc) || wlc->monitor) + return false; FOREACH_AS_STA(wlc, idx, cfg) { /* disallow PS when one of the following bsscfg specific conditions meets */ @@ -348,8 +422,6 @@ void wlc_reset(struct wlc_info *wlc) { BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - wlc->check_for_unaligned_tbtt = false; - /* slurp up hw mac counters before core reset */ wlc_statsupd(wlc); @@ -358,15 +430,13 @@ void wlc_reset(struct wlc_info *wlc) sizeof(macstat_t)); wlc_bmac_reset(wlc->hw); - wlc->txretried = 0; - } void wlc_fatal_error(struct wlc_info *wlc) { wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", wlc->pub->unit); - wl_init(wlc->wl); + brcms_init(wlc->wl); } /* Return the channel the driver should initialize during wlc_init. @@ -415,15 +485,8 @@ void wlc_init(struct wlc_info *wlc) wlc_bmac_init(wlc->hw, chanspec, mute); - wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (wlc->machwcap & MCAP_TKIPMIC) - wlc->tkmickeys = - wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; - /* update beacon listen interval */ wlc_bcn_li_upd(wlc); - wlc->bcn_wait_prd = - (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); /* the world is new again, so is our reported rate */ wlc_reprate_init(wlc); @@ -457,8 +520,6 @@ void wlc_init(struct wlc_info *wlc) } } - wlc_key_hw_init_all(wlc); - wlc_bandinit_ordered(wlc, chanspec); wlc_init_scb(wlc, &global_scb); @@ -550,7 +611,7 @@ void wlc_mac_promisc(struct wlc_info *wlc) * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit * since all BSS data traffic is directed at the AP */ - if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) + if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub)) promisc_bits |= MCTL_PROMISC; /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL @@ -664,8 +725,8 @@ static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) local = WLC_TXPWR_MAX; if (wlc->pub->associated && - (bcm_chspec_ctlchan(wlc->chanspec) == - bcm_chspec_ctlchan(wlc->home_chanspec))) { + (brcmu_chspec_ctlchan(wlc->chanspec) == + brcmu_chspec_ctlchan(wlc->home_chanspec))) { /* get the local power constraint if we are on the AP's * channel [802.11h, 7.3.2.13] @@ -774,224 +835,6 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) wlc_ucode_mac_upd(wlc); } -#if defined(BCMDBG) -static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) -{ - txpwr_limits_t txpwr; - tx_power_t power; - tx_power_legacy_t *old_power = NULL; - int r, c; - uint qdbm; - bool override; - - if (len == sizeof(tx_power_legacy_t)) - old_power = (tx_power_legacy_t *) pwr; - else if (len < sizeof(tx_power_t)) - return -EOVERFLOW; - - memset(&power, 0, sizeof(tx_power_t)); - - power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; - if (wlc->pub->associated) - power.local_chanspec = wlc->home_chanspec; - - /* Return the user target tx power limits for the various rates. Note wlc_phy.c's - * public interface only implements getting and setting a single value for all of - * rates, so we need to fill the array ourselves. - */ - wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - for (r = 0; r < WL_TX_POWER_RATES; r++) { - power.user_limit[r] = (u8) qdbm; - } - - power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; - power.local_constraint = - wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; - - power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; - power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; - - wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); - -#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK -#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" -#endif - - /* CCK tx power limits */ - for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; - c++, r++) - power.reg_limit[r] = txpwr.cck[c]; - -#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM -#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" -#endif - - /* 20 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; - c++, r++) - power.reg_limit[r] = txpwr.ofdm[c]; - - if (WLC_PHY_11N_CAP(wlc->band)) { - - /* 20 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_cdd[c]; - - /* 40 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_siso[c]; - - /* 40 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; - -#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM -#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" -#endif - - /* 20MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_siso[c]; - - /* 20MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_cdd[c]; - - /* 20MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_stbc[c]; - - /* 40MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_siso[c]; - - /* 40MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_cdd[c]; - - /* 40MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_stbc[c]; - -#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM -#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" -#endif - - /* 20MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_mimo[c]; - - /* 40MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_mimo[c]; - - /* MCS 32 */ - power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(power.chanspec)); - - /* copy the tx_power_t struct to the return buffer, - * or convert to a tx_power_legacy_t struct - */ - if (!old_power) { - memcpy(pwr, &power, sizeof(tx_power_t)); - } else { - int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - - memset(old_power, 0, sizeof(tx_power_legacy_t)); - - old_power->txpwr_local_max = power.local_max; - old_power->txpwr_local_constraint = power.local_constraint; - if (CHSPEC_IS2G(power.chanspec)) { - old_power->txpwr_chan_reg_max = txpwr.cck[0]; - old_power->txpwr_est_Pout[band_idx] = - power.est_Pout_cck; - old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; - } else { - old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; - old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; - } - old_power->txpwr_antgain[0] = power.antgain[0]; - old_power->txpwr_antgain[1] = power.antgain[1]; - - for (r = 0; r < NUM_PWRCTRL_RATES; r++) { - old_power->txpwr_band_max[r] = power.user_limit[r]; - old_power->txpwr_limit[r] = power.reg_limit[r]; - old_power->txpwr_target[band_idx][r] = power.target[r]; - if (CHSPEC_IS2G(power.chanspec)) - old_power->txpwr_bphy_cck_max[r] = - power.board_limit[r]; - else - old_power->txpwr_aphy_max[r] = - power.board_limit[r]; - } - } - - return 0; -} -#endif /* defined(BCMDBG) */ - -static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) -{ - u32 bi; - bi = 2 * wlc->cfg->current_bss->dtim_period * - wlc->cfg->current_bss->beacon_period; - if (wlc->bcn_li_dtim) - bi *= wlc->bcn_li_dtim; - else if (wlc->bcn_li_bcn) - /* recalculate bi based on bcn_li_bcn */ - bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; - - if (bi < 2 * TIMER_INTERVAL_WATCHDOG) - bi = 2 * TIMER_INTERVAL_WATCHDOG; - return bi; -} - -/* Change to run the watchdog either from a periodic timer or from tbtt handler. - * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. - */ -void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) -{ - /* make sure changing watchdog driver is allowed */ - if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) - return; - if (!tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - /* stop watchdog timer and use tbtt interrupt to drive watchdog */ - if (tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - wlc->WDlast = OSL_SYSUPTIME(); - } - /* arm watchdog timer and drive the watchdog there */ - else if (!tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - wlc->WDarmed = true; - } - if (tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), - true); - wlc->WDarmed = true; - } -} - ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) { ratespec_t lowest_basic_rspec; @@ -1218,7 +1061,6 @@ static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) return; /* wait for at least one beacon before entering sleeping state */ - wlc->PMawakebcn = true; FOREACH_AS_STA(wlc, idx, cfg) cfg->PMawakebcn = true; wlc_set_ps_ctrl(wlc); @@ -1266,8 +1108,6 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, return; } - wlc->wme_admctl = 0; - do { memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); /* fill in shm ac params struct */ @@ -1339,10 +1179,6 @@ void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) 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; - /* 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 */ params->txop = edcf_acp->TXOP; @@ -1371,7 +1207,7 @@ void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) bool wlc_timers_init(struct wlc_info *wlc, int unit) { - wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, + wlc->wdtimer = brcms_init_timer(wlc->wl, wlc_watchdog_by_timer, wlc, "watchdog"); if (!wlc->wdtimer) { wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer " @@ -1379,7 +1215,7 @@ bool wlc_timers_init(struct wlc_info *wlc, int unit) goto fail; } - wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, + wlc->radio_timer = brcms_init_timer(wlc->wl, wlc_radio_timer, wlc, "radio"); if (!wlc->radio_timer) { wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer " @@ -1403,25 +1239,13 @@ void wlc_info_init(struct wlc_info *wlc, int unit) /* Assume the device is there until proven otherwise */ wlc->device_present = true; - /* set default power output percentage to 100 percent */ - wlc->txpwr_percent = 100; - /* Save our copy of the chanspec */ wlc->chanspec = CH20MHZ_CHSPEC(1); - /* initialize CCK preamble mode to unassociated state */ - wlc->shortpreamble = false; - - wlc->legacy_probe = true; - /* various 802.11g modes */ wlc->shortslot = false; wlc->shortslot_override = WLC_SHORTSLOT_AUTO; - wlc->barker_overlap_control = true; - wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; - wlc->txburst_limit_override = AUTO; - wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); @@ -1454,30 +1278,6 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->SRL = RETRY_SHORT_DEF; wlc->LRL = RETRY_LONG_DEF; - /* init PM state */ - wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ - wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ - wlc->PMenabled = false; /* Current PM state */ - wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ - wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ - - /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ - wlc->WME_PM_blocked = false; - - /* Init wme queuing method */ - wlc->wme_prec_queuing = false; - - /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ - wlc->wake = false; - /* Are we waiting for a response to PS-Poll that we sent */ - wlc->PSpoll = false; - - /* APSD defaults */ - wlc->wme_apsd = true; - wlc->apsd_sta_usp = false; - wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ - wlc->apsd_trigger_ac = AC_BITMAP_ALL; - /* Set flag to indicate that hw keys should be used when available. */ wlc->wsec_swkeys = false; @@ -1487,8 +1287,6 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->wsec_keys[i]->idx = (u8) i; } - wlc->_regulatory_domain = false; /* 802.11d */ - /* WME QoS mode is Auto by default */ wlc->pub->_wme = AUTO; @@ -1498,14 +1296,10 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->pub->_ampdu = AMPDU_AGG_HOST; wlc->pub->bcmerror = 0; - wlc->ibss_allowed = true; - wlc->ibss_coalesce_allowed = true; wlc->pub->_coex = ON; /* initialize mpc delay */ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - wlc->pr80838_war = true; } static bool wlc_state_bmac_sync(struct wlc_info *wlc) @@ -1564,7 +1358,7 @@ struct wlc_pub *wlc_pub(void *wlc) /* * The common driver entry routine. Error codes should be unique */ -void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, +void *wlc_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, bool piomode, void *regsva, uint bustype, void *btparam, uint *perr) { @@ -1589,11 +1383,8 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->core = wlc->corestate; wlc->wl = wl; pub->unit = unit; - wlc->btparam = btparam; pub->_piomode = piomode; wlc->bandinit_pending = false; - /* By default restrict TKIP associations from 11n STA's */ - wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; /* populate struct wlc_info with default values */ wlc_info_init(wlc, unit); @@ -1604,10 +1395,6 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, /* 11n_disable nvram */ n_disabled = getintvar(pub->vars, "11n_disable"); - /* register a module (to handle iovars) */ - wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, - wlc_doiovar, NULL, NULL); - /* * low level attach steps(all hw accesses go * inside, no more in rest of the attach) @@ -1762,9 +1549,6 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->cck_40txbw = AUTO; wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); - /* Enable setting the RIFS Mode bit by default in HT Info IE */ - wlc->rifs_advert = AUTO; - /* Set default values of SGI */ if (WLC_SGI_CAP_PHY(wlc)) { wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); @@ -1904,11 +1688,11 @@ static void wlc_timers_deinit(struct wlc_info *wlc) { /* free timer state */ if (wlc->wdtimer) { - wl_free_timer(wlc->wl, wlc->wdtimer); + brcms_free_timer(wlc->wl, wlc->wdtimer); wlc->wdtimer = NULL; } if (wlc->radio_timer) { - wl_free_timer(wlc->wl, wlc->radio_timer); + brcms_free_timer(wlc->wl, wlc->radio_timer); wlc->radio_timer = NULL; } } @@ -1957,28 +1741,6 @@ uint wlc_detach(struct wlc_info *wlc) wlc_detach_module(wlc); - /* free other state */ - - -#ifdef BCMDBG - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; -#endif /* BCMDBG */ - - { - /* free dumpcb list */ - struct dumpcb_s *prev, *ptr; - prev = ptr = wlc->dumpcb_head; - while (ptr) { - ptr = prev->next; - kfree(prev); - prev = ptr; - } - wlc->dumpcb_head = NULL; - } - - /* Detach from iovar manager */ - wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); while (wlc->tx_queues != NULL) wlc_txq_free(wlc, wlc->tx_queues); @@ -1995,9 +1757,6 @@ void wlc_ap_upd(struct wlc_info *wlc) else wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ - /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ - wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; - /* fixup mpc */ wlc->mpc = true; } @@ -2119,7 +1878,7 @@ void wlc_radio_disable(struct wlc_info *wlc) } wlc_radio_monitor_start(wlc); - wl_down(wlc->wl); + brcms_down(wlc->wl); } static void wlc_radio_enable(struct wlc_info *wlc) @@ -2130,9 +1889,7 @@ static void wlc_radio_enable(struct wlc_info *wlc) if (DEVICEREMOVED(wlc)) return; - if (!wlc->down_override) { /* imposed by wl down/out ioctl */ - wl_up(wlc->wl); - } + brcms_up(wlc->wl); } /* periodical query hw radio button while driver is "down" */ @@ -2143,7 +1900,7 @@ static void wlc_radio_timer(void *arg) if (DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } @@ -2163,7 +1920,8 @@ static bool wlc_radio_monitor_start(struct wlc_info *wlc) wlc->radio_monitor = true; wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); - wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); + brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, + true); return true; } @@ -2174,19 +1932,12 @@ bool wlc_radio_monitor_stop(struct wlc_info *wlc) wlc->radio_monitor = false; wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); - return wl_del_timer(wlc->wl, wlc->radio_timer); + return brcms_del_timer(wlc->wl, wlc->radio_timer); } static void wlc_watchdog_by_timer(void *arg) { - struct wlc_info *wlc = (struct wlc_info *) arg; wlc_watchdog(arg); - if (WLC_WATCHDOG_TBTT(wlc)) { - /* set to normal osl watchdog period */ - wl_del_timer(wlc->wl, wlc->wdtimer); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - } } /* common watchdog code */ @@ -2204,7 +1955,7 @@ static void wlc_watchdog(void *arg) if (DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } @@ -2339,7 +2090,7 @@ int wlc_up(struct wlc_info *wlc) wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, WLC_BAND_ALL); - wl_init(wlc->wl); + brcms_init(wlc->wl); wlc->pub->up = true; if (wlc->bandinit_pending) { @@ -2359,7 +2110,7 @@ int wlc_up(struct wlc_info *wlc) wlc_wme_retries_write(wlc); /* start one second watchdog timer */ - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); + brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); wlc->WDarmed = true; /* ensure antenna config is up to date */ @@ -2437,7 +2188,7 @@ uint wlc_down(struct wlc_info *wlc) /* cancel the watchdog timer */ if (wlc->WDarmed) { - if (!wl_del_timer(wlc->wl, wlc->wdtimer)) + if (!brcms_del_timer(wlc->wl, wlc->wdtimer)) callbacks++; wlc->WDarmed = false; } @@ -2453,7 +2204,7 @@ uint wlc_down(struct wlc_info *wlc) /* flush tx queues */ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - bcm_pktq_flush(&qi->q, true, NULL, NULL); + brcmu_pktq_flush(&qi->q, true, NULL, NULL); } callbacks += wlc_bmac_down_finish(wlc->hw); @@ -2475,7 +2226,6 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ bool shortslot_restrict = false; /* Restrict association to stations that support shortslot */ - bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ bool preamble_restrict = false; /* Restrict association to stations that support short @@ -2571,8 +2321,6 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) band->gmode = gmode; - wlc->ignore_bcns = ignore_bcns; - wlc->shortslot_override = shortslot; if (AP_ENAB(wlc->pub)) { @@ -2781,11 +2529,9 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bool bool_val; int bcmerror; d11regs_t *regs; - uint i; struct scb *nextscb; bool ta_ok; uint band; - rw_reg_t *r; struct wlc_bsscfg *bsscfg; wlc_bss_info_t *current_bss; @@ -2797,13 +2543,12 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, nextscb = NULL; ta_ok = false; band = 0; - r = NULL; /* If the device is turned off, then it's not "removed" */ if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return -EBADE; } @@ -2821,61 +2566,15 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = 0; regs = wlc->regs; - /* A few commands don't need any arguments; all the others do. */ - switch (cmd) { - case WLC_UP: - case WLC_OUT: - case WLC_DOWN: - case WLC_DISASSOC: - case WLC_RESTART: - case WLC_REBOOT: - case WLC_START_CHANNEL_QA: - case WLC_INIT: - break; - - default: - if ((arg == NULL) || (len <= 0)) { - wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs " - "arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = -EINVAL; - goto done; - } + if ((arg == NULL) || (len <= 0)) { + wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = -EINVAL; + goto done; } switch (cmd) { -#if defined(BCMDBG) - case WLC_GET_MSGLEVEL: - *pval = wl_msg_level; - break; - - case WLC_SET_MSGLEVEL: - wl_msg_level = val; - break; -#endif - - case WLC_GET_INSTANCE: - *pval = wlc->pub->unit; - break; - - case WLC_GET_CHANNEL:{ - channel_info_t *ci = (channel_info_t *) arg; - - if (len <= (int)sizeof(ci)) { - bcmerror = EOVERFLOW; - goto done; - } - - ci->hw_channel = - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); - ci->target_channel = - CHSPEC_CHANNEL(wlc->default_bss->chanspec); - ci->scan_channel = 0; - - break; - } - case WLC_SET_CHANNEL:{ chanspec_t chspec = CH20MHZ_CHSPEC(val); @@ -2909,273 +2608,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } -#if defined(BCMDBG) - case WLC_GET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val >= MHFMAX) { - bcmerror = -EINVAL; - break; - } - - *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); - break; - - case WLC_SET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - i = (u16) val; - if (i >= MHFMAX) { - bcmerror = -EINVAL; - break; - } - - wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), - WLC_BAND_AUTO); - break; - - case WLC_GET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = -EINVAL; - break; - } - - *pval = wlc_read_shm(wlc, (u16) val); - break; - - case WLC_SET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = -EINVAL; - break; - } - - wlc_write_shm(wlc, (u16) val, - (u16) (val >> NBITS(u16))); - break; - - case WLC_R_REG: /* MAC registers */ - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = -EOVERFLOW; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = -EINVAL; - break; - } - if (r->size == sizeof(u32)) - r->val = - R_REG((u32 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else if (r->size == sizeof(u16)) - r->val = - R_REG((u16 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else - bcmerror = -EINVAL; - break; - - case WLC_W_REG: - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = -EOVERFLOW; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = -EINVAL; - break; - } - if (r->size == sizeof(u32)) - W_REG((u32 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else if (r->size == sizeof(u16)) - W_REG((u16 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else - bcmerror = -EINVAL; - break; -#endif /* BCMDBG */ - - case WLC_GET_TXANT: - *pval = wlc->stf->txant; - break; - - case WLC_SET_TXANT: - bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); - if (bcmerror < 0) - break; - - wlc->stf->txant = (s8) val; - - /* if down, we are done */ - if (!wlc->pub->up) - break; - - wlc_suspend_mac_and_wait(wlc); - - wlc_stf_phy_txant_upd(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - - wlc_enable_mac(wlc); - - break; - - case WLC_GET_ANTDIV:{ - u8 phy_antdiv; - - /* return configured value if core is down */ - if (!wlc->pub->up) { - *pval = wlc->stf->ant_rx_ovr; - - } else { - if (wlc_phy_ant_rxdiv_get - (wlc->band->pi, &phy_antdiv)) - *pval = (int)phy_antdiv; - else - *pval = (int)wlc->stf->ant_rx_ovr; - } - - break; - } - case WLC_SET_ANTDIV: - /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ - if ((val < -1) || (val > 3)) { - bcmerror = -EINVAL; - break; - } - - if (val == -1) - val = ANT_RX_DIV_DEF; - - wlc->stf->ant_rx_ovr = (u8) val; - wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); - break; - - case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ - u16 rxstatus; - - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - rxstatus = R_REG(&wlc->regs->phyrxstatus0); - if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = -EBADE; - break; - } - *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCANTDIV: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - *pval = - (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & - MHF1_ANTDIV); - break; - - case WLC_SET_UCANTDIV:{ - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* if multiband, band must be locked */ - if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = -ENOMEDIUM; - break; - } - - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); - break; - } -#endif /* defined(BCMDBG) */ - - case WLC_GET_SRL: - *pval = wlc->SRL; - break; - case WLC_SET_SRL: if (val >= 1 && val <= RETRY_SHORT_MAX) { int ac; @@ -3191,10 +2623,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = -EINVAL; break; - case WLC_GET_LRL: - *pval = wlc->LRL; - break; - case WLC_SET_LRL: if (val >= 1 && val <= 255) { int ac; @@ -3210,159 +2638,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = -EINVAL; break; - case WLC_GET_CWMIN: - *pval = wlc->band->CWmin; - break; - - case WLC_SET_CWMIN: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - if (val >= 1 && val <= 255) { - wlc_set_cwmin(wlc, (u16) val); - } else - bcmerror = -EINVAL; - break; - - case WLC_GET_CWMAX: - *pval = wlc->band->CWmax; - break; - - case WLC_SET_CWMAX: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - if (val >= 255 && val <= 2047) { - wlc_set_cwmax(wlc, (u16) val); - } else - bcmerror = -EINVAL; - break; - - case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ - *pval = wlc->pub->radio_disabled; - break; - - case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to - * set - */ - u16 radiomask, radioval; - uint validbits = - WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; - mbool new = 0; - - radiomask = (val & 0xffff0000) >> 16; - radioval = val & 0x0000ffff; - - if ((radiomask == 0) || (radiomask & ~validbits) - || (radioval & ~validbits) - || ((radioval & ~radiomask) != 0)) { - wiphy_err(wlc->wiphy, "SET_RADIO with wrong " - "bits 0x%x\n", val); - bcmerror = -EINVAL; - break; - } - - new = - (wlc->pub->radio_disabled & ~radiomask) | radioval; - wlc->pub->radio_disabled = new; - - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - break; - } - - case WLC_GET_PHYTYPE: - *pval = WLC_PHYTYPE(wlc->band->phytype); - break; - -#if defined(BCMDBG) - case WLC_GET_KEY: - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { - wl_wsec_key_t key; - - wsec_key_t *src_key = wlc->wsec_keys[val]; - - if (len < (int)sizeof(key)) { - bcmerror = -EOVERFLOW; - break; - } - - memset((char *)&key, 0, sizeof(key)); - if (src_key) { - key.index = src_key->id; - key.len = src_key->len; - memcpy(key.data, src_key->data, key.len); - key.algo = src_key->algo; - if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) - key.flags |= WL_SOFT_KEY; - if (src_key->flags & WSEC_PRIMARY_KEY) - key.flags |= WL_PRIMARY_KEY; - - memcpy(key.ea, src_key->ea, ETH_ALEN); - } - - memcpy(arg, &key, sizeof(key)); - } else - bcmerror = -EINVAL; - break; -#endif /* defined(BCMDBG) */ - - case WLC_SET_KEY: - bcmerror = - wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_KEY_SEQ:{ - wsec_key_t *key; - - if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = -EOVERFLOW; - break; - } - - /* Return the key's tx iv as an EAPOL sequence counter. - * This will be used to supply the RSC value to a supplicant. - * The format is 8 bytes, with least significant in seq[0]. - */ - - key = WSEC_KEY(wlc, val); - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && - (key != NULL)) { - u8 seq[DOT11_WPA_KEY_RSC_LEN]; - u16 lo; - u32 hi; - /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea)) { - lo = bsscfg->wpa_none_txiv.lo; - hi = bsscfg->wpa_none_txiv.hi; - } else { - lo = key->txiv.lo; - hi = key->txiv.hi; - } - - /* format the buffer, low to high */ - seq[0] = lo & 0xff; - seq[1] = (lo >> 8) & 0xff; - seq[2] = hi & 0xff; - seq[3] = (hi >> 8) & 0xff; - seq[4] = (hi >> 16) & 0xff; - seq[5] = (hi >> 24) & 0xff; - seq[6] = 0; - seq[7] = 0; - - memcpy(arg, seq, sizeof(seq)); - } else { - bcmerror = -EINVAL; - } - break; - } - case WLC_GET_CURR_RATESET:{ wl_rateset_t *ret_rs = (wl_rateset_t *) arg; wlc_rateset_t *rs; @@ -3383,24 +2658,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - case WLC_GET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - - memset(&rs, 0, sizeof(wlc_rateset_t)); - wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); - - if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = -EOVERFLOW; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs.count; - memcpy(&ret_rs->rates, &rs.rates, rs.count); - break; - } - case WLC_SET_RATESET:{ wlc_rateset_t rs; wl_rateset_t *in_rs = (wl_rateset_t *) arg; @@ -3441,13 +2698,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - case WLC_GET_BCNPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->beacon_period; - else - *pval = wlc->default_bss->beacon_period; - break; - case WLC_SET_BCNPRD: /* range [1, 0xffff] */ if (val >= DOT11_MIN_BEACON_PERIOD @@ -3457,124 +2707,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = -EINVAL; break; - case WLC_GET_DTIMPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->dtim_period; - else - *pval = wlc->default_bss->dtim_period; - break; - - case WLC_SET_DTIMPRD: - /* range [1, 0xff] */ - if (val >= DOT11_MIN_DTIM_PERIOD - && val <= DOT11_MAX_DTIM_PERIOD) { - wlc->default_bss->dtim_period = (u8) val; - } else - bcmerror = -EINVAL; - break; - -#ifdef SUPPORT_PS - case WLC_GET_PM: - *pval = wlc->PM; - break; - - case WLC_SET_PM: - if ((val >= PM_OFF) && (val <= PM_MAX)) { - wlc->PM = (u8) val; - if (wlc->pub->up) { - } - /* Change watchdog driver to align watchdog with tbtt if possible */ - wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); - } else - bcmerror = -EBADE; - break; -#endif /* SUPPORT_PS */ - -#ifdef SUPPORT_PS -#ifdef BCMDBG - case WLC_GET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = -BCME_NOTSTA; - break; - } - *pval = wlc->wake; - break; - - case WLC_SET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = -BCME_NOTSTA; - break; - } - - wlc->wake = val ? true : false; - - /* if down, we're done */ - if (!wlc->pub->up) - break; - - /* apply to the mac */ - wlc_set_ps_ctrl(wlc); - break; -#endif /* BCMDBG */ -#endif /* SUPPORT_PS */ - - case WLC_GET_REVINFO: - bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); - break; - - case WLC_GET_AP: - *pval = (int)AP_ENAB(wlc->pub); - break; - - case WLC_GET_ATIM: - if (bsscfg->associated) - *pval = (int)current_bss->atim_window; - else - *pval = (int)wlc->default_bss->atim_window; - break; - - case WLC_SET_ATIM: - wlc->default_bss->atim_window = (u32) val; - break; - -#ifdef SUPPORT_HWKEY - case WLC_GET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, - wlcif); - break; - - case WLC_SET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_WPA_AUTH: - *pval = (int)bsscfg->WPA_auth; - break; - - case WLC_SET_WPA_AUTH: - /* change of WPA_Auth modifies the PS_ALLOWED state */ - if (BSSCFG_STA(bsscfg)) { - bsscfg->WPA_auth = (u16) val; - } else - bsscfg->WPA_auth = (u16) val; - break; -#endif /* SUPPORT_HWKEY */ - - case WLC_GET_BANDLIST: - /* count of number of bands, followed by each band type */ - *pval++ = NBANDS(wlc); - *pval++ = wlc->band->bandtype; - if (NBANDS(wlc) > 1) - *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; - break; - - case WLC_GET_BAND: - *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; - break; - case WLC_GET_PHYLIST: { unsigned char *cp = arg; @@ -3594,14 +2726,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - case WLC_GET_SHORTSLOT: - *pval = wlc->shortslot; - break; - - case WLC_GET_SHORTSLOT_OVERRIDE: - *pval = wlc->shortslot_override; - break; - case WLC_SET_SHORTSLOT_OVERRIDE: if ((val != WLC_SHORTSLOT_AUTO) && (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { @@ -3635,256 +2759,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; - case WLC_GET_LEGACY_ERP: - *pval = wlc->include_legacy_erp; - break; - - case WLC_SET_LEGACY_ERP: - if (wlc->include_legacy_erp == bool_val) - break; - - wlc->include_legacy_erp = bool_val; - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - - case WLC_GET_GMODE: - if (wlc->band->bandtype == WLC_BAND_2G) - *pval = wlc->band->gmode; - else if (NBANDS(wlc) > 1) - *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; - break; - - case WLC_SET_GMODE: - if (!wlc->pub->associated) - bcmerror = wlc_set_gmode(wlc, (u8) val, true); - else { - bcmerror = -EISCONN; - break; - } - break; - - case WLC_GET_GMODE_PROTECTION: - *pval = wlc->protection->_g; - break; - - case WLC_GET_PROTECTION_CONTROL: - *pval = wlc->protection->overlap; - break; - - case WLC_SET_PROTECTION_CONTROL: - if ((val != WLC_PROTECTION_CTL_OFF) && - (val != WLC_PROTECTION_CTL_LOCAL) && - (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = -EINVAL; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); - - /* Current g_protection will sync up to the specified control alg in watchdog - * if the driver is up and associated. - * If the driver is down or not associated, the control setting has no effect. - */ - break; - - case WLC_GET_GMODE_PROTECTION_OVERRIDE: - *pval = wlc->protection->g_override; - break; - - case WLC_SET_GMODE_PROTECTION_OVERRIDE: - if ((val != WLC_PROTECTION_AUTO) && - (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = -EINVAL; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); - - break; - - case WLC_SET_SUP_RATESET_OVERRIDE:{ - wlc_rateset_t rs, new; - - /* copyin */ - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = -EOVERFLOW; - break; - } - memcpy(&rs, arg, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if (rs.count > WLC_NUMRATES) { - bcmerror = -EINVAL; - break; - } - - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - /* gmode only command when not in gmode */ - bcmerror = -EINVAL; - break; - } - - /* check for an empty rateset to clear the override */ - if (rs.count == 0) { - memset(&wlc->sup_rates_override, 0, - sizeof(wlc_rateset_t)); - break; - } - - /* - * 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 = -EINVAL; - break; - } - - /* apply new rateset to the override */ - memcpy(&wlc->sup_rates_override, &new, - sizeof(wlc_rateset_t)); - - /* update bcn and probe resp if needed */ - if (wlc->pub->up && AP_ENAB(wlc->pub) - && wlc->pub->associated) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - } - - case WLC_GET_SUP_RATESET_OVERRIDE: - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - /* gmode only command when not in gmode */ - bcmerror = -EINVAL; - break; - } - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = -EOVERFLOW; - break; - } - memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); - - break; - - case WLC_GET_PRB_RESP_TIMEOUT: - *pval = wlc->prb_resp_timeout; - break; - - case WLC_SET_PRB_RESP_TIMEOUT: - if (wlc->pub->up) { - bcmerror = -EISCONN; - break; - } - if (val < 0 || val >= 0xFFFF) { - bcmerror = -EINVAL; /* bad value */ - break; - } - wlc->prb_resp_timeout = (u16) val; - break; - - case WLC_GET_KEY_PRIMARY:{ - wsec_key_t *key; - - /* treat the 'val' parm as the key id */ - key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (key != NULL) { - *pval = key->id == val ? true : false; - } else { - bcmerror = -EINVAL; - } - break; - } - - case WLC_SET_KEY_PRIMARY:{ - wsec_key_t *key, *old_key; - - bcmerror = -EINVAL; - - /* treat the 'val' parm as the key id */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - key = bsscfg->bss_def_keys[i]; - if (key != NULL && key->id == val) { - old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (old_key != NULL) - old_key->flags &= - ~WSEC_PRIMARY_KEY; - key->flags |= WSEC_PRIMARY_KEY; - bsscfg->wsec_index = i; - bcmerror = 0; - } - } - break; - } - -#ifdef BCMDBG - case WLC_INIT: - wl_init(wlc->wl); - break; -#endif - - case WLC_SET_VAR: - case WLC_GET_VAR:{ - char *name; - /* validate the name value */ - name = (char *)arg; - for (i = 0; i < (uint) len && *name != '\0'; - i++, name++) - ; - - if (i == (uint) len) { - bcmerror = -EOVERFLOW; - break; - } - i++; /* include the null in the string length */ - - if (cmd == WLC_GET_VAR) { - bcmerror = - wlc_iovar_op(wlc, arg, - (void *)((s8 *) arg + i), - len - i, arg, len, IOV_GET, - wlcif); - } else - bcmerror = - wlc_iovar_op(wlc, arg, NULL, 0, - (void *)((s8 *) arg + i), - len - i, IOV_SET, wlcif); - - break; - } - - case WLC_SET_WSEC_PMK: - bcmerror = -ENOTSUPP; - break; - -#if defined(BCMDBG) - case WLC_CURRENT_PWR: - if (!wlc->pub->up) - bcmerror = -ENOLINK; - else - bcmerror = wlc_get_current_txpwr(wlc, arg, len); - break; -#endif - - case WLC_LAST: - wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__); } done: @@ -3894,70 +2768,11 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, return bcmerror; } -#if defined(BCMDBG) -/* consolidated register access ioctl error checking */ -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 -EINVAL; - - /* if multiband and band is not specified, band must be locked */ - if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return -ENOMEDIUM; - - /* must have core clocks */ - if (!wlc->clk) - return -EIO; - - return 0; -} -#endif /* defined(BCMDBG) */ - -/* 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) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, - NULL); -} - -/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), - IOV_SET, NULL); -} - /* - * register iovar table, watchdog and down handlers. - * calling function must keep 'iovars' until wlc_module_unregister is called. - * 'iovar' must have the last entry's name field being NULL as terminator. + * register watchdog and down handlers. */ -int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t i_fn, +int wlc_module_register(struct wlc_pub *pub, + const char *name, void *hdl, watchdog_fn_t w_fn, down_fn_t d_fn) { struct wlc_info *wlc = (struct wlc_info *) pub->wlc; @@ -3968,9 +2783,7 @@ int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, if (wlc->modulecb[i].name[0] == '\0') { strncpy(wlc->modulecb[i].name, name, sizeof(wlc->modulecb[i].name) - 1); - wlc->modulecb[i].iovars = iovars; wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].iovar_fn = i_fn; wlc->modulecb[i].watchdog_fn = w_fn; wlc->modulecb[i].down_fn = d_fn; return 0; @@ -4015,295 +2828,6 @@ static void wlc_wme_retries_write(struct wlc_info *wlc) } } -/* Get or set an iovar. The params/p_len pair specifies any additional - * qualifying parameters (e.g. an "element index") for a get, while the - * arg/len pair is the buffer for the value to be set or retrieved. - * Operation (get/set) is specified by the last argument. - * interface context provided by wlcif - * - * All pointers may point into the same buffer. - */ -int -wlc_iovar_op(struct wlc_info *wlc, const char *name, - void *params, int p_len, void *arg, int len, - bool set, struct wlc_if *wlcif) -{ - int err = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - u32 actionid; - int i; - - if (!set && (len == sizeof(int)) && - !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - 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 */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!wlc->modulecb[i].iovars) - continue; - vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); - if (vi) - break; - } - /* iovar name not found */ - if (i >= WLC_MAXMODULES) { - return -ENOTSUPP; - } - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - p_len = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - /* Do the actual parameter implementation */ - err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, - name, params, p_len, arg, len, val_size, - wlcif); - return err; -} - -int -wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, - bool set) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int err = 0; - s32 int_val = 0; - - /* check generic condition flags */ - if (set) { - if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? -EISCONN : -ENOLINK); - } else if ((vi->flags & IOVF_SET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = -ENOMEDIUM; - } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = -EIO; - } - } else { - if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? -EISCONN : -ENOLINK); - } else if ((vi->flags & IOVF_GET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = -ENOMEDIUM; - } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = -EIO; - } - } - - if (err) - goto exit; - - /* length check on io buf */ - err = bcm_iovar_lencheck(vi, arg, len, set); - if (err) - goto exit; - - /* On set, check value ranges for integer types */ - if (set) { - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - memcpy(&int_val, arg, sizeof(int)); - err = wlc_iovar_rangecheck(wlc, int_val, vi); - break; - } - } - exit: - return err; -} - -/* handler for iovar table wlc_iovars */ -/* - * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each - * iovar case, the switch statement maps the iovar id into separate get - * and set values. If you add a new iovar to the switch you MUST use - * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with - * another case. - * Please use params for additional qualifying parameters. - */ -int -wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, int len, - int val_size, struct wlc_if *wlcif) -{ - struct wlc_info *wlc = hdl; - struct wlc_bsscfg *bsscfg; - int err = 0; - s32 int_val = 0; - s32 int_val2 = 0; - s32 *ret_int_ptr; - bool bool_val; - bool bool_val2; - wlc_bss_info_t *current_bss; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - - bsscfg = NULL; - current_bss = NULL; - - err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); - if (err != 0) - return err; - - /* convenience int and bool vals for first 8 bytes of buffer */ - if (p_len >= (int)sizeof(int_val)) - memcpy(&int_val, params, sizeof(int_val)); - - if (p_len >= (int)sizeof(int_val) * 2) - memcpy(&int_val2, - (void *)((unsigned long)params + sizeof(int_val)), - sizeof(int_val)); - - /* convenience int ptr for 4-byte gets (requires int aligned arg) */ - ret_int_ptr = (s32 *) arg; - - bool_val = (int_val != 0) ? true : false; - bool_val2 = (int_val2 != 0) ? true : false; - - 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): - wlc->RTSThresh = int_val; - break; - - case IOV_GVAL(IOV_QTXPOWER):{ - uint qdbm; - bool override; - - err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, - &override); - if (err != 0) - return err; - - /* Return qdbm units */ - *ret_int_ptr = - qdbm | (override ? WL_TXPWR_OVERRIDE : 0); - break; - } - - /* As long as override is false, this only sets the *user* targets. - User can twiddle this all he wants with no harm. - wlc_phy_txpower_set() explicitly sets override to false if - not internal or test. - */ - case IOV_SVAL(IOV_QTXPOWER):{ - u8 qdbm; - bool override; - - /* Remove override bit and clip to max qdbm value */ - qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); - /* Extract override setting */ - override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; - err = - wlc_phy_txpower_set(wlc->band->pi, qdbm, override); - break; - } - - case IOV_GVAL(IOV_MPC): - *ret_int_ptr = (s32) wlc->mpc; - break; - - case IOV_SVAL(IOV_MPC): - wlc->mpc = bool_val; - wlc_radio_mpc_upd(wlc); - - break; - - case IOV_GVAL(IOV_BCN_LI_BCN): - *ret_int_ptr = wlc->bcn_li_bcn; - break; - - case IOV_SVAL(IOV_BCN_LI_BCN): - wlc->bcn_li_bcn = (u8) int_val; - if (wlc->pub->up) - wlc_bcn_li_upd(wlc); - break; - - default: - wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n", - wlc->pub->unit, __func__); - err = -ENOTSUPP; - break; - } - - goto exit; /* avoid unused label warning */ - - exit: - return err; -} - -static int -wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) -{ - int err = 0; - u32 min_val = 0; - u32 max_val = 0; - - /* Only ranged integers are checked */ - switch (vi->type) { - case IOVT_INT32: - max_val |= 0x7fffffff; - /* fall through */ - case IOVT_INT16: - max_val |= 0x00007fff; - /* fall through */ - case IOVT_INT8: - max_val |= 0x0000007f; - min_val = ~max_val; - if (vi->flags & IOVF_NTRL) - min_val = 1; - else if (vi->flags & IOVF_WHL) - min_val = 0; - /* Signed values are checked against max_val and min_val */ - if ((s32) val < (s32) min_val - || (s32) val > (s32) max_val) - err = -EINVAL; - break; - - case IOVT_UINT32: - max_val |= 0xffffffff; - /* fall through */ - case IOVT_UINT16: - max_val |= 0x0000ffff; - /* fall through */ - case IOVT_UINT8: - max_val |= 0x000000ff; - if (vi->flags & IOVF_NTRL) - min_val = 1; - if ((val < min_val) || (val > max_val)) - err = -EINVAL; - break; - } - - return err; -} - #ifdef BCMDBG static const char *supr_reason[] = { "None", "PMQ Entry", "Flush request", @@ -4416,9 +2940,10 @@ bool wlc_chipmatch(u16 vendor, u16 device) return false; } + if (device == BCM43224_D11N_ID_VEN1) + return true; if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) return true; - if (device == BCM4313_D11N2G_ID) return true; if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) @@ -4481,16 +3006,16 @@ void wlc_print_txdesc(d11txh_t *txh) printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); printk(KERN_DEBUG "\n"); - bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); + brcmu_format_hex(hexbuf, iv, sizeof(txh->IV)); printk(KERN_DEBUG "SecIV: %s\n", hexbuf); - bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); + brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); printk(KERN_DEBUG "RA: %s\n", hexbuf); printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); - bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); + brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); - bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); + brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); printk(KERN_DEBUG "PLCP: %s ", hexbuf); printk(KERN_DEBUG "DUR: %04x", fragdfb); printk(KERN_DEBUG "\n"); @@ -4506,9 +3031,9 @@ void wlc_print_txdesc(d11txh_t *txh) printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); - bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); + brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); - bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); + brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); printk(KERN_DEBUG "RTS Frame: %s", hexbuf); printk(KERN_DEBUG "\n"); } @@ -4526,7 +3051,7 @@ void wlc_print_rxh(d11rxhdr_t *rxh) u16 macstatus2 = rxh->RxStatus2; char flagstr[64]; char lenbuf[20]; - static const bcm_bit_desc_t macstat_flags[] = { + static const struct brcmu_bit_desc macstat_flags[] = { {RXS_FCSERR, "FCSErr"}, {RXS_RESPFRAMETX, "Reply"}, {RXS_PBPRES, "PADDING"}, @@ -4539,7 +3064,7 @@ void wlc_print_rxh(d11rxhdr_t *rxh) 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); + brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64); snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); @@ -4554,32 +3079,6 @@ void wlc_print_rxh(d11rxhdr_t *rxh) } #endif /* defined(BCMDBG) */ -#if defined(BCMDBG) -int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - ssid_len = IEEE80211_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint) ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((unsigned char) c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - return (int)(p - buf); -} -#endif /* defined(BCMDBG) */ - static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) { return wlc_bmac_rate_shm_offset(wlc->hw, rate); @@ -4613,7 +3112,7 @@ 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 = bcm_pktq_peek_tail(q, &eprec); + p = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) { wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" "\n", __func__, eprec, prec); @@ -4635,16 +3134,16 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, } /* Evict packet according to discard policy */ - p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : - bcm_pktq_pdeq_tail(q, eprec); - bcm_pkt_buf_free_skb(p); + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : + brcmu_pktq_pdeq_tail(q, eprec); + brcmu_pkt_buf_free_skb(p); } /* Enqueue */ if (head) - p = bcm_pktq_penq_head(q, prec, pkt); + p = brcmu_pktq_penq_head(q, prec, pkt); else - p = bcm_pktq_penq(q, prec, pkt); + p = brcmu_pktq_penq(q, prec, pkt); return true; } @@ -4669,7 +3168,7 @@ void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, * XXX we might hit this condtion in case * packet flooding from mac80211 stack */ - bcm_pkt_buf_free_skb(sdu); + brcmu_pkt_buf_free_skb(sdu); } /* Check if flow control needs to be turned on after enqueuing the packet @@ -4733,7 +3232,7 @@ void wlc_send_q(struct wlc_info *wlc) /* Send all the enq'd pkts that we can. * Dequeue packets with precedence with empty HW fifo only */ - while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) { + while (prec_map && (pkt[0] = brcmu_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); @@ -4748,7 +3247,7 @@ void wlc_send_q(struct wlc_info *wlc) } if (err == -EBUSY) { - bcm_pktq_penq_head(q, prec, pkt[0]); + brcmu_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! */ @@ -5171,7 +3670,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, qos = ieee80211_is_data_qos(h->frame_control); /* compute length of frame in bytes for use in PLCP computations */ - len = bcm_pkttotlen(p); + len = brcmu_pkttotlen(p); phylen = len + FCS_LEN; /* If WEP enabled, add room in phylen for the additional bytes of @@ -5763,29 +4262,6 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) { struct wlc_bsscfg *cfg = wlc->cfg; - if (BSSCFG_STA(cfg)) { - /* run watchdog here if the watchdog timer is not armed */ - if (WLC_WATCHDOG_TBTT(wlc)) { - u32 cur, delta; - if (wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - cur = OSL_SYSUPTIME(); - delta = cur > wlc->WDlast ? cur - wlc->WDlast : - (u32) ~0 - wlc->WDlast + cur + 1; - if (delta >= TIMER_INTERVAL_WATCHDOG) { - wlc_watchdog((void *)wlc); - wlc->WDlast = cur; - } - - wl_add_timer(wlc->wl, wlc->wdtimer, - wlc_watchdog_backup_bi(wlc), true); - wlc->WDarmed = true; - } - } - if (!cfg->BSS) { /* DirFrmQ is now valid...defer setting until end of ATIM window */ wlc->qvalid |= MCMD_DIRFRMQVAL; @@ -5926,7 +4402,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info->flags |= IEEE80211_TX_STAT_ACK; } - totlen = bcm_pkttotlen(p); + totlen = brcmu_pkttotlen(p); free_pdu = true; wlc_txfifo_complete(wlc, queue, 1); @@ -5934,7 +4410,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) if (lastframe) { p->next = NULL; p->prev = NULL; - wlc->txretried = 0; /* remove PLCP & Broadcom tx descriptor header */ skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); @@ -5948,7 +4423,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) fatal: if (p) - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); return true; @@ -5964,15 +4439,9 @@ wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) /* There is more room; mark precedences related to this FIFO sendable */ WLC_TX_FIFO_ENAB(wlc, fifo); - if (!TXPKTPENDTOT(wlc)) { - if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) - wlc_bsscfg_tx_check(wlc); - } - /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ if (AP_ENAB(wlc->pub) && - wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { - wlc->bcmcfifo_drain = false; + !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); } @@ -6178,7 +4647,7 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) rxh = (d11rxhdr_t *) (p->data); /* strip off rxhdr */ - skb_pull(p, wlc->hwrxoff); + skb_pull(p, WL_HWRXOFF); /* fixup rx header endianness */ rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize); @@ -6252,7 +4721,7 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) return; toss: - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return @@ -6690,8 +5159,6 @@ static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) band->mimo_cap_40 = false; } } - - wlc->mimo_band_bwcap = bwcap; } void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) @@ -6985,43 +5452,6 @@ void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg) memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); } -/* Retrieve a consolidated set of revision information, - * typically for the WLC_GET_REVINFO ioctl - */ -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 -EOVERFLOW; - - rinfo->vendorid = wlc->vendorid; - rinfo->deviceid = wlc->deviceid; - rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | - (wlc->band->radioid << IDCODE_ID_SHIFT); - rinfo->chiprev = wlc->pub->sih->chiprev; - rinfo->corerev = wlc->pub->corerev; - rinfo->boardid = wlc->pub->sih->boardtype; - rinfo->boardvendor = wlc->pub->sih->boardvendor; - rinfo->boardrev = wlc->pub->boardrev; - rinfo->ucoderev = wlc->ucode_rev; - rinfo->driverrev = EPI_VERSION_NUM; - rinfo->bus = wlc->pub->sih->bustype; - rinfo->chipnum = wlc->pub->sih->chip; - - if (len >= (offsetof(wlc_rev_info_t, chippkg))) { - rinfo->phytype = wlc->band->phytype; - rinfo->phyrev = wlc->band->phyrev; - rinfo->anarev = 0; /* obsolete stuff, suppress */ - } - - if (len >= sizeof(*rinfo)) { - rinfo->chippkg = wlc->pub->sih->chippkg; - } - - 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, @@ -7273,20 +5703,6 @@ wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); } -void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) -{ - wlc->band->CWmin = newmin; - wlc_bmac_set_cwmin(wlc->hw, newmin); -} - -void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) -{ - wlc->band->CWmax = newmax; - wlc_bmac_set_cwmax(wlc->hw, newmax); -} - -/* Search mem rw utilities */ - void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) { wlc_bmac_pllreq(wlc->hw, set, req_bit); @@ -7415,12 +5831,15 @@ static void wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, int prio) { +#ifdef NON_FUNCTIONAL + /* wlcif_list is never filled so this function is not functional */ struct wlc_if *wlcif; for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) - wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); + brcms_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); } +#endif } static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) @@ -7435,7 +5854,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 */ - bcm_pktq_init(&qi->q, WLC_PREC_COUNT, + brcmu_pktq_init(&qi->q, WLC_PREC_COUNT, (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + wlc->pub->psq_pkts_total); @@ -7501,7 +5920,7 @@ void wlc_inval_dma_pkts(struct wlc_hw_info *hw, struct ieee80211_sta *sta, void (*dma_callback_fn)) { - struct hnddma_pub *dmah; + struct dma_pub *dmah; int i; for (i = 0; i < NFIFO; i++) { dmah = hw->di[i]; @@ -7519,11 +5938,122 @@ 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); + brcmu_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); + brcms_msleep(wlc->wl, 1); } } + +int wlc_set_par(struct wlc_info *wlc, enum wlc_par_id par_id, int int_val) +{ + int err = 0; + + switch (par_id) { + case IOV_BCN_LI_BCN: + wlc->bcn_li_bcn = (u8) int_val; + if (wlc->pub->up) + wlc_bcn_li_upd(wlc); + break; + /* As long as override is false, this only sets the *user* + targets. User can twiddle this all he wants with no harm. + wlc_phy_txpower_set() explicitly sets override to false if + not internal or test. + */ + case IOV_QTXPOWER:{ + u8 qdbm; + bool override; + + /* Remove override bit and clip to max qdbm value */ + qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); + /* Extract override setting */ + override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; + err = + wlc_phy_txpower_set(wlc->band->pi, qdbm, override); + break; + } + case IOV_MPC: + wlc->mpc = (bool)int_val; + wlc_radio_mpc_upd(wlc); + break; + default: + err = -ENOTSUPP; + } + return err; +} + +int wlc_get_par(struct wlc_info *wlc, enum wlc_par_id par_id, int *ret_int_ptr) +{ + int err = 0; + + switch (par_id) { + case IOV_BCN_LI_BCN: + *ret_int_ptr = wlc->bcn_li_bcn; + break; + case IOV_QTXPOWER: { + uint qdbm; + bool override; + + err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, + &override); + if (err != 0) + return err; + + /* Return qdbm units */ + *ret_int_ptr = + qdbm | (override ? WL_TXPWR_OVERRIDE : 0); + break; + } + case IOV_MPC: + *ret_int_ptr = (s32) wlc->mpc; + break; + default: + err = -ENOTSUPP; + } + return err; +} + +/* + * 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++) + ; + } + /* nothing found */ + return NULL; +} + +/* + * 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); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/main.h index fb48dfcb97d5..c41205a5ce44 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/main.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_h_ -#define _wlc_h_ +#ifndef _BRCM_MAIN_H_ +#define _BRCM_MAIN_H_ #define MA_WINDOW_SZ 8 /* moving average window size */ #define WL_HWRXOFF 38 /* chip rx buffer offset */ @@ -23,7 +23,19 @@ #define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ #define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ -#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) +#define SEQNUM_SHIFT 4 +#define AMPDU_DELIMITER_LEN 4 +#define SEQNUM_MAX 0x1000 + +#define APHY_CWMIN 15 +#define PHY_CWMAX 1023 + +#define EDCF_AIFSN_MIN 1 +#define FRAGNUM_MASK 0xF + +#define NTXRATE 64 /* # tx MPDUs rate is reported for */ + +#define WLC_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8)) /* Maximum wait time for a MAC suspend */ #define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ @@ -35,6 +47,26 @@ /* transmit buffer max headroom for protocol headers */ #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) +#define AC_COUNT 4 + +/* 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) + * #define <NAME>_S 4 + * ... + * regval = R_REG(osh, ®s->regfoo); + * field = GFIELD(regval, <NAME>); + * regval = SFIELD(regval, <NAME>, 1); + * W_REG(osh, ®s->regfoo, regval); + */ +#define BITFIELD_MASK(width) \ + (((unsigned)1 << (width)) - 1) +#define GFIELD(val, field) \ + (((val) >> field ## _S) & field ## _M) +#define SFIELD(val, field, bits) \ + (((val) & (~(field ## _M << field ## _S))) | \ + ((unsigned)(bits) << field ## _S)) + /* For managing scan result lists */ struct wlc_bss_list { uint count; @@ -136,7 +168,7 @@ extern const u8 prio2fifo[]; #define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ #define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ -/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ +/* Per-AC retry limit register definitions; uses defs.h bitfield macros */ #define EDCF_SHORT_S 0 #define EDCF_SFB_S 4 #define EDCF_LONG_S 8 @@ -146,6 +178,8 @@ extern const u8 prio2fifo[]; #define EDCF_LONG_M BITFIELD_MASK(4) #define EDCF_LFB_M BITFIELD_MASK(4) +#define NFIFO 6 /* # tx/rx fifopairs */ + #define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) #define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) #define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) @@ -208,19 +242,6 @@ struct wlc_protection { s8 nongf_override; /* override for use of GF protection */ s8 n_pam_override; /* override for preamble: MM or GF */ bool n_obss; /* indicated OBSS Non-HT STA present */ - - uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ - uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ - /* only is gone */ - uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ - uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ - uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ - uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ - uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ - uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ - uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ - uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ - uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ }; /* anything affects the single/dual streams/antenna operation */ @@ -276,6 +297,49 @@ struct wlc_stf { #define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ #define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ +/* Maximum # of keys that wl driver supports in S/W. + * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. + */ +#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ +#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ + +/* +* Max # of keys currently supported: +* +* s/w keys if WSEC_SW(wlc->wsec). +* h/w keys otherwise. +*/ +#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS + +/* number of 802.11 default (non-paired, group keys) */ +#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ + +typedef struct wsec_iv { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ +} wsec_iv_t; + +#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ + +typedef struct wsec_key { + u8 ea[ETH_ALEN]; /* per station */ + u8 idx; /* key index in wsec_keys array */ + u8 id; /* key ID [0-3] */ + u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u8 rcmta; /* rcmta entry index, same as idx by default */ + u16 flags; /* misc flags */ + u8 algo_hw; /* cache for hw register */ + u8 aes_mode; /* cache for hw register */ + s8 iv_len; /* IV length */ + s8 icv_len; /* ICV length */ + u32 len; /* key length..don't move this var */ + /* data is 4byte aligned */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ + wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ + wsec_iv_t txiv; /* Tx IV */ + +} wsec_key_t; + /* * core state (mac) */ @@ -303,7 +367,7 @@ struct wlcband { wlc_phy_t *pi; /* pointer to phy specific information */ bool abgphy_encore; - u8 gmode; /* currently active gmode (see wlioctl.h) */ + u8 gmode; /* currently active gmode */ struct scb *hwrs_scb; /* permanent scb for hw rateset */ @@ -336,7 +400,7 @@ struct pkt_cb { /* module control blocks */ struct modulecb { char name[32]; /* module name : NULL indicates empty array member */ - const bcm_iovar_t *iovars; /* iovar table */ + const struct brcmu_iovar *iovars; /* iovar table */ void *hdl; /* handle passed when handler 'doiovar' is called */ watchdog_fn_t watchdog_fn; /* watchdog handler */ iovar_fn_t iovar_fn; /* iovar handler */ @@ -355,6 +419,24 @@ struct dumpcb_s { struct dumpcb_s *next; }; +struct edcf_acparam { + u8 ACI; + u8 ECW; + u16 TXOP; +} __attribute__((packed)); +typedef struct edcf_acparam edcf_acparam_t; + +struct wme_param_ie { + u8 oui[3]; + u8 type; + u8 subtype; + u8 version; + u8 qosinfo; + u8 rsvd; + edcf_acparam_t acparam[AC_COUNT]; +} __attribute__((packed)); +typedef struct wme_param_ie wme_param_ie_t; + /* virtual interface */ struct wlc_if { struct wlc_if *next; @@ -364,7 +446,7 @@ struct wlc_if { * AID2PVBMAP(scb). */ u8 flags; /* flags for the interface */ - struct wl_if *wlif; /* pointer to wlif */ + struct brcms_if *wlif; /* pointer to wlif */ struct wlc_txq_info *qi; /* pointer to associated tx queue */ union { struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ @@ -372,8 +454,8 @@ struct wlc_if { } u; }; -/* flags for the interface */ -#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ +/* flags for the interface, this interface is linked to a brcms_if */ +#define WLC_IF_LINKED 0x02 struct wlc_hwband { int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ @@ -397,7 +479,7 @@ struct wlc_hw_info { struct wlc_info *wlc; /* fifo */ - struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ + struct dma_pub *di[NFIFO]; /* dma handles, per fifo */ uint unit; /* device instance number */ @@ -413,7 +495,7 @@ struct wlc_hw_info { u32 machwcap_backup; /* backup of machwcap */ u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ - si_t *sih; /* SB handle (cookie for siutils calls) */ + struct si_pub *sih; /* SI handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ uint vars_size; /* size of vars, free vars on detach */ d11regs_t *regs; /* pointer to device registers */ @@ -484,7 +566,7 @@ struct wlc_txq_info { */ struct wlc_info { struct wlc_pub *pub; /* pointer to wlc public state */ - struct wl_info *wl; /* pointer to os-specific private state */ + struct brcms_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ @@ -528,8 +610,6 @@ struct wlc_info { struct antsel_info *asi; /* antsel module handler */ wlc_cm_info_t *cmi; /* channel manager module handler */ - void *btparam; /* bus type specific cookie */ - uint vars_size; /* size of vars, free vars on detach */ u16 vendorid; /* PCI vendor id */ @@ -544,7 +624,6 @@ struct wlc_info { bool bandinit_pending; /* track band init in auto band */ bool radio_monitor; /* radio timer is running */ - bool down_override; /* true=down */ bool going_down; /* down path intermediate variable */ bool mpc; /* enable minimum power consumption */ @@ -553,16 +632,10 @@ struct wlc_info { u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ - /* timer */ - struct wl_timer *wdtimer; /* timer for watchdog routine */ - uint fast_timer; /* Periodic timeout for 'fast' timer */ - uint slow_timer; /* Periodic timeout for 'slow' timer */ - uint glacial_timer; /* Periodic timeout for 'glacial' timer */ - uint phycal_mlo; /* last time measurelow calibration was done */ - uint phycal_txpower; /* last time txpower calibration was done */ - - struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ - struct wl_timer *pspoll_timer; /* periodic pspoll timer */ + /* timer for watchdog routine */ + struct brcms_timer *wdtimer; + /* timer for hw radio button monitor routine */ + struct brcms_timer *radio_timer; /* promiscuous */ bool monitor; /* monitor (MPDU sniffing) mode */ @@ -570,30 +643,11 @@ struct wlc_info { bool bcnmisc_scan; /* bcns promisc mode override for scan */ bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ - u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ - /* driver feature */ bool _rifs; /* enable per-packet rifs */ - s32 rifs_advert; /* RIFS mode advertisement */ s8 sgi_tx; /* sgi tx */ - bool wet; /* true if wireless ethernet bridging mode */ /* AP-STA synchronization, power save */ - bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ - bool PM_override; /* no power-save flag, override PM(user input) */ - bool PMenabled; /* current power-management state (CAM or PS) */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool PMblocked; /* block any PSPolling in PS mode, used to buffer - * AP traffic, also used to indicate in progress - * of scan, rm, etc. off home channel activity. - */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - u8 PM; /* power-management mode (CAM, PS or FASTPS) */ - bool PMawakebcn; /* bcn recvd during current waking state */ - - bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ - bool wake; /* host-specified PS-mode sleep state */ - u8 pspoll_prd; /* pspoll interval in milliseconds */ u8 bcn_li_bcn; /* beacon listen interval in # beacons */ u8 bcn_li_dtim; /* beacon listen interval in # dtims */ @@ -602,18 +656,14 @@ struct wlc_info { /* WME */ ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - bool wme_apsd; /* enable Advanced Power Save Delivery */ - ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA * contains parameters in use locally, and on * AP contains parameters advertised to STA * in beacons and assoc responses. */ - bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ - int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ u16 tx_prec_map; /* Precedence map based on HW FIFO space */ u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ @@ -623,10 +673,6 @@ struct wlc_info { */ struct wlc_bsscfg *bsscfg[WLC_MAXBSSCFG]; struct wlc_bsscfg *cfg; /* the primary bsscfg (can be AP or STA) */ - u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ - u8 aps_associated; /* count of UP AP bsscfgs */ - u8 block_datafifo; /* prohibit posting frames to data fifos */ - bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ /* tx queue */ struct wlc_txq_info *tx_queues; /* common TX Queue list */ @@ -638,43 +684,24 @@ struct wlc_info { * treated as sw keys (used for debugging) */ struct modulecb *modulecb; - struct dumpcb_s *dumpcb_head; u8 mimoft; /* SIGN or 11N */ - u8 mimo_band_bwcap; /* bw cap per band type */ - s8 txburst_limit_override; /* tx burst limit override */ - u16 txburst_limit; /* tx burst limit value */ s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ /* HT CAP IE being advertised by this node: */ struct ieee80211_ht_cap ht_cap; - uint seckeys; /* 54 key table shm address */ - uint tkmickeys; /* 12 TKIP MIC key table shm address */ - wlc_bss_info_t *default_bss; /* configured BSS parameters */ - u16 AID; /* association ID */ - u16 counter; /* per-sdu monotonically increasing counter */ u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ - bool ibss_allowed; /* false, all IBSS will be ignored during a scan - * and the driver will not allow the creation of - * an IBSS network - */ - bool ibss_coalesce_allowed; - char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d * auto-country mode */ char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d * auto-country mode */ -#ifdef BCMDBG - bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ -#endif - u16 prb_resp_timeout; /* do not send prb resp if request older than this, * 0 = disable */ @@ -696,44 +723,17 @@ struct wlc_info { u16 LFBL; /* Long Frame Rate Fallback Limit */ /* network config */ - bool shortpreamble; /* currently operating with CCK ShortPreambles */ bool shortslot; /* currently using 11g ShortSlot timing */ - s8 barker_preamble; /* current Barker Preamble Mode */ s8 shortslot_override; /* 11g ShortSlot override */ bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ - bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ - bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ - bool legacy_probe; /* restricts probe requests to CCK rates */ struct wlc_protection *protection; s8 PLCPHdr_override; /* 802.11b Preamble Type override */ struct wlc_stf *stf; - struct pkt_cb *pkt_callback; /* tx completion callback handlers */ - - u32 txretried; /* tx retried number in one msdu */ - ratespec_t bcn_rspec; /* save bcn ratespec purpose */ - bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ - struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ - u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) - * 0 == disable - */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Access Category in which APSD Null - * Trigger frames can be send - */ - u8 htphy_membership; /* HT PHY membership */ - - bool _regulatory_domain; /* 802.11d enabled? */ - - u8 mimops_PM; - - u8 txpwr_percent; /* power output percentage */ - - u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ - uint tempsense_lasttime; u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ @@ -741,7 +741,6 @@ struct wlc_info { u16 next_bsscfg_ID; - struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ 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 @@ -749,8 +748,6 @@ struct wlc_info { u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last * time */ - bool pr80838_war; - uint hwrxoff; struct wiphy *wiphy; }; @@ -767,6 +764,84 @@ struct antsel_info { wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ }; +/* BSS configuration state */ +struct wlc_bsscfg { + struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ + bool up; /* is this configuration up operational */ + bool enable; /* is this configuration enabled */ + bool associated; /* is BSS in ASSOCIATED state */ + bool BSS; /* infraustructure or adhac */ + bool dtim_programmed; + + u8 SSID_len; /* the length of SSID */ + u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ + struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ + s8 _idx; /* the index of this bsscfg, + * assigned at wlc_bsscfg_alloc() + */ + /* MAC filter */ + uint nmac; /* # of entries on maclist array */ + int macmode; /* allow/deny stations on maclist array */ + struct ether_addr *maclist; /* list of source MAC addrs to match */ + + /* security */ + u32 wsec; /* wireless security bitvec */ + s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ + s16 openshared; /* try Open auth first, then Shared Key */ + bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ + bool eap_restrict; /* restrict data until 802.1X auth succeeds */ + u16 WPA_auth; /* WPA: authenticated key management */ + bool wpa2_preauth; /* default is true, wpa_cap sets value */ + bool wsec_portopen; /* indicates keys are plumbed */ + wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ + int wsec_index; /* 0-3: default tx key, -1: not set */ + wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + + /* TKIP countermeasures */ + bool tkip_countermeasures; /* flags TKIP no-assoc period */ + u32 tk_cm_dt; /* detect timer */ + u32 tk_cm_bt; /* blocking timer */ + u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ + bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ + + u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ + u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ + u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ + u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ + + u32 flags; /* WLC_BSSCFG flags; see below */ + + u8 *bcn; /* AP beacon */ + uint bcn_len; /* AP beacon length */ + bool ar_disassoc; /* disassociated in associated recreation */ + + int auth_atmptd; /* auth type (open/shared) attempted */ + + pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ + uint npmkid_cand; /* num PMKID candidates */ + pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ + uint npmkid; /* num cached PMKIDs */ + + wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ + + /* PM states */ + bool PMawakebcn; /* bcn recvd during current waking state */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool priorPMstate; /* Detecting PM state transitions */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + + /* BSSID entry in RCMTA, use the wsec key management infrastructure to + * manage the RCMTA entries. + */ + wsec_key_t *rcmta; + + /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ + u16 ID; + + uint txrspecidx; /* index into tx rate circular buffer */ + ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ +}; + #define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) #define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) @@ -784,7 +859,7 @@ struct antsel_info { #define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) #define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) #define GETNEXTTXP(wlc, _queue) \ - dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) + dma_getnexttxp((wlc)->hw->di[(_queue)], DMA_RANGE_TRANSMITTED) #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) @@ -805,8 +880,6 @@ 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); -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_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); extern void wlc_reset_bmac_done(struct wlc_info *wlc); @@ -862,8 +935,8 @@ extern void wlc_inval_dma_pkts(struct wlc_hw_info *hw, void (*dma_callback_fn)); #if defined(BCMDBG) -extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, - struct bcmstrbuf *b); +extern void wlc_dump_ie(struct wlc_info *wlc, struct brcmu_tlv *ie, + struct brcmu_strbuf *b); #endif extern void wlc_reprate_init(struct wlc_info *wlc); @@ -900,12 +973,6 @@ extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); extern bool wlc_timers_init(struct wlc_info *wlc, int unit); -extern const bcm_iovar_t wlc_iovars[]; - -extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, - int len, int val_size, struct wlc_if *wlcif); - #if defined(BCMDBG) extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); #endif @@ -928,12 +995,9 @@ extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs); 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_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); -#endif /* _wlc_h_ */ +#endif /* _BRCM_MAIN_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c index 18b844a8d2fb..ca781c445a86 100644 --- a/drivers/staging/brcm80211/brcmsmac/nicpci.c +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.c @@ -17,17 +17,170 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <bcmnvram.h> +#include <defs.h> +#include "types.h" +#include <brcmu_utils.h> #include <aiutils.h> -#include <hndsoc.h> -#include <bcmdevs.h> -#include <sbchipc.h> -#include <pci_core.h> -#include <pcie_core.h> +#include <soc.h> +#include <brcm_hw_ids.h> +#include <chipcommon.h> +#include <scb.h> +#include <pub.h> #include <nicpci.h> -#include <pcicfg.h> + +/* SPROM offsets */ +#define SRSH_ASPM_OFFSET 4 /* word 4 */ +#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */ +#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */ +#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */ + +#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */ +#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */ +#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */ +#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */ +#define SRSH_BD_OFFSET 6 /* word 6 */ + +/* chipcontrol */ +#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */ + +/* MDIO control */ +#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ +#define MDIOCTL_DIVISOR_VAL 0x2 +#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ +#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ + +/* MDIO Data */ +#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ +#define MDIODATA_TA 0x00020000 /* Turnaround */ +#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */ +#define MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */ +#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */ +#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */ +#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ +#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */ +#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */ +#define MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */ +#define MDIODATA_WRITE 0x10000000 /* write Transaction */ +#define MDIODATA_READ 0x20000000 /* Read Transaction */ +#define MDIODATA_START 0x40000000 /* start of Transaction */ + +#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */ +#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */ + +/* serdes regs (rev < 10) */ +#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ +#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ +#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ + + /* SERDES RX registers */ +#define SERDES_RX_CTRL 1 /* Rx cntrl */ +#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ +#define SERDES_RX_CDR 6 /* CDR */ +#define SERDES_RX_CDRBW 7 /* CDR BW */ + /* SERDES RX control register */ +#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */ +#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */ + + /* SERDES PLL registers */ +#define SERDES_PLL_CTRL 1 /* PLL control reg */ +#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */ + +/* Linkcontrol reg offset in PCIE Cap */ +#define PCIE_CAP_LINKCTRL_OFFSET 16 /* linkctrl offset in pcie cap */ +#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */ +#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */ +#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */ + +#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */ + +/* Power management threshold */ +#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */ +#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */ +#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */ +#define PCIE_ASPMTIMER_EXTEND 0x01000000 /* > rev7: enable extend ASPM timer */ + +/* different register spaces to access thr'u pcie indirect access */ +#define PCIE_CONFIGREGS 1 /* Access to config space */ +#define PCIE_PCIEREGS 2 /* Access to pcie registers */ + +/* PCIE protocol PHY diagnostic registers */ +#define PCIE_PLP_STATUSREG 0x204 /* Status */ + +/* Status reg PCIE_PLP_STATUSREG */ +#define PCIE_PLP_POLARITYINV_STAT 0x10 + +/* PCIE protocol DLLP diagnostic registers */ +#define PCIE_DLLP_LCREG 0x100 /* Link Control */ +#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ + +/* PCIE protocol TLP diagnostic registers */ +#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ + +/* Sonics side: PCI core and host control registers */ +struct sbpciregs { + u32 control; /* PCI control */ + u32 PAD[3]; + u32 arbcontrol; /* PCI arbiter control */ + u32 clkrun; /* Clkrun Control (>=rev11) */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status */ + u32 intmask; /* Interrupt mask */ + u32 sbtopcimailbox; /* Sonics to PCI mailbox */ + u32 PAD[9]; + u32 bcastaddr; /* Sonics broadcast address */ + u32 bcastdata; /* Sonics broadcast data */ + u32 PAD[2]; + u32 gpioin; /* ro: gpio input (>=rev2) */ + u32 gpioout; /* rw: gpio output (>=rev2) */ + u32 gpioouten; /* rw: gpio output enable (>= rev2) */ + u32 gpiocontrol; /* rw: gpio control (>= rev2) */ + u32 PAD[36]; + u32 sbtopci0; /* Sonics to PCI translation 0 */ + u32 sbtopci1; /* Sonics to PCI translation 1 */ + u32 sbtopci2; /* Sonics to PCI translation 2 */ + u32 PAD[189]; + u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ + u16 sprom[36]; /* SPROM shadow Area */ + u32 PAD[46]; +}; + +/* SB side: PCIE core and host control registers */ +typedef struct sbpcieregs { + u32 control; /* host mode only */ + u32 PAD[2]; + u32 biststatus; /* bist Status: 0x00C */ + u32 gpiosel; /* PCIE gpio sel: 0x010 */ + u32 gpioouten; /* PCIE gpio outen: 0x14 */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status: 0x20 */ + u32 intmask; /* Interrupt mask: 0x24 */ + u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */ + u32 PAD[53]; + u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ + u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ + u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ + u32 PAD[5]; + + /* pcie core supports in direct access to config space */ + u32 configaddr; /* pcie config space access: Address field: 0x120 */ + u32 configdata; /* pcie config space access: Data field: 0x124 */ + + /* mdio access to serdes */ + u32 mdiocontrol; /* controls the mdio access: 0x128 */ + u32 mdiodata; /* Data to the mdio access: 0x12c */ + + /* pcie protocol phy/dllp/tlp register indirect access mechanism */ + u32 pcieindaddr; /* indirect access to the internal register: 0x130 */ + u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */ + + u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */ + u32 PAD[177]; + u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */ + u16 sprom[64]; /* SPROM shadow Area */ +} sbpcieregs_t; typedef struct { union { @@ -35,7 +188,7 @@ typedef struct { struct sbpciregs *pciregs; } regs; /* Memory mapped register to the core */ - si_t *sih; /* System interconnect handle */ + struct si_pub *sih; /* System interconnect handle */ struct pci_dev *dev; u8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ bool pcie_pr42767; @@ -69,8 +222,6 @@ static void pcie_war_noplldown(pcicore_info_t *pi); static void pcie_war_polarity(pcicore_info_t *pi); static void pcie_war_pci_setup(pcicore_info_t *pi); -static bool pcicore_pmecap(pcicore_info_t *pi); - #define PCIE_ASPM(sih) ((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5))) @@ -80,7 +231,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi); /* Initialize the PCI core. It's caller's responsibility to make sure that this is done * only once */ -void *pcicore_init(si_t *sih, void *pdev, void *regs) +void *pcicore_init(struct si_pub *sih, void *pdev, void *regs) { pcicore_info_t *pi; @@ -178,7 +329,7 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, } /* ***** Register Access API */ -uint +static uint pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, uint offset) { @@ -202,7 +353,7 @@ pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, return retval; } -uint +static uint pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val) { @@ -327,7 +478,7 @@ pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val) } /* ***** Support functions ***** */ -u8 pcie_clkreq(void *pch, u32 mask, u32 val) +static u8 pcie_clkreq(void *pch, u32 mask, u32 val) { pcicore_info_t *pi = (pcicore_info_t *) pch; u32 reg_val; @@ -356,7 +507,7 @@ u8 pcie_clkreq(void *pch, u32 mask, u32 val) static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) { u32 w; - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; sbpcieregs_t *pcieregs = pi->regs.pcieregs; if (!PCIE_PUB(sih) || sih->buscorerev < 7) @@ -374,7 +525,7 @@ static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) /* centralized clkreq control policy */ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) { - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; switch (state) { case SI_DOATTACH: @@ -440,7 +591,7 @@ static void pcie_war_polarity(pcicore_info_t *pi) static void pcie_war_aspm_clkreq(pcicore_info_t *pi) { sbpcieregs_t *pcieregs = pi->regs.pcieregs; - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; u16 val16, *reg16; u32 w; @@ -535,7 +686,7 @@ static void pcie_war_noplldown(pcicore_info_t *pi) /* Needs to happen when coming out of 'standby'/'hibernate' */ static void pcie_war_pci_setup(pcicore_info_t *pi) { - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; sbpcieregs_t *pcieregs = pi->regs.pcieregs; u32 w; @@ -577,28 +728,11 @@ static void pcie_war_pci_setup(pcicore_info_t *pi) pcie_misc_config_fixup(pi); } -void pcie_war_ovr_aspm_update(void *pch, u8 aspm) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - - if (!PCIE_ASPM(pi->sih)) - return; - - /* Validate */ - if (aspm > PCIE_ASPM_ENAB) - return; - - pi->pcie_war_aspm_ovr = aspm; - - /* Update the current state */ - pcie_war_aspm_clkreq(pi); -} - /* ***** Functions called during driver state changes ***** */ void pcicore_attach(void *pch, char *pvars, int state) { pcicore_info_t *pi = (pcicore_info_t *) pch; - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; /* Determine if this board needs override */ if (PCIE_ASPM(sih)) { @@ -672,165 +806,52 @@ void pcicore_down(void *pch, int state) pcie_extendL1timer(pi, false); } -/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */ -/* Just uses PCI config accesses to find out, when needed before sb_attach is done */ -bool pcicore_pmecap_fast(void *pch) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u8 cap_ptr; - u32 pmecap; - - 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 & (PCI_PM_CAP_PME_MASK << 16)) != 0; -} - -/* return true if PM capability exists in the pci config space - * Uses and caches the information using core handle - */ -static bool pcicore_pmecap(pcicore_info_t *pi) -{ - u8 cap_ptr; - u32 pmecap; - - if (!pi->pmecap_offset) { - cap_ptr = pcicore_find_pci_capability(pi->dev, - PCI_CAP_ID_PM, - NULL, NULL); - if (!cap_ptr) - return false; - - pi->pmecap_offset = cap_ptr; - - pci_read_config_dword(pi->dev, pi->pmecap_offset, - &pmecap); - - /* At least one state can generate PME */ - pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0; - } - - return pi->pmecap; -} - -/* Enable PME generation */ -void pcicore_pmeen(void *pch) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u32 w; - - /* if not pmecapable return */ - if (!pcicore_pmecap(pi)) - return; - - pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, - &w); - w |= (PCI_PM_CTRL_PME_ENABLE); - pci_write_config_dword(pi->dev, - pi->pmecap_offset + PCI_PM_CTRL, w); -} - /* - * Return true if PME status set + * precondition: current core is sii->buscoretype */ -bool pcicore_pmestat(void *pch) +void pcicore_fixcfg(void *pch, void *regs) { pcicore_info_t *pi = (pcicore_info_t *) pch; - u32 w; - - if (!pcicore_pmecap(pi)) - return false; - - pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, - &w); - - return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS; + struct si_info *sii = SI_INFO(pi->sih); + struct sbpciregs *pciregs = regs; + sbpcieregs_t *pcieregs = regs; + u16 val16, *reg16 = NULL; + uint pciidx; + + /* check 'pi' is correct and fix it if not */ + if (sii->pub.buscoretype == PCIE_CORE_ID) { + reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; + } else if (sii->pub.buscoretype == PCI_CORE_ID) { + reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; + } + pciidx = ai_coreidx(&sii->pub); + val16 = R_REG(reg16); + if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { + val16 = + (u16) (pciidx << SRSH_PI_SHIFT) | (val16 & + ~SRSH_PI_MASK); + W_REG(reg16, val16); + } } -/* Disable PME generation, clear the PME status bit if set +/* + * precondition: current core is pci core */ -void pcicore_pmeclr(void *pch) +void pcicore_pci_setup(void *pch, void *regs) { pcicore_info_t *pi = (pcicore_info_t *) pch; + struct sbpciregs *pciregs = regs; u32 w; - if (!pcicore_pmecap(pi)) - return; - - 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 &= ~(PCI_PM_CTRL_PME_ENABLE); - - pci_write_config_dword(pi->dev, - pi->pmecap_offset + PCI_PM_CTRL, w); -} - -u32 pcie_lcreg(void *pch, u32 mask, u32 val) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u8 offset; - u32 tmpval; - - offset = pi->pciecap_lcreg_offset; - if (!offset) - return 0; + OR_REG(&pciregs->sbtopci2, + (SBTOPCI_PREF | SBTOPCI_BURST)); - /* set operation */ - if (mask) - pci_write_config_dword(pi->dev, offset, val); - - pci_read_config_dword(pi->dev, offset, &tmpval); - return tmpval; -} - -u32 -pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type) -{ - u32 reg_val = 0; - pcicore_info_t *pi = (pcicore_info_t *) pch; - sbpcieregs_t *pcieregs = pi->regs.pcieregs; - - if (mask) { - PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val)); - pcie_writereg(pcieregs, type, offset, val); + if (SI_INFO(pi->sih)->pub.buscorerev >= 11) { + OR_REG(&pciregs->sbtopci2, + SBTOPCI_RC_READMULTI); + w = R_REG(&pciregs->clkrun); + W_REG(&pciregs->clkrun, + (w | PCI_CLKRUN_DSBL)); + w = R_REG(&pciregs->clkrun); } - - /* Should not read register 0x154 */ - if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11 - && type == PCIE_PCIEREGS) - return reg_val; - - reg_val = pcie_readreg(pcieregs, type, offset); - PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val)); - - return reg_val; -} - -u32 -pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask, - u32 val) -{ - u32 reg_val = 0; - pcicore_info_t *pi = (pcicore_info_t *) pch; - - if (mask) { - PCI_ERROR(("PCIEMDIOREG: 0x%x writeval 0x%x\n", offset, val)); - pcie_mdiowrite(pi, mdioslave, offset, val); - } - - if (pcie_mdioread(pi, mdioslave, offset, ®_val)) - reg_val = 0xFFFFFFFF; - PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave, - offset, reg_val)); - - return reg_val; } diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.h b/drivers/staging/brcm80211/brcmsmac/nicpci.h new file mode 100644 index 000000000000..c44b70512c4f --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.h @@ -0,0 +1,85 @@ +/* + * 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 _BRCM_NICPCI_H_ +#define _BRCM_NICPCI_H_ + +/* PCI configuration address space size */ +#define PCI_SZPCR 256 + +/* Brcm PCI configuration registers */ +/* backplane address space accessed by BAR0 */ +#define PCI_BAR0_WIN 0x80 +/* sprom property control */ +#define PCI_SPROM_CONTROL 0x88 +/* mask of PCI and other cores interrupts */ +#define PCI_INT_MASK 0x94 +/* backplane core interrupt mask bits offset */ +#define PCI_SBIM_SHIFT 8 +/* backplane address space accessed by second 4KB of BAR0 */ +#define PCI_BAR0_WIN2 0xac +/* pci config space gpio input (>=rev3) */ +#define PCI_GPIO_IN 0xb0 +/* pci config space gpio output (>=rev3) */ +#define PCI_GPIO_OUT 0xb4 +/* pci config space gpio output enable (>=rev3) */ +#define PCI_GPIO_OUTEN 0xb8 + +/* bar0 + 4K accesses external sprom */ +#define PCI_BAR0_SPROM_OFFSET (4 * 1024) +/* bar0 + 6K accesses pci core registers */ +#define PCI_BAR0_PCIREGS_OFFSET (6 * 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_PCISBR_OFFSET (4 * 1024) +/* bar0 window size Match with corerev 13 */ +#define PCI_BAR0_WINSZ (16 * 1024) +/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ +/* bar0 + 8K accesses pci/pcie core registers */ +#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) +/* bar0 + 12K accesses chipc core registers */ +#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) + +#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ + +/* Sonics to PCI translation types */ +#define SBTOPCI_PREF 0x4 /* prefetch enable */ +#define SBTOPCI_BURST 0x8 /* burst enable */ +#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + +/* PCI core index in SROM shadow area */ +#define SRSH_PI_OFFSET 0 /* first word */ +#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ +#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + +struct si_pub; + +extern void *pcicore_init(struct si_pub *sih, void *pdev, void *regs); +extern void pcicore_deinit(void *pch); +extern void pcicore_attach(void *pch, char *pvars, int state); +extern void pcicore_hwup(void *pch); +extern void pcicore_up(void *pch, int state); +extern void pcicore_sleep(void *pch); +extern void pcicore_down(void *pch, int state); +extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id, + unsigned char *buf, u32 *buflen); +extern void pcicore_fixcfg(void *pch, void *regs); +extern void pcicore_pci_setup(void *pch, void *regs); + +#endif /* _BRCM_NICPCI_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/nvram.c b/drivers/staging/brcm80211/brcmsmac/nvram.c deleted file mode 100644 index 085ec0b9224f..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/nvram.c +++ /dev/null @@ -1,215 +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/slab.h> -#include <linux/string.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <bcmnvram.h> -#include <sbchipc.h> -#include <bcmdevs.h> -#include <hndsoc.h> - -#define NVR_MSG(x) - -typedef struct _vars { - struct _vars *next; - int bufsz; /* allocated size */ - int size; /* actual vars size */ - char *vars; -} vars_t; - -#define VARS_T_OH sizeof(vars_t) - -static vars_t *vars; - -#define NVRAM_FILE 1 - -static char *findvar(char *vars, char *lim, const char *name); - -int nvram_init(void) -{ - - /* Make sure we read nvram in flash just once before freeing the memory */ - if (vars != NULL) { - NVR_MSG(("nvram_init: called again without calling nvram_exit()\n")); - return 0; - } - return 0; -} - -int nvram_append(char *varlst, uint varsz) -{ - uint bufsz = VARS_T_OH; - vars_t *new; - - new = kmalloc(bufsz, GFP_ATOMIC); - if (new == NULL) - return -ENOMEM; - - new->vars = varlst; - new->bufsz = bufsz; - new->size = varsz; - new->next = vars; - vars = new; - - return 0; -} - -void nvram_exit(void) -{ - vars_t *this, *next; - - this = vars; - if (this) - kfree(this->vars); - - while (this) { - next = this->next; - kfree(this); - this = next; - } - vars = NULL; -} - -static char *findvar(char *vars, char *lim, const char *name) -{ - char *s; - int len; - - len = strlen(name); - - for (s = vars; (s < lim) && *s;) { - if ((memcmp(s, name, len) == 0) && (s[len] == '=')) - return &s[len + 1]; - - while (*s++) - ; - } - - 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; - vars_t *cur; - - for (cur = vars; cur; cur = cur->next) { - v = findvar(cur->vars, cur->vars + cur->size, name); - if (v) - break; - } - - return v; -} - -int nvram_set(const char *name, const char *value) -{ - return 0; -} - -int nvram_unset(const char *name) -{ - return 0; -} - -int nvram_reset(void) -{ - return 0; -} - -int nvram_commit(void) -{ - return 0; -} - -int nvram_getall(char *buf, int count) -{ - int len, resid = count; - vars_t *this; - - this = vars; - while (this) { - char *from, *lim, *to; - int acc; - - from = this->vars; - lim = (char *)(this->vars + this->size); - to = buf; - acc = 0; - while ((from < lim) && (*from)) { - len = strlen(from) + 1; - if (resid < (acc + len)) - return -EOVERFLOW; - memcpy(to, from, len); - acc += len; - from += len; - to += len; - } - - resid -= acc; - buf += acc; - this = this->next; - } - if (resid < 1) - return -EOVERFLOW; - *buf = '\0'; - return 0; -} diff --git a/drivers/staging/brcm80211/brcmsmac/bcmotp.c b/drivers/staging/brcm80211/brcmsmac/otp.c index d09628b5a88e..d21d6cadb9d2 100644 --- a/drivers/staging/brcm80211/brcmsmac/bcmotp.c +++ b/drivers/staging/brcm80211/brcmsmac/otp.c @@ -21,46 +21,58 @@ #include <linux/pci.h> #include <linux/crc-ccitt.h> -#include <bcmdefs.h> -#include <bcmdevs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcm_hw_ids.h> +#include "types.h" +#include <brcmu_utils.h> #include <aiutils.h> -#include <hndsoc.h> -#include <sbchipc.h> -#include <bcmotp.h> +#include <soc.h> +#include <chipcommon.h> +#include "otp.h" + +#define OTPS_GUP_MASK 0x00000f00 +#define OTPS_GUP_SHIFT 8 +#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ +#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ +#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ +#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ + +/* Fields in otpprog in rev >= 21 */ +#define OTPP_COL_MASK 0x000000ff +#define OTPP_COL_SHIFT 0 +#define OTPP_ROW_MASK 0x0000ff00 +#define OTPP_ROW_SHIFT 8 +#define OTPP_OC_MASK 0x0f000000 +#define OTPP_OC_SHIFT 24 +#define OTPP_READERR 0x10000000 +#define OTPP_VALUE_MASK 0x20000000 +#define OTPP_VALUE_SHIFT 29 +#define OTPP_START_BUSY 0x80000000 +#define OTPP_READ 0x40000000 + +/* Opcodes for OTPP_OC field */ +#define OTPPOC_READ 0 +#define OTPPOC_BIT_PROG 1 +#define OTPPOC_VERIFY 3 +#define OTPPOC_INIT 4 +#define OTPPOC_SET 5 +#define OTPPOC_RESET 6 +#define OTPPOC_OCST 7 +#define OTPPOC_ROW_LOCK 8 +#define OTPPOC_PRESCN_TEST 9 -/* - * There are two different OTP controllers so far: - * 1. new IPX OTP controller: chipc 21, >=23 - * 2. older HND OTP controller: chipc 12, 17, 22 - * - * Define BCMHNDOTP to include support for the HND OTP controller. - * Define BCMIPXOTP to include support for the IPX OTP controller. - * - * NOTE 1: More than one may be defined - * NOTE 2: If none are defined, the default is to include them all. - */ - -#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP) -#define BCMHNDOTP 1 -#define BCMIPXOTP 1 -#endif - -#define OTPTYPE_HND(ccrev) ((ccrev) < 21 || (ccrev) == 22) #define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23) #define OTPP_TRIES 10000000 /* # of tries for OTPP */ -#ifdef BCMIPXOTP #define MAXNUMRDES 9 /* Maximum OTP redundancy entries */ -#endif /* OTP common function type */ typedef int (*otp_status_t) (void *oh); typedef int (*otp_size_t) (void *oh); -typedef void *(*otp_init_t) (si_t *sih); +typedef void *(*otp_init_t) (struct si_pub *sih); typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off); -typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data, +typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data, uint *wlen); typedef int (*otp_nvread_t) (void *oh, char *data, uint *len); @@ -77,9 +89,8 @@ typedef struct otp_fn_s { typedef struct { uint ccrev; /* chipc revision */ otp_fn_t *fn; /* OTP functions */ - si_t *sih; /* Saved sb handle */ + struct si_pub *sih; /* Saved sb handle */ -#ifdef BCMIPXOTP /* IPX OTP section */ u16 wsize; /* Size of otp in words */ u16 rows; /* Geometry */ @@ -94,15 +105,6 @@ typedef struct { u16 fbase; /* fuse subregion offset */ u16 flim; /* fuse subregion boundary */ int otpgu_base; /* offset to General Use Region */ -#endif /* BCMIPXOTP */ - -#ifdef BCMHNDOTP - /* HND OTP section */ - uint size; /* Size of otp in bytes */ - uint hwprot; /* Hardware protection bits */ - uint signvalid; /* Signature valid bits */ - int boundary; /* hw/sw boundary */ -#endif /* BCMHNDOTP */ } otpinfo_t; static otpinfo_t otpinfo; @@ -120,8 +122,6 @@ static otpinfo_t otpinfo; * */ -#ifdef BCMIPXOTP - #define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w") /* OTP layout */ @@ -214,7 +214,7 @@ static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) /* Calculate max HW/SW region byte size by subtracting fuse region and checksum size, * osizew is oi->wsize (OTP size - GU size) in words */ -static int ipxotp_max_rgnsz(si_t *sih, int osizew) +static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew) { int ret = 0; @@ -304,7 +304,7 @@ static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc) oi->flim = oi->wsize; } -static void *ipxotp_init(si_t *sih) +static void *ipxotp_init(struct si_pub *sih) { uint idx; chipcregs_t *cc; @@ -466,374 +466,7 @@ static otp_fn_t ipxotp_fn = { (otp_status_t) ipxotp_status }; -#endif /* BCMIPXOTP */ - -/* - * HND OTP Code - * - * Exported functions: - * hndotp_status() - * hndotp_size() - * hndotp_init() - * hndotp_read_bit() - * hndotp_read_region() - * hndotp_nvread() - * - */ - -#ifdef BCMHNDOTP - -/* Fields in otpstatus */ -#define OTPS_PROGFAIL 0x80000000 -#define OTPS_PROTECT 0x00000007 -#define OTPS_HW_PROTECT 0x00000001 -#define OTPS_SW_PROTECT 0x00000002 -#define OTPS_CID_PROTECT 0x00000004 -#define OTPS_RCEV_MSK 0x00003f00 -#define OTPS_RCEV_SHIFT 8 - -/* Fields in the otpcontrol register */ -#define OTPC_RECWAIT 0xff000000 -#define OTPC_PROGWAIT 0x00ffff00 -#define OTPC_PRW_SHIFT 8 -#define OTPC_MAXFAIL 0x00000038 -#define OTPC_VSEL 0x00000006 -#define OTPC_SELVL 0x00000001 - -/* OTP regions (Word offsets from otp size) */ -#define OTP_SWLIM_OFF (-4) -#define OTP_CIDBASE_OFF 0 -#define OTP_CIDLIM_OFF 4 - -/* Predefined OTP words (Word offset from otp size) */ -#define OTP_BOUNDARY_OFF (-4) -#define OTP_HWSIGN_OFF (-3) -#define OTP_SWSIGN_OFF (-2) -#define OTP_CIDSIGN_OFF (-1) -#define OTP_CID_OFF 0 -#define OTP_PKG_OFF 1 -#define OTP_FID_OFF 2 -#define OTP_RSV_OFF 3 -#define OTP_LIM_OFF 4 -#define OTP_RD_OFF 4 /* Redundancy row starts here */ -#define OTP_RC0_OFF 28 /* Redundancy control word 1 */ -#define OTP_RC1_OFF 32 /* Redundancy control word 2 */ -#define OTP_RC_LIM_OFF 36 /* Redundancy control word end */ - -#define OTP_HW_REGION OTPS_HW_PROTECT -#define OTP_SW_REGION OTPS_SW_PROTECT -#define OTP_CID_REGION OTPS_CID_PROTECT - -#if OTP_HW_REGION != OTP_HW_RGN -#error "incompatible OTP_HW_RGN" -#endif -#if OTP_SW_REGION != OTP_SW_RGN -#error "incompatible OTP_SW_RGN" -#endif -#if OTP_CID_REGION != OTP_CI_RGN -#error "incompatible OTP_CI_RGN" -#endif - -/* Redundancy entry definitions */ -#define OTP_RCE_ROW_SZ 6 -#define OTP_RCE_SIGN_MASK 0x7fff -#define OTP_RCE_ROW_MASK 0x3f -#define OTP_RCE_BITS 21 -#define OTP_RCE_SIGN_SZ 15 -#define OTP_RCE_BIT0 1 - -#define OTP_WPR 4 -#define OTP_SIGNATURE 0x578a -#define OTP_MAGIC 0x4e56 - -static int hndotp_status(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)(oi->hwprot | oi->signvalid); -} - -static int hndotp_size(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)(oi->size); -} - -static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) -{ - volatile u16 *ptr; - - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - return R_REG(&ptr[wn]); -} - -static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - volatile u16 *ptr; - - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - - return R_REG(&ptr[(oi->size / 2) + woff]); -} - -static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) -{ - uint k, row, col; - u32 otpp, st; - - row = idx / 65; - col = idx % 65; - - otpp = OTPP_START_BUSY | OTPP_READ | - ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK); - - W_REG(&cc->otpprog, otpp); - st = R_REG(&cc->otpprog); - for (k = 0; - ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES); - k++) - st = R_REG(&cc->otpprog); - - if (k >= OTPP_TRIES) { - return 0xffff; - } - if (st & OTPP_READERR) { - return 0xffff; - } - st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; - return (u16) st; -} - -static void *hndotp_init(si_t *sih) -{ - uint idx; - chipcregs_t *cc; - otpinfo_t *oi; - u32 cap = 0, clkdiv, otpdiv = 0; - void *ret = NULL; - - oi = &otpinfo; - - idx = ai_coreidx(sih); - - /* Check for otp */ - cc = ai_setcoreidx(sih, SI_CC_IDX); - if (cc != NULL) { - cap = R_REG(&cc->capabilities); - if ((cap & CC_CAP_OTPSIZE) == 0) { - /* Nothing there */ - goto out; - } - - if (!((oi->ccrev == 12) || (oi->ccrev == 17) - || (oi->ccrev == 22))) - return NULL; - - /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is - * 8 row (64 bytes) smaller - */ - oi->size = - 1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) - + CC_CAP_OTPSIZE_BASE); - if (oi->ccrev >= 18) - oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2); - - oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT); - oi->boundary = -1; - - /* Check the region signature */ - if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) { - oi->signvalid |= OTP_HW_REGION; - oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF); - } - - if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE) - oi->signvalid |= OTP_SW_REGION; - - if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE) - oi->signvalid |= OTP_CID_REGION; - - /* Set OTP clkdiv for stability */ - if (oi->ccrev == 22) - otpdiv = 12; - - if (otpdiv) { - clkdiv = R_REG(&cc->clkdiv); - clkdiv = - (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT); - W_REG(&cc->clkdiv, clkdiv); - } - udelay(10); - - ret = (void *)oi; - } - - out: /* All done */ - ai_setcoreidx(sih, idx); - - return ret; -} - -static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - u32 idx, st; - chipcregs_t *cc; - int i; - - - 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 -ENODATA; - - *wlen = - ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2; - - 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); - - ai_setcoreidx(oi->sih, idx); - - return 0; -} - -static int hndotp_nvread(void *oh, char *data, uint *len) -{ - int rc = 0; - otpinfo_t *oi = (otpinfo_t *) oh; - u32 base, bound, lim = 0, st; - int i, chunk, gchunks, tsz = 0; - u32 idx; - chipcregs_t *cc; - uint offset; - u16 *rawotp = NULL; - - /* save the orig core */ - 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))) { - rc = -1; - goto out; - } - - /* Read the whole otp so we can easily manipulate it */ - lim = hndotp_size(oh); - rawotp = kmalloc(lim, GFP_ATOMIC); - if (rawotp == NULL) { - rc = -2; - goto out; - } - for (i = 0; i < (int)(lim / 2); i++) - rawotp[i] = hndotp_otpr(oh, cc, i); - - if ((st & OTP_HW_REGION) == 0) { - /* This could be a programming failure in the first - * chunk followed by one or more good chunks - */ - for (i = 0; i < (int)(lim / 2); i++) - if (rawotp[i] == OTP_MAGIC) - break; - - if (i < (int)(lim / 2)) { - base = i; - bound = (i * 2) + rawotp[i + 1]; - } else { - rc = -3; - goto out; - } - } else { - bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF]; - - /* There are two cases: 1) The whole otp is used as nvram - * and 2) There is a hardware header followed by nvram. - */ - if (rawotp[0] == OTP_MAGIC) { - base = 0; - } else - base = bound; - } - - /* Find and copy the data */ - - chunk = 0; - gchunks = 0; - i = base / 2; - offset = 0; - while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) { - int dsz, rsz = rawotp[i + 1]; - - if (((i * 2) + rsz) >= (int)lim) { - /* Bad length, try to find another chunk anyway */ - rsz = 6; - } - if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) == - CRC16_GOOD_VALUE) { - /* Good crc, copy the vars */ - gchunks++; - dsz = rsz - 6; - tsz += dsz; - if (offset + dsz >= *len) { - goto out; - } - memcpy(&data[offset], &rawotp[i + 2], dsz); - offset += dsz; - /* Remove extra null characters at the end */ - while (offset > 1 && - data[offset - 1] == 0 && data[offset - 2] == 0) - offset--; - i += rsz / 2; - } else { - /* bad length or crc didn't check, try to find the next set */ - if (rawotp[i + (rsz / 2)] == OTP_MAGIC) { - /* Assume length is good */ - i += rsz / 2; - } else { - while (++i < (int)(lim / 2)) - if (rawotp[i] == OTP_MAGIC) - break; - } - } - chunk++; - } - - *len = offset; - - out: - kfree(rawotp); - ai_setcoreidx(oi->sih, idx); - - return rc; -} - -static otp_fn_t hndotp_fn = { - (otp_size_t) hndotp_size, - (otp_read_bit_t) hndotp_read_bit, - - (otp_init_t) hndotp_init, - (otp_read_region_t) hndotp_read_region, - (otp_nvread_t) hndotp_nvread, - - (otp_status_t) hndotp_status -}; - -#endif /* BCMHNDOTP */ - /* - * Common Code: Compiled for IPX / HND / AUTO * otp_status() * otp_size() * otp_read_bit() @@ -866,7 +499,7 @@ u16 otp_read_bit(void *oh, uint offset) return readBit; } -void *otp_init(si_t *sih) +void *otp_init(struct si_pub *sih) { otpinfo_t *oi; void *ret = NULL; @@ -876,15 +509,8 @@ void *otp_init(si_t *sih) oi->ccrev = sih->ccrev; -#ifdef BCMIPXOTP if (OTPTYPE_IPX(oi->ccrev)) oi->fn = &ipxotp_fn; -#endif - -#ifdef BCMHNDOTP - if (OTPTYPE_HND(oi->ccrev)) - oi->fn = &hndotp_fn; -#endif if (oi->fn == NULL) { return NULL; @@ -898,7 +524,7 @@ void *otp_init(si_t *sih) } int -otp_read_region(si_t *sih, int region, u16 *data, +otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) { bool wasup = false; void *oh; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/otp.h index df6e04c6ac58..c1eb3477baba 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_types.h +++ b/drivers/staging/brcm80211/brcmsmac/otp.h @@ -14,24 +14,32 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_types_h_ -#define _wlc_types_h_ +#ifndef _BRCM_OTP_H_ +#define _BRCM_OTP_H_ -/* forward declarations */ +/* OTP regions */ +#define OTP_HW_RGN 1 +#define OTP_SW_RGN 2 +#define OTP_CI_RGN 4 +#define OTP_FUSE_RGN 8 +#define OTP_ALL_RGN 0xf /* From h/w region to end of OTP including checksum */ -struct wlc_info; -struct wlc_hw_info; -struct wlc_if; -struct wl_if; -struct ampdu_info; -struct antsel_info; -struct bmac_pmq; +/* OTP Size */ +#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */ -struct d11init; +/* Fixed size subregions sizes in words */ +#define OTPGU_CI_SZ 2 -#ifndef _hnddma_pub_ -#define _hnddma_pub_ -struct hnddma_pub; -#endif /* _hnddma_pub_ */ +/* OTP usage */ +#define OTP4325_FM_DISABLED_OFFSET 188 -#endif /* _wlc_types_h_ */ +/* Exported functions */ +extern int otp_status(void *oh); +extern int otp_size(void *oh); +extern u16 otp_read_bit(void *oh, uint offset); +extern void *otp_init(struct si_pub *sih); +extern int otp_read_region(struct si_pub *sih, int region, u16 *data, + uint *wlen); +extern int otp_nvread(void *oh, char *data, uint *len); + +#endif /* _BRCM_OTP_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c index 6cba4dfbc3dd..0185788c6bd2 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c @@ -14,8 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <wlc_cfg.h> - #include <linux/kernel.h> #include <linux/string.h> #include <linux/bitops.h> @@ -23,16 +21,16 @@ #include <linux/module.h> #include <linux/pci.h> -#include <bcmdefs.h> -#include <bcmnvram.h> -#include <sbchipc.h> -#include <bcmdevs.h> -#include <sbhnddma.h> +#include <defs.h> +#include <chipcommon.h> +#include <brcm_hw_ids.h> +#include <dma.h> -#include <wlc_phy_int.h> -#include <wlc_phyreg_n.h> -#include <wlc_phy_radio.h> -#include <wlc_phy_lcn.h> +#include <types.h> +#include <phy_int.h> +#include <phyreg_n.h> +#include <phy_radio.h> +#include <phy_lcn.h> u32 phyhal_msg_level = PHYHAL_ERROR; @@ -172,7 +170,7 @@ char *phy_getvar(phy_info_t *pi, const char *name) ; } - return nvram_get(name); + return NULL; } int phy_getintvar(phy_info_t *pi, const char *name) @@ -247,16 +245,10 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) if ((D11REV_GE(pi->sh->corerev, 24)) || (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(&pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, addr); data = R_REG(&pi->regs->radioregdata); } else { - W_REG(&pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, addr); #ifdef __ARM_ARCH_4T__ __asm__(" .align 4 "); @@ -281,16 +273,10 @@ void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(&pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, addr); W_REG(&pi->regs->radioregdata, val); } else { - W_REG(&pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, addr); W_REG(&pi->regs->phy4wdatalo, val); } @@ -312,29 +298,17 @@ static u32 read_radio_id(phy_info_t *pi) if (D11REV_GE(pi->sh->corerev, 24)) { u32 b0, b1, b2; - W_REG(&pi->regs->radioregaddr, 0); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 0); b0 = (u32) R_REG(&pi->regs->radioregdata); - W_REG(&pi->regs->radioregaddr, 1); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 1); b1 = (u32) R_REG(&pi->regs->radioregdata); - W_REG(&pi->regs->radioregaddr, 2); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 2); b2 = (u32) R_REG(&pi->regs->radioregdata); id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4) & 0xf); } else { - W_REG(&pi->regs->phy4waddr, RADIO_IDCODE); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, RADIO_IDCODE); id = (u32) R_REG(&pi->regs->phy4wdatalo); id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16; } @@ -397,10 +371,7 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); pi->phy_wreg = 0; return R_REG(®s->phyregdata); @@ -413,8 +384,7 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) regs = pi->regs; #ifdef __mips__ - W_REG(®s->phyregaddr, addr); - (void)R_REG(®s->phyregaddr); + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, val); if (addr == 0x72) (void)R_REG(®s->phyregdata); @@ -436,10 +406,7 @@ void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, (R_REG(®s->phyregdata) & val)); pi->phy_wreg = 0; @@ -451,10 +418,7 @@ void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, (R_REG(®s->phyregdata) | val)); pi->phy_wreg = 0; @@ -466,10 +430,7 @@ void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, ((R_REG(®s->phyregdata) & ~mask) | (val & mask))); @@ -2350,27 +2311,6 @@ bool wlc_phy_test_ison(wlc_phy_t *ppi) return pi->phytest_on; } -bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval) -{ - phy_info_t *pi = (phy_info_t *) ppi; - bool ret = true; - - wlc_phyreg_enter(ppi); - - if (ISNPHY(pi)) { - - ret = false; - } else if (ISLCNPHY(pi)) { - u16 crsctrl = read_phy_reg(pi, 0x410); - u16 div = crsctrl & (0x1 << 1); - *pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1))); - } - - wlc_phyreg_exit(ppi); - - return ret; -} - void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) { phy_info_t *pi = (phy_info_t *) ppi; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h index 8939153efa56..8bd0d139a377 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h @@ -14,14 +14,18 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_h_ -#define _wlc_phy_h_ +/* + * phy_hal.h: functionality exported from the phy to higher layers + */ + +#ifndef _BRCM_PHY_HAL_H_ +#define _BRCM_PHY_HAL_H_ -#include <wlioctl.h> #include <aiutils.h> #include <d11.h> -#include <wlc_phy_shim.h> +#include <phy_shim.h> #include <net/mac80211.h> /* struct wiphy */ +#include "brcmu_wifi.h" /* chanspec_t */ #define IDCODE_VER_MASK 0x0000000f #define IDCODE_VER_SHIFT 0 @@ -87,12 +91,20 @@ #define WLC_TXPWR_DB_FACTOR 4 +/* a large TX Power as an init value to factor out of min() calculations, + * keep low enough to fit in an s8, units are .25 dBm + */ +#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ + #define WLC_NUM_RATES_CCK 4 #define WLC_NUM_RATES_OFDM 8 #define WLC_NUM_RATES_MCS_1_STREAM 8 #define WLC_NUM_RATES_MCS_2_STREAM 8 #define WLC_NUM_RATES_MCS_3_STREAM 8 #define WLC_NUM_RATES_MCS_4_STREAM 8 + +#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ + typedef struct txpwr_limits { u8 cck[WLC_NUM_RATES_CCK]; u8 ofdm[WLC_NUM_RATES_OFDM]; @@ -115,6 +127,32 @@ typedef struct txpwr_limits { } txpwr_limits_t; typedef struct { + u32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + u8 local_max; /* local max according to the AP */ + u8 local_constraint; /* local constraint according to the AP */ + s8 antgain[2]; /* Ant gain for each band - from SROM */ + u8 rf_cores; /* count of RF Cores being reported */ + u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ + u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain + * without adjustment + */ + u8 est_Pout_cck; /* Latest CCK tx power out estimate */ + u8 tx_power_max[4]; /* Maximum target power among all rates */ + u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ + u8 user_limit[WL_TX_POWER_RATES]; /* User limit */ + u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */ + u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ + u8 target[WL_TX_POWER_RATES]; /* Latest target power */ +} tx_power_t; + +typedef struct tx_inst_power { + u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ + u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ +} tx_inst_power_t; + +typedef struct { u8 vec[MAXCHANNEL / NBBY]; } chanvec_t; @@ -126,7 +164,7 @@ struct phy_pub; typedef struct phy_pub wlc_phy_t; typedef struct shared_phy_params { - si_t *sih; + struct si_pub *sih; void *physhim; uint unit; uint corerev; @@ -226,7 +264,6 @@ extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock); extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi); extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val); -extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval); extern void wlc_phy_clear_tssi(wlc_phy_t *ppi); extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val); extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags); @@ -253,4 +290,4 @@ extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi, u8 mcs_offset); extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset); -#endif /* _wlc_phy_h_ */ +#endif /* _BRCM_PHY_HAL_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h index 10cbf520474f..f3fddfcf6040 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h @@ -14,15 +14,16 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_int_h_ -#define _wlc_phy_int_h_ +#ifndef _BRCM_PHY_INT_H_ +#define _BRCM_PHY_INT_H_ #include <linux/kernel.h> -#include <bcmdefs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcmu_utils.h> -#include <bcmsrom_fmt.h> -#include <wlc_phy_hal.h> +#include <phy_hal.h> + +#define PHY_VERSION { 1, 82, 8, 0 } #define PHYHAL_ERROR 0x0001 #define PHYHAL_TRACE 0x0002 @@ -42,6 +43,14 @@ extern u32 phyhal_msg_level; #define LCNXN_BASEREV 16 +typedef struct { + u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */ + u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ + u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */ + u8 triso; /* TR switch isolation */ + u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */ +} wlc_phy_srom_fem_t; + struct wlc_hw_info; typedef struct phy_info phy_info_t; typedef void (*initfn_t) (phy_info_t *); @@ -248,7 +257,7 @@ typedef enum { #define PHY_CHAIN_TX_DISABLE_TEMP 115 #define PHY_HYSTERESIS_DELTATEMP 5 -#define PHY_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) +#define PHY_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8)) #define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \ mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \ @@ -527,7 +536,7 @@ typedef struct { struct shared_phy { struct phy_info *phy_head; uint unit; - si_t *sih; + struct si_pub *sih; void *physhim; uint corerev; u32 machwcap; @@ -653,8 +662,8 @@ struct phy_info { s8 tx_power_offset[TXP_NUM_RATES]; u8 tx_power_target[TXP_NUM_RATES]; - srom_fem_t srom_fem2g; - srom_fem_t srom_fem5g; + wlc_phy_srom_fem_t srom_fem2g; + wlc_phy_srom_fem_t srom_fem5g; u8 tx_power_max; u8 tx_power_max_rate_ind; @@ -1223,4 +1232,4 @@ extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec); extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih); -#endif /* _wlc_phy_int_h_ */ +#endif /* _BRCM_PHY_INT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c index b8864c5b7a19..84d50c26ae07 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c @@ -18,20 +18,21 @@ #include <linux/string.h> #include <linux/bitops.h> #include <linux/delay.h> -#include <wlc_cfg.h> #include <linux/pci.h> +#include <brcmu_utils.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_qmath.h" -#include "wlc_phy_lcn.h" -#include "wlc_phytbl_lcn.h" +#include <pmu.h> +#include <scb.h> +#include <pub.h> + +#include <brcm_hw_ids.h> +#include <dma.h> + +#include "phy_radio.h" +#include "phy_int.h" +#include "phy_qmath.h" +#include "phy_lcn.h" +#include "phytbl_lcn.h" #define PLL_2064_NDIV 90 #define PLL_2064_LOW_END_VCO 3000 diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h index b7bfc7230dfc..efa8c903360b 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_lcn_h_ -#define _wlc_phy_lcn_h_ +#ifndef _BRCM_PHY_LCN_H_ +#define _BRCM_PHY_LCN_H_ struct phy_info_lcnphy { int lcnphy_txrf_sp_9_override; @@ -116,4 +116,4 @@ struct phy_info_lcnphy { uint lcnphy_aci_start_time; s8 lcnphy_tx_power_offset[TXP_NUM_RATES]; }; -#endif /* _wlc_phy_lcn_h_ */ +#endif /* _BRCM_PHY_LCN_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c index 71275094e810..e10f98dc742e 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c @@ -16,21 +16,21 @@ #include <linux/kernel.h> #include <linux/string.h> -#include <bcmdefs.h> -#include <wlc_cfg.h> +#include <defs.h> #include <linux/delay.h> #include <linux/pci.h> #include <aiutils.h> -#include <sbchipc.h> -#include <wlc_pmu.h> +#include <chipcommon.h> +#include <pmu.h> -#include <bcmdevs.h> -#include <sbhnddma.h> +#include <brcm_hw_ids.h> +#include <dma.h> -#include <wlc_phy_radio.h> -#include <wlc_phy_int.h> -#include <wlc_phyreg_n.h> -#include <wlc_phytbl_n.h> +#include <types.h> +#include <phy_radio.h> +#include <phy_int.h> +#include <phyreg_n.h> +#include <phytbl_n.h> #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ @@ -141,6 +141,10 @@ #define NPHY_ADJUSTED_MINCRSPOWER 0x1e +/* 5357 Chip specific ChipControl register bits */ +#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ +#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ + typedef struct _nphy_iqcal_params { u16 txlpf; u16 txgm; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c index c98176fd0aae..801c7c0d5555 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c @@ -16,7 +16,7 @@ #include <linux/types.h> -#include "wlc_phy_qmath.h" +#include "phy_qmath.h" /* Description: This function make 16 bit unsigned multiplication. To fit the output into diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h index 3dcee1c4aa65..49f57f4e847b 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __QMATH_H__ -#define __QMATH_H__ +#ifndef _BRCM_QMATH_H_ +#define _BRCM_QMATH_H_ u16 qm_mulu16(u16 op1, u16 op2); @@ -37,4 +37,4 @@ s16 qm_norm32(s32 op); void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N); -#endif /* #ifndef __QMATH_H__ */ +#endif /* #ifndef _BRCM_QMATH_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h index 72176ae2882c..c3a675455ff5 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _BCM20XX_H -#define _BCM20XX_H +#ifndef _BRCM_PHY_RADIO_H_ +#define _BRCM_PHY_RADIO_H_ #define RADIO_IDCODE 0x01 @@ -1530,4 +1530,4 @@ #define RADIO_2057_VCM_MASK 0x7 -#endif /* _BCM20XX_H */ +#endif /* _BRCM_PHY_RADIO_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h index 211bc3a842af..211bc3a842af 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c index 81c59b05482a..4dcc69169357 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -15,9 +15,9 @@ */ #include <linux/types.h> -#include <sbhnddma.h> -#include <wlc_phy_int.h> -#include <wlc_phytbl_lcn.h> +#include <dma.h> +#include <phy_int.h> +#include <phytbl_lcn.h> const u32 dot11lcn_gain_tbl_rev0[] = { 0x00000000, diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h index 5a64a988d107..5a64a988d107 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c index 742df997a3b1..1dd613ac5e62 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c @@ -16,9 +16,9 @@ #include <linux/kernel.h> -#include <sbhnddma.h> -#include <wlc_phy_int.h> -#include <wlc_phytbl_n.h> +#include <dma.h> +#include <phy_int.h> +#include <phytbl_n.h> const u32 frame_struct_rev0[] = { 0x08004a04, diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h index 396122f5e50b..396122f5e50b 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/phy_shim.c index 16fea021f4a5..d4975736f0d6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.c @@ -23,37 +23,28 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/pci.h> -#include <proto/802.11.h> -#include <bcmdefs.h> -#include <bcmutils.h> -#include <bcmwifi.h> +#include <defs.h> +#include <brcmu_utils.h> +#include <brcmu_wifi.h> #include <aiutils.h> -#include <wlioctl.h> -#include <sbconfig.h> -#include <sbchipc.h> -#include <pcicfg.h> -#include <sbhnddma.h> -#include <hnddma.h> -#include <wlc_pmu.h> - -#include "wlc_types.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" +#include <chipcommon.h> +#include "dma.h" +#include <pmu.h> + +#include "types.h" #include "d11.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "bcmsrom.h" -#include "wlc_key.h" -#include "wlc_bmac.h" -#include "wlc_phy_hal.h" -#include "wl_export.h" -#include "wlc_main.h" -#include "wlc_phy_shim.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "srom.h" +#include "bmac.h" +#include "phy_hal.h" +#include "main.h" +#include "phy_shim.h" +#include "mac80211_if.h" /* PHY SHIM module specific state */ struct wlc_phy_shim_info { @@ -89,39 +80,40 @@ struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, void (*fn) (void *arg), void *arg, const char *name) { - return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); + return (struct wlapi_timer *) + brcms_init_timer(physhim->wl, fn, arg, name); } void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) { - wl_free_timer(physhim->wl, (struct wl_timer *)t); + brcms_free_timer(physhim->wl, (struct brcms_timer *)t); } void wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, int periodic) { - wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); + brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic); } bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) { - return wl_del_timer(physhim->wl, (struct wl_timer *)t); + return brcms_del_timer(physhim->wl, (struct brcms_timer *)t); } void wlapi_intrson(wlc_phy_shim_info_t *physhim) { - wl_intrson(physhim->wl); + brcms_intrson(physhim->wl); } u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) { - return wl_intrsoff(physhim->wl); + return brcms_intrsoff(physhim->wl); } void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) { - wl_intrsrestore(physhim->wl, macintmask); + brcms_intrsrestore(physhim->wl, macintmask); } void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/phy_shim.h index c151a5d8c693..1677df218a51 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.h @@ -14,8 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_shim_h_ -#define _wlc_phy_shim_h_ +/* + * phy_shim.h: stuff defined in phy_shim.c and included only by the phy + */ + +#ifndef _BRCM_PHY_SHIM_H_ +#define _BRCM_PHY_SHIM_H_ #define RADAR_TYPE_NONE 0 /* Radar type None */ #define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ @@ -51,6 +55,57 @@ #define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ #define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ +#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ +#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ +#define WL_ANT_IDX_1 0 /* antenna index 1 */ +#define WL_ANT_IDX_2 1 /* antenna index 2 */ + +/* values for n_preamble_type */ +#define WLC_N_PREAMBLE_MIXEDMODE 0 +#define WLC_N_PREAMBLE_GF 1 +#define WLC_N_PREAMBLE_GF_BRCM 2 + +#define WL_TX_POWER_RATES_LEGACY 45 +#define WL_TX_POWER_MCS20_FIRST 12 +#define WL_TX_POWER_MCS20_NUM 16 +#define WL_TX_POWER_MCS40_FIRST 28 +#define WL_TX_POWER_MCS40_NUM 17 + + +#define WL_TX_POWER_RATES 101 +#define WL_TX_POWER_CCK_FIRST 0 +#define WL_TX_POWER_CCK_NUM 4 +#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM_NUM 8 +#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */ +#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */ +#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */ +#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */ +#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */ +#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */ +#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */ +#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */ +#define WL_TX_POWER_MCS_1_STREAM_NUM 8 +#define WL_TX_POWER_MCS_2_STREAM_NUM 8 +#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */ +#define WL_TX_POWER_MCS_32_NUM 1 + +/* sslpnphy specifics */ +#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */ + +/* tx_power_t.flags bits */ +#define WL_TX_POWER_F_ENABLED 1 +#define WL_TX_POWER_F_HW 2 +#define WL_TX_POWER_F_MIMO 4 +#define WL_TX_POWER_F_SISO 8 + +/* values to force tx/rx chain */ +#define WLC_N_TXRX_CHAIN0 0 +#define WLC_N_TXRX_CHAIN1 1 + /* Forward declarations */ struct wlc_hw_info; typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; @@ -109,4 +164,4 @@ extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, u32 phy_mode); extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); -#endif /* _wlc_phy_shim_h_ */ +#endif /* _BRCM_PHY_SHIM_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c b/drivers/staging/brcm80211/brcmsmac/pmu.c index 82986bd1ccfa..b822d403fe52 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c +++ b/drivers/staging/brcm80211/brcmsmac/pmu.c @@ -18,11 +18,13 @@ #include <linux/delay.h> #include <linux/io.h> -#include <bcmdevs.h> -#include <sbchipc.h> -#include <bcmutils.h> -#include <bcmnvram.h> -#include "wlc_pmu.h" +#include <brcm_hw_ids.h> +#include "types.h" +#include <chipcommon.h> +#include <brcmu_utils.h> +#include "scb.h" +#include "pub.h" +#include "pmu.h" /* * d11 slow to fast clock transition time in slow clock cycles @@ -128,9 +130,474 @@ #define RES_DEPEND_ADD 1 #define RES_DEPEND_REMOVE -1 +/* Fields in pmucontrol */ +#define PCTL_ILP_DIV_MASK 0xffff0000 +#define PCTL_ILP_DIV_SHIFT 16 +#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ +#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ +#define PCTL_HT_REQ_EN 0x00000100 +#define PCTL_ALP_REQ_EN 0x00000080 +#define PCTL_XTALFREQ_MASK 0x0000007c +#define PCTL_XTALFREQ_SHIFT 2 +#define PCTL_ILP_DIV_EN 0x00000002 +#define PCTL_LPO_SEL 0x00000001 + +/* Fields in clkstretch */ +#define CSTRETCH_HT 0xffff0000 +#define CSTRETCH_ALP 0x0000ffff + /* d11 slow to fast clock transition time in slow clock cycles */ #define D11SCC_SLOW2FAST_TRANSITION 2 +/* ILP clock */ +#define ILP_CLOCK 32000 + +/* ALP clock on pre-PMU chips */ +#define ALP_CLOCK 20000000 + +/* HT clock */ +#define HT_CLOCK 80000000 + +#define OTPS_READY 0x00001000 + +/* pmustatus */ +#define PST_EXTLPOAVAIL 0x0100 +#define PST_WDRESET 0x0080 +#define PST_INTPEND 0x0040 +#define PST_SBCLKST 0x0030 +#define PST_SBCLKST_ILP 0x0010 +#define PST_SBCLKST_ALP 0x0020 +#define PST_SBCLKST_HT 0x0030 +#define PST_ALPAVAIL 0x0008 +#define PST_HTAVAIL 0x0004 +#define PST_RESINIT 0x0003 + +/* PMU Resource Request Timer registers */ +/* This is based on PmuRev0 */ +#define PRRT_TIME_MASK 0x03ff +#define PRRT_INTEN 0x0400 +#define PRRT_REQ_ACTIVE 0x0800 +#define PRRT_ALP_REQ 0x1000 +#define PRRT_HT_REQ 0x2000 + +/* PMU resource bit position */ +#define PMURES_BIT(bit) (1 << (bit)) + +/* PMU resource number limit */ +#define PMURES_MAX_RESNUM 30 + +/* PMU chip control0 register */ +#define PMU_CHIPCTL0 0 + +/* PMU chip control1 register */ +#define PMU_CHIPCTL1 1 +#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 + +#define PMU_CC1_IF_TYPE_MASK 0x00000030 +#define PMU_CC1_IF_TYPE_RMII 0x00000000 +#define PMU_CC1_IF_TYPE_MII 0x00000010 +#define PMU_CC1_IF_TYPE_RGMII 0x00000020 + +#define PMU_CC1_SW_TYPE_MASK 0x000000c0 +#define PMU_CC1_SW_TYPE_EPHY 0x00000000 +#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 +#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 +#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 + +/* PMU corerev and chip specific PLL controls. + * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number + * to differentiate different PLLs controlled by the same PMU rev. + */ +/* pllcontrol registers */ +/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */ +#define PMU0_PLL0_PLLCTL0 0 +#define PMU0_PLL0_PC0_PDIV_MASK 1 +#define PMU0_PLL0_PC0_PDIV_FREQ 25000 +#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 +#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 +#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 + +/* PC0_DIV_ARM for PLLOUT_ARM */ +#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 +#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 +#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 +#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */ +#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 +#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 +#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 +#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 + +/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */ +#define PMU0_PLL0_PLLCTL1 1 +#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 +#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 +#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 +#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 +#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 + +/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */ +#define PMU0_PLL0_PLLCTL2 2 +#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf +#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 + +/* pllcontrol registers */ +/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */ +#define PMU1_PLL0_PLLCTL0 0 +#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 +#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 +#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 +#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 + +/* m<x>div */ +#define PMU1_PLL0_PLLCTL1 1 +#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff +#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 +#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 +#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 +#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 +#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 +#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 +#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 + +#define PMU1_PLL0_CHIPCTL0 0 +#define PMU1_PLL0_CHIPCTL1 1 +#define PMU1_PLL0_CHIPCTL2 2 + +#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 +#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) +#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) + +/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */ +#define PMU1_PLL0_PLLCTL2 2 +#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff +#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 +#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 +#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 +#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 +#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 +#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 +#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */ +#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 +#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 + +/* ndiv_frac */ +#define PMU1_PLL0_PLLCTL3 3 +#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff +#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 + +/* pll_ctrl */ +#define PMU1_PLL0_PLLCTL4 4 + +/* pll_ctrl, vco_rng, clkdrive_ch<x> */ +#define PMU1_PLL0_PLLCTL5 5 +#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 +#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 + +/* PMU rev 2 control words */ +#define PMU2_PHY_PLL_PLLCTL 4 +#define PMU2_SI_PLL_PLLCTL 10 + +/* PMU rev 2 */ +/* pllcontrol registers */ +/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */ +#define PMU2_PLL_PLLCTL0 0 +#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 +#define PMU2_PLL_PC0_P1DIV_SHIFT 20 +#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 +#define PMU2_PLL_PC0_P2DIV_SHIFT 24 + +/* m<x>div */ +#define PMU2_PLL_PLLCTL1 1 +#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff +#define PMU2_PLL_PC1_M1DIV_SHIFT 0 +#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 +#define PMU2_PLL_PC1_M2DIV_SHIFT 8 +#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 +#define PMU2_PLL_PC1_M3DIV_SHIFT 16 +#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 +#define PMU2_PLL_PC1_M4DIV_SHIFT 24 + +/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */ +#define PMU2_PLL_PLLCTL2 2 +#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff +#define PMU2_PLL_PC2_M5DIV_SHIFT 0 +#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 +#define PMU2_PLL_PC2_M6DIV_SHIFT 8 +#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 +#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 +#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 +#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 + +/* ndiv_frac */ +#define PMU2_PLL_PLLCTL3 3 +#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff +#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 + +/* pll_ctrl */ +#define PMU2_PLL_PLLCTL4 4 + +/* pll_ctrl, vco_rng, clkdrive_ch<x> */ +#define PMU2_PLL_PLLCTL5 5 +#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 +#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 +#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 +#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 +#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 +#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 +#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 +#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 +#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 +#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 +#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 +#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 + +/* PMU rev 5 (& 6) */ +#define PMU5_PLL_P1P2_OFF 0 +#define PMU5_PLL_P1_MASK 0x0f000000 +#define PMU5_PLL_P1_SHIFT 24 +#define PMU5_PLL_P2_MASK 0x00f00000 +#define PMU5_PLL_P2_SHIFT 20 +#define PMU5_PLL_M14_OFF 1 +#define PMU5_PLL_MDIV_MASK 0x000000ff +#define PMU5_PLL_MDIV_WIDTH 8 +#define PMU5_PLL_NM5_OFF 2 +#define PMU5_PLL_NDIV_MASK 0xfff00000 +#define PMU5_PLL_NDIV_SHIFT 20 +#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 +#define PMU5_PLL_NDIV_MODE_SHIFT 17 +#define PMU5_PLL_FMAB_OFF 3 +#define PMU5_PLL_MRAT_MASK 0xf0000000 +#define PMU5_PLL_MRAT_SHIFT 28 +#define PMU5_PLL_ABRAT_MASK 0x08000000 +#define PMU5_PLL_ABRAT_SHIFT 27 +#define PMU5_PLL_FDIV_MASK 0x07ffffff +#define PMU5_PLL_PLLCTL_OFF 4 +#define PMU5_PLL_PCHI_OFF 5 +#define PMU5_PLL_PCHI_MASK 0x0000003f + +/* pmu XtalFreqRatio */ +#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF +#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 +#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 + +/* Divider allocation in 4716/47162/5356/5357 */ +#define PMU5_MAINPLL_CPU 1 +#define PMU5_MAINPLL_MEM 2 +#define PMU5_MAINPLL_SI 3 + +#define PMU7_PLL_PLLCTL7 7 +#define PMU7_PLL_PLLCTL8 8 +#define PMU7_PLL_PLLCTL11 11 + +/* PLL usage in 4716/47162 */ +#define PMU4716_MAINPLL_PLL0 12 + +/* PLL usage in 5356/5357 */ +#define PMU5356_MAINPLL_PLL0 0 +#define PMU5357_MAINPLL_PLL0 0 + +/* 4328 resources */ +#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ +#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ +#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */ +#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ +#define RES4328_ILP_REQUEST 4 /* 0x00010 */ +#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */ +#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */ +#define RES4328_ROM_SWITCH 7 /* 0x00080 */ +#define RES4328_PA_REF_LDO 8 /* 0x00100 */ +#define RES4328_RADIO_LDO 9 /* 0x00200 */ +#define RES4328_AFE_LDO 10 /* 0x00400 */ +#define RES4328_PLL_LDO 11 /* 0x00800 */ +#define RES4328_BG_FILTBYP 12 /* 0x01000 */ +#define RES4328_TX_FILTBYP 13 /* 0x02000 */ +#define RES4328_RX_FILTBYP 14 /* 0x04000 */ +#define RES4328_XTAL_PU 15 /* 0x08000 */ +#define RES4328_XTAL_EN 16 /* 0x10000 */ +#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */ +#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */ +#define RES4328_BB_PLL_PU 19 /* 0x80000 */ + +/* 4325 A0/A1 resources */ +#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */ +#define RES4325_CBUCK_BURST 1 /* 0x00000002 */ +#define RES4325_CBUCK_PWM 2 /* 0x00000004 */ +#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */ +#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */ +#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */ +#define RES4325_ILP_REQUEST 6 /* 0x00000040 */ +#define RES4325_ABUCK_BURST 7 /* 0x00000080 */ +#define RES4325_ABUCK_PWM 8 /* 0x00000100 */ +#define RES4325_LNLDO1_PU 9 /* 0x00000200 */ +#define RES4325_OTP_PU 10 /* 0x00000400 */ +#define RES4325_LNLDO3_PU 11 /* 0x00000800 */ +#define RES4325_LNLDO4_PU 12 /* 0x00001000 */ +#define RES4325_XTAL_PU 13 /* 0x00002000 */ +#define RES4325_ALP_AVAIL 14 /* 0x00004000 */ +#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */ +#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */ +#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */ +#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */ +#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */ +#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */ +#define RES4325_HT_AVAIL 21 /* 0x00200000 */ + +/* 4325 B0/C0 resources */ +#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */ +#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */ +#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */ +#define RES4325B0_CLDO_PU 4 /* 0x00000010 */ + +/* 4325 C1 resources */ +#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */ + +#define RES4329_RESERVED0 0 /* 0x00000001 */ +#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */ +#define RES4329_CBUCK_BURST 2 /* 0x00000004 */ +#define RES4329_CBUCK_PWM 3 /* 0x00000008 */ +#define RES4329_CLDO_PU 4 /* 0x00000010 */ +#define RES4329_PALDO_PU 5 /* 0x00000020 */ +#define RES4329_ILP_REQUEST 6 /* 0x00000040 */ +#define RES4329_RESERVED7 7 /* 0x00000080 */ +#define RES4329_RESERVED8 8 /* 0x00000100 */ +#define RES4329_LNLDO1_PU 9 /* 0x00000200 */ +#define RES4329_OTP_PU 10 /* 0x00000400 */ +#define RES4329_RESERVED11 11 /* 0x00000800 */ +#define RES4329_LNLDO2_PU 12 /* 0x00001000 */ +#define RES4329_XTAL_PU 13 /* 0x00002000 */ +#define RES4329_ALP_AVAIL 14 /* 0x00004000 */ +#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */ +#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */ +#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */ +#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */ +#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */ +#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */ +#define RES4329_HT_AVAIL 21 /* 0x00200000 */ + +/* 4315 resources */ +#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */ +#define RES4315_CBUCK_BURST 2 /* 0x00000004 */ +#define RES4315_CBUCK_PWM 3 /* 0x00000008 */ +#define RES4315_CLDO_PU 4 /* 0x00000010 */ +#define RES4315_PALDO_PU 5 /* 0x00000020 */ +#define RES4315_ILP_REQUEST 6 /* 0x00000040 */ +#define RES4315_LNLDO1_PU 9 /* 0x00000200 */ +#define RES4315_OTP_PU 10 /* 0x00000400 */ +#define RES4315_LNLDO2_PU 12 /* 0x00001000 */ +#define RES4315_XTAL_PU 13 /* 0x00002000 */ +#define RES4315_ALP_AVAIL 14 /* 0x00004000 */ +#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */ +#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */ +#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */ +#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */ +#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */ +#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */ +#define RES4315_HT_AVAIL 21 /* 0x00200000 */ + +/* 4319 resources */ +#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */ +#define RES4319_CBUCK_BURST 2 /* 0x00000004 */ +#define RES4319_CBUCK_PWM 3 /* 0x00000008 */ +#define RES4319_CLDO_PU 4 /* 0x00000010 */ +#define RES4319_PALDO_PU 5 /* 0x00000020 */ +#define RES4319_ILP_REQUEST 6 /* 0x00000040 */ +#define RES4319_LNLDO1_PU 9 /* 0x00000200 */ +#define RES4319_OTP_PU 10 /* 0x00000400 */ +#define RES4319_LNLDO2_PU 12 /* 0x00001000 */ +#define RES4319_XTAL_PU 13 /* 0x00002000 */ +#define RES4319_ALP_AVAIL 14 /* 0x00004000 */ +#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */ +#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */ +#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */ +#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */ +#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */ +#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */ +#define RES4319_HT_AVAIL 21 /* 0x00200000 */ + +#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 +#define CCTL_4319USB_XTAL_SEL_SHIFT 19 +#define CCTL_4319USB_48MHZ_PLL_SEL 1 +#define CCTL_4319USB_24MHZ_PLL_SEL 2 + +/* PMU resources for 4336 */ +#define RES4336_CBUCK_LPOM 0 +#define RES4336_CBUCK_BURST 1 +#define RES4336_CBUCK_LP_PWM 2 +#define RES4336_CBUCK_PWM 3 +#define RES4336_CLDO_PU 4 +#define RES4336_DIS_INT_RESET_PD 5 +#define RES4336_ILP_REQUEST 6 +#define RES4336_LNLDO_PU 7 +#define RES4336_LDO3P3_PU 8 +#define RES4336_OTP_PU 9 +#define RES4336_XTAL_PU 10 +#define RES4336_ALP_AVAIL 11 +#define RES4336_RADIO_PU 12 +#define RES4336_BG_PU 13 +#define RES4336_VREG1p4_PU_PU 14 +#define RES4336_AFE_PWRSW_PU 15 +#define RES4336_RX_PWRSW_PU 16 +#define RES4336_TX_PWRSW_PU 17 +#define RES4336_BB_PWRSW_PU 18 +#define RES4336_SYNTH_PWRSW_PU 19 +#define RES4336_MISC_PWRSW_PU 20 +#define RES4336_LOGEN_PWRSW_PU 21 +#define RES4336_BBPLL_PWRSW_PU 22 +#define RES4336_MACPHY_CLKAVAIL 23 +#define RES4336_HT_AVAIL 24 +#define RES4336_RSVD 25 + +/* 4330 resources */ +#define RES4330_CBUCK_LPOM 0 +#define RES4330_CBUCK_BURST 1 +#define RES4330_CBUCK_LP_PWM 2 +#define RES4330_CBUCK_PWM 3 +#define RES4330_CLDO_PU 4 +#define RES4330_DIS_INT_RESET_PD 5 +#define RES4330_ILP_REQUEST 6 +#define RES4330_LNLDO_PU 7 +#define RES4330_LDO3P3_PU 8 +#define RES4330_OTP_PU 9 +#define RES4330_XTAL_PU 10 +#define RES4330_ALP_AVAIL 11 +#define RES4330_RADIO_PU 12 +#define RES4330_BG_PU 13 +#define RES4330_VREG1p4_PU_PU 14 +#define RES4330_AFE_PWRSW_PU 15 +#define RES4330_RX_PWRSW_PU 16 +#define RES4330_TX_PWRSW_PU 17 +#define RES4330_BB_PWRSW_PU 18 +#define RES4330_SYNTH_PWRSW_PU 19 +#define RES4330_MISC_PWRSW_PU 20 +#define RES4330_LOGEN_PWRSW_PU 21 +#define RES4330_BBPLL_PWRSW_PU 22 +#define RES4330_MACPHY_CLKAVAIL 23 +#define RES4330_HT_AVAIL 24 +#define RES4330_5gRX_PWRSW_PU 25 +#define RES4330_5gTX_PWRSW_PU 26 +#define RES4330_5g_LOGEN_PWRSW_PU 27 + +/* 4313 resources */ +#define RES4313_BB_PU_RSRC 0 +#define RES4313_ILP_REQ_RSRC 1 +#define RES4313_XTAL_PU_RSRC 2 +#define RES4313_ALP_AVAIL_RSRC 3 +#define RES4313_RADIO_PU_RSRC 4 +#define RES4313_BG_PU_RSRC 5 +#define RES4313_VREG1P4_PU_RSRC 6 +#define RES4313_AFE_PWRSW_RSRC 7 +#define RES4313_RX_PWRSW_RSRC 8 +#define RES4313_TX_PWRSW_RSRC 9 +#define RES4313_BB_PWRSW_RSRC 10 +#define RES4313_SYNTH_PWRSW_RSRC 11 +#define RES4313_MISC_PWRSW_RSRC 12 +#define RES4313_BB_PLL_PWRSW_RSRC 13 +#define RES4313_HT_AVAIL_RSRC 14 +#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 + +/* PMU resource up transition time in ILP cycles */ +#define PMURES_UP_TRANSITION 2 + /* Setup resource up/down timers */ typedef struct { u8 resnum; @@ -142,7 +609,8 @@ typedef struct { u32 res_mask; /* resources (chip specific) */ s8 action; /* action */ u32 depend_mask; /* changes to the dependancies mask */ - bool(*filter) (si_t *sih); /* action is taken when filter is NULL or return true */ + /* action is taken when filter is NULL or return true: */ + bool(*filter) (struct si_pub *sih); } pmu_res_depend_t; /* setup pll and query clock speed */ @@ -158,10 +626,10 @@ typedef struct { /* * 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 bool si_pmu_res_depfltr_bb(struct si_pub *sih); +static bool si_pmu_res_depfltr_ncb(struct si_pub *sih); +static bool si_pmu_res_depfltr_paldo(struct si_pub *sih); +static bool si_pmu_res_depfltr_npaldo(struct si_pub *sih); static const pmu_res_updown_t bcm4328a0_res_updown[] = { { @@ -505,33 +973,33 @@ static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = { }; /* 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) +static bool si_pmu_res_depfltr_bb(struct si_pub *sih) { return (sih->boardflags & BFL_BUCKBOOST) != 0; } /* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */ -static bool si_pmu_res_depfltr_ncb(si_t *sih) +static bool si_pmu_res_depfltr_ncb(struct si_pub *sih) { return (sih->boardflags & BFL_NOCBUCK) != 0; } /* true if the power topology uses the PALDO */ -static bool si_pmu_res_depfltr_paldo(si_t *sih) +static bool si_pmu_res_depfltr_paldo(struct si_pub *sih) { return (sih->boardflags & BFL_PALDO) != 0; } /* true if the power topology doesn't use the PALDO */ -static bool si_pmu_res_depfltr_npaldo(si_t *sih) +static bool si_pmu_res_depfltr_npaldo(struct si_pub *sih) { return (sih->boardflags & BFL_PALDO) == 0; } /* Return dependancies (direct or all/indirect) for the given resources */ static u32 -si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, +si_pmu_res_deps(struct si_pub *sih, chipcregs_t *cc, u32 rsrcs, bool all) { u32 deps = 0; @@ -551,7 +1019,7 @@ si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, } /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ -static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) +static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax) { u32 min_mask = 0, max_mask = 0; uint rsrcs; @@ -638,7 +1106,7 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) /* Return up time in ILP cycles for the given resource. */ static uint -si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { +si_pmu_res_uptime(struct si_pub *sih, chipcregs_t *cc, u8 rsrc) { u32 deps; uint up, i, dup, dmax; u32 min_mask = 0, max_mask = 0; @@ -671,7 +1139,7 @@ si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { } static void -si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) +si_pmu_spuravoid_pllupdate(struct si_pub *sih, chipcregs_t *cc, u8 spuravoid) { u32 tmp = 0; u8 phypll_offset = 0; @@ -871,7 +1339,7 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) } /* select default xtal frequency for each chip */ -static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) +static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(struct si_pub *sih) { switch (sih->chip) { case BCM4329_CHIP_ID: @@ -896,7 +1364,7 @@ static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) } /* select xtal table for each chip */ -static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) +static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(struct si_pub *sih) { switch (sih->chip) { case BCM4329_CHIP_ID: @@ -918,7 +1386,7 @@ static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) /* query alp/xtal clock frequency */ static u32 -si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc) +si_pmu1_alpclk0(struct si_pub *sih, chipcregs_t *cc) { const pmu1_xtaltab0_t *xt; u32 xf; @@ -936,7 +1404,7 @@ si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc) } /* select default pll fvco for each chip */ -static u32 si_pmu1_pllfvco0(si_t *sih) +static u32 si_pmu1_pllfvco0(struct si_pub *sih) { switch (sih->chip) { case BCM4329_CHIP_ID: @@ -956,7 +1424,7 @@ static u32 si_pmu1_pllfvco0(si_t *sih) return 0; } -static void si_pmu_set_4330_plldivs(si_t *sih) +static void si_pmu_set_4330_plldivs(struct si_pub *sih) { u32 FVCO = si_pmu1_pllfvco0(sih) / 1000; u32 m1div, m2div, m3div, m4div, m5div, m6div; @@ -990,7 +1458,7 @@ static void si_pmu_set_4330_plldivs(si_t *sih) * case the xtal frequency is unknown to the s/w so we need to call * si_pmu1_xtaldef0() wherever it is needed to return a default value. */ -static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) +static void si_pmu1_pllinit0(struct si_pub *sih, chipcregs_t *cc, u32 xtal) { const pmu1_xtaltab0_t *xt; u32 tmp; @@ -1210,7 +1678,7 @@ static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) W_REG(&cc->pmucontrol, tmp); } -u32 si_pmu_ilp_clock(si_t *sih) +u32 si_pmu_ilp_clock(struct si_pub *sih) { static u32 ilpcycles_per_sec; @@ -1232,7 +1700,7 @@ u32 si_pmu_ilp_clock(si_t *sih) return ilpcycles_per_sec; } -void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) +void si_pmu_set_ldo_voltage(struct si_pub *sih, u8 ldo, u8 voltage) { u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; u8 addr = 0; @@ -1282,7 +1750,7 @@ void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) mask << shift, (voltage & mask) << shift); } -u16 si_pmu_fast_pwrup_delay(si_t *sih) +u16 si_pmu_fast_pwrup_delay(struct si_pub *sih) { uint delay = PMU_MAX_TRANSITION_DLY; chipcregs_t *cc; @@ -1356,7 +1824,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih) return (u16) delay; } -void si_pmu_sprom_enable(si_t *sih, bool enable) +void si_pmu_sprom_enable(struct si_pub *sih, bool enable) { chipcregs_t *cc; uint origidx; @@ -1370,7 +1838,7 @@ void si_pmu_sprom_enable(si_t *sih, bool enable) } /* Read/write a chipcontrol reg */ -u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val) +u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, reg); @@ -1379,7 +1847,7 @@ u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val) } /* Read/write a regcontrol reg */ -u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val) +u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, reg); @@ -1388,7 +1856,7 @@ u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val) } /* Read/write a pllcontrol reg */ -u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val) +u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, reg); @@ -1397,14 +1865,14 @@ u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val) } /* PMU PLL update */ -void si_pmu_pllupd(si_t *sih) +void si_pmu_pllupd(struct si_pub *sih) { ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); } /* query alp/xtal clock frequency */ -u32 si_pmu_alp_clock(si_t *sih) +u32 si_pmu_alp_clock(struct si_pub *sih) { chipcregs_t *cc; uint origidx; @@ -1455,7 +1923,7 @@ u32 si_pmu_alp_clock(si_t *sih) return clock; } -void si_pmu_spuravoid(si_t *sih, u8 spuravoid) +void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid) { chipcregs_t *cc; uint origidx, intr_val; @@ -1490,7 +1958,7 @@ void si_pmu_spuravoid(si_t *sih, u8 spuravoid) } /* initialize PMU */ -void si_pmu_init(si_t *sih) +void si_pmu_init(struct si_pub *sih) { chipcregs_t *cc; uint origidx; @@ -1518,7 +1986,7 @@ void si_pmu_init(si_t *sih) } /* initialize PMU chip controls and other chip level stuff */ -void si_pmu_chip_init(si_t *sih) +void si_pmu_chip_init(struct si_pub *sih) { uint origidx; @@ -1533,7 +2001,7 @@ void si_pmu_chip_init(si_t *sih) } /* initialize PMU switch/regulators */ -void si_pmu_swreg_init(si_t *sih) +void si_pmu_swreg_init(struct si_pub *sih) { switch (sih->chip) { case BCM4336_CHIP_ID: @@ -1558,7 +2026,7 @@ void si_pmu_swreg_init(si_t *sih) } /* initialize PLL */ -void si_pmu_pll_init(si_t *sih, uint xtalfreq) +void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq) { chipcregs_t *cc; uint origidx; @@ -1598,7 +2066,7 @@ void si_pmu_pll_init(si_t *sih, uint xtalfreq) } /* initialize PMU resources */ -void si_pmu_res_init(si_t *sih) +void si_pmu_res_init(struct si_pub *sih) { chipcregs_t *cc; uint origidx; @@ -1769,7 +2237,7 @@ void si_pmu_res_init(si_t *sih) ai_setcoreidx(sih, origidx); } -u32 si_pmu_measure_alpclk(si_t *sih) +u32 si_pmu_measure_alpclk(struct si_pub *sih) { chipcregs_t *cc; uint origidx; @@ -1822,7 +2290,7 @@ u32 si_pmu_measure_alpclk(si_t *sih) return alp_khz; } -bool si_pmu_is_otp_powered(si_t *sih) +bool si_pmu_is_otp_powered(struct si_pub *sih) { uint idx; chipcregs_t *cc; @@ -1872,7 +2340,7 @@ bool si_pmu_is_otp_powered(si_t *sih) } /* power up/down OTP through PMU resources */ -void si_pmu_otp_power(si_t *sih, bool on) +void si_pmu_otp_power(struct si_pub *sih, bool on) { chipcregs_t *cc; uint origidx; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h b/drivers/staging/brcm80211/brcmsmac/pmu.h index bd5b809b2e31..eff8d5b05038 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h +++ b/drivers/staging/brcm80211/brcmsmac/pmu.h @@ -15,8 +15,8 @@ */ -#ifndef WLC_PMU_H_ -#define WLC_PMU_H_ +#ifndef _BRCM_PMU_H_ +#define _BRCM_PMU_H_ #include <linux/types.h> @@ -36,23 +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_measure_alpclk(si_t *sih); -extern bool si_pmu_is_otp_powered(si_t *sih); -extern void si_pmu_otp_power(si_t *sih, bool on); +extern void si_pmu_set_ldo_voltage(struct si_pub *sih, u8 ldo, u8 voltage); +extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); +extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable); +extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_ilp_clock(struct si_pub *sih); +extern u32 si_pmu_alp_clock(struct si_pub *sih); +extern void si_pmu_pllupd(struct si_pub *sih); +extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid); +extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern void si_pmu_init(struct si_pub *sih); +extern void si_pmu_chip_init(struct si_pub *sih); +extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq); +extern void si_pmu_res_init(struct si_pub *sih); +extern void si_pmu_swreg_init(struct si_pub *sih); +extern u32 si_pmu_measure_alpclk(struct si_pub *sih); +extern bool si_pmu_is_otp_powered(struct si_pub *sih); +extern void si_pmu_otp_power(struct si_pub *sih, bool on); -#endif /* WLC_PMU_H_ */ +#endif /* _BRCM_PMU_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/pub.h index 9334deacda12..e5f24b051ab0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/pub.h @@ -14,8 +14,11 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_pub_h_ -#define _wlc_pub_h_ +#ifndef _BRCM_PUB_H_ +#define _BRCM_PUB_H_ + +#include "types.h" /* forward structure declarations */ +#include "brcmu_wifi.h" /* for chanspec_t */ #define WLC_NUMRATES 16 /* max # of rates in a rateset */ #define MAXMULTILIST 32 /* max # multicast addresses */ @@ -96,6 +99,12 @@ #define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ #endif /* AIDMAPSZ */ +#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ + +#define WL_SPURAVOID_OFF 0 +#define WL_SPURAVOID_ON1 1 +#define WL_SPURAVOID_ON2 2 + struct ieee80211_tx_queue_params; typedef struct wlc_tunables { @@ -134,7 +143,6 @@ struct rsn_parms { }; /* - * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) @@ -152,7 +160,7 @@ struct rsn_parms { IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) -/* wlc internal bss_info, wl external one is in wlioctl.h */ +/* wlc internal bss_info */ typedef struct wlc_bss_info { u8 BSSID[ETH_ALEN]; /* network BSSID */ u16 flags; /* flags for internal attributes */ @@ -211,7 +219,7 @@ struct wlc_if; /* watchdog down and dump callback function proto's */ typedef int (*watchdog_fn_t) (void *handle); typedef int (*down_fn_t) (void *handle); -typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); +typedef int (*dump_fn_t) (void *handle, struct brcmu_strbuf *b); /* IOVar handler * @@ -226,7 +234,7 @@ typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); * * All pointers may point into the same buffer. */ -typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, +typedef int (*iovar_fn_t) (void *handle, const struct brcmu_iovar *vi, u32 actionid, const char *name, void *params, uint plen, void *arg, int alen, int vsize, struct wlc_if *wlcif); @@ -247,7 +255,7 @@ struct wlc_pub { uint mac80211_state; uint unit; /* device instance number */ uint corerev; /* core revision */ - si_t *sih; /* SB handle (cookie for siutils calls) */ + struct si_pub *sih; /* SI handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ bool up; /* interface up and running */ bool hw_off; /* HW is off */ @@ -311,9 +319,6 @@ struct wlc_pub { u32 boardflags; /* Board specific flags from srom */ u32 boardflags2; /* More board flags if sromrev >= 4 */ bool tempsense_disable; /* disable periodic tempsense check */ - - bool _lmac; /* lmac module included and enabled */ - bool _lmacproto; /* lmac protocol module included and enabled */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool _ampdumac; /* mac assist ampdu enabled or not */ @@ -335,7 +340,7 @@ typedef struct wl_rxsts { uint preamble; /* Unknown, short, long */ uint encoding; /* Unknown, CCK, PBCC, OFDM */ uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ - struct wl_if *wlif; /* wl interface */ + struct brcms_if *wlif; /* wl interface */ } wl_rxsts_t; /* status per error RX pkt */ @@ -371,6 +376,13 @@ typedef struct wl_rxsts { #define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ #define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ +enum wlc_par_id { + IOV_MPC = 1, + IOV_RTSTHRESH, + IOV_QTXPOWER, + IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */ +}; + /* forward declare and use the struct notation so we don't have to * have it defined if not necessary. */ @@ -483,18 +495,108 @@ extern const u8 wme_fifo2ac[]; #define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ #define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ +/* + * 54g modes (basic bits may still be overridden) + * + * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 + * Preamble: Long + * Shortslot: Off + * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: Auto + * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 + * Extended Rateset: 6b, 9, 12b, 48 + * Preamble: Short required + * Shortslot: Auto + * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: On + * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 + * Preamble: Short required + * Shortslot: On and required + * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b + * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 + * Preamble: Long + * Shortslot: Auto + */ +#define GMODE_LEGACY_B 0 +#define GMODE_AUTO 1 +#define GMODE_ONLY 2 +#define GMODE_B_DEFERRED 3 +#define GMODE_PERFORMANCE 4 +#define GMODE_LRS 5 +#define GMODE_MAX 6 + +/* values for PLCPHdr_override */ +#define WLC_PLCP_AUTO -1 +#define WLC_PLCP_SHORT 0 +#define WLC_PLCP_LONG 1 + +/* values for g_protection_override and n_protection_override */ +#define WLC_PROTECTION_AUTO -1 +#define WLC_PROTECTION_OFF 0 +#define WLC_PROTECTION_ON 1 +#define WLC_PROTECTION_MMHDR_ONLY 2 +#define WLC_PROTECTION_CTS_ONLY 3 + +/* values for g_protection_control and n_protection_control */ +#define WLC_PROTECTION_CTL_OFF 0 +#define WLC_PROTECTION_CTL_LOCAL 1 +#define WLC_PROTECTION_CTL_OVERLAP 2 + +/* values for n_protection */ +#define WLC_N_PROTECTION_OFF 0 +#define WLC_N_PROTECTION_OPTIONAL 1 +#define WLC_N_PROTECTION_20IN40 2 +#define WLC_N_PROTECTION_MIXEDMODE 3 + +/* values for band specific 40MHz capabilities */ +#define WLC_N_BW_20ALL 0 +#define WLC_N_BW_40ALL 1 +#define WLC_N_BW_20IN2G_40IN5G 2 + +/* bitflags for SGI support (sgi_rx iovar) */ +#define WLC_N_SGI_20 0x01 +#define WLC_N_SGI_40 0x02 + +/* defines used by the nrate iovar */ +#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ +#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ +#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ +#define NRATE_STF_SHIFT 8 /* stf mode shift */ +#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ +#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ +#define NRATE_SGI_SHIFT 23 /* sgi mode */ +#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ +#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ + +#define NRATE_STF_SISO 0 /* stf mode SISO */ +#define NRATE_STF_CDD 1 /* stf mode CDD */ +#define NRATE_STF_STBC 2 /* stf mode STBC */ +#define NRATE_STF_SDM 3 /* stf mode SDM */ + +#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ + +#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ + +typedef struct { + u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ + u8 num_antcfg; /* number of available antenna configurations */ +} wlc_antselcfg_t; + /* common functions for every port */ -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 void *wlc_attach(struct brcms_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); extern int wlc_up(struct wlc_info *wlc); extern uint wlc_down(struct wlc_info *wlc); extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); -extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); -extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); extern bool wlc_chipmatch(u16 vendor, u16 device); extern void wlc_init(struct wlc_info *wlc); extern void wlc_reset(struct wlc_info *wlc); @@ -507,9 +609,6 @@ extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); 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, - int p_len, void *arg, int len, bool set, - 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); @@ -535,18 +634,17 @@ extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); struct ieee80211_sta; extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, u16 tid); +extern int wlc_set_par(struct wlc_info *wlc, enum wlc_par_id par_id, int val); +extern int wlc_get_par(struct wlc_info *wlc, enum wlc_par_id par_id, int *ret_int_ptr); +extern char *getvar(char *vars, const char *name); +extern int getintvar(char *vars, const char *name); /* 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); -/* ioctl */ -extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, - void *arg, - int len, bool set); - -extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t iovar_fn, +extern int wlc_module_register(struct wlc_pub *pub, + const char *name, void *hdl, watchdog_fn_t watchdog_fn, down_fn_t down_fn); extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl); @@ -558,18 +656,10 @@ extern void wlc_scan_stop(struct wlc_info *wlc); 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 - /* helper functions */ extern bool wlc_check_radio_disabled(struct wlc_info *wlc); extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); -#if defined(BCMDBG) -extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); -#endif - #define MAXBANDS 2 /* Maximum #of bands */ /* bandstate array indices */ #define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ @@ -581,4 +671,4 @@ extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) /* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ #define WLC_RPCTX_PARAMS 32 -#endif /* _wlc_pub_h_ */ +#endif /* _BRCM_PUB_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/rate.c index 87b252d6a7f5..5162ec2e3990 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/rate.c @@ -16,20 +16,16 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <proto/802.11.h> -#include <bcmdefs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <wlioctl.h> -#include <sbhnddma.h> +#include "dma.h" -#include "wlc_types.h" +#include "types.h" #include "d11.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_rate.h" +#include "scb.h" +#include "pub.h" +#include "rate.h" /* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ const u8 rate_info[WLC_MAXRATE + 1] = { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/rate.h index 5575e83bdc69..5575e83bdc69 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h +++ b/drivers/staging/brcm80211/brcmsmac/rate.h diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/scb.h index f07a891d5d27..edd471b9de45 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h +++ b/drivers/staging/brcm80211/brcmsmac/scb.h @@ -14,8 +14,11 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_scb_h_ -#define _wlc_scb_h_ +#ifndef _BRCM_SCB_H_ +#define _BRCM_SCB_H_ + +#include <linux/if_ether.h> /* for ETH_ALEN */ +#include <defs.h> #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ /* structure to store per-tid state for the ampdu initiator */ @@ -77,4 +80,4 @@ struct scb { #define SCB_PS(a) NULL #define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) #define SCB_AMPDU(a) true -#endif /* _wlc_scb_h_ */ +#endif /* _BRCM_SCB_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h b/drivers/staging/brcm80211/brcmsmac/srom.c index f4b3e61dc37d..17e0f2aa4051 100644 --- a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h +++ b/drivers/staging/brcm80211/brcmsmac/srom.c @@ -13,20 +13,345 @@ * 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 <defs.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <stdarg.h> +#include "types.h" +#include <brcmu_utils.h> +#include <soc.h> +#include <chipcommon.h> +#include <brcm_hw_ids.h> +#include <nicpci.h> +#include <aiutils.h> +#include "srom.h" +#include "otp.h" -#ifndef _bcmsrom_tbl_h_ -#define _bcmsrom_tbl_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)) -#include "wlioctl.h" +#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 { - const char *name; - u32 revmask; - u32 flags; - u16 off; - u16 mask; -} sromvar_t; +/* Maximum srom: 6 Kilobits == 768 bytes */ +#define SROM_MAX 768 + +/* PCI fields */ +#define PCI_F0DEVID 48 + +#define SROM_WORDS 64 + +#define SROM_SSID 2 + +#define SROM_WL1LHMAXP 29 + +#define SROM_WL1LPAB0 30 +#define SROM_WL1LPAB1 31 +#define SROM_WL1LPAB2 32 + +#define SROM_WL1HPAB0 33 +#define SROM_WL1HPAB1 34 +#define SROM_WL1HPAB2 35 + +#define SROM_MACHI_IL0 36 +#define SROM_MACMID_IL0 37 +#define SROM_MACLO_IL0 38 +#define SROM_MACHI_ET1 42 +#define SROM_MACMID_ET1 43 +#define SROM_MACLO_ET1 44 +#define SROM3_MACHI 37 +#define SROM3_MACMID 38 +#define SROM3_MACLO 39 + +#define SROM_BXARSSI2G 40 +#define SROM_BXARSSI5G 41 + +#define SROM_TRI52G 42 +#define SROM_TRI5GHL 43 + +#define SROM_RXPO52G 45 + +#define SROM_AABREV 46 +/* Fields in AABREV */ +#define SROM_BR_MASK 0x00ff +#define SROM_CC_MASK 0x0f00 +#define SROM_CC_SHIFT 8 +#define SROM_AA0_MASK 0x3000 +#define SROM_AA0_SHIFT 12 +#define SROM_AA1_MASK 0xc000 +#define SROM_AA1_SHIFT 14 + +#define SROM_WL0PAB0 47 +#define SROM_WL0PAB1 48 +#define SROM_WL0PAB2 49 + +#define SROM_LEDBH10 50 +#define SROM_LEDBH32 51 + +#define SROM_WL10MAXP 52 + +#define SROM_WL1PAB0 53 +#define SROM_WL1PAB1 54 +#define SROM_WL1PAB2 55 + +#define SROM_ITT 56 + +#define SROM_BFL 57 +#define SROM_BFL2 28 +#define SROM3_BFL2 61 + +#define SROM_AG10 58 + +#define SROM_CCODE 59 + +#define SROM_OPO 60 + +#define SROM3_LEDDC 62 + +#define SROM_CRCREV 63 + +/* 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 usable srom i.e. the usable storage in chips with OTP that + * implements hardware redundancy. + */ + +#define SROM4_WORDS 220 + +#define SROM4_SIGN 32 +#define SROM4_SIGNATURE 0x5372 + +#define SROM4_BREV 33 + +#define SROM4_BFL0 34 +#define SROM4_BFL1 35 +#define SROM4_BFL2 36 +#define SROM4_BFL3 37 +#define SROM5_BFL0 37 +#define SROM5_BFL1 38 +#define SROM5_BFL2 39 +#define SROM5_BFL3 40 + +#define SROM4_MACHI 38 +#define SROM4_MACMID 39 +#define SROM4_MACLO 40 +#define SROM5_MACHI 41 +#define SROM5_MACMID 42 +#define SROM5_MACLO 43 + +#define SROM4_CCODE 41 +#define SROM4_REGREV 42 +#define SROM5_CCODE 34 +#define SROM5_REGREV 35 + +#define SROM4_LEDBH10 43 +#define SROM4_LEDBH32 44 +#define SROM5_LEDBH10 59 +#define SROM5_LEDBH32 60 + +#define SROM4_LEDDC 45 +#define SROM5_LEDDC 45 + +#define SROM4_AA 46 + +#define SROM4_AG10 47 +#define SROM4_AG32 48 + +#define SROM4_TXPID2G 49 +#define SROM4_TXPID5G 51 +#define SROM4_TXPID5GL 53 +#define SROM4_TXPID5GH 55 + +#define SROM4_TXRXC 61 +#define SROM4_TXCHAIN_MASK 0x000f +#define SROM4_TXCHAIN_SHIFT 0 +#define SROM4_RXCHAIN_MASK 0x00f0 +#define SROM4_RXCHAIN_SHIFT 4 +#define SROM4_SWITCH_MASK 0xff00 +#define SROM4_SWITCH_SHIFT 8 + +/* Per-path fields */ +#define MAX_PATH_SROM 4 +#define SROM4_PATH0 64 +#define SROM4_PATH1 87 +#define SROM4_PATH2 110 +#define SROM4_PATH3 133 + +#define SROM4_2G_ITT_MAXP 0 +#define SROM4_2G_PA 1 +#define SROM4_5G_ITT_MAXP 5 +#define SROM4_5GLH_MAXP 6 +#define SROM4_5G_PA 7 +#define SROM4_5GL_PA 11 +#define SROM4_5GH_PA 15 + +/* All the miriad power offsets */ +#define SROM4_2G_CCKPO 156 +#define SROM4_2G_OFDMPO 157 +#define SROM4_5G_OFDMPO 159 +#define SROM4_5GL_OFDMPO 161 +#define SROM4_5GH_OFDMPO 163 +#define SROM4_2G_MCSPO 165 +#define SROM4_5G_MCSPO 173 +#define SROM4_5GL_MCSPO 181 +#define SROM4_5GH_MCSPO 189 +#define SROM4_CDDPO 197 +#define SROM4_STBCPO 198 +#define SROM4_BW40PO 199 +#define SROM4_BWDUPPO 200 +#define SROM4_CRCREV 219 + +/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. + * This is acombined srom for both MIMO and SISO boards, usable in + * the .130 4Kilobit OTP with hardware redundancy. + */ +#define SROM8_BREV 65 + +#define SROM8_BFL0 66 +#define SROM8_BFL1 67 +#define SROM8_BFL2 68 +#define SROM8_BFL3 69 + +#define SROM8_MACHI 70 +#define SROM8_MACMID 71 +#define SROM8_MACLO 72 + +#define SROM8_CCODE 73 +#define SROM8_REGREV 74 + +#define SROM8_LEDBH10 75 +#define SROM8_LEDBH32 76 + +#define SROM8_LEDDC 77 + +#define SROM8_AA 78 + +#define SROM8_AG10 79 +#define SROM8_AG32 80 + +#define SROM8_TXRXC 81 + +#define SROM8_BXARSSI2G 82 +#define SROM8_BXARSSI5G 83 +#define SROM8_TRI52G 84 +#define SROM8_TRI5GHL 85 +#define SROM8_RXPO52G 86 + +#define SROM8_FEM2G 87 +#define SROM8_FEM5G 88 +#define SROM8_FEM_ANTSWLUT_MASK 0xf800 +#define SROM8_FEM_ANTSWLUT_SHIFT 11 +#define SROM8_FEM_TR_ISO_MASK 0x0700 +#define SROM8_FEM_TR_ISO_SHIFT 8 +#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 +#define SROM8_FEM_PDET_RANGE_SHIFT 3 +#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 +#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 +#define SROM8_FEM_TSSIPOS_MASK 0x0001 +#define SROM8_FEM_TSSIPOS_SHIFT 0 + +#define SROM8_THERMAL 89 + +/* Temp sense related entries */ +#define SROM8_MPWR_RAWTS 90 +#define SROM8_TS_SLP_OPT_CORRX 91 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ +#define SROM8_FOC_HWIQ_IQSWP 92 + +/* Temperature delta for PHY calibration */ +#define SROM8_PHYCAL_TEMPDELTA 93 + +/* Per-path offsets & fields */ +#define SROM8_PATH0 96 +#define SROM8_PATH1 112 +#define SROM8_PATH2 128 +#define SROM8_PATH3 144 + +#define SROM8_2G_ITT_MAXP 0 +#define SROM8_2G_PA 1 +#define SROM8_5G_ITT_MAXP 4 +#define SROM8_5GLH_MAXP 5 +#define SROM8_5G_PA 6 +#define SROM8_5GL_PA 9 +#define SROM8_5GH_PA 12 + +/* All the miriad power offsets */ +#define SROM8_2G_CCKPO 160 + +#define SROM8_2G_OFDMPO 161 +#define SROM8_5G_OFDMPO 163 +#define SROM8_5GL_OFDMPO 165 +#define SROM8_5GH_OFDMPO 167 + +#define SROM8_2G_MCSPO 169 +#define SROM8_5G_MCSPO 177 +#define SROM8_5GL_MCSPO 185 +#define SROM8_5GH_MCSPO 193 + +#define SROM8_CDDPO 201 +#define SROM8_STBCPO 202 +#define SROM8_BW40PO 203 +#define SROM8_BWDUPPO 204 + +/* SISO PA parameters are in the path0 spaces */ +#define SROM8_SISO 96 + +/* Legacy names for SISO PA paramters */ +#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) +#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) +#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) +#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) +#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) +#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) +#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) +#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) +#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) +#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) +#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) +#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) +#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) +#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) +#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) + +/* SROM REV 9 */ +#define SROM9_2GPO_CCKBW20 160 +#define SROM9_2GPO_CCKBW20UL 161 +#define SROM9_2GPO_LOFDMBW20 162 +#define SROM9_2GPO_LOFDMBW20UL 164 + +#define SROM9_5GLPO_LOFDMBW20 166 +#define SROM9_5GLPO_LOFDMBW20UL 168 +#define SROM9_5GMPO_LOFDMBW20 170 +#define SROM9_5GMPO_LOFDMBW20UL 172 +#define SROM9_5GHPO_LOFDMBW20 174 +#define SROM9_5GHPO_LOFDMBW20UL 176 + +#define SROM9_2GPO_MCSBW20 178 +#define SROM9_2GPO_MCSBW20UL 180 +#define SROM9_2GPO_MCSBW40 182 + +#define SROM9_5GLPO_MCSBW20 184 +#define SROM9_5GLPO_MCSBW20UL 186 +#define SROM9_5GLPO_MCSBW40 188 +#define SROM9_5GMPO_MCSBW20 190 +#define SROM9_5GMPO_MCSBW20UL 192 +#define SROM9_5GMPO_MCSBW40 194 +#define SROM9_5GHPO_MCSBW20 196 +#define SROM9_5GHPO_MCSBW20UL 198 +#define SROM9_5GHPO_MCSBW40 200 + +#define SROM9_PO_MCS32 202 +#define SROM9_PO_LOFDM40DUP 203 + +/* SROM flags (see sromvar_t) */ #define SRFL_MORE 1 /* value continues as described by the next entry */ #define SRFL_NOFFS 2 /* value bits can't be all one's */ #define SRFL_PRHEX 4 /* value is in hexdecimal format */ @@ -36,6 +361,23 @@ typedef struct { #define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ #define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ +/* Max. nvram variable table size */ +#define MAXSZ_NVRAM_VARS 4096 + +typedef struct { + const char *name; + u32 revmask; + u32 flags; + u16 off; + u16 mask; +} sromvar_t; + +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; + /* Assumptions: * - Ethernet address spans across 3 consective words * @@ -48,7 +390,6 @@ typedef struct { * - The last entry's name field must be NULL to indicate the end of the table. Other * entries must have non-NULL name. */ - static const sromvar_t pci_sromvars[] = { {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, @@ -437,77 +778,555 @@ static const sromvar_t perpath_pci_sromvars[] = { {NULL, 0, 0, 0, 0} }; -#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) -#define PHY_TYPE_N 4 /* N-Phy value */ -#define PHY_TYPE_LP 5 /* LP-Phy value */ -#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ -#if !defined(PHY_TYPE_NULL) -#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ -#endif /* !defined(PHY_TYPE_NULL) */ +static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); +static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, + uint *count); +static int sprom_read_pci(struct si_pub *sih, u16 *sprom, + uint wordoff, u16 *buf, uint nwords, bool check_crc); +#if defined(BCMNVRAMR) +static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz); +#endif +static u16 srom_cc_cmd(struct si_pub *sih, void *ccregs, u32 cmd, + uint wordoff, u16 data); -typedef struct { - u16 phy_type; - u16 bandrange; - u16 chain; - const char *vars; -} pavars_t; - -static const pavars_t pavars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, - "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, - "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, - "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, - "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, - /* LPPHY */ - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, - {PHY_TYPE_NULL, 0, 0, ""} -}; +static int initvars_table(char *start, char *end, + char **vars, uint *count); -typedef struct { - u16 phy_type; - u16 bandrange; - const char *vars; -} povars_t; - -static const povars_t povars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, - "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " - "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, - "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " - "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, - "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " - "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, - "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " - "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, - {PHY_TYPE_NULL, 0, ""} -}; +/* Initialization of varbuf structure */ +static void varbuf_init(varbuf_t *b, char *buf, uint size) +{ + b->size = size; + b->base = b->buf = buf; +} -typedef struct { - u8 tag; /* Broadcom subtag name */ - u8 len; /* Length field of the tuple, note that it includes the - * subtag name (1 byte): 1 + tuple content length - */ - const char *params; -} cis_tuple_t; - -#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ -#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ -#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ -#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ - -#endif /* _bcmsrom_tbl_h_ */ +/* 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(struct si_pub *sih, uint bustype, void *curmap, + char **vars, uint *count) +{ + uint len; + + len = 0; + + if (vars == NULL || count == NULL) + return 0; + + *vars = NULL; + *count = 0; + + if (curmap != NULL && bustype == PCI_BUS) + return initvars_srom_pci(sih, curmap, vars, count); + + 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(struct si_pub *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(struct si_pub *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 (brcmu_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(struct si_pub *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 (brcmu_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; +} + +/* 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(struct si_pub *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 = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); + if (!base) { + err = -2; + goto errout; + } + + 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'; + + err = initvars_table(base, vp, vars, count); + + errout: + if (base) + kfree(base); + + kfree(srom); + return err; +} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h b/drivers/staging/brcm80211/brcmsmac/srom.h index 51a223880bcf..ee4f8801e7cd 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h +++ b/drivers/staging/brcm80211/brcmsmac/srom.h @@ -14,23 +14,19 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef phy_version_h_ -#define phy_version_h_ +#ifndef _BRCM_SROM_H_ +#define _BRCM_SROM_H_ -#define PHY_MAJOR_VERSION 1 +/* Prototypes */ +extern int srom_var_init(struct si_pub *sih, uint bus, void *curmap, + char **vars, uint *count); -#define PHY_MINOR_VERSION 82 +extern int srom_read(struct si_pub *sih, uint bus, void *curmap, + uint byteoff, uint nbytes, u16 *buf, bool check_crc); -#define PHY_RC_NUMBER 8 - -#define PHY_INCREMENTAL_NUMBER 0 - -#define PHY_BUILD_NUMBER 0 - -#define PHY_VERSION { 1, 82, 8, 0 } - -#define PHY_VERSION_NUM 0x01520800 - -#define PHY_VERSION_STR "1.82.8.0" - -#endif /* phy_version_h_ */ +/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP + * and extract from it into name=value pairs + */ +extern int srom_parsecis(u8 **pcis, uint ciscnt, + char **vars, uint *count); +#endif /* _BRCM_SROM_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/stf.c index c4f58172182d..5f98804ec7bd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/stf.c @@ -17,30 +17,22 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <proto/802.11.h> - -#include <bcmdefs.h> -#include <bcmutils.h> +#include <defs.h> +#include <brcmu_utils.h> #include <aiutils.h> -#include <wlioctl.h> -#include <bcmwifi.h> -#include <bcmnvram.h> -#include <sbhnddma.h> +#include <brcmu_wifi.h> +#include "dma.h" -#include "wlc_types.h" +#include "types.h" #include "d11.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wlc_bmac.h" -#include "wlc_stf.h" +#include "rate.h" +#include "scb.h" +#include "pub.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" +#include "bmac.h" +#include "stf.h" #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 @@ -364,39 +356,6 @@ void wlc_stf_detach(struct wlc_info *wlc) { } -int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) -{ - 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 : -EINVAL); - - switch (val) { - case -1: - val = ANT_TX_DEF; - break; - case 0: - val = ANT_TX_FORCE_0; - break; - case 1: - val = ANT_TX_FORCE_1; - break; - case 3: - val = ANT_TX_LAST_RX; - break; - default: - bcmerror = -EINVAL; - break; - } - - if (bcmerror == 0) - wlc->stf->txant = (s8) val; - - return bcmerror; - -} - /* * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain * change diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/stf.h index 2b1180b128a8..75e8205a2c41 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h +++ b/drivers/staging/brcm80211/brcmsmac/stf.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_stf_h_ -#define _wlc_stf_h_ +#ifndef _BRCM_STF_H_ +#define _BRCM_STF_H_ extern int wlc_stf_attach(struct wlc_info *wlc); extern void wlc_stf_detach(struct wlc_info *wlc); @@ -28,11 +28,9 @@ extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); - -extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); -#endif /* _wlc_stf_h_ */ +#endif /* _BRCM_STF_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/types.h index 85fbd0635310..e907990f74ca 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h +++ b/drivers/staging/brcm80211/brcmsmac/types.h @@ -14,21 +14,69 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_cfg_h_ -#define _wlc_cfg_h_ - -#define NBANDS(wlc) ((wlc)->pub->_nbands) -#define NBANDS_PUB(pub) ((pub)->_nbands) -#define NBANDS_HW(hw) ((hw)->_nbands) - -#define IS_SINGLEBAND_5G(device) 0 +#ifndef _BRCM_TYPES_H_ +#define _BRCM_TYPES_H_ + +/* Bus types */ +#define SI_BUS 0 /* SOC Interconnect */ +#define PCI_BUS 1 /* PCI target */ +#define SDIO_BUS 3 /* SDIO target */ +#define JTAG_BUS 4 /* JTAG */ +#define USB_BUS 5 /* USB (does not support R/W REG) */ +#define SPI_BUS 6 /* gSPI target */ +#define RPC_BUS 7 /* RPC target */ + +#define WL_CHAN_FREQ_RANGE_2G 0 +#define WL_CHAN_FREQ_RANGE_5GL 1 +#define WL_CHAN_FREQ_RANGE_5GM 2 +#define WL_CHAN_FREQ_RANGE_5GH 3 + +#define MAX_DMA_SEGS 4 + +/* boardflags */ +#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ +#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ +#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_NOPA 0x00010000 /* Board has no PA */ +#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_PALDO 0x02000000 /* Power topology uses PALDO */ +#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ + +/* boardflags2 */ +#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ +#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ +#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ +#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_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_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_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 */ +#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON" + * Most drivers will turn it off without this flag + * to save power. + */ + +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ +#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 */ /* **** Core type/rev defaults **** */ -#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 +#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 * also need to update wlc.h MAXCOREREV */ -#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: +#define NCONF 0x000001ff /* Supported nphy revs: * 0 4321a0 * 1 4321a1 * 2 4321b0/b1/c0/c1 @@ -40,35 +88,19 @@ * 8 5357a0, 43236a0 */ -#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: +#define LCNCONF 0x00000007 /* Supported lcnphy revs: * 0 4313a0, 4336a0, 4330a0 * 1 * 2 4330a0 */ -#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: +#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs: * 0 4329a0/k0 * 1 4329b0/4329C0 * 2 4319a0 * 3 5356a0 */ - -/* For undefined values, use defaults */ -#ifndef D11CONF -#define D11CONF D11_DEFAULT -#endif -#ifndef NCONF -#define NCONF NPHY_DEFAULT -#endif -#ifndef LCNCONF -#define LCNCONF LCNPHY_DEFAULT -#endif - -#ifndef SSLPNCONF -#define SSLPNCONF SSLPNPHY_DEFAULT -#endif - /******************************************************************** * Phy/Core Configuration. Defines macros to to check core phy/rev * * compile-time configuration. Defines default core support. * @@ -142,40 +174,11 @@ #define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break #define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break -#if (D11CONF ^ (D11CONF & D11_DEFAULT)) -#error "Unsupported MAC revision configured" -#endif -#if (NCONF ^ (NCONF & NPHY_DEFAULT)) -#error "Unsupported NPHY revision configured" -#endif -#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) -#error "Unsupported LPPHY revision configured" -#endif - -/* *** Consistency checks *** */ -#if !D11CONF -#error "No MAC revisions configured!" -#endif - -#if !NCONF && !LCNCONF && !SSLPNCONF -#error "No PHY configured!" -#endif - /* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ #define _PHYCONF_N (1 << PHY_TYPE_N) - -#if LCNCONF #define _PHYCONF_LCN (1 << PHY_TYPE_LCN) -#else -#define _PHYCONF_LCN 0 -#endif /* LCNCONF */ - -#if SSLPNCONF #define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) -#else -#define _PHYCONF_SSLPN 0 -#endif /* SSLPNCONF */ #define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) @@ -207,28 +210,11 @@ * * *********************************************** */ -#ifndef NTXD #define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ -#endif /* NTXD */ -#ifndef NRXD #define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#endif /* NRXD */ - -#ifndef NRXBUFPOST #define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ -#endif /* NRXBUFPOST */ - -#ifndef MAXSCB /* station control blocks in cache */ #define MAXSCB 32 /* Maximum SCBs in cache for STA */ -#endif /* MAXSCB */ - -#ifndef AMPDU_NUM_MPDU #define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ -#endif /* AMPDU_NUM_MPDU */ - -#ifndef AMPDU_NUM_MPDU_3STREAMS -#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ -#endif /* AMPDU_NUM_MPDU_3STREAMS */ /* Count of packet callback structures. either of following * 1. Set to the number of SCBs since a STA @@ -236,45 +222,145 @@ * queue up an "are you there?" Null Data callback for each associated STA * 2. controlled by tunable config file */ -#ifndef MAXPKTCB #define MAXPKTCB MAXSCB /* Max number of packet callbacks */ -#endif /* MAXPKTCB */ - -#ifndef CTFPOOLSZ -#define CTFPOOLSZ 128 -#endif /* CTFPOOLSZ */ /* NetBSD also needs to keep track of this */ #define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ #define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ -#ifndef WLC_MAXBSSCFG #define WLC_MAXBSSCFG (1) /* max # BSS configs */ -#endif /* WLC_MAXBSSCFG */ - -#ifndef MAXBSS #define MAXBSS 64 /* max # available networks */ -#endif /* MAXBSS */ - -#ifndef WLC_DATAHIWAT #define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ -#endif /* WLC_DATAHIWAT */ - -#ifndef WLC_AMPDUDATAHIWAT #define WLC_AMPDUDATAHIWAT 255 -#endif /* WLC_AMPDUDATAHIWAT */ /* bounded rx loops */ -#ifndef RXBND #define RXBND 8 /* max # frames to process in wlc_recv() */ -#endif /* RXBND */ -#ifndef TXSBND #define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ -#endif /* TXSBND */ + +#define WLBANDINITFN(_fn) _fn #define BAND_5G(bt) ((bt) == WLC_BAND_5G) #define BAND_2G(bt) ((bt) == WLC_BAND_2G) -#define WLBANDINITDATA(_data) _data -#define WLBANDINITFN(_fn) _fn - -#endif /* _wlc_cfg_h_ */ +#define BCMMSG(dev, fmt, args...) \ +do { \ + if (brcm_msg_level & LOG_TRACE_VAL) \ + wiphy_err(dev, "%s: " fmt, __func__, ##args); \ +} while (0) + +#define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL) + +/* register access macros */ +#ifndef __BIG_ENDIAN +#ifndef __mips__ +#define R_REG(r) \ + ({\ + sizeof(*(r)) == sizeof(u8) ? \ + readb((volatile u8*)(r)) : \ + sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ + readl((volatile u32*)(r)); \ + }) +#else /* __mips__ */ +#define R_REG(r) \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = readb((volatile u8*)(r)); \ + break; \ + case sizeof(u16): \ + __osl_v = readw((volatile u16*)(r)); \ + break; \ + case sizeof(u32): \ + __osl_v = \ + readl((volatile u32*)(r)); \ + break; \ + } \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + }) +#endif /* __mips__ */ + +#define W_REG(r, v) do { \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), (volatile u8*)(r)); break; \ + case sizeof(u16): \ + writew((u16)(v), (volatile u16*)(r)); break; \ + case sizeof(u32): \ + writel((u32)(v), (volatile u32*)(r)); break; \ + }; \ + } while (0) +#else /* __BIG_ENDIAN */ +#define R_REG(r) \ + ({ \ + __typeof(*(r)) __osl_v; \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = \ + readb((volatile u8*)((r)^3)); \ + break; \ + case sizeof(u16): \ + __osl_v = \ + readw((volatile u16*)((r)^2)); \ + break; \ + case sizeof(u32): \ + __osl_v = readl((volatile u32*)(r)); \ + break; \ + } \ + __osl_v; \ + }) + +#define W_REG(r, v) do { \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), \ + (volatile u8*)((r)^3)); break; \ + case sizeof(u16): \ + writew((u16)(v), \ + (volatile u16*)((r)^2)); break; \ + case sizeof(u32): \ + writel((u32)(v), \ + (volatile u32*)(r)); break; \ + } \ + } while (0) +#endif /* __BIG_ENDIAN */ + +#ifdef __mips__ +/* + * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder + * transactions. As a fix, a read after write is performed on certain places + * in the code. Older chips and the newer 5357 family don't require this fix. + */ +#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); }) +#else +#define W_REG_FLUSH(r, v) W_REG((r), (v)) +#endif /* __mips__ */ + +#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) +#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) + +#define SET_REG(r, mask, val) \ + W_REG((r), ((R_REG(r) & ~(mask)) | (val))) + + +/* forward declarations */ +struct sk_buff; +struct brcms_info; +struct wlc_info; +struct wlc_hw_info; +struct wlc_if; +struct brcms_if; +struct ampdu_info; +struct antsel_info; +struct bmac_pmq; +struct d11init; +struct dma_pub; +struct wlc_bsscfg; +struct brcmu_strbuf; +struct si_pub; + +/* brcm_msg_level is a bit vector with defs in defs.h */ +extern u32 brcm_msg_level; + +#endif /* _BRCM_TYPES_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c index cc00dd19746b..32d5196d6491 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c @@ -15,8 +15,8 @@ */ #include <linux/types.h> -#include <bcmdefs.h> -#include <wl_ucode.h> +#include <defs.h> +#include <ucode_loader.h> enum { D11UCODE_NAMETAG_START = 0, @@ -53,59 +53,63 @@ u32 bcm43xx_24_lcnsz; u32 *bcm43xx_bommajor; u32 *bcm43xx_bomminor; -int wl_ucode_data_init(struct wl_info *wl) +int brcms_ucode_data_init(struct brcms_info *wl) { int rc; - rc = wl_check_firmwares(wl); + rc = brcms_check_firmwares(wl); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, - D11LCN0BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, + D11LCN0BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, - D11LCN1BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, + D11LCN1BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, - D11LCN2BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, + D11LCN2BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, - D11N0ABSINITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11n0absinitvals16, + D11N0ABSINITVALS16); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, D11UCODE_OVERSIGHT16_MIMO); - rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, + rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, D11UCODE_OVERSIGHT24_LCN); - rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, + rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, D11UCODE_OVERSIGHT_BOMMAJOR); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, D11UCODE_OVERSIGHT_BOMMINOR); return rc; } -void wl_ucode_data_free(void) +void brcms_ucode_data_free(void) { - wl_ucode_free_buf((void *)d11lcn0bsinitvals24); - wl_ucode_free_buf((void *)d11lcn0initvals24); - wl_ucode_free_buf((void *)d11lcn1bsinitvals24); - wl_ucode_free_buf((void *)d11lcn1initvals24); - wl_ucode_free_buf((void *)d11lcn2bsinitvals24); - wl_ucode_free_buf((void *)d11lcn2initvals24); - wl_ucode_free_buf((void *)d11n0absinitvals16); - wl_ucode_free_buf((void *)d11n0bsinitvals16); - wl_ucode_free_buf((void *)d11n0initvals16); - wl_ucode_free_buf((void *)bcm43xx_16_mimo); - wl_ucode_free_buf((void *)bcm43xx_24_lcn); - wl_ucode_free_buf((void *)bcm43xx_bommajor); - wl_ucode_free_buf((void *)bcm43xx_bomminor); + brcms_ucode_free_buf((void *)d11lcn0bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn0initvals24); + brcms_ucode_free_buf((void *)d11lcn1bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn1initvals24); + brcms_ucode_free_buf((void *)d11lcn2bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn2initvals24); + brcms_ucode_free_buf((void *)d11n0absinitvals16); + brcms_ucode_free_buf((void *)d11n0bsinitvals16); + brcms_ucode_free_buf((void *)d11n0initvals16); + brcms_ucode_free_buf((void *)bcm43xx_16_mimo); + brcms_ucode_free_buf((void *)bcm43xx_24_lcn); + brcms_ucode_free_buf((void *)bcm43xx_bommajor); + brcms_ucode_free_buf((void *)bcm43xx_bomminor); return; } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h index 6933fda0e6a0..ca53deced7bf 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h +++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "types.h" /* forward structure declarations */ + #define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ #define MAX_FW_SIZE 150000 @@ -39,11 +41,12 @@ extern u32 bcm43xx_16_mimosz; extern u32 *bcm43xx_24_lcn; extern u32 bcm43xx_24_lcnsz; -extern int wl_ucode_data_init(struct wl_info *wl); -extern void wl_ucode_data_free(void); +extern int brcms_ucode_data_init(struct brcms_info *wl); +extern void brcms_ucode_data_free(void); -extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); -extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, +extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, + unsigned int idx); +extern int brcms_ucode_init_uint(struct brcms_info *wl, unsigned *data, unsigned int idx); -extern void wl_ucode_free_buf(void *); -extern int wl_check_firmwares(struct wl_info *wl); +extern void brcms_ucode_free_buf(void *); +extern int brcms_check_firmwares(struct brcms_info *wl); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h deleted file mode 100644 index 5582de3ee721..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h +++ /dev/null @@ -1,92 +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 _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 BCMMSG(dev, fmt, args...) \ -do { \ - if (wl_msg_level & WL_TRACE_VAL) \ - wiphy_err(dev, "%s: " fmt, __func__, ##args); \ -} while (0) - -#ifdef BCMDBG - - -/* Extra message control for AMPDU debugging */ -#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ -#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ -#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ -#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ -#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ -#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ -#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ -#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ - -extern u32 wl_ampdu_dbg; - -#define WL_AMPDU_PRINT(level, fmt, args...) \ -do { \ - if (wl_ampdu_dbg & level) { \ - WL_AMPDU(fmt, ##args); \ - } \ -} while (0) - -#define WL_AMPDU_UPDN(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) -#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) -#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) -#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) - -#else /* BCMDBG */ - - -#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR_ON() 0 -#define WL_AMPDU_HW_ON() 0 -#define WL_AMPDU_HWTXS_ON() 0 - -#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 deleted file mode 100644 index 0fe0b24b586f..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ /dev/null @@ -1,47 +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 _wl_export_h_ -#define _wl_export_h_ - -/* misc callbacks */ -struct wl_info; -struct wl_if; -struct wlc_if; -extern void wl_init(struct wl_info *wl); -extern uint wl_reset(struct wl_info *wl); -extern void wl_intrson(struct wl_info *wl); -extern u32 wl_intrsoff(struct wl_info *wl); -extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); -extern int wl_up(struct wl_info *wl); -extern void wl_down(struct wl_info *wl); -extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio); -extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); -extern bool wl_rfkill_set_hw_state(struct wl_info *wl); - -/* timer functions */ -struct wl_timer; -extern struct wl_timer *wl_init_timer(struct wl_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -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/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h deleted file mode 100644 index 2572541bde9b..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ /dev/null @@ -1,135 +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 _WLC_BSSCFG_H_ -#define _WLC_BSSCFG_H_ - -/* Check if a particular BSS config is AP or STA */ -#define BSSCFG_AP(cfg) (0) -#define BSSCFG_STA(cfg) (1) - -#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) - -#define NTXRATE 64 /* # tx MPDUs rate is reported for */ -#define MAXMACLIST 64 /* max # source MAC matches */ -#define BCN_TEMPLATE_COUNT 2 - -/* Iterator for "associated" STA bss configs: - (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */ -#define FOREACH_AS_STA(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) - -/* As above for all non-NULL BSS configs */ -#define FOREACH_BSS(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx])) - -/* BSS configuration state */ -struct wlc_bsscfg { - struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ - bool up; /* is this configuration up operational */ - bool enable; /* is this configuration enabled */ - bool associated; /* is BSS in ASSOCIATED state */ - bool BSS; /* infraustructure or adhac */ - bool dtim_programmed; - - u8 SSID_len; /* the length of SSID */ - u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ - struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ - s8 _idx; /* the index of this bsscfg, - * assigned at wlc_bsscfg_alloc() - */ - /* MAC filter */ - uint nmac; /* # of entries on maclist array */ - int macmode; /* allow/deny stations on maclist array */ - struct ether_addr *maclist; /* list of source MAC addrs to match */ - - /* security */ - u32 wsec; /* wireless security bitvec */ - s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ - s16 openshared; /* try Open auth first, then Shared Key */ - bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ - bool eap_restrict; /* restrict data until 802.1X auth succeeds */ - u16 WPA_auth; /* WPA: authenticated key management */ - bool wpa2_preauth; /* default is true, wpa_cap sets value */ - bool wsec_portopen; /* indicates keys are plumbed */ - wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ - int wsec_index; /* 0-3: default tx key, -1: not set */ - wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - - /* TKIP countermeasures */ - bool tkip_countermeasures; /* flags TKIP no-assoc period */ - u32 tk_cm_dt; /* detect timer */ - u32 tk_cm_bt; /* blocking timer */ - u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ - bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - - u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ - u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ - u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ - u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ - - u32 flags; /* WLC_BSSCFG flags; see below */ - - u8 *bcn; /* AP beacon */ - uint bcn_len; /* AP beacon length */ - bool ar_disassoc; /* disassociated in associated recreation */ - - int auth_atmptd; /* auth type (open/shared) attempted */ - - pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ - uint npmkid_cand; /* num PMKID candidates */ - pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ - uint npmkid; /* num cached PMKIDs */ - - wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ - - /* PM states */ - bool PMawakebcn; /* bcn recvd during current waking state */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool priorPMstate; /* Detecting PM state transitions */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - - /* BSSID entry in RCMTA, use the wsec key management infrastructure to - * manage the RCMTA entries. - */ - wsec_key_t *rcmta; - - /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ - u16 ID; - - uint txrspecidx; /* index into tx rate circular buffer */ - ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ -}; - -#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ -#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ - -#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) -#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) - -/* Extend N_ENAB to per-BSS */ -#define BSS_N_ENAB(wlc, cfg) \ - (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) - -#define MBSS_BCN_ENAB(cfg) 0 -#define MBSS_PRB_ENAB(cfg) 0 -#define SOFTBCN_ENAB(pub) (0) -#define SOFTPRB_ENAB(pub) (0) -#define wlc_bsscfg_tx_check(a) do { } while (0); - -#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h deleted file mode 100644 index cab10c737937..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ /dev/null @@ -1,140 +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 _wlc_key_h_ -#define _wlc_key_h_ - -struct scb; -struct wlc_info; -struct wlc_bsscfg; -/* Maximum # of keys that wl driver supports in S/W. - * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. - */ -#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ -#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ - -#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ - -#define WPA2_GTK_MAX 3 - -/* -* Max # of keys currently supported: -* -* s/w keys if WSEC_SW(wlc->wsec). -* h/w keys otherwise. -*/ -#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS - -/* number of 802.11 default (non-paired, group keys) */ -#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ - -/* Max # of hardware keys supported */ -#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS - -/* Max # of hardware TKIP MIC keys supported */ -#define WLC_MAX_TKMIC_HW_KEYS(wlc) (WSEC_MAX_TKMIC_ENGINE_KEYS) - -#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ - ((((wlc)->machwcap & MCAP_TKIPMIC)) && \ - (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ - !WSEC_SOFTKEY(wlc, key, bsscfg) && \ - WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ - (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) - -/* index of key in key table */ -#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) - -#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ - WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) - -/* get a key, non-NULL only if key allocated and not clear */ -#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ - (wlc)->wsec_keys[i] : NULL) - -#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) - -/* default key */ -#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ - (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) - -/* Macros for key management in IBSS mode */ -#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ -#define WSEC_IBSS_RCMTA_INDEX(idx) \ - (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) - -/* contiguous # key slots for infrastructure mode STA */ -#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 - -typedef struct wsec_iv { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ -} wsec_iv_t; - -#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ - -typedef struct wsec_key { - u8 ea[ETH_ALEN]; /* per station */ - u8 idx; /* key index in wsec_keys array */ - u8 id; /* key ID [0-3] */ - u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u8 rcmta; /* rcmta entry index, same as idx by default */ - u16 flags; /* misc flags */ - u8 algo_hw; /* cache for hw register */ - u8 aes_mode; /* cache for hw register */ - s8 iv_len; /* IV length */ - s8 icv_len; /* ICV length */ - u32 len; /* key length..don't move this var */ - /* data is 4byte aligned */ - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ - wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ - wsec_iv_t txiv; /* Tx IV */ - -} wsec_key_t; - -#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -/* For use with wsec_key_t.flags */ - -#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ -#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ -#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ -#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) (-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) -#define wlc_key_delete(a, b, c) do {} while (0) -#define wlc_scb_key_delete(a, b) do {} while (0) -#define wlc_key_lookup(a, b, c, d, e) (NULL) -#define wlc_key_hw_init_all(a) do {} while (0) -#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) (-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) (-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) -#define wlc_key_scb_delete(a, b) do {} while (0) - -#endif /* _wlc_key_h_ */ |