brcm80211: move under broadcom vendor directory
Part of reorganising wireless drivers directory and Kconfig. Note that I had to edit Makefiles from subdirectories to use the new location. Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
48
drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
Normal file
48
drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# 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.
|
||||
|
||||
ccflags-y := \
|
||||
-D__CHECK_ENDIAN__ \
|
||||
-Idrivers/net/wireless/broadcom/brcm80211/brcmsmac \
|
||||
-Idrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy \
|
||||
-Idrivers/net/wireless/broadcom/brcm80211/include
|
||||
|
||||
brcmsmac-y := \
|
||||
mac80211_if.o \
|
||||
ucode_loader.o \
|
||||
ampdu.o \
|
||||
antsel.o \
|
||||
channel.o \
|
||||
main.o \
|
||||
phy_shim.o \
|
||||
pmu.o \
|
||||
rate.o \
|
||||
stf.o \
|
||||
aiutils.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 \
|
||||
dma.o \
|
||||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += brcmsmac.o
|
710
drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c
Normal file
710
drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* File contents: support functions for PCI/PCIe
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <chipcommon.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <soc.h>
|
||||
#include "types.h"
|
||||
#include "pub.h"
|
||||
#include "pmu.h"
|
||||
#include "aiutils.h"
|
||||
|
||||
/* slow_clk_ctl */
|
||||
/* slow clock source mask */
|
||||
#define SCC_SS_MASK 0x00000007
|
||||
/* source of slow clock is LPO */
|
||||
#define SCC_SS_LPO 0x00000000
|
||||
/* source of slow clock is crystal */
|
||||
#define SCC_SS_XTAL 0x00000001
|
||||
/* source of slow clock is PCI */
|
||||
#define SCC_SS_PCI 0x00000002
|
||||
/* LPOFreqSel, 1: 160Khz, 0: 32KHz */
|
||||
#define SCC_LF 0x00000200
|
||||
/* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
|
||||
#define SCC_LP 0x00000400
|
||||
/* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
|
||||
#define SCC_FS 0x00000800
|
||||
/* IgnorePllOffReq, 1/0:
|
||||
* power logic ignores/honors PLL clock disable requests from core
|
||||
*/
|
||||
#define SCC_IP 0x00001000
|
||||
/* XtalControlEn, 1/0:
|
||||
* power logic does/doesn't disable crystal when appropriate
|
||||
*/
|
||||
#define SCC_XC 0x00002000
|
||||
/* XtalPU (RO), 1/0: crystal running/disabled */
|
||||
#define SCC_XP 0x00004000
|
||||
/* ClockDivider (SlowClk = 1/(4+divisor)) */
|
||||
#define SCC_CD_MASK 0xffff0000
|
||||
#define SCC_CD_SHIFT 16
|
||||
|
||||
/* system_clk_ctl */
|
||||
/* ILPen: Enable Idle Low Power */
|
||||
#define SYCC_IE 0x00000001
|
||||
/* ALPen: Enable Active Low Power */
|
||||
#define SYCC_AE 0x00000002
|
||||
/* ForcePLLOn */
|
||||
#define SYCC_FP 0x00000004
|
||||
/* Force ALP (or HT if ALPen is not set */
|
||||
#define SYCC_AR 0x00000008
|
||||
/* Force HT */
|
||||
#define SYCC_HR 0x00000010
|
||||
/* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
|
||||
#define SYCC_CD_MASK 0xffff0000
|
||||
#define SYCC_CD_SHIFT 16
|
||||
|
||||
#define CST4329_SPROM_OTP_SEL_MASK 0x00000003
|
||||
/* OTP is powered up, use def. CIS, no SPROM */
|
||||
#define CST4329_DEFCIS_SEL 0
|
||||
/* OTP is powered up, SPROM is present */
|
||||
#define CST4329_SPROM_SEL 1
|
||||
/* OTP is powered up, no SPROM */
|
||||
#define CST4329_OTP_SEL 2
|
||||
/* OTP is powered down, SPROM is present */
|
||||
#define CST4329_OTP_PWRDN 3
|
||||
|
||||
#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
|
||||
/* 12 mA drive strength */
|
||||
#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0
|
||||
/* 12 mA drive strength for later 43224s */
|
||||
#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0
|
||||
|
||||
/* 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 */
|
||||
/* 0 disable */
|
||||
#define CCTRL4331_BT_COEXIST (1<<0)
|
||||
/* 0 SECI is disabled (JTAG functional) */
|
||||
#define CCTRL4331_SECI (1<<1)
|
||||
/* 0 disable */
|
||||
#define CCTRL4331_EXT_LNA (1<<2)
|
||||
/* sprom/gpio13-15 mux */
|
||||
#define CCTRL4331_SPROM_GPIO13_15 (1<<3)
|
||||
/* 0 ext pa disable, 1 ext pa enabled */
|
||||
#define CCTRL4331_EXTPA_EN (1<<4)
|
||||
/* set drive out GPIO_CLK on sprom_cs pin */
|
||||
#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5)
|
||||
/* use sprom_cs pin as PCIE mdio interface */
|
||||
#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6)
|
||||
/* aband extpa will be at gpio2/5 and sprom_dout */
|
||||
#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7)
|
||||
/* override core control on pipe_AuxClkEnable */
|
||||
#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8)
|
||||
/* override core control on pipe_AuxPowerDown */
|
||||
#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9)
|
||||
/* pcie_auxclkenable */
|
||||
#define CCTRL4331_PCIE_AUXCLKEN (1<<10)
|
||||
/* pcie_pipe_pllpowerdown */
|
||||
#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11)
|
||||
/* enable bt_shd0 at gpio4 */
|
||||
#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16)
|
||||
/* enable bt_shd1 at gpio5 */
|
||||
#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17)
|
||||
|
||||
/* 4331 Chip specific ChipStatus register bits */
|
||||
/* crystal frequency 20/40Mhz */
|
||||
#define CST4331_XTAL_FREQ 0x00000001
|
||||
#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
|
||||
/* gpio [7:6], SDIO CIS selection */
|
||||
#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0
|
||||
#define CST4319_SPROM_OTP_SEL_SHIFT 6
|
||||
/* use default CIS, OTP is powered up */
|
||||
#define CST4319_DEFCIS_SEL 0x00000000
|
||||
/* use SPROM, OTP is powered up */
|
||||
#define CST4319_SPROM_SEL 0x00000040
|
||||
/* use OTP, OTP is powered up */
|
||||
#define CST4319_OTP_SEL 0x00000080
|
||||
/* use SPROM, OTP is powered down */
|
||||
#define CST4319_OTP_PWRDN 0x000000c0
|
||||
/* gpio [8], sdio/usb mode */
|
||||
#define CST4319_SDIO_USB_MODE 0x00000100
|
||||
#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
|
||||
/* PALDO is configured with external PNP */
|
||||
#define CST4319_PALDO_EXTPNP 0x00010000
|
||||
#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 */
|
||||
/* 12 mA drive strengh for later 4313 */
|
||||
#define CCTRL_4313_12MA_LED_DRIVE 0x00000007
|
||||
|
||||
/* 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
|
||||
|
||||
/* PCI config space bit 4 for 4306c0 slow clock source */
|
||||
#define PCI_CFG_GPIO_SCS 0x10
|
||||
/* PCI config space GPIO 14 for Xtal power-up */
|
||||
#define PCI_CFG_GPIO_XTAL 0x40
|
||||
/* PCI config space GPIO 15 for PLL power-down */
|
||||
#define PCI_CFG_GPIO_PLL 0x80
|
||||
|
||||
/* 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
|
||||
|
||||
#define NOREV -1 /* Invalid rev */
|
||||
|
||||
/* GPIO Based LED powersave defines */
|
||||
#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
|
||||
#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
|
||||
|
||||
/* 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
|
||||
|
||||
/* External PA enable mask */
|
||||
#define GPIO_CTRL_EPA_EN_MASK 0x40
|
||||
|
||||
#define DEFAULT_GPIOTIMERVAL \
|
||||
((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
|
||||
|
||||
#define BADIDX (SI_MAXCORES + 1)
|
||||
|
||||
#define IS_SIM(chippkg) \
|
||||
((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
|
||||
|
||||
#define GOODCOREADDR(x, b) \
|
||||
(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
|
||||
IS_ALIGNED((x), SI_CORE_SIZE))
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
static bool
|
||||
ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
|
||||
{
|
||||
/* no cores found, bail out */
|
||||
if (cc->bus->nr_cores == 0)
|
||||
return false;
|
||||
|
||||
/* get chipcommon rev */
|
||||
sii->pub.ccrev = cc->id.rev;
|
||||
|
||||
/* get chipcommon chipstatus */
|
||||
sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
|
||||
|
||||
/* get chipcommon capabilites */
|
||||
sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
|
||||
|
||||
/* get pmu rev and caps */
|
||||
if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
|
||||
sii->pub.pmucaps = bcma_read32(cc,
|
||||
CHIPCREGOFFS(pmucapabilities));
|
||||
sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct si_info *ai_doattach(struct si_info *sii,
|
||||
struct bcma_bus *pbus)
|
||||
{
|
||||
struct si_pub *sih = &sii->pub;
|
||||
struct bcma_device *cc;
|
||||
|
||||
sii->icbus = pbus;
|
||||
sii->pcibus = pbus->host_pci;
|
||||
|
||||
/* switch to Chipcommon core */
|
||||
cc = pbus->drv_cc.core;
|
||||
|
||||
sih->chip = pbus->chipinfo.id;
|
||||
sih->chiprev = pbus->chipinfo.rev;
|
||||
sih->chippkg = pbus->chipinfo.pkg;
|
||||
sih->boardvendor = pbus->boardinfo.vendor;
|
||||
sih->boardtype = pbus->boardinfo.type;
|
||||
|
||||
if (!ai_buscore_setup(sii, cc))
|
||||
goto exit;
|
||||
|
||||
/* === NVRAM, clock is ready === */
|
||||
bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
|
||||
bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
|
||||
|
||||
/* PMU specific initializations */
|
||||
if (ai_get_cccaps(sih) & CC_CAP_PMU) {
|
||||
(void)si_pmu_measure_alpclk(sih);
|
||||
}
|
||||
|
||||
return sii;
|
||||
|
||||
exit:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a si handle and do the attach.
|
||||
*/
|
||||
struct si_pub *
|
||||
ai_attach(struct bcma_bus *pbus)
|
||||
{
|
||||
struct si_info *sii;
|
||||
|
||||
/* alloc struct si_info */
|
||||
sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC);
|
||||
if (sii == NULL)
|
||||
return NULL;
|
||||
|
||||
if (ai_doattach(sii, pbus) == NULL) {
|
||||
kfree(sii);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct si_pub *) sii;
|
||||
}
|
||||
|
||||
/* may be called with core in reset */
|
||||
void ai_detach(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii;
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
|
||||
if (sii == NULL)
|
||||
return;
|
||||
|
||||
kfree(sii);
|
||||
}
|
||||
|
||||
/*
|
||||
* read/modify chipcommon core register.
|
||||
*/
|
||||
uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
|
||||
{
|
||||
struct bcma_device *cc;
|
||||
u32 w;
|
||||
struct si_info *sii;
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
cc = sii->icbus->drv_cc.core;
|
||||
|
||||
/* mask and set */
|
||||
if (mask || val)
|
||||
bcma_maskset32(cc, regoff, ~mask, val);
|
||||
|
||||
/* readback */
|
||||
w = bcma_read32(cc, regoff);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/* return the slow clock source - LPO, XTAL, or PCI */
|
||||
static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
|
||||
{
|
||||
return SCC_SS_XTAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the ILP (slowclock) min or max frequency
|
||||
* precondition: we've established the chip has dynamic clk control
|
||||
*/
|
||||
static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
|
||||
struct bcma_device *cc)
|
||||
{
|
||||
uint div;
|
||||
|
||||
/* Chipc rev 10 is InstaClock */
|
||||
div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
|
||||
div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
|
||||
return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
|
||||
}
|
||||
|
||||
static void
|
||||
ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
|
||||
{
|
||||
uint slowmaxfreq, pll_delay, slowclk;
|
||||
uint pll_on_delay, fref_sel_delay;
|
||||
|
||||
pll_delay = PLL_DELAY;
|
||||
|
||||
/*
|
||||
* If the slow clock is not sourced by the xtal then
|
||||
* add the xtal_on_delay since the xtal will also be
|
||||
* powered down by dynamic clk control logic.
|
||||
*/
|
||||
|
||||
slowclk = ai_slowclk_src(sih, cc);
|
||||
if (slowclk != SCC_SS_XTAL)
|
||||
pll_delay += XTAL_ON_DELAY;
|
||||
|
||||
/* Starting with 4318 it is ILP that is used for the delays */
|
||||
slowmaxfreq =
|
||||
ai_slowclk_freq(sih, false, cc);
|
||||
|
||||
pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
|
||||
fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
|
||||
|
||||
bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay);
|
||||
bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay);
|
||||
}
|
||||
|
||||
/* initialize power control delay registers */
|
||||
void ai_clkctl_init(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii = container_of(sih, struct si_info, pub);
|
||||
struct bcma_device *cc;
|
||||
|
||||
if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
|
||||
return;
|
||||
|
||||
cc = sii->icbus->drv_cc.core;
|
||||
if (cc == NULL)
|
||||
return;
|
||||
|
||||
/* set all Instaclk chip ILP to 1 MHz */
|
||||
bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
|
||||
(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
|
||||
|
||||
ai_clkctl_setdelay(sih, cc);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the value suitable for writing to the
|
||||
* dot11 core FAST_PWRUP_DELAY register
|
||||
*/
|
||||
u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii;
|
||||
struct bcma_device *cc;
|
||||
uint slowminfreq;
|
||||
u16 fpdelay;
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
if (ai_get_cccaps(sih) & CC_CAP_PMU) {
|
||||
fpdelay = si_pmu_fast_pwrup_delay(sih);
|
||||
return fpdelay;
|
||||
}
|
||||
|
||||
if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
|
||||
return 0;
|
||||
|
||||
fpdelay = 0;
|
||||
cc = sii->icbus->drv_cc.core;
|
||||
if (cc) {
|
||||
slowminfreq = ai_slowclk_freq(sih, false, cc);
|
||||
fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2)
|
||||
* 1000000) + (slowminfreq - 1)) / slowminfreq;
|
||||
}
|
||||
return fpdelay;
|
||||
}
|
||||
|
||||
/*
|
||||
* clock control policy function throught chipcommon
|
||||
*
|
||||
* set dynamic clk control mode (forceslow, forcefast, dynamic)
|
||||
* returns true if we are forcing fast clock
|
||||
* this is a wrapper over the next internal function
|
||||
* to allow flexible policy settings for outside caller
|
||||
*/
|
||||
bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
|
||||
{
|
||||
struct si_info *sii;
|
||||
struct bcma_device *cc;
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
|
||||
cc = sii->icbus->drv_cc.core;
|
||||
bcma_core_set_clockmode(cc, mode);
|
||||
return mode == BCMA_CLKMODE_FAST;
|
||||
}
|
||||
|
||||
/* Enable BT-COEX & Ex-PA for 4313 */
|
||||
void ai_epa_4313war(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii = container_of(sih, struct si_info, pub);
|
||||
struct bcma_device *cc;
|
||||
|
||||
cc = sii->icbus->drv_cc.core;
|
||||
|
||||
/* EPA Fix */
|
||||
bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK);
|
||||
}
|
||||
|
||||
/* check if the device is removed */
|
||||
bool ai_deviceremoved(struct si_pub *sih)
|
||||
{
|
||||
u32 w = 0;
|
||||
struct si_info *sii;
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
|
||||
if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
|
||||
return false;
|
||||
|
||||
pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
|
||||
if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
229
drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.h
Normal file
229
drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_AIUTILS_H_
|
||||
#define _BRCM_AIUTILS_H_
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* SOC Interconnect Address Map.
|
||||
* All regions may not exist on all chips.
|
||||
*/
|
||||
/* each core gets 4Kbytes for registers */
|
||||
#define SI_CORE_SIZE 0x1000
|
||||
/*
|
||||
* Max cores (this is arbitrary, for software
|
||||
* convenience and could be changed if we
|
||||
* make any larger chips
|
||||
*/
|
||||
#define SI_MAXCORES 16
|
||||
|
||||
/* Client Mode sb2pcitranslation2 size in bytes */
|
||||
#define SI_PCI_DMA_SZ 0x40000000
|
||||
|
||||
/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
|
||||
#define SI_PCIE_DMA_H32 0x80000000
|
||||
|
||||
/* chipcommon being the first core: */
|
||||
#define SI_CC_IDX 0
|
||||
|
||||
/* SOC Interconnect types (aka chip types) */
|
||||
#define SOCI_AI 1
|
||||
|
||||
/* A register that is common to all cores to
|
||||
* communicate w/PMU regarding clock control.
|
||||
*/
|
||||
#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
|
||||
|
||||
/* clk_ctl_st register */
|
||||
#define CCS_FORCEALP 0x00000001 /* force ALP request */
|
||||
#define CCS_FORCEHT 0x00000002 /* force HT request */
|
||||
#define CCS_FORCEILP 0x00000004 /* force ILP request */
|
||||
#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
|
||||
#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
|
||||
#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
|
||||
#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
|
||||
#define CCS_ERSRC_REQ_SHIFT 8
|
||||
#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
|
||||
#define CCS_HTAVAIL 0x00020000 /* HT is available */
|
||||
#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
|
||||
#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
|
||||
#define CCS_ERSRC_STS_SHIFT 24
|
||||
|
||||
/* HT avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_HTAVAIL 0x00010000
|
||||
/* ALP avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_ALPAVAIL 0x00020000
|
||||
|
||||
/* Not really related to SOC Interconnect, but a couple of software
|
||||
* conventions for the use the flash space:
|
||||
*/
|
||||
|
||||
/* Minumum amount of flash we support */
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
#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
|
||||
|
||||
/* dynamic clock control defines */
|
||||
#define LPOMINFREQ 25000 /* low power oscillator min */
|
||||
#define LPOMAXFREQ 43000 /* low power oscillator max */
|
||||
#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
|
||||
#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
|
||||
#define PCIMINFREQ 25000000 /* 25 MHz */
|
||||
#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
|
||||
|
||||
#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
|
||||
#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
|
||||
|
||||
/* clkctl xtal what flags */
|
||||
#define XTAL 0x1 /* primary crystal oscillator (2050) */
|
||||
#define PLL 0x2 /* main chip pll */
|
||||
|
||||
/* GPIO usage priorities */
|
||||
#define GPIO_DRV_PRIORITY 0 /* Driver */
|
||||
#define GPIO_APP_PRIORITY 1 /* Application */
|
||||
#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
|
||||
* reservation
|
||||
*/
|
||||
|
||||
/* GPIO pull up/down */
|
||||
#define GPIO_PULLUP 0
|
||||
#define GPIO_PULLDN 1
|
||||
|
||||
/* GPIO event regtype */
|
||||
#define GPIO_REGEVT 0 /* GPIO register event */
|
||||
#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
|
||||
#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
|
||||
|
||||
/* device path */
|
||||
#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
|
||||
|
||||
/* SI routine enumeration: to be used by update function with multiple hooks */
|
||||
#define SI_DOATTACH 1
|
||||
#define SI_PCIDOWN 2
|
||||
#define SI_PCIUP 3
|
||||
|
||||
/*
|
||||
* Data structure to export all chip specific common variables
|
||||
* public (read-only) portion of aiutils handle returned by si_attach()
|
||||
*/
|
||||
struct si_pub {
|
||||
int ccrev; /* chip common core rev */
|
||||
u32 cccaps; /* chip common capabilities */
|
||||
int pmurev; /* pmu core rev */
|
||||
u32 pmucaps; /* pmu capabilities */
|
||||
uint boardtype; /* board type */
|
||||
uint boardvendor; /* board vendor */
|
||||
uint chip; /* chip number */
|
||||
uint chiprev; /* chip revision */
|
||||
uint chippkg; /* chip package option */
|
||||
};
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
struct gpioh_item {
|
||||
void *arg;
|
||||
bool level;
|
||||
void (*handler) (u32 stat, void *arg);
|
||||
u32 event;
|
||||
struct gpioh_item *next;
|
||||
};
|
||||
|
||||
/* misc si info needed by some of the routines */
|
||||
struct si_info {
|
||||
struct si_pub pub; /* back plane public state (must be first) */
|
||||
struct bcma_bus *icbus; /* handle to soc interconnect bus */
|
||||
struct pci_dev *pcibus; /* handle to pci bus */
|
||||
|
||||
u32 chipst; /* chip status */
|
||||
};
|
||||
|
||||
/*
|
||||
* Many of the routines below take an 'sih' handle as their first arg.
|
||||
* Allocate this by calling si_attach(). Free it by calling si_detach().
|
||||
* At any one time, the sih is logically focused on one particular si core
|
||||
* (the "current core").
|
||||
* Use si_setcore() or si_setcoreidx() to change the association to another core
|
||||
*/
|
||||
|
||||
|
||||
/* AMBA Interconnect exported externs */
|
||||
u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
|
||||
|
||||
/* === exported functions === */
|
||||
struct si_pub *ai_attach(struct bcma_bus *pbus);
|
||||
void ai_detach(struct si_pub *sih);
|
||||
uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
|
||||
void ai_clkctl_init(struct si_pub *sih);
|
||||
u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
|
||||
bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode);
|
||||
bool ai_deviceremoved(struct si_pub *sih);
|
||||
|
||||
/* Enable Ex-PA for 4313 */
|
||||
void ai_epa_4313war(struct si_pub *sih);
|
||||
|
||||
static inline u32 ai_get_cccaps(struct si_pub *sih)
|
||||
{
|
||||
return sih->cccaps;
|
||||
}
|
||||
|
||||
static inline int ai_get_pmurev(struct si_pub *sih)
|
||||
{
|
||||
return sih->pmurev;
|
||||
}
|
||||
|
||||
static inline u32 ai_get_pmucaps(struct si_pub *sih)
|
||||
{
|
||||
return sih->pmucaps;
|
||||
}
|
||||
|
||||
static inline uint ai_get_boardtype(struct si_pub *sih)
|
||||
{
|
||||
return sih->boardtype;
|
||||
}
|
||||
|
||||
static inline uint ai_get_boardvendor(struct si_pub *sih)
|
||||
{
|
||||
return sih->boardvendor;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chip_id(struct si_pub *sih)
|
||||
{
|
||||
return sih->chip;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chiprev(struct si_pub *sih)
|
||||
{
|
||||
return sih->chiprev;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chippkg(struct si_pub *sih)
|
||||
{
|
||||
return sih->chippkg;
|
||||
}
|
||||
|
||||
#endif /* _BRCM_AIUTILS_H_ */
|
1144
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c
Normal file
1144
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c
Normal file
File diff suppressed because it is too large
Load Diff
53
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.h
Normal file
53
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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_AMPDU_H_
|
||||
#define _BRCM_AMPDU_H_
|
||||
|
||||
/*
|
||||
* Data structure representing an in-progress session for accumulating
|
||||
* frames for AMPDU.
|
||||
*
|
||||
* wlc: pointer to common driver data
|
||||
* skb_list: queue of skb's for AMPDU
|
||||
* max_ampdu_len: maximum length for this AMPDU
|
||||
* max_ampdu_frames: maximum number of frames for this AMPDU
|
||||
* ampdu_len: total number of bytes accumulated for this AMPDU
|
||||
* dma_len: DMA length of this AMPDU
|
||||
*/
|
||||
struct brcms_ampdu_session {
|
||||
struct brcms_c_info *wlc;
|
||||
struct sk_buff_head skb_list;
|
||||
unsigned max_ampdu_len;
|
||||
u16 max_ampdu_frames;
|
||||
u16 ampdu_len;
|
||||
u16 dma_len;
|
||||
};
|
||||
|
||||
void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
|
||||
struct brcms_c_info *wlc);
|
||||
int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
|
||||
struct sk_buff *p);
|
||||
void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session);
|
||||
|
||||
struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
|
||||
void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
|
||||
void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
|
||||
struct sk_buff *p, struct tx_status *txs);
|
||||
void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
|
||||
void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
|
||||
|
||||
#endif /* _BRCM_AMPDU_H_ */
|
309
drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c
Normal file
309
drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* 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 <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "main.h"
|
||||
#include "phy_shim.h"
|
||||
#include "antsel.h"
|
||||
#include "debug.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 BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
|
||||
#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
|
||||
#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
|
||||
(BRCMS_ANTSEL_11N_1(ant)))
|
||||
#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
|
||||
#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
|
||||
|
||||
/* antenna switch */
|
||||
/* defines for no boardlevel antenna diversity */
|
||||
#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x3 antdiv defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x3 3
|
||||
#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x4 antdiv rev4 defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x4 4
|
||||
#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
|
||||
|
||||
static const u16 mimo_2x4_div_antselpat_tbl[] = {
|
||||
0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
|
||||
0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
|
||||
0, 0, 0, 0, /* n.a. */
|
||||
0, 0, 0, 0 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x4_div_antselid_tbl[16] = {
|
||||
0, 0, 0, 0, 0, 2, 3, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
static const u16 mimo_2x3_div_antselpat_tbl[] = {
|
||||
16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
|
||||
16, 16, 16, 16, /* n.a. */
|
||||
16, 2, 16, 16, /* ant0: 2 ant1: 1 */
|
||||
16, 16, 16, 16 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x3_div_antselid_tbl[16] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
/* boardlevel antenna selection: init antenna selection structure */
|
||||
static void
|
||||
brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
|
||||
bool auto_sel)
|
||||
{
|
||||
if (asi->antsel_type == ANTSEL_2x3) {
|
||||
u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
|
||||
((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x4) {
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
|
||||
|
||||
} else { /* no antenna selection available */
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->num_antcfg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct antsel_info *asi;
|
||||
struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
|
||||
|
||||
asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
|
||||
if (!asi)
|
||||
return NULL;
|
||||
|
||||
asi->wlc = wlc;
|
||||
asi->pub = wlc->pub;
|
||||
asi->antsel_type = ANTSEL_NA;
|
||||
asi->antsel_avail = false;
|
||||
asi->antsel_antswitch = sprom->antswitch;
|
||||
|
||||
if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
|
||||
switch (asi->antsel_antswitch) {
|
||||
case ANTSWITCH_TYPE_1:
|
||||
case ANTSWITCH_TYPE_2:
|
||||
case ANTSWITCH_TYPE_3:
|
||||
/* 4321/2 board with 2x3 switch logic */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
/* Antenna selection availability */
|
||||
if ((sprom->ant_available_bg == 7) ||
|
||||
(sprom->ant_available_a == 7)) {
|
||||
asi->antsel_avail = true;
|
||||
} else if (
|
||||
sprom->ant_available_bg == 3 ||
|
||||
sprom->ant_available_a == 3) {
|
||||
asi->antsel_avail = false;
|
||||
} else {
|
||||
asi->antsel_avail = false;
|
||||
brcms_err(wlc->hw->d11core,
|
||||
"antsel_attach: 2o3 "
|
||||
"board cfg invalid\n");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((asi->pub->sromrev == 4) &&
|
||||
(sprom->ant_available_bg == 7) &&
|
||||
(sprom->ant_available_a == 0)) {
|
||||
/* hack to match old 4321CB2 cards with 2of3 antenna switch */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
asi->antsel_avail = true;
|
||||
} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
|
||||
asi->antsel_type = ANTSEL_2x4;
|
||||
asi->antsel_avail = true;
|
||||
}
|
||||
|
||||
/* Set the antenna selection type for the low driver */
|
||||
brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
|
||||
|
||||
/* Init (auto/manual) antenna selection */
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
|
||||
|
||||
return asi;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_detach(struct antsel_info *asi)
|
||||
{
|
||||
kfree(asi);
|
||||
}
|
||||
|
||||
/*
|
||||
* boardlevel antenna selection:
|
||||
* convert ant_cfg to mimo_antsel (ucode interface)
|
||||
*/
|
||||
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
|
||||
{
|
||||
u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
|
||||
u16 mimo_antsel = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: ucode interface control */
|
||||
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel)
|
||||
{
|
||||
struct brcms_c_info *wlc = asi->wlc;
|
||||
u8 ant_cfg;
|
||||
u16 mimo_antsel;
|
||||
|
||||
/* 1) Update TX antconfig for all frames that are not unicast data
|
||||
* (aka default TX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
|
||||
|
||||
/* 2) Update RX antconfig for all frames that are not unicast data
|
||||
* (aka default RX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_init(struct antsel_info *asi)
|
||||
{
|
||||
if ((asi->antsel_type == ANTSEL_2x3) ||
|
||||
(asi->antsel_type == ANTSEL_2x4))
|
||||
brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert id to ant_cfg */
|
||||
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
|
||||
{
|
||||
u8 antcfg = ANT_SELCFG_DEF_2x2;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
|
||||
return antcfg;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
|
||||
u8 antselid, u8 fbantselid, u8 *antcfg,
|
||||
u8 *fbantcfg)
|
||||
{
|
||||
u8 ant;
|
||||
|
||||
/* if use default, assign it and return */
|
||||
if (usedef) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
|
||||
*fbantcfg = *antcfg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sel) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
|
||||
} else {
|
||||
ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
|
||||
*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
|
||||
*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
|
||||
} else {
|
||||
*antcfg =
|
||||
asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
|
||||
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
|
||||
{
|
||||
u8 antselid = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
}
|
||||
|
||||
return antselid;
|
||||
}
|
27
drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.h
Normal file
27
drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_ANTSEL_H_
|
||||
#define _BRCM_ANTSEL_H_
|
||||
|
||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
|
||||
void brcms_c_antsel_detach(struct antsel_info *asi);
|
||||
void brcms_c_antsel_init(struct antsel_info *asi);
|
||||
void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
|
||||
u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg);
|
||||
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
|
||||
|
||||
#endif /* _BRCM_ANTSEL_H_ */
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __TRACE_BRCMSMAC_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmsmac
|
||||
|
||||
/*
|
||||
* We define a tracepoint, its arguments, its printk format and its
|
||||
* 'fast binary record' layout.
|
||||
*/
|
||||
TRACE_EVENT(brcms_timer,
|
||||
/* TPPROTO is the prototype of the function called by this tracepoint */
|
||||
TP_PROTO(struct brcms_timer *t),
|
||||
/*
|
||||
* TPARGS(firstarg, p) are the parameters names, same as found in the
|
||||
* prototype.
|
||||
*/
|
||||
TP_ARGS(t),
|
||||
/*
|
||||
* Fast binary tracing: define the trace record via TP_STRUCT__entry().
|
||||
* You can think about it like a regular C structure local variable
|
||||
* definition.
|
||||
*/
|
||||
TP_STRUCT__entry(
|
||||
__field(uint, ms)
|
||||
__field(uint, set)
|
||||
__field(uint, periodic)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->ms = t->ms;
|
||||
__entry->set = t->set;
|
||||
__entry->periodic = t->periodic;
|
||||
),
|
||||
TP_printk(
|
||||
"ms=%u set=%u periodic=%u",
|
||||
__entry->ms, __entry->set, __entry->periodic
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_dpc,
|
||||
TP_PROTO(unsigned long data),
|
||||
TP_ARGS(data),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, data)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->data = data;
|
||||
),
|
||||
TP_printk(
|
||||
"data=%p",
|
||||
(void *)__entry->data
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_macintstatus,
|
||||
TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus,
|
||||
u32 mask),
|
||||
TP_ARGS(dev, in_isr, macintstatus, mask),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(int, in_isr)
|
||||
__field(u32, macintstatus)
|
||||
__field(u32, mask)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev, dev_name(dev));
|
||||
__entry->in_isr = in_isr;
|
||||
__entry->macintstatus = macintstatus;
|
||||
__entry->mask = mask;
|
||||
),
|
||||
TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev),
|
||||
__entry->in_isr, __entry->macintstatus, __entry->mask)
|
||||
);
|
||||
#endif /* __TRACE_BRCMSMAC_H */
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCM_TRACING */
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(__TRACE_BRCMSMAC_MSG_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __TRACE_BRCMSMAC_MSG_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmsmac_msg
|
||||
|
||||
#define MAX_MSG_LEN 100
|
||||
|
||||
DECLARE_EVENT_CLASS(brcms_msg_event,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf),
|
||||
TP_STRUCT__entry(
|
||||
__dynamic_array(char, msg, MAX_MSG_LEN)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
MAX_MSG_LEN, vaf->fmt,
|
||||
*vaf->va) >= MAX_MSG_LEN);
|
||||
),
|
||||
TP_printk("%s", __get_str(msg))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(brcms_msg_event, brcms_info,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(brcms_msg_event, brcms_warn,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(brcms_msg_event, brcms_err,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(brcms_msg_event, brcms_crit,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_dbg,
|
||||
TP_PROTO(u32 level, const char *func, struct va_format *vaf),
|
||||
TP_ARGS(level, func, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, level)
|
||||
__string(func, func)
|
||||
__dynamic_array(char, msg, MAX_MSG_LEN)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->level = level;
|
||||
__assign_str(func, func);
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
MAX_MSG_LEN, vaf->fmt,
|
||||
*vaf->va) >= MAX_MSG_LEN);
|
||||
),
|
||||
TP_printk("%s: %s", __get_str(func), __get_str(msg))
|
||||
);
|
||||
#endif /* __TRACE_BRCMSMAC_MSG_H */
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac_msg
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCM_TRACING */
|
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(__TRACE_BRCMSMAC_TX_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __TRACE_BRCMSMAC_TX_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmsmac_tx
|
||||
|
||||
TRACE_EVENT(brcms_txdesc,
|
||||
TP_PROTO(const struct device *dev,
|
||||
void *txh, size_t txh_len),
|
||||
TP_ARGS(dev, txh, txh_len),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__dynamic_array(u8, txh, txh_len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev, dev_name(dev));
|
||||
memcpy(__get_dynamic_array(txh), txh, txh_len);
|
||||
),
|
||||
TP_printk("[%s] txdesc", __get_str(dev))
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_txstatus,
|
||||
TP_PROTO(const struct device *dev, u16 framelen, u16 frameid,
|
||||
u16 status, u16 lasttxtime, u16 sequence, u16 phyerr,
|
||||
u16 ackphyrxsh),
|
||||
TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr,
|
||||
ackphyrxsh),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(u16, framelen)
|
||||
__field(u16, frameid)
|
||||
__field(u16, status)
|
||||
__field(u16, lasttxtime)
|
||||
__field(u16, sequence)
|
||||
__field(u16, phyerr)
|
||||
__field(u16, ackphyrxsh)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev, dev_name(dev));
|
||||
__entry->framelen = framelen;
|
||||
__entry->frameid = frameid;
|
||||
__entry->status = status;
|
||||
__entry->lasttxtime = lasttxtime;
|
||||
__entry->sequence = sequence;
|
||||
__entry->phyerr = phyerr;
|
||||
__entry->ackphyrxsh = ackphyrxsh;
|
||||
),
|
||||
TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x "
|
||||
"Seq %#04x PHYTxStatus %#04x RxAck %#04x",
|
||||
__get_str(dev), __entry->frameid, __entry->status,
|
||||
__entry->lasttxtime, __entry->sequence, __entry->phyerr,
|
||||
__entry->ackphyrxsh)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_ampdu_session,
|
||||
TP_PROTO(const struct device *dev, unsigned max_ampdu_len,
|
||||
u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames,
|
||||
u16 dma_len),
|
||||
TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames,
|
||||
dma_len),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(unsigned, max_ampdu_len)
|
||||
__field(u16, max_ampdu_frames)
|
||||
__field(u16, ampdu_len)
|
||||
__field(u16, ampdu_frames)
|
||||
__field(u16, dma_len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev, dev_name(dev));
|
||||
__entry->max_ampdu_len = max_ampdu_len;
|
||||
__entry->max_ampdu_frames = max_ampdu_frames;
|
||||
__entry->ampdu_len = ampdu_len;
|
||||
__entry->ampdu_frames = ampdu_frames;
|
||||
__entry->dma_len = dma_len;
|
||||
),
|
||||
TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u",
|
||||
__get_str(dev), __entry->max_ampdu_len,
|
||||
__entry->max_ampdu_frames, __entry->ampdu_len,
|
||||
__entry->ampdu_frames, __entry->dma_len)
|
||||
);
|
||||
#endif /* __TRACE_BRCMSMAC_TX_H */
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac_tx
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCM_TRACING */
|
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h> /* bug in tracepoint.h, it should include this */
|
||||
|
||||
#ifndef __CHECKER__
|
||||
#include "mac80211_if.h"
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "brcms_trace_events.h"
|
||||
#endif
|
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BRCMS_TRACE_EVENTS_H
|
||||
#define __BRCMS_TRACE_EVENTS_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/tracepoint.h>
|
||||
#include "mac80211_if.h"
|
||||
|
||||
#ifndef CONFIG_BRCM_TRACING
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(...)
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(evt_class, name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#endif
|
||||
|
||||
#include "brcms_trace_brcmsmac.h"
|
||||
#include "brcms_trace_brcmsmac_tx.h"
|
||||
#include "brcms_trace_brcmsmac_msg.h"
|
||||
|
||||
#endif /* __TRACE_BRCMSMAC_H */
|
774
drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
Normal file
774
drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
Normal file
@@ -0,0 +1,774 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <net/regulatory.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include "pub.h"
|
||||
#include "phy/phy_hal.h"
|
||||
#include "main.h"
|
||||
#include "stf.h"
|
||||
#include "channel.h"
|
||||
#include "mac80211_if.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* QDB() macro takes a dB value and converts to a quarter dB value */
|
||||
#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
|
||||
|
||||
#define LOCALE_MIMO_IDX_bn 0
|
||||
#define LOCALE_MIMO_IDX_11n 0
|
||||
|
||||
/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
|
||||
#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
|
||||
|
||||
/* maxpwr mapping to 5GHz band channels:
|
||||
* maxpwr[0] - channels [34-48]
|
||||
* maxpwr[1] - channels [52-60]
|
||||
* maxpwr[2] - channels [62-64]
|
||||
* maxpwr[3] - channels [100-140]
|
||||
* maxpwr[4] - channels [149-165]
|
||||
*/
|
||||
#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */
|
||||
|
||||
#define LC(id) LOCALE_MIMO_IDX_ ## id
|
||||
|
||||
#define LOCALES(mimo2, mimo5) \
|
||||
{LC(mimo2), LC(mimo5)}
|
||||
|
||||
/* macro to get 5 GHz channel group index for tx power */
|
||||
#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
|
||||
(((c) < 62) ? 1 : \
|
||||
(((c) < 100) ? 2 : \
|
||||
(((c) < 149) ? 3 : 4))))
|
||||
|
||||
#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
|
||||
#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
|
||||
NL80211_RRF_DFS | \
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
|
||||
NL80211_RRF_DFS | \
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
static const struct ieee80211_regdomain brcms_regdom_x2 = {
|
||||
.n_reg_rules = 6,
|
||||
.alpha2 = "X2",
|
||||
.reg_rules = {
|
||||
BRCM_2GHZ_2412_2462,
|
||||
BRCM_2GHZ_2467_2472,
|
||||
BRCM_5GHZ_5180_5240,
|
||||
BRCM_5GHZ_5260_5320,
|
||||
BRCM_5GHZ_5500_5700,
|
||||
BRCM_5GHZ_5745_5825,
|
||||
}
|
||||
};
|
||||
|
||||
/* locale per-channel tx power limits for MIMO frames
|
||||
* maxpwr arrays are index by channel for 2.4 GHz limits, and
|
||||
* by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
|
||||
*/
|
||||
struct locale_mimo_info {
|
||||
/* tx 20 MHz power limits, qdBm units */
|
||||
s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
|
||||
/* tx 40 MHz power limits, qdBm units */
|
||||
s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
|
||||
};
|
||||
|
||||
/* Country names and abbreviations with locale defined from ISO 3166 */
|
||||
struct country_info {
|
||||
const u8 locale_mimo_2G; /* 2.4G mimo info */
|
||||
const u8 locale_mimo_5G; /* 5G mimo info */
|
||||
};
|
||||
|
||||
struct brcms_regd {
|
||||
struct country_info country;
|
||||
const struct ieee80211_regdomain *regdomain;
|
||||
};
|
||||
|
||||
struct brcms_cm_info {
|
||||
struct brcms_pub *pub;
|
||||
struct brcms_c_info *wlc;
|
||||
const struct brcms_regd *world_regd;
|
||||
};
|
||||
|
||||
/*
|
||||
* MIMO Locale Definitions - 2.4 GHz
|
||||
*/
|
||||
static const struct locale_mimo_info locale_bn = {
|
||||
{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
|
||||
QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
|
||||
QDB(13), QDB(13), QDB(13)},
|
||||
{0, 0, QDB(13), QDB(13), QDB(13),
|
||||
QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
|
||||
QDB(13), 0, 0},
|
||||
};
|
||||
|
||||
static const struct locale_mimo_info *g_mimo_2g_table[] = {
|
||||
&locale_bn
|
||||
};
|
||||
|
||||
/*
|
||||
* MIMO Locale Definitions - 5 GHz
|
||||
*/
|
||||
static const struct locale_mimo_info locale_11n = {
|
||||
{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
|
||||
{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
|
||||
};
|
||||
|
||||
static const struct locale_mimo_info *g_mimo_5g_table[] = {
|
||||
&locale_11n
|
||||
};
|
||||
|
||||
static const struct brcms_regd cntry_locales[] = {
|
||||
/* Worldwide RoW 2, must always be at index 0 */
|
||||
{
|
||||
.country = LOCALES(bn, 11n),
|
||||
.regdomain = &brcms_regdom_x2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
|
||||
{
|
||||
if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
|
||||
return NULL;
|
||||
|
||||
return g_mimo_2g_table[locale_idx];
|
||||
}
|
||||
|
||||
static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
|
||||
{
|
||||
if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
|
||||
return NULL;
|
||||
|
||||
return g_mimo_5g_table[locale_idx];
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicates whether the country provided is valid to pass
|
||||
* to cfg80211 or not.
|
||||
*
|
||||
* returns true if valid; false if not.
|
||||
*/
|
||||
static bool brcms_c_country_valid(const char *ccode)
|
||||
{
|
||||
/*
|
||||
* only allow ascii alpha uppercase for the first 2
|
||||
* chars.
|
||||
*/
|
||||
if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
|
||||
(0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* do not match ISO 3166-1 user assigned country codes
|
||||
* that may be in the driver table
|
||||
*/
|
||||
if (!strcmp("AA", ccode) || /* AA */
|
||||
!strcmp("ZZ", ccode) || /* ZZ */
|
||||
ccode[0] == 'X' || /* XA - XZ */
|
||||
(ccode[0] == 'Q' && /* QM - QZ */
|
||||
(ccode[1] >= 'M' && ccode[1] <= 'Z')))
|
||||
return false;
|
||||
|
||||
if (!strcmp("NA", ccode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct brcms_regd *brcms_world_regd(const char *regdom, int len)
|
||||
{
|
||||
const struct brcms_regd *regd = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cntry_locales); i++) {
|
||||
if (!strncmp(regdom, cntry_locales[i].regdomain->alpha2, len)) {
|
||||
regd = &cntry_locales[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return regd;
|
||||
}
|
||||
|
||||
static const struct brcms_regd *brcms_default_world_regd(void)
|
||||
{
|
||||
return &cntry_locales[0];
|
||||
}
|
||||
|
||||
/* JP, J1 - J10 are Japan ccodes */
|
||||
static bool brcms_c_japan_ccode(const char *ccode)
|
||||
{
|
||||
return (ccode[0] == 'J' &&
|
||||
(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
|
||||
}
|
||||
|
||||
static void
|
||||
brcms_c_channel_min_txpower_limits_with_local_constraint(
|
||||
struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
|
||||
u8 local_constraint_qdbm)
|
||||
{
|
||||
int j;
|
||||
|
||||
/* CCK Rates */
|
||||
for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
|
||||
txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
|
||||
|
||||
/* 20 MHz Legacy OFDM SISO */
|
||||
for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
|
||||
txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
|
||||
|
||||
/* 20 MHz Legacy OFDM CDD */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
|
||||
txpwr->ofdm_cdd[j] =
|
||||
min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
|
||||
|
||||
/* 40 MHz Legacy OFDM SISO */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
|
||||
txpwr->ofdm_40_siso[j] =
|
||||
min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
|
||||
|
||||
/* 40 MHz Legacy OFDM CDD */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
|
||||
txpwr->ofdm_40_cdd[j] =
|
||||
min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
|
||||
|
||||
/* 20MHz MCS 0-7 SISO */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_20_siso[j] =
|
||||
min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
|
||||
|
||||
/* 20MHz MCS 0-7 CDD */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_20_cdd[j] =
|
||||
min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
|
||||
|
||||
/* 20MHz MCS 0-7 STBC */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_20_stbc[j] =
|
||||
min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
|
||||
|
||||
/* 20MHz MCS 8-15 MIMO */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
|
||||
txpwr->mcs_20_mimo[j] =
|
||||
min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
|
||||
|
||||
/* 40MHz MCS 0-7 SISO */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_40_siso[j] =
|
||||
min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
|
||||
|
||||
/* 40MHz MCS 0-7 CDD */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_40_cdd[j] =
|
||||
min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
|
||||
|
||||
/* 40MHz MCS 0-7 STBC */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
|
||||
txpwr->mcs_40_stbc[j] =
|
||||
min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
|
||||
|
||||
/* 40MHz MCS 8-15 MIMO */
|
||||
for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
|
||||
txpwr->mcs_40_mimo[j] =
|
||||
min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
|
||||
|
||||
/* 40MHz MCS 32 */
|
||||
txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* set the driver's current country and regulatory information
|
||||
* using a country code as the source. Look up built in country
|
||||
* information found with the country code.
|
||||
*/
|
||||
static void
|
||||
brcms_c_set_country(struct brcms_cm_info *wlc_cm,
|
||||
const struct brcms_regd *regd)
|
||||
{
|
||||
struct brcms_c_info *wlc = wlc_cm->wlc;
|
||||
|
||||
if ((wlc->pub->_n_enab & SUPPORT_11N) !=
|
||||
wlc->protection->nmode_user)
|
||||
brcms_c_set_nmode(wlc);
|
||||
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
|
||||
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct brcms_cm_info *wlc_cm;
|
||||
struct brcms_pub *pub = wlc->pub;
|
||||
struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
|
||||
const char *ccode = sprom->alpha2;
|
||||
int ccode_len = sizeof(sprom->alpha2);
|
||||
|
||||
wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
|
||||
if (wlc_cm == NULL)
|
||||
return NULL;
|
||||
wlc_cm->pub = pub;
|
||||
wlc_cm->wlc = wlc;
|
||||
wlc->cmi = wlc_cm;
|
||||
|
||||
/* store the country code for passing up as a regulatory hint */
|
||||
wlc_cm->world_regd = brcms_world_regd(ccode, ccode_len);
|
||||
if (brcms_c_country_valid(ccode))
|
||||
strncpy(wlc->pub->srom_ccode, ccode, ccode_len);
|
||||
|
||||
/*
|
||||
* If no custom world domain is found in the SROM, use the
|
||||
* default "X2" domain.
|
||||
*/
|
||||
if (!wlc_cm->world_regd) {
|
||||
wlc_cm->world_regd = brcms_default_world_regd();
|
||||
ccode = wlc_cm->world_regd->regdomain->alpha2;
|
||||
ccode_len = BRCM_CNTRY_BUF_SZ - 1;
|
||||
}
|
||||
|
||||
/* save default country for exiting 11d regulatory mode */
|
||||
strncpy(wlc->country_default, ccode, ccode_len);
|
||||
|
||||
/* initialize autocountry_default to driver default */
|
||||
strncpy(wlc->autocountry_default, ccode, ccode_len);
|
||||
|
||||
brcms_c_set_country(wlc_cm, wlc_cm->world_regd);
|
||||
|
||||
return wlc_cm;
|
||||
}
|
||||
|
||||
void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
|
||||
{
|
||||
kfree(wlc_cm);
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
|
||||
u8 local_constraint_qdbm)
|
||||
{
|
||||
struct brcms_c_info *wlc = wlc_cm->wlc;
|
||||
struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
|
||||
struct txpwr_limits txpwr;
|
||||
|
||||
brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
|
||||
|
||||
brcms_c_channel_min_txpower_limits_with_local_constraint(
|
||||
wlc_cm, &txpwr, local_constraint_qdbm
|
||||
);
|
||||
|
||||
/* set or restore gmode as required by regulatory */
|
||||
if (ch->flags & IEEE80211_CHAN_NO_OFDM)
|
||||
brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
|
||||
else
|
||||
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
|
||||
|
||||
brcms_b_set_chanspec(wlc->hw, chanspec,
|
||||
!!(ch->flags & IEEE80211_CHAN_NO_IR),
|
||||
&txpwr);
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
|
||||
struct txpwr_limits *txpwr)
|
||||
{
|
||||
struct brcms_c_info *wlc = wlc_cm->wlc;
|
||||
struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
|
||||
uint i;
|
||||
uint chan;
|
||||
int maxpwr;
|
||||
int delta;
|
||||
const struct country_info *country;
|
||||
struct brcms_band *band;
|
||||
int conducted_max = BRCMS_TXPWR_MAX;
|
||||
const struct locale_mimo_info *li_mimo;
|
||||
int maxpwr20, maxpwr40;
|
||||
int maxpwr_idx;
|
||||
uint j;
|
||||
|
||||
memset(txpwr, 0, sizeof(struct txpwr_limits));
|
||||
|
||||
if (WARN_ON(!ch))
|
||||
return;
|
||||
|
||||
country = &wlc_cm->world_regd->country;
|
||||
|
||||
chan = CHSPEC_CHANNEL(chanspec);
|
||||
band = wlc->bandstate[chspec_bandunit(chanspec)];
|
||||
li_mimo = (band->bandtype == BRCM_BAND_5G) ?
|
||||
brcms_c_get_mimo_5g(country->locale_mimo_5G) :
|
||||
brcms_c_get_mimo_2g(country->locale_mimo_2G);
|
||||
|
||||
delta = band->antgain;
|
||||
|
||||
if (band->bandtype == BRCM_BAND_2G)
|
||||
conducted_max = QDB(22);
|
||||
|
||||
maxpwr = QDB(ch->max_power) - delta;
|
||||
maxpwr = max(maxpwr, 0);
|
||||
maxpwr = min(maxpwr, conducted_max);
|
||||
|
||||
/* CCK txpwr limits for 2.4G band */
|
||||
if (band->bandtype == BRCM_BAND_2G) {
|
||||
for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
|
||||
txpwr->cck[i] = (u8) maxpwr;
|
||||
}
|
||||
|
||||
for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
|
||||
txpwr->ofdm[i] = (u8) maxpwr;
|
||||
|
||||
/*
|
||||
* OFDM 40 MHz SISO has the same power as the corresponding
|
||||
* MCS0-7 rate unless overriden by the locale specific code.
|
||||
* We set this value to 0 as a flag (presumably 0 dBm isn't
|
||||
* a possibility) and then copy the MCS0-7 value to the 40 MHz
|
||||
* value if it wasn't explicitly set.
|
||||
*/
|
||||
txpwr->ofdm_40_siso[i] = 0;
|
||||
|
||||
txpwr->ofdm_cdd[i] = (u8) maxpwr;
|
||||
|
||||
txpwr->ofdm_40_cdd[i] = 0;
|
||||
}
|
||||
|
||||
delta = 0;
|
||||
if (band->antgain > QDB(6))
|
||||
delta = band->antgain - QDB(6); /* Excess over 6 dB */
|
||||
|
||||
if (band->bandtype == BRCM_BAND_2G)
|
||||
maxpwr_idx = (chan - 1);
|
||||
else
|
||||
maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
|
||||
|
||||
maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
|
||||
maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
|
||||
|
||||
maxpwr20 = maxpwr20 - delta;
|
||||
maxpwr20 = max(maxpwr20, 0);
|
||||
maxpwr40 = maxpwr40 - delta;
|
||||
maxpwr40 = max(maxpwr40, 0);
|
||||
|
||||
/* Fill in the MCS 0-7 (SISO) rates */
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
|
||||
/*
|
||||
* 20 MHz has the same power as the corresponding OFDM rate
|
||||
* unless overriden by the locale specific code.
|
||||
*/
|
||||
txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
|
||||
txpwr->mcs_40_siso[i] = 0;
|
||||
}
|
||||
|
||||
/* Fill in the MCS 0-7 CDD rates */
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
|
||||
txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
|
||||
}
|
||||
|
||||
/*
|
||||
* These locales have SISO expressed in the
|
||||
* table and override CDD later
|
||||
*/
|
||||
if (li_mimo == &locale_bn) {
|
||||
if (li_mimo == &locale_bn) {
|
||||
maxpwr20 = QDB(16);
|
||||
maxpwr40 = 0;
|
||||
|
||||
if (chan >= 3 && chan <= 11)
|
||||
maxpwr40 = QDB(16);
|
||||
}
|
||||
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
txpwr->mcs_20_siso[i] = (u8) maxpwr20;
|
||||
txpwr->mcs_40_siso[i] = (u8) maxpwr40;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the MCS 0-7 STBC rates */
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
txpwr->mcs_20_stbc[i] = 0;
|
||||
txpwr->mcs_40_stbc[i] = 0;
|
||||
}
|
||||
|
||||
/* Fill in the MCS 8-15 SDM rates */
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
|
||||
txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
|
||||
txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
|
||||
}
|
||||
|
||||
/* Fill in MCS32 */
|
||||
txpwr->mcs32 = (u8) maxpwr40;
|
||||
|
||||
for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
|
||||
if (txpwr->ofdm_40_cdd[i] == 0)
|
||||
txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
|
||||
if (i == 0) {
|
||||
i = i + 1;
|
||||
if (txpwr->ofdm_40_cdd[i] == 0)
|
||||
txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
|
||||
* value if it wasn't provided explicitly.
|
||||
*/
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
if (txpwr->mcs_40_siso[i] == 0)
|
||||
txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
|
||||
if (txpwr->ofdm_40_siso[i] == 0)
|
||||
txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
|
||||
if (i == 0) {
|
||||
i = i + 1;
|
||||
if (txpwr->ofdm_40_siso[i] == 0)
|
||||
txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
|
||||
* STBC values if they weren't provided explicitly.
|
||||
*/
|
||||
for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
|
||||
if (txpwr->mcs_20_stbc[i] == 0)
|
||||
txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
|
||||
|
||||
if (txpwr->mcs_40_stbc[i] == 0)
|
||||
txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the chanspec is using a legal set of parameters, i.e. that the
|
||||
* chanspec specified a band, bw, ctl_sb and channel and that the
|
||||
* combination could be legal given any set of circumstances.
|
||||
* RETURNS: true is the chanspec is malformed, false if it looks good.
|
||||
*/
|
||||
static bool brcms_c_chspec_malformed(u16 chanspec)
|
||||
{
|
||||
/* must be 2G or 5G band */
|
||||
if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
|
||||
return true;
|
||||
/* must be 20 or 40 bandwidth */
|
||||
if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
|
||||
return true;
|
||||
|
||||
/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
|
||||
if (CHSPEC_IS20(chanspec)) {
|
||||
if (!CHSPEC_SB_NONE(chanspec))
|
||||
return true;
|
||||
} else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the chanspec for this locale, for 40MHZ we need to also
|
||||
* check that the sidebands are valid 20MZH channels in this locale
|
||||
* and they are also a legal HT combination
|
||||
*/
|
||||
static bool
|
||||
brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec)
|
||||
{
|
||||
struct brcms_c_info *wlc = wlc_cm->wlc;
|
||||
u8 channel = CHSPEC_CHANNEL(chspec);
|
||||
|
||||
/* check the chanspec */
|
||||
if (brcms_c_chspec_malformed(chspec)) {
|
||||
brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n",
|
||||
wlc->pub->unit, chspec);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
|
||||
chspec_bandunit(chspec))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
|
||||
{
|
||||
return brcms_c_valid_chanspec_ext(wlc_cm, chspec);
|
||||
}
|
||||
|
||||
static bool brcms_is_radar_freq(u16 center_freq)
|
||||
{
|
||||
return center_freq >= 5260 && center_freq <= 5700;
|
||||
}
|
||||
|
||||
static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
int i;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
|
||||
if (!brcms_is_radar_freq(ch->center_freq))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* All channels in this range should be passive and have
|
||||
* DFS enabled.
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
const struct ieee80211_reg_rule *rule;
|
||||
int band, i;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
sband = wiphy->bands[band];
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
|
||||
if (ch->flags &
|
||||
(IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
rule = freq_reg_info(wiphy,
|
||||
MHZ_TO_KHZ(ch->center_freq));
|
||||
if (IS_ERR(rule))
|
||||
continue;
|
||||
|
||||
if (!(rule->flags & NL80211_RRF_NO_IR))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
} else if (ch->beacon_found) {
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void brcms_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct brcms_info *wl = hw->priv;
|
||||
struct brcms_c_info *wlc = wl->wlc;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
int band, i;
|
||||
bool ch_found = false;
|
||||
|
||||
brcms_reg_apply_radar_flags(wiphy);
|
||||
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
|
||||
brcms_reg_apply_beaconing_flags(wiphy, request->initiator);
|
||||
|
||||
/* Disable radio if all channels disallowed by regulatory */
|
||||
for (band = 0; !ch_found && band < IEEE80211_NUM_BANDS; band++) {
|
||||
sband = wiphy->bands[band];
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
for (i = 0; !ch_found && i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch_found) {
|
||||
mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
|
||||
} else {
|
||||
mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
|
||||
brcms_err(wlc->hw->d11core,
|
||||
"wl%d: %s: no valid channel for \"%s\"\n",
|
||||
wlc->pub->unit, __func__, request->alpha2);
|
||||
}
|
||||
|
||||
if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
|
||||
wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
|
||||
brcms_c_japan_ccode(request->alpha2));
|
||||
}
|
||||
|
||||
void brcms_c_regd_init(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct wiphy *wiphy = wlc->wiphy;
|
||||
const struct brcms_regd *regd = wlc->cmi->world_regd;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
struct brcms_chanvec sup_chan;
|
||||
struct brcms_band *band;
|
||||
int band_idx, i;
|
||||
|
||||
/* Disable any channels not supported by the phy */
|
||||
for (band_idx = 0; band_idx < wlc->pub->_nbands; band_idx++) {
|
||||
band = wlc->bandstate[band_idx];
|
||||
|
||||
wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
|
||||
&sup_chan);
|
||||
|
||||
if (band_idx == BAND_2G_INDEX)
|
||||
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
else
|
||||
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (!isset(sup_chan.vec, ch->hw_value))
|
||||
ch->flags |= IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
wlc->wiphy->reg_notifier = brcms_reg_notifier;
|
||||
wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_STRICT_REG;
|
||||
wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
|
||||
brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
|
||||
}
|
47
drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.h
Normal file
47
drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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_CHANNEL_H_
|
||||
#define _BRCM_CHANNEL_H_
|
||||
|
||||
/* conversion for phy txpwr calculations that use .25 dB units */
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* bits for locale_info flags */
|
||||
#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
|
||||
#define BRCMS_EIRP 0x01 /* Flag for EIRP */
|
||||
#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
|
||||
#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
|
||||
#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
|
||||
#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
|
||||
#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
|
||||
#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
|
||||
|
||||
#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
|
||||
|
||||
struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
|
||||
|
||||
void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
|
||||
|
||||
bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec);
|
||||
|
||||
void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
|
||||
struct txpwr_limits *txpwr);
|
||||
void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
|
||||
u8 local_constraint_qdbm);
|
||||
void brcms_c_regd_init(struct brcms_c_info *wlc);
|
||||
|
||||
#endif /* _WLC_CHANNEL_H */
|
1902
drivers/net/wireless/broadcom/brcm80211/brcmsmac/d11.h
Normal file
1902
drivers/net/wireless/broadcom/brcm80211/brcmsmac/d11.h
Normal file
File diff suppressed because it is too large
Load Diff
270
drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
Normal file
270
drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
* Copyright (c) 2012 Canonical Ltd.
|
||||
*
|
||||
* 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/debugfs.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "types.h"
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "brcms_trace_events.h"
|
||||
#include "phy/phy_int.h"
|
||||
|
||||
static struct dentry *root_folder;
|
||||
|
||||
void brcms_debugfs_init(void)
|
||||
{
|
||||
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
if (IS_ERR(root_folder))
|
||||
root_folder = NULL;
|
||||
}
|
||||
|
||||
void brcms_debugfs_exit(void)
|
||||
{
|
||||
if (!root_folder)
|
||||
return;
|
||||
|
||||
debugfs_remove_recursive(root_folder);
|
||||
root_folder = NULL;
|
||||
}
|
||||
|
||||
int brcms_debugfs_attach(struct brcms_pub *drvr)
|
||||
{
|
||||
if (!root_folder)
|
||||
return -ENODEV;
|
||||
|
||||
drvr->dbgfs_dir = debugfs_create_dir(
|
||||
dev_name(&drvr->wlc->hw->d11core->dev), root_folder);
|
||||
return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
|
||||
}
|
||||
|
||||
void brcms_debugfs_detach(struct brcms_pub *drvr)
|
||||
{
|
||||
if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
|
||||
debugfs_remove_recursive(drvr->dbgfs_dir);
|
||||
}
|
||||
|
||||
struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
|
||||
{
|
||||
return drvr->dbgfs_dir;
|
||||
}
|
||||
|
||||
static
|
||||
int brcms_debugfs_hardware_read(struct seq_file *s, void *data)
|
||||
{
|
||||
struct brcms_pub *drvr = s->private;
|
||||
struct brcms_hardware *hw = drvr->wlc->hw;
|
||||
struct bcma_device *core = hw->d11core;
|
||||
struct bcma_bus *bus = core->bus;
|
||||
char boardrev[BRCMU_BOARDREV_LEN];
|
||||
|
||||
seq_printf(s, "chipnum 0x%x\n"
|
||||
"chiprev 0x%x\n"
|
||||
"chippackage 0x%x\n"
|
||||
"corerev 0x%x\n"
|
||||
"boardid 0x%x\n"
|
||||
"boardvendor 0x%x\n"
|
||||
"boardrev %s\n"
|
||||
"boardflags 0x%x\n"
|
||||
"boardflags2 0x%x\n"
|
||||
"ucoderev 0x%x\n"
|
||||
"radiorev 0x%x\n"
|
||||
"phytype 0x%x\n"
|
||||
"phyrev 0x%x\n"
|
||||
"anarev 0x%x\n"
|
||||
"nvramrev %d\n",
|
||||
bus->chipinfo.id, bus->chipinfo.rev, bus->chipinfo.pkg,
|
||||
core->id.rev, bus->boardinfo.type, bus->boardinfo.vendor,
|
||||
brcmu_boardrev_str(hw->boardrev, boardrev),
|
||||
drvr->wlc->hw->boardflags, drvr->wlc->hw->boardflags2,
|
||||
drvr->wlc->ucode_rev, hw->band->radiorev,
|
||||
hw->band->phytype, hw->band->phyrev, hw->band->pi->ana_rev,
|
||||
hw->sromrev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcms_debugfs_macstat_read(struct seq_file *s, void *data)
|
||||
{
|
||||
struct brcms_pub *drvr = s->private;
|
||||
struct brcms_info *wl = drvr->ieee_hw->priv;
|
||||
struct macstat stats;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&wl->lock);
|
||||
stats = *(drvr->wlc->core->macstat_snapshot);
|
||||
spin_unlock_bh(&wl->lock);
|
||||
|
||||
seq_printf(s, "txallfrm: %d\n", stats.txallfrm);
|
||||
seq_printf(s, "txrtsfrm: %d\n", stats.txrtsfrm);
|
||||
seq_printf(s, "txctsfrm: %d\n", stats.txctsfrm);
|
||||
seq_printf(s, "txackfrm: %d\n", stats.txackfrm);
|
||||
seq_printf(s, "txdnlfrm: %d\n", stats.txdnlfrm);
|
||||
seq_printf(s, "txbcnfrm: %d\n", stats.txbcnfrm);
|
||||
seq_printf(s, "txfunfl[8]:");
|
||||
for (i = 0; i < ARRAY_SIZE(stats.txfunfl); i++)
|
||||
seq_printf(s, " %d", stats.txfunfl[i]);
|
||||
seq_printf(s, "\ntxtplunfl: %d\n", stats.txtplunfl);
|
||||
seq_printf(s, "txphyerr: %d\n", stats.txphyerr);
|
||||
seq_printf(s, "pktengrxducast: %d\n", stats.pktengrxducast);
|
||||
seq_printf(s, "pktengrxdmcast: %d\n", stats.pktengrxdmcast);
|
||||
seq_printf(s, "rxfrmtoolong: %d\n", stats.rxfrmtoolong);
|
||||
seq_printf(s, "rxfrmtooshrt: %d\n", stats.rxfrmtooshrt);
|
||||
seq_printf(s, "rxinvmachdr: %d\n", stats.rxinvmachdr);
|
||||
seq_printf(s, "rxbadfcs: %d\n", stats.rxbadfcs);
|
||||
seq_printf(s, "rxbadplcp: %d\n", stats.rxbadplcp);
|
||||
seq_printf(s, "rxcrsglitch: %d\n", stats.rxcrsglitch);
|
||||
seq_printf(s, "rxstrt: %d\n", stats.rxstrt);
|
||||
seq_printf(s, "rxdfrmucastmbss: %d\n", stats.rxdfrmucastmbss);
|
||||
seq_printf(s, "rxmfrmucastmbss: %d\n", stats.rxmfrmucastmbss);
|
||||
seq_printf(s, "rxcfrmucast: %d\n", stats.rxcfrmucast);
|
||||
seq_printf(s, "rxrtsucast: %d\n", stats.rxrtsucast);
|
||||
seq_printf(s, "rxctsucast: %d\n", stats.rxctsucast);
|
||||
seq_printf(s, "rxackucast: %d\n", stats.rxackucast);
|
||||
seq_printf(s, "rxdfrmocast: %d\n", stats.rxdfrmocast);
|
||||
seq_printf(s, "rxmfrmocast: %d\n", stats.rxmfrmocast);
|
||||
seq_printf(s, "rxcfrmocast: %d\n", stats.rxcfrmocast);
|
||||
seq_printf(s, "rxrtsocast: %d\n", stats.rxrtsocast);
|
||||
seq_printf(s, "rxctsocast: %d\n", stats.rxctsocast);
|
||||
seq_printf(s, "rxdfrmmcast: %d\n", stats.rxdfrmmcast);
|
||||
seq_printf(s, "rxmfrmmcast: %d\n", stats.rxmfrmmcast);
|
||||
seq_printf(s, "rxcfrmmcast: %d\n", stats.rxcfrmmcast);
|
||||
seq_printf(s, "rxbeaconmbss: %d\n", stats.rxbeaconmbss);
|
||||
seq_printf(s, "rxdfrmucastobss: %d\n", stats.rxdfrmucastobss);
|
||||
seq_printf(s, "rxbeaconobss: %d\n", stats.rxbeaconobss);
|
||||
seq_printf(s, "rxrsptmout: %d\n", stats.rxrsptmout);
|
||||
seq_printf(s, "bcntxcancl: %d\n", stats.bcntxcancl);
|
||||
seq_printf(s, "rxf0ovfl: %d\n", stats.rxf0ovfl);
|
||||
seq_printf(s, "rxf1ovfl: %d\n", stats.rxf1ovfl);
|
||||
seq_printf(s, "rxf2ovfl: %d\n", stats.rxf2ovfl);
|
||||
seq_printf(s, "txsfovfl: %d\n", stats.txsfovfl);
|
||||
seq_printf(s, "pmqovfl: %d\n", stats.pmqovfl);
|
||||
seq_printf(s, "rxcgprqfrm: %d\n", stats.rxcgprqfrm);
|
||||
seq_printf(s, "rxcgprsqovfl: %d\n", stats.rxcgprsqovfl);
|
||||
seq_printf(s, "txcgprsfail: %d\n", stats.txcgprsfail);
|
||||
seq_printf(s, "txcgprssuc: %d\n", stats.txcgprssuc);
|
||||
seq_printf(s, "prs_timeout: %d\n", stats.prs_timeout);
|
||||
seq_printf(s, "rxnack: %d\n", stats.rxnack);
|
||||
seq_printf(s, "frmscons: %d\n", stats.frmscons);
|
||||
seq_printf(s, "txnack: %d\n", stats.txnack);
|
||||
seq_printf(s, "txglitch_nack: %d\n", stats.txglitch_nack);
|
||||
seq_printf(s, "txburst: %d\n", stats.txburst);
|
||||
seq_printf(s, "bphy_rxcrsglitch: %d\n", stats.bphy_rxcrsglitch);
|
||||
seq_printf(s, "phywatchdog: %d\n", stats.phywatchdog);
|
||||
seq_printf(s, "bphy_badplcp: %d\n", stats.bphy_badplcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct brcms_debugfs_entry {
|
||||
int (*read)(struct seq_file *seq, void *data);
|
||||
struct brcms_pub *drvr;
|
||||
};
|
||||
|
||||
static int brcms_debugfs_entry_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
struct brcms_debugfs_entry *entry = inode->i_private;
|
||||
|
||||
return single_open(f, entry->read, entry->drvr);
|
||||
}
|
||||
|
||||
static const struct file_operations brcms_debugfs_def_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = brcms_debugfs_entry_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek
|
||||
};
|
||||
|
||||
static int
|
||||
brcms_debugfs_add_entry(struct brcms_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data))
|
||||
{
|
||||
struct device *dev = &drvr->wlc->hw->d11core->dev;
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
struct brcms_debugfs_entry *entry;
|
||||
|
||||
if (IS_ERR_OR_NULL(dentry))
|
||||
return -ENOENT;
|
||||
|
||||
entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->read = read_fn;
|
||||
entry->drvr = drvr;
|
||||
|
||||
dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
|
||||
&brcms_debugfs_def_ops);
|
||||
|
||||
return PTR_ERR_OR_ZERO(dentry);
|
||||
}
|
||||
|
||||
void brcms_debugfs_create_files(struct brcms_pub *drvr)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(drvr->dbgfs_dir))
|
||||
return;
|
||||
|
||||
brcms_debugfs_add_entry(drvr, "hardware", brcms_debugfs_hardware_read);
|
||||
brcms_debugfs_add_entry(drvr, "macstat", brcms_debugfs_macstat_read);
|
||||
}
|
||||
|
||||
#define __brcms_fn(fn) \
|
||||
void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
|
||||
{ \
|
||||
struct va_format vaf = { \
|
||||
.fmt = fmt, \
|
||||
}; \
|
||||
va_list args; \
|
||||
\
|
||||
va_start(args, fmt); \
|
||||
vaf.va = &args; \
|
||||
dev_ ##fn(dev, "%pV", &vaf); \
|
||||
trace_brcms_ ##fn(&vaf); \
|
||||
va_end(args); \
|
||||
}
|
||||
|
||||
__brcms_fn(info)
|
||||
__brcms_fn(warn)
|
||||
__brcms_fn(err)
|
||||
__brcms_fn(crit)
|
||||
|
||||
#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
|
||||
void __brcms_dbg(struct device *dev, u32 level, const char *func,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
#ifdef CONFIG_BRCMDBG
|
||||
if ((brcm_msg_level & level) && net_ratelimit())
|
||||
dev_err(dev, "%s %pV", func, &vaf);
|
||||
#endif
|
||||
trace_brcms_dbg(level, func, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
76
drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h
Normal file
76
drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
* Copyright (c) 2012 Canonical Ltd.
|
||||
*
|
||||
* 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 _BRCMS_DEBUG_H_
|
||||
#define _BRCMS_DEBUG_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "main.h"
|
||||
#include "mac80211_if.h"
|
||||
|
||||
__printf(2, 3)
|
||||
void __brcms_info(struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
void __brcms_warn(struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
void __brcms_err(struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
void __brcms_crit(struct device *dev, const char *fmt, ...);
|
||||
|
||||
#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
|
||||
__printf(4, 5)
|
||||
void __brcms_dbg(struct device *dev, u32 level, const char *func,
|
||||
const char *fmt, ...);
|
||||
#else
|
||||
static inline __printf(4, 5)
|
||||
void __brcms_dbg(struct device *dev, u32 level, const char *func,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug macros cannot be used when wlc is uninitialized. Generally
|
||||
* this means any code that could run before brcms_c_attach() has
|
||||
* returned successfully probably shouldn't use the following macros.
|
||||
*/
|
||||
|
||||
#define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a)
|
||||
#define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a)
|
||||
#define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a)
|
||||
#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a)
|
||||
#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a)
|
||||
|
||||
#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
|
||||
#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a)
|
||||
#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a)
|
||||
#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)
|
||||
#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a)
|
||||
#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)
|
||||
#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a)
|
||||
|
||||
struct brcms_pub;
|
||||
void brcms_debugfs_init(void);
|
||||
void brcms_debugfs_exit(void);
|
||||
int brcms_debugfs_attach(struct brcms_pub *drvr);
|
||||
void brcms_debugfs_detach(struct brcms_pub *drvr);
|
||||
struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr);
|
||||
void brcms_debugfs_create_files(struct brcms_pub *drvr);
|
||||
|
||||
#endif /* _BRCMS_DEBUG_H_ */
|
1564
drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
Normal file
1564
drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
Normal file
File diff suppressed because it is too large
Load Diff
125
drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h
Normal file
125
drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
/* map/unmap direction */
|
||||
#define DMA_TX 1 /* TX direction for DMA */
|
||||
#define DMA_RX 2 /* RX direction for DMA */
|
||||
|
||||
/* 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 */
|
||||
|
||||
struct dma32diag { /* diag access */
|
||||
u32 fifoaddr; /* diag address */
|
||||
u32 fifodatalow; /* low 32bits of data */
|
||||
u32 fifodatahigh; /* high 32bits of data */
|
||||
u32 pad; /* reserved */
|
||||
};
|
||||
|
||||
/* 64 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
struct dma64regs {
|
||||
u32 control; /* enable, et al */
|
||||
u32 ptr; /* last descriptor posted to chip */
|
||||
u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */
|
||||
u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */
|
||||
u32 status0; /* current descriptor, xmt state */
|
||||
u32 status1; /* active descriptor, xmt error */
|
||||
};
|
||||
|
||||
/* range param for dma_getnexttxp() and dma_txreclaim */
|
||||
enum txd_range {
|
||||
DMA_RANGE_ALL = 1,
|
||||
DMA_RANGE_TRANSMITTED,
|
||||
DMA_RANGE_TRANSFERED
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported data structure (read-only)
|
||||
*/
|
||||
/* export structure */
|
||||
struct dma_pub {
|
||||
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 brcms_c_info *wlc,
|
||||
uint txregbase, uint rxregbase,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset);
|
||||
|
||||
void dma_rxinit(struct dma_pub *pub);
|
||||
int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
|
||||
bool dma_rxfill(struct dma_pub *pub);
|
||||
bool dma_rxreset(struct dma_pub *pub);
|
||||
bool dma_txreset(struct dma_pub *pub);
|
||||
void dma_txinit(struct dma_pub *pub);
|
||||
int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
|
||||
struct sk_buff *p0);
|
||||
void dma_txflush(struct dma_pub *pub);
|
||||
int dma_txpending(struct dma_pub *pub);
|
||||
void dma_kick_tx(struct dma_pub *pub);
|
||||
void dma_txsuspend(struct dma_pub *pub);
|
||||
bool dma_txsuspended(struct dma_pub *pub);
|
||||
void dma_txresume(struct dma_pub *pub);
|
||||
void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_rxreclaim(struct dma_pub *pub);
|
||||
void dma_detach(struct dma_pub *pub);
|
||||
unsigned long dma_getvar(struct dma_pub *pub, const char *name);
|
||||
struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_counterreset(struct dma_pub *pub);
|
||||
|
||||
void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
|
||||
(void *pkt, void *arg_a), void *arg_a);
|
||||
|
||||
/*
|
||||
* DMA(Bug) on bcm47xx 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(CONFIG_BCM47XX)
|
||||
if (!len) {
|
||||
while (!(len = *(u16 *) KSEG1ADDR(head->data)))
|
||||
udelay(1);
|
||||
|
||||
*(u16 *) (head->data) = cpu_to_le16((u16) len);
|
||||
}
|
||||
#endif /* defined(CONFIG_BCM47XX) */
|
||||
}
|
||||
|
||||
#endif /* _BRCM_DMA_H_ */
|
126
drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
Normal file
126
drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/bcma/bcma_driver_chipcommon.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include "mac80211_if.h"
|
||||
#include "pub.h"
|
||||
#include "main.h"
|
||||
#include "led.h"
|
||||
|
||||
/* number of leds */
|
||||
#define BRCMS_LED_NO 4
|
||||
/* behavior mask */
|
||||
#define BRCMS_LED_BEH_MASK 0x7f
|
||||
/* activelow (polarity) bit */
|
||||
#define BRCMS_LED_AL_MASK 0x80
|
||||
/* radio enabled */
|
||||
#define BRCMS_LED_RADIO 3
|
||||
|
||||
static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
|
||||
{
|
||||
if (wl->radio_led.gpio == -1)
|
||||
return;
|
||||
|
||||
if (wl->radio_led.active_low)
|
||||
state = !state;
|
||||
|
||||
if (state)
|
||||
gpio_set_value(wl->radio_led.gpio, 1);
|
||||
else
|
||||
gpio_set_value(wl->radio_led.gpio, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Callback from the LED subsystem. */
|
||||
static void brcms_led_brightness_set(struct led_classdev *led_dev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct brcms_info *wl = container_of(led_dev,
|
||||
struct brcms_info, led_dev);
|
||||
brcms_radio_led_ctrl(wl, brightness);
|
||||
}
|
||||
|
||||
void brcms_led_unregister(struct brcms_info *wl)
|
||||
{
|
||||
if (wl->led_dev.dev)
|
||||
led_classdev_unregister(&wl->led_dev);
|
||||
if (wl->radio_led.gpio != -1)
|
||||
gpio_free(wl->radio_led.gpio);
|
||||
}
|
||||
|
||||
int brcms_led_register(struct brcms_info *wl)
|
||||
{
|
||||
int i, err;
|
||||
struct brcms_led *radio_led = &wl->radio_led;
|
||||
/* get CC core */
|
||||
struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc;
|
||||
struct gpio_chip *bcma_gpio = &cc_drv->gpio;
|
||||
struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
|
||||
u8 *leds[] = { &sprom->gpio0,
|
||||
&sprom->gpio1,
|
||||
&sprom->gpio2,
|
||||
&sprom->gpio3 };
|
||||
unsigned gpio = -1;
|
||||
bool active_low = false;
|
||||
|
||||
/* none by default */
|
||||
radio_led->gpio = -1;
|
||||
radio_led->active_low = false;
|
||||
|
||||
if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
|
||||
return -ENODEV;
|
||||
|
||||
/* find radio enabled LED */
|
||||
for (i = 0; i < BRCMS_LED_NO; i++) {
|
||||
u8 led = *leds[i];
|
||||
if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
|
||||
gpio = bcma_gpio->base + i;
|
||||
if (led & BRCMS_LED_AL_MASK)
|
||||
active_low = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpio == -1 || !gpio_is_valid(gpio))
|
||||
return -ENODEV;
|
||||
|
||||
/* request and configure LED gpio */
|
||||
err = gpio_request_one(gpio,
|
||||
active_low ? GPIOF_OUT_INIT_HIGH
|
||||
: GPIOF_OUT_INIT_LOW,
|
||||
"radio on");
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
|
||||
gpio, err);
|
||||
return err;
|
||||
}
|
||||
err = gpio_direction_output(gpio, 1);
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
|
||||
gpio, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
|
||||
"brcmsmac-%s:radio", wiphy_name(wl->wiphy));
|
||||
|
||||
wl->led_dev.name = wl->radio_led.name;
|
||||
wl->led_dev.default_trigger =
|
||||
ieee80211_get_radio_led_name(wl->pub->ieee_hw);
|
||||
wl->led_dev.brightness_set = brcms_led_brightness_set;
|
||||
err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
|
||||
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
|
||||
wl->radio_led.name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
|
||||
wl->radio_led.name,
|
||||
gpio);
|
||||
radio_led->gpio = gpio;
|
||||
radio_led->active_low = active_low;
|
||||
|
||||
return 0;
|
||||
}
|
36
drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
Normal file
36
drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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_LED_H_
|
||||
#define _BRCM_LED_H_
|
||||
struct brcms_led {
|
||||
char name[32];
|
||||
unsigned gpio;
|
||||
bool active_low;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
static inline void brcms_led_unregister(struct brcms_info *wl) {};
|
||||
static inline int brcms_led_register(struct brcms_info *wl)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _BRCM_LED_H_ */
|
1700
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
Normal file
1700
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
Normal file
File diff suppressed because it is too large
Load Diff
113
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.h
Normal file
113
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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_MAC80211_IF_H_
|
||||
#define _BRCM_MAC80211_IF_H_
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include "ucode_loader.h"
|
||||
#include "led.h"
|
||||
/*
|
||||
* Starting index for 5G rates in the
|
||||
* legacy rate table.
|
||||
*/
|
||||
#define BRCMS_LEGACY_5G_RATE_OFFSET 4
|
||||
|
||||
/* softmac ioctl definitions */
|
||||
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
|
||||
|
||||
struct brcms_timer {
|
||||
struct delayed_work dly_wrk;
|
||||
struct brcms_info *wl;
|
||||
void (*fn) (void *); /* function called upon expiration */
|
||||
void *arg; /* fixed argument provided to called function */
|
||||
uint ms;
|
||||
bool periodic;
|
||||
bool set; /* indicates if timer is active */
|
||||
struct brcms_timer *next; /* for freeing on unload */
|
||||
#ifdef DEBUG
|
||||
char *name; /* Description of the timer */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct brcms_if {
|
||||
uint subunit; /* WDS/BSS unit */
|
||||
struct pci_dev *pci_dev;
|
||||
};
|
||||
|
||||
#define MAX_FW_IMAGES 4
|
||||
struct brcms_firmware {
|
||||
u32 fw_cnt;
|
||||
const struct firmware *fw_bin[MAX_FW_IMAGES];
|
||||
const struct firmware *fw_hdr[MAX_FW_IMAGES];
|
||||
u32 hdr_num_entries[MAX_FW_IMAGES];
|
||||
};
|
||||
|
||||
struct brcms_info {
|
||||
struct brcms_pub *pub; /* pointer to public wlc state */
|
||||
struct brcms_c_info *wlc; /* pointer to private common data */
|
||||
u32 magic;
|
||||
|
||||
int irq;
|
||||
|
||||
spinlock_t lock; /* per-device perimeter lock */
|
||||
spinlock_t isr_lock; /* per-device ISR synchronization lock */
|
||||
|
||||
/* tx flush */
|
||||
wait_queue_head_t tx_flush_wq;
|
||||
|
||||
/* timer related fields */
|
||||
atomic_t callbacks; /* # outstanding callback functions */
|
||||
struct brcms_timer *timers; /* timer cleanup queue */
|
||||
|
||||
struct tasklet_struct tasklet; /* dpc tasklet */
|
||||
bool resched; /* dpc needs to be and is rescheduled */
|
||||
struct brcms_firmware fw;
|
||||
struct wiphy *wiphy;
|
||||
struct brcms_ucode ucode;
|
||||
bool mute_tx;
|
||||
struct brcms_led radio_led;
|
||||
struct led_classdev led_dev;
|
||||
};
|
||||
|
||||
/* misc callbacks */
|
||||
void brcms_init(struct brcms_info *wl);
|
||||
uint brcms_reset(struct brcms_info *wl);
|
||||
void brcms_intrson(struct brcms_info *wl);
|
||||
u32 brcms_intrsoff(struct brcms_info *wl);
|
||||
void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
|
||||
int brcms_up(struct brcms_info *wl);
|
||||
void brcms_down(struct brcms_info *wl);
|
||||
void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
|
||||
bool state, int prio);
|
||||
bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
|
||||
|
||||
/* timer functions */
|
||||
struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name);
|
||||
void brcms_free_timer(struct brcms_timer *timer);
|
||||
void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
|
||||
bool brcms_del_timer(struct brcms_timer *timer);
|
||||
void brcms_dpc(unsigned long data);
|
||||
void brcms_timer(struct brcms_timer *t);
|
||||
void brcms_fatal_error(struct brcms_info *wl);
|
||||
|
||||
#endif /* _BRCM_MAC80211_IF_H_ */
|
8139
drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c
Normal file
8139
drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c
Normal file
File diff suppressed because it is too large
Load Diff
669
drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
Normal file
669
drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
Normal file
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* 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_MAIN_H_
|
||||
#define _BRCM_MAIN_H_
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "scb.h"
|
||||
|
||||
#define INVCHANNEL 255 /* invalid channel */
|
||||
|
||||
/* max # brcms_c_module_register() calls */
|
||||
#define BRCMS_MAXMODULES 22
|
||||
|
||||
#define SEQNUM_SHIFT 4
|
||||
#define SEQNUM_MAX 0x1000
|
||||
|
||||
#define NTXRATE 64 /* # tx MPDUs rate is reported for */
|
||||
|
||||
/* Maximum wait time for a MAC suspend */
|
||||
/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
|
||||
#define BRCMS_MAX_MAC_SUSPEND 83000
|
||||
|
||||
/* responses for probe requests older that this are tossed, zero to disable */
|
||||
#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
|
||||
|
||||
/* transmit buffer max headroom for protocol headers */
|
||||
#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
|
||||
|
||||
/* 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))
|
||||
|
||||
#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
|
||||
|
||||
/* max # supported core revisions (0 .. MAXCOREREV - 1) */
|
||||
#define MAXCOREREV 28
|
||||
|
||||
/* Double check that unsupported cores are not enabled */
|
||||
#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
|
||||
#error "Configuration for D11CONF includes unsupported versions."
|
||||
#endif /* Bad versions */
|
||||
|
||||
/* values for shortslot_override */
|
||||
#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
|
||||
#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */
|
||||
#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */
|
||||
|
||||
/* value for short/long and mixmode/greenfield preamble */
|
||||
#define BRCMS_LONG_PREAMBLE (0)
|
||||
#define BRCMS_SHORT_PREAMBLE (1 << 0)
|
||||
#define BRCMS_GF_PREAMBLE (1 << 1)
|
||||
#define BRCMS_MM_PREAMBLE (1 << 2)
|
||||
#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
|
||||
((_pre) == BRCMS_MM_PREAMBLE))
|
||||
|
||||
/* TxFrameID */
|
||||
/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
|
||||
/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
|
||||
#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
|
||||
#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
|
||||
#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
|
||||
#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
|
||||
#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
|
||||
#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
|
||||
|
||||
/* promote boardrev */
|
||||
#define BOARDREV_PROMOTABLE 0xFF /* from */
|
||||
#define BOARDREV_PROMOTED 1 /* to */
|
||||
|
||||
#define DATA_BLOCK_TX_SUPR (1 << 4)
|
||||
|
||||
/* Ucode MCTL_WAKE override bits */
|
||||
#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
|
||||
#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
|
||||
#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04
|
||||
#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08
|
||||
#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10
|
||||
|
||||
/* stuff pulled in from wlc.c */
|
||||
|
||||
/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
|
||||
* times; and if we run out, constant I_RU interrupts may cause lockup. We
|
||||
* will still get error counts from rx0ovfl.
|
||||
*/
|
||||
#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
|
||||
/* default software intmasks */
|
||||
#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
|
||||
#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
|
||||
MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
|
||||
MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
|
||||
|
||||
#define MAXTXPKTS 6 /* max # pkts pending */
|
||||
|
||||
/* frameburst */
|
||||
#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
|
||||
#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
|
||||
|
||||
#define NFIFO 6 /* # tx/rx fifopairs */
|
||||
|
||||
/* PLL requests */
|
||||
|
||||
/* pll is shared on old chips */
|
||||
#define BRCMS_PLLREQ_SHARED 0x1
|
||||
/* hold pll for radio monitor register checking */
|
||||
#define BRCMS_PLLREQ_RADIO_MON 0x2
|
||||
/* hold/release pll for some short operation */
|
||||
#define BRCMS_PLLREQ_FLIP 0x4
|
||||
|
||||
#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))
|
||||
|
||||
/*
|
||||
* 802.11 protection information
|
||||
*
|
||||
* _g: use g spec protection, driver internal.
|
||||
* g_override: override for use of g spec protection.
|
||||
* gmode_user: user config gmode, operating band->gmode is different.
|
||||
* overlap: Overlap BSS/IBSS protection for both 11g and 11n.
|
||||
* nmode_user: user config nmode, operating pub->nmode is different.
|
||||
* n_cfg: use OFDM protection on MIMO frames.
|
||||
* n_cfg_override: override for use of N protection.
|
||||
* nongf: non-GF present protection.
|
||||
* nongf_override: override for use of GF protection.
|
||||
* n_pam_override: override for preamble: MM or GF.
|
||||
* n_obss: indicated OBSS Non-HT STA present.
|
||||
*/
|
||||
struct brcms_protection {
|
||||
bool _g;
|
||||
s8 g_override;
|
||||
u8 gmode_user;
|
||||
s8 overlap;
|
||||
s8 nmode_user;
|
||||
s8 n_cfg;
|
||||
s8 n_cfg_override;
|
||||
bool nongf;
|
||||
s8 nongf_override;
|
||||
s8 n_pam_override;
|
||||
bool n_obss;
|
||||
};
|
||||
|
||||
/*
|
||||
* anything affecting the single/dual streams/antenna operation
|
||||
*
|
||||
* hw_txchain: HW txchain bitmap cfg.
|
||||
* txchain: txchain bitmap being used.
|
||||
* txstreams: number of txchains being used.
|
||||
* hw_rxchain: HW rxchain bitmap cfg.
|
||||
* rxchain: rxchain bitmap being used.
|
||||
* rxstreams: number of rxchains being used.
|
||||
* ant_rx_ovr: rx antenna override.
|
||||
* txant: userTx antenna setting.
|
||||
* phytxant: phyTx antenna setting in txheader.
|
||||
* ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
|
||||
* ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
|
||||
* else use wlc->band->stf->ss_mode_band.
|
||||
* ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
|
||||
* rxchain_restore_delay: delay time to restore default rxchain.
|
||||
* ldpc: AUTO/ON/OFF ldpc cap supported.
|
||||
* txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
|
||||
* spatial_policy:
|
||||
*/
|
||||
struct brcms_stf {
|
||||
u8 hw_txchain;
|
||||
u8 txchain;
|
||||
u8 txstreams;
|
||||
u8 hw_rxchain;
|
||||
u8 rxchain;
|
||||
u8 rxstreams;
|
||||
u8 ant_rx_ovr;
|
||||
s8 txant;
|
||||
u16 phytxant;
|
||||
u8 ss_opmode;
|
||||
bool ss_algosel_auto;
|
||||
u16 ss_algo_channel;
|
||||
u8 rxchain_restore_delay;
|
||||
s8 ldpc;
|
||||
u8 txcore[MAX_STREAMS_SUPPORTED + 1];
|
||||
s8 spatial_policy;
|
||||
};
|
||||
|
||||
#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
|
||||
(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
|
||||
|| (((scb)->flags & SCB_STBCCAP) && \
|
||||
(wlc)->band->band_stf_stbc_tx == AUTO && \
|
||||
isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
|
||||
|
||||
#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3))
|
||||
|
||||
#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3)) || \
|
||||
BRCMS_ISLCNPHY(wlc->band))
|
||||
|
||||
#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \
|
||||
>> RXS_CHAN_PHYTYPE_SHIFT)
|
||||
#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \
|
||||
>> RXS_CHAN_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* core state (mac)
|
||||
*/
|
||||
struct brcms_core {
|
||||
uint coreidx; /* # sb enumerated core */
|
||||
|
||||
/* fifo */
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
|
||||
struct macstat *macstat_snapshot; /* mac hw prev read values */
|
||||
};
|
||||
|
||||
/*
|
||||
* band state (phy+ana+radio)
|
||||
*/
|
||||
struct brcms_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
|
||||
u8 gmode; /* currently active gmode */
|
||||
|
||||
struct scb *hwrs_scb; /* permanent scb for hw rateset */
|
||||
|
||||
/* band-specific copy of default_bss.rateset */
|
||||
struct brcms_c_rateset defrateset;
|
||||
|
||||
u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
|
||||
s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
|
||||
/* rates supported by chip (phy-specific) */
|
||||
struct brcms_c_rateset hw_rateset;
|
||||
u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
|
||||
bool mimo_cap_40; /* 40 MHz cap enabled on this band */
|
||||
s8 antgain; /* antenna gain from srom */
|
||||
|
||||
u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
|
||||
u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
|
||||
struct ieee80211_supported_band band;
|
||||
};
|
||||
|
||||
/* module control blocks */
|
||||
struct modulecb {
|
||||
/* module name : NULL indicates empty array member */
|
||||
char name[32];
|
||||
/* handle passed when handler 'doiovar' is called */
|
||||
struct brcms_info *hdl;
|
||||
|
||||
int (*down_fn)(void *handle); /* down handler. Note: the int returned
|
||||
* by the down function is a count of the
|
||||
* number of timers that could not be
|
||||
* freed.
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
struct brcms_hw_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
u16 mhfs[MHFMAX]; /* MHF array shadow */
|
||||
u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
|
||||
u16 CWmin;
|
||||
u16 CWmax;
|
||||
u32 core_flags;
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
};
|
||||
|
||||
struct brcms_hardware {
|
||||
bool _piomode; /* true if pio mode */
|
||||
struct brcms_c_info *wlc;
|
||||
|
||||
/* fifo */
|
||||
struct dma_pub *di[NFIFO]; /* dma handles, per fifo */
|
||||
|
||||
uint unit; /* device instance number */
|
||||
|
||||
/* version info */
|
||||
u16 vendorid; /* PCI vendor id */
|
||||
u16 deviceid; /* PCI device id */
|
||||
uint corerev; /* core revision */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
u32 machwcap; /* MAC capabilities */
|
||||
u32 machwcap_backup; /* backup of machwcap */
|
||||
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
struct bcma_device *d11core; /* pointer to 802.11 core */
|
||||
struct phy_shim_info *physhim; /* phy shim layer handler */
|
||||
struct shared_phy *phy_sh; /* pointer to shared phy state */
|
||||
struct brcms_hw_band *band;/* pointer to active per-band state */
|
||||
/* band state per phy/radio */
|
||||
struct brcms_hw_band *bandstate[MAXBANDS];
|
||||
u16 bmac_phytxant; /* cache of high phytxant state */
|
||||
bool shortslot; /* currently using 11g ShortSlot timing */
|
||||
u16 SRL; /* 802.11 dot11ShortRetryLimit */
|
||||
u16 LRL; /* 802.11 dot11LongRetryLimit */
|
||||
u16 SFBL; /* Short Frame Rate Fallback Limit */
|
||||
u16 LFBL; /* Long Frame Rate Fallback Limit */
|
||||
|
||||
bool up; /* d11 hardware up and running */
|
||||
uint now; /* # elapsed seconds */
|
||||
uint _nbands; /* # bands supported */
|
||||
u16 chanspec; /* bmac chanspec shadow */
|
||||
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
const u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
|
||||
|
||||
u32 pllreq; /* pll requests to keep PLL on */
|
||||
|
||||
u8 suspended_fifos; /* Which TX fifo to remain awake for */
|
||||
u32 maccontrol; /* Cached value of maccontrol */
|
||||
uint mac_suspend_depth; /* current depth of mac_suspend levels */
|
||||
u32 wake_override; /* bit flags to force MAC to WAKE mode */
|
||||
u32 mute_override; /* Prevent ucode from sending beacons */
|
||||
u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */
|
||||
bool noreset; /* true= do not reset hw, used by WLC_OUT */
|
||||
bool forcefastclk; /* true if h/w is forcing to use fast clk */
|
||||
bool clk; /* core is out of reset and has clock */
|
||||
bool sbclk; /* sb has clock */
|
||||
bool phyclk; /* phy is out of reset and has clock */
|
||||
|
||||
bool ucode_loaded; /* true after ucode downloaded */
|
||||
|
||||
|
||||
u8 hw_stf_ss_opmode; /* STF single stream operation mode */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u32 antsel_avail; /*
|
||||
* put struct antsel_info here if more info is
|
||||
* needed
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* Principal common driver data structure.
|
||||
*
|
||||
* pub: pointer to driver public state.
|
||||
* wl: pointer to specific private state.
|
||||
* hw: HW related state.
|
||||
* clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
|
||||
* fastpwrup_dly: time in us needed to bring up d11 fast clock.
|
||||
* macintstatus: bit channel between isr and dpc.
|
||||
* macintmask: sw runtime master macintmask value.
|
||||
* defmacintmask: default "on" macintmask value.
|
||||
* clk: core is out of reset and has clock.
|
||||
* core: pointer to active io core.
|
||||
* band: pointer to active per-band state.
|
||||
* corestate: per-core state (one per hw core).
|
||||
* bandstate: per-band state (one per phy/radio).
|
||||
* qvalid: DirFrmQValid and BcMcFrmQValid.
|
||||
* ampdu: ampdu module handler.
|
||||
* asi: antsel module handler.
|
||||
* cmi: channel manager module handler.
|
||||
* vendorid: PCI vendor id.
|
||||
* deviceid: PCI device id.
|
||||
* ucode_rev: microcode revision.
|
||||
* machwcap: MAC capabilities, BMAC shadow.
|
||||
* perm_etheraddr: original sprom local ethernet address.
|
||||
* bandlocked: disable auto multi-band switching.
|
||||
* bandinit_pending: track band init in auto band.
|
||||
* radio_monitor: radio timer is running.
|
||||
* going_down: down path intermediate variable.
|
||||
* wdtimer: timer for watchdog routine.
|
||||
* radio_timer: timer for hw radio button monitor routine.
|
||||
* monitor: monitor (MPDU sniffing) mode.
|
||||
* bcnmisc_monitor: bcns promisc mode override for monitor.
|
||||
* _rifs: enable per-packet rifs.
|
||||
* bcn_li_bcn: beacon listen interval in # beacons.
|
||||
* bcn_li_dtim: beacon listen interval in # dtims.
|
||||
* WDarmed: watchdog timer is armed.
|
||||
* WDlast: last time wlc_watchdog() was called.
|
||||
* edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
|
||||
* wme_retries: per-AC retry limits.
|
||||
* bsscfg: set of BSS configurations, idx 0 is default and always valid.
|
||||
* cfg: the primary bsscfg (can be AP or STA).
|
||||
* modulecb:
|
||||
* mimoft: SIGN or 11N.
|
||||
* cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
|
||||
* ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
|
||||
* mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
|
||||
* default_bss: configured BSS parameters.
|
||||
* mc_fid_counter: BC/MC FIFO frame ID counter.
|
||||
* country_default: saved country for leaving 802.11d auto-country mode.
|
||||
* autocountry_default: initial country for 802.11d auto-country mode.
|
||||
* prb_resp_timeout: do not send prb resp if request older
|
||||
* than this, 0 = disable.
|
||||
* home_chanspec: shared home chanspec.
|
||||
* chanspec: target operational channel.
|
||||
* usr_fragthresh: user configured fragmentation threshold.
|
||||
* fragthresh[NFIFO]: per-fifo fragmentation thresholds.
|
||||
* RTSThresh: 802.11 dot11RTSThreshold.
|
||||
* SRL: 802.11 dot11ShortRetryLimit.
|
||||
* LRL: 802.11 dot11LongRetryLimit.
|
||||
* SFBL: Short Frame Rate Fallback Limit.
|
||||
* LFBL: Long Frame Rate Fallback Limit.
|
||||
* shortslot: currently using 11g ShortSlot timing.
|
||||
* shortslot_override: 11g ShortSlot override.
|
||||
* include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
|
||||
* PLCPHdr_override: 802.11b Preamble Type override.
|
||||
* stf:
|
||||
* bcn_rspec: save bcn ratespec purpose.
|
||||
* tempsense_lasttime;
|
||||
* tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
|
||||
* tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
|
||||
* wiphy:
|
||||
* pri_scb: primary Station Control Block
|
||||
*/
|
||||
struct brcms_c_info {
|
||||
struct brcms_pub *pub;
|
||||
struct brcms_info *wl;
|
||||
struct brcms_hardware *hw;
|
||||
|
||||
/* clock */
|
||||
u16 fastpwrup_dly;
|
||||
|
||||
/* interrupt */
|
||||
u32 macintstatus;
|
||||
u32 macintmask;
|
||||
u32 defmacintmask;
|
||||
|
||||
bool clk;
|
||||
|
||||
/* multiband */
|
||||
struct brcms_core *core;
|
||||
struct brcms_band *band;
|
||||
struct brcms_core *corestate;
|
||||
struct brcms_band *bandstate[MAXBANDS];
|
||||
|
||||
/* packet queue */
|
||||
uint qvalid;
|
||||
|
||||
struct ampdu_info *ampdu;
|
||||
struct antsel_info *asi;
|
||||
struct brcms_cm_info *cmi;
|
||||
|
||||
u16 vendorid;
|
||||
u16 deviceid;
|
||||
uint ucode_rev;
|
||||
|
||||
u8 perm_etheraddr[ETH_ALEN];
|
||||
|
||||
bool bandlocked;
|
||||
bool bandinit_pending;
|
||||
|
||||
bool radio_monitor;
|
||||
bool going_down;
|
||||
|
||||
bool beacon_template_virgin;
|
||||
|
||||
struct brcms_timer *wdtimer;
|
||||
struct brcms_timer *radio_timer;
|
||||
|
||||
/* promiscuous */
|
||||
uint filter_flags;
|
||||
|
||||
/* driver feature */
|
||||
bool _rifs;
|
||||
|
||||
/* AP-STA synchronization, power save */
|
||||
u8 bcn_li_bcn;
|
||||
u8 bcn_li_dtim;
|
||||
|
||||
bool WDarmed;
|
||||
u32 WDlast;
|
||||
|
||||
/* WME */
|
||||
u16 edcf_txop[IEEE80211_NUM_ACS];
|
||||
|
||||
u16 wme_retries[IEEE80211_NUM_ACS];
|
||||
|
||||
struct brcms_bss_cfg *bsscfg;
|
||||
|
||||
struct modulecb *modulecb;
|
||||
|
||||
u8 mimoft;
|
||||
s8 cck_40txbw;
|
||||
s8 ofdm_40txbw;
|
||||
s8 mimo_40txbw;
|
||||
|
||||
struct brcms_bss_info *default_bss;
|
||||
|
||||
u16 mc_fid_counter;
|
||||
|
||||
char country_default[BRCM_CNTRY_BUF_SZ];
|
||||
char autocountry_default[BRCM_CNTRY_BUF_SZ];
|
||||
u16 prb_resp_timeout;
|
||||
|
||||
u16 home_chanspec;
|
||||
|
||||
/* PHY parameters */
|
||||
u16 chanspec;
|
||||
u16 usr_fragthresh;
|
||||
u16 fragthresh[NFIFO];
|
||||
u16 RTSThresh;
|
||||
u16 SRL;
|
||||
u16 LRL;
|
||||
u16 SFBL;
|
||||
u16 LFBL;
|
||||
|
||||
/* network config */
|
||||
bool shortslot;
|
||||
s8 shortslot_override;
|
||||
bool include_legacy_erp;
|
||||
|
||||
struct brcms_protection *protection;
|
||||
s8 PLCPHdr_override;
|
||||
|
||||
struct brcms_stf *stf;
|
||||
|
||||
u32 bcn_rspec;
|
||||
|
||||
uint tempsense_lasttime;
|
||||
|
||||
u16 tx_duty_cycle_ofdm;
|
||||
u16 tx_duty_cycle_cck;
|
||||
|
||||
struct wiphy *wiphy;
|
||||
struct scb pri_scb;
|
||||
|
||||
struct sk_buff *beacon;
|
||||
u16 beacon_tim_offset;
|
||||
u16 beacon_dtim_period;
|
||||
struct sk_buff *probe_resp;
|
||||
};
|
||||
|
||||
/* antsel module specific state */
|
||||
struct antsel_info {
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_pub *pub; /* pointer to public fn */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u8 antsel_antswitch; /* board level antenna switch type */
|
||||
bool antsel_avail; /* Ant selection availability (SROM based) */
|
||||
struct brcms_antselcfg antcfg_11n; /* antenna configuration */
|
||||
struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
|
||||
};
|
||||
|
||||
enum brcms_bss_type {
|
||||
BRCMS_TYPE_STATION,
|
||||
BRCMS_TYPE_AP,
|
||||
BRCMS_TYPE_ADHOC,
|
||||
};
|
||||
|
||||
/*
|
||||
* BSS configuration state
|
||||
*
|
||||
* wlc: wlc to which this bsscfg belongs to.
|
||||
* type: interface type
|
||||
* SSID_len: the length of SSID
|
||||
* SSID: SSID string
|
||||
*
|
||||
*
|
||||
* BSSID: BSSID (associated)
|
||||
* cur_etheraddr: h/w address
|
||||
* flags: BSSCFG flags; see below
|
||||
*
|
||||
* current_bss: BSS parms in ASSOCIATED state
|
||||
*
|
||||
*
|
||||
* ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
|
||||
*/
|
||||
struct brcms_bss_cfg {
|
||||
struct brcms_c_info *wlc;
|
||||
enum brcms_bss_type type;
|
||||
u8 SSID_len;
|
||||
u8 SSID[IEEE80211_MAX_SSID_LEN];
|
||||
u8 BSSID[ETH_ALEN];
|
||||
struct brcms_bss_info *current_bss;
|
||||
};
|
||||
|
||||
int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p);
|
||||
int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
|
||||
uint *blocks);
|
||||
|
||||
int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
|
||||
void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
|
||||
u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len);
|
||||
u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
|
||||
bool use_rspec, u16 mimo_ctlchbw);
|
||||
u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
|
||||
u32 rts_rate, u32 frame_rate,
|
||||
u8 rts_preamble_type, u8 frame_preamble_type,
|
||||
uint frame_len, bool ba);
|
||||
void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
|
||||
struct ieee80211_sta *sta, void (*dma_callback_fn));
|
||||
void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
|
||||
int brcms_c_set_nmode(struct brcms_c_info *wlc);
|
||||
void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, u32 bcn_rate);
|
||||
void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type);
|
||||
void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
|
||||
bool mute, struct txpwr_limits *txpwr);
|
||||
void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v);
|
||||
u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
|
||||
void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
|
||||
int bands);
|
||||
void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
|
||||
void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
|
||||
void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
|
||||
void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
|
||||
void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
|
||||
void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset,
|
||||
int len, void *buf);
|
||||
u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
|
||||
void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
|
||||
const void *buf, int len, u32 sel);
|
||||
void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
|
||||
void *buf, int len, u32 sel);
|
||||
void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
|
||||
u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
|
||||
void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
|
||||
void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
|
||||
void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
|
||||
void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
|
||||
void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode);
|
||||
void brcms_c_init_scb(struct scb *scb);
|
||||
|
||||
#endif /* _BRCM_MAIN_H_ */
|
2953
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
2953
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
File diff suppressed because it is too large
Load Diff
284
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
284
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_hal.h: functionality exported from the phy to higher layers
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_HAL_H_
|
||||
#define _BRCM_PHY_HAL_H_
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <phy_shim.h>
|
||||
|
||||
#define IDCODE_VER_MASK 0x0000000f
|
||||
#define IDCODE_VER_SHIFT 0
|
||||
#define IDCODE_MFG_MASK 0x00000fff
|
||||
#define IDCODE_MFG_SHIFT 0
|
||||
#define IDCODE_ID_MASK 0x0ffff000
|
||||
#define IDCODE_ID_SHIFT 12
|
||||
#define IDCODE_REV_MASK 0xf0000000
|
||||
#define IDCODE_REV_SHIFT 28
|
||||
|
||||
#define NORADIO_ID 0xe4f5
|
||||
#define NORADIO_IDCODE 0x4e4f5246
|
||||
|
||||
#define BCM2055_ID 0x2055
|
||||
#define BCM2055_IDCODE 0x02055000
|
||||
#define BCM2055A0_IDCODE 0x1205517f
|
||||
|
||||
#define BCM2056_ID 0x2056
|
||||
#define BCM2056_IDCODE 0x02056000
|
||||
#define BCM2056A0_IDCODE 0x1205617f
|
||||
|
||||
#define BCM2057_ID 0x2057
|
||||
#define BCM2057_IDCODE 0x02057000
|
||||
#define BCM2057A0_IDCODE 0x1205717f
|
||||
|
||||
#define BCM2064_ID 0x2064
|
||||
#define BCM2064_IDCODE 0x02064000
|
||||
#define BCM2064A0_IDCODE 0x0206417f
|
||||
|
||||
#define PHY_TPC_HW_OFF false
|
||||
#define PHY_TPC_HW_ON true
|
||||
|
||||
#define PHY_PERICAL_DRIVERUP 1
|
||||
#define PHY_PERICAL_WATCHDOG 2
|
||||
#define PHY_PERICAL_PHYINIT 3
|
||||
#define PHY_PERICAL_JOIN_BSS 4
|
||||
#define PHY_PERICAL_START_IBSS 5
|
||||
#define PHY_PERICAL_UP_BSS 6
|
||||
#define PHY_PERICAL_CHAN 7
|
||||
#define PHY_FULLCAL 8
|
||||
|
||||
#define PHY_PERICAL_DISABLE 0
|
||||
#define PHY_PERICAL_SPHASE 1
|
||||
#define PHY_PERICAL_MPHASE 2
|
||||
#define PHY_PERICAL_MANUAL 3
|
||||
|
||||
#define PHY_HOLD_FOR_ASSOC 1
|
||||
#define PHY_HOLD_FOR_SCAN 2
|
||||
#define PHY_HOLD_FOR_RM 4
|
||||
#define PHY_HOLD_FOR_PLT 8
|
||||
#define PHY_HOLD_FOR_MUTE 16
|
||||
#define PHY_HOLD_FOR_NOT_ASSOC 0x20
|
||||
|
||||
#define PHY_MUTE_FOR_PREISM 1
|
||||
#define PHY_MUTE_ALL 0xffffffff
|
||||
|
||||
#define PHY_NOISE_FIXED_VAL (-95)
|
||||
#define PHY_NOISE_FIXED_VAL_NPHY (-92)
|
||||
#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
|
||||
|
||||
#define PHY_MODE_CAL 0x0002
|
||||
#define PHY_MODE_NOISEM 0x0004
|
||||
|
||||
#define BRCMS_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 BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
#define BRCMS_NUM_RATES_CCK 4
|
||||
#define BRCMS_NUM_RATES_OFDM 8
|
||||
#define BRCMS_NUM_RATES_MCS_1_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_2_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_3_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_4_STREAM 8
|
||||
|
||||
#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
|
||||
|
||||
struct d11regs;
|
||||
struct phy_shim_info;
|
||||
|
||||
struct txpwr_limits {
|
||||
u8 cck[BRCMS_NUM_RATES_CCK];
|
||||
u8 ofdm[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
|
||||
u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
|
||||
u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
u8 mcs32;
|
||||
};
|
||||
|
||||
struct tx_power {
|
||||
u32 flags;
|
||||
u16 chanspec; /* txpwr report for this channel */
|
||||
u16 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 */
|
||||
/* Index of the rate with the max target power */
|
||||
u8 tx_power_max_rate_ind[4];
|
||||
/* User limit */
|
||||
u8 user_limit[WL_TX_POWER_RATES];
|
||||
/* Regulatory power limit */
|
||||
u8 reg_limit[WL_TX_POWER_RATES];
|
||||
/* Max power board can support (SROM) */
|
||||
u8 board_limit[WL_TX_POWER_RATES];
|
||||
/* Latest target power */
|
||||
u8 target[WL_TX_POWER_RATES];
|
||||
};
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
struct brcms_chanvec {
|
||||
u8 vec[MAXCHANNEL / NBBY];
|
||||
};
|
||||
|
||||
struct shared_phy_params {
|
||||
struct si_pub *sih;
|
||||
struct phy_shim_info *physhim;
|
||||
uint unit;
|
||||
uint corerev;
|
||||
u16 vid;
|
||||
u16 did;
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
uint chippkg;
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
};
|
||||
|
||||
|
||||
struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
|
||||
struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
|
||||
struct bcma_device *d11core, int bandtype,
|
||||
struct wiphy *wiphy);
|
||||
void wlc_phy_detach(struct brcms_phy_pub *ppi);
|
||||
|
||||
bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
|
||||
u16 *phyrev, u16 *radioid, u16 *radiover);
|
||||
bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
|
||||
u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
|
||||
|
||||
void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
|
||||
void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
|
||||
int wlc_phy_down(struct brcms_phy_pub *ppi);
|
||||
u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
|
||||
void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
|
||||
|
||||
void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec);
|
||||
u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch);
|
||||
u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
|
||||
|
||||
int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, struct d11rxhdr *rxh);
|
||||
void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
|
||||
bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
|
||||
|
||||
void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
|
||||
|
||||
void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
|
||||
void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
|
||||
|
||||
|
||||
void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
|
||||
|
||||
void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
|
||||
bool wide_filter);
|
||||
void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
|
||||
struct brcms_chanvec *channels);
|
||||
u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band);
|
||||
|
||||
void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, u8 *_min_,
|
||||
u8 *_max_, int rate);
|
||||
void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
|
||||
u8 *_max_, u8 *_min_);
|
||||
void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint band,
|
||||
s32 *, s32 *, u32 *);
|
||||
void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *,
|
||||
u16 chanspec);
|
||||
int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override);
|
||||
int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override);
|
||||
void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *);
|
||||
bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl);
|
||||
u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
|
||||
u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
|
||||
bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
|
||||
|
||||
void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain);
|
||||
void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain);
|
||||
void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain);
|
||||
u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
|
||||
s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec);
|
||||
void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
|
||||
|
||||
void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
|
||||
void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
|
||||
void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
|
||||
|
||||
void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
|
||||
void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
|
||||
void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
|
||||
|
||||
void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
|
||||
|
||||
void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
|
||||
struct tx_power *power, uint channel);
|
||||
|
||||
void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
|
||||
bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent);
|
||||
void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
|
||||
void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt);
|
||||
void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
|
||||
|
||||
void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
|
||||
|
||||
void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
|
||||
void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
|
||||
|
||||
const u8 *wlc_phy_get_ofdm_rate_lookup(void);
|
||||
|
||||
s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
|
||||
u8 mcs_offset);
|
||||
s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
|
||||
#endif /* _BRCM_PHY_HAL_H_ */
|
1142
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h
Normal file
1142
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h
Normal file
File diff suppressed because it is too large
Load Diff
5247
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
5247
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
121
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
121
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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_PHY_LCN_H_
|
||||
#define _BRCM_PHY_LCN_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct brcms_phy_lcnphy {
|
||||
int lcnphy_txrf_sp_9_override;
|
||||
u8 lcnphy_full_cal_channel;
|
||||
u8 lcnphy_cal_counter;
|
||||
u16 lcnphy_cal_temper;
|
||||
bool lcnphy_recal;
|
||||
|
||||
u8 lcnphy_rc_cap;
|
||||
u32 lcnphy_mcs20_po;
|
||||
|
||||
u8 lcnphy_tr_isolation_mid;
|
||||
u8 lcnphy_tr_isolation_low;
|
||||
u8 lcnphy_tr_isolation_hi;
|
||||
|
||||
u8 lcnphy_bx_arch;
|
||||
u8 lcnphy_rx_power_offset;
|
||||
u8 lcnphy_rssi_vf;
|
||||
u8 lcnphy_rssi_vc;
|
||||
u8 lcnphy_rssi_gs;
|
||||
u8 lcnphy_tssi_val;
|
||||
u8 lcnphy_rssi_vf_lowtemp;
|
||||
u8 lcnphy_rssi_vc_lowtemp;
|
||||
u8 lcnphy_rssi_gs_lowtemp;
|
||||
|
||||
u8 lcnphy_rssi_vf_hightemp;
|
||||
u8 lcnphy_rssi_vc_hightemp;
|
||||
u8 lcnphy_rssi_gs_hightemp;
|
||||
|
||||
s16 lcnphy_pa0b0;
|
||||
s16 lcnphy_pa0b1;
|
||||
s16 lcnphy_pa0b2;
|
||||
|
||||
u16 lcnphy_rawtempsense;
|
||||
u8 lcnphy_measPower;
|
||||
u8 lcnphy_tempsense_slope;
|
||||
u8 lcnphy_freqoffset_corr;
|
||||
u8 lcnphy_tempsense_option;
|
||||
u8 lcnphy_tempcorrx;
|
||||
bool lcnphy_iqcal_swp_dis;
|
||||
bool lcnphy_hw_iqcal_en;
|
||||
uint lcnphy_bandedge_corr;
|
||||
bool lcnphy_spurmod;
|
||||
u16 lcnphy_tssi_tx_cnt;
|
||||
u16 lcnphy_tssi_idx;
|
||||
u16 lcnphy_tssi_npt;
|
||||
|
||||
u16 lcnphy_target_tx_freq;
|
||||
s8 lcnphy_tx_power_idx_override;
|
||||
u16 lcnphy_noise_samples;
|
||||
|
||||
u32 lcnphy_papdRxGnIdx;
|
||||
u32 lcnphy_papd_rxGnCtrl_init;
|
||||
|
||||
u32 lcnphy_gain_idx_14_lowword;
|
||||
u32 lcnphy_gain_idx_14_hiword;
|
||||
u32 lcnphy_gain_idx_27_lowword;
|
||||
u32 lcnphy_gain_idx_27_hiword;
|
||||
s16 lcnphy_ofdmgainidxtableoffset;
|
||||
s16 lcnphy_dsssgainidxtableoffset;
|
||||
u32 lcnphy_tr_R_gain_val;
|
||||
u32 lcnphy_tr_T_gain_val;
|
||||
s8 lcnphy_input_pwr_offset_db;
|
||||
u16 lcnphy_Med_Low_Gain_db;
|
||||
u16 lcnphy_Very_Low_Gain_db;
|
||||
s8 lcnphy_lastsensed_temperature;
|
||||
s8 lcnphy_pkteng_rssi_slope;
|
||||
u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
|
||||
u8 lcnphy_volt_winner;
|
||||
u8 lcnphy_volt_low;
|
||||
u8 lcnphy_54_48_36_24mbps_backoff;
|
||||
u8 lcnphy_11n_backoff;
|
||||
u8 lcnphy_lowerofdm;
|
||||
u8 lcnphy_cck;
|
||||
u8 lcnphy_psat_2pt3_detected;
|
||||
s32 lcnphy_lowest_Re_div_Im;
|
||||
s8 lcnphy_final_papd_cal_idx;
|
||||
u16 lcnphy_extstxctrl4;
|
||||
u16 lcnphy_extstxctrl0;
|
||||
u16 lcnphy_extstxctrl1;
|
||||
s16 lcnphy_cck_dig_filt_type;
|
||||
s16 lcnphy_ofdm_dig_filt_type;
|
||||
struct lcnphy_cal_results lcnphy_cal_results;
|
||||
|
||||
u8 lcnphy_psat_pwr;
|
||||
u8 lcnphy_psat_indx;
|
||||
s32 lcnphy_min_phase;
|
||||
u8 lcnphy_final_idx;
|
||||
u8 lcnphy_start_idx;
|
||||
u8 lcnphy_current_index;
|
||||
u16 lcnphy_logen_buf_1;
|
||||
u16 lcnphy_local_ovr_2;
|
||||
u16 lcnphy_local_oval_6;
|
||||
u16 lcnphy_local_oval_5;
|
||||
u16 lcnphy_logen_mixer_1;
|
||||
|
||||
u8 lcnphy_aci_stat;
|
||||
uint lcnphy_aci_start_time;
|
||||
s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
|
||||
};
|
||||
#endif /* _BRCM_PHY_LCN_H_ */
|
28721
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
Normal file
28721
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
Normal file
File diff suppressed because it is too large
Load Diff
308
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
308
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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 "phy_qmath.h"
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit unsigned multiplication.
|
||||
* To fit the output into 16 bits the 32 bit multiplication result is right
|
||||
* shifted by 16 bits.
|
||||
*/
|
||||
u16 qm_mulu16(u16 op1, u16 op2)
|
||||
{
|
||||
return (u16) (((u32) op1 * (u32) op2) >> 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit multiplication and return the result
|
||||
* in 16 bits. To fit the multiplication result into 16 bits the multiplication
|
||||
* result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
|
||||
* is done to remove the extra sign bit formed due to the multiplication.
|
||||
* When both the 16bit inputs are 0x8000 then the output is saturated to
|
||||
* 0x7fffffff.
|
||||
*/
|
||||
s16 qm_muls16(s16 op1, s16 op2)
|
||||
{
|
||||
s32 result;
|
||||
if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
|
||||
result = 0x7fffffff;
|
||||
else
|
||||
result = ((s32) (op1) * (s32) (op2));
|
||||
|
||||
return (s16) (result >> 15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 32 bit numbers and return the 32bit
|
||||
* result. If the result overflow 32 bits, the output will be saturated to
|
||||
* 32bits.
|
||||
*/
|
||||
s32 qm_add32(s32 op1, s32 op2)
|
||||
{
|
||||
s32 result;
|
||||
result = op1 + op2;
|
||||
if (op1 < 0 && op2 < 0 && result > 0)
|
||||
result = 0x80000000;
|
||||
else if (op1 > 0 && op2 > 0 && result < 0)
|
||||
result = 0x7fffffff;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 16 bit numbers and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_add16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 + (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit subtraction and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_sub16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 - (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 32 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 32 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s32 qm_shl32(s32 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s32 result;
|
||||
result = op;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
else if (shift < -31)
|
||||
shift = -31;
|
||||
if (shift >= 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add32(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 16 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s16 qm_shl16(s16 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s16 result;
|
||||
result = op;
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
else if (shift < -15)
|
||||
shift = -15;
|
||||
if (shift > 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add16(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit right shift when shift is +ve.
|
||||
* This function make a 16 bit saturated left shift when shift is -ve. This
|
||||
* function return the result of the shift operation.
|
||||
*/
|
||||
s16 qm_shr16(s16 op, int shift)
|
||||
{
|
||||
return qm_shl16(op, -shift);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function return the number of redundant sign bits in a
|
||||
* 32 bit number. Example: qm_norm32(0x00000080) = 23
|
||||
*/
|
||||
s16 qm_norm32(s32 op)
|
||||
{
|
||||
u16 u16extraSignBits;
|
||||
if (op == 0) {
|
||||
return 31;
|
||||
} else {
|
||||
u16extraSignBits = 0;
|
||||
while ((op >> 31) == (op >> 30)) {
|
||||
u16extraSignBits++;
|
||||
op = op << 1;
|
||||
}
|
||||
}
|
||||
return u16extraSignBits;
|
||||
}
|
||||
|
||||
/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
|
||||
static const s16 log_table[] = {
|
||||
0,
|
||||
1455,
|
||||
2866,
|
||||
4236,
|
||||
5568,
|
||||
6863,
|
||||
8124,
|
||||
9352,
|
||||
10549,
|
||||
11716,
|
||||
12855,
|
||||
13968,
|
||||
15055,
|
||||
16117,
|
||||
17156,
|
||||
18173,
|
||||
19168,
|
||||
20143,
|
||||
21098,
|
||||
22034,
|
||||
22952,
|
||||
23852,
|
||||
24736,
|
||||
25604,
|
||||
26455,
|
||||
27292,
|
||||
28114,
|
||||
28922,
|
||||
29717,
|
||||
30498,
|
||||
31267,
|
||||
32024
|
||||
};
|
||||
|
||||
#define LOG_TABLE_SIZE 32 /* log_table size */
|
||||
#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
|
||||
#define Q_LOG_TABLE 15 /* qformat of log_table */
|
||||
#define LOG10_2 19728 /* log10(2) in q.16 */
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* This routine takes the input number N and its q format qN and compute
|
||||
* the log10(N). This routine first normalizes the input no N. Then N is in
|
||||
* mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
|
||||
* Then log2(mag * 2^x) = log2(mag) + x is computed. From that
|
||||
* log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
|
||||
* This routine looks the log2 value in the table considering
|
||||
* LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
|
||||
* LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
|
||||
* for interpolation.
|
||||
* Inputs:
|
||||
* N - number to which log10 has to be found.
|
||||
* qN - q format of N
|
||||
* log10N - address where log10(N) will be written.
|
||||
* qLog10N - address where log10N qformat will be written.
|
||||
* Note/Problem:
|
||||
* For accurate results input should be in normalized or near normalized form.
|
||||
*/
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
|
||||
{
|
||||
s16 s16norm, s16tableIndex, s16errorApproximation;
|
||||
u16 u16offset;
|
||||
s32 s32log;
|
||||
|
||||
/* normalize the N. */
|
||||
s16norm = qm_norm32(N);
|
||||
N = N << s16norm;
|
||||
|
||||
/* The qformat of N after normalization.
|
||||
* -30 is added to treat the no as between 1.0 to 2.0
|
||||
* i.e. after adding the -30 to the qformat the decimal point will be
|
||||
* just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
|
||||
* at the right side of 30th bit.
|
||||
*/
|
||||
qN = qN + s16norm - 30;
|
||||
|
||||
/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
|
||||
* MSB */
|
||||
s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
|
||||
|
||||
/* remove the MSB. the MSB is always 1 after normalization. */
|
||||
s16tableIndex =
|
||||
s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
|
||||
|
||||
/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
|
||||
N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
|
||||
|
||||
/* take the offset as the 16 MSBS after table index.
|
||||
*/
|
||||
u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
|
||||
|
||||
/* look the log value in the table. */
|
||||
s32log = log_table[s16tableIndex]; /* q.15 format */
|
||||
|
||||
/* interpolate using the offset. q.15 format. */
|
||||
s16errorApproximation = (s16) qm_mulu16(u16offset,
|
||||
(u16) (log_table[s16tableIndex + 1] -
|
||||
log_table[s16tableIndex]));
|
||||
|
||||
/* q.15 format */
|
||||
s32log = qm_add16((s16) s32log, s16errorApproximation);
|
||||
|
||||
/* adjust for the qformat of the N as
|
||||
* log2(mag * 2^x) = log2(mag) + x
|
||||
*/
|
||||
s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
|
||||
|
||||
/* normalize the result. */
|
||||
s16norm = qm_norm32(s32log);
|
||||
|
||||
/* bring all the important bits into lower 16 bits */
|
||||
/* q.15+s16norm-16 format */
|
||||
s32log = qm_shl32(s32log, s16norm - 16);
|
||||
|
||||
/* compute the log10(N) by multiplying log2(N) with log10(2).
|
||||
* as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
|
||||
* log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
|
||||
*/
|
||||
*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
|
||||
|
||||
/* write the q format of the result. */
|
||||
*qLog10N = 15 + s16norm - 16 + 1;
|
||||
|
||||
return;
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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_QMATH_H_
|
||||
#define _BRCM_QMATH_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
u16 qm_mulu16(u16 op1, u16 op2);
|
||||
|
||||
s16 qm_muls16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_add32(s32 op1, s32 op2);
|
||||
|
||||
s16 qm_add16(s16 op1, s16 op2);
|
||||
|
||||
s16 qm_sub16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_shl32(s32 op, int shift);
|
||||
|
||||
s16 qm_shl16(s16 op, int shift);
|
||||
|
||||
s16 qm_shr16(s16 op, int shift);
|
||||
|
||||
s16 qm_norm32(s32 op);
|
||||
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
|
||||
|
||||
#endif /* #ifndef _BRCM_QMATH_H_ */
|
1533
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
1533
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
File diff suppressed because it is too large
Load Diff
167
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
167
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define NPHY_TBL_ID_GAIN1 0
|
||||
#define NPHY_TBL_ID_GAIN2 1
|
||||
#define NPHY_TBL_ID_GAINBITS1 2
|
||||
#define NPHY_TBL_ID_GAINBITS2 3
|
||||
#define NPHY_TBL_ID_GAINLIMIT 4
|
||||
#define NPHY_TBL_ID_WRSSIGainLimit 5
|
||||
#define NPHY_TBL_ID_RFSEQ 7
|
||||
#define NPHY_TBL_ID_AFECTRL 8
|
||||
#define NPHY_TBL_ID_ANTSWCTRLLUT 9
|
||||
#define NPHY_TBL_ID_IQLOCAL 15
|
||||
#define NPHY_TBL_ID_NOISEVAR 16
|
||||
#define NPHY_TBL_ID_SAMPLEPLAY 17
|
||||
#define NPHY_TBL_ID_CORE1TXPWRCTL 26
|
||||
#define NPHY_TBL_ID_CORE2TXPWRCTL 27
|
||||
#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
|
||||
|
||||
#define NPHY_TBL_ID_EPSILONTBL0 31
|
||||
#define NPHY_TBL_ID_SCALARTBL0 32
|
||||
#define NPHY_TBL_ID_EPSILONTBL1 33
|
||||
#define NPHY_TBL_ID_SCALARTBL1 34
|
||||
|
||||
#define NPHY_TO_BPHY_OFF 0xc00
|
||||
|
||||
#define NPHY_BandControl_currentBand 0x0001
|
||||
#define RFCC_CHIP0_PU 0x0400
|
||||
#define RFCC_POR_FORCE 0x0040
|
||||
#define RFCC_OE_POR_FORCE 0x0080
|
||||
#define NPHY_RfctrlIntc_override_OFF 0
|
||||
#define NPHY_RfctrlIntc_override_TRSW 1
|
||||
#define NPHY_RfctrlIntc_override_PA 2
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
|
||||
#define RIFS_ENABLE 0x80
|
||||
#define BPHY_BAND_SEL_UP20 0x10
|
||||
#define NPHY_MLenable 0x02
|
||||
|
||||
#define NPHY_RfseqMode_CoreActv_override 0x0001
|
||||
#define NPHY_RfseqMode_Trigger_override 0x0002
|
||||
#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
|
||||
#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
|
||||
|
||||
#define NPHY_RfseqTrigger_rx2tx 0x0001
|
||||
#define NPHY_RfseqTrigger_tx2rx 0x0002
|
||||
#define NPHY_RfseqTrigger_updategainh 0x0004
|
||||
#define NPHY_RfseqTrigger_updategainl 0x0008
|
||||
#define NPHY_RfseqTrigger_updategainu 0x0010
|
||||
#define NPHY_RfseqTrigger_reset2rx 0x0020
|
||||
#define NPHY_RfseqStatus_rx2tx 0x0001
|
||||
#define NPHY_RfseqStatus_tx2rx 0x0002
|
||||
#define NPHY_RfseqStatus_updategainh 0x0004
|
||||
#define NPHY_RfseqStatus_updategainl 0x0008
|
||||
#define NPHY_RfseqStatus_updategainu 0x0010
|
||||
#define NPHY_RfseqStatus_reset2rx 0x0020
|
||||
#define NPHY_ClassifierCtrl_cck_en 0x1
|
||||
#define NPHY_ClassifierCtrl_ofdm_en 0x2
|
||||
#define NPHY_ClassifierCtrl_waited_en 0x4
|
||||
#define NPHY_IQFlip_ADC1 0x0001
|
||||
#define NPHY_IQFlip_ADC2 0x0010
|
||||
#define NPHY_sampleCmd_STOP 0x0002
|
||||
|
||||
#define RX_GF_OR_MM 0x0004
|
||||
#define RX_GF_MM_AUTO 0x0100
|
||||
|
||||
#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
|
||||
|
||||
#define NPHY_IqestCmd_iqstart 0x1
|
||||
#define NPHY_IqestCmd_iqMode 0x2
|
||||
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
|
||||
|
||||
#define PRIM_SEL_UP20 0x8000
|
||||
|
||||
#define NPHY_RFSEQ_RX2TX 0x0
|
||||
#define NPHY_RFSEQ_TX2RX 0x1
|
||||
#define NPHY_RFSEQ_RESET2RX 0x2
|
||||
#define NPHY_RFSEQ_UPDATEGAINH 0x3
|
||||
#define NPHY_RFSEQ_UPDATEGAINL 0x4
|
||||
#define NPHY_RFSEQ_UPDATEGAINU 0x5
|
||||
|
||||
#define NPHY_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_RFSEQ_CMD_EXT_PA 0x3
|
||||
#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
|
||||
#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
|
||||
#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
|
||||
#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
|
||||
#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_RFSEQ_CMD_END 0xf
|
||||
|
||||
#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
|
||||
#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
|
||||
#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
|
||||
#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
|
||||
#define NPHY_REV3_RFSEQ_CMD_END 0x1f
|
||||
|
||||
#define NPHY_RSSI_SEL_W1 0x0
|
||||
#define NPHY_RSSI_SEL_W2 0x1
|
||||
#define NPHY_RSSI_SEL_NB 0x2
|
||||
#define NPHY_RSSI_SEL_IQ 0x3
|
||||
#define NPHY_RSSI_SEL_TSSI_2G 0x4
|
||||
#define NPHY_RSSI_SEL_TSSI_5G 0x5
|
||||
#define NPHY_RSSI_SEL_TBD 0x6
|
||||
|
||||
#define NPHY_RAIL_I 0x0
|
||||
#define NPHY_RAIL_Q 0x1
|
||||
|
||||
#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
|
||||
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
|
||||
|
||||
#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
|
||||
#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
|
||||
#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
|
||||
|
||||
#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
|
||||
#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
|
||||
#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
|
||||
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
|
||||
|
||||
#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
|
||||
|
||||
#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
|
||||
|
||||
#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
|
||||
|
||||
#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
|
||||
|
||||
#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
|
||||
|
||||
#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
|
3293
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
3293
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_ipa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_info_sz_rev0;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
|
||||
|
||||
struct lcnphy_tx_gain_tbl_entry {
|
||||
unsigned char gm;
|
||||
unsigned char pga;
|
||||
unsigned char pad;
|
||||
unsigned char dac;
|
||||
unsigned char bb_mult;
|
||||
};
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
|
||||
|
||||
extern const struct
|
||||
lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
|
10630
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
10630
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define ANT_SWCTRL_TBL_REV3_IDX (0)
|
||||
|
||||
#include <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev0[],
|
||||
mimophytbl_info_rev0_volatile[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev0,
|
||||
mimophytbl_info_sz_rev0_volatile;
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev3[],
|
||||
mimophytbl_info_rev3_volatile[],
|
||||
mimophytbl_info_rev3_volatile1[],
|
||||
mimophytbl_info_rev3_volatile2[],
|
||||
mimophytbl_info_rev3_volatile3[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev3,
|
||||
mimophytbl_info_sz_rev3_volatile,
|
||||
mimophytbl_info_sz_rev3_volatile1,
|
||||
mimophytbl_info_sz_rev3_volatile2,
|
||||
mimophytbl_info_sz_rev3_volatile3;
|
||||
|
||||
extern const u32 noise_var_tbl_rev3[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev7[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev7;
|
||||
|
||||
extern const u32 noise_var_tbl_rev7[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev16[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev16;
|
216
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c
Normal file
216
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is "two-way" interface, acting as the SHIM layer between driver
|
||||
* and PHY layer. The driver can optionally call this translation layer
|
||||
* to do some preprocessing, then reach PHY. On the PHY->driver direction,
|
||||
* all calls go through this layer since PHY doesn't have access to the
|
||||
* driver's brcms_hardware pointer.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "mac80211_if.h"
|
||||
#include "phy_shim.h"
|
||||
|
||||
/* PHY SHIM module specific state */
|
||||
struct phy_shim_info {
|
||||
struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_info *wl; /* pointer to os-specific private state */
|
||||
};
|
||||
|
||||
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc) {
|
||||
struct phy_shim_info *physhim = NULL;
|
||||
|
||||
physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
|
||||
if (!physhim)
|
||||
return NULL;
|
||||
|
||||
physhim->wlc_hw = wlc_hw;
|
||||
physhim->wlc = wlc;
|
||||
physhim->wl = wl;
|
||||
|
||||
return physhim;
|
||||
}
|
||||
|
||||
void wlc_phy_shim_detach(struct phy_shim_info *physhim)
|
||||
{
|
||||
kfree(physhim);
|
||||
}
|
||||
|
||||
struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn)(struct brcms_phy *pi),
|
||||
void *arg, const char *name)
|
||||
{
|
||||
return (struct wlapi_timer *)
|
||||
brcms_init_timer(physhim->wl, (void (*)(void *))fn,
|
||||
arg, name);
|
||||
}
|
||||
|
||||
void wlapi_free_timer(struct wlapi_timer *t)
|
||||
{
|
||||
brcms_free_timer((struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
|
||||
{
|
||||
brcms_add_timer((struct brcms_timer *)t, ms, periodic);
|
||||
}
|
||||
|
||||
bool wlapi_del_timer(struct wlapi_timer *t)
|
||||
{
|
||||
return brcms_del_timer((struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void wlapi_intrson(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_intrson(physhim->wl);
|
||||
}
|
||||
|
||||
u32 wlapi_intrsoff(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_intrsoff(physhim->wl);
|
||||
}
|
||||
|
||||
void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
|
||||
{
|
||||
brcms_intrsrestore(physhim->wl, macintmask);
|
||||
}
|
||||
|
||||
void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
|
||||
{
|
||||
brcms_b_write_shm(physhim->wlc_hw, offset, v);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
|
||||
{
|
||||
return brcms_b_read_shm(physhim->wlc_hw, offset);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
|
||||
u16 val, int bands)
|
||||
{
|
||||
brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
|
||||
}
|
||||
|
||||
void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
|
||||
{
|
||||
brcms_b_corereset(physhim->wlc_hw, flags);
|
||||
}
|
||||
|
||||
void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_suspend_mac_and_wait(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
|
||||
{
|
||||
brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
|
||||
}
|
||||
|
||||
void wlapi_enable_mac(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_enable_mac(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
|
||||
{
|
||||
brcms_b_mctrl(physhim->wlc_hw, mask, val);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_phy_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
|
||||
{
|
||||
brcms_b_bw_set(physhim->wlc_hw, bw);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_b_get_txant(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_macphyclk_set(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
|
||||
{
|
||||
brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_core_phypll_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_set(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
|
||||
int len, void *buf)
|
||||
{
|
||||
brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
|
||||
{
|
||||
return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
|
||||
}
|
||||
|
||||
void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
|
||||
int len, u32 sel)
|
||||
{
|
||||
brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
|
||||
int l, u32 sel)
|
||||
{
|
||||
brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
|
||||
}
|
172
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h
Normal file
172
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define RADAR_TYPE_NONE 0 /* Radar type None */
|
||||
#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
|
||||
#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
|
||||
#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
|
||||
#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
|
||||
#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
|
||||
#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
|
||||
#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
|
||||
#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
|
||||
#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
|
||||
#define RADAR_TYPE_FRA 10 /* French radar */
|
||||
|
||||
/* French radar pulse widths */
|
||||
#define FRA_T1_20MHZ 52770
|
||||
#define FRA_T2_20MHZ 61538
|
||||
#define FRA_T3_20MHZ 66002
|
||||
#define FRA_T1_40MHZ 105541
|
||||
#define FRA_T2_40MHZ 123077
|
||||
#define FRA_T3_40MHZ 132004
|
||||
#define FRA_ERR_20MHZ 60
|
||||
#define FRA_ERR_40MHZ 120
|
||||
|
||||
#define ANTSEL_NA 0 /* No boardlevel selection available */
|
||||
#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
|
||||
#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
|
||||
|
||||
/* Rx Antenna diversity control values */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#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 BRCMS_N_PREAMBLE_MIXEDMODE 0
|
||||
#define BRCMS_N_PREAMBLE_GF 1
|
||||
#define BRCMS_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
|
||||
/* Index for first 20MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM_FIRST 4
|
||||
/* Index for first 20MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM20_CDD_FIRST 12
|
||||
/* Index for first 40MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM40_SISO_FIRST 52
|
||||
/* Index for first 40MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM40_CDD_FIRST 60
|
||||
#define WL_TX_POWER_OFDM_NUM 8
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST 20
|
||||
/* Index for first 20MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS20_CDD_FIRST 28
|
||||
/* Index for first 20MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS20_STBC_FIRST 36
|
||||
/* Index for first 20MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS20_SDM_FIRST 44
|
||||
/* Index for first 40MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS40_SISO_FIRST 68
|
||||
/* Index for first 40MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS40_CDD_FIRST 76
|
||||
/* Index for first 40MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS40_STBC_FIRST 84
|
||||
/* Index for first 40MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS40_SDM_FIRST 92
|
||||
#define WL_TX_POWER_MCS_1_STREAM_NUM 8
|
||||
#define WL_TX_POWER_MCS_2_STREAM_NUM 8
|
||||
/* Index for 40MHz rate MCS 32 */
|
||||
#define WL_TX_POWER_MCS_32 100
|
||||
#define WL_TX_POWER_MCS_32_NUM 1
|
||||
|
||||
/* sslpnphy specifics */
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12
|
||||
|
||||
/* struct tx_power::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 BRCMS_N_TXRX_CHAIN0 0
|
||||
#define BRCMS_N_TXRX_CHAIN1 1
|
||||
|
||||
struct brcms_phy;
|
||||
|
||||
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc);
|
||||
void wlc_phy_shim_detach(struct phy_shim_info *physhim);
|
||||
|
||||
/* PHY to WL utility functions */
|
||||
struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn)(struct brcms_phy *pi),
|
||||
void *arg, const char *name);
|
||||
void wlapi_free_timer(struct wlapi_timer *t);
|
||||
void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
|
||||
bool wlapi_del_timer(struct wlapi_timer *t);
|
||||
void wlapi_intrson(struct phy_shim_info *physhim);
|
||||
u32 wlapi_intrsoff(struct phy_shim_info *physhim);
|
||||
void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask);
|
||||
|
||||
void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v);
|
||||
u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
|
||||
void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask, u16 val,
|
||||
int bands);
|
||||
void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
|
||||
void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
|
||||
void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
|
||||
void wlapi_enable_mac(struct phy_shim_info *physhim);
|
||||
void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val);
|
||||
void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
|
||||
void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
|
||||
void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
|
||||
void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
|
||||
void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
|
||||
void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim);
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim);
|
||||
void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
|
||||
int len, void *buf);
|
||||
u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate);
|
||||
void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
|
||||
void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, void *buf,
|
||||
int, u32 sel);
|
||||
void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, const void *buf,
|
||||
int, u32);
|
||||
|
||||
void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, u32 phy_mode);
|
||||
u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
|
||||
|
||||
#endif /* _BRCM_PHY_SHIM_H_ */
|
165
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pmu.c
Normal file
165
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pmu.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "pub.h"
|
||||
#include "aiutils.h"
|
||||
#include "pmu.h"
|
||||
#include "soc.h"
|
||||
|
||||
/*
|
||||
* external LPO crystal frequency
|
||||
*/
|
||||
#define EXT_ILP_HZ 32768
|
||||
|
||||
/*
|
||||
* Duration for ILP clock frequency measurment in milliseconds
|
||||
*
|
||||
* remark: 1000 must be an integer multiple of this duration
|
||||
*/
|
||||
#define ILP_CALC_DUR 10
|
||||
|
||||
/* 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
|
||||
|
||||
/* ILP clock */
|
||||
#define ILP_CLOCK 32000
|
||||
|
||||
/* ALP clock on pre-PMU chips */
|
||||
#define ALP_CLOCK 20000000
|
||||
|
||||
/* 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 bit position */
|
||||
#define PMURES_BIT(bit) (1 << (bit))
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* pmu XtalFreqRatio */
|
||||
#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
|
||||
#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
|
||||
#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
|
||||
|
||||
/* 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
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
uint delay = PMU_MAX_TRANSITION_DLY;
|
||||
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCMA_CHIP_ID_BCM43224:
|
||||
case BCMA_CHIP_ID_BCM43225:
|
||||
case BCMA_CHIP_ID_BCM4313:
|
||||
delay = 3700;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (u16) delay;
|
||||
}
|
||||
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii = container_of(sih, struct si_info, pub);
|
||||
struct bcma_device *core;
|
||||
u32 alp_khz;
|
||||
|
||||
if (ai_get_pmurev(sih) < 10)
|
||||
return 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
core = sii->icbus->drv_cc.core;
|
||||
|
||||
if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
|
||||
u32 ilp_ctr, alp_hz;
|
||||
|
||||
/*
|
||||
* Enable the reg to measure the freq,
|
||||
* in case it was disabled before
|
||||
*/
|
||||
bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
|
||||
/* Delay for well over 4 ILP clocks */
|
||||
udelay(1000);
|
||||
|
||||
/* Read the latched number of ALP ticks per 4 ILP ticks */
|
||||
ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
|
||||
PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
|
||||
/*
|
||||
* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
|
||||
* bit to save power
|
||||
*/
|
||||
bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
|
||||
|
||||
/* Calculate ALP frequency */
|
||||
alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
|
||||
|
||||
/*
|
||||
* Round to nearest 100KHz, and at
|
||||
* the same time convert to KHz
|
||||
*/
|
||||
alp_khz = (alp_hz + 50000) / 100000 * 100;
|
||||
} else
|
||||
alp_khz = 0;
|
||||
|
||||
return alp_khz;
|
||||
}
|
26
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pmu.h
Normal file
26
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pmu.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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_PMU_H_
|
||||
#define _BRCM_PMU_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_PMU_H_ */
|
341
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h
Normal file
341
drivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* 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_PUB_H_
|
||||
#define _BRCM_PUB_H_
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
|
||||
|
||||
/* phy types */
|
||||
#define PHY_TYPE_A 0 /* Phy type A */
|
||||
#define PHY_TYPE_G 2 /* Phy type G */
|
||||
#define PHY_TYPE_N 4 /* Phy type N */
|
||||
#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
|
||||
#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
|
||||
#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
|
||||
|
||||
/* bw */
|
||||
#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
|
||||
#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
|
||||
#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
|
||||
|
||||
#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
|
||||
#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
|
||||
#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */
|
||||
#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
|
||||
#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
|
||||
|
||||
/* 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 BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
/* rate related definitions */
|
||||
#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */
|
||||
#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
/* default antdiv setting */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
/* Tx on antenna 0, "legacy term Main" */
|
||||
#define ANT_TX_FORCE_0 0
|
||||
/* Tx on antenna 1, "legacy term Aux" */
|
||||
#define ANT_TX_FORCE_1 1
|
||||
/* Tx on phy's last good Rx antenna */
|
||||
#define ANT_TX_LAST_RX 3
|
||||
/* driver's default tx antenna setting */
|
||||
#define ANT_TX_DEF 3
|
||||
|
||||
/* Tx Chain values */
|
||||
/* def bitmap of txchain */
|
||||
#define TXCHAIN_DEF 0x1
|
||||
/* default bitmap of tx chains for nphy */
|
||||
#define TXCHAIN_DEF_NPHY 0x3
|
||||
/* default bitmap of tx chains for nphy */
|
||||
#define TXCHAIN_DEF_HTPHY 0x7
|
||||
/* def bitmap of rxchain */
|
||||
#define RXCHAIN_DEF 0x1
|
||||
/* default bitmap of rx chains for nphy */
|
||||
#define RXCHAIN_DEF_NPHY 0x3
|
||||
/* default bitmap of rx chains for nphy */
|
||||
#define RXCHAIN_DEF_HTPHY 0x7
|
||||
/* no antenna switch */
|
||||
#define ANTSWITCH_NONE 0
|
||||
/* antenna switch on 4321CB2, 2of3 */
|
||||
#define ANTSWITCH_TYPE_1 1
|
||||
/* antenna switch on 4321MPCI, 2of3 */
|
||||
#define ANTSWITCH_TYPE_2 2
|
||||
/* antenna switch on 4322, 2of3 */
|
||||
#define ANTSWITCH_TYPE_3 3
|
||||
|
||||
#define RXBUFSZ PKTBUFSZ
|
||||
|
||||
#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
|
||||
|
||||
struct brcm_rateset {
|
||||
/* # rates in this set */
|
||||
u32 count;
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[WL_NUMRATES];
|
||||
};
|
||||
|
||||
struct brcms_c_rateset {
|
||||
uint count; /* number of rates in rates[] */
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[BRCMS_NUMRATES];
|
||||
u8 htphy_membership; /* HT PHY Membership */
|
||||
u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
|
||||
};
|
||||
|
||||
/* All the HT-specific default advertised capabilities (including AMPDU)
|
||||
* should be grouped here at one place
|
||||
*/
|
||||
#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
|
||||
|
||||
/* wlc internal bss_info */
|
||||
struct brcms_bss_info {
|
||||
u8 BSSID[ETH_ALEN]; /* network BSSID */
|
||||
u16 flags; /* flags for internal attributes */
|
||||
u8 SSID_len; /* the length of SSID */
|
||||
u8 SSID[32]; /* SSID string */
|
||||
s16 RSSI; /* receive signal strength (in dBm) */
|
||||
s16 SNR; /* receive signal SNR in dB */
|
||||
u16 beacon_period; /* units are Kusec */
|
||||
u16 chanspec; /* Channel num, bw, ctrl_sb and band */
|
||||
struct brcms_c_rateset rateset; /* supported rates */
|
||||
};
|
||||
|
||||
#define MAC80211_PROMISC_BCNS (1 << 0)
|
||||
#define MAC80211_SCAN (1 << 1)
|
||||
|
||||
/*
|
||||
* Public portion of common driver state structure.
|
||||
* The wlc handle points at this.
|
||||
*/
|
||||
struct brcms_pub {
|
||||
struct brcms_c_info *wlc;
|
||||
struct ieee80211_hw *ieee_hw;
|
||||
struct scb_ampdu *global_ampdu;
|
||||
uint mac80211_state;
|
||||
uint unit; /* device instance number */
|
||||
uint corerev; /* core revision */
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
bool up; /* interface up and running */
|
||||
bool hw_off; /* HW is off */
|
||||
bool hw_up; /* one time hw up/down */
|
||||
bool _piomode; /* true if pio mode */
|
||||
uint _nbands; /* # bands supported */
|
||||
uint now; /* # elapsed seconds */
|
||||
|
||||
bool delayed_down; /* down delayed */
|
||||
bool associated; /* true:part of [I]BSS, false: not */
|
||||
/* (union of stas_associated, aps_associated) */
|
||||
bool _ampdu; /* ampdu enabled or not */
|
||||
u8 _n_enab; /* bitmap of 11N + HT support */
|
||||
|
||||
u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
|
||||
|
||||
u32 radio_disabled; /* bit vector for radio disabled reasons */
|
||||
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
|
||||
|
||||
struct wl_cnt *_cnt; /* low-level counters in driver */
|
||||
struct dentry *dbgfs_dir;
|
||||
};
|
||||
|
||||
enum wlc_par_id {
|
||||
IOV_MPC = 1,
|
||||
IOV_RTSTHRESH,
|
||||
IOV_QTXPOWER,
|
||||
IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */
|
||||
};
|
||||
|
||||
/***********************************************
|
||||
* Feature-related macros to optimize out code *
|
||||
* *********************************************
|
||||
*/
|
||||
|
||||
#define ENAB_1x1 0x01
|
||||
#define ENAB_2x2 0x02
|
||||
#define ENAB_3x3 0x04
|
||||
#define ENAB_4x4 0x08
|
||||
#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
|
||||
#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
|
||||
|
||||
/* WL11N Support */
|
||||
#define AMPDU_AGG_HOST 1
|
||||
|
||||
/* network protection config */
|
||||
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
|
||||
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
|
||||
#define BRCMS_PROT_G_USER 3 /* gmode specified by user */
|
||||
#define BRCMS_PROT_OVERLAP 4 /* overlap */
|
||||
#define BRCMS_PROT_N_USER 10 /* nmode specified by user */
|
||||
#define BRCMS_PROT_N_CFG 11 /* n protection */
|
||||
#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */
|
||||
#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */
|
||||
#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */
|
||||
#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */
|
||||
#define BRCMS_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
|
||||
|
||||
/* MCS values greater than this enable multiple streams */
|
||||
#define HIGHEST_SINGLE_STREAM_MCS 7
|
||||
|
||||
#define MAXBANDS 2 /* Maximum #of bands */
|
||||
|
||||
/* max number of antenna configurations */
|
||||
#define ANT_SELCFG_MAX 4
|
||||
|
||||
struct brcms_antselcfg {
|
||||
u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
|
||||
u8 num_antcfg; /* number of available antenna configurations */
|
||||
};
|
||||
|
||||
/* common functions for every port */
|
||||
struct brcms_c_info *brcms_c_attach(struct brcms_info *wl,
|
||||
struct bcma_device *core, uint unit,
|
||||
bool piomode, uint *perr);
|
||||
uint brcms_c_detach(struct brcms_c_info *wlc);
|
||||
int brcms_c_up(struct brcms_c_info *wlc);
|
||||
uint brcms_c_down(struct brcms_c_info *wlc);
|
||||
|
||||
bool brcms_c_chipmatch(struct bcma_device *core);
|
||||
void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx);
|
||||
void brcms_c_reset(struct brcms_c_info *wlc);
|
||||
|
||||
void brcms_c_intrson(struct brcms_c_info *wlc);
|
||||
u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
|
||||
void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
|
||||
bool brcms_c_intrsupd(struct brcms_c_info *wlc);
|
||||
bool brcms_c_isr(struct brcms_c_info *wlc);
|
||||
bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
|
||||
bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
|
||||
struct ieee80211_hw *hw);
|
||||
bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
|
||||
void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val);
|
||||
int brcms_c_get_header_len(void);
|
||||
void brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
|
||||
const u8 *addr);
|
||||
void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
|
||||
const struct ieee80211_tx_queue_params *arg,
|
||||
bool suspend);
|
||||
struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
|
||||
void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta,
|
||||
u16 tid);
|
||||
void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
|
||||
u8 ba_wsize, uint max_rx_ampdu_bytes);
|
||||
int brcms_c_module_register(struct brcms_pub *pub, const char *name,
|
||||
struct brcms_info *hdl,
|
||||
int (*down_fn)(void *handle));
|
||||
int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
|
||||
struct brcms_info *hdl);
|
||||
void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
|
||||
void brcms_c_enable_mac(struct brcms_c_info *wlc);
|
||||
void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
|
||||
void brcms_c_scan_start(struct brcms_c_info *wlc);
|
||||
void brcms_c_scan_stop(struct brcms_c_info *wlc);
|
||||
int brcms_c_get_curband(struct brcms_c_info *wlc);
|
||||
int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
|
||||
int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
|
||||
void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
|
||||
struct brcm_rateset *currs);
|
||||
int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs);
|
||||
int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
|
||||
u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
|
||||
void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
|
||||
s8 sslot_override);
|
||||
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval);
|
||||
u64 brcms_c_tsf_get(struct brcms_c_info *wlc);
|
||||
void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf);
|
||||
int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
|
||||
int brcms_c_get_tx_power(struct brcms_c_info *wlc);
|
||||
bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
|
||||
void brcms_c_mute(struct brcms_c_info *wlc, bool on);
|
||||
bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
|
||||
void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
|
||||
void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
|
||||
u8 *ssid, size_t ssid_len);
|
||||
void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr);
|
||||
void brcms_c_update_beacon(struct brcms_c_info *wlc);
|
||||
void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
|
||||
u16 tim_offset, u16 dtim_period);
|
||||
void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
|
||||
struct sk_buff *probe_resp);
|
||||
void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable);
|
||||
void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len);
|
||||
|
||||
#endif /* _BRCM_PUB_H_ */
|
514
drivers/net/wireless/broadcom/brcm80211/brcmsmac/rate.c
Normal file
514
drivers/net/wireless/broadcom/brcm80211/brcmsmac/rate.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
|
||||
#include "d11.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[BRCM_MAXRATE + 1] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
|
||||
/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
|
||||
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
|
||||
/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
|
||||
};
|
||||
|
||||
/* rates are in units of Kbps */
|
||||
const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
|
||||
/* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
|
||||
{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
|
||||
{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
|
||||
{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
|
||||
{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
|
||||
{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
|
||||
{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
|
||||
{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
|
||||
};
|
||||
|
||||
/*
|
||||
* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
|
||||
* Number of spatial streams: always 1 other fields: refer to table 78 of
|
||||
* section 17.3.2.2 of the original .11a standard
|
||||
*/
|
||||
struct legacy_phycfg {
|
||||
u32 rate_ofdm; /* ofdm mac rate */
|
||||
/* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
u8 tx_phy_ctl3;
|
||||
};
|
||||
|
||||
/* Number of legacy_rate_cfg entries in the table */
|
||||
#define LEGACY_PHYCFG_TABLE_SIZE 12
|
||||
|
||||
/*
|
||||
* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
|
||||
* Eventually MIMOPHY would also be converted to this format
|
||||
* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
|
||||
*/
|
||||
static const struct
|
||||
legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
|
||||
{BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
|
||||
{BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
|
||||
{BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
|
||||
{BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
|
||||
/* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_6M, 0x00},
|
||||
/* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_9M, 0x02},
|
||||
/* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_12M, 0x08},
|
||||
/* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_18M, 0x0A},
|
||||
/* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_24M, 0x10},
|
||||
/* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_36M, 0x12},
|
||||
/* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_48M, 0x19},
|
||||
/* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_54M, 0x1A},
|
||||
};
|
||||
|
||||
/* Hardware rates (also encodes default basic rates) */
|
||||
|
||||
const struct brcms_c_rateset cck_ofdm_mimo_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, */
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/* 54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset ofdm_mimo_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* Default ratesets that include MCS32 for 40BW channels */
|
||||
static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48 */
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/* 54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset cck_ofdm_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48,*/
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/*54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset gphy_legacy_rates = {
|
||||
4,
|
||||
/* 1b, 2b, 5.5b, 11b Mbps */
|
||||
{ 0x82, 0x84, 0x8b, 0x96},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset ofdm_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset cck_rates = {
|
||||
4,
|
||||
/* 1b, 2b, 5.5, 11 Mbps */
|
||||
{ 0x82, 0x84, 0x0b, 0x16},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* check if rateset is valid.
|
||||
* if check_brate is true, rateset without a basic rate is considered NOT valid.
|
||||
*/
|
||||
static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
|
||||
{
|
||||
uint idx;
|
||||
|
||||
if (!rs->count)
|
||||
return false;
|
||||
|
||||
if (!check_brate)
|
||||
return true;
|
||||
|
||||
/* error if no basic rates */
|
||||
for (idx = 0; idx < rs->count; idx++) {
|
||||
if (rs->rates[idx] & BRCMS_RATE_FLAG)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
|
||||
{
|
||||
int i;
|
||||
for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
|
||||
rs->mcs[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filter based on hardware rateset, and sort filtered rateset with basic
|
||||
* bit(s) preserved, and check if resulting rateset is valid.
|
||||
*/
|
||||
bool
|
||||
brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
|
||||
const struct brcms_c_rateset *hw_rs,
|
||||
bool check_brate, u8 txstreams)
|
||||
{
|
||||
u8 rateset[BRCM_MAXRATE + 1];
|
||||
u8 r;
|
||||
uint count;
|
||||
uint i;
|
||||
|
||||
memset(rateset, 0, sizeof(rateset));
|
||||
count = rs->count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
|
||||
r = (int)rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
|
||||
continue;
|
||||
rateset[r] = rs->rates[i]; /* preserve basic bit! */
|
||||
}
|
||||
|
||||
/* fill out the rates in order, looking at only supported rates */
|
||||
count = 0;
|
||||
for (i = 0; i < hw_rs->count; i++) {
|
||||
r = hw_rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if (rateset[r])
|
||||
rs->rates[count++] = rateset[r];
|
||||
}
|
||||
|
||||
rs->count = count;
|
||||
|
||||
/* only set the mcs rate bit if the equivalent hw mcs bit is set */
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
|
||||
|
||||
if (brcms_c_rateset_valid(rs, check_brate))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate the rate of a rx'd frame and return it as a ratespec */
|
||||
u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
|
||||
{
|
||||
int phy_type;
|
||||
u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
|
||||
|
||||
phy_type =
|
||||
((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
|
||||
|
||||
if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
|
||||
(phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
|
||||
switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
|
||||
case PRXS0_CCK:
|
||||
rspec =
|
||||
cck_phy2mac_rate(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
break;
|
||||
case PRXS0_OFDM:
|
||||
rspec =
|
||||
ofdm_phy2mac_rate(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
break;
|
||||
case PRXS0_PREN:
|
||||
rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
|
||||
if (plcp[0] & MIMO_PLCP_40MHZ) {
|
||||
/* indicate rspec is for 40 MHz mode */
|
||||
rspec &= ~RSPEC_BW_MASK;
|
||||
rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
|
||||
}
|
||||
break;
|
||||
case PRXS0_STDN:
|
||||
/* fallthru */
|
||||
default:
|
||||
/* not supported, error condition */
|
||||
break;
|
||||
}
|
||||
if (plcp3_issgi(plcp[3]))
|
||||
rspec |= RSPEC_SHORT_GI;
|
||||
} else
|
||||
if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
|
||||
rspec = ofdm_phy2mac_rate(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
else
|
||||
rspec = cck_phy2mac_rate(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
|
||||
return rspec;
|
||||
}
|
||||
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(struct brcms_c_rateset));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and selectively filter one rateset to another.
|
||||
* 'basic_only' means only copy basic rates.
|
||||
* 'rates' indicates cck (11b) and ofdm rates combinations.
|
||||
* - 0: cck and ofdm
|
||||
* - 1: cck only
|
||||
* - 2: ofdm only
|
||||
* 'xmask' is the copy mask (typically 0x7f or 0xff).
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
|
||||
bool basic_only, u8 rates, uint xmask, bool mcsallow)
|
||||
{
|
||||
uint i;
|
||||
uint r;
|
||||
uint count;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < src->count; i++) {
|
||||
r = src->rates[i];
|
||||
if (basic_only && !(r & BRCMS_RATE_FLAG))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_CCK &&
|
||||
is_ofdm_rate((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_OFDM &&
|
||||
is_cck_rate((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
dst->rates[count++] = r & xmask;
|
||||
}
|
||||
dst->count = count;
|
||||
dst->htphy_membership = src->htphy_membership;
|
||||
|
||||
if (mcsallow && rates != BRCMS_RATES_CCK)
|
||||
memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
|
||||
else
|
||||
brcms_c_rateset_mcs_clear(dst);
|
||||
}
|
||||
|
||||
/* select rateset for a given phy_type and bandtype and filter it, sort it
|
||||
* and fill rs_tgt with result
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
|
||||
const struct brcms_c_rateset *rs_hw,
|
||||
uint phy_type, int bandtype, bool cck_only,
|
||||
uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
|
||||
{
|
||||
const struct brcms_c_rateset *rs_dflt;
|
||||
struct brcms_c_rateset rs_sel;
|
||||
if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
|
||||
if (bandtype == BRCM_BAND_5G)
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
|
||||
else
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&cck_ofdm_mimo_rates :
|
||||
&cck_ofdm_40bw_mimo_rates);
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
|
||||
rs_dflt = (bandtype == BRCM_BAND_5G) ?
|
||||
&ofdm_rates : &cck_ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
|
||||
rs_dflt = &ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
|
||||
rs_dflt = &cck_ofdm_rates;
|
||||
} else {
|
||||
/* should not happen, error condition */
|
||||
rs_dflt = &cck_rates; /* force cck */
|
||||
}
|
||||
|
||||
/* if hw rateset is not supplied, assign selected rateset to it */
|
||||
if (!rs_hw)
|
||||
rs_hw = rs_dflt;
|
||||
|
||||
brcms_c_rateset_copy(rs_dflt, &rs_sel);
|
||||
brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
|
||||
brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
|
||||
cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
|
||||
rate_mask, mcsallow);
|
||||
brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
|
||||
mcsallow ? txstreams : 1);
|
||||
}
|
||||
|
||||
s16 brcms_c_rate_legacy_phyctl(uint rate)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
|
||||
if (rate == legacy_phycfg_table[i].rate_ofdm)
|
||||
return legacy_phycfg_table[i].tx_phy_ctl3;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rateset->mcs[i] = 0;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
|
||||
{
|
||||
memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
|
||||
brcms_c_rateset_mcs_upd(rateset, txstreams);
|
||||
}
|
||||
|
||||
/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
|
||||
void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
|
||||
{
|
||||
if (bw == BRCMS_40_MHZ)
|
||||
setbit(rateset->mcs, 32);
|
||||
else
|
||||
clrbit(rateset->mcs, 32);
|
||||
}
|
245
drivers/net/wireless/broadcom/brcm80211/brcmsmac/rate.h
Normal file
245
drivers/net/wireless/broadcom/brcm80211/brcmsmac/rate.h
Normal file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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_RATE_H_
|
||||
#define _BRCM_RATE_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "phy_hal.h"
|
||||
|
||||
extern const u8 rate_info[];
|
||||
extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
|
||||
extern const struct brcms_c_rateset ofdm_mimo_rates;
|
||||
extern const struct brcms_c_rateset cck_ofdm_rates;
|
||||
extern const struct brcms_c_rateset ofdm_rates;
|
||||
extern const struct brcms_c_rateset cck_rates;
|
||||
extern const struct brcms_c_rateset gphy_legacy_rates;
|
||||
extern const struct brcms_c_rateset rate_limit_1_2;
|
||||
|
||||
struct brcms_mcs_info {
|
||||
/* phy rate in kbps [20Mhz] */
|
||||
u32 phy_rate_20;
|
||||
/* phy rate in kbps [40Mhz] */
|
||||
u32 phy_rate_40;
|
||||
/* phy rate in kbps [20Mhz] with SGI */
|
||||
u32 phy_rate_20_sgi;
|
||||
/* phy rate in kbps [40Mhz] with SGI */
|
||||
u32 phy_rate_40_sgi;
|
||||
/* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
u8 tx_phy_ctl3;
|
||||
/* matching legacy ofdm rate in 500bkps */
|
||||
u8 leg_ofdm;
|
||||
};
|
||||
|
||||
#define BRCMS_MAXMCS 32 /* max valid mcs index */
|
||||
#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
|
||||
extern const struct brcms_mcs_info mcs_table[];
|
||||
|
||||
#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
|
||||
#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
|
||||
|
||||
/* returns num tx streams - 1 */
|
||||
static inline u8 mcs_2_txstreams(u8 mcs)
|
||||
{
|
||||
return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
|
||||
{
|
||||
if (sgi) {
|
||||
if (is40)
|
||||
return mcs_table[mcs].phy_rate_40_sgi;
|
||||
return mcs_table[mcs].phy_rate_20_sgi;
|
||||
}
|
||||
if (is40)
|
||||
return mcs_table[mcs].phy_rate_40;
|
||||
|
||||
return mcs_table[mcs].phy_rate_20;
|
||||
}
|
||||
|
||||
/* Macro to use the rate_info table */
|
||||
#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
|
||||
|
||||
/*
|
||||
* rate spec : holds rate and mode specific information required to generate a
|
||||
* tx frame. Legacy CCK and OFDM information is held in the same manner as was
|
||||
* done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
|
||||
* specific information
|
||||
*/
|
||||
|
||||
/* rate spec bit fields */
|
||||
|
||||
/* Either 500Kbps units or MIMO MCS idx */
|
||||
#define RSPEC_RATE_MASK 0x0000007F
|
||||
/* mimo MCS is stored in RSPEC_RATE_MASK */
|
||||
#define RSPEC_MIMORATE 0x08000000
|
||||
/* mimo bw mask */
|
||||
#define RSPEC_BW_MASK 0x00000700
|
||||
/* mimo bw shift */
|
||||
#define RSPEC_BW_SHIFT 8
|
||||
/* mimo Space/Time/Frequency mode mask */
|
||||
#define RSPEC_STF_MASK 0x00003800
|
||||
/* mimo Space/Time/Frequency mode shift */
|
||||
#define RSPEC_STF_SHIFT 11
|
||||
/* mimo coding type mask */
|
||||
#define RSPEC_CT_MASK 0x0000C000
|
||||
/* mimo coding type shift */
|
||||
#define RSPEC_CT_SHIFT 14
|
||||
/* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_STC_MASK 0x00300000
|
||||
/* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_STC_SHIFT 20
|
||||
/* mimo bit indicates adv coding in use */
|
||||
#define RSPEC_LDPC_CODING 0x00400000
|
||||
/* mimo bit indicates short GI in use */
|
||||
#define RSPEC_SHORT_GI 0x00800000
|
||||
/* bit indicates override both rate & mode */
|
||||
#define RSPEC_OVERRIDE 0x80000000
|
||||
/* bit indicates override rate only */
|
||||
#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
|
||||
|
||||
static inline bool rspec_active(u32 rspec)
|
||||
{
|
||||
return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
|
||||
}
|
||||
|
||||
static inline u8 rspec_phytxbyte2(u32 rspec)
|
||||
{
|
||||
return (rspec & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static inline u32 rspec_get_bw(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
|
||||
}
|
||||
|
||||
static inline bool rspec_issgi(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
|
||||
}
|
||||
|
||||
static inline bool rspec_is40mhz(u32 rspec)
|
||||
{
|
||||
u32 bw = rspec_get_bw(rspec);
|
||||
|
||||
return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
|
||||
}
|
||||
|
||||
static inline uint rspec2rate(u32 rspec)
|
||||
{
|
||||
if (rspec & RSPEC_MIMORATE)
|
||||
return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
|
||||
rspec_issgi(rspec));
|
||||
return rspec & RSPEC_RATE_MASK;
|
||||
}
|
||||
|
||||
static inline u8 rspec_mimoplcp3(u32 rspec)
|
||||
{
|
||||
return (rspec & 0xf00000) >> 16;
|
||||
}
|
||||
|
||||
static inline bool plcp3_issgi(u8 plcp)
|
||||
{
|
||||
return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
|
||||
}
|
||||
|
||||
static inline uint rspec_stc(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint rspec_stf(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
|
||||
}
|
||||
|
||||
static inline bool is_mcs_rate(u32 ratespec)
|
||||
{
|
||||
return (ratespec & RSPEC_MIMORATE) != 0;
|
||||
}
|
||||
|
||||
static inline bool is_ofdm_rate(u32 ratespec)
|
||||
{
|
||||
return !is_mcs_rate(ratespec) &&
|
||||
(rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
|
||||
}
|
||||
|
||||
static inline bool is_cck_rate(u32 ratespec)
|
||||
{
|
||||
u32 rate = (ratespec & BRCMS_RATE_MASK);
|
||||
|
||||
return !is_mcs_rate(ratespec) && (
|
||||
rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
|
||||
rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
|
||||
}
|
||||
|
||||
static inline bool is_single_stream(u8 mcs)
|
||||
{
|
||||
return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
|
||||
}
|
||||
|
||||
static inline u8 cck_rspec(u8 cck)
|
||||
{
|
||||
return cck & RSPEC_RATE_MASK;
|
||||
}
|
||||
|
||||
/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
|
||||
* increments */
|
||||
static inline u8 ofdm_phy2mac_rate(u8 rlpt)
|
||||
{
|
||||
return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7];
|
||||
}
|
||||
|
||||
static inline u8 cck_phy2mac_rate(u8 signal)
|
||||
{
|
||||
return signal/5;
|
||||
}
|
||||
|
||||
/* Rates specified in brcms_c_rateset_filter() */
|
||||
#define BRCMS_RATES_CCK_OFDM 0
|
||||
#define BRCMS_RATES_CCK 1
|
||||
#define BRCMS_RATES_OFDM 2
|
||||
|
||||
/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
|
||||
* rateset */
|
||||
bool brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
|
||||
const struct brcms_c_rateset *hw_rs,
|
||||
bool check_brate, u8 txstreams);
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst);
|
||||
|
||||
/* would be nice to have these documented ... */
|
||||
u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
|
||||
|
||||
void brcms_c_rateset_filter(struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst, bool basic_only,
|
||||
u8 rates, uint xmask, bool mcsallow);
|
||||
|
||||
void brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
|
||||
const struct brcms_c_rateset *rs_hw, uint phy_type,
|
||||
int bandtype, bool cck_only, uint rate_mask,
|
||||
bool mcsallow, u8 bw, u8 txstreams);
|
||||
|
||||
s16 brcms_c_rate_legacy_phyctl(uint rate);
|
||||
|
||||
void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
|
||||
void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
|
||||
void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams);
|
||||
void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw);
|
||||
|
||||
#endif /* _BRCM_RATE_H_ */
|
81
drivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h
Normal file
81
drivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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_SCB_H_
|
||||
#define _BRCM_SCB_H_
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <defs.h>
|
||||
#include "types.h"
|
||||
|
||||
#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
|
||||
|
||||
#define AMPDU_MAX_SCB_TID NUMPRIO
|
||||
|
||||
/* scb flags */
|
||||
#define SCB_WMECAP 0x0040
|
||||
#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
|
||||
#define SCB_IS40 0x80000 /* 40MHz capable */
|
||||
#define SCB_STBCCAP 0x40000000 /* STBC Capable */
|
||||
|
||||
#define SCB_MAGIC 0xbeefcafe
|
||||
|
||||
/* structure to store per-tid state for the ampdu initiator */
|
||||
struct scb_ampdu_tid_ini {
|
||||
u8 tid; /* initiator tid for easy lookup */
|
||||
/* tx retry count; indexed by seq modulo */
|
||||
u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
|
||||
struct scb *scb; /* backptr for easy lookup */
|
||||
u8 ba_wsize; /* negotiated ba window size (in pdu) */
|
||||
};
|
||||
|
||||
struct scb_ampdu {
|
||||
struct scb *scb; /* back pointer for easy reference */
|
||||
u8 mpdu_density; /* mpdu density */
|
||||
u8 max_pdu; /* max pdus allowed in ampdu */
|
||||
u8 release; /* # of mpdus released at a time */
|
||||
u16 min_len; /* min mpdu len to support the density */
|
||||
u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
|
||||
|
||||
/*
|
||||
* This could easily be a ini[] pointer and we keep this info in wl
|
||||
* itself instead of having mac80211 hold it for us. Also could be made
|
||||
* dynamic per tid instead of static.
|
||||
*/
|
||||
/* initiator info - per tid (NUMPRIO): */
|
||||
struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
|
||||
};
|
||||
|
||||
/* station control block - one per remote MAC address */
|
||||
struct scb {
|
||||
u32 magic;
|
||||
u32 flags; /* various bit flags as defined below */
|
||||
u32 flags2; /* various bit flags2 as defined below */
|
||||
u8 state; /* current state bitfield of auth/assoc process */
|
||||
u8 ea[ETH_ALEN]; /* station address */
|
||||
uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
|
||||
|
||||
u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
|
||||
/* seqctl of last received frame (for dups) for non-QoS data and
|
||||
* management */
|
||||
u16 seqctl_nonqos;
|
||||
u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
|
||||
|
||||
struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */
|
||||
};
|
||||
|
||||
#endif /* _BRCM_SCB_H_ */
|
440
drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c
Normal file
440
drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* 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 <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "rate.h"
|
||||
#include "phy/phy_hal.h"
|
||||
#include "channel.h"
|
||||
#include "main.h"
|
||||
#include "stf.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define MIN_SPATIAL_EXPANSION 0
|
||||
#define MAX_SPATIAL_EXPANSION 1
|
||||
|
||||
#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
|
||||
|
||||
#define NSTS_1 1
|
||||
#define NSTS_2 2
|
||||
#define NSTS_3 3
|
||||
#define NSTS_4 4
|
||||
|
||||
static const u8 txcore_default[5] = {
|
||||
(0), /* bitmap of the core enabled */
|
||||
(0x01), /* For Nsts = 1, enable core 1 */
|
||||
(0x03), /* For Nsts = 2, enable core 1 & 2 */
|
||||
(0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
|
||||
(0x0f) /* For Nsts = 4, enable all cores */
|
||||
};
|
||||
|
||||
static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlc->pub->up) {
|
||||
brcms_c_update_beacon(wlc);
|
||||
brcms_c_update_probe_resp(wlc, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
|
||||
* turn on/off txchain.
|
||||
*/
|
||||
void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct brcms_phy_pub *pi = wlc->band->pi;
|
||||
uint active_chains, txchain;
|
||||
|
||||
/* Check if the chip is too hot. Disable one Tx chain, if it is */
|
||||
/* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
|
||||
active_chains = wlc_phy_stf_chain_active_get(pi);
|
||||
txchain = active_chains & 0xf;
|
||||
|
||||
if (wlc->stf->txchain == wlc->stf->hw_txchain) {
|
||||
if (txchain && (txchain < wlc->stf->hw_txchain))
|
||||
/* turn off 1 tx chain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
|
||||
if (txchain == wlc->stf->hw_txchain)
|
||||
/* turn back on txchain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
|
||||
u16 chanspec)
|
||||
{
|
||||
struct tx_power power;
|
||||
u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
|
||||
|
||||
/* Clear previous settings */
|
||||
*ss_algo_channel = 0;
|
||||
|
||||
if (!wlc->pub->up) {
|
||||
*ss_algo_channel = (u16) -1;
|
||||
return;
|
||||
}
|
||||
|
||||
wlc_phy_txpower_get_current(wlc->band->pi, &power,
|
||||
CHSPEC_CHANNEL(chanspec));
|
||||
|
||||
siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
|
||||
cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
|
||||
stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
|
||||
|
||||
/* criteria to choose stf mode */
|
||||
|
||||
/*
|
||||
* the "+3dbm (12 0.25db units)" is to account for the fact that with
|
||||
* CDD, tx occurs on both chains
|
||||
*/
|
||||
if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
|
||||
else
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
|
||||
|
||||
/*
|
||||
* STBC is ORed into to algo channel as STBC requires per-packet SCB
|
||||
* capability check so cannot be default mode of operation. One of
|
||||
* SISO, CDD have to be set
|
||||
*/
|
||||
if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
|
||||
}
|
||||
|
||||
static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
|
||||
return false;
|
||||
|
||||
if ((int_val == ON) && (wlc->stf->txstreams == 1))
|
||||
return false;
|
||||
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (int_val != HT_CAP_RX_STBC_ONE_STREAM))
|
||||
return false;
|
||||
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (wlc->stf->rxstreams == 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
|
||||
u8 core_mask)
|
||||
{
|
||||
brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n",
|
||||
wlc->pub->unit, Nsts, core_mask);
|
||||
|
||||
if (hweight8(core_mask) > wlc->stf->txstreams)
|
||||
core_mask = 0;
|
||||
|
||||
if ((hweight8(core_mask) == wlc->stf->txstreams) &&
|
||||
((core_mask & ~wlc->stf->txchain)
|
||||
|| !(core_mask & wlc->stf->txchain)))
|
||||
core_mask = wlc->stf->txchain;
|
||||
|
||||
wlc->stf->txcore[Nsts] = core_mask;
|
||||
/* Nsts = 1..4, txcore index = 1..4 */
|
||||
if (Nsts == 1) {
|
||||
/* Needs to update beacon and ucode generated response
|
||||
* frames when 1 stream core map changed
|
||||
*/
|
||||
wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
if (wlc->clk) {
|
||||
brcms_c_suspend_mac_and_wait(wlc);
|
||||
brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
|
||||
brcms_c_enable_mac(wlc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
int i;
|
||||
u8 core_mask = 0;
|
||||
|
||||
brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit,
|
||||
val);
|
||||
|
||||
wlc->stf->spatial_policy = (s8) val;
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
|
||||
core_mask = (val == MAX_SPATIAL_EXPANSION) ?
|
||||
wlc->stf->txchain : txcore_default[i];
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Centralized txant update function. call it whenever wlc->stf->txant and/or
|
||||
* wlc->stf->txchain change.
|
||||
*
|
||||
* Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
|
||||
* achieve various tx/rx antenna selection schemes
|
||||
*
|
||||
* legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means auto(last rx).
|
||||
* for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means last rx and do tx-antenna selection for SISO transmissions
|
||||
* for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means last rx and do tx-antenna selection for SISO transmissions
|
||||
* for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
|
||||
* means both cores active
|
||||
*/
|
||||
static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
s8 txant;
|
||||
|
||||
txant = (s8) wlc->stf->txant;
|
||||
if (BRCMS_PHY_11N_CAP(wlc->band)) {
|
||||
if (txant == ANT_TX_FORCE_0) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_0;
|
||||
} else if (txant == ANT_TX_FORCE_1) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_1;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
NREV_GE(wlc->band->phyrev, 3)
|
||||
&& NREV_LT(wlc->band->phyrev, 7))
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_2;
|
||||
} else {
|
||||
if (BRCMS_ISLCNPHY(wlc->band) ||
|
||||
BRCMS_ISSSLPNPHY(wlc->band))
|
||||
wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
|
||||
else {
|
||||
/* catch out of sync wlc->stf->txcore */
|
||||
WARN_ON(wlc->stf->txchain <= 0);
|
||||
wlc->stf->phytxant =
|
||||
wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (txant == ANT_TX_FORCE_0)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
|
||||
else if (txant == ANT_TX_FORCE_1)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
|
||||
else
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
|
||||
}
|
||||
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
}
|
||||
|
||||
int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
|
||||
{
|
||||
u8 txchain = (u8) int_val;
|
||||
u8 txstreams;
|
||||
uint i;
|
||||
|
||||
if (wlc->stf->txchain == txchain)
|
||||
return 0;
|
||||
|
||||
if ((txchain & ~wlc->stf->hw_txchain)
|
||||
|| !(txchain & wlc->stf->hw_txchain))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* if nrate override is configured to be non-SISO STF mode, reject
|
||||
* reducing txchain to 1
|
||||
*/
|
||||
txstreams = (u8) hweight8(txchain);
|
||||
if (txstreams > MAX_STREAMS_SUPPORTED)
|
||||
return -EINVAL;
|
||||
|
||||
wlc->stf->txchain = txchain;
|
||||
wlc->stf->txstreams = txstreams;
|
||||
brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
wlc->stf->txant =
|
||||
(wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
|
||||
wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
|
||||
wlc->stf->rxchain);
|
||||
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* update wlc->stf->ss_opmode which represents the operational stf_ss mode
|
||||
* we're using
|
||||
*/
|
||||
int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
|
||||
{
|
||||
int ret_code = 0;
|
||||
u8 prev_stf_ss;
|
||||
u8 upd_stf_ss;
|
||||
|
||||
prev_stf_ss = wlc->stf->ss_opmode;
|
||||
|
||||
/*
|
||||
* NOTE: opmode can only be SISO or CDD as STBC is decided on a
|
||||
* per-packet basis
|
||||
*/
|
||||
if (BRCMS_STBC_CAP_PHY(wlc) &&
|
||||
wlc->stf->ss_algosel_auto
|
||||
&& (wlc->stf->ss_algo_channel != (u16) -1)) {
|
||||
upd_stf_ss = (wlc->stf->txstreams == 1 ||
|
||||
isset(&wlc->stf->ss_algo_channel,
|
||||
PHY_TXC1_MODE_SISO)) ?
|
||||
PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
|
||||
} else {
|
||||
if (wlc->band != band)
|
||||
return ret_code;
|
||||
upd_stf_ss = (wlc->stf->txstreams == 1) ?
|
||||
PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
|
||||
}
|
||||
if (prev_stf_ss != upd_stf_ss) {
|
||||
wlc->stf->ss_opmode = upd_stf_ss;
|
||||
brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
int brcms_c_stf_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
(wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
|
||||
PHY_TXC1_MODE_CDD;
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
|
||||
if (BRCMS_STBC_CAP_PHY(wlc)) {
|
||||
wlc->stf->ss_algosel_auto = true;
|
||||
/* Init the default value */
|
||||
wlc->stf->ss_algo_channel = (u16) -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_stf_detach(struct brcms_c_info *wlc)
|
||||
{
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
|
||||
|
||||
/* get available rx/tx chains */
|
||||
wlc->stf->hw_txchain = sprom->txchain;
|
||||
wlc->stf->hw_rxchain = sprom->rxchain;
|
||||
|
||||
/* these parameter are intended to be used for all PHY types */
|
||||
if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band))
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
|
||||
else
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF;
|
||||
}
|
||||
|
||||
wlc->stf->txchain = wlc->stf->hw_txchain;
|
||||
wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
|
||||
|
||||
if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band))
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
|
||||
else
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF;
|
||||
}
|
||||
|
||||
wlc->stf->rxchain = wlc->stf->hw_rxchain;
|
||||
wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
|
||||
|
||||
/* initialize the txcore table */
|
||||
memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
|
||||
|
||||
/* default spatial_policy */
|
||||
wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
|
||||
brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
|
||||
}
|
||||
|
||||
static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
u32 rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
|
||||
if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
else if (wlc->stf->txant == ANT_TX_DEF)
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
phytxant &= PHY_TXC_ANT_MASK;
|
||||
return phytxant;
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
|
||||
{
|
||||
return _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
u16 mask = PHY_TXC_ANT_MASK;
|
||||
|
||||
/* for non-siso rates or default setting, use the available chains */
|
||||
if (BRCMS_ISNPHY(wlc->band)) {
|
||||
phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
mask = PHY_TXC_HTANT_MASK;
|
||||
}
|
||||
phytxant |= phytxant & mask;
|
||||
return phytxant;
|
||||
}
|
37
drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h
Normal file
37
drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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_STF_H_
|
||||
#define _BRCM_STF_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int brcms_c_stf_attach(struct brcms_c_info *wlc);
|
||||
void brcms_c_stf_detach(struct brcms_c_info *wlc);
|
||||
|
||||
void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
|
||||
void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
|
||||
u16 *ss_algo_channel, u16 chanspec);
|
||||
int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band);
|
||||
void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force);
|
||||
bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
|
||||
void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
|
||||
u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec);
|
||||
u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec);
|
||||
|
||||
#endif /* _BRCM_STF_H_ */
|
303
drivers/net/wireless/broadcom/brcm80211/brcmsmac/types.h
Normal file
303
drivers/net/wireless/broadcom/brcm80211/brcmsmac/types.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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_TYPES_H_
|
||||
#define _BRCM_TYPES_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#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
|
||||
|
||||
/* boardflags */
|
||||
|
||||
/* Board has gpio 9 controlling the PA */
|
||||
#define BFL_PACTRL 0x00000002
|
||||
/* Not ok to power down the chip pll and oscillator */
|
||||
#define BFL_NOPLLDOWN 0x00000020
|
||||
/* Board supports the Front End Module */
|
||||
#define BFL_FEM 0x00000800
|
||||
/* Board has an external LNA in 2.4GHz band */
|
||||
#define BFL_EXTLNA 0x00001000
|
||||
/* Board has no PA */
|
||||
#define BFL_NOPA 0x00010000
|
||||
/* Power topology uses BUCKBOOST */
|
||||
#define BFL_BUCKBOOST 0x00200000
|
||||
/* Board has FEM and switch to share antenna w/ BT */
|
||||
#define BFL_FEM_BT 0x00400000
|
||||
/* Power topology doesn't use CBUCK */
|
||||
#define BFL_NOCBUCK 0x00800000
|
||||
/* Power topology uses PALDO */
|
||||
#define BFL_PALDO 0x02000000
|
||||
/* Board has an external LNA in 5GHz band */
|
||||
#define BFL_EXTLNA_5GHz 0x10000000
|
||||
|
||||
/* boardflags2 */
|
||||
|
||||
/* Board has an external rxbb regulator */
|
||||
#define BFL2_RXBB_INT_REG_DIS 0x00000001
|
||||
/* Flag to implement alternative A-band PLL settings */
|
||||
#define BFL2_APLL_WAR 0x00000002
|
||||
/* Board permits enabling TX Power Control */
|
||||
#define BFL2_TXPWRCTRL_EN 0x00000004
|
||||
/* Board supports the 2X4 diversity switch */
|
||||
#define BFL2_2X4_DIV 0x00000008
|
||||
/* Board supports 5G band power gain */
|
||||
#define BFL2_5G_PWRGAIN 0x00000010
|
||||
/* Board overrides ASPM and Clkreq settings */
|
||||
#define BFL2_PCIEWAR_OVR 0x00000020
|
||||
#define BFL2_LEGACY 0x00000080
|
||||
/* 4321mcm93 board uses Skyworks FEM */
|
||||
#define BFL2_SKWRKFEM_BRD 0x00000100
|
||||
/* Board has a WAR for clock-harmonic spurs */
|
||||
#define BFL2_SPUR_WAR 0x00000200
|
||||
/* Flag to narrow G-band PLL loop b/w */
|
||||
#define BFL2_GPLL_WAR 0x00000400
|
||||
/* Tx CCK pkts on Ant 0 only */
|
||||
#define BFL2_SINGLEANT_CCK 0x00001000
|
||||
/* WAR to reduce and avoid clock-harmonic spurs in 2G */
|
||||
#define BFL2_2G_SPUR_WAR 0x00002000
|
||||
/* Flag to widen G-band PLL loop b/w */
|
||||
#define BFL2_GPLL_WAR2 0x00010000
|
||||
#define BFL2_IPALVLSHIFT_3P3 0x00020000
|
||||
/* Use internal envelope detector for TX IQCAL */
|
||||
#define BFL2_INTERNDET_TXIQCAL 0x00040000
|
||||
/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
|
||||
* off without this flag to save power. */
|
||||
#define BFL2_XTALBUFOUTEN 0x00080000
|
||||
|
||||
/*
|
||||
* board specific GPIO assignment, gpio 0-3 are also customer-configurable
|
||||
* led
|
||||
*/
|
||||
|
||||
/* bit 9 controls the PA on new 4306 boards */
|
||||
#define BOARD_GPIO_PACTRL 0x200
|
||||
#define BOARD_GPIO_12 0x1000
|
||||
#define BOARD_GPIO_13 0x2000
|
||||
|
||||
/* **** Core type/rev defaults **** */
|
||||
#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
|
||||
* also need to update wlc.h MAXCOREREV
|
||||
*/
|
||||
|
||||
#define NCONF 0x000001ff /* Supported nphy revs:
|
||||
* 0 4321a0
|
||||
* 1 4321a1
|
||||
* 2 4321b0/b1/c0/c1
|
||||
* 3 4322a0
|
||||
* 4 4322a1
|
||||
* 5 4716a0
|
||||
* 6 43222a0, 43224a0
|
||||
* 7 43226a0
|
||||
* 8 5357a0, 43236a0
|
||||
*/
|
||||
|
||||
#define LCNCONF 0x00000007 /* Supported lcnphy revs:
|
||||
* 0 4313a0, 4336a0, 4330a0
|
||||
* 1
|
||||
* 2 4330a0
|
||||
*/
|
||||
|
||||
#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs:
|
||||
* 0 4329a0/k0
|
||||
* 1 4329b0/4329C0
|
||||
* 2 4319a0
|
||||
* 3 5356a0
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* Phy/Core Configuration. Defines macros to to check core phy/rev *
|
||||
* compile-time configuration. Defines default core support. *
|
||||
* ******************************************************************
|
||||
*/
|
||||
|
||||
/* Basic macros to check a configuration bitmask */
|
||||
|
||||
#define CONF_HAS(config, val) ((config) & (1 << (val)))
|
||||
#define CONF_MSK(config, mask) ((config) & (mask))
|
||||
#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
|
||||
#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
|
||||
|
||||
#define CONF_IS(config, val) ((config) == (1 << (val)))
|
||||
#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
|
||||
#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
|
||||
#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
|
||||
#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
|
||||
|
||||
/* Wrappers for some of the above, specific to config constants */
|
||||
|
||||
#define NCONF_HAS(val) CONF_HAS(NCONF, val)
|
||||
#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
|
||||
#define NCONF_IS(val) CONF_IS(NCONF, val)
|
||||
#define NCONF_GE(val) CONF_GE(NCONF, val)
|
||||
#define NCONF_GT(val) CONF_GT(NCONF, val)
|
||||
#define NCONF_LT(val) CONF_LT(NCONF, val)
|
||||
#define NCONF_LE(val) CONF_LE(NCONF, val)
|
||||
|
||||
#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
|
||||
#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
|
||||
#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
|
||||
#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
|
||||
#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
|
||||
#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
|
||||
#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
|
||||
|
||||
#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
|
||||
#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
|
||||
#define D11CONF_IS(val) CONF_IS(D11CONF, val)
|
||||
#define D11CONF_GE(val) CONF_GE(D11CONF, val)
|
||||
#define D11CONF_GT(val) CONF_GT(D11CONF, val)
|
||||
#define D11CONF_LT(val) CONF_LT(D11CONF, val)
|
||||
#define D11CONF_LE(val) CONF_LE(D11CONF, val)
|
||||
|
||||
#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
|
||||
#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
|
||||
|
||||
#define NREV_IS(var, val) \
|
||||
(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define NREV_GE(var, val) \
|
||||
(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define NREV_GT(var, val) \
|
||||
(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define NREV_LT(var, val) \
|
||||
(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define NREV_LE(var, val) \
|
||||
(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define LCNREV_IS(var, val) \
|
||||
(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define LCNREV_GE(var, val) \
|
||||
(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define LCNREV_GT(var, val) \
|
||||
(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define LCNREV_LT(var, val) \
|
||||
(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define LCNREV_LE(var, val) \
|
||||
(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define D11REV_IS(var, val) \
|
||||
(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define D11REV_GE(var, val) \
|
||||
(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define D11REV_GT(var, val) \
|
||||
(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define D11REV_LT(var, val) \
|
||||
(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define D11REV_LE(var, val) \
|
||||
(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define PHYTYPE_IS(var, val)\
|
||||
(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
|
||||
|
||||
#define _PHYCONF_N (1 << PHY_TYPE_N)
|
||||
#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
|
||||
#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
|
||||
|
||||
#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
|
||||
|
||||
/* Utility macro to identify 802.11n (HT) capable PHYs */
|
||||
#define PHYTYPE_11N_CAP(phytype) \
|
||||
(PHYTYPE_IS(phytype, PHY_TYPE_N) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_SSN))
|
||||
|
||||
/* Last but not least: shorter wlc-specific var checks */
|
||||
#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
|
||||
#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
|
||||
#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
|
||||
|
||||
#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
|
||||
|
||||
/**********************************************************************
|
||||
* ------------- End of Core phy/rev configuration. ----------------- *
|
||||
* ********************************************************************
|
||||
*/
|
||||
|
||||
#define BCMMSG(dev, fmt, args...) \
|
||||
do { \
|
||||
if (brcm_msg_level & BRCM_DL_INFO) \
|
||||
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
/*
|
||||
* 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 bcma_wflush16(c, o, v) \
|
||||
({ bcma_write16(c, o, v); (void)bcma_read16(c, o); })
|
||||
#else
|
||||
#define bcma_wflush16(c, o, v) bcma_write16(c, o, v)
|
||||
#endif /* CONFIG_BCM47XX */
|
||||
|
||||
/* multi-bool data type: set of bools, mbool is true if any is set */
|
||||
|
||||
/* set one bool */
|
||||
#define mboolset(mb, bit) ((mb) |= (bit))
|
||||
/* clear one bool */
|
||||
#define mboolclr(mb, bit) ((mb) &= ~(bit))
|
||||
/* true if one bool is set */
|
||||
#define mboolisset(mb, bit) (((mb) & (bit)) != 0)
|
||||
#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
|
||||
|
||||
#define CEIL(x, y) (((x) + ((y)-1)) / (y))
|
||||
|
||||
/* forward declarations */
|
||||
struct wiphy;
|
||||
struct ieee80211_sta;
|
||||
struct ieee80211_tx_queue_params;
|
||||
struct brcms_info;
|
||||
struct brcms_c_info;
|
||||
struct brcms_hardware;
|
||||
struct brcms_band;
|
||||
struct dma_pub;
|
||||
struct si_pub;
|
||||
struct tx_status;
|
||||
struct d11rxhdr;
|
||||
struct txpwr_limits;
|
||||
|
||||
/* iovar structure */
|
||||
struct brcmu_iovar {
|
||||
const char *name; /* name for lookup and display */
|
||||
u16 varid; /* id for switch */
|
||||
u16 flags; /* driver-specific flag bits */
|
||||
u16 type; /* base type of argument */
|
||||
u16 minlen; /* min length for buffer vars */
|
||||
};
|
||||
|
||||
/* brcm_msg_level is a bit vector with defs in defs.h */
|
||||
extern u32 brcm_msg_level;
|
||||
|
||||
#endif /* _BRCM_TYPES_H_ */
|
109
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ucode_loader.c
Normal file
109
drivers/net/wireless/broadcom/brcm80211/brcmsmac/ucode_loader.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 <defs.h>
|
||||
#include "types.h"
|
||||
#include <ucode_loader.h>
|
||||
|
||||
enum {
|
||||
D11UCODE_NAMETAG_START = 0,
|
||||
D11LCN0BSINITVALS24,
|
||||
D11LCN0INITVALS24,
|
||||
D11LCN1BSINITVALS24,
|
||||
D11LCN1INITVALS24,
|
||||
D11LCN2BSINITVALS24,
|
||||
D11LCN2INITVALS24,
|
||||
D11N0ABSINITVALS16,
|
||||
D11N0BSINITVALS16,
|
||||
D11N0INITVALS16,
|
||||
D11UCODE_OVERSIGHT16_MIMO,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ,
|
||||
D11UCODE_OVERSIGHT24_LCN,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR
|
||||
};
|
||||
|
||||
int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = brcms_check_firmwares(wl);
|
||||
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
|
||||
D11LCN0BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
|
||||
D11LCN0INITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
|
||||
D11LCN1BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
|
||||
D11LCN1INITVALS24);
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
|
||||
D11LCN2BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
|
||||
D11LCN2INITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
|
||||
D11N0ABSINITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
|
||||
D11N0BSINITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
|
||||
D11N0INITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
|
||||
D11UCODE_OVERSIGHT16_MIMO);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
|
||||
D11UCODE_OVERSIGHT24_LCN);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void brcms_ucode_data_free(struct brcms_ucode *ucode)
|
||||
{
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_UCODE_H_
|
||||
#define _BRCM_UCODE_H_
|
||||
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */
|
||||
#define MAX_FW_SIZE 150000
|
||||
|
||||
#define UCODE_LOADER_API_VER 0
|
||||
|
||||
struct d11init;
|
||||
|
||||
struct brcms_ucode {
|
||||
struct d11init *d11lcn0bsinitvals24;
|
||||
struct d11init *d11lcn0initvals24;
|
||||
struct d11init *d11lcn1bsinitvals24;
|
||||
struct d11init *d11lcn1initvals24;
|
||||
struct d11init *d11lcn2bsinitvals24;
|
||||
struct d11init *d11lcn2initvals24;
|
||||
struct d11init *d11n0absinitvals16;
|
||||
struct d11init *d11n0bsinitvals16;
|
||||
struct d11init *d11n0initvals16;
|
||||
__le32 *bcm43xx_16_mimo;
|
||||
size_t bcm43xx_16_mimosz;
|
||||
__le32 *bcm43xx_24_lcn;
|
||||
size_t bcm43xx_24_lcnsz;
|
||||
u32 *bcm43xx_bommajor;
|
||||
u32 *bcm43xx_bomminor;
|
||||
};
|
||||
|
||||
int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
|
||||
|
||||
void brcms_ucode_data_free(struct brcms_ucode *ucode);
|
||||
|
||||
int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, unsigned int idx);
|
||||
int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
|
||||
unsigned int idx);
|
||||
void brcms_ucode_free_buf(void *);
|
||||
int brcms_check_firmwares(struct brcms_info *wl);
|
||||
|
||||
#endif /* _BRCM_UCODE_H_ */
|
Reference in New Issue
Block a user