diff --git a/arch/arm/boot/dts/qcom/msm8226-720p-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8226-720p-mtp.dtsi index a5c495ba61d21c252532ffc74fe8827b551c1ee2..1277ff8d72564be135a5962ac088964737e7b8da 100644 --- a/arch/arm/boot/dts/qcom/msm8226-720p-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8226-720p-mtp.dtsi @@ -171,7 +171,7 @@ 1 &intc 0 221 0>; interrupt-names = "hc_irq", "pwr_irq", "status_irq"; - status = "ok"; + status = "disabled"; }; &sdhc_3 { qcom,sup-voltages = <1800 1800>; diff --git a/arch/arm/configs/sturgeon_defconfig b/arch/arm/configs/sturgeon_defconfig index ff369faa1c77e236f9f7101575c03fc49a6136b7..2790634a817052404e3012f4480f162dda276b02 100644 --- a/arch/arm/configs/sturgeon_defconfig +++ b/arch/arm/configs/sturgeon_defconfig @@ -181,6 +181,8 @@ CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y CONFIG_NET_CLS_ACT=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y CONFIG_BT=y CONFIG_BRCM_BT_SLEEP=y CONFIG_RFKILL=y @@ -211,6 +213,8 @@ CONFIG_TUN=y # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_BCMDHD=y +CONFIG_BCMDHD_SDIO=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ce4cb0553a6ad57ff60d8d3161e0ae28df614239..ef38b70eda3dd727716819ecf1f7387d9907a795 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -37,6 +37,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/mmc.h> #include <linux/mmc/sd.h> +#include <linux/mmc/sdhci.h> #include "core.h" #include "bus.h" @@ -2057,6 +2058,7 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) void mmc_power_up(struct mmc_host *host) { int bit; + struct sdhci_host *sdh_host = mmc_priv(host); if (host->ios.power_mode == MMC_POWER_ON) return; @@ -2096,16 +2098,14 @@ void mmc_power_up(struct mmc_host *host) * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ - - if (2 == host->index) /* index:2 for sdio device */ - { - mmc_delay(200); - } - else - { - mmc_delay(10); - } - + if (!strcmp("msm_sdcc.3", sdh_host->hw_name)) + { + mmc_delay(200); + } + else + { + mmc_delay(10); + } /* Set signal voltage to 3.3V */ __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); @@ -3814,6 +3814,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, notify_block, struct mmc_host, pm_notify); unsigned long flags; int err = 0; + struct sdhci_host *sdh_host = mmc_priv(host); switch (mode) { case PM_HIBERNATION_PREPARE: @@ -3882,7 +3883,11 @@ int mmc_pm_notify(struct notifier_block *notify_block, } host->rescan_disable = 0; spin_unlock_irqrestore(&host->lock, flags); - mmc_detect_change(host, 0); + /* no detect change for sdio */ + if (strcmp("msm_sdcc.3", sdh_host->hw_name)) + { + mmc_detect_change(host, 0); + } break; default: diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig index b5e991d1d06524580c2f26d62bfd1cfcb92b2daf..1e1b77d4f26492acd61e0f795491922ab9085b5f 100644 --- a/drivers/net/wireless/bcmdhd/Kconfig +++ b/drivers/net/wireless/bcmdhd/Kconfig @@ -7,69 +7,34 @@ config BCMDHD If you choose to build a module, it'll be called dhd. Say M if unsure. -config BCM4330 - tristate "Broadcom 4330 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4330 chipset. - -config BCM4334 - tristate "Broadcom 4334 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4334 chipset. - -config BCM4335 - tristate "Broadcom 4335 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4335 chipset. - -config BCM4339 - tristate "Broadcom 4339 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4339 chipset. - -config BCM4354 - tristate "Broadcom 4354 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4354 chipset. - -config BCM4343 - tristate "Broadcom 4343 wireless cards support" - depends on WLAN - ---help--- - This module adds support for wireless adapters based on - Broadcom 4343 chipset. - config BCMDHD_SDIO bool "SDIO bus interface support" depends on BCMDHD && MMC - default y config BCMDHD_PCIE bool "PCIe bus interface support" depends on BCMDHD && PCI && !BCMDHD_SDIO +config BCM4354 + tristate "BCM4354 support" + depends on BCMDHD + +config BCM4356 + tristate "BCM4356 support" + depends on BCMDHD + default n config BCMDHD_FW_PATH depends on BCMDHD string "Firmware path" - default "/system/vendor/bcm/fw/bcm43430_mfg.bin" + default "/system/vendor/firmware/fw_bcmdhd.bin" ---help--- Path to the firmware file. config BCMDHD_NVRAM_PATH depends on BCMDHD string "NVRAM path" - default "/system/vendor/bcm/nvram/bcm4343s.txt" + default "/system/etc/wifi/bcm4343s.txt" ---help--- Path to the calibration file. diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile index 2294315711d0840f39dd41e9447f675ef09b3e13..07354ee7cd9663cfc6153cf50aa7e8cc809c8e3f 100644 --- a/drivers/net/wireless/bcmdhd/Makefile +++ b/drivers/net/wireless/bcmdhd/Makefile @@ -1,136 +1,254 @@ -# bcmdhd -# -# -# -# -# - -DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ +# bcmdhd v1.201.31 +##################### +# SDIO Basic feature +##################### + +DHDCFLAGS += -Wall -Wstrict-prototypes -Dlinux -DLINUX -DBCMDRIVER \ -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \ - -DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DBCMDBG -DCUSTOMER_HW2 -DWLP2P \ + -DDHDTHREAD -DSHOW_EVENTS -DBCMDBG -DCUSTOMER_HW2 -DWLP2P \ -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ - -DKEEP_ALIVE -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ - -DEMBEDDED_PLATFORM -DPNO_SUPPORT \ - -DDHD_USE_IDLECOUNT -DSET_RANDOM_MAC_SOFTAP -DROAM_ENABLE -DVSDB \ - -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST \ - -DESCAN_RESULT_PATCH -DSUPPORT_PM2_ONLY -DWLTDLS \ - -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD \ - -DMIRACAST_AMPDU_SIZE=8 -DROAM_ENABLE -DWL_IFACE_COMB_NUM_CHANNELS \ - -Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include \ - -Idrivers/net/wireless/bcmdhd/common/include - -DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \ - dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \ - dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \ - bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \ - hnd_pktq.o hnd_pktpool.o - -obj-$(CONFIG_BCMDHD) += bcmdhd.o -bcmdhd-objs += $(DHDOFILES) -ifneq ($(CONFIG_WIRELESS_EXT),) -bcmdhd-objs += wl_iw.o -DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW -endif -ifneq ($(CONFIG_CFG80211),) -bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o dhd_cfg80211.o wl_cfg_btcoex.o -DHDCFLAGS += -DWL_CFG80211 -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF -DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65 -DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15 + -DKEEP_ALIVE -DGET_CUSTOM_MAC_ENABLE -DCSCAN -DPKT_FILTER_SUPPORT \ + -DEMBEDDED_PLATFORM -DPNO_SUPPORT \ + -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT \ + + +DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0 -DUSE_WL_FRAMEBURST -DPROP_TXSTATUS_VSDB \ + + +################# +# Common feature +################# +DHDCFLAGS += -DWL_CFG80211 +# Print out kernel panic point of file and line info when assertion happened +DHDCFLAGS += -DBCMASSERT_LOG + +# keepalive DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000 -DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7 -endif -ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),) -DHDCFLAGS += -DWL_SCHED_SCAN -endif +DHDCFLAGS += -DVSDB + +# For p2p connection issue +DHDCFLAGS += -DWL_SCB_TIMEOUT=10 + + +# TDLS enable +DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE +# For TDLS tear down inactive time 40 sec +DHDCFLAGS += -DCUSTOM_TDLS_IDLE_MODE_SETTING=40000 +# for TDLS RSSI HIGH for establishing TDLS link +DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-60 +# for TDLS RSSI HIGH for tearing down TDLS link +DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-70 + +# Roaming +DHDCFLAGS += -DROAM_AP_ENV_DETECTION +DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API +DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND +# Roaming trigger +DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-75 +DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=10 +# Set PM 2 always regardless suspend/resume +DHDCFLAGS += -DSUPPORT_PM2_ONLY + +# For special PNO Event keep wake lock for 10sec +DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10 +DHDCFLAGS += -DMIRACAST_AMPDU_SIZE=8 + +#Gscan +DHDCFLAGS += -DGSCAN_SUPPORT +DHDCFLAGS += -DRTT_SUPPORT +DHDCFLAGS += -DWL_VENDOR_EXT_SUPPORT +#Link Statistics +DHDCFLAGS += -DLINKSTAT_SUPPORT + + +# DO NOT use Early suspend +# DHDCFLAGS += -DDHD_USE_EARLYSUSPEND + +# Use Android wake lock mechanism +DHDCFLAGS += -DCONFIG_HAS_WAKELOCK +# For Scan result patch +DHDCFLAGS += -DESCAN_RESULT_PATCH + # For Static Buffer ifeq ($(CONFIG_BROADCOM_WIFI_RESERVED_MEM),y) DHDCFLAGS += -DCONFIG_DHD_USE_STATIC_BUF + DHDCFLAGS += -DENHANCED_STATIC_BUF + DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT +endif +ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),) +DHDCFLAGS += -DWL_SCHED_SCAN endif +# Ioctl timeout 5000ms +DHDCFLAGS += -DIOCTL_RESP_TIMEOUT=5000 # Prevent rx thread monopolize DHDCFLAGS += -DWAIT_DEQUEUE -# Use Android wake lock mechanism -DHDCFLAGS += -DCONFIG_HAS_WAKELOCK +# Config PM Control +DHDCFLAGS += -DCONFIG_CONTROL_PM + +# idle count +DHDCFLAGS += -DDHD_USE_IDLECOUNT # SKB TAILPAD to avoid out of boundary memory access DHDCFLAGS += -DDHDENABLE_TAILPAD -DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0 -DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30 - -EXTRA_CFLAGS = $(DHDCFLAGS) -ifeq ($(CONFIG_BCMDHD),m) -EXTRA_LDFLAGS += --strip-debug -else -DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD -endif +# Wi-Fi Direct +DHDCFLAGS += -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST +DHDCFLAGS += -DWL_CFG80211_STA_EVENT +DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS +DHDCFLAGS += -DWL_ENABLE_P2P_IF + +DHDCFLAGS += -DWL_CFG80211_ACL +DHDCFLAGS += -DDISABLE_11H_SOFTAP +DHDCFLAGS += -DSET_RANDOM_MAC_SOFTAP +DHDCFLAGS += -DCUSTOM_FORCE_NODFS_FLAG +DHDCFLAGS += -DCUSTOM_SET_SHORT_DWELL_TIME + +########################## +# driver type +# m: module type driver +# y: built-in type driver +########################## +DRIVER_TYPE ?= y ######################### # Chip dependent feature ######################### -ifneq ($(CONFIG_BCM4339),) -DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 -DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DHDCFLAGS += -DCUSTOM_SDIO_F2_BLKSIZE=512 -DHDCFLAGS += -DDHDTCPACK_SUPPRESS -DHDCFLAGS += -DUSE_WL_TXBF -DHDCFLAGS += -DUSE_WL_FRAMEBURST -DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DHDCFLAGS += -DPROP_TXSTATUS_VSDB -DHDCFLAGS += -DREPEAT_READFRAME -DHDCFLAGS += -DROAM_AP_ENV_DETECTION + +ifneq ($(CONFIG_BCMDHD_SDIO),) + DHDCFLAGS += -DBDC -DOOB_INTR_ONLY -DHW_OOB -DDHD_BCMEVENTS -DMMC_SDIO_ABORT + DHDCFLAGS += -DBCMSDIO -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR + DHDCFLAGS += -DPROP_TXSTATUS + DHDCFLAGS += -DCUSTOM_AMPDU_MPDU=16 + DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 +# tput enhancement + DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 + DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128 +# DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED +# DHDCFLAGS += -DDHDTCPACK_SUPPRESS #maybe need remove + DHDCFLAGS += -DRXFRAME_THREAD + DHDCFLAGS += -DREPEAT_READFRAME + DHDCFLAGS += -DCUSTOM_MAX_TXGLOM_SIZE=40 +# DHDCFLAGS += -DMAX_HDR_READ=128 +# DHDCFLAGS += -DDHD_FIRSTREAD=128 + +# DHDCFLAGS += -DSAR_SUPPORT endif -ifneq ($(CONFIG_BCM4343),) -DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 -DHDCFLAGS += -DCUSTOM_SDIO_F2_BLKSIZE=512 -DHDCFLAGS += -DDISABLE_FLOW_CONTROL -DHDCFLAGS += -DUSE_WL_FRAMEBURST -DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=32 -DHDCFLAGS += -DPROP_TXSTATUS_VSDB +ifneq ($(filter y, $(CONFIG_BCM4354) $(CONFIG_BCM4356)),) + DHDCFLAGS += -DUSE_WL_TXBF + DHDCFLAGS += -DUSE_WL_FRAMEBURST + DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0 + DHDCFLAGS += -DMAX_AP_CLIENT_CNT=10 + DHDCFLAGS += -DMAX_GO_CLIENT_CNT=5 + +# New Features + DHDCFLAGS += -DWL11U + DHDCFLAGS += -DMFP + DHDCFLAGS += -DDHD_ENABLE_LPC + DHDCFLAGS += -DCUSTOM_COUNTRY_CODE +ifneq ($(CONFIG_BCMDHD_SDIO),) + DHDCFLAGS += -DBDC -DOOB_INTR_ONLY -DHW_OOB -DDHD_BCMEVENTS -DMMC_SDIO_ABORT + DHDCFLAGS += -DBCMSDIO -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR + DHDCFLAGS += -DPROP_TXSTATUS + DHDCFLAGS += -DCUSTOM_AMPDU_MPDU=16 + DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 +# tput enhancement + DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 + DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128 + DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED + DHDCFLAGS += -DDHDTCPACK_SUPPRESS #maybe need remove + DHDCFLAGS += -DRXFRAME_THREAD + DHDCFLAGS += -DREPEAT_READFRAME + DHDCFLAGS += -DCUSTOM_MAX_TXGLOM_SIZE=40 + DHDCFLAGS += -DMAX_HDR_READ=128 + DHDCFLAGS += -DDHD_FIRSTREAD=128 + + DHDCFLAGS += -DSAR_SUPPORT +endif -DHDCFLAGS += -DREPEAT_READFRAME -DHDCFLAGS += -DROAM_AP_ENV_DETECTION +ifneq ($(CONFIG_BCMDHD_PCIE),) + DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1 +# tput enhancement + DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 + DHDCFLAGS += -DCUSTOM_AMPDU_MPDU=32 + DHDCFLAGS += -DCUSTOM_AMPDU_RELEASE=16 + DHDCFLAGS += -DPROP_TXSTATUS_VSDB +# Disable watchdog thread + DHDCFLAGS += -DCUSTOM_DHD_WATCHDOG_MS=0 + + DHDCFLAGS += -DSAR_SUPPORT +endif endif -ifneq ($(CONFIG_BCM4334),) -DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 +ifneq ($(CONFIG_BCM4339),) + DHDCFLAGS += -DBCM4339_CHIP -DHW_OOB + + # tput enhancement + DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 + DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128 + DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED + DHDCFLAGS += -DDHDTCPACK_SUPPRESS + DHDCFLAGS += -DUSE_WL_TXBF + DHDCFLAGS += -DUSE_WL_FRAMEBURST + DHDCFLAGS += -DRXFRAME_THREAD + DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 + DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0 + DHDCFLAGS += -DPROP_TXSTATUS_VSDB + DHDCFLAGS += -DCUSTOM_MAX_TXGLOM_SIZE=32 + + # New Features + DHDCFLAGS += -DWL11U + DHDCFLAGS += -DDHD_ENABLE_LPC + DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30 +endif -DHDCFLAGS += -DCUSTOM_SDIO_F2_BLKSIZE=512 -DHDCFLAGS += -DDISABLE_FLOW_CONTROL -DHDCFLAGS += -DUSE_WL_FRAMEBURST -DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=32 -DHDCFLAGS += -DPROP_TXSTATUS_VSDB +#EXTRA_LDFLAGS += --strip-debug -DHDCFLAGS += -DREPEAT_READFRAME -DHDCFLAGS += -DROAM_AP_ENV_DETECTION +ifeq ($(DRIVER_TYPE),y) + DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD + DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC +endif + +EXTRA_CFLAGS += $(DHDCFLAGS) -DDHD_DEBUG +EXTRA_CFLAGS += -DSRCBASE=\"$(src)\" +EXTRA_CFLAGS += -I$(src)/include/ -I$(src)/ +KBUILD_CFLAGS += -I$(LINUXDIR)/include -I$(shell pwd) + +DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o \ + dhd_linux.o dhd_linux_sched.o dhd_cfg80211.o dhd_linux_wq.o aiutils.o bcmevent.o \ + bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \ + wl_android.o wl_roam.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o wl_linux_mon.o \ + dhd_linux_platdev.o dhd_pno.o dhd_rtt.o dhd_linux_wq.o wl_cfg_btcoex.o \ + hnd_pktq.o hnd_pktpool.o wl_cfgvendor.o + +ifneq ($(CONFIG_BCMDHD_SDIO),) + DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o + DHDOFILES += dhd_cdc.o dhd_wlfc.o dhd_sdio.o +endif + +ifneq ($(CONFIG_BCMDHD_PCIE),) + DHDOFILES += dhd_pcie.o dhd_pcie_linux.o dhd_msgbuf.o dhd_flowring.o + DHDOFILES += pcie_core.o endif +bcmdhd-objs := $(DHDOFILES) +obj-$(DRIVER_TYPE) += bcmdhd.o + +all: + @echo "$(MAKE) --no-print-directory -C $(KDIR) SUBDIRS=$(CURDIR) modules" + @$(MAKE) --no-print-directory -C $(KDIR) SUBDIRS=$(CURDIR) modules + +clean: + rm -rf *.o *.ko *.mod.c *~ .*.cmd *.o.cmd .*.o.cmd \ + Module.symvers modules.order .tmp_versions modules.builtin -bcmdhd-$(CONFIG_BCMDHD_SDIO) += \ - bcmsdh.o \ - bcmsdh_linux.o \ - bcmsdh_sdmmc.o \ - bcmsdh_sdmmc_linux.o \ - dhd_sdio.o \ - dhd_cdc.o \ - dhd_wlfc.o -bcmdhd-$(CONFIG_BCMDHD_PCIE) += \ - dhd_pcie.o \ - dhd_pcie_linux.o \ - dhd_msgbuf.o \ - dhd_log.o \ - circularbuf.o \ - pcie_core.o -ccflags-$(CONFIG_BCMDHD_SDIO) += \ - -DSDTEST -DBDC -DDHD_BCMEVENTS -DPROP_TXSTATUS -DOOB_INTR_ONLY \ - -DHW_OOB -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DSDIO_CRC_ERROR_FIX \ - -DUSE_SDIOFIFO_IOVAR -ccflags-$(CONFIG_BCMDHD_PCIE) += \ - -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1 +install: + @$(MAKE) --no-print-directory -C $(KDIR) \ + SUBDIRS=$(CURDIR) modules_install diff --git a/drivers/net/wireless/bcmdhd/aiutils.c b/drivers/net/wireless/bcmdhd/aiutils.c index 2551911fbf2400f2795341a0fc3ae4326cc5b9d5..9095894794d2b476e9c7bdfb7b1c5fe6686dd04b 100644 --- a/drivers/net/wireless/bcmdhd/aiutils.c +++ b/drivers/net/wireless/bcmdhd/aiutils.c @@ -2,7 +2,25 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: aiutils.c 467150 2014-04-02 17:30:43Z $ */ diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c index 6e219b88f3bfe5654ddb442b14c18a6dfc1f9a71..f55bb68486893fab7269ce284e15dd60dd7aa906 100644 --- a/drivers/net/wireless/bcmdhd/bcmevent.c +++ b/drivers/net/wireless/bcmdhd/bcmevent.c @@ -1,8 +1,26 @@ /* * bcmevent read-only data shared by kernel or app layers * - * $Copyright Open Broadcom Corporation$ - * $Id: bcmevent.c 487838 2014-06-27 05:51:44Z $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * $Id: bcmevent.c 470794 2014-04-16 12:01:41Z $ */ #include <typedefs.h> @@ -62,10 +80,6 @@ static const bcmevent_name_str_t bcmevent_names[] = { #endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */ BCMEVENT_NAME(WLC_E_RADIO), BCMEVENT_NAME(WLC_E_PSM_WATCHDOG), -#if defined(BCMCCX) && defined(CCX_SDK) - BCMEVENT_NAME(WLC_E_CCX_ASSOC_START), - BCMEVENT_NAME(WLC_E_CCX_ASSOC_ABORT), -#endif /* BCMCCX && CCX_SDK */ BCMEVENT_NAME(WLC_E_PROBREQ_MSG), BCMEVENT_NAME(WLC_E_SCAN_CONFIRM_IND), BCMEVENT_NAME(WLC_E_PSK_SUP), @@ -75,9 +89,6 @@ static const bcmevent_name_str_t bcmevent_names[] = { BCMEVENT_NAME(WLC_E_UNICAST_DECODE_ERROR), BCMEVENT_NAME(WLC_E_MULTICAST_DECODE_ERROR), BCMEVENT_NAME(WLC_E_TRACE), -#ifdef WLBTAMP - BCMEVENT_NAME(WLC_E_BTA_HCI_EVENT), -#endif BCMEVENT_NAME(WLC_E_IF), #ifdef WLP2P BCMEVENT_NAME(WLC_E_P2P_DISC_LISTEN_COMPLETE), @@ -90,23 +101,6 @@ static const bcmevent_name_str_t bcmevent_names[] = { BCMEVENT_NAME(WLC_E_ACTION_FRAME_RX), BCMEVENT_NAME(WLC_E_ACTION_FRAME_COMPLETE), #endif -#if 0 && (NDISVER >= 0x0620) - BCMEVENT_NAME(WLC_E_PRE_ASSOC_IND), - BCMEVENT_NAME(WLC_E_PRE_REASSOC_IND), - BCMEVENT_NAME(WLC_E_CHANNEL_ADOPTED), - BCMEVENT_NAME(WLC_E_AP_STARTED), - BCMEVENT_NAME(WLC_E_DFS_AP_STOP), - BCMEVENT_NAME(WLC_E_DFS_AP_RESUME), - BCMEVENT_NAME(WLC_E_ASSOC_IND_NDIS), - BCMEVENT_NAME(WLC_E_REASSOC_IND_NDIS), - BCMEVENT_NAME(WLC_E_ACTION_FRAME_RX_NDIS), - BCMEVENT_NAME(WLC_E_AUTH_REQ), - BCMEVENT_NAME(WLC_E_IBSS_COALESCE), -#endif -#ifdef BCMWAPI_WAI - BCMEVENT_NAME(WLC_E_WAI_STA_EVENT), - BCMEVENT_NAME(WLC_E_WAI_MSG), -#endif /* BCMWAPI_WAI */ BCMEVENT_NAME(WLC_E_ESCAN_RESULT), BCMEVENT_NAME(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE), #ifdef WLP2P @@ -157,19 +151,16 @@ static const bcmevent_name_str_t bcmevent_names[] = { BCMEVENT_NAME(WLC_E_BCMC_CREDIT_SUPPORT), #endif BCMEVENT_NAME(WLC_E_TXFAIL_THRESH), -#ifdef WLAIBSS - BCMEVENT_NAME(WLC_E_AIBSS_TXFAIL), -#endif /* WLAIBSS */ +#ifdef GSCAN_SUPPORT + { WLC_E_PFN_GSCAN_FULL_RESULT, "PFN_GSCAN_FULL_RESULT"}, + { WLC_E_PFN_SWC, "PFN_SIGNIFICANT_WIFI_CHANGE"} +#endif /* GSCAN_SUPPORT */ #ifdef WLBSSLOAD_REPORT BCMEVENT_NAME(WLC_E_BSS_LOAD), #endif #if defined(BT_WIFI_HANDOVER) || defined(WL_TBOW) BCMEVENT_NAME(WLC_E_BT_WIFI_HANDOVER_REQ), #endif -#ifdef WLFBT - BCMEVENT_NAME(WLC_E_FBT_AUTH_REQ_IND), -#endif /* WLFBT */ - BCMEVENT_NAME(WLC_E_RMC_EVENT), }; diff --git a/drivers/net/wireless/bcmdhd/bcmsdh.c b/drivers/net/wireless/bcmdhd/bcmsdh.c index f621572b7a797c4425e3238348ab5a264bbb675e..5ee526b06ce309b7e87294b2850da401ebad7905 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh.c @@ -2,7 +2,25 @@ * BCMSDH interface glue * implement bcmsdh API for SDIOH driver * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdh.c 450676 2014-01-22 22:45:13Z $ */ @@ -32,9 +50,6 @@ const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; /* local copy of bcm sd handler */ bcmsdh_info_t * l_bcmsdh = NULL; -#if 0 && (NDISVER < 0x0630) -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd); -#endif #if defined(OOB_INTR_ONLY) && defined(HW_OOB) extern int @@ -86,10 +101,6 @@ bcmsdh_detach(osl_t *osh, void *sdh) bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; if (bcmsdh != NULL) { -#if 0 && (NDISVER < 0x0630) - if (bcmsdh->sdioh) - sdioh_detach(osh, bcmsdh->sdioh); -#endif MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t)); } diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c index ad136bfc2f4690c0eecc1fa0c43569850e0c1bd7..5b2d8b4e5183f30bbc62357c6d22a400b04f44e8 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c @@ -1,7 +1,25 @@ /* * SDIO access interface for drivers - linux specific (pci only) * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdh_linux.c 461444 2014-03-12 02:55:28Z $ */ diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c index d668d887d62fd3cecdc14943baecc867d2f8017f..95e37d9a348465bdfcef9b2cebddabb34984cc4f 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c @@ -423,7 +423,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, { const bcm_iovar_t *vi = NULL; int bcmerror = 0; - int val_size; int32 int_val = 0; bool bool_val; uint32 actionid; @@ -451,13 +450,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, plen = len; } - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - if (plen >= (int)sizeof(int_val)) bcopy(params, &int_val, sizeof(int_val)); @@ -468,7 +460,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, switch (actionid) { case IOV_GVAL(IOV_MSGLEVEL): int_val = (int32)sd_msglevel; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_MSGLEVEL): @@ -477,7 +469,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_BLOCKMODE): int_val = (int32)si->sd_blockmode; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_BLOCKMODE): @@ -491,7 +483,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, break; } int_val = (int32)si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_BLOCKSIZE): @@ -527,12 +519,12 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_RXCHAIN): int_val = (int32)si->use_rxchain; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_DMA): int_val = (int32)si->sd_use_dma; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DMA): @@ -541,7 +533,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_USEINTS): int_val = (int32)si->use_client_ints; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_USEINTS): @@ -555,7 +547,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_DIVISOR): int_val = (uint32)sd_divisor; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DIVISOR): @@ -564,7 +556,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_POWER): int_val = (uint32)sd_power; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_POWER): @@ -573,7 +565,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_CLOCK): int_val = (uint32)sd_clock; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_CLOCK): @@ -582,7 +574,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_SDMODE): int_val = (uint32)sd_sdmode; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_SDMODE): @@ -591,7 +583,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_HISPEED): int_val = (uint32)sd_hiok; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_HISPEED): @@ -600,12 +592,12 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_NUMINTS): int_val = (int32)si->intrcount; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_NUMLOCALINTS): int_val = (int32)0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_HOSTREG): diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c index a93f983f10247cc255c2bc0e8f69aee63503142a..f89b81bea8754c7ad3ed35f09998ccb63214d2bf 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c @@ -201,17 +201,11 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func) /* devices we support, null terminated */ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, - { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, - { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) }, - { /* end: all zeroes */ }, + { .class = SDIO_CLASS_NONE, + .vendor = SDIO_VENDOR_ID_BROADCOM, + .device = SDIO_ANY_ID + }, + { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); diff --git a/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c b/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c new file mode 100644 index 0000000000000000000000000000000000000000..0f151027c2d21f0e483528a088a0f4a589e4e410 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c @@ -0,0 +1,249 @@ +/* + * Broadcom SPI Host Controller Driver - Linux Per-port + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmsdspi_linux.c 406045 2013-06-05 22:09:52Z $ + */ + +#include <typedefs.h> +#include <bcmutils.h> + +#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */ +#include <sdiovar.h> /* to get msglevel bit values */ + +#include <pcicfg.h> +#include <sdio.h> /* SDIO Device and Protocol Specs */ +#include <linux/sched.h> /* request_irq(), free_irq() */ +#include <bcmsdspi.h> +#include <bcmspi.h> + +extern uint sd_crc; +module_param(sd_crc, uint, 0); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#define KERNEL26 +#endif + +struct sdos_info { + sdioh_info_t *sd; + spinlock_t lock; + wait_queue_head_t intr_wait_queue; +}; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#define BLOCKABLE() (!in_atomic()) +#else +#define BLOCKABLE() (!in_interrupt()) +#endif + +/* Interrupt handler */ +static irqreturn_t +sdspi_isr(int irq, void *dev_id +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +, struct pt_regs *ptregs +#endif +) +{ + sdioh_info_t *sd; + struct sdos_info *sdos; + bool ours; + + sd = (sdioh_info_t *)dev_id; + sd->local_intrcount++; + + if (!sd->card_init_done) { + sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq)); + return IRQ_RETVAL(FALSE); + } else { + ours = spi_check_client_intr(sd, NULL); + + /* For local interrupts, wake the waiting process */ + if (ours && sd->got_hcint) { + sdos = (struct sdos_info *)sd->sdos_info; + wake_up_interruptible(&sdos->intr_wait_queue); + } + + return IRQ_RETVAL(ours); + } +} + + +/* Register with Linux for interrupts */ +int +spi_register_irq(sdioh_info_t *sd, uint irq) +{ + sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq)); + if (request_irq(irq, sdspi_isr, IRQF_SHARED, "bcmsdspi", sd) < 0) { + sd_err(("%s: request_irq() failed\n", __FUNCTION__)); + return ERROR; + } + return SUCCESS; +} + +/* Free Linux irq */ +void +spi_free_irq(uint irq, sdioh_info_t *sd) +{ + free_irq(irq, sd); +} + +/* Map Host controller registers */ +uint32 * +spi_reg_map(osl_t *osh, uintptr addr, int size) +{ + return (uint32 *)REG_MAP(addr, size); +} + +void +spi_reg_unmap(osl_t *osh, uintptr addr, int size) +{ + REG_UNMAP((void*)(uintptr)addr); +} + +int +spi_osinit(sdioh_info_t *sd) +{ + struct sdos_info *sdos; + + sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); + sd->sdos_info = (void*)sdos; + if (sdos == NULL) + return BCME_NOMEM; + + sdos->sd = sd; + spin_lock_init(&sdos->lock); + init_waitqueue_head(&sdos->intr_wait_queue); + return BCME_OK; +} + +void +spi_osfree(sdioh_info_t *sd) +{ + struct sdos_info *sdos; + ASSERT(sd && sd->sdos_info); + + sdos = (struct sdos_info *)sd->sdos_info; + MFREE(sd->osh, sdos, sizeof(struct sdos_info)); +} + +/* Interrupt enable/disable */ +SDIOH_API_RC +sdioh_interrupt_set(sdioh_info_t *sd, bool enable) +{ + ulong flags; + struct sdos_info *sdos; + + sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling")); + + sdos = (struct sdos_info *)sd->sdos_info; + ASSERT(sdos); + + if (!(sd->host_init_done && sd->card_init_done)) { + sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__)); + return SDIOH_API_RC_FAIL; + } + + if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { + sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__)); + return SDIOH_API_RC_FAIL; + } + + /* Ensure atomicity for enable/disable calls */ + spin_lock_irqsave(&sdos->lock, flags); + + sd->client_intr_enabled = enable; + if (enable && !sd->lockcount) + spi_devintr_on(sd); + else + spi_devintr_off(sd); + + spin_unlock_irqrestore(&sdos->lock, flags); + + return SDIOH_API_RC_SUCCESS; +} + +/* Protect against reentrancy (disable device interrupts while executing) */ +void +spi_lock(sdioh_info_t *sd) +{ + ulong flags; + struct sdos_info *sdos; + + sdos = (struct sdos_info *)sd->sdos_info; + ASSERT(sdos); + + sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount)); + + spin_lock_irqsave(&sdos->lock, flags); + if (sd->lockcount) { + sd_err(("%s: Already locked!\n", __FUNCTION__)); + ASSERT(sd->lockcount == 0); + } + spi_devintr_off(sd); + sd->lockcount++; + spin_unlock_irqrestore(&sdos->lock, flags); +} + +/* Enable client interrupt */ +void +spi_unlock(sdioh_info_t *sd) +{ + ulong flags; + struct sdos_info *sdos; + + sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled)); + ASSERT(sd->lockcount > 0); + + sdos = (struct sdos_info *)sd->sdos_info; + ASSERT(sdos); + + spin_lock_irqsave(&sdos->lock, flags); + if (--sd->lockcount == 0 && sd->client_intr_enabled) { + spi_devintr_on(sd); + } + spin_unlock_irqrestore(&sdos->lock, flags); +} + +void spi_waitbits(sdioh_info_t *sd, bool yield) +{ +#ifndef BCMSDYIELD + ASSERT(!yield); +#endif + sd_trace(("%s: yield %d canblock %d\n", + __FUNCTION__, yield, BLOCKABLE())); + + /* Clear the "interrupt happened" flag and last intrstatus */ + sd->got_hcint = FALSE; + +#ifdef BCMSDYIELD + if (yield && BLOCKABLE()) { + struct sdos_info *sdos; + sdos = (struct sdos_info *)sd->sdos_info; + /* Wait for the indication, the interrupt will be masked when the ISR fires. */ + wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint)); + } else +#endif /* BCMSDYIELD */ + { + spi_spinbits(sd); + } + +} diff --git a/drivers/net/wireless/bcmdhd/bcmspibrcm.c b/drivers/net/wireless/bcmdhd/bcmspibrcm.c new file mode 100644 index 0000000000000000000000000000000000000000..f0a6102cdf6a1c0a8e41ff0ecac5027bc026b337 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/bcmspibrcm.c @@ -0,0 +1,1810 @@ +/* + * Broadcom BCMSDH to gSPI Protocol Conversion Layer + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmspibrcm.c 373331 2012-12-07 04:46:22Z $ + */ + +#define HSMODE + +#include <typedefs.h> + +#include <bcmdevs.h> +#include <bcmendian.h> +#include <bcmutils.h> +#include <osl.h> +#include <hndsoc.h> +#include <siutils.h> +#include <sbchipc.h> +#include <sbsdio.h> /* SDIO device core hardware definitions. */ +#include <spid.h> + +#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */ +#include <sdiovar.h> /* ioctl/iovars */ +#include <sdio.h> /* SDIO Device and Protocol Specs */ + +#include <pcicfg.h> + + +#include <bcmspibrcm.h> +#include <bcmspi.h> + +/* these are for the older cores... for newer cores we have control for each of them */ +#define F0_RESPONSE_DELAY 16 +#define F1_RESPONSE_DELAY 16 +#define F2_RESPONSE_DELAY F0_RESPONSE_DELAY + + +#define GSPI_F0_RESP_DELAY 0 +#define GSPI_F1_RESP_DELAY F1_RESPONSE_DELAY +#define GSPI_F2_RESP_DELAY 0 +#define GSPI_F3_RESP_DELAY 0 + +#define CMDLEN 4 + +#define DWORDMODE_ON (sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 2) && (sd->dwordmode == TRUE) + +/* Globals */ +#if defined(DHD_DEBUG) +uint sd_msglevel = SDH_ERROR_VAL; +#else +uint sd_msglevel = 0; +#endif + +uint sd_hiok = FALSE; /* Use hi-speed mode if available? */ +uint sd_sdmode = SDIOH_MODE_SPI; /* Use SD4 mode by default */ +uint sd_f2_blocksize = 64; /* Default blocksize */ + + +uint sd_divisor = 2; +uint sd_power = 1; /* Default to SD Slot powered ON */ +uint sd_clock = 1; /* Default to SD Clock turned ON */ +uint sd_crc = 0; /* Default to SPI CRC Check turned OFF */ +uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */ + +uint8 spi_outbuf[SPI_MAX_PKT_LEN]; +uint8 spi_inbuf[SPI_MAX_PKT_LEN]; + +/* 128bytes buffer is enough to clear data-not-available and program response-delay F0 bits + * assuming we will not exceed F0 response delay > 100 bytes at 48MHz. + */ +#define BUF2_PKT_LEN 128 +uint8 spi_outbuf2[BUF2_PKT_LEN]; +uint8 spi_inbuf2[BUF2_PKT_LEN]; + +#define SPISWAP_WD4(x) bcmswap32(x); +#define SPISWAP_WD2(x) (bcmswap16(x & 0xffff)) | \ + (bcmswap16((x & 0xffff0000) >> 16) << 16); + +/* Prototypes */ +static bool bcmspi_test_card(sdioh_info_t *sd); +static bool bcmspi_host_device_init_adapt(sdioh_info_t *sd); +static int bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode); +static int bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg, + uint32 *data, uint32 datalen); +static int bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, + int regsize, uint32 *data); +static int bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, + int regsize, uint32 data); +static int bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, + uint8 *data); +static int bcmspi_driver_init(sdioh_info_t *sd); +static int bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, + uint32 addr, int nbytes, uint32 *data); +static int bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, + uint32 *data); +static void bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer); +static int bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg); + +/* + * Public entry points & extern's + */ +extern sdioh_info_t * +sdioh_attach(osl_t *osh, void *bar0, uint irq) +{ + sdioh_info_t *sd; + + sd_trace(("%s\n", __FUNCTION__)); + if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { + sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); + return NULL; + } + bzero((char *)sd, sizeof(sdioh_info_t)); + sd->osh = osh; + if (spi_osinit(sd) != 0) { + sd_err(("%s: spi_osinit() failed\n", __FUNCTION__)); + MFREE(sd->osh, sd, sizeof(sdioh_info_t)); + return NULL; + } + + sd->bar0 = bar0; + sd->irq = irq; + sd->intr_handler = NULL; + sd->intr_handler_arg = NULL; + sd->intr_handler_valid = FALSE; + + /* Set defaults */ + sd->use_client_ints = TRUE; + sd->sd_use_dma = FALSE; /* DMA Not supported */ + + /* Spi device default is 16bit mode, change to 4 when device is changed to 32bit + * mode + */ + sd->wordlen = 2; + + + if (!spi_hw_attach(sd)) { + sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__)); + spi_osfree(sd); + MFREE(sd->osh, sd, sizeof(sdioh_info_t)); + return (NULL); + } + + if (bcmspi_driver_init(sd) != SUCCESS) { + sd_err(("%s: bcmspi_driver_init() failed()\n", __FUNCTION__)); + spi_hw_detach(sd); + spi_osfree(sd); + MFREE(sd->osh, sd, sizeof(sdioh_info_t)); + return (NULL); + } + + if (spi_register_irq(sd, irq) != SUCCESS) { + sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq)); + spi_hw_detach(sd); + spi_osfree(sd); + MFREE(sd->osh, sd, sizeof(sdioh_info_t)); + return (NULL); + } + + sd_trace(("%s: Done\n", __FUNCTION__)); + + return sd; +} + +extern SDIOH_API_RC +sdioh_detach(osl_t *osh, sdioh_info_t *sd) +{ + sd_trace(("%s\n", __FUNCTION__)); + if (sd) { + sd_err(("%s: detaching from hardware\n", __FUNCTION__)); + spi_free_irq(sd->irq, sd); + spi_hw_detach(sd); + spi_osfree(sd); + MFREE(sd->osh, sd, sizeof(sdioh_info_t)); + } + return SDIOH_API_RC_SUCCESS; +} + +/* Configure callback to client when we recieve client interrupt */ +extern SDIOH_API_RC +sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) +{ + sd_trace(("%s: Entering\n", __FUNCTION__)); +#if !defined(OOB_INTR_ONLY) + sd->intr_handler = fn; + sd->intr_handler_arg = argh; + sd->intr_handler_valid = TRUE; +#endif /* !defined(OOB_INTR_ONLY) */ + return SDIOH_API_RC_SUCCESS; +} + +extern SDIOH_API_RC +sdioh_interrupt_deregister(sdioh_info_t *sd) +{ + sd_trace(("%s: Entering\n", __FUNCTION__)); +#if !defined(OOB_INTR_ONLY) + sd->intr_handler_valid = FALSE; + sd->intr_handler = NULL; + sd->intr_handler_arg = NULL; +#endif /* !defined(OOB_INTR_ONLY) */ + return SDIOH_API_RC_SUCCESS; +} + +extern SDIOH_API_RC +sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) +{ + sd_trace(("%s: Entering\n", __FUNCTION__)); + *onoff = sd->client_intr_enabled; + return SDIOH_API_RC_SUCCESS; +} + +#if defined(DHD_DEBUG) +extern bool +sdioh_interrupt_pending(sdioh_info_t *sd) +{ + return 0; +} +#endif + +extern SDIOH_API_RC +sdioh_query_device(sdioh_info_t *sd) +{ + /* Return a BRCM ID appropriate to the dongle class */ + return (sd->num_funcs > 1) ? BCM4329_D11N_ID : BCM4318_D11G_ID; +} + +/* Provide dstatus bits of spi-transaction for dhd layers. */ +extern uint32 +sdioh_get_dstatus(sdioh_info_t *sd) +{ + return sd->card_dstatus; +} + +extern void +sdioh_chipinfo(sdioh_info_t *sd, uint32 chip, uint32 chiprev) +{ + sd->chip = chip; + sd->chiprev = chiprev; +} + +extern void +sdioh_dwordmode(sdioh_info_t *sd, bool set) +{ + uint8 reg = 0; + int status; + + if ((status = sdioh_request_byte(sd, SDIOH_READ, SPI_FUNC_0, SPID_STATUS_ENABLE, ®)) != + SUCCESS) { + sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__)); + return; + } + + if (set) { + reg |= DWORD_PKT_LEN_EN; + sd->dwordmode = TRUE; + sd->client_block_size[SPI_FUNC_2] = 4096; /* h2spi's limit is 4KB, we support 8KB */ + } else { + reg &= ~DWORD_PKT_LEN_EN; + sd->dwordmode = FALSE; + sd->client_block_size[SPI_FUNC_2] = 2048; + } + + if ((status = sdioh_request_byte(sd, SDIOH_WRITE, SPI_FUNC_0, SPID_STATUS_ENABLE, ®)) != + SUCCESS) { + sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__)); + return; + } +} + + +uint +sdioh_query_iofnum(sdioh_info_t *sd) +{ + return sd->num_funcs; +} + +/* IOVar table */ +enum { + IOV_MSGLEVEL = 1, + IOV_BLOCKMODE, + IOV_BLOCKSIZE, + IOV_DMA, + IOV_USEINTS, + IOV_NUMINTS, + IOV_NUMLOCALINTS, + IOV_HOSTREG, + IOV_DEVREG, + IOV_DIVISOR, + IOV_SDMODE, + IOV_HISPEED, + IOV_HCIREGS, + IOV_POWER, + IOV_CLOCK, + IOV_SPIERRSTATS, + IOV_RESP_DELAY_ALL +}; + +const bcm_iovar_t sdioh_iovars[] = { + {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, + {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ + {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, + {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, + {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, + {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, + {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, + {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, + {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, + {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, + {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, + {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, + {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}, + {"spi_errstats", IOV_SPIERRSTATS, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) }, + {"spi_respdelay", IOV_RESP_DELAY_ALL, 0, IOVT_BOOL, 0 }, + {NULL, 0, 0, 0, 0 } +}; + +int +sdioh_iovar_op(sdioh_info_t *si, const char *name, + void *params, int plen, void *arg, int len, bool set) +{ + const bcm_iovar_t *vi = NULL; + int bcmerror = 0; + int val_size; + int32 int_val = 0; + bool bool_val; + uint32 actionid; +/* + sdioh_regs_t *regs; +*/ + + ASSERT(name); + ASSERT(len >= 0); + + /* Get must have return space; Set does not take qualifiers */ + ASSERT(set || (arg && len)); + ASSERT(!set || (!params && !plen)); + + sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name)); + + if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { + bcmerror = BCME_UNSUPPORTED; + goto exit; + } + + if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) + goto exit; + + /* Set up params so get and set can share the convenience variables */ + if (params == NULL) { + params = arg; + plen = len; + } + + if (vi->type == IOVT_VOID) + val_size = 0; + else if (vi->type == IOVT_BUFFER) + val_size = len; + else + val_size = sizeof(int); + + if (plen >= (int)sizeof(int_val)) + bcopy(params, &int_val, sizeof(int_val)); + + bool_val = (int_val != 0) ? TRUE : FALSE; + + actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); + switch (actionid) { + case IOV_GVAL(IOV_MSGLEVEL): + int_val = (int32)sd_msglevel; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_MSGLEVEL): + sd_msglevel = int_val; + break; + + case IOV_GVAL(IOV_BLOCKSIZE): + if ((uint32)int_val > si->num_funcs) { + bcmerror = BCME_BADARG; + break; + } + int_val = (int32)si->client_block_size[int_val]; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_GVAL(IOV_DMA): + int_val = (int32)si->sd_use_dma; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_DMA): + si->sd_use_dma = (bool)int_val; + break; + + case IOV_GVAL(IOV_USEINTS): + int_val = (int32)si->use_client_ints; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_USEINTS): + break; + + case IOV_GVAL(IOV_DIVISOR): + int_val = (uint32)sd_divisor; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_DIVISOR): + sd_divisor = int_val; + if (!spi_start_clock(si, (uint16)sd_divisor)) { + sd_err(("%s: set clock failed\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + } + break; + + case IOV_GVAL(IOV_POWER): + int_val = (uint32)sd_power; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_POWER): + sd_power = int_val; + break; + + case IOV_GVAL(IOV_CLOCK): + int_val = (uint32)sd_clock; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_CLOCK): + sd_clock = int_val; + break; + + case IOV_GVAL(IOV_SDMODE): + int_val = (uint32)sd_sdmode; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_SDMODE): + sd_sdmode = int_val; + break; + + case IOV_GVAL(IOV_HISPEED): + int_val = (uint32)sd_hiok; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_HISPEED): + sd_hiok = int_val; + + if (!bcmspi_set_highspeed_mode(si, (bool)sd_hiok)) { + sd_err(("%s: Failed changing highspeed mode to %d.\n", + __FUNCTION__, sd_hiok)); + bcmerror = BCME_ERROR; + return ERROR; + } + break; + + case IOV_GVAL(IOV_NUMINTS): + int_val = (int32)si->intrcount; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_GVAL(IOV_NUMLOCALINTS): + int_val = (int32)si->local_intrcount; + bcopy(&int_val, arg, sizeof(int_val)); + break; + case IOV_GVAL(IOV_DEVREG): + { + sdreg_t *sd_ptr = (sdreg_t *)params; + uint8 data; + + if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { + bcmerror = BCME_SDIO_ERROR; + break; + } + + int_val = (int)data; + bcopy(&int_val, arg, sizeof(int_val)); + break; + } + + case IOV_SVAL(IOV_DEVREG): + { + sdreg_t *sd_ptr = (sdreg_t *)params; + uint8 data = (uint8)sd_ptr->value; + + if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { + bcmerror = BCME_SDIO_ERROR; + break; + } + break; + } + + + case IOV_GVAL(IOV_SPIERRSTATS): + { + bcopy(&si->spierrstats, arg, sizeof(struct spierrstats_t)); + break; + } + + case IOV_SVAL(IOV_SPIERRSTATS): + { + bzero(&si->spierrstats, sizeof(struct spierrstats_t)); + break; + } + + case IOV_GVAL(IOV_RESP_DELAY_ALL): + int_val = (int32)si->resp_delay_all; + bcopy(&int_val, arg, sizeof(int_val)); + break; + + case IOV_SVAL(IOV_RESP_DELAY_ALL): + si->resp_delay_all = (bool)int_val; + int_val = STATUS_ENABLE|INTR_WITH_STATUS; + if (si->resp_delay_all) + int_val |= RESP_DELAY_ALL; + else { + if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_RESPONSE_DELAY, 1, + F1_RESPONSE_DELAY) != SUCCESS) { + sd_err(("%s: Unable to set response delay.\n", __FUNCTION__)); + bcmerror = BCME_SDIO_ERROR; + break; + } + } + + if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, int_val) + != SUCCESS) { + sd_err(("%s: Unable to set response delay.\n", __FUNCTION__)); + bcmerror = BCME_SDIO_ERROR; + break; + } + break; + + default: + bcmerror = BCME_UNSUPPORTED; + break; + } +exit: + + return bcmerror; +} + +extern SDIOH_API_RC +sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) +{ + SDIOH_API_RC status; + /* No lock needed since sdioh_request_byte does locking */ + status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); + return status; +} + +extern SDIOH_API_RC +sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) +{ + /* No lock needed since sdioh_request_byte does locking */ + SDIOH_API_RC status; + + if ((fnc_num == SPI_FUNC_1) && (addr == SBSDIO_FUNC1_FRAMECTRL)) { + uint8 dummy_data; + status = sdioh_cfg_read(sd, fnc_num, addr, &dummy_data); + if (status) { + sd_err(("sdioh_cfg_read() failed.\n")); + return status; + } + } + + status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); + return status; +} + +extern SDIOH_API_RC +sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) +{ + uint32 count; + int offset; + uint32 cis_byte; + uint16 *cis = (uint16 *)cisd; + uint bar0 = SI_ENUM_BASE; + int status; + uint8 data; + + sd_trace(("%s: Func %d\n", __FUNCTION__, func)); + + spi_lock(sd); + + /* Set sb window address to 0x18000000 */ + data = (bar0 >> 8) & SBSDIO_SBADDRLOW_MASK; + status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, &data); + if (status == SUCCESS) { + data = (bar0 >> 16) & SBSDIO_SBADDRMID_MASK; + status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, &data); + } else { + sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__)); + spi_unlock(sd); + return (BCME_ERROR); + } + if (status == SUCCESS) { + data = (bar0 >> 24) & SBSDIO_SBADDRHIGH_MASK; + status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, &data); + } else { + sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__)); + spi_unlock(sd); + return (BCME_ERROR); + } + + offset = CC_SROM_OTP; /* OTP offset in chipcommon. */ + for (count = 0; count < length/2; count++) { + if (bcmspi_card_regread (sd, SDIO_FUNC_1, offset, 2, &cis_byte) < 0) { + sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__)); + spi_unlock(sd); + return (BCME_ERROR); + } + + *cis = (uint16)cis_byte; + cis++; + offset += 2; + } + + spi_unlock(sd); + + return (BCME_OK); +} + +extern SDIOH_API_RC +sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) +{ + int status; + uint32 cmd_arg; + uint32 dstatus; + uint32 data = (uint32)(*byte); + + spi_lock(sd); + + cmd_arg = 0; + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, rw == SDIOH_READ ? 0 : 1); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1); + + if (rw == SDIOH_READ) { + sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x\n", + __FUNCTION__, cmd_arg, func, regaddr)); + } else { + sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x data=0x%x\n", + __FUNCTION__, cmd_arg, func, regaddr, data)); + } + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, 1)) != SUCCESS) { + spi_unlock(sd); + return status; + } + + if (rw == SDIOH_READ) { + *byte = (uint8)data; + sd_trace(("%s: RD result=0x%x\n", __FUNCTION__, *byte)); + } + + bcmspi_cmd_getdstatus(sd, &dstatus); + if (dstatus) + sd_trace(("dstatus=0x%x\n", dstatus)); + + spi_unlock(sd); + return SDIOH_API_RC_SUCCESS; +} + +extern SDIOH_API_RC +sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, + uint32 *word, uint nbytes) +{ + int status; + + spi_lock(sd); + + if (rw == SDIOH_READ) + status = bcmspi_card_regread(sd, func, addr, nbytes, word); + else + status = bcmspi_card_regwrite(sd, func, addr, nbytes, *word); + + spi_unlock(sd); + return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); +} + +extern SDIOH_API_RC +sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func, + uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) +{ + int len; + int buflen = (int)buflen_u; + bool fifo = (fix_inc == SDIOH_DATA_FIX); + + spi_lock(sd); + + ASSERT(reg_width == 4); + ASSERT(buflen_u < (1 << 30)); + ASSERT(sd->client_block_size[func]); + + sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n", + __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W', + buflen_u, sd->r_cnt, sd->t_cnt, pkt)); + + /* Break buffer down into blocksize chunks. */ + while (buflen > 0) { + len = MIN(sd->client_block_size[func], buflen); + if (bcmspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) { + sd_err(("%s: bcmspi_card_buf %s failed\n", + __FUNCTION__, rw == SDIOH_READ ? "Read" : "Write")); + spi_unlock(sd); + return SDIOH_API_RC_FAIL; + } + buffer += len; + buflen -= len; + if (!fifo) + addr += len; + } + spi_unlock(sd); + return SDIOH_API_RC_SUCCESS; +} + +/* This function allows write to gspi bus when another rd/wr function is deep down the call stack. + * Its main aim is to have simpler spi writes rather than recursive writes. + * e.g. When there is a need to program response delay on the fly after detecting the SPI-func + * this call will allow to program the response delay. + */ +static int +bcmspi_card_byterewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 byte) +{ + uint32 cmd_arg; + uint32 datalen = 1; + uint32 hostlen; + + cmd_arg = 0; + + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, datalen); + + sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); + + + /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen + * according to the wordlen mode(16/32bit) the device is in. + */ + ASSERT(sd->wordlen == 4 || sd->wordlen == 2); + datalen = ROUNDUP(datalen, sd->wordlen); + + /* Start by copying command in the spi-outbuffer */ + if (sd->wordlen == 4) { /* 32bit spid */ + *(uint32 *)spi_outbuf2 = SPISWAP_WD4(cmd_arg); + if (datalen & 0x3) + datalen += (4 - (datalen & 0x3)); + } else if (sd->wordlen == 2) { /* 16bit spid */ + *(uint32 *)spi_outbuf2 = SPISWAP_WD2(cmd_arg); + if (datalen & 0x1) + datalen++; + } else { + sd_err(("%s: Host is %d bit spid, could not create SPI command.\n", + __FUNCTION__, 8 * sd->wordlen)); + return ERROR; + } + + /* for Write, put the data into the output buffer */ + if (datalen != 0) { + if (sd->wordlen == 4) { /* 32bit spid */ + *(uint32 *)&spi_outbuf2[CMDLEN] = SPISWAP_WD4(byte); + } else if (sd->wordlen == 2) { /* 16bit spid */ + *(uint32 *)&spi_outbuf2[CMDLEN] = SPISWAP_WD2(byte); + } + } + + /* +4 for cmd, +4 for dstatus */ + hostlen = datalen + 8; + hostlen += (4 - (hostlen & 0x3)); + spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, hostlen); + + /* Last 4bytes are dstatus. Device is configured to return status bits. */ + if (sd->wordlen == 4) { /* 32bit spid */ + sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); + } else if (sd->wordlen == 2) { /* 16bit spid */ + sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); + } else { + sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n", + __FUNCTION__, 8 * sd->wordlen)); + return ERROR; + } + + if (sd->card_dstatus) + sd_trace(("dstatus after byte rewrite = 0x%x\n", sd->card_dstatus)); + + return (BCME_OK); +} + +/* Program the response delay corresponding to the spi function */ +static int +bcmspi_prog_resp_delay(sdioh_info_t *sd, int func, uint8 resp_delay) +{ + if (sd->resp_delay_all == FALSE) + return (BCME_OK); + + if (sd->prev_fun == func) + return (BCME_OK); + + if (F0_RESPONSE_DELAY == F1_RESPONSE_DELAY) + return (BCME_OK); + + bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_RESPONSE_DELAY, resp_delay); + + /* Remember function for which to avoid reprogramming resp-delay in next iteration */ + sd->prev_fun = func; + + return (BCME_OK); + +} + +#define GSPI_RESYNC_PATTERN 0x0 + +/* A resync pattern is a 32bit MOSI line with all zeros. Its a special command in gSPI. + * It resets the spi-bkplane logic so that all F1 related ping-pong buffer logic is + * synchronised and all queued resuests are cancelled. + */ +static int +bcmspi_resync_f1(sdioh_info_t *sd) +{ + uint32 cmd_arg = GSPI_RESYNC_PATTERN, data = 0, datalen = 0; + + + /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen + * according to the wordlen mode(16/32bit) the device is in. + */ + ASSERT(sd->wordlen == 4 || sd->wordlen == 2); + datalen = ROUNDUP(datalen, sd->wordlen); + + /* Start by copying command in the spi-outbuffer */ + *(uint32 *)spi_outbuf2 = cmd_arg; + + /* for Write, put the data into the output buffer */ + *(uint32 *)&spi_outbuf2[CMDLEN] = data; + + /* +4 for cmd, +4 for dstatus */ + spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, datalen + 8); + + /* Last 4bytes are dstatus. Device is configured to return status bits. */ + if (sd->wordlen == 4) { /* 32bit spid */ + sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); + } else if (sd->wordlen == 2) { /* 16bit spid */ + sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]); + } else { + sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n", + __FUNCTION__, 8 * sd->wordlen)); + return ERROR; + } + + if (sd->card_dstatus) + sd_trace(("dstatus after resync pattern write = 0x%x\n", sd->card_dstatus)); + + return (BCME_OK); +} + +uint32 dstatus_count = 0; + +static int +bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg) +{ + uint32 dstatus = sd->card_dstatus; + struct spierrstats_t *spierrstats = &sd->spierrstats; + int err = SUCCESS; + + sd_trace(("cmd = 0x%x, dstatus = 0x%x\n", cmd_arg, dstatus)); + + /* Store dstatus of last few gSPI transactions */ + spierrstats->dstatus[dstatus_count % NUM_PREV_TRANSACTIONS] = dstatus; + spierrstats->spicmd[dstatus_count % NUM_PREV_TRANSACTIONS] = cmd_arg; + dstatus_count++; + + if (sd->card_init_done == FALSE) + return err; + + if (dstatus & STATUS_DATA_NOT_AVAILABLE) { + spierrstats->dna++; + sd_trace(("Read data not available on F1 addr = 0x%x\n", + GFIELD(cmd_arg, SPI_REG_ADDR))); + /* Clear dna bit */ + bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, DATA_UNAVAILABLE); + } + + if (dstatus & STATUS_UNDERFLOW) { + spierrstats->rdunderflow++; + sd_err(("FIFO underflow happened due to current F2 read command.\n")); + } + + if (dstatus & STATUS_OVERFLOW) { + spierrstats->wroverflow++; + sd_err(("FIFO overflow happened due to current (F1/F2) write command.\n")); + bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, F1_OVERFLOW); + bcmspi_resync_f1(sd); + sd_err(("Recovering from F1 FIFO overflow.\n")); + } + + if (dstatus & STATUS_F2_INTR) { + spierrstats->f2interrupt++; + sd_trace(("Interrupt from F2. SW should clear corresponding IntStatus bits\n")); + } + + if (dstatus & STATUS_F3_INTR) { + spierrstats->f3interrupt++; + sd_err(("Interrupt from F3. SW should clear corresponding IntStatus bits\n")); + } + + if (dstatus & STATUS_HOST_CMD_DATA_ERR) { + spierrstats->hostcmddataerr++; + sd_err(("Error in CMD or Host data, detected by CRC/Checksum (optional)\n")); + } + + if (dstatus & STATUS_F2_PKT_AVAILABLE) { + spierrstats->f2pktavailable++; + sd_trace(("Packet is available/ready in F2 TX FIFO\n")); + sd_trace(("Packet length = %d\n", sd->dwordmode ? + ((dstatus & STATUS_F2_PKT_LEN_MASK) >> (STATUS_F2_PKT_LEN_SHIFT - 2)) : + ((dstatus & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT))); + } + + if (dstatus & STATUS_F3_PKT_AVAILABLE) { + spierrstats->f3pktavailable++; + sd_err(("Packet is available/ready in F3 TX FIFO\n")); + sd_err(("Packet length = %d\n", + (dstatus & STATUS_F3_PKT_LEN_MASK) >> STATUS_F3_PKT_LEN_SHIFT)); + } + + return err; +} + +extern int +sdioh_abort(sdioh_info_t *sd, uint func) +{ + return 0; +} + +int +sdioh_start(sdioh_info_t *sd, int stage) +{ + return SUCCESS; +} + +int +sdioh_stop(sdioh_info_t *sd) +{ + return SUCCESS; +} + +int +sdioh_waitlockfree(sdioh_info_t *sd) +{ + return SUCCESS; +} + + +/* + * Private/Static work routines + */ +static int +bcmspi_host_init(sdioh_info_t *sd) +{ + + /* Default power on mode */ + sd->sd_mode = SDIOH_MODE_SPI; + sd->polled_mode = TRUE; + sd->host_init_done = TRUE; + sd->card_init_done = FALSE; + sd->adapter_slot = 1; + + return (SUCCESS); +} + +static int +get_client_blocksize(sdioh_info_t *sd) +{ + uint32 regdata[2]; + int status; + + /* Find F1/F2/F3 max packet size */ + if ((status = bcmspi_card_regread(sd, 0, SPID_F1_INFO_REG, + 8, regdata)) != SUCCESS) { + return status; + } + + sd_trace(("pkt_size regdata[0] = 0x%x, regdata[1] = 0x%x\n", + regdata[0], regdata[1])); + + sd->client_block_size[1] = (regdata[0] & F1_MAX_PKT_SIZE) >> 2; + sd_trace(("Func1 blocksize = %d\n", sd->client_block_size[1])); + ASSERT(sd->client_block_size[1] == BLOCK_SIZE_F1); + + sd->client_block_size[2] = ((regdata[0] >> 16) & F2_MAX_PKT_SIZE) >> 2; + sd_trace(("Func2 blocksize = %d\n", sd->client_block_size[2])); + ASSERT(sd->client_block_size[2] == BLOCK_SIZE_F2); + + sd->client_block_size[3] = (regdata[1] & F3_MAX_PKT_SIZE) >> 2; + sd_trace(("Func3 blocksize = %d\n", sd->client_block_size[3])); + ASSERT(sd->client_block_size[3] == BLOCK_SIZE_F3); + + return 0; +} + +static int +bcmspi_client_init(sdioh_info_t *sd) +{ + uint32 status_en_reg = 0; + sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot)); + +#ifdef HSMODE + if (!spi_start_clock(sd, (uint16)sd_divisor)) { + sd_err(("spi_start_clock failed\n")); + return ERROR; + } +#else + /* Start at ~400KHz clock rate for initialization */ + if (!spi_start_clock(sd, 128)) { + sd_err(("spi_start_clock failed\n")); + return ERROR; + } +#endif /* HSMODE */ + + if (!bcmspi_host_device_init_adapt(sd)) { + sd_err(("bcmspi_host_device_init_adapt failed\n")); + return ERROR; + } + + if (!bcmspi_test_card(sd)) { + sd_err(("bcmspi_test_card failed\n")); + return ERROR; + } + + sd->num_funcs = SPI_MAX_IOFUNCS; + + get_client_blocksize(sd); + + /* Apply resync pattern cmd with all zeros to reset spi-bkplane F1 logic */ + bcmspi_resync_f1(sd); + + sd->dwordmode = FALSE; + + bcmspi_card_regread(sd, 0, SPID_STATUS_ENABLE, 1, &status_en_reg); + + sd_trace(("%s: Enabling interrupt with dstatus \n", __FUNCTION__)); + status_en_reg |= INTR_WITH_STATUS; + + if (bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, + status_en_reg & 0xff) != SUCCESS) { + sd_err(("%s: Unable to set response delay for all fun's.\n", __FUNCTION__)); + return ERROR; + } + +#ifndef HSMODE + /* After configuring for High-Speed mode, set the desired clock rate. */ + if (!spi_start_clock(sd, 4)) { + sd_err(("spi_start_clock failed\n")); + return ERROR; + } +#endif /* HSMODE */ + + /* check to see if the response delay needs to be programmed properly */ + { + uint32 f1_respdelay = 0; + bcmspi_card_regread(sd, 0, SPID_RESP_DELAY_F1, 1, &f1_respdelay); + if ((f1_respdelay == 0) || (f1_respdelay == 0xFF)) { + /* older sdiodevice core and has no separte resp delay for each of */ + sd_err(("older corerev < 4 so use the same resp delay for all funcs\n")); + sd->resp_delay_new = FALSE; + } + else { + /* older sdiodevice core and has no separte resp delay for each of */ + int ret_val; + sd->resp_delay_new = TRUE; + sd_err(("new corerev >= 4 so set the resp delay for each of the funcs\n")); + sd_trace(("resp delay for funcs f0(%d), f1(%d), f2(%d), f3(%d)\n", + GSPI_F0_RESP_DELAY, GSPI_F1_RESP_DELAY, + GSPI_F2_RESP_DELAY, GSPI_F3_RESP_DELAY)); + ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F0, 1, + GSPI_F0_RESP_DELAY); + if (ret_val != SUCCESS) { + sd_err(("%s: Unable to set response delay for F0\n", __FUNCTION__)); + return ERROR; + } + ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F1, 1, + GSPI_F1_RESP_DELAY); + if (ret_val != SUCCESS) { + sd_err(("%s: Unable to set response delay for F1\n", __FUNCTION__)); + return ERROR; + } + ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F2, 1, + GSPI_F2_RESP_DELAY); + if (ret_val != SUCCESS) { + sd_err(("%s: Unable to set response delay for F2\n", __FUNCTION__)); + return ERROR; + } + ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F3, 1, + GSPI_F3_RESP_DELAY); + if (ret_val != SUCCESS) { + sd_err(("%s: Unable to set response delay for F2\n", __FUNCTION__)); + return ERROR; + } + } + } + + + sd->card_init_done = TRUE; + + /* get the device rev to program the prop respdelays */ + + return SUCCESS; +} + +static int +bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode) +{ + uint32 regdata; + int status; + + if ((status = bcmspi_card_regread(sd, 0, SPID_CONFIG, + 4, ®data)) != SUCCESS) + return status; + + sd_trace(("In %s spih-ctrl = 0x%x \n", __FUNCTION__, regdata)); + + + if (hsmode == TRUE) { + sd_trace(("Attempting to enable High-Speed mode.\n")); + + if (regdata & HIGH_SPEED_MODE) { + sd_trace(("Device is already in High-Speed mode.\n")); + return status; + } else { + regdata |= HIGH_SPEED_MODE; + sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG)); + if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG, + 4, regdata)) != SUCCESS) { + return status; + } + } + } else { + sd_trace(("Attempting to disable High-Speed mode.\n")); + + if (regdata & HIGH_SPEED_MODE) { + regdata &= ~HIGH_SPEED_MODE; + sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG)); + if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG, + 4, regdata)) != SUCCESS) + return status; + } + else { + sd_trace(("Device is already in Low-Speed mode.\n")); + return status; + } + } + spi_controller_highspeed_mode(sd, hsmode); + + return TRUE; +} + +#define bcmspi_find_curr_mode(sd) { \ + sd->wordlen = 2; \ + status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, ®data); \ + regdata &= 0xff; \ + if ((regdata == 0xad) || (regdata == 0x5b) || \ + (regdata == 0x5d) || (regdata == 0x5a)) \ + break; \ + sd->wordlen = 4; \ + status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, ®data); \ + regdata &= 0xff; \ + if ((regdata == 0xad) || (regdata == 0x5b) || \ + (regdata == 0x5d) || (regdata == 0x5a)) \ + break; \ + sd_trace(("Silicon testability issue: regdata = 0x%x." \ + " Expected 0xad, 0x5a, 0x5b or 0x5d.\n", regdata)); \ + OSL_DELAY(100000); \ +} + +#define INIT_ADAPT_LOOP 100 + +/* Adapt clock-phase-speed-bitwidth between host and device */ +static bool +bcmspi_host_device_init_adapt(sdioh_info_t *sd) +{ + uint32 wrregdata, regdata = 0; + int status; + int i; + + /* Due to a silicon testability issue, the first command from the Host + * to the device will get corrupted (first bit will be lost). So the + * Host should poll the device with a safe read request. ie: The Host + * should try to read F0 addr 0x14 using the Fixed address mode + * (This will prevent a unintended write command to be detected by device) + */ + for (i = 0; i < INIT_ADAPT_LOOP; i++) { + /* If device was not power-cycled it will stay in 32bit mode with + * response-delay-all bit set. Alternate the iteration so that + * read either with or without response-delay for F0 to succeed. + */ + bcmspi_find_curr_mode(sd); + sd->resp_delay_all = (i & 0x1) ? TRUE : FALSE; + + bcmspi_find_curr_mode(sd); + sd->dwordmode = TRUE; + + bcmspi_find_curr_mode(sd); + sd->dwordmode = FALSE; + } + + /* Bail out, device not detected */ + if (i == INIT_ADAPT_LOOP) + return FALSE; + + /* Softreset the spid logic */ + if ((sd->dwordmode) || (sd->wordlen == 4)) { + bcmspi_card_regwrite(sd, 0, SPID_RESET_BP, 1, RESET_ON_WLAN_BP_RESET|RESET_SPI); + bcmspi_card_regread(sd, 0, SPID_RESET_BP, 1, ®data); + sd_trace(("reset reg read = 0x%x\n", regdata)); + sd_trace(("dwordmode = %d, wordlen = %d, resp_delay_all = %d\n", sd->dwordmode, + sd->wordlen, sd->resp_delay_all)); + /* Restore default state after softreset */ + sd->wordlen = 2; + sd->dwordmode = FALSE; + } + + if (sd->wordlen == 4) { + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != + SUCCESS) + return FALSE; + if (regdata == TEST_RO_DATA_32BIT_LE) { + sd_trace(("Spid is already in 32bit LE mode. Value read = 0x%x\n", + regdata)); + sd_trace(("Spid power was left on.\n")); + } else { + sd_err(("Spid power was left on but signature read failed." + " Value read = 0x%x\n", regdata)); + return FALSE; + } + } else { + sd->wordlen = 2; + +#define CTRL_REG_DEFAULT 0x00010430 /* according to the host m/c */ + + wrregdata = (CTRL_REG_DEFAULT); + + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) + return FALSE; + sd_trace(("(we are still in 16bit mode) 32bit READ LE regdata = 0x%x\n", regdata)); + +#ifndef HSMODE + wrregdata |= (CLOCK_PHASE | CLOCK_POLARITY); + wrregdata &= ~HIGH_SPEED_MODE; + bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata); +#endif /* HSMODE */ + + for (i = 0; i < INIT_ADAPT_LOOP; i++) { + if ((regdata == 0xfdda7d5b) || (regdata == 0xfdda7d5a)) { + sd_trace(("0xfeedbead was leftshifted by 1-bit.\n")); + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, + ®data)) != SUCCESS) + return FALSE; + } + OSL_DELAY(1000); + } + + /* Change to host controller intr-polarity of active-low */ + wrregdata &= ~INTR_POLARITY; + sd_trace(("(we are still in 16bit mode) 32bit Write LE reg-ctrl-data = 0x%x\n", + wrregdata)); + /* Change to 32bit mode */ + wrregdata |= WORD_LENGTH_32; + bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata); + + /* Change command/data packaging in 32bit LE mode */ + sd->wordlen = 4; + + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) + return FALSE; + + if (regdata == TEST_RO_DATA_32BIT_LE) { + sd_trace(("Read spid passed. Value read = 0x%x\n", regdata)); + sd_trace(("Spid had power-on cycle OR spi was soft-resetted \n")); + } else { + sd_err(("Stale spid reg values read as it was kept powered. Value read =" + "0x%x\n", regdata)); + return FALSE; + } + } + + + return TRUE; +} + +static bool +bcmspi_test_card(sdioh_info_t *sd) +{ + uint32 regdata; + int status; + + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, ®data)) != SUCCESS) + return FALSE; + + if (regdata == (TEST_RO_DATA_32BIT_LE)) + sd_trace(("32bit LE regdata = 0x%x\n", regdata)); + else { + sd_trace(("Incorrect 32bit LE regdata = 0x%x\n", regdata)); + return FALSE; + } + + +#define RW_PATTERN1 0xA0A1A2A3 +#define RW_PATTERN2 0x4B5B6B7B + + regdata = RW_PATTERN1; + if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS) + return FALSE; + regdata = 0; + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, ®data)) != SUCCESS) + return FALSE; + if (regdata != RW_PATTERN1) { + sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n", + RW_PATTERN1, regdata)); + return FALSE; + } else + sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata)); + + regdata = RW_PATTERN2; + if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS) + return FALSE; + regdata = 0; + if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, ®data)) != SUCCESS) + return FALSE; + if (regdata != RW_PATTERN2) { + sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n", + RW_PATTERN2, regdata)); + return FALSE; + } else + sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata)); + + return TRUE; +} + +static int +bcmspi_driver_init(sdioh_info_t *sd) +{ + sd_trace(("%s\n", __FUNCTION__)); + if ((bcmspi_host_init(sd)) != SUCCESS) { + return ERROR; + } + + if (bcmspi_client_init(sd) != SUCCESS) { + return ERROR; + } + + return SUCCESS; +} + +/* Read device reg */ +static int +bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) +{ + int status; + uint32 cmd_arg, dstatus; + + ASSERT(regsize); + + if (func == 2) + sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n")); + + cmd_arg = 0; + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize); + + sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d\n", + __FUNCTION__, cmd_arg, func, regaddr, regsize)); + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) != SUCCESS) + return status; + + bcmspi_cmd_getdstatus(sd, &dstatus); + if (dstatus) + sd_trace(("dstatus =0x%x\n", dstatus)); + + return SUCCESS; +} + +static int +bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) +{ + + int status; + uint32 cmd_arg; + uint32 dstatus; + + ASSERT(regsize); + + if (func == 2) + sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n")); + + cmd_arg = 0; + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0); /* Fixed access */ + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize); + + sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d\n", + __FUNCTION__, cmd_arg, func, regaddr, regsize)); + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) != SUCCESS) + return status; + + sd_trace(("%s: RD result=0x%x\n", __FUNCTION__, *data)); + + bcmspi_cmd_getdstatus(sd, &dstatus); + sd_trace(("dstatus =0x%x\n", dstatus)); + return SUCCESS; +} + +/* write a device register */ +static int +bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) +{ + int status; + uint32 cmd_arg, dstatus; + + ASSERT(regsize); + + cmd_arg = 0; + + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize); + + sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d data=0x%x\n", + __FUNCTION__, cmd_arg, func, regaddr, regsize, data)); + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, regsize)) != SUCCESS) + return status; + + bcmspi_cmd_getdstatus(sd, &dstatus); + if (dstatus) + sd_trace(("dstatus=0x%x\n", dstatus)); + + return SUCCESS; +} + +/* write a device register - 1 byte */ +static int +bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 *byte) +{ + int status; + uint32 cmd_arg; + uint32 dstatus; + uint32 data = (uint32)(*byte); + + cmd_arg = 0; + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */ + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr); + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1); + + sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x data=0x%x\n", + __FUNCTION__, cmd_arg, func, regaddr, data)); + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, 1)) != SUCCESS) + return status; + + bcmspi_cmd_getdstatus(sd, &dstatus); + if (dstatus) + sd_trace(("dstatus =0x%x\n", dstatus)); + + return SUCCESS; +} + +void +bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer) +{ + *dstatus_buffer = sd->card_dstatus; +} + +/* 'data' is of type uint32 whereas other buffers are of type uint8 */ +static int +bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg, + uint32 *data, uint32 datalen) +{ + uint32 i, j; + uint8 resp_delay = 0; + int err = SUCCESS; + uint32 hostlen; + uint32 spilen = 0; + uint32 dstatus_idx = 0; + uint16 templen, buslen, len, *ptr = NULL; + + sd_trace(("spi cmd = 0x%x\n", cmd_arg)); + + if (DWORDMODE_ON) { + spilen = GFIELD(cmd_arg, SPI_LEN); + if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_0) || + (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_1)) + dstatus_idx = spilen * 3; + + if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) && + (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) { + spilen = spilen << 2; + dstatus_idx = (spilen % 16) ? (16 - (spilen % 16)) : 0; + /* convert len to mod16 size */ + spilen = ROUNDUP(spilen, 16); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2)); + } + } + + /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen + * according to the wordlen mode(16/32bit) the device is in. + */ + if (sd->wordlen == 4) { /* 32bit spid */ + *(uint32 *)spi_outbuf = SPISWAP_WD4(cmd_arg); + if (datalen & 0x3) + datalen += (4 - (datalen & 0x3)); + } else if (sd->wordlen == 2) { /* 16bit spid */ + *(uint32 *)spi_outbuf = SPISWAP_WD2(cmd_arg); + if (datalen & 0x1) + datalen++; + if (datalen < 4) + datalen = ROUNDUP(datalen, 4); + } else { + sd_err(("Host is %d bit spid, could not create SPI command.\n", + 8 * sd->wordlen)); + return ERROR; + } + + /* for Write, put the data into the output buffer */ + if (GFIELD(cmd_arg, SPI_RW_FLAG) == 1) { + /* We send len field of hw-header always a mod16 size, both from host and dongle */ + if (DWORDMODE_ON) { + if (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) { + ptr = (uint16 *)&data[0]; + templen = *ptr; + /* ASSERT(*ptr == ~*(ptr + 1)); */ + templen = ROUNDUP(templen, 16); + *ptr = templen; + sd_trace(("actual tx len = %d\n", (uint16)(~*(ptr+1)))); + } + } + + if (datalen != 0) { + for (i = 0; i < datalen/4; i++) { + if (sd->wordlen == 4) { /* 32bit spid */ + *(uint32 *)&spi_outbuf[i * 4 + CMDLEN] = + SPISWAP_WD4(data[i]); + } else if (sd->wordlen == 2) { /* 16bit spid */ + *(uint32 *)&spi_outbuf[i * 4 + CMDLEN] = + SPISWAP_WD2(data[i]); + } + } + } + } + + /* Append resp-delay number of bytes and clock them out for F0/1/2 reads. */ + if ((GFIELD(cmd_arg, SPI_RW_FLAG) == 0)) { + int func = GFIELD(cmd_arg, SPI_FUNCTION); + switch (func) { + case 0: + if (sd->resp_delay_new) + resp_delay = GSPI_F0_RESP_DELAY; + else + resp_delay = sd->resp_delay_all ? F0_RESPONSE_DELAY : 0; + break; + case 1: + if (sd->resp_delay_new) + resp_delay = GSPI_F1_RESP_DELAY; + else + resp_delay = F1_RESPONSE_DELAY; + break; + case 2: + if (sd->resp_delay_new) + resp_delay = GSPI_F2_RESP_DELAY; + else + resp_delay = sd->resp_delay_all ? F2_RESPONSE_DELAY : 0; + break; + default: + ASSERT(0); + break; + } + /* Program response delay */ + if (sd->resp_delay_new == FALSE) + bcmspi_prog_resp_delay(sd, func, resp_delay); + } + + /* +4 for cmd and +4 for dstatus */ + hostlen = datalen + 8 + resp_delay; + hostlen += dstatus_idx; + hostlen += (4 - (hostlen & 0x3)); + spi_sendrecv(sd, spi_outbuf, spi_inbuf, hostlen); + + /* for Read, get the data into the input buffer */ + if (datalen != 0) { + if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) { /* if read cmd */ + for (j = 0; j < datalen/4; j++) { + if (sd->wordlen == 4) { /* 32bit spid */ + data[j] = SPISWAP_WD4(*(uint32 *)&spi_inbuf[j * 4 + + CMDLEN + resp_delay]); + } else if (sd->wordlen == 2) { /* 16bit spid */ + data[j] = SPISWAP_WD2(*(uint32 *)&spi_inbuf[j * 4 + + CMDLEN + resp_delay]); + } + } + + if ((DWORDMODE_ON) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) { + ptr = (uint16 *)&data[0]; + templen = *ptr; + buslen = len = ~(*(ptr + 1)); + buslen = ROUNDUP(buslen, 16); + /* populate actual len in hw-header */ + if (templen == buslen) + *ptr = len; + } + } + } + + /* Restore back the len field of the hw header */ + if (DWORDMODE_ON) { + if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) && + (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) { + ptr = (uint16 *)&data[0]; + *ptr = (uint16)(~*(ptr+1)); + } + } + + dstatus_idx += (datalen + CMDLEN + resp_delay); + /* Last 4bytes are dstatus. Device is configured to return status bits. */ + if (sd->wordlen == 4) { /* 32bit spid */ + sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf[dstatus_idx]); + } else if (sd->wordlen == 2) { /* 16bit spid */ + sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf[dstatus_idx]); + } else { + sd_err(("Host is %d bit machine, could not read SPI dstatus.\n", + 8 * sd->wordlen)); + return ERROR; + } + if (sd->card_dstatus == 0xffffffff) { + sd_err(("looks like not a GSPI device or device is not powered.\n")); + } + + err = bcmspi_update_stats(sd, cmd_arg); + + return err; + +} + +static int +bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, + uint32 addr, int nbytes, uint32 *data) +{ + int status; + uint32 cmd_arg; + bool write = rw == SDIOH_READ ? 0 : 1; + uint retries = 0; + + bool enable; + uint32 spilen; + + cmd_arg = 0; + + ASSERT(nbytes); + ASSERT(nbytes <= sd->client_block_size[func]); + + if (write) sd->t_cnt++; else sd->r_cnt++; + + if (func == 2) { + /* Frame len check limited by gSPI. */ + if ((nbytes > 2000) && write) { + sd_trace((">2KB write: F2 wr of %d bytes\n", nbytes)); + } + /* ASSERT(nbytes <= 2048); Fix bigger len gspi issue and uncomment. */ + /* If F2 fifo on device is not ready to receive data, don't do F2 transfer */ + if (write) { + uint32 dstatus; + /* check F2 ready with cached one */ + bcmspi_cmd_getdstatus(sd, &dstatus); + if ((dstatus & STATUS_F2_RX_READY) == 0) { + retries = WAIT_F2RXFIFORDY; + enable = 0; + while (retries-- && !enable) { + OSL_DELAY(WAIT_F2RXFIFORDY_DELAY * 1000); + bcmspi_card_regread(sd, SPI_FUNC_0, SPID_STATUS_REG, 4, + &dstatus); + if (dstatus & STATUS_F2_RX_READY) + enable = TRUE; + } + if (!enable) { + struct spierrstats_t *spierrstats = &sd->spierrstats; + spierrstats->f2rxnotready++; + sd_err(("F2 FIFO is not ready to receive data.\n")); + return ERROR; + } + sd_trace(("No of retries on F2 ready %d\n", + (WAIT_F2RXFIFORDY - retries))); + } + } + } + + /* F2 transfers happen on 0 addr */ + addr = (func == 2) ? 0 : addr; + + /* In pio mode buffer is read using fixed address fifo in func 1 */ + if ((func == 1) && (fifo)) + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0); + else + cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); + + cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func); + cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, addr); + cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, write); + spilen = sd->data_xfer_count = MIN(sd->client_block_size[func], nbytes); + if ((sd->dwordmode == TRUE) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) { + /* convert len to mod4 size */ + spilen = spilen + ((spilen & 0x3) ? (4 - (spilen & 0x3)): 0); + cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2)); + } else + cmd_arg = SFIELD(cmd_arg, SPI_LEN, spilen); + + if ((func == 2) && (fifo == 1)) { + sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", + __FUNCTION__, write ? "Wr" : "Rd", func, "INCR", + addr, nbytes, sd->r_cnt, sd->t_cnt)); + } + + sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg)); + sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n", + __FUNCTION__, write ? "Wd" : "Rd", func, "INCR", + addr, nbytes, sd->r_cnt, sd->t_cnt)); + + + if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, nbytes)) != SUCCESS) { + sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, + (write ? "write" : "read"))); + return status; + } + + /* gSPI expects that hw-header-len is equal to spi-command-len */ + if ((func == 2) && (rw == SDIOH_WRITE) && (sd->dwordmode == FALSE)) { + ASSERT((uint16)sd->data_xfer_count == (uint16)(*data & 0xffff)); + ASSERT((uint16)sd->data_xfer_count == (uint16)(~((*data & 0xffff0000) >> 16))); + } + + if ((nbytes > 2000) && !write) { + sd_trace((">2KB read: F2 rd of %d bytes\n", nbytes)); + } + + return SUCCESS; +} + +/* Reset and re-initialize the device */ +int +sdioh_sdio_reset(sdioh_info_t *si) +{ + si->card_init_done = FALSE; + return bcmspi_client_init(si); +} + +SDIOH_API_RC +sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio) +{ + return SDIOH_API_RC_FAIL; +} + +SDIOH_API_RC +sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab) +{ + return SDIOH_API_RC_FAIL; +} + +bool +sdioh_gpioin(sdioh_info_t *sd, uint32 gpio) +{ + return FALSE; +} + +SDIOH_API_RC +sdioh_gpio_init(sdioh_info_t *sd) +{ + return SDIOH_API_RC_FAIL; +} diff --git a/drivers/net/wireless/bcmdhd/bcmutils.c b/drivers/net/wireless/bcmdhd/bcmutils.c index 1cd880d7866226e5e6f18ea1accd895138ffd178..dfa7a4356be279a896814a54a8324a51da6066ef 100644 --- a/drivers/net/wireless/bcmdhd/bcmutils.c +++ b/drivers/net/wireless/bcmdhd/bcmutils.c @@ -1,8 +1,26 @@ /* * Driver O/S-independent utility routines * - * $Copyright Open Broadcom Corporation$ - * $Id: bcmutils.c 488316 2014-06-30 15:22:21Z $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * $Id: bcmutils.c 473326 2014-04-29 00:37:35Z $ */ #include <bcm_cfg.h> @@ -13,6 +31,10 @@ #include <osl.h> #include <bcmutils.h> +#if defined(BCMNVRAM) +#include <siutils.h> +#include <bcmnvram.h> +#endif #else /* !BCMDRIVER */ @@ -42,22 +64,6 @@ void *_bcmutils_dummy_fn = NULL; -#ifdef CUSTOM_DSCP_TO_PRIO_MAPPING -#define CUST_IPV4_TOS_PREC_MASK 0x3F -#define DCSP_MAX_VALUE 64 -/* 0:BE,1:BK,2:RESV(BK):,3:EE,:4:CL,5:VI,6:VO,7:NC */ -int dscp2priomap[DCSP_MAX_VALUE]= -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* BK->BE */ - 2, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0 -}; -#endif /* CUSTOM_DSCP_TO_PRIO_MAPPING */ #ifdef BCMDRIVER @@ -815,12 +821,7 @@ pktsetprio(void *pkt, bool update_vtag) priority = PRIO_8021D_EE; break; default: -#ifndef CUSTOM_DSCP_TO_PRIO_MAPPING priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -#else - priority = (int)dscp2priomap[((tos_tc >> IPV4_TOS_DSCP_SHIFT) - & CUST_IPV4_TOS_PREC_MASK)]; -#endif break; } @@ -1526,7 +1527,6 @@ bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) return (int)(p - buf); } -#endif /* print bytes formatted as hex to a string. return the resulting string length */ int @@ -1542,6 +1542,7 @@ bcm_format_hex(char *str, const void *bytes, int len) } return (int)(p - str); } +#endif /* pretty hex print a contiguous buffer */ void @@ -1588,17 +1589,10 @@ static const char *crypto_algo_names[] = { "AES_CCM", "AES_OCB_MSDU", "AES_OCB_MPDU", -#ifdef BCMCCX - "CKIP", - "CKIP_MMH", - "WEP_MMH", - "NALG", -#else "NALG", "UNDEF", "UNDEF", "UNDEF", -#endif /* BCMCCX */ "WAPI", "PMK", "BIP", diff --git a/drivers/net/wireless/bcmdhd/bcmwifi_channels.c b/drivers/net/wireless/bcmdhd/bcmwifi_channels.c index 4a848d2674de14626b8f84c2b08537be0a139510..8655937f632a5f56527560853fcaad370af87123 100644 --- a/drivers/net/wireless/bcmdhd/bcmwifi_channels.c +++ b/drivers/net/wireless/bcmdhd/bcmwifi_channels.c @@ -3,7 +3,25 @@ * Contents are wifi-specific, used by any kernel or app-level * software that might want wifi things as it grows. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * $Id: bcmwifi_channels.c 309193 2012-01-19 00:03:57Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h b/drivers/net/wireless/bcmdhd/bcmwifi_channels.h similarity index 94% rename from drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h rename to drivers/net/wireless/bcmdhd/bcmwifi_channels.h index b96aee6e1f8e95b595aff5070bfde33e1f95f0d9..b3a446e4b5748f8d2dd4d9fe74cfb600d1b03ef8 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h +++ b/drivers/net/wireless/bcmdhd/bcmwifi_channels.h @@ -3,7 +3,25 @@ * This header file housing the define and function prototype use by * both the wl driver, tools & Apps. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h b/drivers/net/wireless/bcmdhd/bcmwifi_rates.h similarity index 91% rename from drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h rename to drivers/net/wireless/bcmdhd/bcmwifi_rates.h index cf5f88d78cf7034394b817e44d8a938c53ca2007..f8983a101a11e6d3bc40b90afe32d1382e51b9b1 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h +++ b/drivers/net/wireless/bcmdhd/bcmwifi_rates.h @@ -1,7 +1,25 @@ /* * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmwifi_rates.h 5187 2012-06-29 06:17:50Z $ */ diff --git a/drivers/net/wireless/bcmdhd/circularbuf.c b/drivers/net/wireless/bcmdhd/circularbuf.c deleted file mode 100644 index bfb308c34f05d7826ea701b41c1d4c71f5a82872..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/circularbuf.c +++ /dev/null @@ -1,324 +0,0 @@ -/** @file circularbuf.c - * - * PCIe host driver and dongle firmware need to communicate with each other. The mechanism consists - * of multiple circular buffers located in (DMA'able) host memory. A circular buffer is either used - * for host -> dongle (h2d) or dongle -> host communication. Both host driver and firmware make use - * of this source file. This source file contains functions to manage such a set of circular - * buffers, but does not contain the code to read or write the data itself into the buffers. It - * leaves that up to the software layer that uses this file, which can be implemented either using - * pio or DMA transfers. It also leaves the format of the data that is written and read to a higher - * layer. Typically the data is in the form of so-called 'message buffers'. - * - * $Copyright Open Broadcom Corporation$ - * - * $Id: circularbuf.c 467150 2014-04-02 17:30:43Z $ - */ - -#include <circularbuf.h> -#include <bcmmsgbuf.h> -#include <osl.h> - -#define CIRCULARBUF_READ_SPACE_AT_END(x) \ - ((x->w_ptr >= x->rp_ptr) ? (x->w_ptr - x->rp_ptr) : (x->e_ptr - x->rp_ptr)) - -#define CIRCULARBUF_READ_SPACE_AVAIL(x) \ - (((CIRCULARBUF_READ_SPACE_AT_END(x) == 0) && (x->w_ptr < x->rp_ptr)) ? \ - x->w_ptr : CIRCULARBUF_READ_SPACE_AT_END(x)) - -int cbuf_msg_level = CBUF_ERROR_VAL | CBUF_TRACE_VAL | CBUF_INFORM_VAL; - -/* #define CBUF_DEBUG */ -#ifdef CBUF_DEBUG -#define CBUF_DEBUG_CHECK(x) x -#else -#define CBUF_DEBUG_CHECK(x) -#endif /* CBUF_DEBUG */ - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_init - * Description: - * - * - * Input Args : buf_base_addr: address of DMA'able host memory provided by caller - * - * - * Return Values : - * - * ----------------------------------------------------------------------------- - */ -void -circularbuf_init(circularbuf_t *handle, void *buf_base_addr, uint16 total_buf_len) -{ - handle->buf_addr = buf_base_addr; - - handle->depth = handle->e_ptr = HTOL32(total_buf_len); - - /* Initialize Read and Write pointers */ - handle->w_ptr = handle->r_ptr = handle->wp_ptr = handle->rp_ptr = HTOL32(0); - handle->mb_ring_bell = NULL; - handle->mb_ctx = NULL; - - return; -} - -/** - * When an item is added to the circular buffer by the producing party, the consuming party has to - * be notified by means of a 'door bell' or 'ring'. This function allows the caller to register a - * 'ring' function that will be called when a 'write complete' occurs. - */ -void -circularbuf_register_cb(circularbuf_t *handle, mb_ring_t mb_ring_func, void *ctx) -{ - handle->mb_ring_bell = mb_ring_func; - handle->mb_ctx = ctx; -} - -#ifdef CBUF_DEBUG -static void -circularbuf_check_sanity(circularbuf_t *handle) -{ - if ((handle->e_ptr > handle->depth) || - (handle->r_ptr > handle->e_ptr) || - (handle->rp_ptr > handle->e_ptr) || - (handle->w_ptr > handle->e_ptr)) - { - printf("%s:%d: Pointers are corrupted.\n", __FUNCTION__, __LINE__); - circularbuf_debug_print(handle); - ASSERT(0); - } - return; -} -#endif /* CBUF_DEBUG */ - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_reserve_for_write - * - * Description: - * This function reserves N bytes for write in the circular buffer. The circularbuf - * implementation will only reserve space in the circular buffer and return - * the pointer to the address where the new data can be written. - * The actual write implementation (bcopy/dma) is outside the scope of - * circularbuf implementation. - * - * Input Args : - * size - No. of bytes to reserve for write - * - * Return Values : - * void * : Pointer to the reserved location. This is the address - * that will be used for write (dma/bcopy) - * - * ----------------------------------------------------------------------------- - */ -void * BCMFASTPATH -circularbuf_reserve_for_write(circularbuf_t *handle, uint16 size) -{ - int16 avail_space; - void *ret_ptr = NULL; - - CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle)); - ASSERT(size < handle->depth); - - if (handle->wp_ptr >= handle->r_ptr) - avail_space = handle->depth - handle->wp_ptr; - else - avail_space = handle->r_ptr - handle->wp_ptr; - - ASSERT(avail_space <= handle->depth); - if (avail_space > size) - { - /* Great. We have enough space. */ - ret_ptr = CIRCULARBUF_START(handle) + handle->wp_ptr; - - /* - * We need to update the wp_ptr for the next guy to write. - * - * Please Note : We are not updating the write pointer here. This can be - * done only after write is complete (In case of DMA, we can only schedule - * the DMA. Actual completion will be known only on DMA complete interrupt). - */ - handle->wp_ptr += size; - return ret_ptr; - } - - /* - * If there is no available space, we should check if there is some space left - * in the beginning of the circular buffer. Wrap-around case, where there is - * not enough space in the end of the circular buffer. But, there might be - * room in the beginning of the buffer. - */ - if (handle->wp_ptr >= handle->r_ptr) - { - avail_space = handle->r_ptr; - if (avail_space > size) - { - /* OK. There is room in the beginning. Let's go ahead and use that. - * But, before that, we have left a hole at the end of the circular - * buffer as that was not sufficient to accomodate the requested - * size. Let's make sure this is updated in the circularbuf structure - * so that consumer does not use the hole. - */ - handle->e_ptr = handle->wp_ptr; - handle->wp_ptr = size; - - return CIRCULARBUF_START(handle); - } - } - - /* We have tried enough to accomodate the new packet. There is no room for now. */ - return NULL; -} - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_write_complete - * - * Description: - * This function has to be called by the producer end of circularbuf to indicate to - * the circularbuf layer that data has been written and the write pointer can be - * updated. In the process, if there was a doorbell callback registered, that - * function would also be invoked as to notify the consuming party. - * - * Input Args : - * dest_addr : Address where the data was written. This would be the - * same address that was reserved earlier. - * bytes_written : Length of data written - * - * ----------------------------------------------------------------------------- - */ -void BCMFASTPATH -circularbuf_write_complete(circularbuf_t *handle, uint16 bytes_written) -{ - CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle)); - - /* Update the write pointer */ - if ((handle->w_ptr + bytes_written) >= handle->depth) { - OSL_CACHE_FLUSH((void *) CIRCULARBUF_START(handle), bytes_written); - handle->w_ptr = bytes_written; - } else { - OSL_CACHE_FLUSH((void *) (CIRCULARBUF_START(handle) + handle->w_ptr), - bytes_written); - handle->w_ptr += bytes_written; - } - - /* And ring the door bell (mail box interrupt) to indicate to the peer that - * message is available for consumption. - */ - if (handle->mb_ring_bell) - handle->mb_ring_bell(handle->mb_ctx); -} - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_get_read_ptr - * - * Description: - * This function will be called by the consumer of circularbuf for reading data from - * the circular buffer. This will typically be invoked when the consumer gets a - * doorbell interrupt. - * Please note that the function only returns the pointer (and length) from - * where the data can be read. Actual read implementation is up to the - * consumer. It could be a bcopy or dma. - * - * Input Args : - * void * : Address from where the data can be read. - * available_len : Length of data available for read. - * - * ----------------------------------------------------------------------------- - */ -void * BCMFASTPATH -circularbuf_get_read_ptr(circularbuf_t *handle, uint16 *available_len) -{ - uint8 *ret_addr; - - CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle)); - - /* First check if there is any data available in the circular buffer */ - *available_len = CIRCULARBUF_READ_SPACE_AVAIL(handle); - if (*available_len == 0) - return NULL; - - /* - * Although there might be data in the circular buffer for read, in - * cases of write wrap-around and read still in the end of the circular - * buffer, we might have to wrap around the read pending pointer also. - */ - if (CIRCULARBUF_READ_SPACE_AT_END(handle) == 0) - handle->rp_ptr = 0; - - ret_addr = CIRCULARBUF_START(handle) + handle->rp_ptr; - - /* - * Please note that we do not update the read pointer here. Only - * read pending pointer is updated, so that next reader knows where - * to read data from. - * read pointer can only be updated when the read is complete. - */ - handle->rp_ptr = (uint16)(ret_addr - CIRCULARBUF_START(handle) + *available_len); - - ASSERT(*available_len <= handle->depth); - - OSL_CACHE_INV((void *) ret_addr, *available_len); - - return ret_addr; -} - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_read_complete - * Description: - * This function has to be called by the consumer end of circularbuf to indicate - * that data has been consumed and the read pointer can be updated, so the producing side - * can can use the freed space for new entries. - * - * - * Input Args : - * bytes_read : No. of bytes consumed by the consumer. This has to match - * the length returned by circularbuf_get_read_ptr - * - * Return Values : - * CIRCULARBUF_SUCCESS : Otherwise - * - * ----------------------------------------------------------------------------- - */ -circularbuf_ret_t BCMFASTPATH -circularbuf_read_complete(circularbuf_t *handle, uint16 bytes_read) -{ - CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle)); - ASSERT(bytes_read < handle->depth); - - /* Update the read pointer */ - if ((handle->w_ptr < handle->e_ptr) && (handle->r_ptr + bytes_read) > handle->e_ptr) - handle->r_ptr = bytes_read; - else - handle->r_ptr += bytes_read; - - return CIRCULARBUF_SUCCESS; -} - -/** - * ----------------------------------------------------------------------------- - * Function : circularbuf_revert_rp_ptr - * - * Description: - * The rp_ptr update during circularbuf_get_read_ptr() is done to reflect the amount of data - * that is sent out to be read by the consumer. But the consumer may not always read the - * entire data. In such a case, the rp_ptr needs to be reverted back by 'left' bytes, where - * 'left' is the no. of bytes left unread. - * - * Input args: - * bytes : The no. of bytes left unread by the consumer - * - * ----------------------------------------------------------------------------- - */ -circularbuf_ret_t -circularbuf_revert_rp_ptr(circularbuf_t *handle, uint16 bytes) -{ - CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle)); - ASSERT(bytes < handle->depth); - - handle->rp_ptr -= bytes; - - return CIRCULARBUF_SUCCESS; -} diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index 6d7297f9b6e31fcf69c34ba4dee9a16ea2d58370..7c29a33813f874071389f80e61bf8caafedfc599 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -4,9 +4,27 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd.h 491170 2014-07-15 06:23:58Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd.h 474409 2014-05-01 04:27:15Z $ */ /**************** @@ -47,8 +65,10 @@ int get_scheduler_policy(struct task_struct *p); #include <WdfMiniport.h> #endif /* (BCMWDF) */ -#if defined(WL11U) && !defined(MFP) +#if defined(WL11U) +#ifndef MFP #define MFP /* Applying interaction with MFP by spec HS2.0 REL2 */ +#endif /* MFP */ #endif /* WL11U */ #if defined(KEEP_ALIVE) @@ -70,16 +90,6 @@ enum dhd_bus_state { DHD_BUS_SUSPEND, /* Bus has been suspended */ }; -#if defined(NDISVER) && (NDISVER >= 0x0600) -/* Firmware requested operation mode */ -#define STA_MASK 0x0001 -#define HOSTAPD_MASK 0x0002 -#define WFD_MASK 0x0004 -#define SOFTAP_FW_MASK 0x0008 -#define P2P_GO_ENABLED 0x0010 -#define P2P_GC_ENABLED 0x0020 -#define CONCURENT_MASK 0x00F0 -#endif /* (NDISVER >= 0x0600) */ /* For supporting multiple interfaces */ #define DHD_MAX_IFS 16 @@ -110,8 +120,9 @@ enum dhd_op_flags { #define MAX_CNTL_RX_TIMEOUT 1 #endif /* MAX_CNTL_RX_TIMEOUT */ -#define DHD_SCAN_ASSOC_ACTIVE_TIME 40 /* ms: Embedded default Active setting from DHD */ -#define DHD_SCAN_UNASSOC_ACTIVE_TIME 80 /* ms: Embedded def. Unassoc Active setting from DHD */ +#define DHD_SCAN_ASSOC_ACTIVE_TIME 20 /* ms: Embedded default Active setting from DHD */ +#define DHD_SCAN_UNASSOC_ACTIVE_TIME 40 /* ms: Embedded def. Unassoc Active setting from DHD */ +#define DHD_SCAN_UNASSOC_ACTIVE_TIME_PS 30 #define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD */ #ifndef POWERUP_MAX_RETRY @@ -282,6 +293,8 @@ typedef struct dhd_pub { int pktfilter_count; wl_country_t dhd_cspec; /* Current Locale info */ + u32 dhd_cflags; + bool force_country_change; char eventmask[WL_EVENTING_MASK_LEN]; int op_mode; /* STA, HostAPD, WFD, SoftAP */ @@ -291,14 +304,11 @@ typedef struct dhd_pub { */ /* #define WL_ENABLE_P2P_IF 1 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */ struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */ -#endif +#endif -#ifdef WLBTAMP - uint16 maxdatablks; -#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS bool wlfc_enabled; int wlfc_mode; @@ -329,6 +339,12 @@ typedef struct dhd_pub { #endif /* PROP_TXSTATUS */ #ifdef PNO_SUPPORT void *pno_state; +#endif +#ifdef RTT_SUPPORT + void *rtt_state; +#endif +#ifdef ROAM_AP_ENV_DETECTION + bool roam_env_detection; #endif bool dongle_isolation; bool dongle_trap_occured; /* flag for sending HANG event to upper layer */ @@ -355,9 +371,6 @@ typedef struct dhd_pub { #if defined(ARP_OFFLOAD_SUPPORT) uint32 arp_version; #endif -#if defined(BCMSUP_4WAY_HANDSHAKE) && defined(WLAN_AKM_SUITE_FT_8021X) - bool fw_4way_handshake; /* Whether firmware will to do the 4way handshake. */ -#endif #ifdef CUSTOM_SET_CPUCORE struct task_struct * current_dpc; struct task_struct * current_rxf; @@ -377,6 +390,7 @@ typedef struct dhd_pub { char enable_log[MAX_EVENT]; bool dma_d2h_ring_upd_support; bool dma_h2d_ring_upd_support; + int short_dwell_time; #ifdef DHD_WMF bool wmf_ucast_igmp; #ifdef DHD_IGMP_UCQUERY @@ -394,7 +408,7 @@ typedef struct dhd_pub { #endif #if defined(WLTDLS) && defined(PCIE_FULL_DONGLE) tdls_peer_tbl_t peer_tbl; -#endif /* defined(WLTDLS) && defined(PCIE_FULL_DONGLE) */ +#endif } dhd_pub_t; #if defined(BCMWDF) @@ -429,7 +443,7 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(dhd_workitem_context_t, dhd_get_dhd_workitem_ #else #define DHD_PM_RESUME_RETURN_ERROR(a) do { \ if (dhd_mmc_suspend) return a; } while (0) - #endif + #endif #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); @@ -486,21 +500,21 @@ extern int dhd_os_wake_lock_restore(dhd_pub_t *pub); inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) mutex_init(&dhdp->wl_softap_lock); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ } inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) mutex_lock(&dhdp->wl_softap_lock); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ } inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) mutex_unlock(&dhdp->wl_softap_lock); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ } @@ -529,11 +543,6 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) void dhd_net_if_lock(struct net_device *dev); void dhd_net_if_unlock(struct net_device *dev); -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 && defined(BCMSDIO) -extern struct mutex _dhd_sdio_mutex_lock_; -#endif -#endif /* MULTIPLE_SUPPLICANT */ typedef enum dhd_attach_states { @@ -596,18 +605,38 @@ extern void dhd_sched_dpc(dhd_pub_t *dhdp); /* Notify tx completion */ extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); +#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */ +#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */ +#define WIFI_FEATURE_HOTSPOT 0x0004 /* Support for GAS/ANQP */ +#define WIFI_FEATURE_P2P 0x0008 /* Wifi-Direct */ +#define WIFI_FEATURE_SOFT_AP 0x0010 /* Soft AP */ +#define WIFI_FEATURE_GSCAN 0x0020 /* Google-Scan APIs */ +#define WIFI_FEATURE_NAN 0x0040 /* Neighbor Awareness Networking */ +#define WIFI_FEATURE_D2D_RTT 0x0080 /* Device-to-device RTT */ +#define WIFI_FEATURE_D2AP_RTT 0x0100 /* Device-to-AP RTT */ +#define WIFI_FEATURE_BATCH_SCAN 0x0200 /* Batched Scan (legacy) */ +#define WIFI_FEATURE_PNO 0x0400 /* Preferred network offload */ +#define WIFI_FEATURE_ADDITIONAL_STA 0x0800 /* Support for two STAs */ +#define WIFI_FEATURE_TDLS 0x1000 /* Tunnel directed link setup */ +#define WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 /* Support for TDLS off channel */ +#define WIFI_FEATURE_EPR 0x4000 /* Enhanced power reporting */ +#define WIFI_FEATURE_AP_STA 0x8000 /* Support for AP STA Concurrency */ + +#define MAX_FEATURE_SET_CONCURRRENT_GROUPS 3 + +extern int dhd_dev_get_feature_set(struct net_device *dev); +extern int *dhd_dev_get_feature_set_matrix(struct net_device *dev, int *num); +extern int dhd_dev_set_nodfs(struct net_device *dev, u32 nodfs); + /* OS independent layer functions */ extern int dhd_os_proto_block(dhd_pub_t * pub); extern int dhd_os_proto_unblock(dhd_pub_t * pub); extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending); extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub); +extern int dhd_os_d3ack_wait(dhd_pub_t * pub, uint * condition, bool * pending); +extern int dhd_os_d3ack_wake(dhd_pub_t * pub); extern unsigned int dhd_os_get_ioctl_resp_timeout(void); extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -#if 0 && (NDISVER >= 0x0600) -#define dhd_os_open_image(a) wl_os_open_image(a) -#define dhd_os_close_image(a) wl_os_close_image(a) -#define dhd_os_get_image_block(a, b, c) wl_os_get_image_block(a, b, c) -#endif /* (NDISVER >= 0x0600) */ extern int dhd_os_get_image_block(char * buf, int len, void * image); extern void * dhd_os_open_image(char * filename); @@ -628,15 +657,21 @@ extern void dhd_os_tcpackunlock(dhd_pub_t *pub); extern int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr); extern int dhd_customer_gpio_wlan_ctrl(void *adapter, int onoff); extern int dhd_custom_get_mac_address(void *adapter, unsigned char *buf); -extern void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec); +extern void get_customized_country_code(void *adapter, char *country_iso_code, + wl_country_t *cspec, u32 flags); extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret); extern int dhd_os_send_hang_message(dhd_pub_t *dhdp); extern void dhd_set_version_info(dhd_pub_t *pub, char *fw); +extern void dhd_set_short_dwell_time(dhd_pub_t *dhd, int set); +#ifdef CUSTOM_SET_SHORT_DWELL_TIME +extern void net_set_short_dwell_time(struct net_device *dev, int set); +#endif extern bool dhd_os_check_if_up(dhd_pub_t *pub); extern int dhd_os_check_wakelock(dhd_pub_t *pub); +extern int dhd_os_check_wakelock_all(dhd_pub_t *pub); extern int dhd_get_instance(dhd_pub_t *pub); #ifdef CUSTOM_SET_CPUCORE extern void dhd_set_cpucore(dhd_pub_t *dhd, int set); @@ -878,9 +913,7 @@ extern uint dhd_force_tx_queueing; #endif #define DEFAULT_WIFI_TURNOFF_DELAY 0 -#ifndef WIFI_TURNOFF_DELAY #define WIFI_TURNOFF_DELAY DEFAULT_WIFI_TURNOFF_DELAY -#endif /* WIFI_TURNOFF_DELAY */ #define DEFAULT_WIFI_TURNON_DELAY 200 #ifndef WIFI_TURNON_DELAY @@ -1022,9 +1055,6 @@ typedef struct wl_io_pport { } wl_io_pport_t; extern void *dhd_pub_wlinfo(dhd_pub_t *dhd_pub); -#ifdef EXYNOS5433_PCIE_WAR -extern void exynos_pcie_set_l1_exit(void); -extern void exynos_pcie_clear_l1_exit(void); -extern int enum_wifi; -#endif /* EXYNOS5433_PCIE_WAR */ + + #endif /* _dhd_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.c b/drivers/net/wireless/bcmdhd/dhd_bta.c index 6a4ef7938a91da68d6bfa600823848c691a9aacd..d82d6d22bcb0dfb4aad79c5b80229c5128c1721c 100644 --- a/drivers/net/wireless/bcmdhd/dhd_bta.c +++ b/drivers/net/wireless/bcmdhd/dhd_bta.c @@ -1,13 +1,29 @@ /* * BT-AMP support routines * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_bta.c 434434 2013-11-06 07:16:02Z $ */ -#ifndef WLBTAMP #error "WLBTAMP is not defined" -#endif /* WLBTAMP */ #include <typedefs.h> #include <osl.h> diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.h b/drivers/net/wireless/bcmdhd/dhd_bta.h index 4067fc39b2985a1b973913d75b46fbec9390cb24..db636a8c20c78fb1290c0dba0afad01a490f36a1 100644 --- a/drivers/net/wireless/bcmdhd/dhd_bta.h +++ b/drivers/net/wireless/bcmdhd/dhd_bta.h @@ -1,7 +1,25 @@ /* * BT-AMP support routines * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_bta.h 291086 2011-10-21 01:17:24Z $ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h index 3b44a01a56e08f5b77c0220adfb0f5c7cb78accb..525a73b3ac3b6732566f1c645e4e786fe614f7bf 100644 --- a/drivers/net/wireless/bcmdhd/dhd_bus.h +++ b/drivers/net/wireless/bcmdhd/dhd_bus.h @@ -4,9 +4,27 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_bus.h 491657 2014-07-17 06:29:40Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_bus.h 469959 2014-04-11 23:07:39Z $ */ #ifndef _dhd_bus_h_ @@ -162,11 +180,8 @@ extern int dhdpcie_bus_clock_start(struct dhd_bus *bus); extern int dhdpcie_bus_clock_stop(struct dhd_bus *bus); extern int dhdpcie_bus_enable_device(struct dhd_bus *bus); extern int dhdpcie_bus_disable_device(struct dhd_bus *bus); -extern int dhdpcie_bus_alloc_resource(struct dhd_bus *bus); -extern void dhdpcie_bus_free_resource(struct dhd_bus *bus); extern bool dhdpcie_bus_dongle_attach(struct dhd_bus *bus); extern int dhd_bus_release_dongle(struct dhd_bus *bus); - #endif /* BCMPCIE */ #endif /* _dhd_bus_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c index f67bbb378e65f2b031eb7b91cb95eb67b6b226d4..4a69389bf9f4618c6c84ea78909c58b77a68b010 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cdc.c +++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c @@ -1,7 +1,25 @@ /* * DHD Protocol Module for CDC and BDC. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_cdc.c 472193 2014-04-23 06:27:38Z $ * @@ -429,13 +447,6 @@ dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_in PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); #endif /* BDC */ -#if defined(NDISVER) && (NDISVER < 0x0630) - if (PKTLEN(dhd->osh, pktbuf) < (uint32) (data_offset << 2)) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), (data_offset * 4))); - return BCME_ERROR; - } -#endif /* (NDISVER < 0x0630) */ #ifdef PROP_TXSTATUS if (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf))) { diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c index e5c28823305e2a1cb3492f34c5576d1abcae4ea9..eb98e28dbe8fe31cdfde0688cbcada693377e885 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c @@ -1,7 +1,25 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ */ @@ -35,6 +53,9 @@ static int dhd_dongle_up = FALSE; #include <wlioctl.h> #include <brcm_nl80211.h> #include <dhd_cfg80211.h> +#ifdef PCIE_FULL_DONGLE +#include <dhd_flowring.h> +#endif static s32 wl_dongle_up(struct net_device *ndev); static s32 wl_dongle_down(struct net_device *ndev); @@ -199,3 +220,123 @@ default_conf_out: return err; } + +#ifdef PCIE_FULL_DONGLE +void wl_roam_flowring_cleanup(struct bcm_cfg80211 *cfg) +{ + int hostidx = 0; + dhd_pub_t *dhd_pub = (dhd_pub_t *)(cfg->pub); + hostidx = dhd_ifidx2hostidx(dhd_pub->info, hostidx); + dhd_flow_rings_delete(dhd_pub, hostidx); +} +#endif + +#ifdef CONFIG_NL80211_TESTMODE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, void *data, int len) +#else +int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ +{ + struct sk_buff *reply; + struct bcm_cfg80211 *cfg; + dhd_pub_t *dhd; + struct bcm_nlmsg_hdr *nlioc = data; + dhd_ioctl_t ioc = { 0 }; + int err = 0; + void *buf = NULL, *cur; + u16 buflen; + u16 maxmsglen = PAGE_SIZE - 0x100; + bool newbuf = false; + int8 index = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + struct net_device *ndev = NULL; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ + + WL_TRACE(("entry: cmd = %d\n", nlioc->cmd)); + cfg = wiphy_priv(wiphy); + dhd = cfg->pub; + + DHD_OS_WAKE_LOCK(dhd); + + /* send to dongle only if we are not waiting for reload already */ + if (dhd->hang_was_sent) { + WL_ERR(("HANG was sent up earlier\n")); + DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); + DHD_OS_WAKE_UNLOCK(dhd); + return OSL_ERROR(BCME_DONGLE_DOWN); + } + + len -= sizeof(struct bcm_nlmsg_hdr); + + if (nlioc->len > 0) { + if (nlioc->len <= len) { + buf = (void *)nlioc + nlioc->offset; + *(char *)(buf + nlioc->len) = '\0'; + } else { + if (nlioc->len > DHD_IOCTL_MAXLEN) + nlioc->len = DHD_IOCTL_MAXLEN; + buf = vzalloc(nlioc->len); + if (!buf) + return -ENOMEM; + newbuf = true; + memcpy(buf, (void *)nlioc + nlioc->offset, len); + *(char *)(buf + len) = '\0'; + } + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + ndev = wdev_to_wlc_ndev(wdev, cfg); + index = dhd_net2idx(dhd->info, ndev); + if (index == DHD_BAD_IF) { + WL_ERR(("Bad ifidx from wdev:%p\n", wdev)); + return BCME_ERROR; + } +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ + + ioc.cmd = nlioc->cmd; + ioc.len = nlioc->len; + ioc.set = nlioc->set; + ioc.driver = nlioc->magic; + err = dhd_ioctl_process(dhd, index, &ioc, buf); + if (err) { + WL_TRACE(("dhd_ioctl_process return err %d\n", err)); + err = OSL_ERROR(err); + goto done; + } + + cur = buf; + while (nlioc->len > 0) { + buflen = nlioc->len > maxmsglen ? maxmsglen : nlioc->len; + nlioc->len -= buflen; + reply = cfg80211_testmode_alloc_reply_skb(wiphy, buflen+4); + if (!reply) { + WL_ERR(("Failed to allocate reply msg\n")); + err = -ENOMEM; + break; + } + + if (nla_put(reply, BCM_NLATTR_DATA, buflen, cur) || + nla_put_u16(reply, BCM_NLATTR_LEN, buflen)) { + kfree_skb(reply); + err = -ENOBUFS; + break; + } + + do { + err = cfg80211_testmode_reply(reply); + } while (err == -EAGAIN); + if (err) { + WL_ERR(("testmode reply failed:%d\n", err)); + break; + } + cur += buflen; + } + +done: + if (newbuf) + vfree(buf); + DHD_OS_WAKE_UNLOCK(dhd); + return err; +} +#endif /* CONFIG_NL80211_TESTMODE */ diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h index 7e1999d98094617676c8a247c5249af19596d19c..bf89f12ee60b5ef03dfaa0921cb0e8d075324a6a 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h @@ -1,7 +1,25 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ */ @@ -26,5 +44,26 @@ s32 dhd_cfg80211_down(struct bcm_cfg80211 *cfg); s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val); s32 dhd_cfg80211_clean_p2p_info(struct bcm_cfg80211 *cfg); s32 dhd_config_dongle(struct bcm_cfg80211 *cfg); +#ifdef PCIE_FULL_DONGLE +void wl_roam_flowring_cleanup(struct bcm_cfg80211 *cfg); +#endif + +#ifdef CONFIG_NL80211_TESTMODE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, void *data, int len); +#else +int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +static inline int +dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, void *data, int len) +#else +static inline int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ +{ + return 0; +} +#endif /* CONFIG_NL80211_TESTMODE */ #endif /* __DHD_CFG80211__ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg_vendor.c b/drivers/net/wireless/bcmdhd/dhd_cfg_vendor.c deleted file mode 100644 index 7cba554f8a06f9b4e907d8eb77b2df40971d3f7a..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_cfg_vendor.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Linux cfg80211 vendor command/event handlers of DHD - * - * $Copyright Open Broadcom Corporation$ - * - * $Id: dhd_cfg_vendor.c 487126 2014-06-24 23:06:12Z $ - */ - -#include <linuxver.h> -#include <net/cfg80211.h> -#include <net/netlink.h> - -#include <bcmutils.h> -#include <wl_cfg80211.h> -#include <wl_cfgvendor.h> -#include <dngl_stats.h> -#include <dhd.h> -#include <dhdioctl.h> -#include <brcm_nl80211.h> - -#ifdef VENDOR_EXT_SUPPORT -static int dhd_cfgvendor_priv_string_handler(struct wiphy *wiphy, - struct wireless_dev *wdev, const void *data, int len) -{ - const struct bcm_nlmsg_hdr *nlioc = data; - struct net_device *ndev = NULL; - struct bcm_cfg80211 *cfg; - struct sk_buff *reply; - void *buf = NULL, *cur; - dhd_pub_t *dhd; - dhd_ioctl_t ioc = { 0 }; - int ret = 0, ret_len, payload, msglen; - int maxmsglen = PAGE_SIZE - 0x100; - int8 index; - - WL_TRACE(("entry: cmd = %d\n", nlioc->cmd)); - DHD_ERROR(("entry: cmd = %d\n", nlioc->cmd)); - - cfg = wiphy_priv(wiphy); - dhd = cfg->pub; - - DHD_OS_WAKE_LOCK(dhd); - - /* send to dongle only if we are not waiting for reload already */ - if (dhd->hang_was_sent) { - WL_ERR(("HANG was sent up earlier\n")); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); - DHD_OS_WAKE_UNLOCK(dhd); - return OSL_ERROR(BCME_DONGLE_DOWN); - } - - len -= sizeof(struct bcm_nlmsg_hdr); - ret_len = nlioc->len; - if (ret_len > 0 || len > 0) { - if (len > DHD_IOCTL_MAXLEN) { - WL_ERR(("oversize input buffer %d\n", len)); - len = DHD_IOCTL_MAXLEN; - } - if (ret_len > DHD_IOCTL_MAXLEN) { - WL_ERR(("oversize return buffer %d\n", ret_len)); - ret_len = DHD_IOCTL_MAXLEN; - } - payload = max(ret_len, len) + 1; - buf = vzalloc(payload); - if (!buf) { - DHD_OS_WAKE_UNLOCK(dhd); - return -ENOMEM; - } - memcpy(buf, (void *)nlioc + nlioc->offset, len); - *(char *)(buf + len) = '\0'; - } - - ndev = wdev_to_wlc_ndev(wdev, cfg); - index = dhd_net2idx(dhd->info, ndev); - if (index == DHD_BAD_IF) { - WL_ERR(("Bad ifidx from wdev:%p\n", wdev)); - ret = BCME_ERROR; - goto done; - } - - ioc.cmd = nlioc->cmd; - ioc.len = nlioc->len; - ioc.set = nlioc->set; - ioc.driver = nlioc->magic; - ret = dhd_ioctl_process(dhd, index, &ioc, buf); - if (ret) { - WL_TRACE(("dhd_ioctl_process return err %d\n", ret)); - ret = OSL_ERROR(ret); - goto done; - } - - cur = buf; - while (ret_len > 0) { - msglen = nlioc->len > maxmsglen ? maxmsglen : ret_len; - ret_len -= msglen; - payload = msglen + sizeof(msglen); - reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); - if (!reply) { - WL_ERR(("Failed to allocate reply msg\n")); - ret = -ENOMEM; - break; - } - - if (nla_put(reply, BCM_NLATTR_DATA, msglen, cur) || - nla_put_u16(reply, BCM_NLATTR_LEN, msglen)) { - kfree_skb(reply); - ret = -ENOBUFS; - break; - } - - ret = cfg80211_vendor_cmd_reply(reply); - if (ret) { - WL_ERR(("testmode reply failed:%d\n", ret)); - break; - } - cur += msglen; - } - -done: - vfree(buf); - DHD_OS_WAKE_UNLOCK(dhd); - return ret; -} - -const struct wiphy_vendor_command dhd_cfgvendor_cmds [] = { - { - { - .vendor_id = OUI_BRCM, - .subcmd = BRCM_VENDOR_SCMD_PRIV_STR - }, - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = dhd_cfgvendor_priv_string_handler - }, -}; - -int cfgvendor_attach(struct wiphy *wiphy) -{ - wiphy->vendor_commands = dhd_cfgvendor_cmds; - wiphy->n_vendor_commands = ARRAY_SIZE(dhd_cfgvendor_cmds); - - return 0; -} - -int cfgvendor_detach(struct wiphy *wiphy) -{ - wiphy->vendor_commands = NULL; - wiphy->n_vendor_commands = 0; - - return 0; -} -#endif /* VENDOR_EXT_SUPPORT */ diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index 136ea975ffd5da73fd66d6115260ae56a05d0727..1ed11d64c7579fadeb0b337d1b787f6d650cd477 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -1,9 +1,27 @@ /* * Broadcom Dongle Host Driver (DHD), common DHD core. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_common.c 490628 2014-07-11 07:13:31Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_common.c 473079 2014-04-27 07:47:16Z $ */ #include <typedefs.h> #include <osl.h> @@ -34,13 +52,12 @@ #ifdef WL_CFG80211 #include <wl_cfg80211.h> #endif -#ifdef WLBTAMP -#include <proto/bt_amp_hci.h> -#include <dhd_bta.h> -#endif #ifdef PNO_SUPPORT #include <dhd_pno.h> #endif +#ifdef RTT_SUPPORT +#include <dhd_rtt.h> +#endif #define htod32(i) (i) #define htod16(i) (i) @@ -106,7 +123,7 @@ const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR DHD_COMPILED " on " __DATE__ " at " __TIME__; #else const char dhd_version[] = "\nDongle Host Driver, version " EPI_VERSION_STR "\nCompiled from "; -#endif +#endif void dhd_set_timer(void *bus, uint wdtick); @@ -126,10 +143,6 @@ enum { IOV_LOGSTAMP, IOV_GPIOOB, IOV_IOCTLTIMEOUT, -#ifdef WLBTAMP - IOV_HCI_CMD, /* HCI command */ - IOV_HCI_ACL_DATA, /* HCI data packet */ -#endif #if defined(DHD_DEBUG) IOV_CONS, IOV_DCONSOLE_POLL, @@ -138,10 +151,6 @@ enum { IOV_PROPTXSTATUS_ENABLE, IOV_PROPTXSTATUS_MODE, IOV_PROPTXSTATUS_OPT, -#ifdef QMONITOR - IOV_QMON_TIME_THRES, - IOV_QMON_TIME_PERCENT, -#endif /* QMONITOR */ IOV_PROPTXSTATUS_MODULE_IGNORE, IOV_PROPTXSTATUS_CREDIT_IGNORE, IOV_PROPTXSTATUS_TXSTATUS_IGNORE, @@ -193,10 +202,6 @@ const bcm_iovar_t dhd_iovars[] = { {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, -#ifdef WLBTAMP - {"HCI_cmd", IOV_HCI_CMD, 0, IOVT_BUFFER, 0}, - {"HCI_ACL_data", IOV_HCI_ACL_DATA, 0, IOVT_BUFFER, 0}, -#endif #ifdef PROP_TXSTATUS {"proptx", IOV_PROPTXSTATUS_ENABLE, 0, IOVT_BOOL, 0 }, /* @@ -207,10 +212,6 @@ const bcm_iovar_t dhd_iovars[] = { */ {"ptxmode", IOV_PROPTXSTATUS_MODE, 0, IOVT_UINT32, 0 }, {"proptx_opt", IOV_PROPTXSTATUS_OPT, 0, IOVT_UINT32, 0 }, -#ifdef QMONITOR - {"qtime_thres", IOV_QMON_TIME_THRES, 0, IOVT_UINT32, 0 }, - {"qtime_percent", IOV_QMON_TIME_PERCENT, 0, IOVT_UINT32, 0 }, -#endif /* QMONITOR */ {"pmodule_ignore", IOV_PROPTXSTATUS_MODULE_IGNORE, 0, IOVT_BOOL, 0 }, {"pcredit_ignore", IOV_PROPTXSTATUS_CREDIT_IGNORE, 0, IOVT_BOOL, 0 }, {"ptxstatus_ignore", IOV_PROPTXSTATUS_TXSTATUS_IGNORE, 0, IOVT_BOOL, 0 }, @@ -432,7 +433,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_MSGLEVEL): int_val = (int32)dhd_msg_level; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_MSGLEVEL): @@ -453,12 +454,12 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_BCMERROR): int_val = (int32)dhd_pub->bcmerror; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_WDTICK): int_val = (int32)dhd_watchdog_ms; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WDTICK): @@ -476,7 +477,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef DHD_DEBUG case IOV_GVAL(IOV_DCONSOLE_POLL): int_val = (int32)dhd_console_ms; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DCONSOLE_POLL): @@ -522,37 +523,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch break; } -#ifdef WLBTAMP - case IOV_SVAL(IOV_HCI_CMD): { - amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg; - - /* sanity check: command preamble present */ - if (len < HCI_CMD_PREAMBLE_SIZE) - return BCME_BUFTOOSHORT; - - /* sanity check: command parameters are present */ - if (len < (int)(HCI_CMD_PREAMBLE_SIZE + cmd->plen)) - return BCME_BUFTOOSHORT; - - dhd_bta_docmd(dhd_pub, cmd, len); - break; - } - - case IOV_SVAL(IOV_HCI_ACL_DATA): { - amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)arg; - - /* sanity check: HCI header present */ - if (len < HCI_ACL_DATA_PREAMBLE_SIZE) - return BCME_BUFTOOSHORT; - - /* sanity check: ACL data is present */ - if (len < (int)(HCI_ACL_DATA_PREAMBLE_SIZE + ACL_data->dlen)) - return BCME_BUFTOOSHORT; - - dhd_bta_tx_hcidata(dhd_pub, ACL_data, len); - break; - } -#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): { @@ -561,7 +531,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch if (bcmerror != BCME_OK) goto exit; int_val = wlfc_enab ? 1 : 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; } case IOV_SVAL(IOV_PROPTXSTATUS_ENABLE): { @@ -585,36 +555,18 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhd_wlfc_get_mode(dhd_pub, &int_val); if (bcmerror != BCME_OK) goto exit; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PROPTXSTATUS_MODE): dhd_wlfc_set_mode(dhd_pub, int_val); break; -#ifdef QMONITOR - case IOV_GVAL(IOV_QMON_TIME_THRES): { - int_val = dhd_qmon_thres(dhd_pub, FALSE, 0); - bcopy(&int_val, arg, val_size); - break; - } - - case IOV_SVAL(IOV_QMON_TIME_THRES): { - dhd_qmon_thres(dhd_pub, TRUE, int_val); - break; - } - - case IOV_GVAL(IOV_QMON_TIME_PERCENT): { - int_val = dhd_qmon_getpercent(dhd_pub); - bcopy(&int_val, arg, val_size); - break; - } -#endif /* QMONITOR */ case IOV_GVAL(IOV_PROPTXSTATUS_MODULE_IGNORE): bcmerror = dhd_wlfc_get_module_ignore(dhd_pub, &int_val); if (bcmerror != BCME_OK) goto exit; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PROPTXSTATUS_MODULE_IGNORE): @@ -625,7 +577,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhd_wlfc_get_credit_ignore(dhd_pub, &int_val); if (bcmerror != BCME_OK) goto exit; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PROPTXSTATUS_CREDIT_IGNORE): @@ -636,7 +588,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhd_wlfc_get_txstatus_ignore(dhd_pub, &int_val); if (bcmerror != BCME_OK) goto exit; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PROPTXSTATUS_TXSTATUS_IGNORE): @@ -647,7 +599,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhd_wlfc_get_rxpkt_chk(dhd_pub, &int_val); if (bcmerror != BCME_OK) goto exit; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PROPTXSTATUS_RXPKT_CHK): @@ -667,14 +619,14 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef PCIE_FULL_DONGLE int_val = BUS_TYPE_PCIE; #endif - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; #ifdef WLMEDIA_HTSF case IOV_GVAL(IOV_WLPKTDLYSTAT_SZ): int_val = dhd_pub->htsfdlystat_sz; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WLPKTDLYSTAT_SZ): @@ -708,7 +660,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef DHDTCPACK_SUPPRESS case IOV_GVAL(IOV_TCPACK_SUPPRESS): { int_val = (uint32)dhd_pub->tcpack_sup_mode; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; } case IOV_SVAL(IOV_TCPACK_SUPPRESS): { @@ -730,7 +682,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch wmf = dhd_wmf_conf(dhd_pub, bssidx); int_val = wmf->wmf_enable ? 1 :0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; } case IOV_SVAL(IOV_WMF_BSS_ENAB): { @@ -772,7 +724,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch } case IOV_GVAL(IOV_WMF_UCAST_IGMP): int_val = dhd_pub->wmf_ucast_igmp ? 1 : 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WMF_UCAST_IGMP): if (dhd_pub->wmf_ucast_igmp == int_val) @@ -785,7 +737,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch break; case IOV_GVAL(IOV_WMF_MCAST_DATA_SENDUP): int_val = dhd_wmf_mcast_data_sendup(dhd_pub, 0, FALSE, FALSE); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WMF_MCAST_DATA_SENDUP): dhd_wmf_mcast_data_sendup(dhd_pub, 0, TRUE, int_val); @@ -794,7 +746,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef WL_IGMP_UCQUERY case IOV_GVAL(IOV_WMF_UCAST_IGMP_QUERY): int_val = dhd_pub->wmf_ucast_igmp_query ? 1 : 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WMF_UCAST_IGMP_QUERY): if (dhd_pub->wmf_ucast_igmp_query == int_val) @@ -809,7 +761,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef DHD_UCAST_UPNP case IOV_GVAL(IOV_WMF_UCAST_UPNP): int_val = dhd_pub->wmf_ucast_upnp ? 1 : 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WMF_UCAST_UPNP): if (dhd_pub->wmf_ucast_upnp == int_val) @@ -827,7 +779,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef DHD_UNICAST_DHCP case IOV_GVAL(IOV_DHCP_UNICAST): int_val = dhd_pub->dhcp_unicast; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DHCP_UNICAST): if (dhd_pub->dhcp_unicast == int_val) @@ -843,7 +795,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef DHD_L2_FILTER case IOV_GVAL(IOV_BLOCK_PING): int_val = dhd_pub->block_ping; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_BLOCK_PING): if (dhd_pub->block_ping == int_val) @@ -867,7 +819,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch } int_val = dhd_get_ap_isolate(dhd_pub, bssidx); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; } case IOV_SVAL(IOV_AP_ISOLATE): { @@ -1390,6 +1342,8 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data, case WLC_E_PFN_SCAN_COMPLETE: case WLC_E_PFN_SCAN_NONE: case WLC_E_PFN_SCAN_ALLGONE: + case WLC_E_PFN_GSCAN_FULL_RESULT: + case WLC_E_PFN_SWC: DHD_EVENT(("PNOEVENT: %s\n", event_name)); break; @@ -1454,7 +1408,7 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data, /* Display the trace buffer. Advance from * \n to \n to avoid display big - * printf (issue with Linux printf ) + * printf (issue with Linux printk ) */ p = (char *)&buf[MSGTRACE_HDRLEN]; while (*p != '\0' && (s = strstr(p, "\n")) != NULL) { @@ -1698,7 +1652,7 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, /* Ignore the event if NOIF is set */ if (ifevent->reserved & WLC_E_IF_FLAGS_BSSCFG_NOIF) { - DHD_ERROR(("WLC_E_IF: NO_IF set, event Ignored\r\n")); + DHD_ERROR(("WLC_E_IF: NO_IF set, event Ignored\n")); return (BCME_UNSUPPORTED); } #ifdef PCIE_FULL_DONGLE @@ -1768,10 +1722,6 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, htsf_update(dhd_pub->info, event_data); break; #endif /* WLMEDIA_HTSF */ -#if defined(NDISVER) && (NDISVER >= 0x0630) - case WLC_E_NDIS_LINK: - break; -#else case WLC_E_NDIS_LINK: { uint32 temp = hton32(WLC_E_LINK); @@ -1779,7 +1729,6 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, sizeof(pvt_data->event.event_type)); break; } -#endif /* NDISVER >= 0x0630 */ case WLC_E_PFN_NET_FOUND: case WLC_E_PFN_NET_LOST: break; @@ -1789,7 +1738,12 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, case WLC_E_PFN_BEST_BATCHING: dhd_pno_event_handler(dhd_pub, event, (void *)event_data); break; -#endif +#endif +#if defined(RTT_SUPPORT) + case WLC_E_PROXD: + dhd_rtt_event_handler(dhd_pub, event, (void *)event_data); + break; +#endif /* RTT_SUPPORT */ /* These are what external supplicant/authenticator wants */ case WLC_E_ASSOC_IND: case WLC_E_AUTH_IND: @@ -2420,10 +2374,6 @@ void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { -#ifdef WLBTAMP - case WLC_E_BTA_HCI_EVENT: - break; -#endif /* WLBTAMP */ default: break; } @@ -2692,7 +2642,7 @@ wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, * SSIDs list parsing from cscan tlv list */ int -wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) +wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid, int max, int *bytes_left) { char* str; int idx = 0; @@ -2740,6 +2690,7 @@ wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes *bytes_left -= ssid[idx].SSID_len; str += ssid[idx].SSID_len; + ssid[idx].hidden = TRUE; DHD_TRACE(("%s :size=%d left=%d\n", (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left)); diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c index 633d3a7f71c869d143377cc57bed9e80484dcedc..b7d162c2172e5532d5370be805bae3f8f01dfe77 100644 --- a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c +++ b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c @@ -1,6 +1,24 @@ /* * Customer code to add GPIO control during WLAN start/stop -* $Copyright Open Broadcom Corporation$ +* Copyright (C) 1999-2014, Broadcom Corporation +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2 (the "GPL"), +* available at http://www.broadcom.com/licenses/GPLv2.php, with the +* following added to such license: +* +* As a special exception, the copyright holders of this software give you +* permission to link this software with independent modules, and to copy and +* distribute the resulting executable under terms of your choice, provided that +* you also meet, for each linked independent module, the terms and conditions of +* the license of that module. An independent module is a module which is not +* derived from this software. The special exception does not apply to any +* modifications of the software. +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a license +* other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_custom_gpio.c 447105 2014-01-08 05:27:09Z $ */ @@ -21,9 +39,6 @@ #if defined(CUSTOMER_HW2) -#if defined(PLATFORM_MPS) -int __attribute__ ((weak)) wifi_get_fw_nv_path(char *fw, char *nv) { return 0;}; -#endif #endif @@ -33,7 +48,7 @@ int __attribute__ ((weak)) wifi_get_fw_nv_path(char *fw, char *nv) { return 0;}; extern int sdioh_mmc_irq(int irq); #endif /* (BCMLXSDMMC) */ -#if defined(CUSTOMER_HW3) || defined(PLATFORM_MPS) +#if defined(CUSTOMER_HW3) #include <mach/gpio.h> #endif @@ -58,7 +73,7 @@ int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr) { int host_oob_irq = 0; -#if defined(CUSTOMER_HW2) && !defined(PLATFORM_MPS) +#if defined(CUSTOMER_HW2) host_oob_irq = wifi_platform_get_irq_number(adapter, irq_flags_ptr); #else @@ -77,11 +92,11 @@ int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr) WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", __FUNCTION__, dhd_oob_gpio_num)); -#if defined CUSTOMER_HW3 || defined(PLATFORM_MPS) +#if defined CUSTOMER_HW3 gpio_request(dhd_oob_gpio_num, "oob irq"); host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); gpio_direction_input(dhd_oob_gpio_num); -#endif /* defined CUSTOMER_HW3 || defined(PLATFORM_MPS) */ +#endif #endif return (host_oob_irq); @@ -109,8 +124,7 @@ dhd_custom_get_mac_address(void *adapter, unsigned char *buf) return -EINVAL; /* Customer access to MAC address stored outside of DHD driver */ -#if (defined(CUSTOMER_HW2) || defined(CUSTOMER_HW10)) && (LINUX_VERSION_CODE >= \ - KERNEL_VERSION(2, 6, 35)) +#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) ret = wifi_platform_get_mac_addr(adapter, buf); #endif @@ -242,7 +256,8 @@ const struct cntry_locales_custom translate_custom_table[] = { * input : ISO 3166-1 country abbreviation * output: customized cspec */ -void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec) +void get_customized_country_code(void *adapter, char *country_iso_code, + wl_country_t *cspec, u32 flags) { #if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) @@ -251,7 +266,8 @@ void get_customized_country_code(void *adapter, char *country_iso_code, wl_count if (!cspec) return; - cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code); + cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code, + flags); if (cloc_ptr) { strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); cspec->rev = cloc_ptr->custom_locale_rev; diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h index 1b0025740f7090a92482b5d42b991bc210333781..6ab5f607ffb8683478aafdde46e0c06511b647aa 100644 --- a/drivers/net/wireless/bcmdhd/dhd_dbg.h +++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h @@ -1,9 +1,27 @@ /* * Debug/trace/assert driver definitions for Dongle Host Driver. * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_dbg.h 491225 2014-07-15 11:58:29Z $ + * $Id: dhd_dbg.h 424863 2013-09-19 20:06:14Z $ */ #ifndef _dhd_dbg_ @@ -30,9 +48,9 @@ #define DHD_ARPOE(args) do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0) #define DHD_REORDER(args) do {if (dhd_msg_level & DHD_REORDER_VAL) printf args;} while (0) #define DHD_PNO(args) do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0) +#define DHD_RTT(args) do {if (dhd_msg_level & DHD_RTT_VAL) printf args;} while (0) #define DHD_TRACE_HW4 DHD_TRACE -#define DHD_INFO_HW4 DHD_INFO #define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) #define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) @@ -51,6 +69,7 @@ #define DHD_REORDER_ON() (dhd_msg_level & DHD_REORDER_VAL) #define DHD_NOCHECKDIED_ON() (dhd_msg_level & DHD_NOCHECKDIED_VAL) #define DHD_PNO_ON() (dhd_msg_level & DHD_PNO_VAL) +#define DHD_RTT_ON() (dhd_msg_level & DHD_RTT_VAL) #else /* defined(BCMDBG) || defined(DHD_DEBUG) */ @@ -72,7 +91,6 @@ #define DHD_PNO(args) #define DHD_TRACE_HW4 DHD_TRACE -#define DHD_INFO_HW4 DHD_INFO #define DHD_ERROR_ON() 0 #define DHD_TRACE_ON() 0 @@ -91,7 +109,7 @@ #define DHD_REORDER_ON() 0 #define DHD_NOCHECKDIED_ON() 0 #define DHD_PNO_ON() 0 - +#define DHD_RTT_ON() 0 #endif #define DHD_LOG(args) diff --git a/drivers/net/wireless/bcmdhd/dhd_flowring.c b/drivers/net/wireless/bcmdhd/dhd_flowring.c new file mode 100644 index 0000000000000000000000000000000000000000..97c9098789383b6247a4fc1bddc5bcdc79eabbfc --- /dev/null +++ b/drivers/net/wireless/bcmdhd/dhd_flowring.c @@ -0,0 +1,729 @@ +/* + * Broadcom Dongle Host Driver (DHD), Flow ring specific code at top level + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_flowrings.c jaganlv $ + */ + +#include <typedefs.h> +#include <bcmutils.h> +#include <bcmendian.h> +#include <bcmdevs.h> + +#include <proto/ethernet.h> +#include <proto/bcmevent.h> +#include <dngl_stats.h> + +#include <dhd.h> + +#include <dhd_flowring.h> +#include <dhd_bus.h> +#include <dhd_proto.h> +#include <dhd_dbg.h> +#include <proto/802.1d.h> + +static INLINE uint16 dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex, + uint8 prio, char *sa, char *da); + +static INLINE uint16 dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, + uint8 prio, char *sa, char *da); + +static INLINE int dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex, + uint8 prio, char *sa, char *da, uint16 *flowid); +int BCMFASTPATH dhd_flow_queue_overflow(flow_queue_t *queue, void *pkt); + +#define FLOW_QUEUE_PKT_NEXT(p) PKTLINK(p) +#define FLOW_QUEUE_PKT_SETNEXT(p, x) PKTSETLINK((p), (x)) + +const uint8 prio2ac[8] = { 0, 1, 1, 0, 2, 2, 3, 3 }; +const uint8 prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +int BCMFASTPATH +dhd_flow_queue_overflow(flow_queue_t *queue, void *pkt) +{ + return BCME_NORESOURCE; +} + +/* Flow ring's queue management functions */ + +void /* Initialize a flow ring's queue */ +dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max) +{ + ASSERT((queue != NULL) && (max > 0)); + + dll_init(&queue->list); + queue->head = queue->tail = NULL; + queue->len = 0; + queue->max = max - 1; + queue->failures = 0U; + queue->cb = &dhd_flow_queue_overflow; + queue->lock = dhd_os_spin_lock_init(dhdp->osh); + + if (queue->lock == NULL) + DHD_ERROR(("%s: Failed to init spinlock for queue!\n", __FUNCTION__)); +} + +void /* Register an enqueue overflow callback handler */ +dhd_flow_queue_register(flow_queue_t *queue, flow_queue_cb_t cb) +{ + ASSERT(queue != NULL); + queue->cb = cb; +} + + +int BCMFASTPATH /* Enqueue a packet in a flow ring's queue */ +dhd_flow_queue_enqueue(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt) +{ + int ret = BCME_OK; + + ASSERT(queue != NULL); + + if (queue->len >= queue->max) { + queue->failures++; + ret = (*queue->cb)(queue, pkt); + goto done; + } + + if (queue->head) { + FLOW_QUEUE_PKT_SETNEXT(queue->tail, pkt); + } else { + queue->head = pkt; + } + + FLOW_QUEUE_PKT_SETNEXT(pkt, NULL); + + queue->tail = pkt; /* at tail */ + + queue->len++; + +done: + return ret; +} + +void * BCMFASTPATH /* Dequeue a packet from a flow ring's queue, from head */ +dhd_flow_queue_dequeue(dhd_pub_t *dhdp, flow_queue_t *queue) +{ + void * pkt; + + ASSERT(queue != NULL); + + pkt = queue->head; /* from head */ + + if (pkt == NULL) { + ASSERT((queue->len == 0) && (queue->tail == NULL)); + goto done; + } + + queue->head = FLOW_QUEUE_PKT_NEXT(pkt); + if (queue->head == NULL) + queue->tail = NULL; + + queue->len--; + + FLOW_QUEUE_PKT_SETNEXT(pkt, NULL); /* dettach packet from queue */ + +done: + return pkt; +} + +void BCMFASTPATH /* Reinsert a dequeued packet back at the head */ +dhd_flow_queue_reinsert(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt) +{ + if (queue->head == NULL) { + queue->tail = pkt; + } + + FLOW_QUEUE_PKT_SETNEXT(pkt, queue->head); + queue->head = pkt; + queue->len++; +} + + +/* Init Flow Ring specific data structures */ +int +dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_flow_rings) +{ + uint32 idx; + uint32 flow_ring_table_sz; + uint32 if_flow_lkup_sz; + void * flowid_allocator; + flow_ring_table_t *flow_ring_table; + if_flow_lkup_t *if_flow_lkup; + + DHD_INFO(("%s\n", __FUNCTION__)); + + /* Construct a 16bit flow1d allocator */ + flowid_allocator = id16_map_init(dhdp->osh, + num_flow_rings - FLOW_RING_COMMON, FLOWID_RESERVED); + if (flowid_allocator == NULL) { + DHD_ERROR(("%s: flowid allocator init failure\n", __FUNCTION__)); + return BCME_ERROR; + } + + /* Allocate a flow ring table, comprising of requested number of rings */ + flow_ring_table_sz = (num_flow_rings * sizeof(flow_ring_node_t)); + flow_ring_table = (flow_ring_table_t *)MALLOC(dhdp->osh, flow_ring_table_sz); + if (flow_ring_table == NULL) { + DHD_ERROR(("%s: flow ring table alloc failure\n", __FUNCTION__)); + id16_map_fini(dhdp->osh, flowid_allocator); + return BCME_ERROR; + } + + /* Initialize flow ring table state */ + bzero((uchar *)flow_ring_table, flow_ring_table_sz); + for (idx = 0; idx < num_flow_rings; idx++) { + flow_ring_table[idx].status = FLOW_RING_STATUS_CLOSED; + flow_ring_table[idx].flowid = (uint16)idx; + dll_init(&flow_ring_table[idx].list); + + /* Initialize the per flow ring backup queue */ + dhd_flow_queue_init(dhdp, &flow_ring_table[idx].queue, + FLOW_RING_QUEUE_THRESHOLD); + } + + /* Allocate per interface hash table */ + if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS; + if_flow_lkup = (if_flow_lkup_t *)MALLOC(dhdp->osh, if_flow_lkup_sz); + if (if_flow_lkup == NULL) { + DHD_ERROR(("%s: if flow lkup alloc failure\n", __FUNCTION__)); + MFREE(dhdp->osh, flow_ring_table, flow_ring_table_sz); + id16_map_fini(dhdp->osh, flowid_allocator); + return BCME_ERROR; + } + + /* Initialize per interface hash table */ + bzero((uchar *)if_flow_lkup, if_flow_lkup_sz); + for (idx = 0; idx < DHD_MAX_IFS; idx++) { + int hash_ix; + if_flow_lkup[idx].status = 0; + if_flow_lkup[idx].role = 0; + for (hash_ix = 0; hash_ix < DHD_FLOWRING_HASH_SIZE; hash_ix++) + if_flow_lkup[idx].fl_hash[hash_ix] = NULL; + } + + /* Now populate into dhd pub */ + dhdp->num_flow_rings = num_flow_rings; + dhdp->flowid_allocator = (void *)flowid_allocator; + dhdp->flow_ring_table = (void *)flow_ring_table; + dhdp->if_flow_lkup = (void *)if_flow_lkup; + + dhdp->flow_prio_map_type = DHD_FLOW_PRIO_AC_MAP; + bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO); + + DHD_INFO(("%s done\n", __FUNCTION__)); + return BCME_OK; +} + +/* Deinit Flow Ring specific data structures */ +void dhd_flow_rings_deinit(dhd_pub_t *dhdp) +{ + uint16 idx; + uint32 flow_ring_table_sz; + uint32 if_flow_lkup_sz; + flow_ring_table_t *flow_ring_table; + DHD_INFO(("dhd_flow_rings_deinit\n")); + + if (dhdp->flow_ring_table != NULL) { + + ASSERT(dhdp->num_flow_rings > 0); + + flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; + for (idx = 0; idx < dhdp->num_flow_rings; idx++) { + if (flow_ring_table[idx].active) { + dhd_bus_clean_flow_ring(dhdp->bus, idx); + } + ASSERT(flow_queue_empty(&flow_ring_table[idx].queue)); + + /* Deinit flow ring queue locks before destroying flow ring table */ + dhd_os_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].queue.lock); + flow_ring_table[idx].queue.lock = NULL; + } + + /* Destruct the flow ring table */ + flow_ring_table_sz = dhdp->num_flow_rings * sizeof(flow_ring_table_t); + MFREE(dhdp->osh, dhdp->flow_ring_table, flow_ring_table_sz); + dhdp->flow_ring_table = NULL; + } + + /* Destruct the per interface flow lkup table */ + if (dhdp->if_flow_lkup != NULL) { + if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS; + MFREE(dhdp->osh, dhdp->if_flow_lkup, if_flow_lkup_sz); + dhdp->if_flow_lkup = NULL; + } + + /* Destruct the flowid allocator */ + if (dhdp->flowid_allocator != NULL) + dhdp->flowid_allocator = id16_map_fini(dhdp->osh, dhdp->flowid_allocator); + + dhdp->num_flow_rings = 0U; +} + +uint8 +dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex) +{ + if_flow_lkup_t *if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + ASSERT(if_flow_lkup); + return if_flow_lkup[ifindex].role; +} + +#ifdef WLTDLS +bool is_tdls_destination(dhd_pub_t *dhdp, uint8 *da) +{ + tdls_peer_node_t *cur = dhdp->peer_tbl.node; + while (cur != NULL) { + if (!memcmp(da, cur->addr, ETHER_ADDR_LEN)) { + return TRUE; + } + cur = cur->next; + } + return FALSE; +} +#endif /* WLTDLS */ + +/* For a given interface, search the hash table for a matching flow */ +static INLINE uint16 +dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da) +{ + int hash; + bool ismcast = FALSE; + flow_hash_info_t *cur; + if_flow_lkup_t *if_flow_lkup; + + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + + if (if_flow_lkup[ifindex].role == WLC_E_IF_ROLE_STA) { +#ifdef WLTDLS + if (dhdp->peer_tbl.tdls_peer_count && !(ETHER_ISMULTI(da)) && + is_tdls_destination(dhdp, da)) { + hash = DHD_FLOWRING_HASHINDEX(da, prio); + cur = if_flow_lkup[ifindex].fl_hash[hash]; + while (cur != NULL) { + if (!memcmp(cur->flow_info.da, da, ETHER_ADDR_LEN)) + return cur->flowid; + cur = cur->next; + } + return FLOWID_INVALID; + } +#endif /* WLTDLS */ + cur = if_flow_lkup[ifindex].fl_hash[prio]; + if (cur) { + return cur->flowid; + } + + } else { + + if (ETHER_ISMULTI(da)) { + ismcast = TRUE; + hash = 0; + } else { + hash = DHD_FLOWRING_HASHINDEX(da, prio); + } + + cur = if_flow_lkup[ifindex].fl_hash[hash]; + + while (cur) { + if ((ismcast && ETHER_ISMULTI(cur->flow_info.da)) || + (!memcmp(cur->flow_info.da, da, ETHER_ADDR_LEN) && + (cur->flow_info.tid == prio))) { + return cur->flowid; + } + cur = cur->next; + } + } + + return FLOWID_INVALID; +} + +/* Allocate Flow ID */ +static INLINE uint16 +dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da) +{ + flow_hash_info_t *fl_hash_node, *cur; + if_flow_lkup_t *if_flow_lkup; + int hash; + uint16 flowid; + + fl_hash_node = (flow_hash_info_t *) MALLOC(dhdp->osh, sizeof(flow_hash_info_t)); + memcpy(fl_hash_node->flow_info.da, da, sizeof(fl_hash_node->flow_info.da)); + + ASSERT(dhdp->flowid_allocator != NULL); + flowid = id16_map_alloc(dhdp->flowid_allocator); + + if (flowid == FLOWID_INVALID) { + MFREE(dhdp->osh, fl_hash_node, sizeof(flow_hash_info_t)); + DHD_ERROR(("%s: cannot get free flowid \n", __FUNCTION__)); + return FLOWID_INVALID; + } + + fl_hash_node->flowid = flowid; + fl_hash_node->flow_info.tid = prio; + fl_hash_node->flow_info.ifindex = ifindex; + fl_hash_node->next = NULL; + + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + if (if_flow_lkup[ifindex].role == WLC_E_IF_ROLE_STA) { + /* For STA non TDLS dest we allocate entry based on prio only */ +#ifdef WLTDLS + if (dhdp->peer_tbl.tdls_peer_count && + (is_tdls_destination(dhdp, da))) { + hash = DHD_FLOWRING_HASHINDEX(da, prio); + cur = if_flow_lkup[ifindex].fl_hash[hash]; + if (cur) { + while (cur->next) { + cur = cur->next; + } + cur->next = fl_hash_node; + } else { + if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node; + } + } else +#endif /* WLTDLS */ + if_flow_lkup[ifindex].fl_hash[prio] = fl_hash_node; + } else { + + /* For bcast/mcast assign first slot in in interface */ + hash = ETHER_ISMULTI(da) ? 0 : DHD_FLOWRING_HASHINDEX(da, prio); + cur = if_flow_lkup[ifindex].fl_hash[hash]; + if (cur) { + while (cur->next) { + cur = cur->next; + } + cur->next = fl_hash_node; + } else + if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node; + } + + DHD_INFO(("%s: allocated flowid %d\n", __FUNCTION__, fl_hash_node->flowid)); + + return fl_hash_node->flowid; +} + +/* Get flow ring ID, if not present try to create one */ +static INLINE int +dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex, + uint8 prio, char *sa, char *da, uint16 *flowid) +{ + uint16 id; + flow_ring_node_t *flow_ring_node; + flow_ring_table_t *flow_ring_table; + + DHD_INFO(("%s\n", __FUNCTION__)); + + flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; + + id = dhd_flowid_find(dhdp, ifindex, prio, sa, da); + + if (id == FLOWID_INVALID) { + + if_flow_lkup_t *if_flow_lkup; + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + + if (!if_flow_lkup[ifindex].status) + return BCME_ERROR; + + id = dhd_flowid_alloc(dhdp, ifindex, prio, sa, da); + if (id == FLOWID_INVALID) { + DHD_ERROR(("%s: alloc flowid ifindex %u status %u\n", + __FUNCTION__, ifindex, if_flow_lkup[ifindex].status)); + return BCME_ERROR; + } + + /* register this flowid in dhd_pub */ + dhd_add_flowid(dhdp, ifindex, prio, da, id); + } + + ASSERT(id < dhdp->num_flow_rings); + + flow_ring_node = (flow_ring_node_t *) &flow_ring_table[id]; + if (flow_ring_node->active) { + *flowid = id; + return BCME_OK; + } + + /* flow_ring_node->flowid = id; */ + + /* Init Flow info */ + memcpy(flow_ring_node->flow_info.sa, sa, sizeof(flow_ring_node->flow_info.sa)); + memcpy(flow_ring_node->flow_info.da, da, sizeof(flow_ring_node->flow_info.da)); + flow_ring_node->flow_info.tid = prio; + flow_ring_node->flow_info.ifindex = ifindex; + + /* Create and inform device about the new flow */ + if (dhd_bus_flow_ring_create_request(dhdp->bus, (void *)flow_ring_node) + != BCME_OK) { + DHD_ERROR(("%s: create error %d\n", __FUNCTION__, id)); + return BCME_ERROR; + } + flow_ring_node->active = TRUE; + + *flowid = id; + return BCME_OK; +} + +/* Update flowid information on the packet */ +int BCMFASTPATH +dhd_flowid_update(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, void *pktbuf) +{ + uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf); + struct ether_header *eh = (struct ether_header *)pktdata; + uint16 flowid; + + if (dhd_bus_is_txmode_push(dhdp->bus)) + return BCME_OK; + + ASSERT(ifindex < DHD_MAX_IFS); + if (ifindex >= DHD_MAX_IFS) { + return BCME_BADARG; + } + + if (!dhdp->flowid_allocator) { + DHD_ERROR(("%s: Flow ring not intited yet \n", __FUNCTION__)); + return BCME_ERROR; + } + if (dhd_flowid_lookup(dhdp, ifindex, prio, eh->ether_shost, eh->ether_dhost, + &flowid) != BCME_OK) { + return BCME_ERROR; + } + + DHD_INFO(("%s: prio %d flowid %d\n", __FUNCTION__, prio, flowid)); + + /* Tag the packet with flowid */ + DHD_PKTTAG_SET_FLOWID((dhd_pkttag_fr_t *)PKTTAG(pktbuf), flowid); + return BCME_OK; +} + +void +dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid) +{ + int hashix; + bool found = FALSE; + flow_hash_info_t *cur, *prev; + if_flow_lkup_t *if_flow_lkup; + + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + + for (hashix = 0; hashix < DHD_FLOWRING_HASH_SIZE; hashix++) { + + cur = if_flow_lkup[ifindex].fl_hash[hashix]; + + if (cur) { + if (cur->flowid == flowid) { + found = TRUE; + } + + prev = NULL; + while (!found && cur) { + if (cur->flowid == flowid) { + found = TRUE; + break; + } + prev = cur; + cur = cur->next; + } + if (found) { + if (!prev) { + if_flow_lkup[ifindex].fl_hash[hashix] = cur->next; + } else { + prev->next = cur->next; + } + + /* deregister flowid from dhd_pub. */ + dhd_del_flowid(dhdp, ifindex, flowid); + + id16_map_free(dhdp->flowid_allocator, flowid); + MFREE(dhdp->osh, cur, sizeof(flow_hash_info_t)); + + return; + } + } + } + + DHD_ERROR(("%s: could not free flow ring hash entry flowid %d\n", + __FUNCTION__, flowid)); +} + + +/* Delete all Flow rings assocaited with the given Interface */ +void +dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex) +{ + uint32 id; + flow_ring_table_t *flow_ring_table; + + DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex)); + + ASSERT(ifindex < DHD_MAX_IFS); + if (!dhdp->flow_ring_table) + return; + + flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; + for (id = 0; id < dhdp->num_flow_rings; id++) { + if (flow_ring_table[id].active && + (flow_ring_table[id].flow_info.ifindex == ifindex)) { + dhd_bus_flow_ring_delete_request(dhdp->bus, + (void *) &flow_ring_table[id]); + } + } +} + +/* Delete flow/s for given peer address */ +void +dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr) +{ + uint32 id; + flow_ring_table_t *flow_ring_table; + + DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex)); + + ASSERT(ifindex < DHD_MAX_IFS); + if (ifindex >= DHD_MAX_IFS) + return; + + if (!dhdp->flow_ring_table) + return; + + flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table; + for (id = 0; id < dhdp->num_flow_rings; id++) { + if (flow_ring_table[id].active && + (flow_ring_table[id].flow_info.ifindex == ifindex) && + (!memcmp(flow_ring_table[id].flow_info.da, addr, ETHER_ADDR_LEN)) && + (flow_ring_table[id].status != FLOW_RING_STATUS_DELETE_PENDING)) { + DHD_INFO(("%s: deleting flowid %d\n", + __FUNCTION__, flow_ring_table[id].flowid)); + dhd_bus_flow_ring_delete_request(dhdp->bus, + (void *) &flow_ring_table[id]); + } + } +} + +/* Handle Interface ADD, DEL operations */ +void +dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex, + uint8 op, uint8 role) +{ + if_flow_lkup_t *if_flow_lkup; + + ASSERT(ifindex < DHD_MAX_IFS); + if (ifindex >= DHD_MAX_IFS) + return; + + DHD_INFO(("%s: ifindex %u op %u role is %u \n", + __FUNCTION__, ifindex, op, role)); + if (!dhdp->flowid_allocator) { + DHD_ERROR(("%s: Flow ring not intited yet \n", __FUNCTION__)); + return; + } + + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + + if (op == WLC_E_IF_ADD || op == WLC_E_IF_CHANGE) { + + if_flow_lkup[ifindex].role = role; + + if (role != WLC_E_IF_ROLE_STA) { + if_flow_lkup[ifindex].status = TRUE; + DHD_INFO(("%s: Mcast Flow ring for ifindex %d role is %d \n", + __FUNCTION__, ifindex, role)); + /* Create Mcast Flow */ + } + } else if (op == WLC_E_IF_DEL) { + if_flow_lkup[ifindex].status = FALSE; + DHD_INFO(("%s: cleanup all Flow rings for ifindex %d role is %d \n", + __FUNCTION__, ifindex, role)); + } +} + +/* Handle a STA interface link status update */ +int +dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex, uint8 status) +{ + if_flow_lkup_t *if_flow_lkup; + + ASSERT(ifindex < DHD_MAX_IFS); + if (ifindex >= DHD_MAX_IFS) + return BCME_BADARG; + + if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup; + DHD_INFO(("%s: ifindex %d status %d\n", __FUNCTION__, ifindex, status)); + + if (if_flow_lkup[ifindex].role == WLC_E_IF_ROLE_STA) { + if (status) + if_flow_lkup[ifindex].status = TRUE; + else + if_flow_lkup[ifindex].status = FALSE; + } + return BCME_OK; +} +/* Update flow priority mapping */ +int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map) +{ + uint16 flowid; + flow_ring_node_t *flow_ring_node; + + if (map > DHD_FLOW_PRIO_TID_MAP) + return BCME_BADOPTION; + + /* Check if we need to change prio map */ + if (map == dhdp->flow_prio_map_type) + return BCME_OK; + + /* If any ring is active we cannot change priority mapping for flow rings */ + for (flowid = 0; flowid < dhdp->num_flow_rings; flowid++) { + flow_ring_node = DHD_FLOW_RING(dhdp, flowid); + if (flow_ring_node->active) + return BCME_EPERM; + } + /* Infor firmware about new mapping type */ + if (BCME_OK != dhd_flow_prio_map(dhdp, &map, TRUE)) + return BCME_ERROR; + + /* update internal structures */ + dhdp->flow_prio_map_type = map; + if (dhdp->flow_prio_map_type == DHD_FLOW_PRIO_TID_MAP) + bcopy(prio2tid, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO); + else + bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO); + + return BCME_OK; +} + +/* Set/Get flwo ring priority map */ +int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set) +{ + uint8 iovbuf[24]; + if (!set) { + bcm_mkiovar("bus:fl_prio_map", NULL, 0, (char*)iovbuf, sizeof(iovbuf)); + if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0) < 0) { + DHD_ERROR(("%s: failed to get fl_prio_map\n", __FUNCTION__)); + return BCME_ERROR; + } + *map = iovbuf[0]; + return BCME_OK; + } + bcm_mkiovar("bus:fl_prio_map", (char *)map, 4, (char*)iovbuf, sizeof(iovbuf)); + if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { + DHD_ERROR(("%s: failed to set fl_prio_map \n", + __FUNCTION__)); + return BCME_ERROR; + } + return BCME_OK; +} diff --git a/drivers/net/wireless/bcmdhd/dhd_flowring.h b/drivers/net/wireless/bcmdhd/dhd_flowring.h new file mode 100644 index 0000000000000000000000000000000000000000..c2e2d83489c46f068d49e9e0102aa428f4c742be --- /dev/null +++ b/drivers/net/wireless/bcmdhd/dhd_flowring.h @@ -0,0 +1,175 @@ +/* + * Header file describing the flow rings DHD interfaces. + * + * Provides type definitions and function prototypes used to create, delete and manage + * + * flow rings at high level + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_flowrings.h jaganlv $ + */ + +/**************** + * Common types * + */ + +#ifndef _dhd_flowrings_h_ +#define _dhd_flowrings_h_ + +/* Max pkts held in a flow ring's backup queue */ +#define FLOW_RING_QUEUE_THRESHOLD (2048) + +/* Number of H2D common rings : PCIE Spec Rev? */ +#define FLOW_RING_COMMON 2 + +#define FLOWID_INVALID (ID16_INVALID) +#define FLOWID_RESERVED (FLOW_RING_COMMON) + +#define FLOW_RING_STATUS_OPEN 0 +#define FLOW_RING_STATUS_PENDING 1 +#define FLOW_RING_STATUS_CLOSED 2 +#define FLOW_RING_STATUS_DELETE_PENDING 3 +#define FLOW_RING_STATUS_FLUSH_PENDING 4 + +#define DHD_FLOWRING_RX_BUFPOST_PKTSZ 2048 + +#define DHD_FLOW_PRIO_AC_MAP 0 +#define DHD_FLOW_PRIO_TID_MAP 1 + + +/* Pkttag not compatible with PROP_TXSTATUS or WLFC */ +typedef struct dhd_pkttag_fr { + uint16 flowid; + int dataoff; +} dhd_pkttag_fr_t; + +#define DHD_PKTTAG_SET_FLOWID(tag, flow) ((tag)->flowid = (uint16)(flow)) +#define DHD_PKTTAG_SET_DATAOFF(tag, offset) ((tag)->dataoff = (int)(offset)) + +#define DHD_PKTTAG_FLOWID(tag) ((tag)->flowid) +#define DHD_PKTTAG_DATAOFF(tag) ((tag)->dataoff) + +/* Hashing a MacAddress for lkup into a per interface flow hash table */ +#define DHD_FLOWRING_HASH_SIZE 256 +#define DHD_FLOWRING_HASHINDEX(ea, prio) \ + ((((uint8 *)(ea))[3] ^ ((uint8 *)(ea))[4] ^ ((uint8 *)(ea))[5] ^ ((uint8)(prio))) \ + % DHD_FLOWRING_HASH_SIZE) + +#define DHD_IF_ROLE(pub, idx) (((if_flow_lkup_t *)(pub)->if_flow_lkup)[idx].role) +#define DHD_IF_ROLE_AP(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_AP) +#define DHD_IF_ROLE_P2PGO(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_P2P_GO) +#define DHD_FLOW_RING(dhdp, flowid) \ + (flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid]) + +struct flow_queue; + +/* Flow Ring Queue Enqueue overflow callback */ +typedef int (*flow_queue_cb_t)(struct flow_queue * queue, void * pkt); + +typedef struct flow_queue { + dll_t list; /* manage a flowring queue in a dll */ + void * head; /* first packet in the queue */ + void * tail; /* last packet in the queue */ + uint16 len; /* number of packets in the queue */ + uint16 max; /* maximum number of packets, queue may hold */ + uint32 failures; /* enqueue failures due to queue overflow */ + flow_queue_cb_t cb; /* callback invoked on threshold crossing */ + void * lock; /* OS specific lock handle for Q access protection */ +} flow_queue_t; + +#define flow_queue_len(queue) ((int)(queue)->len) +#define flow_queue_max(queue) ((int)(queue)->max) +#define flow_queue_avail(queue) ((int)((queue)->max - (queue)->len)) +#define flow_queue_full(queue) ((queue)->len >= (queue)->max) +#define flow_queue_empty(queue) ((queue)->len == 0) + +typedef struct flow_info { + uint8 tid; + uint8 ifindex; + char sa[ETHER_ADDR_LEN]; + char da[ETHER_ADDR_LEN]; +} flow_info_t; + +typedef struct flow_ring_node { + dll_t list; /* manage a constructed flowring in a dll, must be at first place */ + flow_queue_t queue; + bool active; + uint8 status; + uint16 flowid; + flow_info_t flow_info; + void *prot_info; +} flow_ring_node_t; +typedef flow_ring_node_t flow_ring_table_t; + +typedef struct flow_hash_info { + uint16 flowid; + flow_info_t flow_info; + struct flow_hash_info *next; +} flow_hash_info_t; + +typedef struct if_flow_lkup { + bool status; + uint8 role; /* Interface role: STA/AP */ + flow_hash_info_t *fl_hash[DHD_FLOWRING_HASH_SIZE]; /* Lkup Hash table */ +} if_flow_lkup_t; + +static INLINE flow_ring_node_t * +dhd_constlist_to_flowring(dll_t *item) +{ + return ((flow_ring_node_t *)item); +} + +/* Exported API */ + +/* Flow ring's queue management functions */ +extern void dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max); +extern void dhd_flow_queue_register(flow_queue_t *queue, flow_queue_cb_t cb); +extern int dhd_flow_queue_enqueue(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt); +extern void * dhd_flow_queue_dequeue(dhd_pub_t *dhdp, flow_queue_t *queue); +extern void dhd_flow_queue_reinsert(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt); + +extern int dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_flow_rings); + +extern void dhd_flow_rings_deinit(dhd_pub_t *dhdp); + +extern int dhd_flowid_update(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, + void *pktbuf); + +extern void dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid); + +extern void dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex); + +extern void dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, + char *addr); + +/* Handle Interface ADD, DEL operations */ +extern void dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex, + uint8 op, uint8 role); + +/* Handle a STA interface link status update */ +extern int dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex, + uint8 status); +extern int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set); +extern int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map); + +extern uint8 dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex); +#endif /* _dhd_flowrings_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_ip.c b/drivers/net/wireless/bcmdhd/dhd_ip.c index deef74455b625e2c20912aded8606184d7bb68dd..55657c36752d0942694b84a92d90856ff56c031b 100644 --- a/drivers/net/wireless/bcmdhd/dhd_ip.c +++ b/drivers/net/wireless/bcmdhd/dhd_ip.c @@ -1,7 +1,25 @@ /* * IP Packet Parser Module. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_ip.c 468932 2014-04-09 06:58:15Z $ */ @@ -13,7 +31,7 @@ #include <proto/802.3.h> #include <proto/bcmip.h> #include <bcmendian.h> - +#include <bcmutils.h> #include <dhd_dbg.h> #include <dhd_ip.h> @@ -98,6 +116,68 @@ pkt_frag_t pkt_frag_info(osl_t *osh, void *p) } } +bool pkt_is_dhcp(osl_t *osh, void *p) +{ + uint8 *frame; + int length; + uint8 *pt; /* Pointer to type field */ + uint16 ethertype; + struct ipv4_hdr *iph; /* IP frame pointer */ + int ipl; /* IP frame length */ + uint16 src_port; + + frame = PKTDATA(osh, p); + length = PKTLEN(osh, p); + + /* Process Ethernet II or SNAP-encapsulated 802.3 frames */ + if (length < ETHER_HDR_LEN) { + DHD_INFO(("%s: short eth frame (%d)\n", __FUNCTION__, length)); + return FALSE; + } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) { + /* Frame is Ethernet II */ + pt = frame + ETHER_TYPE_OFFSET; + } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN && + !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) { + pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN; + } else { + DHD_INFO(("%s: non-SNAP 802.3 frame\n", __FUNCTION__)); + return FALSE; + } + + ethertype = ntoh16(*(uint16 *)pt); + + /* Skip VLAN tag, if any */ + if (ethertype == ETHER_TYPE_8021Q) { + pt += VLAN_TAG_LEN; + + if (pt + ETHER_TYPE_LEN > frame + length) { + DHD_INFO(("%s: short VLAN frame (%d)\n", __FUNCTION__, length)); + return FALSE; + } + + ethertype = ntoh16(*(uint16 *)pt); + } + + if (ethertype != ETHER_TYPE_IP) { + DHD_INFO(("%s: non-IP frame (ethertype 0x%x, length %d)\n", + __FUNCTION__, ethertype, length)); + return FALSE; + } + + iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN); + ipl = (uint)(length - (pt + ETHER_TYPE_LEN - frame)); + + /* We support IPv4 only */ + if ((ipl < (IPV4_OPTIONS_OFFSET + 2)) || (IP_VER(iph) != IP_VER_4)) { + DHD_INFO(("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl)); + return FALSE; + } + + src_port = ntoh16(*(uint16 *)(pt + ETHER_TYPE_LEN + IPV4_OPTIONS_OFFSET)); + + return (src_port == 0x43 || src_port == 0x44); +} + #ifdef DHDTCPACK_SUPPRESS typedef struct { @@ -854,7 +934,7 @@ dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt) bcopy(last_tdata_info, tdata_info_tmp, sizeof(tcpdata_info_t)); } bzero(last_tdata_info, sizeof(tcpdata_info_t)); - DHD_ERROR(("%s %d: tcpdata_info(idx %d) is aged out. ttl cnt is now %d\n", + DHD_TRACE(("%s %d: tcpdata_info(idx %d) is aged out. ttl cnt is now %d\n", __FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt)); /* Don't increase "i" here, so that the prev last tcpdata_info is checked */ } else @@ -883,7 +963,7 @@ dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt) /* No TCP flow with the same IP addr and TCP port is found * in tcp_data_info_tbl. So add this flow to the table. */ - DHD_ERROR(("%s %d: Add data info to tbl[%d]: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR + DHD_TRACE(("%s %d: Add data info to tbl[%d]: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, tcpack_sup_mod->tcpdata_info_cnt, IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])), diff --git a/drivers/net/wireless/bcmdhd/dhd_ip.h b/drivers/net/wireless/bcmdhd/dhd_ip.h index 414a94fbcb122cfe59fa649e4c5ee2be73c22bc8..835046c026fb6d129896a8bf02c72ea7bf9fbaf2 100644 --- a/drivers/net/wireless/bcmdhd/dhd_ip.h +++ b/drivers/net/wireless/bcmdhd/dhd_ip.h @@ -3,7 +3,25 @@ * * Provides type definitions and function prototypes used to parse ip packet. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_ip.h 458522 2014-02-27 02:26:15Z $ */ @@ -26,6 +44,7 @@ typedef enum pkt_frag } pkt_frag_t; extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p); +extern bool pkt_is_dhcp(osl_t *osh, void *p); #ifdef DHDTCPACK_SUPPRESS #define TCPACKSZMIN (ETHER_HDR_LEN + IPV4_MIN_HEADER_LEN + TCP_MIN_HEADER_LEN) diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index 1d1c276ba71c7ffc8274703c95cfca800381a58f..a731a535cac1f1b96c3724bdc69a552e30157da4 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -2,9 +2,27 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_linux.c 491481 2014-07-16 14:08:43Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_linux.c 477711 2014-05-14 08:45:17Z $ */ #include <typedefs.h> @@ -74,10 +92,8 @@ #ifdef PNO_SUPPORT #include <dhd_pno.h> #endif -#ifdef WLBTAMP -#include <proto/802.11_bta.h> -#include <proto/bt_amp_hci.h> -#include <dhd_bta.h> +#ifdef RTT_SUPPORT +#include <dhd_rtt.h> #endif #ifdef CONFIG_COMPAT @@ -88,17 +104,10 @@ #include <dhd_wmf_linux.h> #endif /* DHD_WMF */ -#ifdef AMPDU_VO_ENABLE -#include <proto/802.1d.h> -#endif /* AMPDU_VO_ENABLE */ #ifdef DHDTCPACK_SUPPRESS #include <dhd_ip.h> #endif /* DHDTCPACK_SUPPRESS */ -#if defined(DHD_TCP_WINSIZE_ADJUST) -#include <linux/tcp.h> -#include <net/tcp.h> -#endif /* DHD_TCP_WINSIZE_ADJUST */ #ifdef WLMEDIA_HTSF #include <linux/time.h> @@ -126,15 +135,6 @@ typedef struct histo_ { static histo_t vi_d1, vi_d2, vi_d3, vi_d4; #endif /* WLMEDIA_HTSF */ -#if defined(DHD_TCP_WINSIZE_ADJUST) -#define MIN_TCP_WIN_SIZE 18000 -#define WIN_SIZE_SCALE_FACTOR 2 -#define MAX_TARGET_PORTS 5 - -static uint target_ports[MAX_TARGET_PORTS] = {20, 0, 0, 0, 0}; -static uint dhd_use_tcp_window_size_adjust = FALSE; -static void dhd_adjust_tcp_winsize(int op_mode, struct sk_buff *skb); -#endif /* DHD_TCP_WINSIZE_ADJUST */ #if defined(SOFTAP) @@ -205,10 +205,10 @@ DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); #if defined(OOB_INTR_ONLY) extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) static void dhd_hang_process(void *dhd_info, void *event_data, u8 event); -#endif +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) MODULE_LICENSE("GPL v2"); #endif /* LinuxVer */ @@ -269,19 +269,14 @@ extern int dhd_write_macaddr(struct ether_addr *mac); static inline int dhd_write_macaddr(struct ether_addr *mac) { return 0; } #endif -#if defined(SOFTAP_TPUT_ENHANCE) -extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time); -extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int* idle_time); -#endif /* SOFTAP_TPUT_ENHANCE */ static int dhd_reboot_callback(struct notifier_block *this, unsigned long code, void *unused); static struct notifier_block dhd_reboot_notifier = { - .notifier_call = dhd_reboot_callback, - .priority = 1, + .notifier_call = dhd_reboot_callback, + .priority = 1, }; - typedef struct dhd_if_event { struct list_head list; wl_event_data_if_t event; @@ -377,6 +372,8 @@ typedef struct dhd_info { htsf_t htsf; #endif wait_queue_head_t ioctl_resp_wait; + wait_queue_head_t d3ack_wait; + uint32 default_wd_interval; struct timer_list timer; @@ -402,7 +399,7 @@ typedef struct dhd_info { struct wake_lock wl_wdwake; /* Wifi wd wakelock */ #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) /* net_device interface lock, prevent race conditions among net_dev interface * calls and wifi_on or wifi_off */ @@ -449,6 +446,10 @@ typedef struct dhd_info { #endif unsigned int unit; struct notifier_block pm_notifier; +#ifdef SAR_SUPPORT + struct notifier_block sar_notifier; + s32 sar_enable; +#endif } dhd_info_t; #define DHDIF_FWDER(dhdif) FALSE @@ -587,11 +588,7 @@ module_param(instance_base, int, 0644); #endif /* PCIE_FULL_DONGLE */ /* Control fw roaming */ -#ifdef BCMCCX -uint dhd_roam_disable = 0; -#else uint dhd_roam_disable = 0; -#endif /* BCMCCX */ /* Control radio state */ uint dhd_radio_up = 1; @@ -650,11 +647,6 @@ uint dhd_pktgen_len = 0; module_param(dhd_pktgen_len, uint, 0); #endif /* SDTEST */ -#if defined(BCMSUP_4WAY_HANDSHAKE) -/* Use in dongle supplicant for 4-way handshake */ -uint dhd_use_idsup = 0; -module_param(dhd_use_idsup, uint, 0); -#endif /* BCMSUP_4WAY_HANDSHAKE */ extern char dhd_version[]; @@ -806,6 +798,56 @@ dhd_dev_priv_save(struct net_device * dev, dhd_info_t * dhd, dhd_if_t * ifp, dev_priv->ifp = ifp; dev_priv->ifidx = ifidx; } +#ifdef SAR_SUPPORT +static int dhd_sar_callback(struct notifier_block *nfb, unsigned long action, void *data) +{ + dhd_info_t *dhd = (dhd_info_t*)container_of(nfb, struct dhd_info, sar_notifier); + char iovbuf[32]; + s32 sar_enable; + s32 txpower; + int ret; + + if (dhd->pub.busstate == DHD_BUS_DOWN) + return NOTIFY_DONE; + + if (data) { + /* if data != NULL then we expect that the notifier passed + * the exact value of max tx power in quarters of dB. + * qtxpower variable allows us to overwrite TX power. + */ + txpower = *(s32*)data; + if (txpower == -1 || txpower > 127) + txpower = 127; /* Max val of 127 qdbm */ + + txpower |= WL_TXPWR_OVERRIDE; + txpower = htod32(txpower); + + bcm_mkiovar("qtxpower", (char *)&txpower, 4, iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(&dhd->pub, WLC_SET_VAR, + iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) + DHD_ERROR(("%s wl qtxpower failed %d\n", __FUNCTION__, ret)); + } else { + /* '1' means activate sarlimit and '0' means back to normal + * state (deactivate sarlimit) + */ + sar_enable = action ? 1 : 0; + if (dhd->sar_enable == sar_enable) + return NOTIFY_DONE; + bcm_mkiovar("sar_enable", (char *)&sar_enable, 4, iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(&dhd->pub, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) + DHD_ERROR(("%s wl sar_enable %d failed %d\n", __FUNCTION__, sar_enable, ret)); + else + dhd->sar_enable = sar_enable; + } + + return NOTIFY_DONE; +} + +static bool dhd_sar_notifier_registered = FALSE; + +extern int register_notifier_by_sar(struct notifier_block *nb); +extern int unregister_notifier_by_sar(struct notifier_block *nb); +#endif #ifdef PCIE_FULL_DONGLE @@ -1257,9 +1299,7 @@ static inline void* dhd_rxf_dequeue(dhd_pub_t *dhdp) int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost) { -#ifndef CUSTOMER_HW10 dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -#endif /* !CUSTOMER_HW10 */ if (prepost) { /* pre process */ dhd_read_macaddr(dhd); @@ -1368,7 +1408,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) #endif /* Kernel suspended */ DHD_ERROR(("%s: force extra Suspend setting \n", __FUNCTION__)); - +#ifdef CUSTOM_SET_SHORT_DWELL_TIME + dhd_set_short_dwell_time(dhd, TRUE); +#endif #ifndef SUPPORT_PM2_ONLY dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); @@ -1377,7 +1419,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) /* Enable packet filter, only allow unicast packet to send up */ dhd_enable_packet_filter(1, dhd); -#if 0 + /* If DTIM skip is set up as default, force it to wake * each third DTIM for better power savings. Note that * one side effect is a chance to miss BC/MC packet. @@ -1388,7 +1430,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) DHD_ERROR(("%s: set dtim failed\n", __FUNCTION__)); -#endif #ifndef ENABLE_FW_ROAM_SUSPEND /* Disable firmware roaming during suspend */ @@ -1396,7 +1437,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); #endif /* ENABLE_FW_ROAM_SUSPEND */ -#if 0 if (FW_SUPPORTED(dhd, ndoe)) { /* enable IPv6 RA filter in firmware during suspend */ nd_ra_filter = 1; @@ -1407,14 +1447,15 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) DHD_ERROR(("failed to set nd_ra_filter (%d)\n", ret)); } -#endif } else { #ifdef PKT_FILTER_SUPPORT dhd->early_suspended = 0; #endif /* Kernel resumed */ DHD_ERROR(("%s: Remove extra suspend setting \n", __FUNCTION__)); - +#ifdef CUSTOM_SET_SHORT_DWELL_TIME + dhd_set_short_dwell_time(dhd, FALSE); +#endif #ifndef SUPPORT_PM2_ONLY power_mode = PM_FAST; dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, @@ -1603,6 +1644,11 @@ dhd_ifidx2hostidx(dhd_info_t *dhd, int ifidx) ASSERT(dhd); + if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { + DHD_ERROR(("%s: ifidx %d out of range\n", __FUNCTION__, ifidx)); + return 0; /* default - the primary interface */ + } + while (--i > 0) if (dhd->iflist[i] && (dhd->iflist[i]->idx == ifidx)) break; @@ -1838,7 +1884,7 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event) struct net_device *ndev; int ifidx, bssidx; int ret; -#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) struct wireless_dev *vwdev, *primary_wdev; struct net_device *primary_ndev; #endif /* OEM_ANDROID && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */ @@ -1873,7 +1919,7 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event) goto done; } -#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL); if (unlikely(!vwdev)) { WL_ERR(("Could not allocate wireless device\n")); @@ -2176,7 +2222,7 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) /* Look into the packet and update the packet priority */ #ifndef PKTPRIO_OVERRIDE if (PKTPRIO(pktbuf) == 0) -#endif +#endif pktsetprio(pktbuf, FALSE); @@ -2546,9 +2592,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { struct ether_header *eh; -#ifdef WLBTAMP - struct dot11_llc_snap_header *lsh; -#endif pnext = PKTNEXT(dhdp->osh, pktbuf); PKTSETNEXT(dhdp->osh, pktbuf, NULL); @@ -2577,18 +2620,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) continue; } -#ifdef WLBTAMP - lsh = (struct dot11_llc_snap_header *)&eh[1]; - - if ((ntoh16(eh->ether_type) < ETHER_TYPE_MIN) && - (PKTLEN(dhdp->osh, pktbuf) >= RFC1042_HDR_LEN) && - bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && - lsh->type == HTON16(BTA_PROT_L2CAP)) { - amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *) - ((uint8 *)eh + RFC1042_HDR_LEN); - ACL_data = NULL; - } -#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS if (dhd_wlfc_is_header_only_pkt(dhdp, pktbuf)) { @@ -2744,11 +2775,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) wl_event_to_host_order(&event); if (!tout_ctrl) tout_ctrl = DHD_PACKET_TIMEOUT_MS; -#ifdef WLBTAMP - if (event.event_type == WLC_E_BTA_HCI_EVENT) { - dhd_bta_doevt(dhdp, data, event.datalen); - } -#endif /* WLBTAMP */ #if defined(PNO_SUPPORT) if (event.event_type == WLC_E_PFN_NET_FOUND) { @@ -2781,13 +2807,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) ifp->stats.rx_bytes += skb->len; ifp->stats.rx_packets++; } -#if defined(DHD_TCP_WINSIZE_ADJUST) - if (dhd_use_tcp_window_size_adjust) { - if (ifidx == 0 && ntoh16(skb->protocol) == ETHER_TYPE_IP) { - dhd_adjust_tcp_winsize(dhdp->op_mode, skb); - } - } -#endif /* DHD_TCP_WINSIZE_ADJUST */ if (in_interrupt()) { netif_rx(skb); @@ -2839,9 +2858,6 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); struct ether_header *eh; uint16 type; -#ifdef WLBTAMP - uint len; -#endif dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL); @@ -2851,23 +2867,6 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) if (type == ETHER_TYPE_802_1X) atomic_dec(&dhd->pend_8021x_cnt); -#ifdef WLBTAMP - /* Crack open the packet and check to see if it is BT HCI ACL data packet. - * If yes generate packet completion event. - */ - len = PKTLEN(dhdp->osh, txp); - - /* Generate ACL data tx completion event locally to avoid SDIO bus transaction */ - if ((type < ETHER_TYPE_MIN) && (len >= RFC1042_HDR_LEN)) { - struct dot11_llc_snap_header *lsh = (struct dot11_llc_snap_header *)&eh[1]; - - if (bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && - ntoh16(lsh->type) == BTA_PROT_L2CAP) { - - dhd_bta_tx_hcidata_complete(dhdp, txp, success); - } - } -#endif /* WLBTAMP */ } static struct net_device_stats * @@ -3160,13 +3159,15 @@ void dhd_dpc_kill(dhd_pub_t *dhdp) dhd = dhdp->info; - if (!dhd) + if(!dhd) return; tasklet_kill(&dhd->tasklet); - DHD_ERROR(("%s: tasklet disabled\n", __FUNCTION__)); + DHD_ERROR(("%s: tasklet disabled\n",__FUNCTION__)); } -#endif /* BCMPCIE */ +#endif + +static int isresched = 0; static void dhd_dpc(ulong data) @@ -3181,7 +3182,8 @@ dhd_dpc(ulong data) */ /* Call bus dpc unless it indicated down (then clean stop) */ if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) + isresched = dhd_bus_dpc(dhd->pub.bus); + if (isresched) tasklet_schedule(&dhd->tasklet); else DHD_OS_WAKE_UNLOCK(&dhd->pub); @@ -3196,16 +3198,19 @@ dhd_sched_dpc(dhd_pub_t *dhdp) { dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - DHD_OS_WAKE_LOCK(dhdp); if (dhd->thr_dpc_ctl.thr_pid >= 0) { /* If the semaphore does not get up, * wake unlock should be done here */ + DHD_OS_WAKE_LOCK(dhdp); if (!binary_sema_up(&dhd->thr_dpc_ctl)) DHD_OS_WAKE_UNLOCK(dhdp); return; } else { - tasklet_schedule(&dhd->tasklet); + if (!test_bit(TASKLET_STATE_SCHED, &dhd->tasklet.state) && !isresched) { + DHD_OS_WAKE_LOCK(dhdp); + tasklet_schedule(&dhd->tasklet); + } } } @@ -3335,37 +3340,6 @@ dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol) } #endif /* TOE */ -#if defined(WL_CFG80211) -void dhd_set_scb_probe(dhd_pub_t *dhd) -{ -#define NUM_SCB_MAX_PROBE 3 - int ret = 0; - wl_scb_probe_t scb_probe; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - memset(&scb_probe, 0, sizeof(wl_scb_probe_t)); - - if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) - return; - - bcm_mkiovar("scb_probe", NULL, 0, iovbuf, sizeof(iovbuf)); - - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("%s: GET max_scb_probe failed\n", __FUNCTION__)); - - memcpy(&scb_probe, iovbuf, sizeof(wl_scb_probe_t)); - - scb_probe.scb_max_probe = NUM_SCB_MAX_PROBE; - - bcm_mkiovar("scb_probe", (char *)&scb_probe, - sizeof(wl_scb_probe_t), iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("%s: max_scb_probe setting failed\n", __FUNCTION__)); -#undef NUM_SCB_MAX_PROBE - return; -} -#endif /* WL_CFG80211 */ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) static void dhd_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) @@ -3512,7 +3486,7 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) DHD_ERROR(("%s : skipped due to negative pid - unloading?\n", __FUNCTION__)); return FALSE; } -#endif +#endif if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) || ((dhdp->busstate == DHD_BUS_DOWN) && (!dhdp->dongle_reset))) { @@ -3850,27 +3824,29 @@ exit: #if defined(WL_CFG80211) if (ifidx == 0 && !dhd_download_fw_on_driverload) wl_android_wifi_off(net); -#endif +#endif dhd->pub.rxcnt_timeout = 0; dhd->pub.txcnt_timeout = 0; dhd->pub.hang_was_sent = 0; /* Clear country spec for for built-in type driver */ +#ifndef CUSTOM_COUNTRY_CODE if (!dhd_download_fw_on_driverload) { dhd->pub.dhd_cspec.country_abbrev[0] = 0x00; dhd->pub.dhd_cspec.rev = 0; dhd->pub.dhd_cspec.ccode[0] = 0x00; } - +#endif DHD_PERIM_UNLOCK(&dhd->pub); DHD_OS_WAKE_UNLOCK(&dhd->pub); return 0; } -#if defined(WL_CFG80211) && defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(WL_CFG80211) && (defined(USE_INITIAL_2G_SCAN) || \ + defined(USE_INITIAL_SHORT_DWELL_TIME)) extern bool g_first_broadcast_scan; -#endif +#endif /* OEM_ANDROID && WL_CFG80211 && (USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME) */ #ifdef WL11U static int dhd_interworking_enable(dhd_pub_t *dhd) @@ -3910,14 +3886,6 @@ dhd_open(struct net_device *net) -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 && defined(BCMSDIO) - if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { - DHD_ERROR(("%s : dhd_open: call dev open before insmod complete!\n", __FUNCTION__)); - } - mutex_lock(&_dhd_sdio_mutex_lock_); -#endif -#endif /* MULTIPLE_SUPPLICANT */ DHD_OS_WAKE_LOCK(&dhd->pub); DHD_PERIM_LOCK(&dhd->pub); @@ -3937,7 +3905,7 @@ dhd_open(struct net_device *net) goto exit; } -#endif +#endif ifidx = dhd_net2idx(dhd, net); DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); @@ -3959,9 +3927,9 @@ dhd_open(struct net_device *net) #if defined(WL_CFG80211) if (!dhd_download_fw_on_driverload) { DHD_ERROR(("\n%s\n", dhd_version)); -#if defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME) g_first_broadcast_scan = TRUE; -#endif +#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */ ret = wl_android_wifi_on(net); if (ret != 0) { DHD_ERROR(("%s : wl_android_wifi_on failed (%d)\n", @@ -3970,7 +3938,7 @@ dhd_open(struct net_device *net) goto exit; } } -#endif +#endif if (dhd->pub.busstate != DHD_BUS_DATA) { @@ -4003,7 +3971,6 @@ dhd_open(struct net_device *net) ret = -1; goto exit; } - dhd_set_scb_probe(&dhd->pub); #endif /* WL_CFG80211 */ } @@ -4023,11 +3990,6 @@ exit: DHD_PERIM_UNLOCK(&dhd->pub); DHD_OS_WAKE_UNLOCK(&dhd->pub); -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 && defined(BCMSDIO) - mutex_unlock(&_dhd_sdio_mutex_lock_); -#endif -#endif /* MULTIPLE_SUPPLICANT */ return ret; } @@ -4041,14 +4003,6 @@ int dhd_do_driver_init(struct net_device *net) return -EINVAL; } -#ifdef MULTIPLE_SUPPLICANT -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 && defined(BCMSDIO) - if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { - DHD_ERROR(("%s : dhdsdio_probe is already running!\n", __FUNCTION__)); - return 0; - } -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -#endif /* MULTIPLE_SUPPLICANT */ /* && defined(OEM_ANDROID) && defined(BCMSDIO) */ dhd = DHD_DEV_INFO(net); @@ -4455,7 +4409,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) /* will implement get_ids for DBUS later */ #if defined(BCMSDIO) dhd_bus_get_ids(bus, &bus_type, &bus_num, &slot_num); -#endif +#endif adapter = dhd_wifi_platform_get_adapter(bus_type, bus_num, slot_num); /* Allocate primary dhd_info */ @@ -4478,6 +4432,18 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) #ifdef GET_CUSTOM_MAC_ENABLE wifi_platform_get_mac_addr(dhd->adapter, dhd->pub.mac.octet); #endif /* GET_CUSTOM_MAC_ENABLE */ +#ifdef CUSTOM_FORCE_NODFS_FLAG + dhd->pub.dhd_cflags |= WLAN_PLAT_NODFS_FLAG; + dhd->pub.force_country_change = TRUE; +#endif +#ifdef CUSTOM_COUNTRY_CODE + get_customized_country_code(dhd->adapter, + dhd->pub.dhd_cspec.country_abbrev, &dhd->pub.dhd_cspec, + dhd->pub.dhd_cflags); +#endif /* CUSTOM_COUNTRY_CODE */ + + dhd->pub.short_dwell_time = -1; + dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID; dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID; @@ -4532,6 +4498,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) /* Initialize other structure content */ init_waitqueue_head(&dhd->ioctl_resp_wait); + init_waitqueue_head(&dhd->d3ack_wait); init_waitqueue_head(&dhd->ctrl_wait); /* Initialize the spinlocks */ @@ -4559,7 +4526,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake"); wake_lock_init(&dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake"); #endif /* CONFIG_HAS_WAKELOCK */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) mutex_init(&dhd->dhd_net_if_mutex); mutex_init(&dhd->dhd_suspend_mutex); #endif @@ -4645,7 +4612,14 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) register_pm_notifier(&dhd_pm_notifier); } #endif /* CONFIG_PM_SLEEP */ - +#ifdef SAR_SUPPORT + dhd->sar_notifier.notifier_call = dhd_sar_callback; + if (!dhd_sar_notifier_registered) { + dhd_sar_notifier_registered = TRUE; + dhd->sar_enable = 1; /* unknown state value */ + register_notifier_by_sar(&dhd->sar_notifier); + } +#endif /* SAR_SUPPORT */ #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; dhd->early_suspend.suspend = dhd_early_suspend; @@ -4675,7 +4649,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) #endif #ifdef DHDTCPACK_SUPPRESS #ifdef BCMSDIO - dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_DELAYTX); + dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_REPLACE); #elif defined(BCMPCIE) dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_REPLACE); #else @@ -4787,7 +4761,6 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) /* clear the path in module parameter */ firmware_path[0] = '\0'; - nvram_path[0] = '\0'; #ifndef BCMEMBEDIMAGE /* fw_path and nv_path are not mandatory for BCMEMBEDIMAGE */ @@ -4805,9 +4778,6 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) } -#ifdef EXYNOS5433_PCIE_WAR -extern int enum_wifi; -#endif /* EXYNOS5433_PCIE_WAR */ int dhd_bus_start(dhd_pub_t *dhdp) { @@ -4827,17 +4797,11 @@ dhd_bus_start(dhd_pub_t *dhdp) ret = dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, dhd->fw_path, dhd->nv_path); if (ret < 0) { -#ifdef EXYNOS5433_PCIE_WAR - enum_wifi = 0; -#endif /* EXYNOS5433_PCIE_WAR */ DHD_ERROR(("%s: failed to download firmware %s\n", __FUNCTION__, dhd->fw_path)); DHD_PERIM_UNLOCK(dhdp); return ret; } -#ifdef EXYNOS5433_PCIE_WAR - enum_wifi = 1; -#endif /* EXYNOS5433_PCIE_WAR */ } if (dhd->pub.busstate != DHD_BUS_LOAD) { DHD_PERIM_UNLOCK(dhdp); @@ -4877,7 +4841,7 @@ dhd_bus_start(dhd_pub_t *dhdp) /* Enable oob at firmware */ dhd_enable_oob_intr(dhd->pub.bus, TRUE); -#endif +#endif #ifdef PCIE_FULL_DONGLE { uint8 txpush = 0; @@ -4886,7 +4850,6 @@ dhd_bus_start(dhd_pub_t *dhdp) DHD_ERROR(("%s: Initializing %u flowrings\n", __FUNCTION__, num_flowrings)); if ((ret = dhd_flow_rings_init(&dhd->pub, num_flowrings)) != BCME_OK) { - dhd_os_sdunlock(dhdp); DHD_PERIM_UNLOCK(dhdp); return ret; } @@ -5053,7 +5016,7 @@ void dhd_tdls_update_peer_info(struct net_device *dev, bool connect, uint8 *da) } } #endif /* PCIE_FULL_DONGLE */ -#endif +#endif bool dhd_is_concurrent_mode(dhd_pub_t *dhd) { @@ -5116,256 +5079,13 @@ dhd_get_concurrent_capabilites(dhd_pub_t *dhd) return ret; #else return 0; -#endif - } - } - } - return 0; -} -#endif -#if defined(READ_CONFIG_FROM_FILE) -#include <linux/fs.h> -#include <linux/ctype.h> - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -bool PM_control = TRUE; - -static int dhd_preinit_proc(dhd_pub_t *dhd, int ifidx, char *name, char *value) -{ - int var_int; - wl_country_t cspec = {{0}, -1, {0}}; - char *revstr; - char *endptr = NULL; - int iolen; - char smbuf[WLC_IOCTL_SMLEN*2]; - - if (!strcmp(name, "country")) { - revstr = strchr(value, '/'); - if (revstr) { - cspec.rev = strtoul(revstr + 1, &endptr, 10); - memcpy(cspec.country_abbrev, value, WLC_CNTRY_BUF_SZ); - cspec.country_abbrev[2] = '\0'; - memcpy(cspec.ccode, cspec.country_abbrev, WLC_CNTRY_BUF_SZ); - } else { - cspec.rev = -1; - memcpy(cspec.country_abbrev, value, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, value, WLC_CNTRY_BUF_SZ); - get_customized_country_code(dhd->info->adapter, - (char *)&cspec.country_abbrev, &cspec); - } - memset(smbuf, 0, sizeof(smbuf)); - DHD_ERROR(("config country code is country : %s, rev : %d !!\n", - cspec.country_abbrev, cspec.rev)); - iolen = bcm_mkiovar("country", (char*)&cspec, sizeof(cspec), - smbuf, sizeof(smbuf)); - return dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, - smbuf, iolen, TRUE, 0); - } else if (!strcmp(name, "roam_scan_period")) { - var_int = (int)simple_strtol(value, NULL, 0); - return dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_SCAN_PERIOD, - &var_int, sizeof(var_int), TRUE, 0); - } else if (!strcmp(name, "roam_delta")) { - struct { - int val; - int band; - } x; - x.val = (int)simple_strtol(value, NULL, 0); - /* x.band = WLC_BAND_AUTO; */ - x.band = WLC_BAND_ALL; - return dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, &x, sizeof(x), TRUE, 0); - } else if (!strcmp(name, "roam_trigger")) { - int ret = 0; - - roam_trigger[0] = (int)simple_strtol(value, NULL, 0); - roam_trigger[1] = WLC_BAND_ALL; - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, &roam_trigger, - sizeof(roam_trigger), TRUE, 0); - - return ret; - } else if (!strcmp(name, "PM")) { - int ret = 0; - var_int = (int)simple_strtol(value, NULL, 0); - - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, - &var_int, sizeof(var_int), TRUE, 0); - -#if defined(CONFIG_PM_LOCK) - if (var_int == 0) { - g_pm_control = TRUE; - printf("%s var_int=%d don't control PM\n", __func__, var_int); - } else { - g_pm_control = FALSE; - printf("%s var_int=%d do control PM\n", __func__, var_int); - } #endif - - return ret; - } -#ifdef WLBTAMP - else if (!strcmp(name, "btamp_chan")) { - int btamp_chan; - int iov_len = 0; - char iovbuf[128]; - int ret; - - btamp_chan = (int)simple_strtol(value, NULL, 0); - iov_len = bcm_mkiovar("btamp_chan", (char *)&btamp_chan, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0) < 0)) - DHD_ERROR(("%s btamp_chan=%d set failed code %d\n", - __FUNCTION__, btamp_chan, ret)); - else - DHD_ERROR(("%s btamp_chan %d set success\n", - __FUNCTION__, btamp_chan)); - } -#endif /* WLBTAMP */ - else if (!strcmp(name, "band")) { - int ret; - if (!strcmp(value, "auto")) - var_int = WLC_BAND_AUTO; - else if (!strcmp(value, "a")) - var_int = WLC_BAND_5G; - else if (!strcmp(value, "b")) - var_int = WLC_BAND_2G; - else if (!strcmp(value, "all")) - var_int = WLC_BAND_ALL; - else { - printf(" set band value should be one of the a or b or all\n"); - var_int = WLC_BAND_AUTO; - } - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, &var_int, - sizeof(var_int), TRUE, 0)) < 0) - printf(" set band err=%d\n", ret); - return ret; - } else if (!strcmp(name, "cur_etheraddr")) { - struct ether_addr ea; - char buf[32]; - uint iovlen; - int ret; - - bcm_ether_atoe(value, &ea); - - ret = memcmp(&ea.octet, dhd->mac.octet, ETHER_ADDR_LEN); - if (ret == 0) { - DHD_ERROR(("%s: Same Macaddr\n", __FUNCTION__)); - return 0; - } - - DHD_ERROR(("%s: Change Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", __FUNCTION__, - ea.octet[0], ea.octet[1], ea.octet[2], - ea.octet[3], ea.octet[4], ea.octet[5])); - - iovlen = bcm_mkiovar("cur_etheraddr", (char*)&ea, ETHER_ADDR_LEN, buf, 32); - - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, iovlen, TRUE, 0); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret)); - return ret; - } - else { - memcpy(dhd->mac.octet, (void *)&ea, ETHER_ADDR_LEN); - return ret; - } - } else { - uint iovlen; - char iovbuf[WLC_IOCTL_SMLEN]; - - /* wlu_iovar_setint */ - var_int = (int)simple_strtol(value, NULL, 0); - - /* Setup timeout bcn_timeout from dhd driver 4.217.48 */ - if (!strcmp(name, "roam_off")) { - /* Setup timeout if Beacons are lost to report link down */ - if (var_int) { - uint bcn_timeout = 2; - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, - iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); } } - /* Setup timeout bcm_timeout from dhd driver 4.217.48 */ - - DHD_INFO(("%s:[%s]=[%d]\n", __FUNCTION__, name, var_int)); - - iovlen = bcm_mkiovar(name, (char *)&var_int, sizeof(var_int), - iovbuf, sizeof(iovbuf)); - return dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, - iovbuf, iovlen, TRUE, 0); } - return 0; } - -static int dhd_preinit_config(dhd_pub_t *dhd, int ifidx) -{ - mm_segment_t old_fs; - struct kstat stat; - struct file *fp = NULL; - unsigned int len; - char *buf = NULL, *p, *name, *value; - int ret = 0; - char *config_path; - - config_path = CONFIG_BCMDHD_CONFIG_PATH; - - if (!config_path) - { - printf(KERN_ERR "config_path can't read. \n"); - return 0; - } - - old_fs = get_fs(); - set_fs(get_ds()); - if ((ret = vfs_stat(config_path, &stat))) { - set_fs(old_fs); - printf(KERN_ERR "%s: Failed to get information (%d)\n", - config_path, ret); - return ret; - } - set_fs(old_fs); - - if (!(buf = MALLOC(dhd->osh, stat.size + 1))) { - printf(KERN_ERR "Failed to allocate memory %llu bytes\n", stat.size); - return -ENOMEM; - } - - printf("dhd_preinit_config : config path : %s \n", config_path); - - if (!(fp = dhd_os_open_image(config_path)) || - (len = dhd_os_get_image_block(buf, stat.size, fp)) < 0) - goto err; - - buf[stat.size] = '\0'; - for (p = buf; *p; p++) { - if (isspace(*p)) - continue; - for (name = p++; *p && !isspace(*p); p++) { - if (*p == '=') { - *p = '\0'; - p++; - for (value = p; *p && !isspace(*p); p++); - *p = '\0'; - if ((ret = dhd_preinit_proc(dhd, ifidx, name, value)) < 0) { - printf(KERN_ERR "%s: %s=%s\n", - bcmerrorstr(ret), name, value); - } - break; - } - } - } - ret = 0; - -out: - if (fp) - dhd_os_close_image(fp); - if (buf) - MFREE(dhd->osh, buf, stat.size+1); - return ret; - -err: - ret = -1; - goto out; -} -#endif /* READ_CONFIG_FROM_FILE */ +#endif int dhd_preinit_ioctls(dhd_pub_t *dhd) @@ -5378,20 +5098,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) eventmsgs_ext_t *eventmask_msg; char iov_buf[WLC_IOCTL_SMLEN]; int ret2 = 0; -#ifdef WLAIBSS - aibss_bcn_force_config_t bcn_config; - uint32 aibss; -#ifdef WLAIBSS_PS - uint32 aibss_ps; -#endif /* WLAIBSS_PS */ -#endif /* WLAIBSS */ -#if defined(BCMSUP_4WAY_HANDSHAKE) && defined(WLAN_AKM_SUITE_FT_8021X) - uint32 sup_wpa = 0; -#endif -#if defined(CUSTOM_AMPDU_BA_WSIZE) || (defined(WLAIBSS) && \ - defined(CUSTOM_IBSS_AMPDU_BA_WSIZE)) +#if defined(CUSTOM_AMPDU_BA_WSIZE) uint32 ampdu_ba_wsize = 0; -#endif /* CUSTOM_AMPDU_BA_WSIZE ||(WLAIBSS && CUSTOM_IBSS_AMPDU_BA_WSIZE) */ +#endif #if defined(CUSTOM_AMPDU_MPDU) int32 ampdu_mpdu = 0; #endif @@ -5406,7 +5115,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) uint32 hostreorder = 1; #endif /* DISABLE_11N */ #endif /* PROP_TXSTATUS */ -#endif +#endif #ifdef PCIE_FULL_DONGLE uint32 wl_ap_isolate; #endif /* PCIE_FULL_DONGLE */ @@ -5422,18 +5131,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #if defined(CUSTOMER_HW2) && defined(USE_WL_CREDALL) uint32 credall = 1; #endif -#if defined(VSDB) || defined(ROAM_ENABLE) - uint bcn_timeout = 10; -#else uint bcn_timeout = 4; -#endif uint retry_max = 3; #if defined(ARP_OFFLOAD_SUPPORT) int arpoe = 1; #endif - int scan_assoc_time = DHD_SCAN_ASSOC_ACTIVE_TIME; - int scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME; - int scan_passive_time = DHD_SCAN_PASSIVE_TIME; char buf[WLC_IOCTL_SMLEN]; char *ptr; uint32 listen_interval = CUSTOM_LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ @@ -5442,6 +5144,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL}; int roam_scan_period[2] = {10, WLC_BAND_ALL}; int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL}; +#ifdef ROAM_AP_ENV_DETECTION + int roam_env_mode = AP_ENV_INDETERMINATE; +#endif /* ROAM_AP_ENV_DETECTION */ #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC int roam_fullscan_period = 60; #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ @@ -5460,9 +5165,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */ struct ether_addr p2p_ea; #endif -#ifdef BCMCCX - uint32 ccx = 1; -#endif #if (defined(AP) || defined(WLP2P)) && !defined(SOFTAP_AND_GC) uint32 apsta = 1; /* Enable APSTA mode */ @@ -5478,28 +5180,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) uint32 nmode = 0; #endif /* DISABLE_11N */ -#if defined(DISABLE_11AC) - uint32 vhtmode = 0; -#endif /* DISABLE_11AC */ #ifdef USE_WL_TXBF uint32 txbf = 1; #endif /* USE_WL_TXBF */ -#ifdef AMPDU_VO_ENABLE - struct ampdu_tid_control tid; -#endif #ifdef USE_WL_FRAMEBURST uint32 frameburst = 1; #endif /* USE_WL_FRAMEBURST */ -#ifdef DHD_SET_FW_HIGHSPEED - uint32 ack_ratio = 250; - uint32 ack_ratio_depth = 64; -#endif /* DHD_SET_FW_HIGHSPEED */ -#ifdef SUPPORT_2G_VHT - uint32 vht_features = 0x3; /* 2G enable | rates all */ -#endif /* SUPPORT_2G_VHT */ #ifdef CUSTOM_PSPRETEND_THR uint32 pspretend_thr = CUSTOM_PSPRETEND_THR; #endif +#ifdef MAX_AP_CLIENT_CNT + uint32 max_assoc = MAX_AP_CLIENT_CNT; +#endif + #ifdef PKT_FILTER_SUPPORT dhd_pkt_filter_enable = TRUE; #endif /* PKT_FILTER_SUPPORT */ @@ -5593,6 +5286,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) sizeof(iovbuf), TRUE, 0)) < 0) { DHD_ERROR(("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret)); } +#endif +#ifdef MAX_AP_CLIENT_CNT + bcm_mkiovar("maxassoc", (char *)&max_assoc, 4, iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, + sizeof(iovbuf), TRUE, 0)) < 0) { + DHD_ERROR(("%s maxassoc for HostAPD failed %d\n", __FUNCTION__, ret)); + } #endif } else if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) || (op_mode == DHD_FLAG_MFG_MODE)) { @@ -5655,7 +5355,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } #else (void)concurrent_mode; -#endif +#endif } DHD_ERROR(("Firmware up: op_mode=0x%04x, MAC="MACDBG"\n", @@ -5668,11 +5368,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); } -#if defined(DISABLE_11AC) - bcm_mkiovar("vhtmode", (char *)&vhtmode, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("%s wl vhtmode 0 failed %d\n", __FUNCTION__, ret)); -#endif /* DISABLE_11AC */ /* Set Listen Interval */ bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf)); @@ -5697,12 +5392,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) DHD_ERROR(("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret)); +#ifdef ROAM_AP_ENV_DETECTION + if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) { + bcm_mkiovar("roam_env_detection", (char *)&roam_env_mode, + 4, iovbuf, sizeof(iovbuf)); + if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) == BCME_OK) + dhd->roam_env_detection = TRUE; + else { + dhd->roam_env_detection = FALSE; + } + } +#endif /* ROAM_AP_ENV_DETECTION */ #endif /* ROAM_ENABLE */ -#ifdef BCMCCX - bcm_mkiovar("ccx_enable", (char *)&ccx, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#endif /* BCMCCX */ #ifdef WLTDLS /* by default TDLS on and auto mode off */ _dhd_tdls_enable(dhd, true, false, NULL); @@ -5713,7 +5415,18 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set lpc failed %d\n", __FUNCTION__, ret)); + if (ret != BCME_NOTDOWN) { + DHD_ERROR(("%s Set lpc failed %d\n", __FUNCTION__, ret)); + } else { + u32 wl_down = 1; + ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, + (char *)&wl_down, sizeof(wl_down), TRUE, 0); + DHD_ERROR(("%s lpc fail WL_DOWN : %d, lpc = %d\n", __FUNCTION__, ret, lpc)); + + bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf)); + ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); + DHD_ERROR(("%s Set lpc ret --> %d\n", __FUNCTION__, ret)); + } } #endif /* DHD_ENABLE_LPC */ @@ -5757,7 +5470,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) if (ap_fw_loaded == TRUE) { dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0); } -#endif +#endif #if defined(KEEP_ALIVE) { @@ -5766,7 +5479,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #if defined(SOFTAP) if (ap_fw_loaded == FALSE) -#endif +#endif if (!(dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) { if ((res = dhd_keep_alive_onoff(dhd)) < 0) @@ -5790,31 +5503,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_ERROR(("%s Set frameburst failed %d\n", __FUNCTION__, ret)); } #endif /* USE_WL_FRAMEBURST */ -#ifdef DHD_SET_FW_HIGHSPEED - /* Set ack_ratio */ - bcm_mkiovar("ack_ratio", (char *)&ack_ratio, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set ack_ratio failed %d\n", __FUNCTION__, ret)); - } - - /* Set ack_ratio_depth */ - bcm_mkiovar("ack_ratio_depth", (char *)&ack_ratio_depth, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set ack_ratio_depth failed %d\n", __FUNCTION__, ret)); - } -#endif /* DHD_SET_FW_HIGHSPEED */ -#if defined(CUSTOM_AMPDU_BA_WSIZE) || (defined(WLAIBSS) && \ - defined(CUSTOM_IBSS_AMPDU_BA_WSIZE)) +#if defined(CUSTOM_AMPDU_BA_WSIZE) /* Set ampdu ba wsize to 64 or 16 */ #ifdef CUSTOM_AMPDU_BA_WSIZE ampdu_ba_wsize = CUSTOM_AMPDU_BA_WSIZE; #endif -#if defined(WLAIBSS) && defined(CUSTOM_IBSS_AMPDU_BA_WSIZE) - if (dhd->op_mode == DHD_FLAG_IBSS_MODE) - ampdu_ba_wsize = CUSTOM_IBSS_AMPDU_BA_WSIZE; -#endif /* WLAIBSS && CUSTOM_IBSS_AMPDU_BA_WSIZE */ if (ampdu_ba_wsize != 0) { bcm_mkiovar("ampdu_ba_wsize", (char *)&du_ba_wsize, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, @@ -5823,45 +5516,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) __FUNCTION__, ampdu_ba_wsize, ret)); } } -#endif /* CUSTOM_AMPDU_BA_WSIZE || (WLAIBSS && CUSTOM_IBSS_AMPDU_BA_WSIZE) */ - -#ifdef WLAIBSS - /* Configure custom IBSS beacon transmission */ - if (dhd->op_mode & DHD_FLAG_IBSS_MODE) - { - aibss = 1; - bcm_mkiovar("aibss", (char *)&aibss, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set aibss to %d failed %d\n", - __FUNCTION__, aibss, ret)); - } -#ifdef WLAIBSS_PS - aibss_ps = 1; - bcm_mkiovar("aibss_ps", (char *)&aibss_ps, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set aibss PS to %d failed %d\n", - __FUNCTION__, aibss, ret)); - } -#endif /* WLAIBSS_PS */ - } - memset(&bcn_config, 0, sizeof(bcn_config)); - bcn_config.initial_min_bcn_dur = AIBSS_INITIAL_MIN_BCN_DUR; - bcn_config.min_bcn_dur = AIBSS_MIN_BCN_DUR; - bcn_config.bcn_flood_dur = AIBSS_BCN_FLOOD_DUR; - bcn_config.version = AIBSS_BCN_FORCE_CONFIG_VER_0; - bcn_config.len = sizeof(bcn_config); +#endif - bcm_mkiovar("aibss_bcn_force_config", (char *)&bcn_config, - sizeof(aibss_bcn_force_config_t), iov_buf, sizeof(iov_buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iov_buf, - sizeof(iov_buf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set aibss_bcn_force_config to %d, %d, %d failed %d\n", - __FUNCTION__, AIBSS_INITIAL_MIN_BCN_DUR, AIBSS_MIN_BCN_DUR, - AIBSS_BCN_FLOOD_DUR, ret)); - } -#endif /* WLAIBSS */ #if defined(CUSTOM_AMPDU_MPDU) ampdu_mpdu = CUSTOM_AMPDU_MPDU; @@ -5887,25 +5543,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } #endif /* CUSTOM_AMPDU_RELEASE */ -#if defined(BCMSUP_4WAY_HANDSHAKE) && defined(WLAN_AKM_SUITE_FT_8021X) - /* Read 4-way handshake requirements */ - if (dhd_use_idsup == 1) { - bcm_mkiovar("sup_wpa", (char *)&sup_wpa, 4, iovbuf, sizeof(iovbuf)); - ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0); - /* sup_wpa iovar returns NOTREADY status on some platforms using modularized - * in-dongle supplicant. - */ - if (ret >= 0 || ret == BCME_NOTREADY) - dhd->fw_4way_handshake = TRUE; - DHD_TRACE(("4-way handshake mode is: %d\n", dhd->fw_4way_handshake)); - } -#endif /* BCMSUP_4WAY_HANDSHAKE && WLAN_AKM_SUITE_FT_8021X */ -#ifdef SUPPORT_2G_VHT - bcm_mkiovar("vht_features", (char *)&vht_features, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s vht_features set failed %d\n", __FUNCTION__, ret)); - } -#endif /* SUPPORT_2G_VHT */ #ifdef CUSTOM_PSPRETEND_THR /* Turn off MPC in AP mode */ bcm_mkiovar("pspretend_threshold", (char *)&pspretend_thr, 4, @@ -5957,7 +5594,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) setbit(eventmask, WLC_E_TXFAIL); #endif setbit(eventmask, WLC_E_JOIN_START); - setbit(eventmask, WLC_E_SCAN_COMPLETE); #ifdef WLMEDIA_HTSF setbit(eventmask, WLC_E_HTSFSYNC); #endif /* WLMEDIA_HTSF */ @@ -5970,13 +5606,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) /* enable dongle roaming event */ setbit(eventmask, WLC_E_ROAM); setbit(eventmask, WLC_E_BSSID); -#ifdef BCMCCX - setbit(eventmask, WLC_E_ADDTS_IND); - setbit(eventmask, WLC_E_DELTS_IND); -#endif /* BCMCCX */ #ifdef WLTDLS setbit(eventmask, WLC_E_TDLS_PEER_EVENT); #endif /* WLTDLS */ +#ifdef RTT_SUPPORT + setbit(eventmask, WLC_E_PROXD); +#endif /* RTT_SUPPORT */ #ifdef WL_CFG80211 setbit(eventmask, WLC_E_ESCAN_RESULT); if (dhd->op_mode & DHD_FLAG_P2P_MODE) { @@ -5984,9 +5619,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE); } #endif /* WL_CFG80211 */ -#ifdef WLAIBSS - setbit(eventmask, WLC_E_AIBSS_TXFAIL); -#endif /* WLAIBSS */ setbit(eventmask, WLC_E_TRACE); /* Write updated Event mask */ @@ -6014,7 +5646,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) ret = ret2; if (ret2 == 0) { /* event_msgs_ext must be supported */ bcopy(iov_buf, eventmask_msg, msglen); - +#ifdef GSCAN_SUPPORT + setbit(eventmask_msg->mask, WLC_E_PFN_GSCAN_FULL_RESULT); + setbit(eventmask_msg->mask, WLC_E_PFN_SCAN_COMPLETE); + setbit(eventmask_msg->mask, WLC_E_PFN_SWC); +#endif /* GSCAN_SUPPORT */ #ifdef BT_WIFI_HANDOVER setbit(eventmask_msg->mask, WLC_E_BT_WIFI_HANDOVER_REQ); #endif /* BT_WIFI_HANDOVER */ @@ -6038,12 +5674,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } /* unsupported is ok */ kfree(eventmask_msg); - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, - sizeof(scan_assoc_time), TRUE, 0); - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, - sizeof(scan_unassoc_time), TRUE, 0); - dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, (char *)&scan_passive_time, - sizeof(scan_passive_time), TRUE, 0); + dhd_set_short_dwell_time(dhd, FALSE); #ifdef ARP_OFFLOAD_SUPPORT /* Set and enable ARP offload feature for STA only */ @@ -6051,7 +5682,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) if (arpoe && !ap_fw_loaded) { #else if (arpoe) { -#endif +#endif dhd_arp_offload_enable(dhd, TRUE); dhd_arp_offload_set(dhd, dhd_arp_mode); } else { @@ -6088,44 +5719,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_ERROR(("%s wl nmode 0 failed %d\n", __FUNCTION__, ret)); #endif /* DISABLE_11N */ -#ifdef AMPDU_VO_ENABLE - tid.tid = PRIO_8021D_VO; /* Enable TID(6) for voice */ - tid.enable = TRUE; - bcm_mkiovar("ampdu_tid", (char *)&tid, sizeof(tid), iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - - tid.tid = PRIO_8021D_NC; /* Enable TID(7) for voice */ - tid.enable = TRUE; - bcm_mkiovar("ampdu_tid", (char *)&tid, sizeof(tid), iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#endif -#if defined(SOFTAP_TPUT_ENHANCE) - if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { - dhd_bus_setidletime(dhd, (int)100); -#ifdef DHDTCPACK_SUPPRESS - dhd->tcpack_sup_enabled = FALSE; -#endif -#if defined(DHD_TCP_WINSIZE_ADJUST) - dhd_use_tcp_window_size_adjust = TRUE; -#endif - - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("bus:txglom_auto_control", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0) { - glom = 0; - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - } - else { - if (buf[0] == 0) { - glom = 1; - bcm_mkiovar("bus:txglom_auto_control", (char *)&glom, 4, iovbuf, - sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - } - } - } -#endif /* SOFTAP_TPUT_ENHANCE */ /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); ptr = buf; @@ -6136,9 +5729,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcmstrtok(&ptr, "\n", 0); /* Print fw version info */ DHD_ERROR(("Firmware version = %s\n", buf)); -#if defined(BCMSDIO) + dhd_set_version_info(dhd, buf); -#endif /* defined(BCMSDIO) */ } #if defined(BCMSDIO) @@ -6168,9 +5760,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } #endif /* DISABLE_11N */ -#ifdef READ_CONFIG_FROM_FILE - dhd_preinit_config(dhd, 0); -#endif /* READ_CONFIG_FROM_FILE */ if (wlfc_enable) dhd_wlfc_init(dhd); @@ -6195,6 +5784,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_pno_init(dhd); } #endif +#ifdef RTT_SUPPORT + if (!dhd->rtt_state) { + dhd_rtt_init(dhd); + } +#endif + #ifdef WL11U dhd_interworking_enable(dhd); #endif /* WL11U */ @@ -6624,21 +6219,30 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock) wl_iw_iscan_set_scan_broadcast_prep(net, 1); #endif -#if 1 && (defined(BCMPCIE) || (defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= \ - KERNEL_VERSION(2, 6, 27)))) +#if defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) if (ifidx == 0) { #ifdef BCMLXSDMMC up(&dhd_registration_sem); #endif if (!dhd_download_fw_on_driverload) { +#ifdef BCMSDIO dhd_net_bus_devreset(net, TRUE); -#ifdef BCMLXSDMMC dhd_net_bus_suspend(net); -#endif /* BCMLXSDMMC */ +#endif /* BCMSDIO */ + wifi_platform_set_power(dhdp->info->adapter, FALSE, WIFI_TURNOFF_DELAY); + } + } +#endif /* OEM_ANDROID && BCMLXSDMMC && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ + +#if defined(BCMPCIE) + if (ifidx == 0) { + if (!dhd_download_fw_on_driverload) { + dhd_net_bus_devreset(net, TRUE); wifi_platform_set_power(dhdp->info->adapter, FALSE, WIFI_TURNOFF_DELAY); } } -#endif /* OEM_ANDROID && (BCMPCIE || (BCMLXSDMMC && KERNEL_VERSION >= 2.6.27)) */ +#endif /* BCMPCIE */ + return 0; fail: @@ -6675,7 +6279,7 @@ dhd_bus_detach(dhd_pub_t *dhdp) #if defined(OOB_INTR_ONLY) dhd_bus_oob_intr_unregister(dhdp); -#endif +#endif } } } @@ -6824,12 +6428,22 @@ void dhd_detach(dhd_pub_t *dhdp) if (dhdp->pno_state) dhd_pno_deinit(dhdp); #endif +#ifdef RTT_SUPPORT + if (dhdp->rtt_state) + dhd_rtt_deinit(dhdp); +#endif #if defined(CONFIG_PM_SLEEP) if (dhd_pm_notifier_registered) { unregister_pm_notifier(&dhd_pm_notifier); dhd_pm_notifier_registered = FALSE; } #endif /* CONFIG_PM_SLEEP */ +#ifdef SAR_SUPPORT + if (dhd_sar_notifier_registered) { + unregister_notifier_by_sar(&dhd->sar_notifier); + dhd_sar_notifier_registered = FALSE; + } +#endif /* SAR_SUPPORT */ #ifdef DEBUG_CPU_FREQ if (dhd->new_freq) free_percpu(dhd->new_freq); @@ -7056,6 +6670,36 @@ dhd_os_ioctl_resp_wake(dhd_pub_t *pub) return 0; } +int +dhd_os_d3ack_wait(dhd_pub_t *pub, uint *condition, bool *pending) +{ + dhd_info_t * dhd = (dhd_info_t *)(pub->info); + int timeout; + + /* Convert timeout in millsecond to jiffies */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + timeout = msecs_to_jiffies(dhd_ioctl_timeout_msec); +#else + timeout = dhd_ioctl_timeout_msec * HZ / 1000; +#endif + + DHD_PERIM_UNLOCK(pub); + timeout = wait_event_timeout(dhd->d3ack_wait, (*condition), timeout); + DHD_PERIM_LOCK(pub); + + return timeout; +} + +int +dhd_os_d3ack_wake(dhd_pub_t *pub) +{ + dhd_info_t *dhd = (dhd_info_t *)(pub->info); + + wake_up(&dhd->d3ack_wait); + return 0; +} + + void dhd_os_wd_timer_extend(void *bus, bool extend) { @@ -7329,102 +6973,6 @@ void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { -#ifdef WLBTAMP - /* Send up locally generated AMP HCI Events */ - case WLC_E_BTA_HCI_EVENT: { - struct sk_buff *p, *skb; - bcm_event_t *msg; - wl_event_msg_t *p_bcm_event; - char *ptr; - uint32 len; - uint32 pktlen; - dhd_if_t *ifp; - dhd_info_t *dhd; - uchar *eth; - int ifidx; - - len = ntoh32(event->datalen); - pktlen = sizeof(bcm_event_t) + len + 2; - dhd = dhdp->info; - ifidx = dhd_ifname2idx(dhd, event->ifname); - - if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) { - ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32))); - - msg = (bcm_event_t *) PKTDATA(dhdp->osh, p); - - bcopy(&dhdp->mac, &msg->eth.ether_dhost, ETHER_ADDR_LEN); - bcopy(&dhdp->mac, &msg->eth.ether_shost, ETHER_ADDR_LEN); - ETHER_TOGGLE_LOCALADDR(&msg->eth.ether_shost); - - msg->eth.ether_type = hton16(ETHER_TYPE_BRCM); - - /* BCM Vendor specific header... */ - msg->bcm_hdr.subtype = hton16(BCMILCP_SUBTYPE_VENDOR_LONG); - msg->bcm_hdr.version = BCMILCP_BCM_SUBTYPEHDR_VERSION; - bcopy(BRCM_OUI, &msg->bcm_hdr.oui[0], DOT11_OUI_LEN); - - /* vendor spec header length + pvt data length (private indication - * hdr + actual message itself) - */ - msg->bcm_hdr.length = hton16(BCMILCP_BCM_SUBTYPEHDR_MINLENGTH + - BCM_MSG_LEN + sizeof(wl_event_msg_t) + (uint16)len); - msg->bcm_hdr.usr_subtype = hton16(BCMILCP_BCM_SUBTYPE_EVENT); - - PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); - - /* copy wl_event_msg_t into sk_buf */ - - /* pointer to wl_event_msg_t in sk_buf */ - p_bcm_event = &msg->event; - bcopy(event, p_bcm_event, sizeof(wl_event_msg_t)); - - /* copy hci event into sk_buf */ - bcopy(data, (p_bcm_event + 1), len); - - msg->bcm_hdr.length = hton16(sizeof(wl_event_msg_t) + - ntoh16(msg->bcm_hdr.length)); - PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); - - ptr = (char *)(msg + 1); - /* Last 2 bytes of the message are 0x00 0x00 to signal that there - * are no ethertypes which are following this - */ - ptr[len+0] = 0x00; - ptr[len+1] = 0x00; - - skb = PKTTONATIVE(dhdp->osh, p); - eth = skb->data; - len = skb->len; - - ifp = dhd->iflist[ifidx]; - if (ifp == NULL) - ifp = dhd->iflist[0]; - - ASSERT(ifp); - skb->dev = ifp->net; - skb->protocol = eth_type_trans(skb, skb->dev); - - skb->data = eth; - skb->len = len; - - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - - /* Send the packet */ - if (in_interrupt()) { - netif_rx(skb); - } else { - netif_rx_ni(skb); - } - } - else { - /* Could not allocate a sk_buf */ - DHD_ERROR(("%s: unable to alloc sk_buf", __FUNCTION__)); - } - break; - } /* case WLC_E_BTA_HCI_EVENT */ -#endif /* WLBTAMP */ default: break; @@ -7522,6 +7070,9 @@ int dhd_net_bus_devreset(struct net_device *dev, uint8 flag) { int ret = 0; +#if defined (BCMPCIE) + int retry = POWERUP_MAX_RETRY; +#endif dhd_info_t *dhd = DHD_DEV_INFO(dev); if (flag == TRUE) { @@ -7530,15 +7081,21 @@ dhd_net_bus_devreset(struct net_device *dev, uint8 flag) DHD_TRACE(("%s: wl down failed\n", __FUNCTION__)); } #ifdef PROP_TXSTATUS - if (dhd->pub.wlfc_enabled) + if (dhd->pub.wlfc_enabled) { dhd_wlfc_deinit(&dhd->pub); + } #endif /* PROP_TXSTATUS */ #ifdef PNO_SUPPORT - if (dhd->pub.pno_state) - dhd_pno_deinit(&dhd->pub); -#endif + if (dhd->pub.pno_state) { + dhd_pno_deinit(&dhd->pub); + } +#endif /* PNO_SUPPORT */ +#ifdef RTT_SUPPORT + if (dhd->pub.rtt_state) { + dhd_rtt_deinit(&dhd->pub); + } +#endif /* RTT_SUPPORT */ } - #ifdef BCMSDIO if (!flag) { dhd_update_fw_nv_path(dhd); @@ -7546,14 +7103,101 @@ dhd_net_bus_devreset(struct net_device *dev, uint8 flag) dhd_bus_update_fw_nv_path(dhd->pub.bus, dhd->fw_path, dhd->nv_path); } -#endif /* BCMSDIO */ ret = dhd_bus_devreset(&dhd->pub, flag); if (ret) { DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret)); return ret; } +#elif defined (BCMPCIE) + if(dhd_download_fw_on_driverload) { + ret = dhd_bus_start(&dhd->pub); + } else { + if(!flag) { + if(dhd->pub.busstate == DHD_BUS_DOWN) { + if (dhd->pub.dongle_reset) { + while(retry--) { + ret = dhdpcie_bus_clock_start(dhd->pub.bus); + if(!ret) + break; + else + OSL_SLEEP(10); + } + + if(ret && !retry) { + DHD_ERROR(("%s: host pcie clock enable failed: %d\n", __FUNCTION__, ret)); + goto done; + } + + ret = dhdpcie_bus_enable_device(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: host configuration restore failed: %d\n", __FUNCTION__, ret)); + goto done; + } + + ret = dhdpcie_bus_dongle_attach(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: dhd_bus_start: %d\n", __FUNCTION__, ret)); + goto done; + } + } + dhd->pub.dongle_reset = FALSE; + + ret = dhd_bus_start(&dhd->pub); + if(ret) { + DHD_ERROR(("%s: dhd_bus_start: %d\n", __FUNCTION__, ret)); + goto done; + } + } else { + DHD_ERROR(("%s: what should we do here\n", __FUNCTION__)); + goto done; + } + } else { + if(dhd->pub.busstate != DHD_BUS_DOWN) { + ret = dhdpcie_bus_disable_device(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: dhdpcie_bus_disable_device: %d\n", __FUNCTION__, ret)); + goto done; + } + + dhd_os_wd_timer(&dhd->pub, 0); + dhd_bus_stop(dhd->pub.bus, TRUE); + dhd_bus_release_dongle(dhd->pub.bus); + + ret = dhdpcie_bus_clock_stop(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: host clock stop failed: %d\n", __FUNCTION__, ret)); + goto done; + } + + dhd->pub.busstate = DHD_BUS_DOWN; + dhd->pub.dongle_reset = TRUE; + dhd_prot_clear(&dhd->pub); + }else { + ret = dhdpcie_bus_disable_device(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: dhdpcie_bus_disable_device: %d\n", __FUNCTION__, ret)); + goto done; + } + + dhd_bus_release_dongle(dhd->pub.bus); + ret = dhdpcie_bus_clock_stop(dhd->pub.bus); + if(ret) { + DHD_ERROR(("%s: host clock stop failed: %d\n", __FUNCTION__, ret)); + goto done; + } + dhd->pub.dongle_reset = TRUE; + + dhd_prot_clear(&dhd->pub); + } + } + } +done: +#endif /* BCMSDIO */ + + if (ret) + dhd->pub.busstate = DHD_BUS_DOWN; return ret; } @@ -7698,6 +7342,117 @@ dhd_dev_init_ioctl(struct net_device *dev) done: return ret; } +int dhd_dev_get_feature_set(struct net_device *dev) +{ + dhd_info_t *ptr = *(dhd_info_t **)netdev_priv(dev); + dhd_pub_t *dhd = (&ptr->pub); + int feature_set = 0; + + if (!dhd) + return feature_set; + + if (FW_SUPPORTED(dhd, sta)) + feature_set |= WIFI_FEATURE_INFRA; + if (FW_SUPPORTED(dhd, dualband)) + feature_set |= WIFI_FEATURE_INFRA_5G; + if (FW_SUPPORTED(dhd, p2p)) + feature_set |= WIFI_FEATURE_P2P; + if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) + feature_set |= WIFI_FEATURE_SOFT_AP; + if (FW_SUPPORTED(dhd, tdls)) + feature_set |= WIFI_FEATURE_TDLS; + if (FW_SUPPORTED(dhd, vsdb)) + feature_set |= WIFI_FEATURE_TDLS_OFFCHANNEL; + if (FW_SUPPORTED(dhd, nan)) { + feature_set |= WIFI_FEATURE_NAN; + /* NAN is essentail for d2d rtt */ + if (FW_SUPPORTED(dhd, rttd2d)) + feature_set |= WIFI_FEATURE_D2D_RTT; + } +#ifdef RTT_SUPPORT + feature_set |= WIFI_FEATURE_D2AP_RTT; +#endif /* RTT_SUPPORT */ + + /* Supports STA + STA always */ + feature_set |= WIFI_FEATURE_ADDITIONAL_STA; +#ifdef PNO_SUPPORT + if (dhd_is_pno_supported(dhd)) { + feature_set |= WIFI_FEATURE_PNO; + feature_set |= WIFI_FEATURE_BATCH_SCAN; +#ifdef GSCAN_SUPPORT + feature_set |= WIFI_FEATURE_GSCAN; +#endif /* GSCAN_SUPPORT */ + } +#endif /* PNO_SUPPORT */ +#ifdef WL11U + feature_set |= WIFI_FEATURE_HOTSPOT; +#endif /* WL11U */ + return feature_set; +} + +int *dhd_dev_get_feature_set_matrix(struct net_device *dev, int *num) +{ + int feature_set_full, mem_needed; + int *ret; + + *num = 0; + mem_needed = sizeof(int) * MAX_FEATURE_SET_CONCURRRENT_GROUPS; + ret = (int *) kmalloc(mem_needed, GFP_KERNEL); + + if (!ret) { + DHD_ERROR(("%s: failed to allocate %d bytes\n", __FUNCTION__, + mem_needed)); + return ret; + } + + feature_set_full = dhd_dev_get_feature_set(dev); + + ret[0] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + (feature_set_full & WIFI_FEATURE_NAN) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_PNO) | + (feature_set_full & WIFI_FEATURE_BATCH_SCAN) | + (feature_set_full & WIFI_FEATURE_GSCAN) | + (feature_set_full & WIFI_FEATURE_HOTSPOT) | + (feature_set_full & WIFI_FEATURE_ADDITIONAL_STA) | + (feature_set_full & WIFI_FEATURE_EPR); + + ret[1] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + /* Not yet verified NAN with P2P */ + /* (feature_set_full & WIFI_FEATURE_NAN) | */ + (feature_set_full & WIFI_FEATURE_P2P) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_EPR); + + ret[2] = (feature_set_full & WIFI_FEATURE_INFRA) | + (feature_set_full & WIFI_FEATURE_INFRA_5G) | + (feature_set_full & WIFI_FEATURE_NAN) | + (feature_set_full & WIFI_FEATURE_D2D_RTT) | + (feature_set_full & WIFI_FEATURE_D2AP_RTT) | + (feature_set_full & WIFI_FEATURE_TDLS) | + (feature_set_full & WIFI_FEATURE_TDLS_OFFCHANNEL) | + (feature_set_full & WIFI_FEATURE_EPR); + *num = MAX_FEATURE_SET_CONCURRRENT_GROUPS; + + return ret; +} + +int +dhd_dev_set_nodfs(struct net_device *dev, u32 nodfs) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + + if (nodfs) + dhd->pub.dhd_cflags |= WLAN_PLAT_NODFS_FLAG; + else + dhd->pub.dhd_cflags &= ~WLAN_PLAT_NODFS_FLAG; + dhd->pub.force_country_change = TRUE; + return 0; +} #ifdef PNO_SUPPORT /* Linux wrapper to call common dhd_pno_stop_for_ssid */ @@ -7710,7 +7465,7 @@ dhd_dev_pno_stop_for_ssid(struct net_device *dev) } /* Linux wrapper to call common dhd_pno_set_for_ssid */ int -dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, +dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_ext_t* ssids_local, int nssid, uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan) { dhd_info_t *dhd = DHD_DEV_INFO(dev); @@ -7757,9 +7512,169 @@ dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize) dhd_info_t *dhd = DHD_DEV_INFO(dev); return (dhd_pno_get_for_batch(&dhd->pub, buf, bufsize, PNO_STATUS_NORMAL)); } +/* Linux wrapper to call common dhd_pno_set_mac_oui */ +int dhd_dev_pno_set_mac_oui(struct net_device *dev, uint8 *oui) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + return (dhd_pno_set_mac_oui(&dhd->pub, oui)); +} #endif /* PNO_SUPPORT */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) +#ifdef GSCAN_SUPPORT +/* Linux wrapper to call common dhd_pno_set_cfg_gscan */ +int +dhd_dev_pno_set_cfg_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type, + void *buf, uint8 flush) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_set_cfg_gscan(&dhd->pub, type, buf, flush)); +} + +/* Linux wrapper to call common dhd_pno_get_gscan */ +void * +dhd_dev_pno_get_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type, + void *info, uint32 *len) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_get_gscan(&dhd->pub, type, info, len)); +} + +/* Linux wrapper to call common dhd_wait_batch_results_complete */ +void dhd_dev_wait_batch_results_complete(struct net_device *dev) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_wait_batch_results_complete(&dhd->pub)); +} + +/* Linux wrapper to call common dhd_pno_lock_batch_results */ +void +dhd_dev_pno_lock_access_batch_results(struct net_device *dev) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_lock_batch_results(&dhd->pub)); +} +/* Linux wrapper to call common dhd_pno_unlock_batch_results */ +void +dhd_dev_pno_unlock_access_batch_results(struct net_device *dev) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_unlock_batch_results(&dhd->pub)); +} + +/* Linux wrapper to call common dhd_pno_initiate_gscan_request */ +int dhd_dev_pno_run_gscan(struct net_device *dev, bool run, bool flush) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_initiate_gscan_request(&dhd->pub, run, flush)); +} + +/* Linux wrapper to call common dhd_pno_enable_full_scan_result */ +int dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time_flag) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_pno_enable_full_scan_result(&dhd->pub, real_time_flag)); +} + +/* Linux wrapper to call common dhd_handle_swc_evt */ +void * dhd_dev_swc_scan_event(struct net_device *dev, const void *data, int *send_evt_bytes) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_handle_swc_evt(&dhd->pub, data, send_evt_bytes)); +} + +/* Linux wrapper to call common dhd_handle_hotlist_scan_evt */ +void * dhd_dev_hotlist_scan_event(struct net_device *dev, + const void *data, int *send_evt_bytes, hotlist_type_t type) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_handle_hotlist_scan_evt(&dhd->pub, data, send_evt_bytes, type)); +} + +/* Linux wrapper to call common dhd_process_full_gscan_result */ +void * dhd_dev_process_full_gscan_result(struct net_device *dev, +const void *data, int *send_evt_bytes) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_process_full_gscan_result(&dhd->pub, data, send_evt_bytes)); +} + +void dhd_dev_gscan_hotlist_cache_cleanup(struct net_device *dev, hotlist_type_t type) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + dhd_gscan_hotlist_cache_cleanup(&dhd->pub, type); + + return; +} + +int dhd_dev_gscan_batch_cache_cleanup(struct net_device *dev) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_gscan_batch_cache_cleanup(&dhd->pub)); +} + +/* Linux wrapper to call common dhd_retreive_batch_scan_results */ +int dhd_dev_retrieve_batch_scan(struct net_device *dev) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_retreive_batch_scan_results(&dhd->pub)); +} + +#endif /* GSCAN_SUPPORT */ +#ifdef RTT_SUPPORT +/* Linux wrapper to call common dhd_pno_set_cfg_gscan */ +int +dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_rtt_set_cfg(&dhd->pub, buf)); +} +int +dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_rtt_stop(&dhd->pub, mac_list, mac_cnt)); +} + +int +dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx, dhd_rtt_compl_noti_fn noti_fn) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_rtt_register_noti_callback(&dhd->pub, ctx, noti_fn)); +} +int +dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_rtt_unregister_noti_callback(&dhd->pub, noti_fn)); +} + +int +dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa) +{ + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + + return (dhd_rtt_capability(&dhd->pub, capa)); +} +#endif /* RTT_SUPPORT */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) static void dhd_hang_process(void *dhd_info, void *event_info, u8 event) { dhd_info_t *dhd; @@ -7825,17 +7740,29 @@ int dhd_net_wifi_platform_set_power(struct net_device *dev, bool on, unsigned lo return wifi_platform_set_power(dhd->adapter, on, delay_msec); } +bool dhd_force_country_change(struct net_device *dev) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + + if (dhd && dhd->pub.up) + return dhd->pub.force_country_change; + return FALSE; +} + void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_code, wl_country_t *cspec) { dhd_info_t *dhd = DHD_DEV_INFO(dev); - get_customized_country_code(dhd->adapter, country_iso_code, cspec); + get_customized_country_code(dhd->adapter, country_iso_code, cspec, + dhd->pub.dhd_cflags); } + void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify) { dhd_info_t *dhd = DHD_DEV_INFO(dev); if (dhd && dhd->pub.up) { memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); + dhd->pub.force_country_change = FALSE; #ifdef WL_CFG80211 wl_update_wiphybands(NULL, notify); #endif @@ -7870,7 +7797,7 @@ int dhd_net_set_fw_path(struct net_device *dev, char *fw) DHD_INFO(("GOT STA FIRMWARE\n")); ap_fw_loaded = FALSE; } -#endif +#endif return 0; } @@ -7888,7 +7815,7 @@ void dhd_net_if_unlock(struct net_device *dev) static void dhd_net_if_lock_local(dhd_info_t *dhd) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) if (dhd) mutex_lock(&dhd->dhd_net_if_mutex); #endif @@ -7896,7 +7823,7 @@ static void dhd_net_if_lock_local(dhd_info_t *dhd) static void dhd_net_if_unlock_local(dhd_info_t *dhd) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) if (dhd) mutex_unlock(&dhd->dhd_net_if_mutex); #endif @@ -7904,7 +7831,7 @@ static void dhd_net_if_unlock_local(dhd_info_t *dhd) static void dhd_suspend_lock(dhd_pub_t *pub) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) dhd_info_t *dhd = (dhd_info_t *)(pub->info); if (dhd) mutex_lock(&dhd->dhd_suspend_mutex); @@ -7913,7 +7840,7 @@ static void dhd_suspend_lock(dhd_pub_t *pub) static void dhd_suspend_unlock(dhd_pub_t *pub) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) dhd_info_t *dhd = (dhd_info_t *)(pub->info); if (dhd) mutex_unlock(&dhd->dhd_suspend_mutex); @@ -8153,7 +8080,6 @@ int dhd_os_wake_lock(dhd_pub_t *pub) if (dhd) { spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - if (dhd->wakelock_counter == 0 && !dhd->waive_wakelock) { #ifdef CONFIG_HAS_WAKELOCK wake_lock(&dhd->wl_wifi); @@ -8225,6 +8151,33 @@ int dhd_os_check_wakelock(dhd_pub_t *pub) #endif return 0; } + +int dhd_os_check_wakelock_all(dhd_pub_t *pub) +{ +#if defined(CONFIG_HAS_WAKELOCK) || \ + (defined(BCMSDIO) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))) + dhd_info_t *dhd; + + if (!pub) + return 0; + dhd = (dhd_info_t *)(pub->info); +#endif /* CONFIG_HAS_WAKELOCK || BCMSDIO */ + +#ifdef CONFIG_HAS_WAKELOCK + /* Indicate to the SD Host to avoid going to suspend if internal locks are up */ + if (dhd && (wake_lock_active(&dhd->wl_wifi) || + wake_lock_active(&dhd->wl_wdwake) || + wake_lock_active(&dhd->wl_rxwake) || + wake_lock_active(&dhd->wl_ctrlwake))) { + return 1; + } +#elif defined(BCMSDIO) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) + if (dhd && (dhd->wakelock_counter > 0) && dhd_bus_dev_pm_enabled(pub)) + return 1; +#endif + return 0; +} + int net_os_wake_unlock(struct net_device *dev) { dhd_info_t *dhd = DHD_DEV_INFO(dev); @@ -8343,7 +8296,7 @@ bool dhd_os_check_if_up(dhd_pub_t *pub) return pub->up; } -#if defined(BCMSDIO) + /* function to collect firmware, chip id and chip version info */ void dhd_set_version_info(dhd_pub_t *dhdp, char *fw) { @@ -8359,7 +8312,6 @@ void dhd_set_version_info(dhd_pub_t *dhdp, char *fw) "\n Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp), dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp)); } -#endif /* defined(BCMSDIO) */ int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd) { int ifidx; @@ -8412,6 +8364,40 @@ int dhd_get_instance(dhd_pub_t *dhdp) return dhdp->info->unit; } +void dhd_set_short_dwell_time(dhd_pub_t *dhd, int set) +{ + int scan_assoc_time = DHD_SCAN_ASSOC_ACTIVE_TIME; + int scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME; + int scan_passive_time = DHD_SCAN_PASSIVE_TIME; + + DHD_TRACE(("%s: Enter: %d\n", __FUNCTION__, set)); + if (dhd->short_dwell_time != set) { + if (set) { + scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME_PS; + } + dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, + (char *)&scan_unassoc_time, + sizeof(scan_unassoc_time), TRUE, 0); + if (dhd->short_dwell_time == -1) { + dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, + (char *)&scan_assoc_time, + sizeof(scan_assoc_time), TRUE, 0); + dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, + (char *)&scan_passive_time, + sizeof(scan_passive_time), TRUE, 0); + } + dhd->short_dwell_time = set; + } +} + +#ifdef CUSTOM_SET_SHORT_DWELL_TIME +void net_set_short_dwell_time(struct net_device *dev, int set) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + + dhd_set_short_dwell_time(&dhd->pub, set); +} +#endif #ifdef PROP_TXSTATUS @@ -8950,48 +8936,6 @@ void dhd_set_cpucore(dhd_pub_t *dhd, int set) return; } #endif /* CUSTOM_SET_CPUCORE */ -#if defined(DHD_TCP_WINSIZE_ADJUST) -static int dhd_port_list_match(int port) -{ - int i; - for (i = 0; i < MAX_TARGET_PORTS; i++) { - if (target_ports[i] == port) - return 1; - } - return 0; -} -static void dhd_adjust_tcp_winsize(int op_mode, struct sk_buff *skb) -{ - struct iphdr *ipheader; - struct tcphdr *tcpheader; - uint16 win_size; - int32 incremental_checksum; - - if (!(op_mode & DHD_FLAG_HOSTAP_MODE)) - return; - if (skb == NULL || skb->data == NULL) - return; - - ipheader = (struct iphdr*)(skb->data); - - if (ipheader->protocol == IPPROTO_TCP) { - tcpheader = (struct tcphdr*) skb_pull(skb, (ipheader->ihl)<<2); - if (tcpheader) { - win_size = ntoh16(tcpheader->window); - if (win_size < MIN_TCP_WIN_SIZE && - dhd_port_list_match(ntoh16(tcpheader->dest))) { - incremental_checksum = ntoh16(tcpheader->check); - incremental_checksum += win_size - win_size*WIN_SIZE_SCALE_FACTOR; - if (incremental_checksum < 0) - --incremental_checksum; - tcpheader->window = hton16(win_size*WIN_SIZE_SCALE_FACTOR); - tcpheader->check = hton16((unsigned short)incremental_checksum); - } - } - skb_push(skb, (ipheader->ihl)<<2); - } -} -#endif /* DHD_TCP_WINSIZE_ADJUST */ /* Get interface specific ap_isolate configuration */ int dhd_get_ap_isolate(dhd_pub_t *dhdp, uint32 idx) diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.h b/drivers/net/wireless/bcmdhd/dhd_linux.h index 7bcc461e7272686c5d9f660c026f8b3e08fc6c5d..878fc1ffb79b1d0f8eb178746cc55e825d41695b 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.h +++ b/drivers/net/wireless/bcmdhd/dhd_linux.h @@ -1,7 +1,25 @@ /* * DHD Linux header file (dhd_linux exports for cfg80211 and other components) * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_linux.h 399301 2013-04-29 21:41:52Z $ */ @@ -29,6 +47,21 @@ #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) #include <linux/earlysuspend.h> #endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */ +#if defined(CONFIG_WIFI_CONTROL_FUNC) +#include <linux/wlan_plat.h> +#endif + +#if !defined(CONFIG_WIFI_CONTROL_FUNC) +#define WLAN_PLAT_NODFS_FLAG 0x01 +struct wifi_platform_data { + int (*set_power)(int val); + int (*set_reset)(int val); + int (*set_carddetect)(int val); + void *(*mem_prealloc)(int section, unsigned long size); + int (*get_mac_addr)(unsigned char *buf); + void *(*get_country_code)(char *ccode, u32 flags); +}; +#endif /* CONFIG_WIFI_CONTROL_FUNC */ #define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ @@ -68,7 +101,8 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present); int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *irq_flags_ptr); int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf); -void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode); +void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode, + u32 flags); void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size); void* wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter); diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c b/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c index 3b809903e2dc4b3accc14a1ba3f2e0d284f9b2c0..5d221f00784bab89f7314ca687d61935c50b0c5f 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c @@ -1,7 +1,25 @@ /* * Linux platform device for DHD WLAN adapter * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_linux_platdev.c 401742 2013-05-13 15:03:21Z $ */ @@ -18,39 +36,16 @@ #include <dhd_bus.h> #include <dhd_linux.h> #include <wl_android.h> -#if defined(CONFIG_WIFI_CONTROL_FUNC) -#include <linux/wlan_plat.h> -#endif -#ifdef CONFIG_DTS -#include<linux/regulator/consumer.h> -#include<linux/of_gpio.h> -#endif /* CONFIG_DTS */ - -#if !defined(CONFIG_WIFI_CONTROL_FUNC) -struct wifi_platform_data { - int (*set_power)(int val); - int (*set_reset)(int val); - int (*set_carddetect)(int val); - void *(*mem_prealloc)(int section, unsigned long size); - int (*get_mac_addr)(unsigned char *buf); - void *(*get_country_code)(char *ccode); -}; -#endif /* CONFIG_WIFI_CONTROL_FUNC */ #define WIFI_PLAT_NAME "bcmdhd_wlan" #define WIFI_PLAT_NAME2 "bcm4329_wlan" #define WIFI_PLAT_EXT "bcmdhd_wifi_platform" -#ifdef CONFIG_DTS -struct regulator *wifi_regulator = NULL; -#endif /* CONFIG_DTS */ - bool cfg_multichip = FALSE; bcmdhd_wifi_platdata_t *dhd_wifi_platdata = NULL; static int wifi_plat_dev_probe_ret = 0; static bool is_power_on = FALSE; -#if !defined(CONFIG_DTS) -#if defined(DHD_OF_SUPPORT) +#ifdef DHD_OF_SUPPORT static bool dts_enabled = TRUE; extern struct resource dhd_wlan_resources; extern struct wifi_platform_data dhd_wlan_control; @@ -59,7 +54,6 @@ static bool dts_enabled = FALSE; struct resource dhd_wlan_resources = {0}; struct wifi_platform_data dhd_wlan_control = {0}; #endif /* CONFIG_OF && !defined(CONFIG_ARCH_MSM) */ -#endif /* !defind(CONFIG_DTS) */ static int dhd_wifi_platform_load(void); @@ -105,10 +99,12 @@ void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned if (size != 0L) bzero(alloc_ptr, size); return alloc_ptr; + } else { + DHD_ERROR(("%s: failed to alloc static mem section %d\n", + __FUNCTION__, section)); } } - DHD_ERROR(("%s: failed to alloc static mem section %d\n", __FUNCTION__, section)); return NULL; } @@ -134,18 +130,6 @@ int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *ir int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec) { int err = 0; -#ifdef CONFIG_DTS - if (on) { - err = regulator_enable(wifi_regulator); - is_power_on = TRUE; - } - else { - err = regulator_disable(wifi_regulator); - is_power_on = FALSE; - } - if (err < 0) - DHD_ERROR(("%s: regulator enable/disable failed", __FUNCTION__)); -#else struct wifi_platform_data *plat_data; if (!adapter || !adapter->wifi_plat_data) @@ -156,18 +140,25 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long if (plat_data->set_power) { #ifdef ENABLE_4335BT_WAR if (on) { - printf("WiFi: trying to acquire BT lock\n"); + printk("WiFi: trying to acquire BT lock\n"); if (bcm_bt_lock(lock_cookie_wifi) != 0) - printf("** WiFi: timeout in acquiring bt lock**\n"); - printf("%s: btlock acquired\n", __FUNCTION__); + printk("** WiFi: timeout in acquiring bt lock**\n"); + printk("%s: btlock acquired\n", __FUNCTION__); } else { /* For a exceptional case, release btlock */ bcm_bt_unlock(lock_cookie_wifi); } #endif /* ENABLE_4335BT_WAR */ - + /** + if (on) + sysedp_set_state(plat_data->sysedpc, 1); + **/ err = plat_data->set_power(on); + /** + if (!on || err) + sysedp_set_state(plat_data->sysedpc, 0); + **/ } if (msec && !err) @@ -178,8 +169,6 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long else is_power_on = FALSE; -#endif /* CONFIG_DTS */ - return err; } @@ -214,7 +203,8 @@ int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf) return -EOPNOTSUPP; } -void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode) +void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode, + u32 flags) { /* get_country_code was added after 2.6.39 */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) @@ -226,7 +216,7 @@ void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode) DHD_TRACE(("%s\n", __FUNCTION__)); if (plat_data->get_country_code) { - return plat_data->get_country_code(ccode); + return plat_data->get_country_code(ccode, flags); } #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ @@ -237,10 +227,10 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev) { struct resource *resource; wifi_adapter_info_t *adapter; -#ifdef CONFIG_DTS - int irq, gpio; -#endif /* CONFIG_DTS */ - + /** + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + **/ /* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan") * is kept for backward compatibility and supports only 1 adapter */ @@ -257,32 +247,7 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev) adapter->intr_flags = resource->flags & IRQF_TRIGGER_MASK; } -#ifdef CONFIG_DTS - wifi_regulator = regulator_get(&pdev->dev, "wlreg_on"); - if (wifi_regulator == NULL) { - DHD_ERROR(("%s regulator is null\n", __FUNCTION__)); - return -1; - } - - /* This is to get the irq for the OOB */ - gpio = of_get_gpio(pdev->dev.of_node, 0); - - if (gpio < 0) { - DHD_ERROR(("%s gpio information is incorrect\n", __FUNCTION__)); - return -1; - } - irq = gpio_to_irq(gpio); - if (irq < 0) { - DHD_ERROR(("%s irq information is incorrect\n", __FUNCTION__)); - return -1; - } - adapter->irq_num = irq; - - /* need to change the flags according to our requirement */ - adapter->intr_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | - IORESOURCE_IRQ_SHAREABLE; -#endif /* CONFIG_DTS */ - + //wifi_ctrl->sysedpc = sysedp_create_consumer("wifi", "wifi"); wifi_plat_dev_probe_ret = dhd_wifi_platform_load(); return wifi_plat_dev_probe_ret; } @@ -290,7 +255,10 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev) static int wifi_plat_dev_drv_remove(struct platform_device *pdev) { wifi_adapter_info_t *adapter; - + /** + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + **/ /* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan") * is kept for backward compatibility and supports only 1 adapter */ @@ -300,16 +268,17 @@ static int wifi_plat_dev_drv_remove(struct platform_device *pdev) if (is_power_on) { #ifdef BCMPCIE wifi_platform_bus_enumerate(adapter, FALSE); + OSL_SLEEP(100); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); #else wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); #endif /* BCMPCIE */ } - -#ifdef CONFIG_DTS - regulator_put(wifi_regulator); -#endif /* CONFIG_DTS */ + /** + sysedp_free_consumer(wifi_ctrl->sysedpc); + wifi_ctrl->sysedpc = NULL; + **/ return 0; } @@ -334,12 +303,6 @@ static int wifi_plat_dev_drv_resume(struct platform_device *pdev) return 0; } -#ifdef CONFIG_DTS -static const struct of_device_id wifi_device_dt_match[] = { - { .compatible = "android,bcmdhd_wlan", }, - {}, -}; -#endif /* CONFIG_DTS */ static struct platform_driver wifi_platform_dev_driver = { .probe = wifi_plat_dev_drv_probe, .remove = wifi_plat_dev_drv_remove, @@ -347,9 +310,6 @@ static struct platform_driver wifi_platform_dev_driver = { .resume = wifi_plat_dev_drv_resume, .driver = { .name = WIFI_PLAT_NAME, -#ifdef CONFIG_DTS - .of_match_table = wifi_device_dt_match, -#endif /* CONFIG_DTS */ } }; @@ -384,15 +344,12 @@ static int wifi_ctrlfunc_register_drv(void) dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match); dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match); - -#if !defined(CONFIG_DTS) if (!dts_enabled) { if (dev1 == NULL && dev2 == NULL) { DHD_ERROR(("no wifi platform data, skip\n")); return -ENXIO; } } -#endif /* !defined(CONFIG_DTS) */ /* multi-chip support not enabled, build one adapter information for * DHD (either SDIO, USB or PCIe) @@ -426,7 +383,6 @@ static int wifi_ctrlfunc_register_drv(void) } } -#if !defined(CONFIG_DTS) if (dts_enabled) { struct resource *resource; adapter->wifi_plat_data = (void *)&dhd_wlan_control; @@ -435,12 +391,6 @@ static int wifi_ctrlfunc_register_drv(void) adapter->intr_flags = resource->flags & IRQF_TRIGGER_MASK; wifi_plat_dev_probe_ret = dhd_wifi_platform_load(); } -#endif /* !defined(CONFIG_DTS) */ - - -#ifdef CONFIG_DTS - wifi_plat_dev_probe_ret = platform_driver_register(&wifi_platform_dev_driver); -#endif /* CONFIG_DTS */ /* return probe function's return value if registeration succeeded */ return wifi_plat_dev_probe_ret; @@ -450,10 +400,6 @@ void wifi_ctrlfunc_unregister_drv(void) { struct device *dev1, *dev2; -#ifdef CONFIG_DTS - DHD_ERROR(("unregister wifi platform drivers\n")); - platform_driver_unregister(&wifi_platform_dev_driver); -#else dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match); dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match); if (!dts_enabled) @@ -473,8 +419,6 @@ void wifi_ctrlfunc_unregister_drv(void) wifi_platform_bus_enumerate(adapter, FALSE); } } -#endif /* !defined(CONFIG_DTS) */ - kfree(dhd_wifi_platdata->adapters); dhd_wifi_platdata->adapters = NULL; dhd_wifi_platdata->num_adapters = 0; @@ -647,7 +591,7 @@ extern int dhd_dpc_prio; extern uint dhd_deferred_tx; #if defined(BCMLXSDMMC) extern struct semaphore dhd_registration_sem; -#endif +#endif #ifdef BCMSDIO static int dhd_wifi_platform_load_sdio(void) @@ -758,7 +702,7 @@ fail: /* x86 bring-up PC needs no power-up operations */ err = dhd_bus_register(); -#endif +#endif return err; } diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c b/drivers/net/wireless/bcmdhd/dhd_linux_sched.c index ed635b889586d466939f8cb3341a4648f8a851c3..8fc4ff5ab147cf7f3771ddcf4f89b0631a38369b 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux_sched.c @@ -1,7 +1,25 @@ /* * Expose some of the kernel scheduler routines * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_linux_sched.c 457570 2014-02-23 13:54:46Z $ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_wq.c b/drivers/net/wireless/bcmdhd/dhd_linux_wq.c index 1df1c92db1d97f35bf33f92d449b2a86446770dd..2d01570dd2e5e89c6034283384ed92e7219e56be 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_wq.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux_wq.c @@ -2,7 +2,25 @@ * Broadcom Dongle Host Driver (DHD), Generic work queue framework * Generic interface to handle dhd deferred work events * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_linux_wq.c 449578 2014-01-17 13:53:20Z $ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_wq.h b/drivers/net/wireless/bcmdhd/dhd_linux_wq.h index 35982ef5ca8882eab711c6a7ee2e408c7632619b..e8c36390af9f8fb3ed19beae36dc085deefa9627 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_wq.h +++ b/drivers/net/wireless/bcmdhd/dhd_linux_wq.h @@ -2,7 +2,25 @@ * Broadcom Dongle Host Driver (DHD), Generic work queue framework * Generic interface to handle dhd deferred work events * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_linux_wq.h 449578 2014-01-17 13:53:20Z $ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_log.c b/drivers/net/wireless/bcmdhd/dhd_log.c deleted file mode 100644 index a498197d65aae09d5967e7cbf3ca832e84f65de8..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/dhd_log.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * DHD logging module for internal debug - * - * $Copyright Open Broadcom Corporation$ - * - * $Id: dhd_sdio.c 281456 2011-09-02 01:49:45Z $ - */ - -#include <typedefs.h> -#include <osl.h> - -#include <proto/ethernet.h> -#include <proto/802.1d.h> -#include <proto/802.11.h> - -#include <linux/inet.h> - -void dhd_blog(char *cp, int size) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) - static struct socket * _udpSocket = NULL; - struct sockaddr_in _saAddr; - struct iovec iov; - struct msghdr msg; - if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &_udpSocket) >= 0) - { - - { - memset(&_saAddr, 0, sizeof(_saAddr)); - _saAddr.sin_family = AF_INET; - _saAddr.sin_port = htons(7651); - _saAddr.sin_addr.s_addr = in_aton("10.19.74.43"); - - iov.iov_base = cp; - iov.iov_len = size; - - msg.msg_name = &_saAddr; - msg.msg_namelen = sizeof(struct sockaddr_in); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - { - mm_segment_t fs = get_fs(); - set_fs(get_ds()); - - sock_sendmsg(_udpSocket, &msg, size); - - set_fs(fs); - } - } - - sock_release(_udpSocket); - } -#endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -} diff --git a/drivers/net/wireless/bcmdhd/dhd_msgbuf.c b/drivers/net/wireless/bcmdhd/dhd_msgbuf.c index 66f6c51280860c29e2e056329988a319cc03d6ab..a49c705626fbec23119b56cac333cf3a8be31688 100644 --- a/drivers/net/wireless/bcmdhd/dhd_msgbuf.c +++ b/drivers/net/wireless/bcmdhd/dhd_msgbuf.c @@ -4,9 +4,27 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_msgbuf.c 490973 2014-07-14 12:32:56Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_msgbuf.c 474409 2014-05-01 04:27:15Z $ */ #include <typedefs.h> #include <osl.h> @@ -33,7 +51,8 @@ #include <pcie_core.h> #include <bcmpcie.h> - +#include <dhd_pcie.h> +#include <dhd_ip.h> #define RETRIES 2 /* # of retries to retrieve matching ioctl response */ #define IOCTL_HDR_LEN 12 @@ -142,7 +161,7 @@ typedef struct dhd_prot { void *pktid_map_handle; uint16 rx_metadata_offset; uint16 tx_metadata_offset; - uint16 rx_cpln_early_upd_idx; + uint16 rx_cpln_early_upd_idx; } dhd_prot_t; static int dhdmsgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, @@ -214,7 +233,6 @@ static void prot_upd_read_idx(dhd_pub_t *dhd, msgbuf_ring_t * ring); static uint8* prot_get_src_addr(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint16 *available_len); static void prot_store_rxcpln_read_idx(dhd_pub_t *dhd, msgbuf_ring_t *ring); static void prot_early_upd_rxcpln_read_idx(dhd_pub_t *dhd, msgbuf_ring_t * ring); - typedef void (*dhd_msgbuf_func_t)(dhd_pub_t *dhd, void * buf, uint16 msglen); static dhd_msgbuf_func_t table_lookup[DHD_PROT_FUNCS] = { NULL, @@ -309,7 +327,7 @@ typedef struct dhd_pktid_map { #define NATIVE_TO_PKTID_INIT(osh, items) dhd_pktid_map_init((osh), (items)) #define NATIVE_TO_PKTID_FINI(map) dhd_pktid_map_fini(map) -#define NATIVE_TO_PKTID_CLEAR(map) dhd_pktid_map_clear(map) +#define NATIVE_TO_PKTID_CLEAR(map) dhd_pktid_map_clear(map) #define NATIVE_TO_PKTID_RSV(map, pkt) dhd_pktid_map_reserve((map), (pkt)) #define NATIVE_TO_PKTID_SAVE(map, pkt, nkey, pa, len, dma) \ @@ -422,7 +440,7 @@ dhd_pktid_map_clear(dhd_pktid_map_handle_t *handle) dhd_pktid_map_t *map; dhd_pktid_item_t *locker; - DHD_TRACE(("%s\n", __FUNCTION__)); + DHD_TRACE(("%s\n",__FUNCTION__)); if (handle == NULL) return; @@ -438,9 +456,9 @@ dhd_pktid_map_clear(dhd_pktid_map_handle_t *handle) map->keys[nkey] = nkey; /* populate with unique keys */ if (locker->inuse == TRUE) { /* numbered key still in use */ locker->inuse = FALSE; /* force open the locker */ - DHD_TRACE(("%s free id%d\n", __FUNCTION__, nkey)); + DHD_TRACE(("%s free id%d\n",__FUNCTION__,nkey )); DMA_UNMAP(osh, (uint32)locker->physaddr, locker->len, - locker->dma, 0, 0); + locker->dma, 0, 0); PKTFREE(osh, (ulong*)locker->pkt, FALSE); } } @@ -1398,11 +1416,9 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd) while (TRUE) { uint8 *src_addr; uint16 src_len; - /* Store current read pointer */ /* Read pointer will be updated in prot_early_upd_rxcpln_read_idx */ prot_store_rxcpln_read_idx(dhd, prot->d2hring_rx_cpln); - /* Get the message from ring */ src_addr = prot_get_src_addr(dhd, prot->d2hring_rx_cpln, &src_len); if (src_addr == NULL) @@ -1417,6 +1433,9 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd) DHD_ERROR(("%s: Error at process rxpl msgbuf of len %d\n", __FUNCTION__, src_len)); } + + /* Update read pointer */ + prot_upd_read_idx(dhd, prot->d2hring_rx_cpln); } return 0; @@ -1562,7 +1581,6 @@ dhd_process_msgtype(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint8* buf, uint16 len) uint8 msgtype; cmn_msg_hdr_t *msg = NULL; int ret = BCME_OK; - uint8 *buf_head = buf; ASSERT(ring && ring->ringmem); msglen = RING_LEN_ITEMS(ring); @@ -1579,8 +1597,7 @@ dhd_process_msgtype(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint8* buf, uint16 len) msgtype = msg->msg_type; - /* Prefetch data to populate the cache */ - OSL_PREFETCH(buf + msglen); + DHD_INFO(("msgtype %d, msglen is %d, pktlen is %d \n", msgtype, msglen, pktlen)); @@ -1600,13 +1617,11 @@ dhd_process_msgtype(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint8* buf, uint16 len) } pktlen = pktlen - msglen; buf = buf + msglen; - if (msgtype == MSG_TYPE_RX_CMPLT) - prot_early_upd_rxcpln_read_idx(dhd, - dhd->prot->d2hring_rx_cpln); + prot_early_upd_rxcpln_read_idx(dhd, + dhd->prot->d2hring_rx_cpln); } done: - OSL_CACHE_FLUSH(buf_head, len - pktlen); #ifdef DHD_RX_CHAINING dhd_rxchain_commit(dhd); @@ -1650,7 +1665,7 @@ dhd_prot_ioctack_process(dhd_pub_t *dhd, void * buf, uint16 msglen) DHD_ERROR(("got an error status for the ioctl request...need to handle that\n")); } - memset(buf, 0, msglen); + memset(buf, 0 , msglen); ioct_ack->marker = PCIE_D2H_RESET_MARK; } static void @@ -1666,7 +1681,7 @@ dhd_prot_ioctcmplt_process(dhd_pub_t *dhd, void * buf, uint16 msglen) pkt_id = ltoh32(ioct_resp->cmn_hdr.request_id); status = ioct_resp->compl_hdr.status; - memset(buf, 0, msglen); + memset(buf, 0 , msglen); ioct_resp->marker = PCIE_D2H_RESET_MARK; DHD_CTL(("IOCTL_COMPLETE: pktid %x xtid %d status %x resplen %d\n", @@ -1702,7 +1717,7 @@ dhd_prot_txstatus_process(dhd_pub_t *dhd, void * buf, uint16 msglen) if (pkt) { #if defined(BCMPCIE) dhd_txcomplete(dhd, pkt, true); -#endif +#endif #if DHD_DBG_SHOW_METADATA if (dhd->prot->tx_metadata_offset && txstatus->metadata_len) { @@ -1719,7 +1734,7 @@ dhd_prot_txstatus_process(dhd_pub_t *dhd, void * buf, uint16 msglen) PKTFREE(dhd->osh, pkt, TRUE); } - memset(buf, 0, msglen); + memset(buf, 0 , msglen); txstatus->marker = PCIE_D2H_RESET_MARK; DHD_GENERAL_UNLOCK(dhd, flags); @@ -1750,7 +1765,7 @@ dhd_prot_event_process(dhd_pub_t *dhd, void* buf, uint16 len) prot->cur_event_bufs_posted--; dhd_msgbuf_rxbuf_post_event_bufs(dhd); - memset(buf, 0, len); + memset(buf, 0 , len); evnt->marker = PCIE_D2H_RESET_MARK; /* locks required to protect pktid_map */ @@ -1830,7 +1845,7 @@ dhd_prot_rxcmplt_process(dhd_pub_t *dhd, void* buf, uint16 msglen) PKTSETLEN(dhd->osh, pkt, ltoh16(rxcmplt_h->data_len)); ifidx = rxcmplt_h->cmn_hdr.if_id; - memset(buf, 0, msglen); + memset(buf, 0 , msglen); rxcmplt_h->marker = PCIE_D2H_RESET_MARK; #ifdef DHD_RX_CHAINING @@ -1840,7 +1855,6 @@ dhd_prot_rxcmplt_process(dhd_pub_t *dhd, void* buf, uint16 msglen) /* offset from which data starts is populated in rxstatus0 */ dhd_bus_rx_frame(dhd->bus, pkt, ifidx, 1); #endif /* ! DHD_RX_CHAINING */ - } /* Stop protocol: sync w/dongle state. */ @@ -1883,6 +1897,7 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx) uint16 headroom; msgbuf_ring_t *msg_ring; + uint8 dhcp_pkt; if (!dhd_bus_is_txmode_push(dhd->bus)) { flow_ring_table_t *flow_ring_table; @@ -1926,7 +1941,11 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx) pktlen); goto err_no_res_pktfree; } - + /* test if dhcp pkt */ + dhcp_pkt = pkt_is_dhcp(dhd->osh, PKTBUF); + txdesc->flag2 = (txdesc->flag2 & ~(BCMPCIE_PKT_FLAGS2_FORCELOWRATE_MASK << + BCMPCIE_PKT_FLAGS2_FORCELOWRATE_SHIFT)) | ((dhcp_pkt & + BCMPCIE_PKT_FLAGS2_FORCELOWRATE_MASK) << BCMPCIE_PKT_FLAGS2_FORCELOWRATE_SHIFT); /* Extract the data pointer and length information */ pktdata = PKTDATA(dhd->osh, PKTBUF); pktlen = (uint16)PKTLEN(dhd->osh, PKTBUF); @@ -2096,7 +2115,6 @@ dhd_prot_return_rxbuf(dhd_pub_t *dhd, uint16 rxcnt) } - /* Use protocol to issue ioctl to dongle */ int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len) { @@ -2147,7 +2165,9 @@ int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int if (ret >= 0) ret = 0; else { - DHD_ERROR(("%s: status ret value is %d \n", __FUNCTION__, ret)); + if (ret != BCME_NOTASSOCIATED) { + DHD_ERROR(("%s: status ret value is %d \n", __FUNCTION__, ret)); + } dhd->dongle_error = ret; } @@ -2806,7 +2826,7 @@ prot_ring_attach(dhd_prot_t * prot, char* name, uint16 max_item, uint16 len_item bzero(ring, sizeof(*ring)); /* Init name */ - strncpy(ring->name, name, sizeof(ring->name) - 1); + strncpy(ring->name, name, sizeof(ring->name)); /* Ringid in the order given in bcmpcie.h */ ring->idx = ringid; @@ -2894,12 +2914,6 @@ dhd_prot_ring_detach(dhd_pub_t *dhd, msgbuf_ring_t * ring) if (ring == NULL) return; - - if (ring->ringmem == NULL) { - DHD_ERROR(("%s: ring->ringmem is NULL\n", __FUNCTION__)); - return; - } - ring->inited = FALSE; PHYSADDRHISET(phyaddr, ring->ringmem->base_addr.high_addr); @@ -3195,35 +3209,26 @@ prot_upd_read_idx(dhd_pub_t *dhd, msgbuf_ring_t * ring) dhd_bus_cmn_writeshared(dhd->bus, &(RING_READ_PTR(ring)), sizeof(uint16), RING_READ_PTR, ring->idx); } - static void prot_store_rxcpln_read_idx(dhd_pub_t *dhd, msgbuf_ring_t * ring) { dhd_prot_t *prot; - if (!dhd || !dhd->prot) return; - prot = dhd->prot; prot->rx_cpln_early_upd_idx = RING_READ_PTR(ring); } - static void prot_early_upd_rxcpln_read_idx(dhd_pub_t *dhd, msgbuf_ring_t * ring) { dhd_prot_t *prot; - if (!dhd || !dhd->prot) return; - prot = dhd->prot; - if (prot->rx_cpln_early_upd_idx == RING_READ_PTR(ring)) return; - if (++prot->rx_cpln_early_upd_idx >= RING_MAX_ITEM(ring)) prot->rx_cpln_early_upd_idx = 0; - if (DMA_INDX_ENAB(dhd->dma_h2d_ring_upd_support)) dhd_set_dmaed_index(dhd, D2H_DMA_READINDX, ring->idx, (uint16)prot->rx_cpln_early_upd_idx); @@ -3637,19 +3642,15 @@ dhd_rxchain_commit(dhd_pub_t *dhd) dhd_rxchain_reset(rxchain); } #endif /* DHD_RX_CHAINING */ - static void dhd_prot_ring_clear(msgbuf_ring_t* ring) { uint16 size; - - DHD_TRACE(("%s\n", __FUNCTION__)); + DHD_TRACE(("%s\n",__FUNCTION__)); size = ring->ringmem->max_item * ring->ringmem->len_items; - ASSERT(MODX((unsigned long)ring->ring_base.va, DMA_ALIGN_LEN) == 0); OSL_CACHE_INV((void *) ring->ring_base.va, size); bzero(ring->ring_base.va, size); - OSL_CACHE_FLUSH((void *) ring->ring_base.va, size); bzero(ring->ringstate, sizeof(*ring->ringstate)); @@ -3660,37 +3661,38 @@ dhd_prot_clear(dhd_pub_t *dhd) { struct dhd_prot *prot = dhd->prot; - DHD_TRACE(("%s\n", __FUNCTION__)); + DHD_TRACE(("%s\n",__FUNCTION__)); - if (prot == NULL) + if(prot == NULL) return; - if (prot->h2dring_txp_subn) + if(prot->h2dring_txp_subn) dhd_prot_ring_clear(prot->h2dring_txp_subn); - if (prot->h2dring_rxp_subn) + if(prot->h2dring_rxp_subn) dhd_prot_ring_clear(prot->h2dring_rxp_subn); - if (prot->h2dring_ctrl_subn) + if(prot->h2dring_ctrl_subn) dhd_prot_ring_clear(prot->h2dring_ctrl_subn); - if (prot->d2hring_tx_cpln) + if(prot->d2hring_tx_cpln) dhd_prot_ring_clear(prot->d2hring_tx_cpln); - if (prot->d2hring_rx_cpln) + if(prot->d2hring_rx_cpln) dhd_prot_ring_clear(prot->d2hring_rx_cpln); - if (prot->d2hring_ctrl_cpln) + if(prot->d2hring_ctrl_cpln) dhd_prot_ring_clear(prot->d2hring_ctrl_cpln); - if (prot->retbuf.va) { + + if(prot->retbuf.va) { OSL_CACHE_INV((void *) prot->retbuf.va, IOCT_RETBUF_SIZE); bzero(prot->retbuf.va, IOCT_RETBUF_SIZE); OSL_CACHE_FLUSH((void *) prot->retbuf.va, IOCT_RETBUF_SIZE); } - if (prot->ioctbuf.va) { + if(prot->ioctbuf.va) { OSL_CACHE_INV((void *) prot->ioctbuf.va, IOCT_RETBUF_SIZE); bzero(prot->ioctbuf.va, IOCT_RETBUF_SIZE); OSL_CACHE_FLUSH((void *) prot->ioctbuf.va, IOCT_RETBUF_SIZE); } - if (prot->d2h_dma_scratch_buf.va) { + if(prot->d2h_dma_scratch_buf.va) { OSL_CACHE_INV((void *)prot->d2h_dma_scratch_buf.va, DMA_D2H_SCRATCH_BUF_LEN); bzero(prot->d2h_dma_scratch_buf.va, DMA_D2H_SCRATCH_BUF_LEN); OSL_CACHE_FLUSH((void *)prot->d2h_dma_scratch_buf.va, DMA_D2H_SCRATCH_BUF_LEN); diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie.c b/drivers/net/wireless/bcmdhd/dhd_pcie.c index b26ba8596df99e4d6cedbc24e3ea725c037cf0b9..a6675d24101901daa17a76798a40680831c9f2af 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pcie.c +++ b/drivers/net/wireless/bcmdhd/dhd_pcie.c @@ -1,9 +1,27 @@ /* * DHD Bus Module for PCIE * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_pcie.c 491657 2014-07-17 06:29:40Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_pcie.c 477711 2014-05-14 08:45:17Z $ */ @@ -47,6 +65,8 @@ #define ARMCR4REG_BANKIDX (0x40/sizeof(uint32)) #define ARMCR4REG_BANKPDA (0x4C/sizeof(uint32)) /* Temporary war to fix precommit till sync issue between trunk & precommit branch is resolved */ +#define DHD_FLOW_RING(dhdp, flowid) \ + (flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid]) int dhd_dongle_memsize; int dhd_dongle_ramsize; @@ -89,11 +109,11 @@ static void dhdpcie_bus_reg_unmap(osl_t *osh, ulong addr, int size); static int dhdpcie_cc_nvmshadow(dhd_bus_t *bus, struct bcmstrbuf *b); static void dhdpcie_send_mb_data(dhd_bus_t *bus, uint32 h2d_mb_data); static void dhd_fillup_ring_sharedptr_info(dhd_bus_t *bus, ring_info_t *ring_info); -extern void dhd_dpc_kill(dhd_pub_t *dhdp); #ifdef BCMEMBEDIMAGE static int dhdpcie_download_code_array(dhd_bus_t *bus); #endif /* BCMEMBEDIMAGE */ +extern void dhd_dpc_kill(dhd_pub_t *dhdp); @@ -134,6 +154,7 @@ enum { }; + const bcm_iovar_t dhdpcie_iovars[] = { {"intr", IOV_INTR, 0, IOVT_BOOL, 0 }, {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, @@ -148,7 +169,6 @@ const bcm_iovar_t dhdpcie_iovars[] = { {"pciereg", IOV_PCIEREG, 0, IOVT_BUFFER, 2 * sizeof(int32) }, {"pciecfgreg", IOV_PCIECFGREG, 0, IOVT_BUFFER, 2 * sizeof(int32) }, {"pciecorereg", IOV_PCIECOREREG, 0, IOVT_BUFFER, 2 * sizeof(int32) }, - {"pcieserdesreg", IOV_PCIESERDESREG, 0, IOVT_BUFFER, 3 * sizeof(int32) }, {"bar0secwinreg", IOV_BAR0_SECWIN_REG, 0, IOVT_BUFFER, 2 * sizeof(int32) }, {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, {"pcie_dmaxfer", IOV_PCIE_DMAXFER, 0, IOVT_BUFFER, 3 * sizeof(int32) }, @@ -160,7 +180,6 @@ const bcm_iovar_t dhdpcie_iovars[] = { {"dma_ring_indices", IOV_DMA_RINGINDICES, 0, IOVT_UINT32, 0}, {"rx_metadata_len", IOV_RX_METADATALEN, 0, IOVT_UINT32, 0 }, {"tx_metadata_len", IOV_TX_METADATALEN, 0, IOVT_UINT32, 0 }, - {"db1_for_mb", IOV_DB1_FOR_MB, 0, IOVT_UINT32, 0 }, {"txp_thresh", IOV_TXP_THRESHOLD, 0, IOVT_UINT32, 0 }, {"buzzz_dump", IOV_BUZZZ_DUMP, 0, IOVT_UINT32, 0 }, {"flow_prio_map", IOV_FLOW_PRIO_MAP, 0, IOVT_UINT32, 0 }, @@ -217,7 +236,7 @@ dhd_bus_t* dhdpcie_bus_attach(osl_t *osh, volatile char* regs, volatile char* tc { dhd_bus_t *bus; - DHD_TRACE(("%s: ENTER\n", __FUNCTION__)); + DHD_ERROR(("%s: ENTER\n", __FUNCTION__)); do { if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) { @@ -349,7 +368,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus) } if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", + DHD_INFO(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); break; } @@ -455,7 +474,6 @@ dhdpcie_dongle_attach(dhd_bus_t *bus) case BCM4358_CHIP_ID: case BCM4356_CHIP_ID: case BCM4354_CHIP_ID: - case BCM43567_CHIP_ID: case BCM43569_CHIP_ID: case BCM4350_CHIP_ID: case BCM43570_CHIP_ID: @@ -495,6 +513,7 @@ dhdpcie_dongle_attach(dhd_bus_t *bus) bus->intr = (bool)dhd_intr; bus->wait_for_d3_ack = 1; + bus->suspended = FALSE; DHD_TRACE(("%s: EXIT: SUCCESS\n", __FUNCTION__)); return 0; @@ -524,10 +543,6 @@ void dhdpcie_bus_intr_enable(dhd_bus_t *bus) { DHD_TRACE(("enable interrupts\n")); - - if (!bus || !bus->sih) - return; - if ((bus->sih->buscorerev == 2) || (bus->sih->buscorerev == 6) || (bus->sih->buscorerev == 4)) { dhpcie_bus_unmask_interrupt(bus); @@ -544,18 +559,17 @@ dhdpcie_bus_intr_disable(dhd_bus_t *bus) DHD_TRACE(("%s Enter\n", __FUNCTION__)); - if (!bus || !bus->sih) - return; + if (bus) { - if ((bus->sih->buscorerev == 2) || (bus->sih->buscorerev == 6) || - (bus->sih->buscorerev == 4)) { - dhpcie_bus_mask_interrupt(bus); - } - else if (bus->sih) { - si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxMask, - bus->def_intmask, 0); + if ((bus->sih->buscorerev == 2) || (bus->sih->buscorerev == 6) || + (bus->sih->buscorerev == 4)) { + dhpcie_bus_mask_interrupt(bus); + } + else if (bus->sih) { + si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxMask, + bus->def_intmask, 0); + } } - DHD_TRACE(("%s Exit\n", __FUNCTION__)); } @@ -576,12 +590,15 @@ dhdpcie_bus_release(dhd_bus_t *bus) if (bus->dhd) { dongle_isolation = bus->dhd->dongle_isolation; - dhd_detach(bus->dhd); if (bus->intr) { - dhdpcie_bus_intr_disable(bus); + if (bus->dhd->dongle_reset == FALSE) + dhdpcie_bus_intr_disable(bus); dhdpcie_free_irq(bus); } + /* Disable tasklet, already scheduled tasklet may be executed even though dongle has been released */ + dhd_dpc_kill(bus->dhd); + dhd_detach(bus->dhd); dhdpcie_bus_release_dongle(bus, osh, dongle_isolation, TRUE); dhd_free(bus->dhd); bus->dhd = NULL; @@ -711,11 +728,10 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) if (!bus->dhd) return; - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s: already down by net_dev_reset\n", __FUNCTION__)); + if(bus->dhd->busstate == DHD_BUS_DOWN) { + DHD_ERROR(("%s: already down by net_dev_reset\n",__FUNCTION__)); goto done; } - bus->dhd->busstate = DHD_BUS_DOWN; dhdpcie_bus_intr_disable(bus); status = dhdpcie_bus_cfg_read_dword(bus, PCIIntstatus, 4); @@ -726,8 +742,8 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Clear rx control and wake any waiters */ bus->rxlen = 0; dhd_os_ioctl_resp_wake(bus->dhd); - done: + return; } @@ -755,8 +771,6 @@ bool dhd_bus_watchdog(dhd_pub_t *dhd) return FALSE; } - - /* Download firmware image and nvram image */ int dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, @@ -777,9 +791,6 @@ dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh) { int ret = 0; - DHD_TRACE_HW4(("%s: firmware path=%s, nvram path=%s\n", - __FUNCTION__, bus->fw_path, bus->nv_path)); - DHD_OS_WAKE_LOCK(bus->dhd); ret = _dhdpcie_download_firmware(bus); @@ -1436,7 +1447,6 @@ done: } #endif /* DHD_DEBUG */ - /** * Transfers bytes from host to dongle using pio mode. * Parameter 'address' is a backplane address. @@ -1521,8 +1531,6 @@ dhd_bus_schedule_queue(struct dhd_bus *bus, uint16 flow_id, bool txs) DHD_QUEUE_LOCK(queue->lock, flags); while ((txp = dhd_flow_queue_dequeue(bus->dhd, queue)) != NULL) { - PKTORPHAN(txp); - #ifdef DHDTCPACK_SUPPRESS dhd_tcpack_check_xmit(bus->dhd, txp); #endif /* DHDTCPACK_SUPPRESS */ @@ -1706,118 +1714,66 @@ dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count) void dhdpcie_bus_wtcm8(dhd_bus_t *bus, ulong offset, uint8 data) { -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ *(volatile uint8 *)(bus->tcm + offset) = (uint8)data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ } uint8 dhdpcie_bus_rtcm8(dhd_bus_t *bus, ulong offset) { - volatile uint8 data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ #ifdef BCM47XX_ACP_WAR - data = R_REG(bus->dhd->osh, (volatile uint8 *)(bus->tcm + offset)); + volatile uint8 data = R_REG(bus->dhd->osh, (volatile uint8 *)(bus->tcm + offset)); #else - data = *(volatile uint8 *)(bus->tcm + offset); + volatile uint8 data = *(volatile uint8 *)(bus->tcm + offset); #endif -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ return data; } void dhdpcie_bus_wtcm32(dhd_bus_t *bus, ulong offset, uint32 data) { -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ *(volatile uint32 *)(bus->tcm + offset) = (uint32)data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ } void dhdpcie_bus_wtcm16(dhd_bus_t *bus, ulong offset, uint16 data) { -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ *(volatile uint16 *)(bus->tcm + offset) = (uint16)data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ } void dhdpcie_bus_wtcm64(dhd_bus_t *bus, ulong offset, uint64 data) { -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ *(volatile uint64 *)(bus->tcm + offset) = (uint64)data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ } uint16 dhdpcie_bus_rtcm16(dhd_bus_t *bus, ulong offset) { - volatile uint16 data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ #ifdef BCM47XX_ACP_WAR - data = R_REG(bus->dhd->osh, (volatile uint16 *)(bus->tcm + offset)); + volatile uint16 data = R_REG(bus->dhd->osh, (volatile uint16 *)(bus->tcm + offset)); #else - data = *(volatile uint16 *)(bus->tcm + offset); + volatile uint16 data = *(volatile uint16 *)(bus->tcm + offset); #endif -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ return data; } uint32 dhdpcie_bus_rtcm32(dhd_bus_t *bus, ulong offset) { - volatile uint32 data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ #ifdef BCM47XX_ACP_WAR - data = R_REG(bus->dhd->osh, (volatile uint32 *)(bus->tcm + offset)); + volatile uint32 data = R_REG(bus->dhd->osh, (volatile uint32 *)(bus->tcm + offset)); #else - data = *(volatile uint32 *)(bus->tcm + offset); + volatile uint32 data = *(volatile uint32 *)(bus->tcm + offset); #endif -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ return data; } uint64 dhdpcie_bus_rtcm64(dhd_bus_t *bus, ulong offset) { - volatile uint64 data; -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ #ifdef BCM47XX_ACP_WAR - data = R_REG(bus->dhd->osh, (volatile uint64 *)(bus->tcm + offset)); + volatile uint64 data = R_REG(bus->dhd->osh, (volatile uint64 *)(bus->tcm + offset)); #else - data = *(volatile uint64 *)(bus->tcm + offset); + volatile uint64 data = *(volatile uint64 *)(bus->tcm + offset); #endif -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ return data; } @@ -2297,220 +2253,6 @@ done: } #endif /* BCM_BUZZZ */ -#define PCIE_GEN2(sih) ((BUSTYPE((sih)->bustype) == PCI_BUS) && \ - ((sih)->buscoretype == PCIE2_CORE_ID)) - -static bool -pcie2_mdiosetblock(dhd_bus_t *bus, uint blk) -{ - uint mdiodata, mdioctrl, i = 0; - uint pcie_serdes_spinwait = 200; - - mdioctrl = MDIOCTL2_DIVISOR_VAL | (0x1F << MDIOCTL2_REGADDR_SHF); - mdiodata = (blk << MDIODATA2_DEVADDR_SHF) | MDIODATA2_DONE; - - si_corereg(bus->sih, bus->sih->buscoreidx, PCIE2_MDIO_CONTROL, ~0, mdioctrl); - si_corereg(bus->sih, bus->sih->buscoreidx, PCIE2_MDIO_WR_DATA, ~0, mdiodata); - - OSL_DELAY(10); - /* retry till the transaction is complete */ - while (i < pcie_serdes_spinwait) { - uint mdioctrl_read = si_corereg(bus->sih, bus->sih->buscoreidx, PCIE2_MDIO_WR_DATA, - 0, 0); - if (!(mdioctrl_read & MDIODATA2_DONE)) { - break; - } - OSL_DELAY(1000); - i++; - } - - if (i >= pcie_serdes_spinwait) { - DHD_ERROR(("pcie_mdiosetblock: timed out\n")); - return FALSE; - } - - return TRUE; -} - - -static int -pcie2_mdioop(dhd_bus_t *bus, uint physmedia, uint regaddr, bool write, uint *val, - bool slave_bypass) -{ - uint pcie_serdes_spinwait = 200, i = 0, mdio_ctrl; - uint32 reg32; - - pcie2_mdiosetblock(bus, physmedia); - - /* enable mdio access to SERDES */ - mdio_ctrl = MDIOCTL2_DIVISOR_VAL; - mdio_ctrl |= (regaddr << MDIOCTL2_REGADDR_SHF); - - if (slave_bypass) - mdio_ctrl |= MDIOCTL2_SLAVE_BYPASS; - - if (!write) - mdio_ctrl |= MDIOCTL2_READ; - - si_corereg(bus->sih, bus->sih->buscoreidx, PCIE2_MDIO_CONTROL, ~0, mdio_ctrl); - - if (write) { - reg32 = PCIE2_MDIO_WR_DATA; - si_corereg(bus->sih, bus->sih->buscoreidx, PCIE2_MDIO_WR_DATA, ~0, - *val | MDIODATA2_DONE); - } - else - reg32 = PCIE2_MDIO_RD_DATA; - - /* retry till the transaction is complete */ - while (i < pcie_serdes_spinwait) { - uint done_val = si_corereg(bus->sih, bus->sih->buscoreidx, reg32, 0, 0); - if (!(done_val & MDIODATA2_DONE)) { - if (!write) { - *val = si_corereg(bus->sih, bus->sih->buscoreidx, - PCIE2_MDIO_RD_DATA, 0, 0); - *val = *val & MDIODATA2_MASK; - } - return 0; - } - OSL_DELAY(1000); - i++; - } - return -1; -} - -int -dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) -{ - dhd_bus_t *bus = dhdp->bus; - int bcmerror = 0; -#ifdef CONFIG_ARCH_MSM - int retry = POWERUP_MAX_RETRY; -#endif /* CONFIG_ARCH_MSM */ - - if (dhd_download_fw_on_driverload) { - bcmerror = dhd_bus_start(dhdp); - } else { - if (flag == TRUE) { /* Turn off WLAN */ - /* Removing Power */ - DHD_ERROR(("%s: == Power OFF ==\n", __FUNCTION__)); - bus->dhd->up = FALSE; - if (bus->dhd->busstate != DHD_BUS_DOWN) { - dhd_prot_clear(dhdp); - dhd_os_wd_timer(dhdp, 0); - dhd_bus_stop(bus, TRUE); -#ifdef CONFIG_ARCH_MSM - dhd_bus_release_dongle(bus); -#endif /* CONFIG_ARCH_MSM */ - dhdpcie_bus_free_resource(bus); - bcmerror = dhdpcie_bus_disable_device(bus); - if (bcmerror) { - DHD_ERROR(("%s: dhdpcie_bus_disable_device: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } -#ifdef CONFIG_ARCH_MSM - bcmerror = dhdpcie_bus_clock_stop(bus); - if (bcmerror) { - DHD_ERROR(("%s: host clock stop failed: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } -#endif /* CONFIG_ARCH_MSM */ - bus->dhd->busstate = DHD_BUS_DOWN; - } else { - dhd_prot_clear(dhdp); -#ifdef CONFIG_ARCH_MSM - dhd_bus_release_dongle(bus); -#endif /* CONFIG_ARCH_MSM */ - dhdpcie_bus_free_resource(bus); - bcmerror = dhdpcie_bus_disable_device(bus); - if (bcmerror) { - DHD_ERROR(("%s: dhdpcie_bus_disable_device: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } - -#ifdef CONFIG_ARCH_MSM - bcmerror = dhdpcie_bus_clock_stop(bus); - if (bcmerror) { - DHD_ERROR(("%s: host clock stop failed: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } -#endif /* CONFIG_ARCH_MSM */ - } - - bus->dhd->dongle_reset = TRUE; - DHD_ERROR(("%s: WLAN OFF Done\n", __FUNCTION__)); - - } else { /* Turn on WLAN */ - if (bus->dhd->busstate == DHD_BUS_DOWN) { - /* Powering On */ - DHD_ERROR(("%s: == Power ON ==\n", __FUNCTION__)); -#ifdef CONFIG_ARCH_MSM - while (retry--) { - bcmerror = dhdpcie_bus_clock_start(bus); - if (!bcmerror) { - DHD_ERROR(("%s: dhdpcie_bus_clock_start OK\n", - __FUNCTION__)); - break; - } - else - OSL_SLEEP(10); - } - - if (bcmerror && !retry) { - DHD_ERROR(("%s: host pcie clock enable failed: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } -#endif /* CONFIG_ARCH_MSM */ - bcmerror = dhdpcie_bus_enable_device(bus); - if (bcmerror) { - DHD_ERROR(("%s: host configuration restore failed: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } - - bcmerror = dhdpcie_bus_alloc_resource(bus); - if (bcmerror) { - DHD_ERROR(("%s: dhdpcie_bus_resource_alloc failed: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } - - bcmerror = dhdpcie_bus_dongle_attach(bus); - if (bcmerror) { - DHD_ERROR(("%s: dhdpcie_bus_dongle_attach: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } - - bus->dhd->dongle_reset = FALSE; - - bcmerror = dhd_bus_start(dhdp); - if (bcmerror) { - DHD_ERROR(("%s: dhd_bus_start: %d\n", - __FUNCTION__, bcmerror)); - goto done; - } - - bus->dhd->up = TRUE; - DHD_ERROR(("%s: WLAN Power On Done\n", __FUNCTION__)); - } else { - DHD_ERROR(("%s: what should we do here\n", __FUNCTION__)); - goto done; - } - } - } -done: - if (bcmerror) - bus->dhd->busstate = DHD_BUS_DOWN; - - return bcmerror; -} - static int dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, void *params, int plen, void *arg, int len, int val_size) @@ -2564,7 +2306,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons int_val); int_val = si_corereg(bus->sih, bus->sih->buscoreidx, OFFSETOF(sbpcieregs_t, configdata), 0, 0); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_BAR0_SECWIN_REG): @@ -2580,7 +2322,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons bar0 = (uchar *)bus->regs; offset = (uint32 *)(bar0 + 0x4000 + (int_val & 0xFFF)); int_val = *offset; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); dhdpcie_bus_cfg_write_dword(bus, PCIE2_BAR0_CORE2_WIN, sizeof(uint32), cur_base); } break; @@ -2635,37 +2377,10 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons break; } - case IOV_GVAL(IOV_PCIESERDESREG): - { - uint val; - if (!PCIE_GEN2(bus->sih)) { - DHD_ERROR(("supported only in pcie gen2\n")); - bcmerror = BCME_ERROR; - break; - } - if (!pcie2_mdioop(bus, int_val, int_val2, FALSE, &val, FALSE)) { - bcopy(&val, arg, sizeof(int32)); - } - else { - DHD_ERROR(("pcie2_mdioop failed.\n")); - bcmerror = BCME_ERROR; - } - break; - } - case IOV_SVAL(IOV_PCIESERDESREG): - if (!PCIE_GEN2(bus->sih)) { - DHD_ERROR(("supported only in pcie gen2\n")); - bcmerror = BCME_ERROR; - break; - } - if (pcie2_mdioop(bus, int_val, int_val2, TRUE, &int_val3, FALSE)) { - DHD_ERROR(("pcie2_mdioop failed.\n")); - bcmerror = BCME_ERROR; - } - break; + case IOV_GVAL(IOV_PCIECOREREG): int_val = si_corereg(bus->sih, bus->sih->buscoreidx, int_val, 0, 0); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PCIECFGREG): @@ -2674,7 +2389,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_PCIECFGREG): int_val = OSL_PCI_READ_CONFIG(bus->osh, int_val, 4); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PCIE_LPBK): @@ -2687,7 +2402,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_PCIE_SUSPEND): int_val = (bus->dhd->busstate == DHD_BUS_SUSPEND) ? 1 : 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_PCIE_SUSPEND): @@ -2696,7 +2411,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_MEMSIZE): int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_MEMBYTES): case IOV_GVAL(IOV_MEMBYTES): @@ -2796,12 +2511,12 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_RAMSIZE): int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_RAMSTART): int_val = (int32)bus->dongle_ram_base; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_CC_NVMSHADOW): @@ -2824,7 +2539,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_DONGLEISOLATION): int_val = bus->dhd->dongle_isolation; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DONGLEISOLATION): @@ -2833,7 +2548,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_LTRSLEEPON_UNLOOAD): int_val = bus->ltrsleep_on_unload; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_LTRSLEEPON_UNLOOAD): @@ -2853,7 +2568,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons d2h_support = DMA_INDX_ENAB(bus->dhd->dma_d2h_ring_upd_support) ? 1 : 0; h2d_support = DMA_INDX_ENAB(bus->dhd->dma_h2d_ring_upd_support) ? 1 : 0; int_val = d2h_support | (h2d_support << 1); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; } case IOV_SVAL(IOV_DMA_RINGINDICES): @@ -2875,7 +2590,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_RX_METADATALEN): int_val = dhd_prot_metadatalen_get(bus->dhd, TRUE); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_RX_METADATALEN): @@ -2892,7 +2607,7 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_TXP_THRESHOLD): int_val = dhd_prot_txp_threshold(bus->dhd, FALSE, int_val); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DB1_FOR_MB): @@ -2907,12 +2622,12 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons int_val = 1; else int_val = 0; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_TX_METADATALEN): int_val = dhd_prot_metadatalen_get(bus->dhd, FALSE); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_TX_METADATALEN): @@ -2925,12 +2640,12 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons case IOV_GVAL(IOV_FLOW_PRIO_MAP): int_val = bus->dhd->flow_prio_map_type; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_FLOW_PRIO_MAP): int_val = (int32)dhd_update_flow_prio_map(bus->dhd, (uint8)int_val); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; default: @@ -2941,7 +2656,6 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons exit: return bcmerror; } - /* Transfers bytes from host to dongle using pio mode */ static int dhdpcie_bus_lpback_req(struct dhd_bus *bus, uint32 len) @@ -2978,6 +2692,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) int timeleft; bool pending; int rc = 0; + DHD_ERROR(("%s Enter with state :%d\n", __FUNCTION__, state)); if (bus->dhd == NULL) { DHD_ERROR(("bus not inited\n")); @@ -2994,40 +2709,54 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) if (bus->dhd->dongle_reset) return -EIO; - if (state == (bus->dhd->busstate == DHD_BUS_SUSPEND)) /* Set to same state */ + + if (bus->suspended == state) /* Set to same state */ return BCME_OK; if (state) { -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_set_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ bus->wait_for_d3_ack = 0; + bus->suspended = TRUE; + bus->dhd->busstate = DHD_BUS_SUSPEND; DHD_OS_WAKE_LOCK_WAIVE(bus->dhd); + dhd_os_set_ioctl_resp_timeout(DEFAULT_IOCTL_RESP_TIMEOUT); dhdpcie_send_mb_data(bus, H2D_HOST_D3_INFORM); - timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->wait_for_d3_ack, &pending); + timeleft = dhd_os_d3ack_wait(bus->dhd, &bus->wait_for_d3_ack, &pending); + dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT); DHD_OS_WAKE_LOCK_RESTORE(bus->dhd); if (bus->wait_for_d3_ack) { /* Got D3 Ack. Suspend the bus */ - rc = dhdpcie_pci_suspend_resume(bus->dev, state); - bus->dhd->busstate = DHD_BUS_SUSPEND; + if (dhd_os_check_wakelock_all(bus->dhd)) { + DHD_ERROR(("Suspend failed because of wakelock\n")); + bus->dev->current_state = PCI_D3hot; + pci_set_master(bus->dev); + rc = pci_set_power_state(bus->dev, PCI_D0); + if (rc) { + DHD_ERROR(("%s: pci_set_power_state failed:" + " current_state[%d], ret[%d]\n", + __FUNCTION__, bus->dev->current_state, rc)); + } + bus->suspended = FALSE; + bus->dhd->busstate = DHD_BUS_DATA; + rc = BCME_ERROR; + } else { + dhdpcie_bus_intr_disable(bus); + rc = dhdpcie_pci_suspend_resume(bus->dev, state); + } } else if (timeleft == 0) { DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ - return -ETIMEDOUT; + bus->suspended = FALSE; + bus->dhd->busstate = DHD_BUS_DATA; + rc = -ETIMEDOUT; } bus->wait_for_d3_ack = 1; - } - else { + } else { /* Resume */ + DHD_ERROR(("dhdpcie_bus_suspend resume\n")); rc = dhdpcie_pci_suspend_resume(bus->dev, state); + bus->suspended = FALSE; bus->dhd->busstate = DHD_BUS_DATA; - + dhdpcie_bus_intr_enable(bus); } -#ifdef EXYNOS5433_PCIE_WAR - exynos_pcie_clear_l1_exit(); -#endif /* EXYNOS5433_PCIE_WAR */ return rc; } @@ -3367,7 +3096,6 @@ dhd_update_txflowrings(dhd_pub_t *dhd) } } - /* Mailbox ringbell Function */ static void dhd_bus_gen_devmb_intr(struct dhd_bus *bus) @@ -3379,12 +3107,14 @@ dhd_bus_gen_devmb_intr(struct dhd_bus *bus) } if (bus->db1_for_mb) { /* this is a pcie core register, not the config regsiter */ + /* XXX: makesure we are on PCIE */ DHD_INFO(("writing a mail box interrupt to the device, through doorbell 1\n")); si_corereg(bus->sih, bus->sih->buscoreidx, PCIH2D_DB1, ~0, 0x12345678); } else { DHD_INFO(("writing a mail box interrupt to the device, through config space\n")); dhdpcie_bus_cfg_write_dword(bus, PCISBMbx, 4, (1 << 0)); + /* XXX CRWLPCIEGEN2-182 requires double write */ dhdpcie_bus_cfg_write_dword(bus, PCISBMbx, 4, (1 << 0)); } } @@ -3454,13 +3184,6 @@ dhd_bus_dpc(struct dhd_bus *bus) return 0; } - if (bus->dhd->busstate == DHD_BUS_SUSPEND) { - resched = TRUE; - DHD_ERROR(("%s : pcie is still in suspend state!!!\n", __FUNCTION__)); - OSL_DELAY(20 * 1000); /* 20ms */ - return resched; - } - intstatus = bus->intstatus; if ((bus->sih->buscorerev == 6) || (bus->sih->buscorerev == 4) || @@ -3510,9 +3233,6 @@ dhdpcie_send_mb_data(dhd_bus_t *bus, uint32 h2d_mb_data) dhd_bus_cmn_writeshared(bus, &h2d_mb_data, sizeof(uint32), HTOD_MB_DATA, 0); dhd_bus_gen_devmb_intr(bus); - - if (h2d_mb_data == H2D_HOST_D3_INFORM) - DHD_INFO_HW4(("%s: send H2D_HOST_D3_INFORM to dongle\n", __FUNCTION__)); } static void @@ -3539,10 +3259,10 @@ dhdpcie_handle_mb_data(dhd_bus_t *bus) } if (d2h_mb_data & D2H_DEV_D3_ACK) { /* what should we do */ - DHD_INFO_HW4(("%s D2H_MB_DATA: Received D3 ACK\n", __FUNCTION__)); + DHD_ERROR(("D2H_MB_DATA: D3 ACK\n")); if (!bus->wait_for_d3_ack) { bus->wait_for_d3_ack = 1; - dhd_os_ioctl_resp_wake(bus->dhd); + dhd_os_d3ack_wake(bus->dhd); } } if (d2h_mb_data & D2H_DEV_FWHALT) { @@ -3570,6 +3290,11 @@ dhdpcie_bus_process_mailbox_intr(dhd_bus_t *bus, uint32 intstatus) else { if (intstatus & (PCIE_MB_TOPCIE_FN0_0 | PCIE_MB_TOPCIE_FN0_1)) dhdpcie_handle_mb_data(bus); + + if (bus->dhd->busstate == DHD_BUS_SUSPEND) { + return; + } + if (intstatus & PCIE_MB_D2H_MB_MASK) { dhdpci_bus_read_frames(bus); } @@ -4345,18 +4070,6 @@ dhdpcie_bus_enable_device(struct dhd_bus *bus) return dhdpcie_enable_device(bus); } -int -dhdpcie_bus_alloc_resource(struct dhd_bus *bus) -{ - return dhdpcie_alloc_resource(bus); -} - -void -dhdpcie_bus_free_resource(struct dhd_bus *bus) -{ - dhdpcie_free_resource(bus); -} - bool dhdpcie_bus_dongle_attach(struct dhd_bus *bus) { diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie.h b/drivers/net/wireless/bcmdhd/dhd_pcie.h index 5ea6c42f15795f67b6f745bb502377808bade6ac..7ce8aa3b27037aa3684a5f8195978a77204d1eef 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pcie.h +++ b/drivers/net/wireless/bcmdhd/dhd_pcie.h @@ -1,9 +1,27 @@ /* * Linux DHD Bus Module for PCIE * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_pcie.h 491657 2014-07-17 06:29:40Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_pcie.h 473468 2014-04-29 07:30:27Z $ */ @@ -138,7 +156,7 @@ typedef struct dhd_bus { uint8 txmode_push; uint32 max_sub_queues; bool db1_for_mb; - + bool suspended; } dhd_bus_t; /* function declarations */ @@ -161,8 +179,6 @@ extern int dhdpcie_start_host_pcieclock(dhd_bus_t *bus); extern int dhdpcie_stop_host_pcieclock(dhd_bus_t *bus); extern int dhdpcie_disable_device(dhd_bus_t *bus); extern int dhdpcie_enable_device(dhd_bus_t *bus); -extern int dhdpcie_alloc_resource(dhd_bus_t *bus); -extern void dhdpcie_free_resource(dhd_bus_t *bus); extern int dhd_buzzz_dump_dngl(dhd_bus_t *bus); #endif /* dhd_pcie_h */ diff --git a/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c b/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c index 706a59e245f1070ac5c670c49786267445333c98..781c17c0359c2ea3167feeab16ce5983418fcff4 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c @@ -1,9 +1,27 @@ /* * Linux DHD Bus Module for PCIE * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_pcie_linux.c 491657 2014-07-17 06:29:40Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_pcie_linux.c 477713 2014-05-14 08:59:12Z $ */ @@ -29,8 +47,7 @@ #include <bcmmsgbuf.h> #include <pcicfg.h> #include <dhd_pcie.h> -#include <dhd_linux.h> -#ifdef CONFIG_ARCH_MSM +#if defined (CONFIG_ARCH_MSM) #include <mach/msm_pcie.h> #endif @@ -72,7 +89,9 @@ typedef struct dhdpcie_info uint16 last_intrstatus; /* to cache intrstatus */ int irq; char pciname[32]; + struct pci_saved_state* state; + } dhdpcie_info_t; @@ -147,7 +166,7 @@ static int dhdpcie_set_suspend_resume(struct pci_dev *pdev, bool state) int ret = 0; dhdpcie_info_t *pch = pci_get_drvdata(pdev); dhd_bus_t *bus = NULL; - + DHD_ERROR(("%s Enter with state :%x\n", __FUNCTION__, state)); if (pch) { bus = pch->bus; } @@ -161,44 +180,43 @@ static int dhdpcie_set_suspend_resume(struct pci_dev *pdev, bool state) } if (bus && ((bus->dhd->busstate == DHD_BUS_SUSPEND)|| - (bus->dhd->busstate == DHD_BUS_DATA))) { + (bus->dhd->busstate == DHD_BUS_DATA)) && + (bus->suspended != state)) { ret = dhdpcie_bus_suspend(bus, state); } + DHD_ERROR(("%s Exit with state :%d\n", __FUNCTION__, ret)); return ret; } static int dhdpcie_pci_suspend(struct pci_dev * pdev, pm_message_t state) { BCM_REFERENCE(state); + DHD_ERROR(("%s Enter with event %x\n", __FUNCTION__, state.event)); return dhdpcie_set_suspend_resume(pdev, TRUE); } static int dhdpcie_pci_resume(struct pci_dev *pdev) { + DHD_ERROR(("%s Enter\n", __FUNCTION__)); return dhdpcie_set_suspend_resume(pdev, FALSE); } static int dhdpcie_suspend_dev(struct pci_dev *dev) { int ret; - DHD_TRACE_HW4(("%s: Enter\n", __FUNCTION__)); dhdpcie_pme_active(dev, TRUE); pci_save_state(dev); pci_enable_wake(dev, PCI_D0, TRUE); - pci_disable_device(dev); + if (pci_is_enabled(dev)) + pci_disable_device(dev); ret = pci_set_power_state(dev, PCI_D3hot); - if (ret) { - DHD_ERROR(("%s: pci_set_power_state error %d\n", - __FUNCTION__, ret)); - } return ret; } static int dhdpcie_resume_dev(struct pci_dev *dev) { int err = 0; - DHD_TRACE_HW4(("%s: Enter\n", __FUNCTION__)); pci_restore_state(dev); err = pci_enable_device(dev); if (err) { @@ -206,6 +224,12 @@ static int dhdpcie_resume_dev(struct pci_dev *dev) return err; } pci_set_master(dev); + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state + * Code taken from ipw2100 driver + */ err = pci_set_power_state(dev, PCI_D0); if (err) { printf("%s:pci_set_power_state error %d \n", __FUNCTION__, err); @@ -299,7 +323,8 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) DHD_ERROR(("%s: PCIe Enumeration failed\n", __FUNCTION__)); return -ENODEV; } - + /* disable async suspend */ + device_disable_async_suspend(&pdev->dev); DHD_TRACE(("%s: PCIe Enumeration done!!\n", __FUNCTION__)); return 0; } @@ -307,8 +332,8 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int dhdpcie_detach(dhdpcie_info_t *pch) { + osl_t *osh = pch->osh; if (pch) { - osl_t *osh = pch->osh; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) if (!dhd_download_fw_on_driverload) pci_load_and_free_saved_state(pch->dev, &pch->state); @@ -484,8 +509,7 @@ int dhdpcie_init(struct pci_dev *pdev) osl_t *osh = NULL; dhd_bus_t *bus = NULL; dhdpcie_info_t *dhdpcie_info = NULL; - wifi_adapter_info_t *adapter = NULL; - + DHD_ERROR(("%s enter\n", __FUNCTION__)); do { /* osl attach */ if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { @@ -493,15 +517,6 @@ int dhdpcie_init(struct pci_dev *pdev) break; } - /* initialize static buffer */ - adapter = dhd_wifi_platform_get_adapter(PCI_BUS, pdev->bus->number, - PCI_SLOT(pdev->devfn)); - if (adapter != NULL) - DHD_ERROR(("%s: found adapter info '%s'\n", __FUNCTION__, adapter->name)); - else - DHD_ERROR(("%s: can't find adapter info for this chip\n", __FUNCTION__)); - osl_static_mem_init(osh, adapter); - /* allocate linux spcific pcie structure here */ if (!(dhdpcie_info = MALLOC(osh, sizeof(dhdpcie_info_t)))) { DHD_ERROR(("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__)); @@ -544,26 +559,25 @@ int dhdpcie_init(struct pci_dev *pdev) "due to polling mode\n", __FUNCTION__)); } - if (dhd_download_fw_on_driverload) { - if (dhd_bus_start(bus->dhd)) { - DHD_ERROR(("%s: dhd_bud_start() failed\n", __FUNCTION__)); - break; - } - } /* set private data for pci_dev */ pci_set_drvdata(pdev, dhdpcie_info); - /* Attach to the OS network interface */ DHD_TRACE(("%s(): Calling dhd_register_if() \n", __FUNCTION__)); - if (dhd_register_if(bus->dhd, 0, TRUE)) { + if(dhd_register_if(bus->dhd, 0, TRUE)) { DHD_ERROR(("%s(): ERROR.. dhd_register_if() failed\n", __FUNCTION__)); break; } + if (dhd_download_fw_on_driverload) { + if (dhd_bus_start(bus->dhd)) { + DHD_ERROR(("%s: dhd_bud_start() failed\n", __FUNCTION__)); + break; + } + } dhdpcie_init_succeeded = TRUE; - DHD_TRACE(("%s:Exit - SUCCESS \n", __FUNCTION__)); + DHD_ERROR(("%s:Exit - SUCCESS \n", __FUNCTION__)); return 0; /* return SUCCESS */ } while (0); @@ -632,79 +646,56 @@ dhdpcie_isr(int irq, void *arg) int dhdpcie_start_host_pcieclock(dhd_bus_t *bus) { - int ret = 0; -#ifdef SUPPORT_LINKDOWN_RECOVERY - int options = 0; -#endif /* SUPPORT_LINKDOWN_RECOVERY */ + int ret=0; + DHD_TRACE(("%s Enter:\n", __FUNCTION__)); - if (bus == NULL) + if(bus == NULL) return BCME_ERROR; - if (bus->dev == NULL) + if(bus->dev == NULL) return BCME_ERROR; -#if defined(CONFIG_ARCH_MSM) -#ifdef SUPPORT_LINKDOWN_RECOVERY - if (bus->islinkdown) { - options = MSM_PCIE_CONFIG_NO_CFG_RESTORE; - } - ret = msm_pcie_pm_control(MSM_PCIE_RESUME, bus->dev->bus->number, - NULL, NULL, options); - if (bus->islinkdown && !ret) { - msm_pcie_recover_config(bus->dev); - if (bus->dhd) - DHD_OS_WAKE_UNLOCK(bus->dhd); - bus->islinkdown = FALSE; - } -#else - ret = msm_pcie_pm_control(MSM_PCIE_RESUME, bus->dev->bus->number, - NULL, NULL, 0); -#endif /* SUPPORT_LINKDOWN_RECOVERY */ +#if defined (CONFIG_ARCH_MSM) + ret = msm_pcie_pm_control(MSM_PCIE_RESUME, + bus->dev->bus->number, + NULL, NULL, 0); if (ret) { DHD_ERROR(("%s Failed to bring up PCIe link\n", __FUNCTION__)); goto done; } +#endif done: -#endif /* CONFIG_ARCH_MSM */ DHD_TRACE(("%s Exit:\n", __FUNCTION__)); + return ret; } int dhdpcie_stop_host_pcieclock(dhd_bus_t *bus) { - int ret = 0; + int ret=0; -#ifdef SUPPORT_LINKDOWN_RECOVERY - int options = 0; -#endif DHD_TRACE(("%s Enter:\n", __FUNCTION__)); - if (bus == NULL) + if(bus == NULL) return BCME_ERROR; - if (bus->dev == NULL) + if(bus->dev == NULL) return BCME_ERROR; -#if defined(CONFIG_ARCH_MSM) -#ifdef SUPPORT_LINKDOWN_RECOVERY - if (bus->islinkdown) - options = MSM_PCIE_CONFIG_NO_CFG_RESTORE | MSM_PCIE_CONFIG_LINKDOWN; - - ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, bus->dev->bus->number, - NULL, NULL, options); -#else - ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, bus->dev->bus->number, - NULL, NULL, 0); -#endif /* SUPPORT_LINKDOWN_RECOVERY */ +#if defined (CONFIG_ARCH_MSM) + ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, + bus->dev->bus->number, + NULL, NULL, 0); if (ret) { DHD_ERROR(("Failed to stop PCIe link\n")); goto done; } +#endif + done: -#endif /* CONFIG_ARCH_MSM */ DHD_TRACE(("%s Exit:\n", __FUNCTION__)); return ret; } @@ -731,14 +722,14 @@ dhdpcie_enable_device(dhd_bus_t *bus) DHD_TRACE(("%s Enter:\n", __FUNCTION__)); - if (bus == NULL) + if(bus == NULL) return BCME_ERROR; - if (bus->dev == NULL) + if(bus->dev == NULL) return BCME_ERROR; pch = pci_get_drvdata(bus->dev); - if (pch == NULL) + if(pch == NULL) return BCME_ERROR; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -748,112 +739,15 @@ dhdpcie_enable_device(dhd_bus_t *bus) #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ pci_restore_state(bus->dev); ret = pci_enable_device(bus->dev); - if (!ret) + if(!ret) pci_set_master(bus->dev); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ - if (ret) + if(ret) pci_disable_device(bus->dev); return ret; } -int -dhdpcie_alloc_resource(dhd_bus_t *bus) -{ - dhdpcie_info_t *dhdpcie_info; - phys_addr_t bar0_addr, bar1_addr; - ulong bar1_size; - - do { - if (bus == NULL) { - DHD_ERROR(("%s: bus is NULL\n", __FUNCTION__)); - break; - } - - if (bus->dev == NULL) { - DHD_ERROR(("%s: bus->dev is NULL\n", __FUNCTION__)); - break; - } - - dhdpcie_info = pci_get_drvdata(bus->dev); - if (dhdpcie_info == NULL) { - DHD_ERROR(("%s: dhdpcie_info is NULL\n", __FUNCTION__)); - break; - } - - bar0_addr = pci_resource_start(bus->dev, 0); /* Bar-0 mapped address */ - bar1_addr = pci_resource_start(bus->dev, 2); /* Bar-1 mapped address */ - - /* read Bar-1 mapped memory range */ - bar1_size = pci_resource_len(bus->dev, 2); - - if ((bar1_size == 0) || (bar1_addr == 0)) { - printf("%s: BAR1 Not enabled for this device size(%ld)," - " addr(0x"PRINTF_RESOURCE")\n", - __FUNCTION__, bar1_size, bar1_addr); - break; - } - - dhdpcie_info->regs = (volatile char *) REG_MAP(bar0_addr, DONGLE_REG_MAP_SIZE); - if (!dhdpcie_info->regs) { - DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__)); - break; - } - - bus->regs = dhdpcie_info->regs; - dhdpcie_info->tcm = (volatile char *) REG_MAP(bar1_addr, DONGLE_TCM_MAP_SIZE); - dhdpcie_info->tcm_size = DONGLE_TCM_MAP_SIZE; - if (!dhdpcie_info->tcm) { - DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__)); - REG_UNMAP(dhdpcie_info->regs); - bus->regs = NULL; - break; - } - - bus->tcm = dhdpcie_info->tcm; - - DHD_TRACE(("%s:Phys addr : reg space = %p base addr 0x"PRINTF_RESOURCE" \n", - __FUNCTION__, dhdpcie_info->regs, bar0_addr)); - DHD_TRACE(("%s:Phys addr : tcm_space = %p base addr 0x"PRINTF_RESOURCE" \n", - __FUNCTION__, dhdpcie_info->tcm, bar1_addr)); - - return 0; - } while (0); - - return BCME_ERROR; -} - -void -dhdpcie_free_resource(dhd_bus_t *bus) -{ - dhdpcie_info_t *dhdpcie_info; - - if (bus == NULL) { - DHD_ERROR(("%s: bus is NULL\n", __FUNCTION__)); - return; - } - - if (bus->dev == NULL) { - DHD_ERROR(("%s: bus->dev is NULL\n", __FUNCTION__)); - return; - } - - dhdpcie_info = pci_get_drvdata(bus->dev); - if (dhdpcie_info == NULL) { - DHD_ERROR(("%s: dhdpcie_info is NULL\n", __FUNCTION__)); - return; - } - - if (bus->regs) { - REG_UNMAP(dhdpcie_info->regs); - bus->regs = NULL; - } - - if (bus->tcm) { - REG_UNMAP(dhdpcie_info->tcm); - bus->tcm = NULL; - } -} diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.c b/drivers/net/wireless/bcmdhd/dhd_pno.c index d3f9ad7782ddf3d400b357c501d8ece06133fe46..515e672d88d79b40e6d76b893c8a83255c91ff7b 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pno.c +++ b/drivers/net/wireless/bcmdhd/dhd_pno.c @@ -2,7 +2,25 @@ * Broadcom Dongle Host Driver (DHD) * Prefered Network Offload and Wi-Fi Location Service(WLS) code. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_pno.c 423669 2013-09-18 13:01:55Z yangj$ */ @@ -57,13 +75,25 @@ #define PNO_ON 1 #define PNO_OFF 0 #define CHANNEL_2G_MAX 14 +#define CHANNEL_5G_MAX 165 #define MAX_NODE_CNT 5 #define WLS_SUPPORTED(pno_state) (pno_state->wls_supported == TRUE) #define TIME_DIFF(timestamp1, timestamp2) (abs((uint32)(timestamp1/1000) \ - (uint32)(timestamp2/1000))) +#define TIME_DIFF_MS(timestamp1, timestamp2) (abs((uint32)(timestamp1) \ + - (uint32)(timestamp2))) +#define TIMESPEC_TO_US(ts) (((uint64)(ts).tv_sec * USEC_PER_SEC) + \ + (ts).tv_nsec / NSEC_PER_USEC) #define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====") #define TIME_MIN_DIFF 5 +static wlc_ssid_ext_t * dhd_pno_get_legacy_pno_ssid(dhd_pub_t *dhd, + dhd_pno_status_info_t *pno_state); +#ifdef GSCAN_SUPPORT +static wl_pfn_gscan_channel_bucket_t * +dhd_pno_gscan_create_channel_list(dhd_pub_t *dhd, dhd_pno_status_info_t *pno_state, +uint16 *chan_list, uint32 *num_buckets, uint32 *num_buckets_to_fw); +#endif /* GSCAN_SUPPORT */ static inline bool is_dfs(uint16 channel) { @@ -101,6 +131,95 @@ exit: return err; } +bool dhd_is_pno_supported(dhd_pub_t *dhd) +{ + dhd_pno_status_info_t *_pno_state; + + if (!dhd || !dhd->pno_state) { + DHD_ERROR(("NULL POINTER : %s\n", + __FUNCTION__)); + return FALSE; + } + _pno_state = PNO_GET_PNOSTATE(dhd); + return WLS_SUPPORTED(_pno_state); +} + +int dhd_pno_set_mac_oui(dhd_pub_t *dhd, uint8 *oui) +{ + int err = BCME_OK; + dhd_pno_status_info_t *_pno_state; + + if (!dhd || !dhd->pno_state) { + DHD_ERROR(("NULL POINTER : %s\n", + __FUNCTION__)); + return BCME_ERROR; + } + _pno_state = PNO_GET_PNOSTATE(dhd); + if (ETHER_ISMULTI(oui)) { + DHD_ERROR(("Expected unicast OUI\n")); + err = BCME_ERROR; + } else { + memcpy(_pno_state->pno_oui, oui, DOT11_OUI_LEN); + DHD_PNO(("PNO mac oui to be used - %02x:%02x:%02x\n", _pno_state->pno_oui[0], + _pno_state->pno_oui[1], _pno_state->pno_oui[2])); + } + + return err; +} + +#ifdef GSCAN_SUPPORT +static uint64 convert_fw_rel_time_to_systime(uint32 fw_ts_ms) +{ + struct timespec ts; + + get_monotonic_boottime(&ts); + return ((uint64)(TIMESPEC_TO_US(ts)) - (uint64)(fw_ts_ms * 1000)); +} + +static int +_dhd_pno_gscan_cfg(dhd_pub_t *dhd, wl_pfn_gscan_cfg_t *pfncfg_gscan_param, int size) +{ + int err = BCME_OK; + NULL_CHECK(dhd, "dhd is NULL", err); + + DHD_PNO(("%s enter\n", __FUNCTION__)); + + err = dhd_iovar(dhd, 0, "pfn_gscan_cfg", (char *)pfncfg_gscan_param, size, 1); + if (err < 0) { + DHD_ERROR(("%s : failed to execute pfncfg_gscan_param\n", __FUNCTION__)); + goto exit; + } +exit: + return err; +} +static bool +is_batch_retreival_complete(struct dhd_pno_gscan_params *gscan_params) +{ + smp_rmb(); + return (gscan_params->get_batch_flag == GSCAN_BATCH_RETRIEVAL_COMPLETE); +} +#endif /* GSCAN_SUPPORT */ + +static int +dhd_pno_set_mac_addr(dhd_pub_t *dhd, struct ether_addr *macaddr) +{ + int err; + wl_pfn_macaddr_cfg_t cfg; + + cfg.version = WL_PFN_MACADDR_CFG_VER; + if (ETHER_ISNULLADDR(macaddr)) + cfg.flags = 0; + else + cfg.flags = (WL_PFN_MAC_OUI_ONLY_MASK | WL_PFN_SET_MAC_UNASSOC_MASK); + memcpy(&cfg.macaddr, macaddr, ETHER_ADDR_LEN); + + err = dhd_iovar(dhd, 0, "pfn_macaddr", (char *)&cfg, sizeof(cfg), 1); + if (err < 0) + DHD_ERROR(("%s : failed to execute pfn_macaddr\n", __FUNCTION__)); + + return err; +} + static int _dhd_pno_suspend(dhd_pub_t *dhd) { @@ -154,7 +273,7 @@ _dhd_pno_enable(dhd_pub_t *dhd, int enable) /* Enable/Disable PNO */ err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), 1); if (err < 0) { - DHD_ERROR(("%s : failed to execute pfn_set\n", __FUNCTION__)); + DHD_ERROR(("%s : failed to execute pfn_set - %d\n", __FUNCTION__, err)); goto exit; } _pno_state->pno_status = (enable)? @@ -176,6 +295,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t dhd_pno_params_t *_params; dhd_pno_status_info_t *_pno_state; bool combined_scan = FALSE; + struct ether_addr macaddr; DHD_PNO(("%s enter\n", __FUNCTION__)); NULL_CHECK(dhd, "dhd is NULL", err); @@ -208,6 +328,12 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t mode |= DHD_PNO_HOTLIST_MODE; combined_scan = TRUE; } +#ifdef GSCAN_SUPPORT + else if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + DHD_PNO(("will enable combined scan with GSCAN SCAN MODE\n")); + mode |= DHD_PNO_GSCAN_MODE; + } +#endif /* GSCAN_SUPPORT */ } if (mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { /* Scan frequency of 30 sec */ @@ -215,7 +341,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t /* slow adapt scan is off by default */ pfn_param.slow_freq = htod32(0); /* RSSI margin of 30 dBm */ - pfn_param.rssi_margin = htod16(30); + pfn_param.rssi_margin = htod16(PNO_RSSI_MARGIN_DBM); /* Network timeout 60 sec */ pfn_param.lost_network_timeout = htod32(60); /* best n = 2 by default */ @@ -272,14 +398,71 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t } } } - if (pfn_param.scan_freq < htod32(PNO_SCAN_MIN_FW_SEC) || - pfn_param.scan_freq > htod32(PNO_SCAN_MAX_FW_SEC)) { - DHD_ERROR(("%s pno freq(%d sec) is not valid \n", - __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); - err = BCME_BADARG; +#ifdef GSCAN_SUPPORT + if (mode & DHD_PNO_GSCAN_MODE) { + uint32 lost_network_timeout; + + pfn_param.scan_freq = htod32(pno_params->params_gscan.scan_fr); + if (pno_params->params_gscan.mscan) { + pfn_param.bestn = pno_params->params_gscan.bestn; + pfn_param.mscan = pno_params->params_gscan.mscan; + pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT); + } + /* RSSI margin of 30 dBm */ + pfn_param.rssi_margin = htod16(PNO_RSSI_MARGIN_DBM); + /* ADAPTIVE turned off */ + pfn_param.flags &= ~(htod16(ENABLE << ENABLE_ADAPTSCAN_BIT)); + pfn_param.repeat = 0; + pfn_param.exp = 0; + pfn_param.slow_freq = 0; + + if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); + dhd_pno_params_t *_params; + + _params = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); + pfn_param.scan_freq = htod32(MIN(pno_params->params_gscan.scan_fr, + _params->params_legacy.scan_fr)); + } + + lost_network_timeout = (pno_params->params_gscan.max_ch_bucket_freq * + pfn_param.scan_freq * + pno_params->params_gscan.lost_ap_window); + if (lost_network_timeout) { + pfn_param.lost_network_timeout = htod32(MIN(lost_network_timeout, + GSCAN_MIN_BSSID_TIMEOUT)); + } else { + pfn_param.lost_network_timeout = htod32(GSCAN_MIN_BSSID_TIMEOUT); + } + } else +#endif /* GSCAN_SUPPORT */ + { + if (pfn_param.scan_freq < htod32(PNO_SCAN_MIN_FW_SEC) || + pfn_param.scan_freq > htod32(PNO_SCAN_MAX_FW_SEC)) { + DHD_ERROR(("%s pno freq(%d sec) is not valid \n", + __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); + err = BCME_BADARG; + goto exit; + } + } + + memset(&macaddr, 0, ETHER_ADDR_LEN); + memcpy(&macaddr, _pno_state->pno_oui, DOT11_OUI_LEN); + + DHD_PNO(("Setting mac oui to FW - %02x:%02x:%02x\n", _pno_state->pno_oui[0], + _pno_state->pno_oui[1], _pno_state->pno_oui[2])); + err = dhd_pno_set_mac_addr(dhd, &macaddr); + if (err < 0) { + DHD_ERROR(("%s : failed to set pno mac address, error - %d\n", __FUNCTION__, err)); goto exit; } + +#ifdef GSCAN_SUPPORT + if (mode == DHD_PNO_BATCH_MODE || + ((mode & DHD_PNO_GSCAN_MODE) && pno_params->params_gscan.mscan)) { +#else if (mode == DHD_PNO_BATCH_MODE) { +#endif /* GSCAN_SUPPORT */ int _tmp = pfn_param.bestn; /* set bestn to calculate the max mscan which firmware supports */ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 1); @@ -298,7 +481,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t } err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), 1); if (err < 0) { - DHD_ERROR(("%s : failed to execute pfn_set\n", __FUNCTION__)); + DHD_ERROR(("%s : failed to execute pfn_set %d\n", __FUNCTION__, err)); goto exit; } /* need to return mscan if this is for batch scan instead of err */ @@ -307,7 +490,7 @@ exit: return err; } static int -_dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssids_list, int nssid) +_dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssids_list, int nssid) { int err = BCME_OK; int i = 0; @@ -320,8 +503,8 @@ _dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssids_list, int nssid) { int j; for (j = 0; j < nssid; j++) { - DHD_PNO(("%d: scan for %s size = %d\n", j, - ssids_list[j].SSID, ssids_list[j].SSID_len)); + DHD_PNO(("%d: scan for %s size = %d hidden = %d\n", j, + ssids_list[j].SSID, ssids_list[j].SSID_len, ssids_list[j].hidden)); } } /* Check for broadcast ssid */ @@ -339,7 +522,10 @@ _dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssids_list, int nssid) pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); pfn_element.wsec = htod32(0); pfn_element.infra = htod32(1); - pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); + if (ssids_list[i].hidden) + pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); + else + pfn_element.flags = 0; memcpy((char *)pfn_element.ssid.SSID, ssids_list[i].SSID, ssids_list[i].SSID_len); pfn_element.ssid.SSID_len = ssids_list[i].SSID_len; @@ -423,11 +609,20 @@ _dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list, if (skip_dfs && is_dfs(dtoh32(list->element[i]))) continue; + } else if (band == WLC_BAND_AUTO) { + if (skip_dfs || !is_dfs(dtoh32(list->element[i]))) + continue; + } else { /* All channels */ if (skip_dfs && is_dfs(dtoh32(list->element[i]))) continue; } - d_chan_list[j++] = dtoh32(list->element[i]); + if (dtoh32(list->element[i]) <= CHANNEL_5G_MAX) { + d_chan_list[j++] = (uint16) dtoh32(list->element[i]); + } else { + err = BCME_BADCHAN; + goto exit; + } } *nchan = j; exit: @@ -718,7 +913,7 @@ _dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid) if (nbssid) { NULL_CHECK(p_pfn_bssid, "bssid list is NULL", err); } - err = dhd_iovar(dhd, 0, "pfn_add_bssid", (char *)&p_pfn_bssid, + err = dhd_iovar(dhd, 0, "pfn_add_bssid", (char *)p_pfn_bssid, sizeof(wl_pfn_bssid_t) * nbssid, 1); if (err < 0) { DHD_ERROR(("%s : failed to execute pfn_cfg\n", __FUNCTION__)); @@ -727,6 +922,33 @@ _dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid) exit: return err; } + +#ifdef GSCAN_SUPPORT +static int +_dhd_pno_add_significant_bssid(dhd_pub_t *dhd, + wl_pfn_significant_bssid_t *p_pfn_significant_bssid, int nbssid) +{ + int err = BCME_OK; + NULL_CHECK(dhd, "dhd is NULL", err); + + if (!nbssid) { + err = BCME_ERROR; + goto exit; + } + + NULL_CHECK(p_pfn_significant_bssid, "bssid list is NULL", err); + + err = dhd_iovar(dhd, 0, "pfn_add_swc_bssid", (char *)p_pfn_significant_bssid, + sizeof(wl_pfn_significant_bssid_t) * nbssid, 1); + if (err < 0) { + DHD_ERROR(("%s : failed to execute pfn_significant_bssid %d\n", __FUNCTION__, err)); + goto exit; + } +exit: + return err; +} +#endif /* GSCAN_SUPPORT */ + int dhd_pno_stop_for_ssid(dhd_pub_t *dhd) { @@ -734,7 +956,7 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd) uint32 mode = 0; dhd_pno_status_info_t *_pno_state; dhd_pno_params_t *_params; - wl_pfn_bssid_t *p_pfn_bssid; + wl_pfn_bssid_t *p_pfn_bssid = NULL; NULL_CHECK(dhd, "dev is NULL", err); NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); _pno_state = PNO_GET_PNOSTATE(dhd); @@ -744,6 +966,30 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd) } DHD_PNO(("%s enter\n", __FUNCTION__)); _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + struct dhd_pno_gscan_params *gscan_params; + + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + gscan_params = &_params->params_gscan; + if (gscan_params->mscan) + dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); + + /* save current pno_mode before calling dhd_pno_clean */ + mode = _pno_state->pno_mode; + err = dhd_pno_clean(dhd); + if (err < 0) { + DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + __FUNCTION__, err)); + goto exit; + } + /* restore previous pno_mode */ + _pno_state->pno_mode = mode; + /* Restart gscan */ + err = dhd_pno_initiate_gscan_request(dhd, 1, 0); + goto exit; + } +#endif /* GSCAN_SUPPORT */ /* restart Batch mode if the batch mode is on */ if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { /* retrieve the batching data from firmware into host */ @@ -802,6 +1048,7 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd) } } exit: + kfree(p_pfn_bssid); return err; } @@ -814,11 +1061,72 @@ dhd_pno_enable(dhd_pub_t *dhd, int enable) return (_dhd_pno_enable(dhd, enable)); } +static wlc_ssid_ext_t * dhd_pno_get_legacy_pno_ssid(dhd_pub_t *dhd, + dhd_pno_status_info_t *pno_state) +{ + int err = BCME_OK; + int i; + struct dhd_pno_ssid *iter, *next; + dhd_pno_params_t *_params1 = &pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]; + wlc_ssid_ext_t *p_ssid_list; + + p_ssid_list = kzalloc(sizeof(wlc_ssid_ext_t) * + _params1->params_legacy.nssid, GFP_KERNEL); + if (p_ssid_list == NULL) { + DHD_ERROR(("%s : failed to allocate wlc_ssid_ext_t array (count: %d)", + __FUNCTION__, _params1->params_legacy.nssid)); + err = BCME_ERROR; + pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + goto exit; + } + i = 0; + /* convert dhd_pno_ssid to wlc_ssid_ext_t */ + list_for_each_entry_safe(iter, next, &_params1->params_legacy.ssid_list, list) { + p_ssid_list[i].SSID_len = iter->SSID_len; + p_ssid_list[i].hidden = iter->hidden; + memcpy(p_ssid_list[i].SSID, iter->SSID, p_ssid_list[i].SSID_len); + i++; + } +exit: + return p_ssid_list; +} + +static int +dhd_pno_add_to_ssid_list(dhd_pno_params_t *params, wlc_ssid_ext_t *ssid_list, + int nssid) +{ + int ret = 0; + int i; + struct dhd_pno_ssid *_pno_ssid; + + for (i = 0; i < nssid; i++) { + if (ssid_list[i].SSID_len > DOT11_MAX_SSID_LEN) { + DHD_ERROR(("%s : Invalid SSID length %d\n", + __FUNCTION__, ssid_list[i].SSID_len)); + ret = BCME_ERROR; + goto exit; + } + _pno_ssid = kzalloc(sizeof(struct dhd_pno_ssid), GFP_KERNEL); + if (_pno_ssid == NULL) { + DHD_ERROR(("%s : failed to allocate struct dhd_pno_ssid\n", + __FUNCTION__)); + ret = BCME_ERROR; + goto exit; + } + _pno_ssid->SSID_len = ssid_list[i].SSID_len; + _pno_ssid->hidden = ssid_list[i].hidden; + memcpy(_pno_ssid->SSID, ssid_list[i].SSID, _pno_ssid->SSID_len); + list_add_tail(&_pno_ssid->list, ¶ms->params_legacy.ssid_list); + } + +exit: + return ret; +} + int -dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, +dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssid_list, int nssid, uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan) { - struct dhd_pno_ssid *_pno_ssid; dhd_pno_params_t *_params; dhd_pno_params_t *_params2; dhd_pno_status_info_t *_pno_state; @@ -833,21 +1141,27 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, if (!dhd_support_sta_mode(dhd)) { err = BCME_BADOPTION; - goto exit; + goto exit_no_clear; } DHD_PNO(("%s enter : scan_fr :%d, pno_repeat :%d," "pno_freq_expo_max: %d, nchan :%d\n", __FUNCTION__, scan_fr, pno_repeat, pno_freq_expo_max, nchan)); _params = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); + /* If GSCAN is also ON will handle this down below */ +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE && + !(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE)) { +#else if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { +#endif /* GSCAN_SUPPORT */ DHD_ERROR(("%s : Legacy PNO mode was already started, " "will disable previous one to start new one\n", __FUNCTION__)); err = dhd_pno_stop_for_ssid(dhd); if (err < 0) { DHD_ERROR(("%s : failed to stop legacy PNO (err %d)\n", __FUNCTION__, err)); - goto exit; + goto exit_no_clear; } } _pno_state->pno_mode |= DHD_PNO_LEGACY_MODE; @@ -855,14 +1169,29 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, if (err < 0) { DHD_ERROR(("%s : failed to reinitialize profile (err %d)\n", __FUNCTION__, err)); - goto exit; + goto exit_no_clear; } memset(_chan_list, 0, sizeof(_chan_list)); - tot_nchan = nchan; + tot_nchan = MIN(nchan, WL_NUMCHANNELS); if (tot_nchan > 0 && channel_list) { - for (i = 0; i < nchan; i++) + for (i = 0; i < tot_nchan; i++) _params->params_legacy.chan_list[i] = _chan_list[i] = channel_list[i]; } +#ifdef GSCAN_SUPPORT + else { + tot_nchan = WL_NUMCHANNELS; + err = _dhd_pno_get_channels(dhd, _chan_list, &tot_nchan, + (WLC_BAND_2G | WLC_BAND_5G), TRUE); + if (err < 0) { + tot_nchan = 0; + DHD_PNO(("Could not get channel list for PNO SSID\n")); + } else { + for (i = 0; i < tot_nchan; i++) + _params->params_legacy.chan_list[i] = _chan_list[i]; + } + } +#endif /* GSCAN_SUPPORT */ + if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { DHD_PNO(("BATCH SCAN is on progress in firmware\n")); /* retrieve the batching data from firmware into host */ @@ -872,23 +1201,23 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, err = _dhd_pno_enable(dhd, PNO_OFF); if (err < 0) { DHD_ERROR(("%s : failed to disable PNO\n", __FUNCTION__)); - goto exit; + goto exit_no_clear; } /* restore the previous mode */ _pno_state->pno_mode = mode; /* use superset of channel list between two mode */ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { _params2 = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]); - if (_params2->params_batch.nchan > 0 && nchan > 0) { + if (_params2->params_batch.nchan > 0 && tot_nchan > 0) { err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, &_params2->params_batch.chan_list[0], _params2->params_batch.nchan, - &channel_list[0], nchan); + &channel_list[0], tot_nchan); if (err < 0) { DHD_ERROR(("%s : failed to merge channel list" " between legacy and batch\n", __FUNCTION__)); - goto exit; + goto exit_no_clear; } } else { DHD_PNO(("superset channel will use" @@ -896,16 +1225,16 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, } } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { _params2 = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]); - if (_params2->params_hotlist.nchan > 0 && nchan > 0) { + if (_params2->params_hotlist.nchan > 0 && tot_nchan > 0) { err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, &_params2->params_hotlist.chan_list[0], _params2->params_hotlist.nchan, - &channel_list[0], nchan); + &channel_list[0], tot_nchan); if (err < 0) { DHD_ERROR(("%s : failed to merge channel list" " between legacy and hotlist\n", __FUNCTION__)); - goto exit; + goto exit_no_clear; } } } @@ -913,9 +1242,21 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, _params->params_legacy.scan_fr = scan_fr; _params->params_legacy.pno_repeat = pno_repeat; _params->params_legacy.pno_freq_expo_max = pno_freq_expo_max; - _params->params_legacy.nchan = nchan; + _params->params_legacy.nchan = tot_nchan; _params->params_legacy.nssid = nssid; INIT_LIST_HEAD(&_params->params_legacy.ssid_list); +#ifdef GSCAN_SUPPORT + /* dhd_pno_initiate_gscan_request will handle simultaneous Legacy PNO and GSCAN */ + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + if (dhd_pno_add_to_ssid_list(_params, ssid_list, nssid) < 0) { + err = BCME_ERROR; + goto exit; + } + DHD_PNO(("GSCAN mode is ON! Will restart GSCAN+Legacy PNO\n")); + err = dhd_pno_initiate_gscan_request(dhd, 1, 0); + goto exit; + } +#endif /* GSCAN_SUPPORT */ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_LEGACY_MODE)) < 0) { DHD_ERROR(("failed to set call pno_set (err %d) in firmware\n", err)); goto exit; @@ -924,17 +1265,9 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, DHD_ERROR(("failed to add ssid list(err %d), %d in firmware\n", err, nssid)); goto exit; } - for (i = 0; i < nssid; i++) { - _pno_ssid = kzalloc(sizeof(struct dhd_pno_ssid), GFP_KERNEL); - if (_pno_ssid == NULL) { - DHD_ERROR(("%s : failed to allocate struct dhd_pno_ssid\n", - __FUNCTION__)); - goto exit; - } - _pno_ssid->SSID_len = ssid_list[i].SSID_len; - memcpy(_pno_ssid->SSID, ssid_list[i].SSID, _pno_ssid->SSID_len); - list_add_tail(&_pno_ssid->list, &_params->params_legacy.ssid_list); - + if (dhd_pno_add_to_ssid_list(_params, ssid_list, nssid) < 0) { + err = BCME_ERROR; + goto exit; } if (tot_nchan > 0) { if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) { @@ -948,6 +1281,9 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, DHD_ERROR(("%s : failed to enable PNO\n", __FUNCTION__)); } exit: + if (err < 0) + _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE); +exit_no_clear: /* clear mode in case of error */ if (err < 0) _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; @@ -960,11 +1296,10 @@ dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params) uint16 _chan_list[WL_NUMCHANNELS]; int rem_nchan = 0, tot_nchan = 0; int mode = 0, mscan = 0; - int i = 0; dhd_pno_params_t *_params; dhd_pno_params_t *_params2; dhd_pno_status_info_t *_pno_state; - wlc_ssid_t *p_ssid_list = NULL; + wlc_ssid_ext_t *p_ssid_list = NULL; NULL_CHECK(dhd, "dhd is NULL", err); NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); NULL_CHECK(batch_params, "batch_params is NULL", err); @@ -1034,7 +1369,6 @@ dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params) tot_nchan = _params->params_batch.nchan; } if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { - struct dhd_pno_ssid *iter, *next; DHD_PNO(("PNO SSID is on progress in firmware\n")); /* store current pno_mode before disabling pno */ mode = _pno_state->pno_mode; @@ -1061,22 +1395,12 @@ dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params) } else { DHD_PNO(("superset channel will use all channels in firmware\n")); } - p_ssid_list = kzalloc(sizeof(wlc_ssid_t) * - _params2->params_legacy.nssid, GFP_KERNEL); - if (p_ssid_list == NULL) { - DHD_ERROR(("%s : failed to allocate wlc_ssid_t array (count: %d)", - __FUNCTION__, _params2->params_legacy.nssid)); - err = BCME_ERROR; - _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + p_ssid_list = dhd_pno_get_legacy_pno_ssid(dhd, _pno_state); + if (!p_ssid_list) { + err = BCME_NOMEM; + DHD_ERROR(("failed to get Legacy PNO SSID list\n")); goto exit; } - i = 0; - /* convert dhd_pno_ssid to dhd_pno_ssid */ - list_for_each_entry_safe(iter, next, &_params2->params_legacy.ssid_list, list) { - p_ssid_list[i].SSID_len = iter->SSID_len; - memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list[i].SSID_len); - i++; - } if ((err = _dhd_pno_add_ssid(dhd, p_ssid_list, _params2->params_legacy.nssid)) < 0) { DHD_ERROR(("failed to add ssid list (err %d) in firmware\n", err)); @@ -1110,77 +1434,1377 @@ exit: /* return #max scan firmware can do */ err = mscan; } - if (p_ssid_list) - kfree(p_ssid_list); + kfree(p_ssid_list); return err; } -static int -_dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) + +#ifdef GSCAN_SUPPORT +static void dhd_pno_reset_cfg_gscan(dhd_pno_params_t *_params, + dhd_pno_status_info_t *_pno_state, uint8 flags) { - int err = BCME_OK; - int i, j; - uint32 timestamp = 0; - dhd_pno_params_t *_params = NULL; - dhd_pno_status_info_t *_pno_state = NULL; - wl_pfn_lscanresults_t *plbestnet = NULL; - wl_pfn_lnet_info_t *plnetinfo; - dhd_pno_bestnet_entry_t *pbestnet_entry; - dhd_pno_best_header_t *pbestnetheader = NULL; - dhd_pno_scan_results_t *pscan_results = NULL, *siter, *snext; - bool allocate_header = FALSE; - NULL_CHECK(dhd, "dhd is NULL", err); - NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); - if (!dhd_support_sta_mode(dhd)) { - err = BCME_BADOPTION; - goto exit; - } DHD_PNO(("%s enter\n", __FUNCTION__)); - _pno_state = PNO_GET_PNOSTATE(dhd); - if (!WLS_SUPPORTED(_pno_state)) { - DHD_ERROR(("%s : wifi location service is not supported\n", __FUNCTION__)); - err = BCME_UNSUPPORTED; - goto exit; - } - if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { - DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__)); - goto exit; - } - mutex_lock(&_pno_state->pno_mutex); - _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; - if (buf && bufsize) { - if (!list_empty(&_params->params_batch.get_batch.expired_scan_results_list)) { - /* need to check whether we have cashed data or not */ - DHD_PNO(("%s: have cashed batching data in Driver\n", - __FUNCTION__)); - /* convert to results format */ - goto convert_format; - } else { - /* this is a first try to get batching results */ - if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) { - /* move the scan_results_list to expired_scan_results_lists */ - list_for_each_entry_safe(siter, snext, - &_params->params_batch.get_batch.scan_results_list, list) { - list_move_tail(&siter->list, - &_params->params_batch.get_batch.expired_scan_results_list); - } - _params->params_batch.get_batch.top_node_cnt = 0; - _params->params_batch.get_batch.expired_tot_scan_cnt = - _params->params_batch.get_batch.tot_scan_cnt; - _params->params_batch.get_batch.tot_scan_cnt = 0; - goto convert_format; + if (flags & GSCAN_FLUSH_SCAN_CFG) { + _params->params_gscan.bestn = 0; + _params->params_gscan.mscan = 0; + _params->params_gscan.buffer_threshold = GSCAN_BATCH_NO_THR_SET; + _params->params_gscan.scan_fr = 0; + _params->params_gscan.send_all_results_flag = 0; + memset(_params->params_gscan.channel_bucket, 0, + _params->params_gscan.nchannel_buckets * + sizeof(struct dhd_pno_gscan_channel_bucket)); + _params->params_gscan.nchannel_buckets = 0; + DHD_PNO(("Flush Scan config\n")); + } + if (flags & GSCAN_FLUSH_HOTLIST_CFG) + { + struct dhd_pno_bssid *iter, *next; + if (_params->params_gscan.nbssid_hotlist > 0) { + list_for_each_entry_safe(iter, next, + &_params->params_gscan.hotlist_bssid_list, list) { + list_del(&iter->list); + kfree(iter); } } + _params->params_gscan.nbssid_hotlist = 0; + DHD_PNO(("Flush Hotlist Config\n")); } - /* create dhd_pno_scan_results_t whenever we got event WLC_E_PFN_BEST_BATCHING */ - pscan_results = (dhd_pno_scan_results_t *)MALLOC(dhd->osh, SCAN_RESULTS_SIZE); - if (pscan_results == NULL) { - err = BCME_NOMEM; - DHD_ERROR(("failed to allocate dhd_pno_scan_results_t\n")); - goto exit; + if (flags & GSCAN_FLUSH_SIGNIFICANT_CFG) + { + dhd_pno_significant_bssid_t *iter, *next; + + if (_params->params_gscan.nbssid_significant_change > 0) { + list_for_each_entry_safe(iter, next, + &_params->params_gscan.significant_bssid_list, list) { + list_del(&iter->list); + kfree(iter); + } + } + _params->params_gscan.nbssid_significant_change = 0; + DHD_PNO(("Flush Significant Change Config\n")); } - pscan_results->bestnetheader = NULL; + + return; +} + +void dhd_pno_lock_batch_results(dhd_pub_t *dhd) +{ + dhd_pno_status_info_t *_pno_state; + _pno_state = PNO_GET_PNOSTATE(dhd); + mutex_lock(&_pno_state->pno_mutex); + return; +} + +void dhd_pno_unlock_batch_results(dhd_pub_t *dhd) +{ + dhd_pno_status_info_t *_pno_state; + _pno_state = PNO_GET_PNOSTATE(dhd); + mutex_unlock(&_pno_state->pno_mutex); + return; +} + +void dhd_wait_batch_results_complete(dhd_pub_t *dhd) +{ + dhd_pno_status_info_t *_pno_state; + dhd_pno_params_t *_params; + + _pno_state = PNO_GET_PNOSTATE(dhd); + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + + /* Has the workqueue finished its job already?? */ + if (_params->params_gscan.get_batch_flag == GSCAN_BATCH_RETRIEVAL_IN_PROGRESS) { + DHD_PNO(("%s: Waiting to complete retrieval..\n", __FUNCTION__)); + wait_event_interruptible_timeout(_pno_state->batch_get_wait, + is_batch_retreival_complete(&_params->params_gscan), + msecs_to_jiffies(GSCAN_BATCH_GET_MAX_WAIT)); + } else { /* GSCAN_BATCH_RETRIEVAL_COMPLETE */ + gscan_results_cache_t *iter; + uint16 num_results = 0; + int err; + + mutex_lock(&_pno_state->pno_mutex); + iter = _params->params_gscan.gscan_batch_cache; + while (iter) { + num_results += iter->tot_count - iter->tot_consumed; + iter = iter->next; + } + mutex_unlock(&_pno_state->pno_mutex); + + /* All results consumed/No results cached?? + * Get fresh results from FW + */ + if (!num_results) { + DHD_PNO(("%s: No results cached, getting from FW..\n", __FUNCTION__)); + err = dhd_retreive_batch_scan_results(dhd); + if (err == BCME_OK) { + wait_event_interruptible_timeout(_pno_state->batch_get_wait, + is_batch_retreival_complete(&_params->params_gscan), + msecs_to_jiffies(GSCAN_BATCH_GET_MAX_WAIT)); + } + } + } + DHD_PNO(("%s: Wait complete\n", __FUNCTION__)); + + return; +} + +static void *dhd_get_gscan_batch_results(dhd_pub_t *dhd, uint32 *len) +{ + gscan_results_cache_t *iter, *results; + dhd_pno_status_info_t *_pno_state; + dhd_pno_params_t *_params; + uint16 num_scan_ids = 0, num_results = 0; + + _pno_state = PNO_GET_PNOSTATE(dhd); + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + + iter = results = _params->params_gscan.gscan_batch_cache; + while (iter) { + num_results += iter->tot_count - iter->tot_consumed; + num_scan_ids++; + iter = iter->next; + } + + *len = ((num_results << 16) | (num_scan_ids)); + return results; +} + +void * dhd_pno_get_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, + void *info, uint32 *len) +{ + void *ret = NULL; + dhd_pno_gscan_capabilities_t *ptr; + + if (!len) { + DHD_ERROR(("%s: len is NULL\n", __FUNCTION__)); + return ret; + } + + switch (type) { + case DHD_PNO_GET_CAPABILITIES: + ptr = (dhd_pno_gscan_capabilities_t *) + kmalloc(sizeof(dhd_pno_gscan_capabilities_t), GFP_KERNEL); + if (!ptr) + break; + /* Hardcoding these values for now, need to get + * these values from FW, will change in a later check-in + */ + ptr->max_scan_cache_size = 12; + ptr->max_scan_buckets = GSCAN_MAX_CH_BUCKETS; + ptr->max_ap_cache_per_scan = 16; + ptr->max_rssi_sample_size = PFN_SWC_RSSI_WINDOW_MAX; + ptr->max_scan_reporting_threshold = 100; + ptr->max_hotlist_aps = PFN_HOTLIST_MAX_NUM_APS; + ptr->max_significant_wifi_change_aps = PFN_SWC_MAX_NUM_APS; + ret = (void *)ptr; + *len = sizeof(dhd_pno_gscan_capabilities_t); + break; + + case DHD_PNO_GET_BATCH_RESULTS: + ret = dhd_get_gscan_batch_results(dhd, len); + break; + case DHD_PNO_GET_CHANNEL_LIST: + if (info) { + uint16 ch_list[WL_NUMCHANNELS]; + uint32 *ptr, mem_needed, i; + int32 err, nchan = WL_NUMCHANNELS; + uint32 *gscan_band = (uint32 *) info; + uint8 band = 0; + + /* No band specified?, nothing to do */ + if ((*gscan_band & GSCAN_BAND_MASK) == 0) { + DHD_PNO(("No band specified\n")); + *len = 0; + break; + } + + /* HAL and DHD use different bits for 2.4G and + * 5G in bitmap. Hence translating it here... + */ + if (*gscan_band & GSCAN_BG_BAND_MASK) + band |= WLC_BAND_2G; + if (*gscan_band & GSCAN_A_BAND_MASK) + band |= WLC_BAND_5G; + + err = _dhd_pno_get_channels(dhd, ch_list, &nchan, + (band & GSCAN_ABG_BAND_MASK), + !(*gscan_band & GSCAN_DFS_MASK)); + + if (err < 0) { + DHD_ERROR(("%s: failed to get valid channel list\n", + __FUNCTION__)); + *len = 0; + } else { + mem_needed = sizeof(uint32) * nchan; + ptr = (uint32 *) kmalloc(mem_needed, GFP_KERNEL); + if (!ptr) { + DHD_ERROR(("%s: Unable to malloc %d bytes\n", + __FUNCTION__, mem_needed)); + break; + } + for (i = 0; i < nchan; i++) { + ptr[i] = wf_channel2mhz(ch_list[i], + (ch_list[i] <= CH_MAX_2G_CHANNEL? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G)); + } + ret = ptr; + *len = mem_needed; + } + } else { + *len = 0; + DHD_ERROR(("%s: info buffer is NULL\n", __FUNCTION__)); + } + break; + + default: + break; + } + + return ret; + +} + +int dhd_pno_set_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, + void *buf, uint8 flush) +{ + int err = BCME_OK; + dhd_pno_params_t *_params; + int i; + dhd_pno_status_info_t *_pno_state; + + NULL_CHECK(dhd, "dhd is NULL", err); + + DHD_PNO(("%s enter\n", __FUNCTION__)); + + _pno_state = PNO_GET_PNOSTATE(dhd); + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + mutex_lock(&_pno_state->pno_mutex); + + switch (type) { + case DHD_PNO_BATCH_SCAN_CFG_ID: + { + gscan_batch_params_t *ptr = (gscan_batch_params_t *)buf; + _params->params_gscan.bestn = ptr->bestn; + _params->params_gscan.mscan = ptr->mscan; + _params->params_gscan.buffer_threshold = ptr->buffer_threshold; + } + break; + case DHD_PNO_GEOFENCE_SCAN_CFG_ID: + { + gscan_hotlist_scan_params_t *ptr = (gscan_hotlist_scan_params_t *)buf; + struct dhd_pno_bssid *_pno_bssid; + struct bssid_t *bssid_ptr; + int8 flags; + + if (flush) { + dhd_pno_reset_cfg_gscan(_params, _pno_state, + GSCAN_FLUSH_HOTLIST_CFG); + } + + if (!ptr->nbssid) + break; + + if (!_params->params_gscan.nbssid_hotlist) + INIT_LIST_HEAD(&_params->params_gscan.hotlist_bssid_list); + + if ((_params->params_gscan.nbssid_hotlist + + ptr->nbssid) > PFN_SWC_MAX_NUM_APS) { + DHD_ERROR(("Excessive number of hotlist APs programmed %d\n", + (_params->params_gscan.nbssid_hotlist + + ptr->nbssid))); + err = BCME_RANGE; + goto exit; + } + + for (i = 0, bssid_ptr = ptr->bssid; i < ptr->nbssid; i++, bssid_ptr++) { + _pno_bssid = kzalloc(sizeof(struct dhd_pno_bssid), GFP_KERNEL); + + if (!_pno_bssid) { + DHD_ERROR(("_pno_bssid is NULL, cannot kalloc %zd bytes", + sizeof(struct dhd_pno_bssid))); + err = BCME_NOMEM; + goto exit; + } + memcpy(&_pno_bssid->macaddr, &bssid_ptr->macaddr, ETHER_ADDR_LEN); + + flags = (int8) bssid_ptr->rssi_reporting_threshold; + _pno_bssid->flags = flags << WL_PFN_RSSI_SHIFT; + list_add_tail(&_pno_bssid->list, + &_params->params_gscan.hotlist_bssid_list); + } + + _params->params_gscan.nbssid_hotlist += ptr->nbssid; + _params->params_gscan.lost_ap_window = ptr->lost_ap_window; + } + break; + case DHD_PNO_SIGNIFICANT_SCAN_CFG_ID: + { + gscan_swc_params_t *ptr = (gscan_swc_params_t *)buf; + dhd_pno_significant_bssid_t *_pno_significant_change_bssid; + wl_pfn_significant_bssid_t *significant_bssid_ptr; + + if (flush) { + dhd_pno_reset_cfg_gscan(_params, _pno_state, + GSCAN_FLUSH_SIGNIFICANT_CFG); + } + + if (!ptr->nbssid) + break; + + if (!_params->params_gscan.nbssid_significant_change) + INIT_LIST_HEAD(&_params->params_gscan.significant_bssid_list); + + if ((_params->params_gscan.nbssid_significant_change + + ptr->nbssid) > PFN_SWC_MAX_NUM_APS) { + DHD_ERROR(("Excessive number of SWC APs programmed %d\n", + (_params->params_gscan.nbssid_significant_change + + ptr->nbssid))); + err = BCME_RANGE; + goto exit; + } + + for (i = 0, significant_bssid_ptr = ptr->bssid_elem_list; + i < ptr->nbssid; i++, significant_bssid_ptr++) { + _pno_significant_change_bssid = + kzalloc(sizeof(dhd_pno_significant_bssid_t), + GFP_KERNEL); + + if (!_pno_significant_change_bssid) { + DHD_ERROR(("SWC bssidptr is NULL, cannot kalloc %zd bytes", + sizeof(dhd_pno_significant_bssid_t))); + err = BCME_NOMEM; + goto exit; + } + memcpy(&_pno_significant_change_bssid->BSSID, + &significant_bssid_ptr->macaddr, ETHER_ADDR_LEN); + _pno_significant_change_bssid->rssi_low_threshold = + significant_bssid_ptr->rssi_low_threshold; + _pno_significant_change_bssid->rssi_high_threshold = + significant_bssid_ptr->rssi_high_threshold; + list_add_tail(&_pno_significant_change_bssid->list, + &_params->params_gscan.significant_bssid_list); + } + + _params->params_gscan.swc_nbssid_threshold = ptr->swc_threshold; + _params->params_gscan.swc_rssi_window_size = ptr->rssi_window; + _params->params_gscan.lost_ap_window = ptr->lost_ap_window; + _params->params_gscan.nbssid_significant_change += ptr->nbssid; + + } + break; + case DHD_PNO_SCAN_CFG_ID: + { + int i, k, valid = 0; + uint16 band, min; + gscan_scan_params_t *ptr = (gscan_scan_params_t *)buf; + struct dhd_pno_gscan_channel_bucket *ch_bucket; + + if (ptr->nchannel_buckets <= GSCAN_MAX_CH_BUCKETS) { + _params->params_gscan.nchannel_buckets = ptr->nchannel_buckets; + + memcpy(_params->params_gscan.channel_bucket, ptr->channel_bucket, + _params->params_gscan.nchannel_buckets * + sizeof(struct dhd_pno_gscan_channel_bucket)); + min = ptr->channel_bucket[0].bucket_freq_multiple; + ch_bucket = _params->params_gscan.channel_bucket; + + for (i = 0; i < ptr->nchannel_buckets; i++) { + band = ch_bucket[i].band; + for (k = 0; k < ptr->channel_bucket[i].num_channels; k++) { + ch_bucket[i].chan_list[k] = + wf_mhz2channel(ptr->channel_bucket[i].chan_list[k], + 0); + } + ch_bucket[i].band = 0; + /* HAL and DHD use different bits for 2.4G and + * 5G in bitmap. Hence translating it here... + */ + if (band & GSCAN_BG_BAND_MASK) + ch_bucket[i].band |= WLC_BAND_2G; + if (band & GSCAN_A_BAND_MASK) + ch_bucket[i].band |= WLC_BAND_5G; + if (band & GSCAN_DFS_MASK) + ch_bucket[i].band |= GSCAN_DFS_MASK; + + if (ptr->scan_fr == + ptr->channel_bucket[i].bucket_freq_multiple) { + valid = 1; + } + if (ptr->channel_bucket[i].bucket_freq_multiple < min) + min = ptr->channel_bucket[i].bucket_freq_multiple; + DHD_PNO(("band %d report_flag %d\n", ch_bucket[i].band, + ch_bucket[i].report_flag)); + } + if (!valid) + ptr->scan_fr = min; + + for (i = 0; i < ptr->nchannel_buckets; i++) { + ch_bucket[i].bucket_freq_multiple = + ch_bucket[i].bucket_freq_multiple/ptr->scan_fr; + } + _params->params_gscan.scan_fr = ptr->scan_fr; + + DHD_PNO(("num_buckets %d scan_fr %d\n", ptr->nchannel_buckets, + _params->params_gscan.scan_fr)); + } else { + err = BCME_BADARG; + } + } + break; + default: + err = BCME_BADARG; + break; + } +exit: + mutex_unlock(&_pno_state->pno_mutex); + return err; + +} + + +static bool +validate_gscan_params(struct dhd_pno_gscan_params *gscan_params) +{ + unsigned int i, k; + + if (!gscan_params->scan_fr || !gscan_params->nchannel_buckets) { + DHD_ERROR(("%s : Scan freq - %d or number of channel buckets - %d is empty\n", + __FUNCTION__, gscan_params->scan_fr, gscan_params->nchannel_buckets)); + return false; + } + + for (i = 0; i < gscan_params->nchannel_buckets; i++) { + if (!gscan_params->channel_bucket[i].band) { + for (k = 0; k < gscan_params->channel_bucket[i].num_channels; k++) { + if (gscan_params->channel_bucket[i].chan_list[k] > CHANNEL_5G_MAX) { + DHD_ERROR(("%s : Unknown channel %d\n", __FUNCTION__, + gscan_params->channel_bucket[i].chan_list[k])); + return false; + } + } + } + } + + return true; +} + +static int +dhd_pno_set_for_gscan(dhd_pub_t *dhd, struct dhd_pno_gscan_params *gscan_params) +{ + int err = BCME_OK; + int mode, i = 0, k; + uint16 _chan_list[WL_NUMCHANNELS]; + int tot_nchan = 0; + int num_buckets_to_fw, tot_num_buckets, gscan_param_size; + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); + wl_pfn_gscan_channel_bucket_t *ch_bucket = NULL; + wl_pfn_gscan_cfg_t *pfn_gscan_cfg_t = NULL; + wl_pfn_significant_bssid_t *p_pfn_significant_bssid = NULL; + wl_pfn_bssid_t *p_pfn_bssid = NULL; + wlc_ssid_ext_t *pssid_list = NULL; + dhd_pno_params_t *params_legacy; + dhd_pno_params_t *_params; + + params_legacy = &_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]; + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + + NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); + NULL_CHECK(gscan_params, "gscan_params is NULL", err); + + DHD_PNO(("%s enter\n", __FUNCTION__)); + + if (!dhd_support_sta_mode(dhd)) { + err = BCME_BADOPTION; + goto exit; + } + if (!WLS_SUPPORTED(_pno_state)) { + DHD_ERROR(("%s : wifi location service is not supported\n", __FUNCTION__)); + err = BCME_UNSUPPORTED; + goto exit; + } + + if (!validate_gscan_params(gscan_params)) { + DHD_ERROR(("%s : Cannot start gscan - bad params\n", __FUNCTION__)); + err = BCME_BADARG; + goto exit; + } + + if (!(ch_bucket = dhd_pno_gscan_create_channel_list(dhd, _pno_state, + _chan_list, &tot_num_buckets, &num_buckets_to_fw))) + goto exit; + + if (_pno_state->pno_mode & (DHD_PNO_GSCAN_MODE | DHD_PNO_LEGACY_MODE)) { + /* store current pno_mode before disabling pno */ + mode = _pno_state->pno_mode; + err = dhd_pno_clean(dhd); + if (err < 0) { + DHD_ERROR(("%s : failed to disable PNO\n", __FUNCTION__)); + goto exit; + } + /* restore the previous mode */ + _pno_state->pno_mode = mode; + } + + _pno_state->pno_mode |= DHD_PNO_GSCAN_MODE; + + if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { + pssid_list = dhd_pno_get_legacy_pno_ssid(dhd, _pno_state); + + if (!pssid_list) { + err = BCME_NOMEM; + DHD_ERROR(("failed to get Legacy PNO SSID list\n")); + goto exit; + } + + if ((err = _dhd_pno_add_ssid(dhd, pssid_list, + params_legacy->params_legacy.nssid)) < 0) { + DHD_ERROR(("failed to add ssid list (err %d) in firmware\n", err)); + goto exit; + } + } + + if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_GSCAN_MODE)) < 0) { + DHD_ERROR(("failed to set call pno_set (err %d) in firmware\n", err)); + goto exit; + } + + gscan_param_size = sizeof(wl_pfn_gscan_cfg_t) + + (num_buckets_to_fw - 1) * sizeof(wl_pfn_gscan_channel_bucket_t); + pfn_gscan_cfg_t = (wl_pfn_gscan_cfg_t *) MALLOC(dhd->osh, gscan_param_size); + + if (!pfn_gscan_cfg_t) { + DHD_ERROR(("%s: failed to malloc memory of size %d\n", + __FUNCTION__, gscan_param_size)); + err = BCME_NOMEM; + goto exit; + } + + if (gscan_params->mscan) + pfn_gscan_cfg_t->buffer_threshold = gscan_params->buffer_threshold; + else + pfn_gscan_cfg_t->buffer_threshold = GSCAN_BATCH_NO_THR_SET; + + if (gscan_params->nbssid_significant_change) { + pfn_gscan_cfg_t->swc_nbssid_threshold = gscan_params->swc_nbssid_threshold; + pfn_gscan_cfg_t->swc_rssi_window_size = gscan_params->swc_rssi_window_size; + pfn_gscan_cfg_t->lost_ap_window = gscan_params->lost_ap_window; + } else { + pfn_gscan_cfg_t->swc_nbssid_threshold = 0; + pfn_gscan_cfg_t->swc_rssi_window_size = 0; + pfn_gscan_cfg_t->lost_ap_window = 0; + } + pfn_gscan_cfg_t->flags = + (gscan_params->send_all_results_flag & GSCAN_SEND_ALL_RESULTS_MASK); + pfn_gscan_cfg_t->count_of_channel_buckets = num_buckets_to_fw; + + for (i = 0, k = 0; i < tot_num_buckets; i++) { + if (ch_bucket[i].bucket_end_index != CHANNEL_BUCKET_EMPTY_INDEX) { + pfn_gscan_cfg_t->channel_bucket[k].bucket_end_index = + ch_bucket[i].bucket_end_index; + pfn_gscan_cfg_t->channel_bucket[k].bucket_freq_multiple = + ch_bucket[i].bucket_freq_multiple; + pfn_gscan_cfg_t->channel_bucket[k].report_flag = + ch_bucket[i].report_flag; + k++; + } + } + + tot_nchan = pfn_gscan_cfg_t->channel_bucket[num_buckets_to_fw - 1].bucket_end_index + 1; + DHD_PNO(("Total channel num %d total ch_buckets %d ch_buckets_to_fw %d \n", tot_nchan, + tot_num_buckets, num_buckets_to_fw)); + + if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) { + DHD_ERROR(("%s : failed to set call pno_cfg (err %d) in firmware\n", + __FUNCTION__, err)); + goto exit; + } + + if ((err = _dhd_pno_gscan_cfg(dhd, pfn_gscan_cfg_t, gscan_param_size)) < 0) { + DHD_ERROR(("%s : failed to set call pno_gscan_cfg (err %d) in firmware\n", + __FUNCTION__, err)); + goto exit; + } + if (gscan_params->nbssid_significant_change) { + dhd_pno_significant_bssid_t *iter, *next; + + p_pfn_significant_bssid = kzalloc(sizeof(wl_pfn_significant_bssid_t) * + gscan_params->nbssid_significant_change, GFP_KERNEL); + if (p_pfn_significant_bssid == NULL) { + DHD_ERROR(("%s : failed to allocate memory %zd\n", + __FUNCTION__, + sizeof(wl_pfn_significant_bssid_t) * + gscan_params->nbssid_significant_change)); + err = BCME_NOMEM; + goto exit; + } + i = 0; + /* convert dhd_pno_significant_bssid_t to wl_pfn_significant_bssid_t */ + list_for_each_entry_safe(iter, next, &gscan_params->significant_bssid_list, list) { + p_pfn_significant_bssid[i].rssi_low_threshold = iter->rssi_low_threshold; + p_pfn_significant_bssid[i].rssi_high_threshold = iter->rssi_high_threshold; + memcpy(&p_pfn_significant_bssid[i].macaddr, &iter->BSSID, ETHER_ADDR_LEN); + i++; + } + + DHD_PNO(("nbssid_significant_change %d \n", + gscan_params->nbssid_significant_change)); + err = _dhd_pno_add_significant_bssid(dhd, p_pfn_significant_bssid, + gscan_params->nbssid_significant_change); + if (err < 0) { + DHD_ERROR(("%s : failed to call _dhd_pno_add_significant_bssid(err :%d)\n", + __FUNCTION__, err)); + goto exit; + } + } + + if (gscan_params->nbssid_hotlist) { + struct dhd_pno_bssid *iter, *next; + wl_pfn_bssid_t *ptr; + p_pfn_bssid = (wl_pfn_bssid_t *)kzalloc(sizeof(wl_pfn_bssid_t) * + gscan_params->nbssid_hotlist, GFP_KERNEL); + if (p_pfn_bssid == NULL) { + DHD_ERROR(("%s : failed to allocate wl_pfn_bssid_t array" + " (count: %d)", + __FUNCTION__, _params->params_hotlist.nbssid)); + err = BCME_ERROR; + _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; + goto exit; + } + ptr = p_pfn_bssid; + /* convert dhd_pno_bssid to wl_pfn_bssid */ + DHD_PNO(("nhotlist %d\n", gscan_params->nbssid_hotlist)); + list_for_each_entry_safe(iter, next, + &gscan_params->hotlist_bssid_list, list) { + memcpy(&ptr->macaddr, + &iter->macaddr, ETHER_ADDR_LEN); + ptr->flags = iter->flags; + ptr++; + } + + err = _dhd_pno_add_bssid(dhd, p_pfn_bssid, gscan_params->nbssid_hotlist); + if (err < 0) { + DHD_ERROR(("%s : failed to call _dhd_pno_add_bssid(err :%d)\n", + __FUNCTION__, err)); + goto exit; + } + } + + if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0) + DHD_ERROR(("%s : failed to enable PNO err %d\n", __FUNCTION__, err)); + +exit: + /* clear mode in case of error */ + if (err < 0) + _pno_state->pno_mode &= ~DHD_PNO_GSCAN_MODE; + kfree(pssid_list); + kfree(p_pfn_significant_bssid); + kfree(p_pfn_bssid); + if (pfn_gscan_cfg_t) + MFREE(dhd->osh, pfn_gscan_cfg_t, gscan_param_size); + if (ch_bucket) + MFREE(dhd->osh, ch_bucket, + (tot_num_buckets * sizeof(wl_pfn_gscan_channel_bucket_t))); + return err; + +} + +static void +dhd_pno_merge_gscan_pno_channels(dhd_pno_status_info_t *pno_state, + uint16 *chan_list, + uint8 *ch_scratch_pad, + wl_pfn_gscan_channel_bucket_t *ch_bucket, + uint32 *num_buckets_to_fw, + int num_channels) +{ + uint16 chan_buf[WL_NUMCHANNELS]; + int i, j = 0, ch_bucket_idx = 0; + dhd_pno_params_t *_params = &pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + dhd_pno_params_t *_params1 = &pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]; + uint16 *legacy_chan_list = _params1->params_legacy.chan_list; + bool is_legacy_scan_freq_higher; + uint8 report_flag = CH_BUCKET_REPORT_REGULAR; + + if (!_params1->params_legacy.scan_fr) + _params1->params_legacy.scan_fr = PNO_SCAN_MIN_FW_SEC; + + is_legacy_scan_freq_higher = + _params->params_gscan.scan_fr < _params1->params_legacy.scan_fr; + + /* Calculate new Legacy scan multiple of base scan_freq + * The legacy PNO channel bucket is added at the end of the + * channel bucket list. + */ + if (is_legacy_scan_freq_higher) { + ch_bucket[_params->params_gscan.nchannel_buckets].bucket_freq_multiple = + _params1->params_legacy.scan_fr/_params->params_gscan.scan_fr; + + } else { + uint16 max = 0; + + /* Calculate new multiple of base scan_freq for gscan buckets */ + ch_bucket[_params->params_gscan.nchannel_buckets].bucket_freq_multiple = 1; + for (i = 0; i < _params->params_gscan.nchannel_buckets; i++) { + ch_bucket[i].bucket_freq_multiple *= _params->params_gscan.scan_fr; + ch_bucket[i].bucket_freq_multiple /= _params1->params_legacy.scan_fr; + if (max < ch_bucket[i].bucket_freq_multiple) + max = ch_bucket[i].bucket_freq_multiple; + } + _params->params_gscan.max_ch_bucket_freq = max; + } + + /* Off to remove duplicates!! + * Find channels that are already being serviced by gscan before legacy bucket + * These have to be removed from legacy bucket. + * !!Assuming chan_list channels are validated list of channels!! + * ch_scratch_pad is 1 at gscan bucket locations see dhd_pno_gscan_create_channel_list() + */ + for (i = 0; i < _params1->params_legacy.nchan; i++) + ch_scratch_pad[legacy_chan_list[i]] += 2; + + ch_bucket_idx = 0; + memcpy(chan_buf, chan_list, num_channels * sizeof(uint16)); + + /* Finally create channel list and bucket + * At this point ch_scratch_pad can have 4 values: + * 0 - Channel not present in either Gscan or Legacy PNO bucket + * 1 - Channel present only in Gscan bucket + * 2 - Channel present only in Legacy PNO bucket + * 3 - Channel present in both Gscan and Legacy PNO buckets + * Thus Gscan buckets can have values 1 or 3 and Legacy 2 or 3 + * For channel buckets with scan_freq < legacy accept all + * channels i.e. ch_scratch_pad = 1 and 3 + * else accept only ch_scratch_pad = 1 and mark rejects as + * ch_scratch_pad = 4 so that they go in legacy + */ + for (i = 0; i < _params->params_gscan.nchannel_buckets; i++) { + if (ch_bucket[i].bucket_freq_multiple <= + ch_bucket[_params->params_gscan.nchannel_buckets].bucket_freq_multiple) { + for (; ch_bucket_idx <= ch_bucket[i].bucket_end_index; ch_bucket_idx++, j++) + chan_list[j] = chan_buf[ch_bucket_idx]; + + ch_bucket[i].bucket_end_index = j - 1; + } else { + num_channels = 0; + for (; ch_bucket_idx <= ch_bucket[i].bucket_end_index; ch_bucket_idx++) { + if (ch_scratch_pad[chan_buf[ch_bucket_idx]] == 1) { + chan_list[j] = chan_buf[ch_bucket_idx]; + j++; + num_channels++; + } else { + ch_scratch_pad[chan_buf[ch_bucket_idx]] = 4; + /* If Gscan channel is merged off to legacy bucket and + * if the gscan channel bucket has a report flag > 0 + * use the same for legacy + */ + if (report_flag < ch_bucket[i].report_flag) + report_flag = ch_bucket[i].report_flag; + } + } + + if (num_channels) { + ch_bucket[i].bucket_end_index = j - 1; + } else { + ch_bucket[i].bucket_end_index = CHANNEL_BUCKET_EMPTY_INDEX; + *num_buckets_to_fw = *num_buckets_to_fw - 1; + } + } + + } + + num_channels = 0; + ch_bucket[_params->params_gscan.nchannel_buckets].report_flag = report_flag; + /* Now add channels to the legacy scan bucket + * ch_scratch_pad = 0 to 4 at this point, for legacy -> 2,3,4. 2 means exclusively + * Legacy so add to bucket. 4 means it is a reject of gscan bucket and must + * be added to Legacy bucket,reject 3 + */ + for (i = 0; i < _params1->params_legacy.nchan; i++) { + if (ch_scratch_pad[legacy_chan_list[i]] != 3) { + chan_list[j] = legacy_chan_list[i]; + j++; + num_channels++; + } + } + if (num_channels) { + ch_bucket[_params->params_gscan.nchannel_buckets].bucket_end_index = j - 1; + } + else { + ch_bucket[_params->params_gscan.nchannel_buckets].bucket_end_index = + CHANNEL_BUCKET_EMPTY_INDEX; + *num_buckets_to_fw = *num_buckets_to_fw - 1; + } + + return; +} + +static wl_pfn_gscan_channel_bucket_t * +dhd_pno_gscan_create_channel_list(dhd_pub_t *dhd, + dhd_pno_status_info_t *_pno_state, + uint16 *chan_list, + uint32 *num_buckets, + uint32 *num_buckets_to_fw) +{ + int i, num_channels, err, nchan = WL_NUMCHANNELS; + uint16 *ptr = chan_list, max; + uint8 *ch_scratch_pad; + wl_pfn_gscan_channel_bucket_t *ch_bucket; + dhd_pno_params_t *_params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + bool is_pno_legacy_running = _pno_state->pno_mode & DHD_PNO_LEGACY_MODE; + dhd_pno_gscan_channel_bucket_t *gscan_buckets = _params->params_gscan.channel_bucket; + + if (is_pno_legacy_running) + *num_buckets = _params->params_gscan.nchannel_buckets + 1; + else + *num_buckets = _params->params_gscan.nchannel_buckets; + + *num_buckets_to_fw = *num_buckets; + + ch_bucket = (wl_pfn_gscan_channel_bucket_t *) MALLOC(dhd->osh, + ((*num_buckets) * sizeof(wl_pfn_gscan_channel_bucket_t))); + + if (!ch_bucket) { + DHD_ERROR(("%s: failed to malloc memory of size %zd\n", + __FUNCTION__, (*num_buckets) * sizeof(wl_pfn_gscan_channel_bucket_t))); + *num_buckets_to_fw = *num_buckets = 0; + return NULL; + } + + max = gscan_buckets[0].bucket_freq_multiple; + num_channels = 0; + for (i = 0; i < _params->params_gscan.nchannel_buckets; i++) { + if (!gscan_buckets[i].band) { + num_channels += gscan_buckets[i].num_channels; + memcpy(ptr, gscan_buckets[i].chan_list, + gscan_buckets[i].num_channels * sizeof(uint16)); + ptr = ptr + gscan_buckets[i].num_channels; + } else { + /* get a valid channel list based on band B or A */ + err = _dhd_pno_get_channels(dhd, ptr, + &nchan, (gscan_buckets[i].band & GSCAN_ABG_BAND_MASK), + !(gscan_buckets[i].band & GSCAN_DFS_MASK)); + + if (err < 0) { + DHD_ERROR(("%s: failed to get valid channel list(band : %d)\n", + __FUNCTION__, gscan_buckets[i].band)); + MFREE(dhd->osh, ch_bucket, + ((*num_buckets) * sizeof(wl_pfn_gscan_channel_bucket_t))); + *num_buckets_to_fw = *num_buckets = 0; + return NULL; + } + + num_channels += nchan; + ptr = ptr + nchan; + } + + ch_bucket[i].bucket_end_index = num_channels - 1; + ch_bucket[i].bucket_freq_multiple = gscan_buckets[i].bucket_freq_multiple; + ch_bucket[i].report_flag = gscan_buckets[i].report_flag; + if (max < gscan_buckets[i].bucket_freq_multiple) + max = gscan_buckets[i].bucket_freq_multiple; + nchan = WL_NUMCHANNELS - num_channels; + DHD_PNO(("end_idx %d freq_mult - %d\n", + ch_bucket[i].bucket_end_index, ch_bucket[i].bucket_freq_multiple)); + } + + ch_scratch_pad = (uint8 *) kzalloc(CHANNEL_5G_MAX, GFP_KERNEL); + if (!ch_scratch_pad) { + DHD_ERROR(("%s: failed to malloc memory of size %d\n", + __FUNCTION__, CHANNEL_5G_MAX)); + MFREE(dhd->osh, ch_bucket, + ((*num_buckets) * sizeof(wl_pfn_gscan_channel_bucket_t))); + *num_buckets_to_fw = *num_buckets = 0; + return NULL; + } + + /* Need to look for duplicates in gscan buckets if the framework programmed + * the gscan buckets badly, for now return error if there are duplicates. + * Plus as an added bonus, we get all channels in Gscan bucket + * set to 1 for dhd_pno_merge_gscan_pno_channels() + */ + for (i = 0; i < num_channels; i++) { + if (!ch_scratch_pad[chan_list[i]]) { + ch_scratch_pad[chan_list[i]] = 1; + } else { + DHD_ERROR(("%s: Duplicate channel - %d programmed in channel bucket\n", + __FUNCTION__, chan_list[i])); + MFREE(dhd->osh, ch_bucket, ((*num_buckets) * + sizeof(wl_pfn_gscan_channel_bucket_t))); + *num_buckets_to_fw = *num_buckets = 0; + kfree(ch_scratch_pad); + return NULL; + } + + } + + _params->params_gscan.max_ch_bucket_freq = max; + /* Legacy PNO maybe running, which means we need to create a legacy PNO bucket + * Plus need to remove duplicates as the legacy PNO chan_list may have common channels + * If channel is to be scanned more frequently as per gscan requirements + * remove from legacy PNO ch_bucket. Similarly, if legacy wants a channel scanned + * more often, it is removed from the Gscan channel bucket. + * In the end both are satisfied. + */ + if (is_pno_legacy_running) + dhd_pno_merge_gscan_pno_channels(_pno_state, chan_list, + ch_scratch_pad, ch_bucket, num_buckets_to_fw, num_channels); + + kfree(ch_scratch_pad); + return ch_bucket; +} + +static int dhd_pno_stop_for_gscan(dhd_pub_t *dhd) +{ + int err = BCME_OK; + int mode; + dhd_pno_status_info_t *_pno_state; + wlc_ssid_ext_t *pssid_list = NULL; + + _pno_state = PNO_GET_PNOSTATE(dhd); + DHD_PNO(("%s enter\n", __FUNCTION__)); + + if (!dhd_support_sta_mode(dhd)) { + err = BCME_BADOPTION; + goto exit; + } + if (!WLS_SUPPORTED(_pno_state)) { + DHD_ERROR(("%s : wifi location service is not supported\n", + __FUNCTION__)); + err = BCME_UNSUPPORTED; + goto exit; + } + + if (!(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE)) { + DHD_ERROR(("%s : GSCAN is not enabled\n", __FUNCTION__)); + goto exit; + } + mutex_lock(&_pno_state->pno_mutex); + mode = _pno_state->pno_mode & ~DHD_PNO_GSCAN_MODE; + err = dhd_pno_clean(dhd); + if (err < 0) { + DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + __FUNCTION__, err)); + mutex_unlock(&_pno_state->pno_mutex); + return err; + } + _pno_state->pno_mode = mode; + mutex_unlock(&_pno_state->pno_mutex); + + /* Reprogram Legacy PNO if it was running */ + if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { + struct dhd_pno_legacy_params *params_legacy; + uint16 chan_list[WL_NUMCHANNELS]; + + params_legacy = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy); + _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + pssid_list = dhd_pno_get_legacy_pno_ssid(dhd, _pno_state); + if (!pssid_list) { + err = BCME_NOMEM; + DHD_ERROR(("failed to get Legacy PNO SSID list\n")); + goto exit; + } + + DHD_PNO(("Restarting Legacy PNO SSID scan...\n")); + memcpy(chan_list, params_legacy->chan_list, + (params_legacy->nchan * sizeof(uint16))); + err = dhd_pno_set_for_ssid(dhd, pssid_list, params_legacy->nssid, + params_legacy->scan_fr, params_legacy->pno_repeat, + params_legacy->pno_freq_expo_max, chan_list, + params_legacy->nchan); + if (err < 0) { + _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + DHD_ERROR(("%s : failed to restart legacy PNO scan(err: %d)\n", + __FUNCTION__, err)); + goto exit; + } + + } + +exit: + kfree(pssid_list); + return err; +} + +int +dhd_pno_initiate_gscan_request(dhd_pub_t *dhd, bool run, bool flush) +{ + int err = BCME_OK; + dhd_pno_params_t *params; + dhd_pno_status_info_t *_pno_state; + struct dhd_pno_gscan_params *gscan_params; + + NULL_CHECK(dhd, "dhd is NULL\n", err); + NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); + _pno_state = PNO_GET_PNOSTATE(dhd); + + DHD_PNO(("%s enter - run %d flush %d\n", __FUNCTION__, run, flush)); + + params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + gscan_params = ¶ms->params_gscan; + + if (run) { + err = dhd_pno_set_for_gscan(dhd, gscan_params); + } else { + if (flush) { + mutex_lock(&_pno_state->pno_mutex); + dhd_pno_reset_cfg_gscan(params, _pno_state, GSCAN_FLUSH_ALL_CFG); + mutex_unlock(&_pno_state->pno_mutex); + } + /* Need to stop all gscan */ + err = dhd_pno_stop_for_gscan(dhd); + } + + return err; +} + +int dhd_pno_enable_full_scan_result(dhd_pub_t *dhd, bool real_time_flag) +{ + int err = BCME_OK; + dhd_pno_params_t *params; + dhd_pno_status_info_t *_pno_state; + struct dhd_pno_gscan_params *gscan_params; + uint8 old_flag; + + NULL_CHECK(dhd, "dhd is NULL\n", err); + NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); + _pno_state = PNO_GET_PNOSTATE(dhd); + + DHD_PNO(("%s enter\n", __FUNCTION__)); + + if (!WLS_SUPPORTED(_pno_state)) { + DHD_ERROR(("%s : wifi location service is not supported\n", __FUNCTION__)); + err = BCME_UNSUPPORTED; + goto exit; + } + + params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + gscan_params = ¶ms->params_gscan; + + mutex_lock(&_pno_state->pno_mutex); + + old_flag = gscan_params->send_all_results_flag; + gscan_params->send_all_results_flag = (uint8) real_time_flag; + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + if (old_flag != gscan_params->send_all_results_flag) { + wl_pfn_gscan_cfg_t gscan_cfg; + + gscan_cfg.flags = (gscan_params->send_all_results_flag & + GSCAN_SEND_ALL_RESULTS_MASK); + gscan_cfg.flags |= GSCAN_CFG_FLAGS_ONLY_MASK; + + if ((err = _dhd_pno_gscan_cfg(dhd, &gscan_cfg, + sizeof(wl_pfn_gscan_cfg_t))) < 0) { + DHD_ERROR(("%s : pno_gscan_cfg failed (err %d) in firmware\n", + __FUNCTION__, err)); + goto exit_mutex_unlock; + } + } else { + DHD_PNO(("No change in flag - %d\n", old_flag)); + } + } else { + DHD_PNO(("Gscan not started\n")); + } +exit_mutex_unlock: + mutex_unlock(&_pno_state->pno_mutex); +exit: + return err; +} + +int dhd_gscan_batch_cache_cleanup(dhd_pub_t *dhd) +{ + int ret = 0; + dhd_pno_params_t *params; + struct dhd_pno_gscan_params *gscan_params; + dhd_pno_status_info_t *_pno_state; + gscan_results_cache_t *iter, *tmp; + + _pno_state = PNO_GET_PNOSTATE(dhd); + params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + gscan_params = ¶ms->params_gscan; + iter = gscan_params->gscan_batch_cache; + + while (iter) { + if (iter->tot_consumed == iter->tot_count) { + tmp = iter->next; + kfree(iter); + iter = tmp; + } else + break; + } + gscan_params->gscan_batch_cache = iter; + ret = (iter == NULL); + return ret; +} + +static int _dhd_pno_get_gscan_batch_from_fw(dhd_pub_t *dhd) +{ + int err = BCME_OK; + uint32 timestamp = 0, ts = 0, i, j, timediff; + dhd_pno_params_t *params; + dhd_pno_status_info_t *_pno_state; + wl_pfn_lnet_info_t *plnetinfo; + struct dhd_pno_gscan_params *gscan_params; + wl_pfn_lscanresults_t *plbestnet = NULL; + gscan_results_cache_t *iter, *tail; + wifi_gscan_result_t *result; + uint8 *nAPs_per_scan = NULL; + uint8 num_scans_in_cur_iter; + uint16 count, scan_id = 0; + + NULL_CHECK(dhd, "dhd is NULL\n", err); + NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); + + _pno_state = PNO_GET_PNOSTATE(dhd); + params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + DHD_PNO(("%s enter\n", __FUNCTION__)); + + if (!WLS_SUPPORTED(_pno_state)) { + DHD_ERROR(("%s : wifi location service is not supported\n", __FUNCTION__)); + err = BCME_UNSUPPORTED; + goto exit; + } + + gscan_params = ¶ms->params_gscan; + nAPs_per_scan = (uint8 *) MALLOC(dhd->osh, gscan_params->mscan); + + if (!nAPs_per_scan) { + DHD_ERROR(("%s :Out of memory!! Cant malloc %d bytes\n", __FUNCTION__, + gscan_params->mscan)); + err = BCME_NOMEM; + goto exit; + } + + plbestnet = (wl_pfn_lscanresults_t *)MALLOC(dhd->osh, PNO_BESTNET_LEN); + + mutex_lock(&_pno_state->pno_mutex); + + iter = gscan_params->gscan_batch_cache; + /* If a cache has not been consumed , just delete it */ + while (iter) { + iter->tot_consumed = iter->tot_count; + iter = iter->next; + } + dhd_gscan_batch_cache_cleanup(dhd); + + if (!(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE)) { + DHD_ERROR(("%s : GSCAN is not enabled\n", __FUNCTION__)); + goto exit_mutex_unlock; + } + + timediff = gscan_params->scan_fr * 1000; + timediff = timediff >> 1; + + /* Ok, now lets start getting results from the FW */ + plbestnet->status = PFN_INCOMPLETE; + tail = gscan_params->gscan_batch_cache; + while (plbestnet->status != PFN_COMPLETE) { + memset(plbestnet, 0, PNO_BESTNET_LEN); + err = dhd_iovar(dhd, 0, "pfnlbest", (char *)plbestnet, PNO_BESTNET_LEN, 0); + if (err < 0) { + DHD_ERROR(("%s : Cannot get all the batch results, err :%d\n", + __FUNCTION__, err)); + goto exit_mutex_unlock; + } + DHD_PNO(("ver %d, status : %d, count %d\n", plbestnet->version, + plbestnet->status, plbestnet->count)); + if (plbestnet->version != PFN_SCANRESULT_VERSION) { + err = BCME_VERSION; + DHD_ERROR(("bestnet version(%d) is mismatch with Driver version(%d)\n", + plbestnet->version, PFN_SCANRESULT_VERSION)); + goto exit_mutex_unlock; + } + + num_scans_in_cur_iter = 0; + timestamp = plbestnet->netinfo[0].timestamp; + /* find out how many scans' results did we get in this batch of FW results */ + for (i = 0, count = 0; i < plbestnet->count; i++, count++) { + plnetinfo = &plbestnet->netinfo[i]; + /* Unlikely to happen, but just in case the results from + * FW doesnt make sense..... Assume its part of one single scan + */ + if (num_scans_in_cur_iter > gscan_params->mscan) { + num_scans_in_cur_iter = 0; + count = plbestnet->count; + break; + } + if (TIME_DIFF_MS(timestamp, plnetinfo->timestamp) > timediff) { + nAPs_per_scan[num_scans_in_cur_iter] = count; + count = 0; + num_scans_in_cur_iter++; + } + timestamp = plnetinfo->timestamp; + } + nAPs_per_scan[num_scans_in_cur_iter] = count; + num_scans_in_cur_iter++; + + DHD_PNO(("num_scans_in_cur_iter %d\n", num_scans_in_cur_iter)); + plnetinfo = &plbestnet->netinfo[0]; + + for (i = 0; i < num_scans_in_cur_iter; i++) { + iter = (gscan_results_cache_t *) + kmalloc(((nAPs_per_scan[i] - 1) * sizeof(wifi_gscan_result_t)) + + sizeof(gscan_results_cache_t), + GFP_KERNEL); + if (!iter) { + DHD_ERROR(("%s :Out of memory!! Cant malloc %d bytes\n", + __FUNCTION__, gscan_params->mscan)); + err = BCME_NOMEM; + goto exit_mutex_unlock; + } + /* Need this check because the new set of results from FW + * maybe a continuation of previous sets' scan results + */ + if (TIME_DIFF_MS(ts, plnetinfo->timestamp) > timediff) + iter->scan_id = ++scan_id; + else + iter->scan_id = scan_id; + + DHD_PNO(("scan_id %d tot_count %d\n", scan_id, nAPs_per_scan[i])); + iter->tot_count = nAPs_per_scan[i]; + iter->tot_consumed = 0; + if (plnetinfo->flags & PFN_PARTIAL_SCAN_MASK) { + DHD_PNO(("This scan is aborted\n")); + iter->flag = (ENABLE << PNO_STATUS_ABORT); + } else if (gscan_params->reason) { + iter->flag = (ENABLE << gscan_params->reason); + } + + if (!tail) + gscan_params->gscan_batch_cache = iter; + else + tail->next = iter; + + tail = iter; + iter->next = NULL; + for (j = 0; j < nAPs_per_scan[i]; j++, plnetinfo++) { + result = &iter->results[j]; + + result->channel = wf_channel2mhz(plnetinfo->pfnsubnet.channel, + (plnetinfo->pfnsubnet.channel <= CH_MAX_2G_CHANNEL? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G)); + result->rssi = (int32) plnetinfo->RSSI; + /* Info not available & not expected */ + result->beacon_period = 0; + result->capability = 0; + result->ie_length = 0; + result->rtt = (uint64) plnetinfo->rtt0; + result->rtt_sd = (uint64) plnetinfo->rtt1; + result->ts = convert_fw_rel_time_to_systime(plnetinfo->timestamp); + ts = plnetinfo->timestamp; + if (plnetinfo->pfnsubnet.SSID_len > DOT11_MAX_SSID_LEN) { + DHD_ERROR(("%s: Invalid SSID length %d\n", + __FUNCTION__, plnetinfo->pfnsubnet.SSID_len)); + plnetinfo->pfnsubnet.SSID_len = DOT11_MAX_SSID_LEN; + } + memcpy(result->ssid, plnetinfo->pfnsubnet.SSID, + plnetinfo->pfnsubnet.SSID_len); + result->ssid[plnetinfo->pfnsubnet.SSID_len] = '\0'; + memcpy(&result->macaddr, &plnetinfo->pfnsubnet.BSSID, + ETHER_ADDR_LEN); + + DHD_PNO(("\tSSID : ")); + DHD_PNO(("\n")); + DHD_PNO(("\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", + result->macaddr.octet[0], + result->macaddr.octet[1], + result->macaddr.octet[2], + result->macaddr.octet[3], + result->macaddr.octet[4], + result->macaddr.octet[5])); + DHD_PNO(("\tchannel: %d, RSSI: %d, timestamp: %d ms\n", + plnetinfo->pfnsubnet.channel, + plnetinfo->RSSI, plnetinfo->timestamp)); + DHD_PNO(("\tRTT0 : %d, RTT1: %d\n", + plnetinfo->rtt0, plnetinfo->rtt1)); + + } + } + } +exit_mutex_unlock: + mutex_unlock(&_pno_state->pno_mutex); +exit: + params->params_gscan.get_batch_flag = GSCAN_BATCH_RETRIEVAL_COMPLETE; + smp_wmb(); + wake_up_interruptible(&_pno_state->batch_get_wait); + if (nAPs_per_scan) + MFREE(dhd->osh, nAPs_per_scan, gscan_params->mscan * sizeof(uint8)); + if (plbestnet) + MFREE(dhd->osh, plbestnet, PNO_BESTNET_LEN); + DHD_PNO(("Batch retrieval done!\n")); + return err; +} +#endif /* GSCAN_SUPPORT */ + +static int +_dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) +{ + int err = BCME_OK; + int i, j; + uint32 timestamp = 0; + dhd_pno_params_t *_params = NULL; + dhd_pno_status_info_t *_pno_state = NULL; + wl_pfn_lscanresults_t *plbestnet = NULL; + wl_pfn_lnet_info_t *plnetinfo; + dhd_pno_bestnet_entry_t *pbestnet_entry; + dhd_pno_best_header_t *pbestnetheader = NULL; + dhd_pno_scan_results_t *pscan_results = NULL, *siter, *snext; + bool allocate_header = FALSE; + NULL_CHECK(dhd, "dhd is NULL", err); + NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); + if (!dhd_support_sta_mode(dhd)) { + err = BCME_BADOPTION; + goto exit_no_unlock; + } + DHD_PNO(("%s enter\n", __FUNCTION__)); + _pno_state = PNO_GET_PNOSTATE(dhd); + + if (!WLS_SUPPORTED(_pno_state)) { + DHD_ERROR(("%s : wifi location service is not supported\n", __FUNCTION__)); + err = BCME_UNSUPPORTED; + goto exit_no_unlock; + } +#ifdef GSCAN_SUPPORT + if (!(_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_GSCAN_MODE))) { +#else + if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { +#endif /* GSCAN_SUPPORT */ + DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__)); + goto exit_no_unlock; + } + mutex_lock(&_pno_state->pno_mutex); + _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; + if (buf && bufsize) { + if (!list_empty(&_params->params_batch.get_batch.expired_scan_results_list)) { + /* need to check whether we have cashed data or not */ + DHD_PNO(("%s: have cashed batching data in Driver\n", + __FUNCTION__)); + /* convert to results format */ + goto convert_format; + } else { + /* this is a first try to get batching results */ + if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) { + /* move the scan_results_list to expired_scan_results_lists */ + list_for_each_entry_safe(siter, snext, + &_params->params_batch.get_batch.scan_results_list, list) { + list_move_tail(&siter->list, + &_params->params_batch.get_batch.expired_scan_results_list); + } + _params->params_batch.get_batch.top_node_cnt = 0; + _params->params_batch.get_batch.expired_tot_scan_cnt = + _params->params_batch.get_batch.tot_scan_cnt; + _params->params_batch.get_batch.tot_scan_cnt = 0; + goto convert_format; + } + } + } + /* create dhd_pno_scan_results_t whenever we got event WLC_E_PFN_BEST_BATCHING */ + pscan_results = (dhd_pno_scan_results_t *)MALLOC(dhd->osh, SCAN_RESULTS_SIZE); + if (pscan_results == NULL) { + err = BCME_NOMEM; + DHD_ERROR(("failed to allocate dhd_pno_scan_results_t\n")); + goto exit; + } + pscan_results->bestnetheader = NULL; pscan_results->cnt_header = 0; /* add the element into list unless total node cnt is less than MAX_NODE_ CNT */ if (_params->params_batch.get_batch.top_node_cnt < MAX_NODE_CNT) { @@ -1283,6 +2907,11 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) pbestnet_entry->rtt0 = plnetinfo->rtt0; pbestnet_entry->rtt1 = plnetinfo->rtt1; pbestnet_entry->timestamp = plnetinfo->timestamp; + if (plnetinfo->pfnsubnet.SSID_len > DOT11_MAX_SSID_LEN) { + DHD_ERROR(("%s: Invalid SSID length %d: trimming it to max\n", + __FUNCTION__, plnetinfo->pfnsubnet.SSID_len)); + plnetinfo->pfnsubnet.SSID_len = DOT11_MAX_SSID_LEN; + } pbestnet_entry->SSID_len = plnetinfo->pfnsubnet.SSID_len; memcpy(pbestnet_entry->SSID, plnetinfo->pfnsubnet.SSID, pbestnet_entry->SSID_len); @@ -1354,6 +2983,7 @@ exit: _params->params_batch.get_batch.bytes_written = err; } mutex_unlock(&_pno_state->pno_mutex); +exit_no_unlock: if (waitqueue_active(&_pno_state->get_batch_done.wait)) complete(&_pno_state->get_batch_done); return err; @@ -1371,9 +3001,19 @@ _dhd_pno_get_batch_handler(struct work_struct *work) DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__)); return; } - params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; - _dhd_pno_get_for_batch(dhd, params_batch->get_batch.buf, - params_batch->get_batch.bufsize, params_batch->get_batch.reason); + +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + _dhd_pno_get_gscan_batch_from_fw(dhd); + return; + } else +#endif /* GSCAN_SUPPORT */ + { + params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; + + _dhd_pno_get_for_batch(dhd, params_batch->get_batch.buf, + params_batch->get_batch.bufsize, params_batch->get_batch.reason); + } } @@ -1399,20 +3039,39 @@ dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) goto exit; } params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; - if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { - DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__)); - memset(pbuf, 0, bufsize); - pbuf += sprintf(pbuf, "scancount=%d\n", 0); - sprintf(pbuf, "%s", RESULTS_END_MARKER); - err = strlen(buf); - goto exit; +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + struct dhd_pno_gscan_params *gscan_params; + gscan_params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan; + gscan_params->reason = reason; + err = dhd_retreive_batch_scan_results(dhd); + if (err == BCME_OK) { + wait_event_interruptible_timeout(_pno_state->batch_get_wait, + is_batch_retreival_complete(gscan_params), + msecs_to_jiffies(GSCAN_BATCH_GET_MAX_WAIT)); + } + } else +#endif + { + if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { + DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__)); + memset(pbuf, 0, bufsize); + pbuf += sprintf(pbuf, "scancount=%d\n", 0); + sprintf(pbuf, "%s", RESULTS_END_MARKER); + err = strlen(buf); + goto exit; + } + params_batch->get_batch.buf = buf; + params_batch->get_batch.bufsize = bufsize; + params_batch->get_batch.reason = reason; + params_batch->get_batch.bytes_written = 0; + schedule_work(&_pno_state->work); + wait_for_completion(&_pno_state->get_batch_done); } - params_batch->get_batch.buf = buf; - params_batch->get_batch.bufsize = bufsize; - params_batch->get_batch.reason = reason; - params_batch->get_batch.bytes_written = 0; - schedule_work(&_pno_state->work); - wait_for_completion(&_pno_state->get_batch_done); + +#ifdef GSCAN_SUPPORT + if (!(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE)) +#endif err = params_batch->get_batch.bytes_written; exit: return err; @@ -1426,8 +3085,8 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) int i = 0; dhd_pno_status_info_t *_pno_state; dhd_pno_params_t *_params; - wl_pfn_bssid_t *p_pfn_bssid; - wlc_ssid_t *p_ssid_list = NULL; + wl_pfn_bssid_t *p_pfn_bssid = NULL; + wlc_ssid_ext_t *p_ssid_list = NULL; NULL_CHECK(dhd, "dhd is NULL", err); NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); _pno_state = PNO_GET_PNOSTATE(dhd); @@ -1442,6 +3101,14 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) err = BCME_UNSUPPORTED; goto exit; } + +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + DHD_PNO(("Gscan is ongoing, nothing to stop here\n")); + return err; + } +#endif + if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { DHD_ERROR(("%s : PNO BATCH MODE is not enabled\n", __FUNCTION__)); goto exit; @@ -1454,25 +3121,14 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) /* restart Legacy PNO if the Legacy PNO is on */ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { struct dhd_pno_legacy_params *_params_legacy; - struct dhd_pno_ssid *iter, *next; _params_legacy = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy); - p_ssid_list = kzalloc(sizeof(wlc_ssid_t) * - _params_legacy->nssid, GFP_KERNEL); - if (p_ssid_list == NULL) { - DHD_ERROR(("%s : failed to allocate wlc_ssid_t array (count: %d)", - __FUNCTION__, _params_legacy->nssid)); - err = BCME_ERROR; - _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + p_ssid_list = dhd_pno_get_legacy_pno_ssid(dhd, _pno_state); + if (!p_ssid_list) { + err = BCME_NOMEM; + DHD_ERROR(("failed to get Legacy PNO SSID list\n")); goto exit; } - i = 0; - /* convert dhd_pno_ssid to dhd_pno_ssid */ - list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) { - p_ssid_list[i].SSID_len = iter->SSID_len; - memcpy(p_ssid_list[i].SSID, iter->SSID, p_ssid_list[i].SSID_len); - i++; - } err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid, _params_legacy->scan_fr, _params_legacy->pno_repeat, _params_legacy->pno_freq_expo_max, _params_legacy->chan_list, @@ -1523,8 +3179,8 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) exit: _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE); - if (p_ssid_list) - kfree(p_ssid_list); + kfree(p_ssid_list); + kfree(p_pfn_bssid); return err; } @@ -1684,7 +3340,7 @@ dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) uint32 mode = 0; dhd_pno_status_info_t *_pno_state; dhd_pno_params_t *_params; - wlc_ssid_t *p_ssid_list; + wlc_ssid_ext_t *p_ssid_list = NULL; NULL_CHECK(dhd, "dhd is NULL", err); NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); _pno_state = PNO_GET_PNOSTATE(dhd); @@ -1719,24 +3375,14 @@ dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { /* restart Legacy PNO Scan */ struct dhd_pno_legacy_params *_params_legacy; - struct dhd_pno_ssid *iter, *next; _params_legacy = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy); - p_ssid_list = - kzalloc(sizeof(wlc_ssid_t) * _params_legacy->nssid, GFP_KERNEL); - if (p_ssid_list == NULL) { - DHD_ERROR(("%s : failed to allocate wlc_ssid_t array (count: %d)", - __FUNCTION__, _params_legacy->nssid)); - err = BCME_ERROR; - _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; + p_ssid_list = dhd_pno_get_legacy_pno_ssid(dhd, _pno_state); + if (!p_ssid_list) { + err = BCME_NOMEM; + DHD_ERROR(("failed to get Legacy PNO SSID list\n")); goto exit; } - /* convert dhd_pno_ssid to dhd_pno_ssid */ - list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) { - p_ssid_list->SSID_len = iter->SSID_len; - memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list->SSID_len); - p_ssid_list++; - } err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid, _params_legacy->scan_fr, _params_legacy->pno_repeat, _params_legacy->pno_freq_expo_max, _params_legacy->chan_list, @@ -1768,9 +3414,292 @@ dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) } } exit: + kfree(p_ssid_list); + return err; +} + +#ifdef GSCAN_SUPPORT +int dhd_retreive_batch_scan_results(dhd_pub_t *dhd) +{ + int err = BCME_OK; + dhd_pno_status_info_t *_pno_state; + dhd_pno_params_t *_params; + struct dhd_pno_batch_params *params_batch; + _pno_state = PNO_GET_PNOSTATE(dhd); + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + + params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; + if (_params->params_gscan.get_batch_flag == GSCAN_BATCH_RETRIEVAL_COMPLETE) { + DHD_PNO(("Retreive batch results\n")); + params_batch->get_batch.buf = NULL; + params_batch->get_batch.bufsize = 0; + params_batch->get_batch.reason = PNO_STATUS_EVENT; + _params->params_gscan.get_batch_flag = GSCAN_BATCH_RETRIEVAL_IN_PROGRESS; + schedule_work(&_pno_state->work); + } else { + DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING retrieval" + "already in progress, will skip\n", __FUNCTION__)); + err = BCME_ERROR; + } + return err; } +/* Handle Significant WiFi Change (SWC) event from FW + * Send event to HAL when all results arrive from FW + */ +void * dhd_handle_swc_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes) +{ + void *ptr = NULL; + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); + struct dhd_pno_gscan_params *gscan_params; + struct dhd_pno_swc_evt_param *params; + wl_pfn_swc_results_t *results = (wl_pfn_swc_results_t *)event_data; + wl_pfn_significant_net_t *change_array; + int i; + + gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan); + params = &(gscan_params->param_significant); + + if (!results->total_count) { + *send_evt_bytes = 0; + return ptr; + } + + if (!params->results_rxed_so_far) { + if (!params->change_array) { + params->change_array = (wl_pfn_significant_net_t *) + kmalloc(sizeof(wl_pfn_significant_net_t) * results->total_count, + GFP_KERNEL); + + if (!params->change_array) { + DHD_ERROR(("%s Cannot Malloc %zd bytes!!\n", __FUNCTION__, + sizeof(wl_pfn_significant_net_t) * results->total_count)); + *send_evt_bytes = 0; + return ptr; + } + } else { + DHD_ERROR(("RX'ed WLC_E_PFN_SWC evt from FW, previous evt not complete!!")); + *send_evt_bytes = 0; + return ptr; + } + + } + + DHD_PNO(("%s: pkt_count %d total_count %d\n", __FUNCTION__, + results->pkt_count, results->total_count)); + + for (i = 0; i < results->pkt_count; i++) { + DHD_PNO(("\t %02x:%02x:%02x:%02x:%02x:%02x\n", + results->list[i].BSSID.octet[0], + results->list[i].BSSID.octet[1], + results->list[i].BSSID.octet[2], + results->list[i].BSSID.octet[3], + results->list[i].BSSID.octet[4], + results->list[i].BSSID.octet[5])); + } + + change_array = ¶ms->change_array[params->results_rxed_so_far]; + memcpy(change_array, results->list, sizeof(wl_pfn_significant_net_t) * results->pkt_count); + params->results_rxed_so_far += results->pkt_count; + + if (params->results_rxed_so_far == results->total_count) { + params->results_rxed_so_far = 0; + *send_evt_bytes = sizeof(wl_pfn_significant_net_t) * results->total_count; + /* Pack up change buffer to send up and reset + * results_rxed_so_far, after its done. + */ + ptr = (void *) params->change_array; + /* expecting the callee to free this mem chunk */ + params->change_array = NULL; + } + else { + *send_evt_bytes = 0; + } + + return ptr; +} + +void dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type) +{ + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); + struct dhd_pno_gscan_params *gscan_params; + gscan_results_cache_t *iter, *tmp; + + if (!_pno_state) + return; + gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan); + + if (type == HOTLIST_FOUND) { + iter = gscan_params->gscan_hotlist_found; + gscan_params->gscan_hotlist_found = NULL; + } else { + iter = gscan_params->gscan_hotlist_lost; + gscan_params->gscan_hotlist_lost = NULL; + } + + while (iter) { + tmp = iter->next; + kfree(iter); + iter = tmp; + } + + return; +} + +void * +dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size) +{ + wl_bss_info_t *bi = NULL; + wl_gscan_result_t *gscan_result; + wifi_gscan_result_t *result = NULL; + u32 bi_length = 0; + uint8 channel; + uint32 mem_needed; + struct timespec ts; + + *size = 0; + + gscan_result = (wl_gscan_result_t *)data; + + if (!gscan_result) { + DHD_ERROR(("Invalid gscan result (NULL pointer)\n")); + goto exit; + } + if (!gscan_result->bss_info) { + DHD_ERROR(("Invalid gscan bss info (NULL pointer)\n")); + goto exit; + } + bi = &gscan_result->bss_info[0].info; + bi_length = dtoh32(bi->length); + if (bi_length != (dtoh32(gscan_result->buflen) - + WL_GSCAN_RESULTS_FIXED_SIZE - WL_GSCAN_INFO_FIXED_FIELD_SIZE)) { + DHD_ERROR(("Invalid bss_info length %d: ignoring\n", bi_length)); + goto exit; + } + if (bi->SSID_len > DOT11_MAX_SSID_LEN) { + DHD_ERROR(("Invalid SSID length %d: trimming it to max\n", bi->SSID_len)); + bi->SSID_len = DOT11_MAX_SSID_LEN; + } + + mem_needed = OFFSETOF(wifi_gscan_result_t, ie_data) + bi->ie_length; + result = kmalloc(mem_needed, GFP_KERNEL); + + if (!result) { + DHD_ERROR(("%s Cannot malloc scan result buffer %d bytes\n", + __FUNCTION__, mem_needed)); + goto exit; + } + + memcpy(result->ssid, bi->SSID, bi->SSID_len); + result->ssid[bi->SSID_len] = '\0'; + channel = wf_chspec_ctlchan(bi->chanspec); + result->channel = wf_channel2mhz(channel, + (channel <= CH_MAX_2G_CHANNEL? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G)); + result->rssi = (int32) bi->RSSI; + result->rtt = 0; + result->rtt_sd = 0; + get_monotonic_boottime(&ts); + result->ts = (uint64) TIMESPEC_TO_US(ts); + result->beacon_period = dtoh16(bi->beacon_period); + result->capability = dtoh16(bi->capability); + result->ie_length = dtoh32(bi->ie_length); + memcpy(&result->macaddr, &bi->BSSID, ETHER_ADDR_LEN); + memcpy(result->ie_data, ((uint8 *)bi + bi->ie_offset), bi->ie_length); + *size = mem_needed; +exit: + return result; +} + +void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes, + hotlist_type_t type) +{ + void *ptr = NULL; + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); + struct dhd_pno_gscan_params *gscan_params; + wl_pfn_scanresults_t *results = (wl_pfn_scanresults_t *)event_data; + wifi_gscan_result_t *hotlist_found_array; + wl_pfn_net_info_t *plnetinfo; + gscan_results_cache_t *gscan_hotlist_cache; + int malloc_size = 0, i, total = 0; + + gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan); + + if (!results->count) { + *send_evt_bytes = 0; + return ptr; + } + + malloc_size = sizeof(gscan_results_cache_t) + + ((results->count - 1) * sizeof(wifi_gscan_result_t)); + gscan_hotlist_cache = (gscan_results_cache_t *) kmalloc(malloc_size, GFP_KERNEL); + + if (!gscan_hotlist_cache) { + DHD_ERROR(("%s Cannot Malloc %d bytes!!\n", __FUNCTION__, malloc_size)); + *send_evt_bytes = 0; + return ptr; + } + + if (type == HOTLIST_FOUND) { + gscan_hotlist_cache->next = gscan_params->gscan_hotlist_found; + gscan_params->gscan_hotlist_found = gscan_hotlist_cache; + DHD_PNO(("%s enter, FOUND results count %d\n", __FUNCTION__, results->count)); + } else { + gscan_hotlist_cache->next = gscan_params->gscan_hotlist_lost; + gscan_params->gscan_hotlist_lost = gscan_hotlist_cache; + DHD_PNO(("%s enter, LOST results count %d\n", __FUNCTION__, results->count)); + } + + gscan_hotlist_cache->tot_count = results->count; + gscan_hotlist_cache->tot_consumed = 0; + plnetinfo = results->netinfo; + + for (i = 0; i < results->count; i++, plnetinfo++) { + hotlist_found_array = &gscan_hotlist_cache->results[i]; + hotlist_found_array->channel = wf_channel2mhz(plnetinfo->pfnsubnet.channel, + (plnetinfo->pfnsubnet.channel <= CH_MAX_2G_CHANNEL? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G)); + hotlist_found_array->rssi = (int32) plnetinfo->RSSI; + /* Info not available & not expected */ + hotlist_found_array->beacon_period = 0; + hotlist_found_array->capability = 0; + hotlist_found_array->ie_length = 0; + + hotlist_found_array->ts = convert_fw_rel_time_to_systime(plnetinfo->timestamp); + if (plnetinfo->pfnsubnet.SSID_len > DOT11_MAX_SSID_LEN) { + DHD_ERROR(("Invalid SSID length %d: trimming it to max\n", + plnetinfo->pfnsubnet.SSID_len)); + plnetinfo->pfnsubnet.SSID_len = DOT11_MAX_SSID_LEN; + } + memcpy(hotlist_found_array->ssid, plnetinfo->pfnsubnet.SSID, + plnetinfo->pfnsubnet.SSID_len); + hotlist_found_array->ssid[plnetinfo->pfnsubnet.SSID_len] = '\0'; + + memcpy(&hotlist_found_array->macaddr, &plnetinfo->pfnsubnet.BSSID, ETHER_ADDR_LEN); + DHD_PNO(("\t%s %02x:%02x:%02x:%02x:%02x:%02x rssi %d\n", hotlist_found_array->ssid, + hotlist_found_array->macaddr.octet[0], + hotlist_found_array->macaddr.octet[1], + hotlist_found_array->macaddr.octet[2], + hotlist_found_array->macaddr.octet[3], + hotlist_found_array->macaddr.octet[4], + hotlist_found_array->macaddr.octet[5], + hotlist_found_array->rssi)); + } + + + if (results->status == PFN_COMPLETE) { + ptr = (void *) gscan_hotlist_cache; + while (gscan_hotlist_cache) { + total += gscan_hotlist_cache->tot_count; + gscan_hotlist_cache = gscan_hotlist_cache->next; + } + *send_evt_bytes = total * sizeof(wifi_gscan_result_t); + } + + return ptr; +} +#endif /* GSCAN_SUPPORT */ int dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) { @@ -1796,6 +3725,7 @@ dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) /* TODO : need to implement event logic using generic netlink */ break; case WLC_E_PFN_BEST_BATCHING: +#ifndef GSCAN_SUPPORT { struct dhd_pno_batch_params *params_batch; params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; @@ -1810,6 +3740,9 @@ dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) "will skip this event\n", __FUNCTION__)); break; } +#else + break; +#endif /* !GSCAN_SUPPORT */ default: DHD_ERROR(("unknown event : %d\n", event_type)); } @@ -1836,6 +3769,9 @@ int dhd_pno_init(dhd_pub_t *dhd) mutex_init(&_pno_state->pno_mutex); INIT_WORK(&_pno_state->work, _dhd_pno_get_batch_handler); init_completion(&_pno_state->get_batch_done); +#ifdef GSCAN_SUPPORT + init_waitqueue_head(&_pno_state->batch_get_wait); +#endif /* GSCAN_SUPPORT */ err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, 0); if (err == BCME_UNSUPPORTED) { _pno_state->wls_supported = FALSE; @@ -1861,6 +3797,15 @@ int dhd_pno_deinit(dhd_pub_t *dhd) _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE); } +#ifdef GSCAN_SUPPORT + if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) { + _params = &_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS]; + mutex_lock(&_pno_state->pno_mutex); + dhd_pno_reset_cfg_gscan(_params, _pno_state, GSCAN_FLUSH_ALL_CFG); + mutex_unlock(&_pno_state->pno_mutex); + } +#endif /* GSCAN_SUPPORT */ + if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; /* clear resource if the BATCH MODE is on */ diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.h b/drivers/net/wireless/bcmdhd/dhd_pno.h index 1980476fb9dcb9324b0097a70a7921c86a5e6696..3365fa9b14f1f2c19db2948abfb6ce9e641241fd 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pno.h +++ b/drivers/net/wireless/bcmdhd/dhd_pno.h @@ -1,7 +1,25 @@ /* * Header file of Broadcom Dongle Host Driver (DHD) * Prefered Network Offload code and Wi-Fi Location Service(WLS) code. - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_pno.h 423669 2013-09-18 13:01:55Z $ */ @@ -41,6 +59,33 @@ #define RESULTS_END_MARKER "----\n" #define SCAN_END_MARKER "####\n" #define AP_END_MARKER "====\n" +#define PNO_RSSI_MARGIN_DBM 30 + +#ifdef GSCAN_SUPPORT + +#define GSCAN_MAX_CH_BUCKETS 8 +#define GSCAN_BG_BAND_MASK (1 << 0) +#define GSCAN_A_BAND_MASK (1 << 1) +#define GSCAN_DFS_MASK (1 << 2) +#define GSCAN_ABG_BAND_MASK (GSCAN_A_BAND_MASK | GSCAN_BG_BAND_MASK) +#define GSCAN_BAND_MASK (GSCAN_ABG_BAND_MASK | GSCAN_DFS_MASK) + +#define GSCAN_FLUSH_HOTLIST_CFG (1 << 0) +#define GSCAN_FLUSH_SIGNIFICANT_CFG (1 << 1) +#define GSCAN_FLUSH_SCAN_CFG (1 << 2) +#define GSCAN_FLUSH_ALL_CFG (GSCAN_FLUSH_SCAN_CFG | \ + GSCAN_FLUSH_SIGNIFICANT_CFG | \ + GSCAN_FLUSH_HOTLIST_CFG) +/* Do not change GSCAN_BATCH_RETRIEVAL_COMPLETE */ +#define GSCAN_BATCH_RETRIEVAL_COMPLETE 0 +#define GSCAN_BATCH_RETRIEVAL_IN_PROGRESS 1 +#define GSCAN_BATCH_NO_THR_SET 101 +#define GSCAN_LOST_AP_WINDOW_DEFAULT 4 +#define GSCAN_MIN_BSSID_TIMEOUT 90 +#define GSCAN_BATCH_GET_MAX_WAIT 500 + +#define CHANNEL_BUCKET_EMPTY_INDEX 0xFFFF +#endif /* GSCAN_SUPPORT */ enum scan_status { /* SCAN ABORT by other scan */ @@ -64,6 +109,12 @@ enum index_mode { INDEX_OF_LEGACY_PARAMS, INDEX_OF_BATCH_PARAMS, INDEX_OF_HOTLIST_PARAMS, + /* GSCAN includes hotlist scan and they do not run + * independent of each other + */ +#ifdef GSCAN_SUPPORT + INDEX_OF_GSCAN_PARAMS = INDEX_OF_HOTLIST_PARAMS, +#endif /* GSCAN_SUPPORT */ INDEX_MODE_MAX }; enum dhd_pno_status { @@ -77,16 +128,56 @@ typedef struct cmd_tlv { char subtype; char reserved; } cmd_tlv_t; +#ifdef GSCAN_SUPPORT +typedef enum { + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_BG = 1, /* 2.4 GHz */ + WIFI_BAND_A = 2, /* 5 GHz without DFS */ + WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ + WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ + WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ + WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ +} gscan_wifi_band_t; + +typedef enum { + HOTLIST_LOST, + HOTLIST_FOUND +} hotlist_type_t; + +typedef enum dhd_pno_gscan_cmd_cfg { + DHD_PNO_BATCH_SCAN_CFG_ID, + DHD_PNO_GEOFENCE_SCAN_CFG_ID, + DHD_PNO_SIGNIFICANT_SCAN_CFG_ID, + DHD_PNO_SCAN_CFG_ID, + DHD_PNO_GET_CAPABILITIES, + DHD_PNO_GET_BATCH_RESULTS, + DHD_PNO_GET_CHANNEL_LIST +} dhd_pno_gscan_cmd_cfg_t; + +typedef enum dhd_pno_mode { + /* Wi-Fi Legacy PNO Mode */ + DHD_PNO_NONE_MODE = 0, + DHD_PNO_LEGACY_MODE = (1 << (0)), + /* Wi-Fi Android BATCH SCAN Mode */ + DHD_PNO_BATCH_MODE = (1 << (1)), + /* Wi-Fi Android Hotlist SCAN Mode */ + DHD_PNO_HOTLIST_MODE = (1 << (2)), + /* Wi-Fi Google Android SCAN Mode */ + DHD_PNO_GSCAN_MODE = (1 << (3)) +} dhd_pno_mode_t; +#else typedef enum dhd_pno_mode { /* Wi-Fi Legacy PNO Mode */ - DHD_PNO_NONE_MODE = 0, + DHD_PNO_NONE_MODE = 0, DHD_PNO_LEGACY_MODE = (1 << (0)), /* Wi-Fi Android BATCH SCAN Mode */ DHD_PNO_BATCH_MODE = (1 << (1)), /* Wi-Fi Android Hotlist SCAN Mode */ DHD_PNO_HOTLIST_MODE = (1 << (2)) } dhd_pno_mode_t; +#endif /* GSCAN_SUPPORT */ struct dhd_pno_ssid { + bool hidden; uint32 SSID_len; uchar SSID[DOT11_MAX_SSID_LEN]; struct list_head list; @@ -167,15 +258,141 @@ struct dhd_pno_hotlist_params { uint16 nbssid; struct list_head bssid_list; }; +#ifdef GSCAN_SUPPORT +typedef struct dhd_pno_gscan_channel_bucket { + uint16 bucket_freq_multiple; + /* band = 1 All bg band channels, + * band = 2 All a band channels, + * band = 0 chan_list channels + */ + uint16 band; + uint8 report_flag; + uint8 num_channels; + uint16 chan_list[GSCAN_MAX_CH_BUCKETS]; +} dhd_pno_gscan_channel_bucket_t; + +struct dhd_pno_swc_evt_param { + uint16 results_rxed_so_far; + wl_pfn_significant_net_t *change_array; +}; + +typedef struct wifi_gscan_result { + uint64 ts; /* Time of discovery */ + char ssid[DOT11_MAX_SSID_LEN+1]; /* null terminated */ + struct ether_addr macaddr; /* BSSID */ + uint32 channel; /* channel frequency in MHz */ + int32 rssi; /* in db */ + uint64 rtt; /* in nanoseconds */ + uint64 rtt_sd; /* standard deviation in rtt */ + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint32 ie_length; /* byte length of Information Elements */ + char ie_data[1]; /* IE data to follow */ +} wifi_gscan_result_t; + +typedef struct gscan_results_cache { + struct gscan_results_cache *next; + uint8 scan_id; + uint8 flag; + uint8 tot_count; + uint8 tot_consumed; + wifi_gscan_result_t results[1]; +} gscan_results_cache_t; + +typedef struct dhd_pno_gscan_capabilities { + int max_scan_cache_size; + int max_scan_buckets; + int max_ap_cache_per_scan; + int max_rssi_sample_size; + int max_scan_reporting_threshold; + int max_hotlist_aps; + int max_significant_wifi_change_aps; +} dhd_pno_gscan_capabilities_t; + +struct dhd_pno_gscan_params { + int32 scan_fr; + uint8 bestn; + uint8 mscan; + uint8 buffer_threshold; + uint8 swc_nbssid_threshold; + uint8 swc_rssi_window_size; + uint8 lost_ap_window; + uint8 nchannel_buckets; + uint8 reason; + uint8 get_batch_flag; + uint8 send_all_results_flag; + uint16 max_ch_bucket_freq; + gscan_results_cache_t *gscan_batch_cache; + gscan_results_cache_t *gscan_hotlist_found; + gscan_results_cache_t *gscan_hotlist_lost; + uint16 nbssid_significant_change; + uint16 nbssid_hotlist; + struct dhd_pno_swc_evt_param param_significant; + struct dhd_pno_gscan_channel_bucket channel_bucket[GSCAN_MAX_CH_BUCKETS]; + struct list_head hotlist_bssid_list; + struct list_head significant_bssid_list; +}; + +typedef struct gscan_scan_params { + int32 scan_fr; + uint16 nchannel_buckets; + struct dhd_pno_gscan_channel_bucket channel_bucket[GSCAN_MAX_CH_BUCKETS]; +} gscan_scan_params_t; + +typedef struct gscan_batch_params { + uint8 bestn; + uint8 mscan; + uint8 buffer_threshold; +} gscan_batch_params_t; + +struct bssid_t { + struct ether_addr macaddr; + int16 rssi_reporting_threshold; /* 0 -> no reporting threshold */ +}; + +typedef struct gscan_hotlist_scan_params { + uint16 lost_ap_window; /* number of scans to declare LOST */ + uint16 nbssid; /* number of bssids */ + struct bssid_t bssid[1]; /* n bssids to follow */ +} gscan_hotlist_scan_params_t; + +/* SWC (Significant WiFi Change) params */ +typedef struct gscan_swc_params { + /* Rssi averaging window size */ + uint8 rssi_window; + /* Number of scans that the AP has to be absent before + * being declared LOST + */ + uint8 lost_ap_window; + /* if x Aps have a significant change generate an event. */ + uint8 swc_threshold; + uint8 nbssid; + wl_pfn_significant_bssid_t bssid_elem_list[1]; +} gscan_swc_params_t; + +typedef struct dhd_pno_significant_bssid { + struct ether_addr BSSID; + int8 rssi_low_threshold; + int8 rssi_high_threshold; + struct list_head list; +} dhd_pno_significant_bssid_t; +#endif /* GSCAN_SUPPORT */ typedef union dhd_pno_params { struct dhd_pno_legacy_params params_legacy; struct dhd_pno_batch_params params_batch; struct dhd_pno_hotlist_params params_hotlist; +#ifdef GSCAN_SUPPORT + struct dhd_pno_gscan_params params_gscan; +#endif /* GSCAN_SUPPORT */ } dhd_pno_params_t; typedef struct dhd_pno_status_info { + uint8 pno_oui[DOT11_OUI_LEN]; dhd_pub_t *dhd; struct work_struct work; struct mutex pno_mutex; +#ifdef GSCAN_SUPPORT + wait_queue_head_t batch_get_wait; +#endif /* GSCAN_SUPPORT */ struct completion get_batch_done; bool wls_supported; /* wifi location service supported or not */ enum dhd_pno_status pno_status; @@ -192,7 +409,7 @@ extern int dhd_dev_pno_stop_for_ssid(struct net_device *dev); extern int -dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, +dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_ext_t* ssids_local, int nssid, uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan); extern int @@ -208,11 +425,33 @@ dhd_dev_pno_stop_for_batch(struct net_device *dev); extern int dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid, struct dhd_pno_hotlist_params *hotlist_params); - +extern int dhd_dev_pno_set_mac_oui(struct net_device *dev, uint8 *oui); +#ifdef GSCAN_SUPPORT +extern int +dhd_dev_pno_set_cfg_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type, + void *buf, uint8 flush); +extern void * +dhd_dev_pno_get_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type, void *info, + uint32 *len); +void dhd_dev_pno_lock_access_batch_results(struct net_device *dev); +void dhd_dev_pno_unlock_access_batch_results(struct net_device *dev); +extern int dhd_dev_pno_run_gscan(struct net_device *dev, bool run, bool flush); +extern int dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time); +extern void * dhd_dev_swc_scan_event(struct net_device *dev, const void *data, + int *send_evt_bytes); +int dhd_retreive_batch_scan_results(dhd_pub_t *dhd); +extern void * dhd_dev_hotlist_scan_event(struct net_device *dev, + const void *data, int *send_evt_bytes, hotlist_type_t type); +void * dhd_dev_process_full_gscan_result(struct net_device *dev, + const void *data, int *send_evt_bytes); +extern int dhd_dev_gscan_batch_cache_cleanup(struct net_device *dev); +extern void dhd_dev_gscan_hotlist_cache_cleanup(struct net_device *dev, hotlist_type_t type); +extern void dhd_dev_wait_batch_results_complete(struct net_device *dev); +#endif /* GSCAN_SUPPORT */ /* dhd pno fuctions */ extern int dhd_pno_stop_for_ssid(dhd_pub_t *dhd); extern int dhd_pno_enable(dhd_pub_t *dhd, int enable); -extern int dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, +extern int dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssid_list, int nssid, uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan); extern int dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params); @@ -230,14 +469,28 @@ extern int dhd_pno_stop_for_hotlist(dhd_pub_t *dhd); extern int dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data); extern int dhd_pno_init(dhd_pub_t *dhd); extern int dhd_pno_deinit(dhd_pub_t *dhd); -#endif - -#if (defined(NDISVER) && (NDISVER >= 0x0630)) && defined(PNO_SUPPORT) -extern int dhd_pno_cfg(dhd_pub_t *dhd, wl_pfn_cfg_t *pcfg); -extern int dhd_pno_suspend(dhd_pub_t *dhd, int pfn_suspend); -extern int dhd_pno_set_add(dhd_pub_t *dhd, wl_pfn_t *netinfo, int nssid, ushort scan_fr, - ushort slowscan_fr, uint8 pno_repeat, uint8 pno_freq_expo_max, int16 flags); -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -#endif /* (defined(NDISVER) && (NDISVER >= 0x0630)) && defined(PNO_SUPPORT) */ +extern bool dhd_is_pno_supported(dhd_pub_t *dhd); +extern int dhd_pno_set_mac_oui(dhd_pub_t *dhd, uint8 *oui); +#ifdef GSCAN_SUPPORT +extern int dhd_pno_set_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, + void *buf, uint8 flush); +extern void * dhd_pno_get_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, void *info, + uint32 *len); +extern void dhd_pno_lock_batch_results(dhd_pub_t *dhd); +extern void dhd_pno_unlock_batch_results(dhd_pub_t *dhd); +extern int dhd_pno_initiate_gscan_request(dhd_pub_t *dhd, bool run, bool flush); +extern int dhd_pno_enable_full_scan_result(dhd_pub_t *dhd, bool real_time_flag); +extern int dhd_pno_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, void *buf); +extern int dhd_dev_retrieve_batch_scan(struct net_device *dev); +extern void *dhd_handle_swc_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes); +extern void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, + int *send_evt_bytes, hotlist_type_t type); +extern void *dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *event_data, + int *send_evt_bytes); +extern int dhd_gscan_batch_cache_cleanup(dhd_pub_t *dhd); +extern void dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type); +extern void dhd_wait_batch_results_complete(dhd_pub_t *dhd); +#endif /* GSCAN_SUPPORT */ +#endif + #endif /* __DHD_PNO_H__ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_proto.h b/drivers/net/wireless/bcmdhd/dhd_proto.h index a44eacffe921af3f9e190fb2b7c822fc130a77ec..87e0c83626f758c273a8bbae976771af4820c2e8 100644 --- a/drivers/net/wireless/bcmdhd/dhd_proto.h +++ b/drivers/net/wireless/bcmdhd/dhd_proto.h @@ -4,9 +4,27 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_proto.h 490409 2014-07-10 16:34:27Z $ + * $Id: dhd_proto.h 472193 2014-04-23 06:27:38Z $ */ #ifndef _dhd_proto_h_ @@ -18,8 +36,14 @@ #include <dhd_flowring.h> #endif +#define DEFAULT_IOCTL_RESP_TIMEOUT 2000 #ifndef IOCTL_RESP_TIMEOUT -#define IOCTL_RESP_TIMEOUT 2000 /* In milli second default value for Production FW */ +#ifdef BCMQT +#define IOCTL_RESP_TIMEOUT 30000 /* In milli second */ +#else +/* In milli second default value for Production FW */ +#define IOCTL_RESP_TIMEOUT DEFAULT_IOCTL_RESP_TIMEOUT +#endif /* BCMQT */ #endif /* IOCTL_RESP_TIMEOUT */ #ifndef MFG_IOCTL_RESP_TIMEOUT @@ -109,6 +133,7 @@ extern void dhd_prot_txdata_write_flush(dhd_pub_t *dhd, uint16 flow_id, bool in_ extern uint32 dhd_prot_txp_threshold(dhd_pub_t *dhd, bool set, uint32 val); extern void dhd_prot_clear(dhd_pub_t *dhd); + #endif /* BCMPCIE */ /******************************** diff --git a/drivers/net/wireless/bcmdhd/dhd_rtt.c b/drivers/net/wireless/bcmdhd/dhd_rtt.c new file mode 100644 index 0000000000000000000000000000000000000000..b96bf1cbda754a265b02ae4e31f878205758e650 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/dhd_rtt.c @@ -0,0 +1,693 @@ +/* + * Header file of Broadcom Dongle Host Driver (DHD) + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_rtt.c 423669 2014-07-01 13:01:55Z $ + */ +#include <typedefs.h> +#include <osl.h> + +#include <epivers.h> +#include <bcmutils.h> + +#include <bcmendian.h> +#include <linuxver.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/sort.h> +#include <dngl_stats.h> +#include <wlioctl.h> + +#include <proto/bcmevent.h> +#include <dhd.h> +#include <dhd_rtt.h> +#include <dhd_dbg.h> +#define GET_RTTSTATE(dhd) ((rtt_status_info_t *)dhd->rtt_state) +static DEFINE_SPINLOCK(noti_list_lock); +#define NULL_CHECK(p, s, err) \ + do { \ + if (!(p)) { \ + printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \ + err = BCME_ERROR; \ + return err; \ + } \ + } while (0) + +#define RTT_TWO_SIDED(capability) \ + do { \ + if((capability & RTT_CAP_ONE_WAY) == (uint8) (RTT_CAP_ONE_WAY)) \ + return FALSE; \ + else \ + return TRUE; \ + } while (0) +#define TIMESPEC_TO_US(ts) (((uint64)(ts).tv_sec * USEC_PER_SEC) + \ + (ts).tv_nsec / NSEC_PER_USEC) +struct rtt_noti_callback { + struct list_head list; + void *ctx; + dhd_rtt_compl_noti_fn noti_fn; +}; + +typedef struct rtt_status_info { + dhd_pub_t *dhd; + int8 status; /* current status for the current entry */ + int8 cur_idx; /* current entry to do RTT */ + int32 capability; /* rtt capability */ + struct mutex rtt_mutex; + rtt_config_params_t rtt_config; + struct work_struct work; + struct list_head noti_fn_list; + struct list_head rtt_results_cache; /* store results for RTT */ +} rtt_status_info_t; +static int dhd_rtt_start(dhd_pub_t *dhd); +chanspec_t +dhd_rtt_convert_to_chspec(wifi_channel_info_t channel) +{ + int bw; + /* set witdh to 20MHZ for 2.4G HZ */ + if (channel.center_freq >= 2400 && channel.center_freq <= 2500) { + channel.width = WIFI_CHAN_WIDTH_20; + } + switch (channel.width) { + case WIFI_CHAN_WIDTH_20: + bw = WL_CHANSPEC_BW_20; + break; + case WIFI_CHAN_WIDTH_40: + bw = WL_CHANSPEC_BW_40; + break; + case WIFI_CHAN_WIDTH_80: + bw = WL_CHANSPEC_BW_80; + break; + case WIFI_CHAN_WIDTH_160: + bw = WL_CHANSPEC_BW_160; + break; + default: + DHD_ERROR(("doesn't support this bandwith : %d", channel.width)); + bw = -1; + break; + } + return wf_channel2chspec(wf_mhz2channel(channel.center_freq, 0), bw); +} +int +dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params) +{ + int err = BCME_OK; + int idx; + rtt_status_info_t *rtt_status; + NULL_CHECK(params, "params is NULL", err); + + NULL_CHECK(dhd, "dhd is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + if (rtt_status->capability == RTT_CAP_NONE) { + DHD_ERROR(("doesn't support RTT \n")); + return BCME_ERROR; + } + if (rtt_status->status == RTT_STARTED) { + DHD_ERROR(("rtt is already started\n")); + return BCME_BUSY; + } + DHD_RTT(("%s enter\n", __FUNCTION__)); + bcopy(params, &rtt_status->rtt_config, sizeof(rtt_config_params_t)); + rtt_status->status = RTT_STARTED; + /* start to measure RTT from 1th device */ + /* find next target to trigger RTT */ + for (idx = rtt_status->cur_idx; idx < rtt_status->rtt_config.rtt_target_cnt; idx++) { + /* skip the disabled device */ + if (rtt_status->rtt_config.target_info[idx].disable) + continue; + else { + /*set the idx to cur_idx */ + rtt_status->cur_idx = idx; + break; + } + } + if (idx < rtt_status->rtt_config.rtt_target_cnt) { + DHD_RTT(("rtt_status->cur_idx : %d\n", rtt_status->cur_idx)); + schedule_work(&rtt_status->work); + } + return err; +} +int +dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt) +{ + int err = BCME_OK; + int i = 0, j = 0; + rtt_status_info_t *rtt_status; + + NULL_CHECK(dhd, "dhd is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + if (rtt_status->status == RTT_STOPPED) { + DHD_ERROR(("rtt is not started\n")); + return BCME_OK; + } + DHD_RTT(("%s enter\n", __FUNCTION__)); + mutex_lock(&rtt_status->rtt_mutex); + for (i = 0; i < mac_cnt; i++) { + for ( j = 0; j < rtt_status->rtt_config.rtt_target_cnt; j++) { + if (!bcmp(&mac_list[i],&rtt_status->rtt_config.target_info[j].addr, + ETHER_ADDR_LEN)) { + rtt_status->rtt_config.target_info[j].disable = TRUE; + } + } + } + mutex_unlock(&rtt_status->rtt_mutex); + return err; +} + +static int +dhd_rtt_start(dhd_pub_t *dhd) { + int err = BCME_OK; + int mpc = 0; + int nss, mcs, bw; + uint32 rspec = 0; + int8 eabuf[ETHER_ADDR_STR_LEN]; + int8 chanbuf[CHANSPEC_STR_LEN]; + bool set_mpc = FALSE; + wl_proxd_iovar_t proxd_iovar; + wl_proxd_params_iovar_t proxd_params; + wl_proxd_params_iovar_t proxd_tune; + wl_proxd_params_tof_method_t *tof_params = &proxd_params.u.tof_params; + rtt_status_info_t *rtt_status; + rtt_target_info_t *rtt_target; + NULL_CHECK(dhd, "dhd is NULL", err); + + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + /* turn off mpc in case of non-associted */ + if (!dhd_is_associated(dhd, NULL, NULL)) { + err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), 1); + if (err < 0) { + DHD_ERROR(("%s : failed to set proxd_tune\n", __FUNCTION__)); + goto exit; + } + set_mpc = TRUE; + } + + if (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt) { + err = BCME_RANGE; + goto exit; + } + DHD_RTT(("%s enter\n", __FUNCTION__)); + bzero(&proxd_tune, sizeof(proxd_tune)); + bzero(&proxd_params, sizeof(proxd_params)); + mutex_lock(&rtt_status->rtt_mutex); + /* Get a target information */ + rtt_target = &rtt_status->rtt_config.target_info[rtt_status->cur_idx]; + mutex_unlock(&rtt_status->rtt_mutex); + /* set role */ + proxd_iovar.method = PROXD_TOF_METHOD; + proxd_iovar.mode = WL_PROXD_MODE_INITIATOR; + + /* make sure that proxd is stop */ + //dhd_iovar(dhd, 0, "proxd_stop", (char *)NULL, 0, 1); + + err = dhd_iovar(dhd, 0, "proxd", (char *)&proxd_iovar, sizeof(proxd_iovar), 1); + if (err < 0 && err != BCME_BUSY) { + DHD_ERROR(("%s : failed to set proxd %d\n", __FUNCTION__, err)); + goto exit; + } + /* mac address */ + bcopy(&rtt_target->addr, &tof_params->tgt_mac, ETHER_ADDR_LEN); + /* frame count */ + if (rtt_target->ftm_cnt > RTT_MAX_FRAME_CNT) + rtt_target->ftm_cnt = RTT_MAX_FRAME_CNT; + + if (rtt_target->ftm_cnt) + tof_params->ftm_cnt = htol16(rtt_target->ftm_cnt); + else + tof_params->ftm_cnt = htol16(DEFAULT_FTM_CNT); + + if (rtt_target->retry_cnt > RTT_MAX_RETRY_CNT) + rtt_target->retry_cnt = RTT_MAX_RETRY_CNT; + + /* retry count */ + if (rtt_target->retry_cnt) + tof_params->retry_cnt = htol16(rtt_target->retry_cnt); + else + tof_params->retry_cnt = htol16(DEFAULT_RETRY_CNT); + + /* chanspec */ + tof_params->chanspec = htol16(rtt_target->chanspec); + /* set parameter */ + DHD_RTT(("Target addr(Idx %d) %s, Channel : %s for RTT (ftm_cnt %d, rety_cnt : %d)\n", + rtt_status->cur_idx, + bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf), + wf_chspec_ntoa(rtt_target->chanspec, chanbuf), rtt_target->ftm_cnt, + rtt_target->retry_cnt)); + + if (rtt_target->type == RTT_ONE_WAY) { + proxd_tune.u.tof_tune.flags = htol32(WL_PROXD_FLAG_ONEWAY); + /* report RTT results for initiator */ + proxd_tune.u.tof_tune.flags |= htol32(WL_PROXD_FLAG_INITIATOR_RPTRTT); + proxd_tune.u.tof_tune.vhtack = 0; + tof_params->tx_rate = htol16(WL_RATE_6M); + tof_params->vht_rate = htol16((WL_RATE_6M >> 16)); + } else { /* RTT TWO WAY */ + /* initiator will send the rtt result to the target */ + proxd_tune.u.tof_tune.flags = htol32(WL_PROXD_FLAG_INITIATOR_REPORT); + tof_params->timeout = 10; /* 10ms for timeout */ + rspec = WL_RSPEC_ENCODE_VHT; /* 11ac VHT */ + /* TODO : need to find a way to set nss and mcs */ + nss = 1; /* default Nss = 1 */ + mcs = 0; /* default MCS 0 */ + rspec |= (nss << WL_RSPEC_VHT_NSS_SHIFT) | mcs; + bw = 0; + switch (CHSPEC_BW(rtt_target->chanspec)) { + case WL_CHANSPEC_BW_20: + bw = WL_RSPEC_BW_20MHZ; + break; + case WL_CHANSPEC_BW_40: + bw = WL_RSPEC_BW_40MHZ; + break; + case WL_CHANSPEC_BW_80: + bw = WL_RSPEC_BW_80MHZ; + break; + case WL_CHANSPEC_BW_160: + bw = WL_RSPEC_BW_160MHZ; + break; + } + rspec |= bw; + tof_params->tx_rate = htol16(rspec & 0xffff); + tof_params->vht_rate = htol16(rspec >> 16); + } + + /* Set Method to TOF */ + proxd_tune.method = PROXD_TOF_METHOD; + err = dhd_iovar(dhd, 0, "proxd_tune", (char *)&proxd_tune, sizeof(proxd_tune), 1); + if (err < 0) { + DHD_ERROR(("%s : failed to set proxd_tune %d\n", __FUNCTION__, err)); + goto exit; + } + + /* Set Method to TOF */ + proxd_params.method = PROXD_TOF_METHOD; + err = dhd_iovar(dhd, 0, "proxd_params", (char *)&proxd_params, sizeof(proxd_params), 1); + if (err < 0) { + DHD_ERROR(("%s : failed to set proxd_params %d\n", __FUNCTION__, err)); + goto exit; + } + err = dhd_iovar(dhd, 0, "proxd_find", (char *)NULL, 0, 1); + if (err < 0) { + DHD_ERROR(("%s : failed to set proxd_find %d\n", __FUNCTION__, err)); + goto exit; + } +exit: + if (err < 0) { + rtt_status->status = RTT_STOPPED; + if (set_mpc) { + /* enable mpc again in case of error */ + mpc = 1; + err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), 1); + } + } + return err; +} +int +dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn) +{ + int err = BCME_OK; + struct rtt_noti_callback *cb = NULL, *iter; + rtt_status_info_t *rtt_status; + NULL_CHECK(dhd, "dhd is NULL", err); + NULL_CHECK(noti_fn, "noti_fn is NULL", err); + + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + spin_lock_bh(¬i_list_lock); + list_for_each_entry(iter, &rtt_status->noti_fn_list, list) + if (iter->noti_fn == noti_fn) { + goto exit; + } + cb = kmalloc(sizeof(struct rtt_noti_callback), GFP_ATOMIC); + if (!cb) { + err = -ENOMEM; + goto exit; + } + cb->noti_fn = noti_fn; + cb->ctx = ctx; + list_add(&cb->list, &rtt_status->noti_fn_list); +exit: + spin_unlock_bh(¬i_list_lock); + return err; +} + +int +dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn) +{ + int err = BCME_OK; + struct rtt_noti_callback *cb = NULL, *iter; + rtt_status_info_t *rtt_status; + NULL_CHECK(dhd, "dhd is NULL", err); + NULL_CHECK(noti_fn, "noti_fn is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + spin_lock_bh(¬i_list_lock); + list_for_each_entry(iter, &rtt_status->noti_fn_list, list) + if (iter->noti_fn == noti_fn) { + cb = iter; + list_del(&cb->list); + break; + } + spin_unlock_bh(¬i_list_lock); + if (cb) { + kfree(cb); + } + return err; +} +static int +dhd_rtt_convert_to_host(rtt_result_t *rtt_results, const wl_proxd_event_data_t* evp) +{ + int err = BCME_OK; + int i; + char eabuf[ETHER_ADDR_STR_LEN]; + char diststr[40]; + struct timespec ts; + NULL_CHECK(rtt_results, "rtt_results is NULL", err); + NULL_CHECK(evp, "evp is NULL", err); + DHD_RTT(("%s enter\n", __FUNCTION__)); + rtt_results->distance = ntoh32(evp->distance); + rtt_results->sdrtt = ntoh32(evp->sdrtt); + rtt_results->ftm_cnt = ntoh16(evp->ftm_cnt); + rtt_results->avg_rssi = ntoh16(evp->avg_rssi); + rtt_results->validfrmcnt = ntoh16(evp->validfrmcnt); + rtt_results->meanrtt = ntoh32(evp->meanrtt); + rtt_results->modertt = ntoh32(evp->modertt); + rtt_results->medianrtt = ntoh32(evp->medianrtt); + rtt_results->err_code = evp->err_code; + rtt_results->tx_rate.preamble = (evp->OFDM_frame_type == TOF_FRAME_RATE_VHT)? 3 : 0; + rtt_results->tx_rate.nss = 0; /* 1 x 1 */ + rtt_results->tx_rate.bw = (evp->bandwidth == TOF_BW_80MHZ)? 2 : (evp->bandwidth == TOF_BW_40MHZ)? 1 : 0; + rtt_results->TOF_type = evp->TOF_type; + if (evp->TOF_type == TOF_TYPE_ONE_WAY) { + /* convert to 100kbps unit */ + rtt_results->tx_rate.bitrate = WL_RATE_6M * 5; + rtt_results->tx_rate.rateMcsIdx = WL_RATE_6M; + } else { + /* TODO : check tx rate for two way */ + rtt_results->tx_rate.bitrate = WL_RATE_6M * 5; + rtt_results->tx_rate.rateMcsIdx = 0; /* MCS 0 */ + } + memset(diststr, 0, sizeof(diststr)); + if (rtt_results->distance == 0xffffffff || rtt_results->distance == 0) + sprintf(diststr, "distance=-1m\n"); + else + sprintf(diststr, "distance=%d.%d m\n", rtt_results->distance>>4, ((rtt_results->distance&0xf)*125)>>1); + + + if (ntoh32(evp->mode) == WL_PROXD_MODE_INITIATOR) { + DHD_RTT(("Target:(%s) %s;\n", bcm_ether_ntoa((&evp->peer_mac), eabuf), diststr)); + DHD_RTT(("RTT : mean %d mode %d median %d\n", rtt_results->meanrtt, + rtt_results->modertt, rtt_results->medianrtt)); + } + else { + DHD_RTT(("Initiator:(%s) %s; ", bcm_ether_ntoa((&evp->peer_mac), eabuf), diststr)); + } + if (rtt_results->sdrtt > 0) + DHD_RTT(("sigma:%d.%d\n", rtt_results->sdrtt/10, rtt_results->sdrtt % 10)); + else + DHD_RTT(("sigma:0\n")); + + DHD_RTT(("rssi:%d validfrmcnt %d, err_code : %d\n", rtt_results->avg_rssi, + rtt_results->validfrmcnt, evp->err_code)); + + switch (evp->err_code) { + case TOF_REASON_OK: + rtt_results->err_code = RTT_REASON_SUCCESS; + break; + case TOF_REASON_TIMEOUT: + rtt_results->err_code = RTT_REASON_TIMEOUT; + break; + case TOF_REASON_NOACK: + rtt_results->err_code = RTT_REASON_NO_RSP; + break; + case TOF_REASON_ABORT: + rtt_results->err_code = RTT_REASON_ABORT; + break; + default: + rtt_results->err_code = RTT_REASON_FAILURE; + break; + } + rtt_results->peer_mac = evp->peer_mac; + /* get the time elapsed from boot time */ + get_monotonic_boottime(&ts); + rtt_results->ts = (uint64) TIMESPEC_TO_US(ts); + + for (i = 0; i < rtt_results->ftm_cnt; i++) { + rtt_results->ftm_buff[i].value = ltoh32(evp->ftm_buff[i].value); + rtt_results->ftm_buff[i].rssi = ltoh32(evp->ftm_buff[i].rssi); + } + return err; +} +int +dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) +{ + int err = BCME_OK; + int len = 0; + int idx; + uint status, event_type, flags, reason, ftm_cnt; + rtt_status_info_t *rtt_status; + wl_proxd_event_data_t* evp; + struct rtt_noti_callback *iter; + rtt_result_t *rtt_result, *entry, *next; + gfp_t kflags; + NULL_CHECK(dhd, "dhd is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + event_type = ntoh32_ua((void *)&event->event_type); + flags = ntoh16_ua((void *)&event->flags); + status = ntoh32_ua((void *)&event->status); + reason = ntoh32_ua((void *)&event->reason); + + if (event_type != WLC_E_PROXD) { + goto exit; + } + kflags = in_softirq()? GFP_ATOMIC : GFP_KERNEL; + evp = (wl_proxd_event_data_t*)event_data; + DHD_RTT(("%s enter : mode: %s, reason :%d \n", __FUNCTION__, + (ntoh16(evp->mode) == WL_PROXD_MODE_INITIATOR)? + "initiator":"target", reason)); + switch (reason) { + case WLC_E_PROXD_STOP: + DHD_RTT(("WLC_E_PROXD_STOP\n")); + break; + case WLC_E_PROXD_ERROR: + case WLC_E_PROXD_COMPLETED: + if (reason == WLC_E_PROXD_ERROR) { + DHD_RTT(("WLC_E_PROXD_ERROR\n")); + } else { + DHD_RTT(("WLC_E_PROXD_COMPLETED\n")); + } + + if(!in_atomic()) + mutex_lock(&rtt_status->rtt_mutex); + ftm_cnt = ltoh16(evp->ftm_cnt); + + if (ftm_cnt > 0) + len = OFFSETOF(rtt_result_t, ftm_buff); + else + len = sizeof(rtt_result_t); + /* check whether the results is already reported or not*/ + list_for_each_entry(entry, &rtt_status->rtt_results_cache, list) { + if (!memcmp(&entry->peer_mac, &evp->peer_mac, ETHER_ADDR_LEN)) { + if(!in_atomic()) + mutex_unlock(&rtt_status->rtt_mutex); + goto exit; + } + } + rtt_result = kzalloc(len + sizeof(ftm_sample_t) * ftm_cnt, kflags); + if (!rtt_result) { + if(!in_atomic()) + mutex_unlock(&rtt_status->rtt_mutex); + err = -ENOMEM; + goto exit; + } + /* point to target_info in status struct and increase pointer */ + rtt_result->target_info = &rtt_status->rtt_config.target_info[rtt_status->cur_idx]; + /* find next target to trigger RTT */ + for (idx = (rtt_status->cur_idx + 1); idx < rtt_status->rtt_config.rtt_target_cnt; idx++) { + /* skip the disabled device */ + if (rtt_status->rtt_config.target_info[idx].disable) + continue; + else { + /*set the idx to cur_idx */ + rtt_status->cur_idx = idx; + break; + } + } + /* convert the event results to host format */ + dhd_rtt_convert_to_host(rtt_result, evp); + list_add_tail(&rtt_result->list, &rtt_status->rtt_results_cache); + if (idx < rtt_status->rtt_config.rtt_target_cnt) { + /* restart to measure RTT from next device */ + schedule_work(&rtt_status->work); + } else { + DHD_RTT(("RTT_STOPPED\n")); + rtt_status->status = RTT_STOPPED; + /* to turn on mpc mode */ + schedule_work(&rtt_status->work); + /* notify the completed information to others */ + list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { + iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache); + } + /* remove the rtt results in cache */ + list_for_each_entry_safe(rtt_result, next, + &rtt_status->rtt_results_cache, list) { + list_del(&rtt_result->list); + kfree(rtt_result); + } + /* reinit the HEAD */ + INIT_LIST_HEAD(&rtt_status->rtt_results_cache); + /* clear information for rtt_config */ + bzero(&rtt_status->rtt_config, sizeof(rtt_config_params_t)); + rtt_status->cur_idx = 0; + } + if(!in_atomic()) + mutex_unlock(&rtt_status->rtt_mutex); + + break; + case WLC_E_PROXD_GONE: + DHD_RTT(("WLC_E_PROXD_GONE\n")); + break; + case WLC_E_PROXD_START: + /* event for targets / accesspoints */ + DHD_RTT(("WLC_E_PROXD_START\n")); + break; + case WLC_E_PROXD_COLLECT_START: + DHD_RTT(("WLC_E_PROXD_COLLECT_START\n")); + break; + case WLC_E_PROXD_COLLECT_STOP: + DHD_RTT(("WLC_E_PROXD_COLLECT_STOP\n")); + break; + case WLC_E_PROXD_COLLECT_COMPLETED: + DHD_RTT(("WLC_E_PROXD_COLLECT_COMPLETED\n")); + break; + case WLC_E_PROXD_COLLECT_ERROR: + DHD_RTT(("WLC_E_PROXD_COLLECT_ERROR; ")); + break; + default: + DHD_ERROR(("WLC_E_PROXD: supported EVENT reason code:%d\n", reason)); + break; + } + +exit: + return err; +} +static void +dhd_rtt_work(struct work_struct *work) +{ + rtt_status_info_t *rtt_status; + dhd_pub_t *dhd; + rtt_status = container_of(work, rtt_status_info_t, work); + if (rtt_status == NULL) { + DHD_ERROR(("%s : rtt_status is NULL\n", __FUNCTION__)); + return; + } + dhd = rtt_status->dhd; + if (dhd == NULL) { + DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__)); + return; + } + dhd_rtt_start(dhd); +} + +int +dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa) +{ + rtt_status_info_t *rtt_status; + int err = BCME_OK; + NULL_CHECK(dhd, "dhd is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + NULL_CHECK(capa, "capa is NULL", err); + bzero(capa, sizeof(rtt_capabilities_t)); + + if (rtt_status->capability & RTT_CAP_ONE_WAY) + capa->rtt_one_sided_supported = 1; + if (rtt_status->capability & RTT_CAP_11V_WAY) + capa->rtt_11v_supported = 1; + if (rtt_status->capability & RTT_CAP_11MC_WAY) + capa->rtt_ftm_supported = 1; + if (rtt_status->capability & RTT_CAP_VS_WAY) + capa->rtt_vs_supported = 1; + + return err; +} +int +dhd_rtt_init(dhd_pub_t *dhd) +{ + int err = BCME_OK; + rtt_status_info_t *rtt_status; + NULL_CHECK(dhd, "dhd is NULL", err); + if (dhd->rtt_state) + goto exit; + dhd->rtt_state = MALLOC(dhd->osh, sizeof(rtt_status_info_t)); + if (dhd->rtt_state == NULL) { + DHD_ERROR(("failed to create rtt_state\n")); + goto exit; + } + bzero(dhd->rtt_state, sizeof(rtt_status_info_t)); + rtt_status = GET_RTTSTATE(dhd); + rtt_status->dhd = dhd; + err = dhd_iovar(dhd, 0, "proxd_params", NULL, 0, 1); + if (err != BCME_UNSUPPORTED) { + /* TODO : need to find a way to check rtt capability */ + rtt_status->capability |= RTT_CAP_ONE_WAY; + rtt_status->capability |= RTT_CAP_VS_WAY; + } + mutex_init(&rtt_status->rtt_mutex); + INIT_LIST_HEAD(&rtt_status->noti_fn_list); + INIT_LIST_HEAD(&rtt_status->rtt_results_cache); + INIT_WORK(&rtt_status->work, dhd_rtt_work); +exit: + return err; +} + +int dhd_rtt_deinit(dhd_pub_t *dhd) +{ + int err = BCME_OK; + rtt_status_info_t *rtt_status; + rtt_result_t *rtt_result, *next; + struct rtt_noti_callback *iter, *iter2; + NULL_CHECK(dhd, "dhd is NULL", err); + rtt_status = GET_RTTSTATE(dhd); + NULL_CHECK(rtt_status, "rtt_status is NULL", err); + rtt_status->status = RTT_STOPPED; + /* clear evt callback list */ + if (!list_empty(&rtt_status->noti_fn_list)) { + list_for_each_entry_safe(iter, iter2, &rtt_status->noti_fn_list, list) { + list_del(&iter->list); + kfree(iter); + } + } + /* remove the rtt results */ + if (!list_empty(&rtt_status->rtt_results_cache)) { + list_for_each_entry_safe(rtt_result, next, &rtt_status->rtt_results_cache, list) { + list_del(&rtt_result->list); + kfree(rtt_result); + } + } + MFREE(dhd->osh, dhd->rtt_state, sizeof(rtt_status_info_t)); + dhd->rtt_state = NULL; + return err; +} diff --git a/drivers/net/wireless/bcmdhd/dhd_rtt.h b/drivers/net/wireless/bcmdhd/dhd_rtt.h new file mode 100644 index 0000000000000000000000000000000000000000..7fb883c75b767e97c1af04893852194900ea60a6 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/dhd_rtt.h @@ -0,0 +1,232 @@ +/* + * Header file of Broadcom Dongle Host Driver (DHD) + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_rtt.h 423669 2014-07-01 13:01:56Z $ + */ +#ifndef __DHD_RTT_H__ +#define __DHD_RTT_H__ + +#include "dngl_stats.h" + +#define RTT_MAX_TARGET_CNT 10 +#define RTT_MAX_FRAME_CNT 25 +#define RTT_MAX_RETRY_CNT 10 +#define DEFAULT_FTM_CNT 6 +#define DEFAULT_RETRY_CNT 6 + + +/* DSSS, CCK and 802.11n rates in [500kbps] units */ +#define WL_MAXRATE 108 /* in 500kbps units */ +#define WL_RATE_1M 2 /* in 500kbps units */ +#define WL_RATE_2M 4 /* in 500kbps units */ +#define WL_RATE_5M5 11 /* in 500kbps units */ +#define WL_RATE_11M 22 /* in 500kbps units */ +#define WL_RATE_6M 12 /* in 500kbps units */ +#define WL_RATE_9M 18 /* in 500kbps units */ +#define WL_RATE_12M 24 /* in 500kbps units */ +#define WL_RATE_18M 36 /* in 500kbps units */ +#define WL_RATE_24M 48 /* in 500kbps units */ +#define WL_RATE_36M 72 /* in 500kbps units */ +#define WL_RATE_48M 96 /* in 500kbps units */ +#define WL_RATE_54M 108 /* in 500kbps units */ + + +enum rtt_role { + RTT_INITIATOR = 0, + RTT_TARGET = 1 +}; +enum rtt_status { + RTT_STOPPED = 0, + RTT_STARTED = 1 +}; +typedef int64_t wifi_timestamp; /* In microseconds (us) */ +typedef int64_t wifi_timespan; +typedef int wifi_rssi; + +typedef enum { + RTT_INVALID, + RTT_ONE_WAY, + RTT_TWO_WAY, + RTT_AUTO +} rtt_type_t; + +typedef enum { + RTT_PEER_STA, + RTT_PEER_AP, + RTT_PEER_P2P, + RTT_PEER_NAN, + RTT_PEER_INVALID +} rtt_peer_type_t; + +typedef enum rtt_reason { + RTT_REASON_SUCCESS, + RTT_REASON_FAILURE, + RTT_REASON_NO_RSP, + RTT_REASON_REJECTED, + RTT_REASON_NOT_SCHEDULED_YET, + RTT_REASON_TIMEOUT, + RTT_REASON_AP_ON_DIFF_CH, + RTT_REASON_AP_NO_CAP, + RTT_REASON_ABORT +} rtt_reason_t; + +typedef enum rtt_capability { + RTT_CAP_NONE = 0, + RTT_CAP_ONE_WAY = (1 << (0)), + RTT_CAP_11V_WAY = (1 << (1)), /* IEEE802.11v */ + RTT_CAP_11MC_WAY = (1 << (2)), /* IEEE802.11mc */ + RTT_CAP_VS_WAY = (1 << (3)) /* BRCM vendor specific */ +} rtt_capability_t ; + +typedef struct wifi_channel_info { + wifi_channel_width_t width; + wifi_channel center_freq; /* primary 20 MHz channel */ + wifi_channel center_freq0; /* center freq (MHz) first segment */ + wifi_channel center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */ +} wifi_channel_info_t; + +typedef struct wifi_rate { + uint32 preamble :3; /* 0: OFDM, 1: CCK, 2 : HT, 3: VHT, 4..7 reserved */ + uint32 nss :2; /* 0 : 1x1, 1: 2x2, 3: 3x3, 4: 4x4 */ + uint32 bw :3; /* 0: 20Mhz, 1: 40Mhz, 2: 80Mhz, 3: 160Mhz */ + /* OFDM/CCK rate code would be as per IEEE std in the unit of 0.5 mb + * HT/VHT it would be mcs index + */ + uint32 rateMcsIdx :8; + uint32 reserved :16; /* reserved */ + uint32 bitrate; /* unit of 100 Kbps */ +} wifi_rate_t; + +typedef struct rtt_target_info { + struct ether_addr addr; + rtt_type_t type; /* rtt_type */ + rtt_peer_type_t peer; /* peer type */ + wifi_channel_info_t channel; /* channel information */ + chanspec_t chanspec; /* chanspec for channel */ + int8 continuous; /* 0 = single shot or 1 = continous raging */ + bool disable; /* disable for RTT measurement */ + uint32 interval; /* interval of RTT measurement (unit ms) when continuous = true */ + uint32 measure_cnt; /* total number of RTT measurement when continuous */ + uint32 ftm_cnt; /* num of packets in each RTT measurement */ + uint32 retry_cnt; /* num of retries if sampling fails */ +} rtt_target_info_t; + +typedef struct rtt_result { + struct list_head list; + uint16 ver; /* version */ + rtt_target_info_t *target_info; /* target info */ + uint16 mode; /* mode: target/initiator */ + uint16 method; /* method: rssi/TOF/AOA */ + uint8 err_code; /* error classification */ + uint8 TOF_type; /* one way or two way TOF */ + wifi_rate_t tx_rate; /* tx rate */ + struct ether_addr peer_mac; /* (e.g for tgt:initiator's */ + int32 distance; /* dst to tgt, units (meter * 16) */ + uint32 meanrtt; /* mean delta */ + uint32 modertt; /* Mode delta */ + uint32 medianrtt; /* median RTT */ + uint32 sdrtt; /* Standard deviation of RTT */ + int16 avg_rssi; /* avg rssi across the ftm frames */ + int16 validfrmcnt; /* Firmware's valid frame counts */ + wifi_timestamp ts; /* the time elapsed from boot time when driver get this result */ + uint16 ftm_cnt; /* num of rtd measurments/length in the ftm buffer */ + ftm_sample_t ftm_buff[1]; /* 1 ... ftm_cnt */ +} rtt_result_t; + +typedef struct rtt_report { + struct ether_addr addr; + uint num_measurement; /* measurement number in case of continous raging */ + rtt_reason_t status; /* raging status */ + rtt_type_t type; /* rtt type */ + rtt_peer_type_t peer; /* peer type */ + wifi_channel_info_t channel; /* channel information */ + wifi_rssi rssi; /* avg rssi accroos the ftm frames */ + wifi_rssi rssi_spread; /* rssi spread in 0.5 db steps e.g. 5 implies 2.5 spread */ + wifi_rate_t tx_rate; /* tx rate */ + wifi_timespan rtt; /* round trip time in nanoseconds */ + wifi_timespan rtt_sd; /* rtt standard deviation in nanoseconds */ + wifi_timespan rtt_spread; /* difference between max and min rtt times recorded */ + int32 distance; /* distance in cm (optional) */ + int32 distance_sd; /* standard deviation in cm (optional) */ + int32 distance_spread;/* difference between max and min distance recorded (optional) */ + wifi_timestamp ts; /* time of the measurement (in microseconds since boot) */ +} rtt_report_t; + +/* RTT Capabilities */ +typedef struct rtt_capabilities{ + uint8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ + uint8 rtt_11v_supported; /* if 11v rtt data collection is supported */ + uint8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ + uint8 rtt_vs_supported; /* if vendor specific data collection is supported */ +} rtt_capabilities_t; + +typedef struct rtt_config_params { + int8 rtt_target_cnt; + rtt_target_info_t target_info[RTT_MAX_TARGET_CNT]; +} rtt_config_params_t; + +typedef void (*dhd_rtt_compl_noti_fn)(void *ctx, void *rtt_data); +/* Linux wrapper to call common dhd_rtt_set_cfg */ +int +dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf); + +int +dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt); + +int +dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx, dhd_rtt_compl_noti_fn noti_fn); + +int +dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn); + +int +dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa); + +/* export to upper layer */ +chanspec_t +dhd_rtt_convert_to_chspec(wifi_channel_info_t channel); + +int +dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params); + +int +dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt); + + +int +dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn); + +int +dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn); + +int +dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data); + +int +dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa); + +int +dhd_rtt_init(dhd_pub_t *dhd); + +int +dhd_rtt_deinit(dhd_pub_t *dhd); +#endif diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index 34dc4cdf5383c51ce4b58658ac844b7abe8adbf0..a96006c2dd2a923743411184e0a3c020c779d9a8 100644 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -1,9 +1,27 @@ /* * DHD Bus Module for SDIO * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: dhd_sdio.c 489913 2014-07-08 18:57:48Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dhd_sdio.c 476991 2014-05-12 06:21:02Z $ */ #include <typedefs.h> @@ -146,11 +164,6 @@ extern bool bcmsdh_fatal_error(void *sdh); PKTFREE(bus->dhd->osh, pkt, FALSE); DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -DEFINE_MUTEX(_dhd_sdio_mutex_lock_); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -#endif #ifdef DHD_DEBUG /* Device console log buffer state */ @@ -692,12 +705,12 @@ dhdsdio_sr_cap(dhd_bus_t *bus) bool cap = FALSE; uint32 core_capext, addr, data; + if (BCM4349_CHIP(bus->sih->chip)) { + /* For now SR capability would not be exercised */ + return cap; + } if (bus->sih->chip == BCM43430_CHIP_ID) { - /* check if fw initialized sr engine */ - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, sr_control1); - if (bcmsdh_reg_read(bus->sdh, addr, 4) != 0) - cap = TRUE; - + /* For now SR capability would not be exercised */ return cap; } if (bus->sih->chip == BCM4324_CHIP_ID) { @@ -714,7 +727,6 @@ dhdsdio_sr_cap(dhd_bus_t *bus) (bus->sih->chip == BCM4354_CHIP_ID) || (bus->sih->chip == BCM4356_CHIP_ID) || (bus->sih->chip == BCM4358_CHIP_ID) || - (BCM4349_CHIP(bus->sih->chip)) || (bus->sih->chip == BCM4350_CHIP_ID)) { core_capext = TRUE; } else { @@ -763,9 +775,7 @@ dhdsdio_sr_cap(dhd_bus_t *bus) static int dhdsdio_srwar_init(dhd_bus_t *bus) { -#if !defined(NDISVER) || (NDISVER < 0x0630) bcmsdh_gpio_init(bus->sdh); -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ #ifdef USE_OOB_GPIO1 dhdsdio_oobwakeup_init(bus); @@ -996,9 +1006,7 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) err = dhdsdio_clk_kso_enab(bus, FALSE); if (OOB_WAKEUP_ENAB(bus)) { -#if !defined(NDISVER) || (NDISVER < 0x0630) err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, FALSE); /* GPIO_1 is off */ -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ } #endif /* USE_CMD14 */ } else { @@ -1008,7 +1016,6 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) DHD_TRACE(("%s: Request SD clk\n", __FUNCTION__)); dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); } -#if !defined(NDISVER) || (NDISVER < 0x0630) if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) { SPINWAIT_SLEEP(sdioh_spinwait_sleep, @@ -1019,7 +1026,6 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) DHD_ERROR(("ERROR: GPIO_DEV_SRSTATE still low!\n")); } } -#endif #ifdef USE_CMD14 err = bcmsdh_sleep(bus->sdh, FALSE); if (SLPAUTO_ENAB(bus) && (err != 0)) { @@ -1050,9 +1056,7 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) #else if (OOB_WAKEUP_ENAB(bus)) { -#if !defined(NDISVER) || (NDISVER < 0x0630) err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, TRUE); /* GPIO_1 is on */ -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ } do { err = dhdsdio_clk_kso_enab(bus, TRUE); @@ -1546,7 +1550,7 @@ dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); #endif /* !defined(HW_OOB) */ } -#endif +#endif int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) @@ -1599,7 +1603,7 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt) for (i = 0; i < (datalen - 4); i++) { DHD_ERROR(("%02X ", dump_data[i])); if ((i & 15) == 15) - printf("\n"); + printk("\n"); } DHD_ERROR(("\n")); } @@ -2800,9 +2804,6 @@ dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) int rv, i; uint32 shaddr = 0; - if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID && !dhdsdio_sr_cap(bus)) - bus->srmemsize = 0; - shaddr = bus->dongle_ram_base + bus->ramsize - 4; i = 0; do { @@ -3224,7 +3225,7 @@ dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) return (int_val & uart_enab); } -#endif +#endif static int dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, @@ -3283,7 +3284,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhdsdio_bussleep(bus, bool_val); } else { int_val = (int32)bus->sleeping; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); } goto exit; } @@ -3297,7 +3298,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch switch (actionid) { case IOV_GVAL(IOV_INTR): int_val = (int32)bus->intr; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_INTR): @@ -3316,7 +3317,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_POLLRATE): int_val = (int32)bus->pollrate; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_POLLRATE): @@ -3326,7 +3327,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_IDLETIME): int_val = bus->idletime; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_IDLETIME): @@ -3339,7 +3340,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_IDLECLOCK): int_val = (int32)bus->idleclock; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_IDLECLOCK): @@ -3348,7 +3349,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_SD1IDLE): int_val = (int32)sd1idle; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_SD1IDLE): @@ -3447,17 +3448,17 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_RAMSIZE): int_val = (int32)bus->ramsize; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_RAMSTART): int_val = (int32)bus->dongle_ram_base; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_SDIOD_DRIVE): int_val = (int32)dhd_sdiod_drive_strength; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_SDIOD_DRIVE): @@ -3479,7 +3480,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_READAHEAD): int_val = (int32)dhd_readahead; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_READAHEAD): @@ -3490,7 +3491,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_SDRXCHAIN): int_val = (int32)bus->use_rxchain; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_SDRXCHAIN): @@ -3501,7 +3502,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch break; case IOV_GVAL(IOV_ALIGNCTL): int_val = (int32)dhd_alignctl; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_ALIGNCTL): @@ -3510,7 +3511,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_SDALIGN): int_val = DHD_SDALIGN; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; #ifdef DHD_DEBUG @@ -3601,7 +3602,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_FORCEEVEN): int_val = (int32)forcealign; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_FORCEEVEN): @@ -3610,7 +3611,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_TXBOUND): int_val = (int32)dhd_txbound; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_TXBOUND): @@ -3619,7 +3620,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_RXBOUND): int_val = (int32)dhd_rxbound; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_RXBOUND): @@ -3628,7 +3629,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_TXMINMAX): int_val = (int32)dhd_txminmax; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_TXMINMAX): @@ -3640,7 +3641,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch if (bcmerror != 0) break; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_SERIALCONS): @@ -3654,7 +3655,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch #ifdef SDTEST case IOV_GVAL(IOV_EXTLOOP): int_val = (int32)bus->ext_loop; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_EXTLOOP): @@ -3673,7 +3674,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch #if defined(USE_SDIOFIFO_IOVAR) case IOV_GVAL(IOV_WATERMARK): int_val = (int32)watermark; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_WATERMARK): @@ -3685,7 +3686,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_MESBUSYCTRL): int_val = (int32)mesbusyctrl; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_MESBUSYCTRL): @@ -3696,12 +3697,12 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, ((uint8)mesbusyctrl | 0x80), NULL); break; -#endif +#endif case IOV_GVAL(IOV_DONGLEISOLATION): int_val = bus->dhd->dongle_isolation; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DONGLEISOLATION): @@ -3728,18 +3729,18 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch /* Get its status */ int_val = (bool) bus->dhd->dongle_reset; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_KSO): int_val = dhdsdio_sleepcsr_get(bus); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_DEVCAP): int_val = dhdsdio_devcap_get(bus); - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_DEVCAP): @@ -3747,7 +3748,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch break; case IOV_GVAL(IOV_TXGLOMSIZE): int_val = (int32)bus->txglomsize; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_TXGLOMSIZE): @@ -3764,12 +3765,12 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_GVAL(IOV_HANGREPORT): int_val = (int32)bus->dhd->hang_report; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_GVAL(IOV_TXINRX_THRES): int_val = bus->txinrx_thres; - bcopy(&int_val, arg, val_size); + bcopy(&int_val, arg, sizeof(int_val)); break; case IOV_SVAL(IOV_TXINRX_THRES): if (int_val < 0) { @@ -3943,11 +3944,6 @@ dhdsdio_download_state(dhd_bus_t *bus, bool enter) if (REMAP_ENAB(bus) && si_socdevram_remap_isenb(bus->sih)) dhdsdio_devram_remap(bus, FALSE); - if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID) { - /* Disabling Remap for SRAM_3 */ - si_socram_set_bankpda(bus->sih, 0x3, 0x0); - } - /* Clear the top bit of memory */ if (bus->ramsize) { uint32 zeros = 0; @@ -4222,9 +4218,7 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Turn off the bus (F2), free any pending packets */ DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); -#if !defined(NDISVER) || (NDISVER < 0x0630) bcmsdh_intr_disable(bus->sdh); -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); /* Clear any pending interrupts now that F2 is disabled */ @@ -5042,6 +5036,33 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) } +#ifdef SDHOST3 +static bool +dhdsdio_pr94636_WAR(dhd_bus_t *bus) +{ + uint cd = 0; + uint ld = 0; + int bcmerror = 0; + uint32 l_data[5]; + uint32 l_addr = (0x18002200 & SBSDIO_SB_OFT_ADDR_MASK); + + /* Read 20 bytes from 0x18002200 + * the sdiod Tx DMA registers address on AI Backplane. + */ + if ((bcmerror = bcmsdh_rwdata(bus->sdh, FALSE, l_addr, (uint8 *)&l_data[0], 20))) { + DHD_ERROR(("%s: bcmsdh_rwdata failed\n", __FUNCTION__)); + return FALSE; + } + ld = l_data[1]; + ld = ld & 0x00001fff; + cd = l_data[4]; + cd = cd & 0x00001fff; + if (cd == ld) + return TRUE; + else + return FALSE; +} +#endif /* SDHOST3 */ /* Return TRUE if there may be more frames to read */ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) @@ -5409,6 +5430,17 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (bus->bus == SPI_BUS) { break; } +#ifdef SDHOST3 + if (((((uint16)bus->sih->chip) == BCM4324_CHIP_ID) && (bus->sih->chiprev <= 1)) || + (((uint16)bus->sih->chip) == BCM43340_CHIP_ID) || + (((uint16)bus->sih->chip) == BCM43341_CHIP_ID) || + (((uint16)bus->sih->chip) == BCM4334_CHIP_ID)) { + if (dhdsdio_pr94636_WAR(bus) == TRUE) { + *finished = TRUE; + break; + } + } +#endif /* SDHOST3 */ /* Read frame header (hardware and software) */ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, @@ -5964,9 +5996,7 @@ clkwait: #if defined(OOB_INTR_ONLY) bcmsdh_oob_intr_set(bus->sdh, TRUE); #endif /* defined(OOB_INTR_ONLY) */ -#if !defined(NDISVER) || (NDISVER < 0x0630) bcmsdh_intr_enable(sdh); -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ } #if defined(OOB_INTR_ONLY) && !defined(HW_OOB) @@ -6098,9 +6128,7 @@ dhdsdio_isr(void *arg) DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n")); } -#if !defined(NDISVER) || (NDISVER < 0x0630) bcmsdh_intr_disable(sdh); -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ bus->intdis = TRUE; #if defined(SDIO_ISR_THREAD) @@ -6110,10 +6138,8 @@ dhdsdio_isr(void *arg) DHD_OS_WAKE_UNLOCK(bus->dhd); #else -#if !defined(NDISVER) || (NDISVER < 0x0630) bus->dpc_sched = TRUE; dhd_sched_dpc(bus->dhd); -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ #endif /* defined(SDIO_ISR_THREAD) */ @@ -6754,17 +6780,6 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, int ret; dhd_bus_t *bus; -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { - DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__)); - } - else { - DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__)); - } - mutex_lock(&_dhd_sdio_mutex_lock_); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -#endif /* Init global variables at run-time, not as part of the declaration. * This is required to support init/de-init of the driver. Initialization @@ -6778,11 +6793,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, sd1idle = TRUE; dhd_readahead = TRUE; retrydata = FALSE; -#if !defined(PLATFORM_MPS) dhd_doflow = FALSE; -#else - dhd_doflow = TRUE; -#endif /* OEM_ANDROID */ dhd_dongle_ramsize = 0; dhd_txminmax = DHD_TXMINMAX; @@ -6917,12 +6928,6 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, } -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_unlock(&_dhd_sdio_mutex_lock_); - DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -#endif init_waitqueue_head(&bus->bus_sleep); @@ -6932,294 +6937,10 @@ fail: dhdsdio_release(bus, osh); forcereturn: -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_unlock(&_dhd_sdio_mutex_lock_); - DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -#endif return NULL; } -#ifdef REGON_BP_HANG_FIX -static int dhd_sdio_backplane_reset(struct dhd_bus *bus) -{ - uint32 temp = 0; - DHD_ERROR(("Resetting the backplane to avoid failure in firmware download..\n")); - - temp = bcmsdh_reg_read(bus->sdh, 0x180021e0, 4); - DHD_INFO(("SDIO Clk Control Reg = %x\n", temp)); - - /* Force HT req from PMU */ - bcmsdh_reg_write(bus->sdh, 0x18000644, 4, 0x6000005); - - /* Increase the clock stretch duration. */ - bcmsdh_reg_write(bus->sdh, 0x18000630, 4, 0xC8FFC8); - - /* Setting ALP clock request in SDIOD clock control status register */ - bcmsdh_reg_write(bus->sdh, 0x180021e0, 4, 0x41); - - /* Allowing clock from SR engine to SR memory */ - bcmsdh_reg_write(bus->sdh, 0x18004400, 4, 0xf92f1); - /* Disabling SR Engine before SR binary download. */ - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x0); - - /* Enabling clock from backplane to SR memory */ - bcmsdh_reg_write(bus->sdh, 0x18004400, 4, 0xf9af1); - - /* Initializing SR memory address register in SOCRAM */ - bcmsdh_reg_write(bus->sdh, 0x18004408, 4, 0x0); - - /* Downloading the SR binary */ - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0xc0002000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x80008000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x1051f080); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x80008000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x1050f080); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x80008000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x1050f080); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x80008000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x1050f080); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000004); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000604); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00001604); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00001404); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a08c80); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010001); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x14a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00011404); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00002000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x04a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00002000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0xf8000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00002000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x04a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00002000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0xf8000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00011604); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010604); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010004); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x14a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000004); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010001); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x14a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010004); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00010000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x14a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x30a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000008); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x04a00000); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0x00000008); - bcmsdh_reg_write(bus->sdh, 0x1800440c, 4, 0xfc000000); - /* SR Binary Download complete */ - - /* Allowing clock from SR engine to SR memory */ - bcmsdh_reg_write(bus->sdh, 0x18004400, 4, 0xf92f1); - - /* Turning ON SR Engine to initiate backplane reset Repeated ?? Maharana */ - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x0); - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x2); - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x37); - bcmsdh_reg_write(bus->sdh, 0x18000650, 4, 0x3); - temp = bcmsdh_reg_read(bus->sdh, 0x18000654, 4); - DHD_INFO(("0x18000654 = %x\n", temp)); - bcmsdh_reg_write(bus->sdh, 0x18000654, 4, 0x800037); - OSL_DELAY(100000); - /* Rolling back the original values for clock stretch and PMU timers */ - bcmsdh_reg_write(bus->sdh, 0x18000644, 4, 0x0); - bcmsdh_reg_write(bus->sdh, 0x18000630, 4, 0xC800C8); - /* Removing ALP clock request in SDIOD clock control status register */ - bcmsdh_reg_write(bus->sdh, 0x180021e0, 4, 0x40); - OSL_DELAY(10000); - return TRUE; -} - -static int dhdsdio_sdio_hang_war(struct dhd_bus *bus) -{ - uint32 temp = 0, temp2 = 0, counter = 0, BT_pwr_up = 0, BT_ready = 0; - /* Removing reset of D11 Core */ - bcmsdh_reg_write(bus->sdh, 0x18101408, 4, 0x3); - bcmsdh_reg_write(bus->sdh, 0x18101800, 4, 0x0); - bcmsdh_reg_write(bus->sdh, 0x18101408, 4, 0x1); - /* Reading CLB XTAL BT cntrl register */ - bcmsdh_reg_write(bus->sdh, 0x180013D8, 2, 0xD1); - bcmsdh_reg_write(bus->sdh, 0x180013DA, 2, 0x12); - bcmsdh_reg_write(bus->sdh, 0x180013D8, 2, 0x2D0); - /* Read if BT is powered up */ - temp = bcmsdh_reg_read(bus->sdh, 0x180013DA, 2); - /* Read BT_ready from WLAN wireless register */ - temp2 = bcmsdh_reg_read(bus->sdh, 0x1800002C, 4); - /* - Check if the BT is powered up and ready. The duration between BT being powered up - and BT becoming ready is the problematic window for WLAN. If we move ahead at this - time then we may encounter a corrupted backplane later. So we wait for BT to be ready - and then proceed after checking the health of the backplane. If the backplane shows - indications of failure then we have to do a full reset of the backplane using SR engine - and then proceed. - */ - (temp & 0xF0) ? (BT_pwr_up = 1):(BT_pwr_up = 0); - (temp2 & (1<<17)) ? (BT_ready = 1):(BT_ready = 0); - DHD_ERROR(("WARNING: Checking if BT is ready BT_pwr_up = %x" - "BT_ready = %x \n", BT_pwr_up, BT_ready)); - while (BT_pwr_up && !BT_ready) - { - OSL_DELAY(1000); - bcmsdh_reg_write(bus->sdh, 0x180013D8, 2, 0x2D0); - temp = bcmsdh_reg_read(bus->sdh, 0x180013DA, 2); - temp2 = bcmsdh_reg_read(bus->sdh, 0x1800002C, 4); - (temp & 0xF0) ? (BT_pwr_up = 1):(BT_pwr_up = 0); - (temp2 & (1<<17)) ? (BT_ready = 1):(BT_ready = 0); - counter++; - if (counter == 5000) - { - DHD_ERROR(("WARNING: Going ahead after 5 secs with" - "risk of failure because BT ready is not yet set\n")); - break; - } - } - DHD_ERROR(("\nWARNING: WL Proceeding BT_pwr_up = %x BT_ready = %x" - "\n", BT_pwr_up, BT_ready)); - counter = 0; - OSL_DELAY(10000); - /* - Get the information of who accessed the crucial backplane entities - by reading read and write access registers - */ - DHD_TRACE(("%d: Read Value @ 0x18104808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18104808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810480C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810480C, 4))); - DHD_TRACE(("%d: Read Value @ 0x18106808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18106808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810680C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810680C, 4))); - DHD_TRACE(("%d: Read Value @ 0x18107808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18107808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810780C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810780C, 4))); - DHD_TRACE(("%d: Read Value @ 0x18108808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18108808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810880C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810880C, 4))); - DHD_TRACE(("%d: Read Value @ 0x18109808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18109808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810980C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810980C, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810C808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810c808, 4))); - DHD_TRACE(("%d: Read Value @ 0x1810C80C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810c80C, 4))); - counter = 0; - while ((bcmsdh_reg_read(bus->sdh, 0x18104808, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810480C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x18106808, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810680C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810780C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810780C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810880C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810880C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810980C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810980C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810C80C, 4) == 5) || - (bcmsdh_reg_read(bus->sdh, 0x1810C80C, 4) == 5)) - { - if (++counter > 10) - { - DHD_ERROR(("Unable to recover the backkplane corruption" - "..Tried %d times.. Exiting\n", counter)); - break; - } - OSL_DELAY(10000); - dhd_sdio_backplane_reset(bus); - /* - Get the information of who accessed the crucial backplane - entities by reading read and write access registers - */ - DHD_ERROR(("%d: Read Value @ 0x18104808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18104808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810480C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810480C, 4))); - DHD_ERROR(("%d: Read Value @ 0x18106808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18106808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810680C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810680C, 4))); - DHD_ERROR(("%d: Read Value @ 0x18107808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18107808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810780C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810780C, 4))); - DHD_ERROR(("%d: Read Value @ 0x18108808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18108808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810880C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810880C, 4))); - DHD_ERROR(("%d: Read Value @ 0x18109808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x18109808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810980C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810980C, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810C808 = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810c808, 4))); - DHD_ERROR(("%d: Read Value @ 0x1810C80C = %x." - "\n", __LINE__, bcmsdh_reg_read(bus->sdh, 0x1810c80C, 4))); - } - /* Set the WL ready to indicate BT that we are done with backplane reset */ - DHD_ERROR(("Setting up AXI_OK\n")); - bcmsdh_reg_write(bus->sdh, 0x18000658, 4, 0x3); - temp = bcmsdh_reg_read(bus->sdh, 0x1800065c, 4); - temp |= 0x80000000; - bcmsdh_reg_write(bus->sdh, 0x1800065c, 4, temp); - return TRUE; -} -#endif /* REGON_BP_HANG_FIX */ static bool dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, uint16 devid) @@ -7238,7 +6959,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, #if defined(DHD_DEBUG) DHD_ERROR(("F1 signature read @0x18000000=0x%4x\n", bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4))); -#endif +#endif /* Force PLL off until si_attach() programs PLL control regs */ @@ -7313,11 +7034,6 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, bus->sih->socitype, bus->sih->chip, bus->sih->chiprev, bus->sih->chippkg)); #endif /* DHD_DEBUG */ -#ifdef REGON_BP_HANG_FIX - /* WAR - for 43241 B0-B1-B2. B3 onwards do not need this */ - if (((uint16)bus->sih->chip == BCM4324_CHIP_ID) && (bus->sih->chiprev < 3)) - dhdsdio_sdio_hang_war(bus); -#endif /* REGON_BP_HANG_FIX */ bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); @@ -7398,6 +7114,17 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, bus->srmemsize = si_socram_srmem_size(bus->sih); } + /* HACK: Fix HW problem with baseband chip in coex */ + if (((uint16)bus->sih->chip) == BCM4354_CHIP_ID) { + bcmsdh_reg_write(bus->sdh, 0x18000c40, 4, 0); + if (bcmsdh_regfail(bus->sdh)) + DHD_ERROR(("DHD: RECONFIG_GPIO3 step 1 failed.\n")); + + bcmsdh_reg_write(bus->sdh, 0x18000e00, 4, 0x00001038); + if (bcmsdh_regfail(bus->sdh)) + DHD_ERROR(("DHD: RECONFIG_GPIO3 step 2 failed.\n")); + } + /* ...but normally deal with the SDPCMDEV core */ if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) && !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) { @@ -7721,17 +7448,6 @@ dhdsdio_disconnect(void *ptr) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { - DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__)); - } - else { - DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__)); - } - mutex_lock(&_dhd_sdio_mutex_lock_); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -#endif if (bus) { @@ -7739,12 +7455,6 @@ dhdsdio_disconnect(void *ptr) dhdsdio_release(bus, bus->dhd->osh); } -#if defined(MULTIPLE_SUPPLICANT) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - mutex_unlock(&_dhd_sdio_mutex_lock_); - DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -#endif /* LINUX */ DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); @@ -7765,7 +7475,8 @@ dhdsdio_suspend(void *context) if ((!ret) && (bus->dhd->up)) { if (wait_event_timeout(bus->bus_sleep, bus->sleeping, wait_time) == 0) { if (!bus->sleeping) { - return 1; + return 0; + //return 1; } } } @@ -7780,7 +7491,7 @@ dhdsdio_resume(void *context) if (dhd_os_check_if_up(bus->dhd)) bcmsdh_oob_intr_set(bus->sdh, TRUE); -#endif +#endif return 0; } @@ -8283,7 +7994,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) dhd_enable_oob_intr(bus, FALSE); bcmsdh_oob_intr_set(bus->sdh, FALSE); bcmsdh_oob_intr_unregister(bus->sdh); -#endif +#endif /* Clean tx/rx buffer pointers, detach from the dongle */ dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE, TRUE); @@ -8324,7 +8035,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) bcmsdh_oob_intr_register(bus->sdh, dhdsdio_isr, bus); bcmsdh_oob_intr_set(bus->sdh, TRUE); -#endif +#endif bus->dhd->dongle_reset = FALSE; bus->dhd->up = TRUE; @@ -8332,7 +8043,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) #if !defined(IGNORE_ETH0_DOWN) /* Restore flow control */ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF); -#endif +#endif dhd_os_wd_timer(dhdp, dhd_watchdog_ms); DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); @@ -8412,25 +8123,6 @@ dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint si return dhdsdio_membytes(bus, set, address, data, size); } -#if defined(NDISVER) && (NDISVER >= 0x0630) -void -dhd_bus_reject_ioreqs(dhd_pub_t *dhdp, bool reject) -{ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_reject_ioreqs(dhdp->bus->sdh, reject); -} - -void -dhd_bus_waitfor_iodrain(dhd_pub_t *dhdp) -{ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - - bcmsdh_waitfor_iodrain(dhdp->bus->sdh); -} -#endif /* (NDISVER) && (NDISVER >= 0x0630) */ void dhd_bus_update_fw_nv_path(struct dhd_bus *bus, char *pfw_path, char *pnv_path) @@ -8553,28 +8245,3 @@ void dhd_sdio_reg_write(void *h, uint32 addr, uint32 val) dhd_os_sdunlock(bus->dhd); } #endif /* DEBUGGER */ - -#if defined(SOFTAP_TPUT_ENHANCE) -void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time) -{ - if (!dhdp || !dhdp->bus) { - DHD_ERROR(("%s:Bus is Invalid\n", __FUNCTION__)); - return; - } - dhdp->bus->idletime = idle_time; -} - -void dhd_bus_getidletime(dhd_pub_t *dhdp, int* idle_time) -{ - if (!dhdp || !dhdp->bus) { - DHD_ERROR(("%s:Bus is Invalid\n", __FUNCTION__)); - return; - } - - if (!idle_time) { - DHD_ERROR(("%s:Arg idle_time is NULL\n", __FUNCTION__)); - return; - } - *idle_time = dhdp->bus->idletime; -} -#endif /* SOFTAP_TPUT_ENHANCE */ diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.c b/drivers/net/wireless/bcmdhd/dhd_wlfc.c index 15844fbc67343ace9eb72a612e0cef692c962dc7..148cf62e9b2433b67c01452f9a6384c198a2dc05 100644 --- a/drivers/net/wireless/bcmdhd/dhd_wlfc.c +++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.c @@ -1,7 +1,25 @@ /* * DHD PROP_TXSTATUS Module. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhd_wlfc.c 490028 2014-07-09 05:58:25Z $ * @@ -23,9 +41,7 @@ #include <wlfc_proto.h> #include <dhd_wlfc.h> #endif -#ifdef DHDTCPACK_SUPPRESS #include <dhd_ip.h> -#endif /* DHDTCPACK_SUPPRESS */ /* @@ -40,11 +56,7 @@ #ifdef PROP_TXSTATUS -#ifdef QMONITOR -#define DHD_WLFC_QMON_COMPLETE(entry) dhd_qmon_txcomplete(&entry->qmon) -#else #define DHD_WLFC_QMON_COMPLETE(entry) -#endif /* QMONITOR */ #define LIMIT_BORROW @@ -981,7 +993,7 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, bool send_tim_update = FALSE; uint32 htod = 0; uint16 htodseq = 0; - uint8 free_ctr; + uint8 free_ctr, flags = 0; int gen = 0xff; dhd_pub_t *dhdp = (dhd_pub_t *)ctx->dhdp; @@ -1035,23 +1047,26 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, return BCME_ERROR; } - WL_TXSTATUS_SET_FREERUNCTR(htod, free_ctr); - WL_TXSTATUS_SET_HSLOT(htod, hslot); - WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); - WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); - WL_TXSTATUS_SET_GENERATION(htod, gen); - DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); - + flags = WLFC_PKTFLAG_PKTFROMHOST; if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { /* Indicate that this packet is being sent in response to an explicit request from the firmware side. */ - WLFC_PKTFLAG_SET_PKTREQUESTED(htod); - } else { - WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); + flags |= WLFC_PKTFLAG_PKT_REQUESTED; + } + if (pkt_is_dhcp(ctx->osh, p)) { + flags |= WLFC_PKTFLAG_PKT_FORCELOWRATE; } + WL_TXSTATUS_SET_FREERUNCTR(htod, free_ctr); + WL_TXSTATUS_SET_HSLOT(htod, hslot); + WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); + WL_TXSTATUS_SET_FLAGS(htod, flags); + WL_TXSTATUS_SET_GENERATION(htod, gen); + DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); + + rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, entry->traffic_lastreported_bmp, entry->mac_handle, htod, htodseq, FALSE); if (rc == BCME_OK) { @@ -1223,9 +1238,6 @@ _dhd_wlfc_enque_delayq(athost_wl_status_info_t* ctx, void* pktbuf, int prec) return BCME_ERROR; } -#ifdef QMONITOR - dhd_qmon_tx(&entry->qmon); -#endif /* A packet has been pushed, update traffic availability bitmap, @@ -1620,9 +1632,6 @@ _dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* { int rc = BCME_OK; -#ifdef QMONITOR - dhd_qmon_reset(&entry->qmon); -#endif if ((action == eWLFC_MAC_ENTRY_ACTION_ADD) || (action == eWLFC_MAC_ENTRY_ACTION_UPDATE)) { entry->occupied = 1; diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/dhd_wlfc.h index e1f748a23321b0b34ee11ac3b3c7a4b3e6e11bd3..1ac120c1528d4099a4a83395d03bedfa7e8557a7 100644 --- a/drivers/net/wireless/bcmdhd/dhd_wlfc.h +++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.h @@ -1,14 +1,29 @@ /* -* $Copyright Open 2009 Broadcom Corporation$ +* Copyright (C) 1999-2014, Broadcom Corporation +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2 (the "GPL"), +* available at http://www.broadcom.com/licenses/GPLv2.php, with the +* following added to such license: +* +* As a special exception, the copyright holders of this software give you +* permission to link this software with independent modules, and to copy and +* distribute the resulting executable under terms of your choice, provided that +* you also meet, for each linked independent module, the terms and conditions of +* the license of that module. An independent module is a module which is not +* derived from this software. The special exception does not apply to any +* modifications of the software. +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a license +* other than the GPL, without Broadcom's express prior written consent. * $Id: dhd_wlfc.h 490028 2014-07-09 05:58:25Z $ * */ #ifndef __wlfc_host_driver_definitions_h__ #define __wlfc_host_driver_definitions_h__ -#ifdef QMONITOR -#include <dhd_qmon.h> -#endif /* #define OOO_DEBUG */ @@ -121,9 +136,6 @@ typedef struct wlfc_mac_descriptor { /* flag. TRUE when in suppress state */ uint8 suppressed; -#ifdef QMONITOR - dhd_qmon_t qmon; -#endif /* QMONITOR */ #ifdef PROP_TXSTATUS_DEBUG uint32 dstncredit_sent_packets; diff --git a/drivers/net/wireless/bcmdhd/dngl_stats.h b/drivers/net/wireless/bcmdhd/dngl_stats.h index ec22f7c383ce7212b77bf170588658d6c116480d..cd37e442b89e37175c36b8935c9dbf9395810faf 100644 --- a/drivers/net/wireless/bcmdhd/dngl_stats.h +++ b/drivers/net/wireless/bcmdhd/dngl_stats.h @@ -2,7 +2,25 @@ * Common stats definitions for clients of dongle * ports * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dngl_stats.h 464743 2014-03-25 21:04:32Z $ */ @@ -22,4 +40,183 @@ typedef struct { unsigned long multicast; /* multicast packets received */ } dngl_stats_t; +typedef int wifi_radio; +typedef int wifi_channel; +typedef int wifi_rssi; + +typedef enum wifi_channel_width { + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, + WIFI_CHAN_WIDTH_INVALID = -1 +} wifi_channel_width_t; + +typedef enum { + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, // if done by firmware/driver + WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver +} wifi_connection_state; + +typedef enum { + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} wifi_roam_state; + +typedef enum { + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } wifi_interface_mode; + +#define WIFI_CAPABILITY_QOS 0x00000001 // set for QOS association +#define WIFI_CAPABILITY_PROTECTED 0x00000002 // set for protected association (802.11 beacon frame control protected bit set) +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 // set if 802.11 Extended Capabilities element interworking bit is set +#define WIFI_CAPABILITY_HS20 0x00000008 // set for HS20 association +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 // set is 802.11 Extended Capabilities element UTF-8 SSID bit is set +#define WIFI_CAPABILITY_COUNTRY 0x00000020 // set is 802.11 Country Element is present + +typedef struct { + wifi_interface_mode mode; // interface mode + u8 mac_addr[6]; // interface mac address (self) + wifi_connection_state state; // connection state (valid for STA, CLI only) + wifi_roam_state roaming; // roaming state + u32 capabilities; // WIFI_CAPABILITY_XXX (self) + u8 ssid[33]; // null terminated SSID + u8 bssid[6]; // bssid + u8 ap_country_str[3]; // country string advertised by AP + u8 country_str[3]; // country string for this association +} wifi_interface_info; + +typedef wifi_interface_info *wifi_interface_handle; + +/* channel information */ +typedef struct { + wifi_channel_width_t width; // channel width (20, 40, 80, 80+80, 160) + wifi_channel center_freq; // primary 20 MHz channel + wifi_channel center_freq0; // center frequency (MHz) first segment + wifi_channel center_freq1; // center frequency (MHz) second segment +} wifi_channel_info; + +/* wifi rate */ +typedef struct { + u32 preamble :3; // 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved + u32 nss :2; // 0:1x1, 1:2x2, 3:3x3, 4:4x4 + u32 bw :3; // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz + u32 rateMcsIdx :8; // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps + // HT/VHT it would be mcs index + u32 reserved :16; // reserved + u32 bitrate; // units of 100 Kbps +} wifi_rate; + +/* channel statistics */ +typedef struct { + wifi_channel_info channel; // channel + u32 on_time; // msecs the radio is awake (32 bits number accruing over time) + u32 cca_busy_time; // msecs the CCA register is busy (32 bits number accruing over time) +} wifi_channel_stat; + +/* radio statistics */ +typedef struct { + wifi_radio radio; // wifi radio (if multiple radio supported) + u32 on_time; // msecs the radio is awake (32 bits number accruing over time) + u32 tx_time; // msecs the radio is transmitting (32 bits number accruing over time) + u32 rx_time; // msecs the radio is in active receive (32 bits number accruing over time) + u32 on_time_scan; // msecs the radio is awake due to all scan (32 bits number accruing over time) + u32 on_time_nbd; // msecs the radio is awake due to NAN (32 bits number accruing over time) + u32 on_time_gscan; // msecs the radio is awake due to G?scan (32 bits number accruing over time) + u32 on_time_roam_scan; // msecs the radio is awake due to roam?scan (32 bits number accruing over time) + u32 on_time_pno_scan; // msecs the radio is awake due to PNO scan (32 bits number accruing over time) + u32 on_time_hs20; // msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits number accruing over time) + u32 num_channels; // number of channels + wifi_channel_stat channels[]; // channel statistics +} wifi_radio_stat; + +/* per rate statistics */ +typedef struct { + wifi_rate rate; // rate information + u32 tx_mpdu; // number of successfully transmitted data pkts (ACK rcvd) + u32 rx_mpdu; // number of received data pkts + u32 mpdu_lost; // number of data packet losses (no ACK) + u32 retries; // total number of data pkt retries + u32 retries_short; // number of short data pkt retries + u32 retries_long; // number of long data pkt retries +} wifi_rate_stat; + +/* access categories */ +typedef enum { + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} wifi_traffic_ac; + +/* wifi peer type */ +typedef enum +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} wifi_peer_type; + +/* per peer statistics */ +typedef struct { + wifi_peer_type type; // peer type (AP, TDLS, GO etc.) + u8 peer_mac_address[6]; // mac address + u32 capabilities; // peer WIFI_CAPABILITY_XXX + u32 num_rate; // number of rates + wifi_rate_stat rate_stats[]; // per rate statistics, number of entries = num_rate +} wifi_peer_info; + +/* per access category statistics */ +typedef struct { + wifi_traffic_ac ac; // access category (VI, VO, BE, BK) + u32 tx_mpdu; // number of successfully transmitted unicast data pkts (ACK rcvd) + u32 rx_mpdu; // number of received unicast mpdus + u32 tx_mcast; // number of succesfully transmitted multicast data packets + // STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent + u32 rx_mcast; // number of received multicast data packets + u32 rx_ampdu; // number of received unicast a-mpdus + u32 tx_ampdu; // number of transmitted unicast a-mpdus + u32 mpdu_lost; // number of data pkt losses (no ACK) + u32 retries; // total number of data pkt retries + u32 retries_short; // number of short data pkt retries + u32 retries_long; // number of long data pkt retries + u32 contention_time_min; // data pkt min contention time (usecs) + u32 contention_time_max; // data pkt max contention time (usecs) + u32 contention_time_avg; // data pkt avg contention time (usecs) + u32 contention_num_samples; // num of data pkts used for contention statistics +} wifi_wmm_ac_stat; + +/* interface statistics */ +typedef struct { + wifi_interface_handle iface; // wifi interface + wifi_interface_info info; // current state of the interface + u32 beacon_rx; // access point beacon received count from connected AP + u32 mgmt_rx; // access point mgmt frames received count from connected AP (including Beacon) + u32 mgmt_action_rx; // action frames received count + u32 mgmt_action_tx; // action frames transmit count + wifi_rssi rssi_mgmt; // access Point Beacon and Management frames RSSI (averaged) + wifi_rssi rssi_data; // access Point Data Frames RSSI (averaged) from connected AP + wifi_rssi rssi_ack; // access Point ACK RSSI (averaged) from connected AP + wifi_wmm_ac_stat ac[WIFI_AC_MAX]; // per ac data packet statistics + u32 num_peers; // number of peers + wifi_peer_info peer_info[]; // per peer statistics +} wifi_iface_stat; + #endif /* _dngl_stats_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h b/drivers/net/wireless/bcmdhd/dngl_wlhdr.h index a3aa62f0078951c8dac0a3b834e932233cff6a76..fbd3209568fdd3d7b495bb2813b9679af94c9455 100644 --- a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h +++ b/drivers/net/wireless/bcmdhd/dngl_wlhdr.h @@ -1,7 +1,25 @@ /* * Dongle WL Header definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dngl_wlhdr.h 464743 2014-03-25 21:04:32Z $ */ diff --git a/drivers/net/wireless/bcmdhd/hnd_pktpool.c b/drivers/net/wireless/bcmdhd/hnd_pktpool.c index 242f4322117a2efd86d7759c87cf323241f60696..bf48b6df998e2cc9536cc32d92d69cbecfe36b6a 100644 --- a/drivers/net/wireless/bcmdhd/hnd_pktpool.c +++ b/drivers/net/wireless/bcmdhd/hnd_pktpool.c @@ -1,7 +1,25 @@ /* * HND generic packet pool operation primitives * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: $ */ diff --git a/drivers/net/wireless/bcmdhd/hnd_pktq.c b/drivers/net/wireless/bcmdhd/hnd_pktq.c index d619113b1a5c084053cf3ea69a646fd1ae86d037..221c30cf0942d770fc73378962a29fecdb623c60 100644 --- a/drivers/net/wireless/bcmdhd/hnd_pktq.c +++ b/drivers/net/wireless/bcmdhd/hnd_pktq.c @@ -1,7 +1,25 @@ /* * HND generic pktq operation primitives * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: $ */ diff --git a/drivers/net/wireless/bcmdhd/hndpmu.c b/drivers/net/wireless/bcmdhd/hndpmu.c index 03f17244faf37de9190484014d67bffba426061e..f0a2d9c9f039f1bc3c19ae56378ef600afeabd78 100644 --- a/drivers/net/wireless/bcmdhd/hndpmu.c +++ b/drivers/net/wireless/bcmdhd/hndpmu.c @@ -2,7 +2,25 @@ * Misc utility routines for accessing PMU corerev specific features * of the SiliconBackplane-based Broadcom chips. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: hndpmu.c 475037 2014-05-02 23:55:49Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/aidmp.h b/drivers/net/wireless/bcmdhd/include/aidmp.h index 6a7b78de9b2473250b8b5619f8332f8c108a3733..4e075257f05ef2d97b6d084bd6cfe317c0af770d 100644 --- a/drivers/net/wireless/bcmdhd/include/aidmp.h +++ b/drivers/net/wireless/bcmdhd/include/aidmp.h @@ -1,7 +1,25 @@ /* * Broadcom AMBA Interconnect definitions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: aidmp.h 456346 2014-02-18 16:48:52Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcm_cfg.h b/drivers/net/wireless/bcmdhd/include/bcm_cfg.h index fb6edc2f13950f183fa992952455b746d6d04b1c..fa2db7c4de5769bc1c5790a88e23fa7361b3c456 100644 --- a/drivers/net/wireless/bcmdhd/include/bcm_cfg.h +++ b/drivers/net/wireless/bcmdhd/include/bcm_cfg.h @@ -1,7 +1,25 @@ /* * BCM common config options * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcm_cfg.h 351867 2012-08-21 18:46:16Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h b/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h index 0375285ee1aa0911afdf2187973df628ddd8fdf7..ee06f3b504126d37316b2294cb379be300ab3b27 100644 --- a/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h +++ b/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h @@ -35,7 +35,25 @@ * and instrumentation on top of the heap, without modifying the heap * allocation implementation. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcm_mpool_pub.h 407097 2013-06-11 18:43:16Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/drivers/net/wireless/bcmdhd/include/bcmcdc.h index 76788d48edadb832a78d0cac6def3bd4edcdfbab..1028bb38608a0974d697f4bd4aac90bd1f50ea8d 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmcdc.h +++ b/drivers/net/wireless/bcmdhd/include/bcmcdc.h @@ -4,7 +4,25 @@ * * Definitions subject to change without notice. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmcdc.h 318308 2012-03-02 02:23:42Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h index 8c720d0a87fd533e2deb7e5cff857872738a7160..755b8535e6104464f861aaed371c4cc29f7bafa1 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h +++ b/drivers/net/wireless/bcmdhd/include/bcmdefs.h @@ -1,7 +1,25 @@ /* * Misc system wide definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmdefs.h 474209 2014-04-30 12:16:47Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/bcmdhd/include/bcmdevs.h index b7c386ef0e84866799b4a7a023331690006b5ad9..678b860dca3e94ebaf987c0014e81200f1ac08d8 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmdevs.h +++ b/drivers/net/wireless/bcmdhd/include/bcmdevs.h @@ -1,9 +1,27 @@ /* * Broadcom device-specific manifest constants. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmdevs.h 484136 2014-06-12 04:36:10Z $ + * $Id: bcmdevs.h 474307 2014-04-30 20:58:03Z $ */ #ifndef _BCMDEVS_H @@ -347,7 +365,6 @@ #define BCM43556_CHIP_ID 0xAA24 /* 43556 chipcommon chipid */ #define BCM43558_CHIP_ID 0xAA26 /* 43558 chipcommon chipid */ #define BCM43566_CHIP_ID 0xAA2E /* 43566 chipcommon chipid */ -#define BCM43567_CHIP_ID 0xAA2F /* 43567 chipcommon chipid */ #define BCM43568_CHIP_ID 0xAA30 /* 43568 chipcommon chipid */ #define BCM43569_CHIP_ID 0xAA31 /* 43569 chipcommon chipid */ #define BCM43570_CHIP_ID 0xAA32 /* 43570 chipcommon chipid */ @@ -358,7 +375,6 @@ (CHIPID(chipid) == BCM43556_CHIP_ID) || \ (CHIPID(chipid) == BCM43558_CHIP_ID) || \ (CHIPID(chipid) == BCM43566_CHIP_ID) || \ - (CHIPID(chipid) == BCM43567_CHIP_ID) || \ (CHIPID(chipid) == BCM43568_CHIP_ID) || \ (CHIPID(chipid) == BCM43569_CHIP_ID) || \ (CHIPID(chipid) == BCM43570_CHIP_ID) || \ @@ -651,380 +667,6 @@ #define MIN_SLOW_CLK 32 /* us Slow clock period */ #define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL -/* Reference Board Types */ -#define BU4710_BOARD 0x0400 -#define VSIM4710_BOARD 0x0401 -#define QT4710_BOARD 0x0402 - -#define BU4309_BOARD 0x040a -#define BCM94309CB_BOARD 0x040b -#define BCM94309MP_BOARD 0x040c -#define BCM4309AP_BOARD 0x040d - -#define BCM94302MP_BOARD 0x040e - -#define BU4306_BOARD 0x0416 -#define BCM94306CB_BOARD 0x0417 -#define BCM94306MP_BOARD 0x0418 - -#define BCM94710D_BOARD 0x041a -#define BCM94710R1_BOARD 0x041b -#define BCM94710R4_BOARD 0x041c -#define BCM94710AP_BOARD 0x041d - -#define BU2050_BOARD 0x041f - -#define BCM94306P50_BOARD 0x0420 - -#define BCM94309G_BOARD 0x0421 - -#define BU4704_BOARD 0x0423 -#define BU4702_BOARD 0x0424 - -#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ - -#define MPSG4306_BOARD 0x0427 - -#define BCM94702MN_BOARD 0x0428 - -/* BCM4702 1U CompactPCI Board */ -#define BCM94702CPCI_BOARD 0x0429 - -/* BCM4702 with BCM95380 VLAN Router */ -#define BCM95380RR_BOARD 0x042a - -/* cb4306 with SiGe PA */ -#define BCM94306CBSG_BOARD 0x042b - -/* cb4306 with SiGe PA */ -#define PCSG94306_BOARD 0x042d - -/* bu4704 with sdram */ -#define BU4704SD_BOARD 0x042e - -/* Dual 11a/11g Router */ -#define BCM94704AGR_BOARD 0x042f - -/* 11a-only minipci */ -#define BCM94308MP_BOARD 0x0430 - -/* 4306/gprs combo */ -#define BCM94306GPRS_BOARD 0x0432 - -/* BCM5365/BCM4704 FPGA Bringup Board */ -#define BU5365_FPGA_BOARD 0x0433 - -#define BU4712_BOARD 0x0444 -#define BU4712SD_BOARD 0x045d -#define BU4712L_BOARD 0x045f - -/* BCM4712 boards */ -#define BCM94712AP_BOARD 0x0445 -#define BCM94712P_BOARD 0x0446 - -/* BCM4318 boards */ -#define BU4318_BOARD 0x0447 -#define CB4318_BOARD 0x0448 -#define MPG4318_BOARD 0x0449 -#define MP4318_BOARD 0x044a -#define SD4318_BOARD 0x044b - -/* BCM4313 boards */ -#define BCM94313BU_BOARD 0x050f -#define BCM94313HM_BOARD 0x0510 -#define BCM94313EPA_BOARD 0x0511 -#define BCM94313HMG_BOARD 0x051C - -/* BCM63XX boards */ -#define BCM96338_BOARD 0x6338 -#define BCM96348_BOARD 0x6348 -#define BCM96358_BOARD 0x6358 -#define BCM96368_BOARD 0x6368 - -/* Another mp4306 with SiGe */ -#define BCM94306P_BOARD 0x044c - -/* mp4303 */ -#define BCM94303MP_BOARD 0x044e - -/* mpsgh4306 */ -#define BCM94306MPSGH_BOARD 0x044f - -/* BRCM 4306 w/ Front End Modules */ -#define BCM94306MPM 0x0450 -#define BCM94306MPL 0x0453 - -/* 4712agr */ -#define BCM94712AGR_BOARD 0x0451 - -/* pcmcia 4303 */ -#define PC4303_BOARD 0x0454 - -/* 5350K */ -#define BCM95350K_BOARD 0x0455 - -/* 5350R */ -#define BCM95350R_BOARD 0x0456 - -/* 4306mplna */ -#define BCM94306MPLNA_BOARD 0x0457 - -/* 4320 boards */ -#define BU4320_BOARD 0x0458 -#define BU4320S_BOARD 0x0459 -#define BCM94320PH_BOARD 0x045a - -/* 4306mph */ -#define BCM94306MPH_BOARD 0x045b - -/* 4306pciv */ -#define BCM94306PCIV_BOARD 0x045c - -#define BU4712SD_BOARD 0x045d - -#define BCM94320PFLSH_BOARD 0x045e - -#define BU4712L_BOARD 0x045f -#define BCM94712LGR_BOARD 0x0460 -#define BCM94320R_BOARD 0x0461 - -#define BU5352_BOARD 0x0462 - -#define BCM94318MPGH_BOARD 0x0463 - -#define BU4311_BOARD 0x0464 -#define BCM94311MC_BOARD 0x0465 -#define BCM94311MCAG_BOARD 0x0466 - -#define BCM95352GR_BOARD 0x0467 - -/* bcm95351agr */ -#define BCM95351AGR_BOARD 0x0470 - -/* bcm94704mpcb */ -#define BCM94704MPCB_BOARD 0x0472 - -/* 4785 boards */ -#define BU4785_BOARD 0x0478 - -/* 4321 boards */ -#define BU4321_BOARD 0x046b -#define BU4321E_BOARD 0x047c -#define MP4321_BOARD 0x046c -#define CB2_4321_BOARD 0x046d -#define CB2_4321_AG_BOARD 0x0066 -#define MC4321_BOARD 0x046e - -/* 4328 boards */ -#define BU4328_BOARD 0x0481 -#define BCM4328SDG_BOARD 0x0482 -#define BCM4328SDAG_BOARD 0x0483 -#define BCM4328UG_BOARD 0x0484 -#define BCM4328UAG_BOARD 0x0485 -#define BCM4328PC_BOARD 0x0486 -#define BCM4328CF_BOARD 0x0487 - -/* 4325 boards */ -#define BCM94325DEVBU_BOARD 0x0490 -#define BCM94325BGABU_BOARD 0x0491 - -#define BCM94325SDGWB_BOARD 0x0492 - -#define BCM94325SDGMDL_BOARD 0x04aa -#define BCM94325SDGMDL2_BOARD 0x04c6 -#define BCM94325SDGMDL3_BOARD 0x04c9 - -#define BCM94325SDABGWBA_BOARD 0x04e1 - -/* 4322 boards */ -#define BCM94322MC_SSID 0x04a4 -#define BCM94322USB_SSID 0x04a8 /* dualband */ -#define BCM94322HM_SSID 0x04b0 -#define BCM94322USB2D_SSID 0x04bf /* single band discrete front end */ - -/* 4312 boards */ -#define BCM4312MCGSG_BOARD 0x04b5 - -/* 4315 boards */ -#define BCM94315DEVBU_SSID 0x04c2 -#define BCM94315USBGP_SSID 0x04c7 -#define BCM94315BGABU_SSID 0x04ca -#define BCM94315USBGP41_SSID 0x04cb - -/* 4319 boards */ -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USB_SSID 0X04e6 -#define BCM94319SD_SSID 0X04e7 - -/* 4716 boards */ -#define BCM94716NR2_SSID 0x04cd - -/* 4319 boards */ -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USBNP4L_SSID 0X04e6 -#define BCM94319WLUSBN4L_SSID 0X04e7 -#define BCM94319SDG_SSID 0X04ea -#define BCM94319LCUSBSDN4L_SSID 0X04eb -#define BCM94319USBB_SSID 0x04ee -#define BCM94319LCSDN4L_SSID 0X0507 -#define BCM94319LSUSBN4L_SSID 0X0508 -#define BCM94319SDNA4L_SSID 0X0517 -#define BCM94319SDELNA4L_SSID 0X0518 -#define BCM94319SDELNA6L_SSID 0X0539 -#define BCM94319ARCADYAN_SSID 0X0546 -#define BCM94319WINDSOR_SSID 0x0561 -#define BCM94319MLAP_SSID 0x0562 -#define BCM94319SDNA_SSID 0x058b -#define BCM94319BHEMU3_SSID 0x0563 -#define BCM94319SDHMB_SSID 0x058c -#define BCM94319SDBREF_SSID 0x05a1 -#define BCM94319USBSDB_SSID 0x05a2 - - -/* 4329 boards */ -#define BCM94329AGB_SSID 0X04b9 -#define BCM94329TDKMDL1_SSID 0X04ba -#define BCM94329TDKMDL11_SSID 0X04fc -#define BCM94329OLYMPICN18_SSID 0X04fd -#define BCM94329OLYMPICN90_SSID 0X04fe -#define BCM94329OLYMPICN90U_SSID 0X050c -#define BCM94329OLYMPICN90M_SSID 0X050b -#define BCM94329AGBF_SSID 0X04ff -#define BCM94329OLYMPICX17_SSID 0X0504 -#define BCM94329OLYMPICX17M_SSID 0X050a -#define BCM94329OLYMPICX17U_SSID 0X0509 -#define BCM94329OLYMPICUNO_SSID 0X0564 -#define BCM94329MOTOROLA_SSID 0X0565 -#define BCM94329OLYMPICLOCO_SSID 0X0568 -/* 4336 SDIO board types */ -#define BCM94336SD_WLBGABU_SSID 0x0511 -#define BCM94336SD_WLBGAREF_SSID 0x0519 -#define BCM94336SDGP_SSID 0x0538 -#define BCM94336SDG_SSID 0x0519 -#define BCM94336SDGN_SSID 0x0538 -#define BCM94336SDGFC_SSID 0x056B - -/* 4330 SDIO board types */ -#define BCM94330SDG_SSID 0x0528 -#define BCM94330SD_FCBGABU_SSID 0x052e -#define BCM94330SD_WLBGABU_SSID 0x052f -#define BCM94330SD_FCBGA_SSID 0x0530 -#define BCM94330FCSDAGB_SSID 0x0532 -#define BCM94330OLYMPICAMG_SSID 0x0549 -#define BCM94330OLYMPICAMGEPA_SSID 0x054F -#define BCM94330OLYMPICUNO3_SSID 0x0551 -#define BCM94330WLSDAGB_SSID 0x0547 -#define BCM94330CSPSDAGBB_SSID 0x054A - -/* 43224 boards */ -#define BCM943224X21 0x056e -#define BCM943224X21_FCC 0x00d1 -#define BCM943224X21B 0x00e9 -#define BCM943224M93 0x008b -#define BCM943224M93A 0x0090 -#define BCM943224X16 0x0093 -#define BCM94322X9 0x008d -#define BCM94322M35e 0x008e - -/* 43228 Boards */ -#define BCM943228BU8_SSID 0x0540 -#define BCM943228BU9_SSID 0x0541 -#define BCM943228BU_SSID 0x0542 -#define BCM943227HM4L_SSID 0x0543 -#define BCM943227HMB_SSID 0x0544 -#define BCM943228HM4L_SSID 0x0545 -#define BCM943228SD_SSID 0x0573 - -/* 43239 Boards */ -#define BCM943239MOD_SSID 0x05ac -#define BCM943239REF_SSID 0x05aa - -/* 4331 boards */ -#define BCM94331X19 0x00D6 /* X19B */ -#define BCM94331X28 0x00E4 /* X28 */ -#define BCM94331X28B 0x010E /* X28B */ -#define BCM94331PCIEBT3Ax_SSID BCM94331X28 -#define BCM94331X12_2G_SSID 0x00EC /* X12 2G */ -#define BCM94331X12_5G_SSID 0x00ED /* X12 5G */ -#define BCM94331X29B 0x00EF /* X29B */ -#define BCM94331X29D 0x010F /* X29D */ -#define BCM94331CSAX_SSID BCM94331X29B -#define BCM94331X19C 0x00F5 /* X19C */ -#define BCM94331X33 0x00F4 /* X33 */ -#define BCM94331BU_SSID 0x0523 -#define BCM94331S9BU_SSID 0x0524 -#define BCM94331MC_SSID 0x0525 -#define BCM94331MCI_SSID 0x0526 -#define BCM94331PCIEBT4_SSID 0x0527 -#define BCM94331HM_SSID 0x0574 -#define BCM94331PCIEDUAL_SSID 0x059B -#define BCM94331MCH5_SSID 0x05A9 -#define BCM94331CS_SSID 0x05C6 -#define BCM94331CD_SSID 0x05DA - -/* 4314 Boards */ -#define BCM94314BU_SSID 0x05b1 - -/* 53572 Boards */ -#define BCM953572BU_SSID 0x058D -#define BCM953572NR2_SSID 0x058E -#define BCM947188NR2_SSID 0x058F -#define BCM953572SDRNR2_SSID 0x0590 - -/* 43236 boards */ -#define BCM943236OLYMPICSULLEY_SSID 0x594 -#define BCM943236PREPROTOBLU2O3_SSID 0x5b9 -#define BCM943236USBELNA_SSID 0x5f8 - -/* 4314 Boards */ -#define BCM94314BUSDIO_SSID 0x05c8 -#define BCM94314BGABU_SSID 0x05c9 -#define BCM94314HMEPA_SSID 0x05ca -#define BCM94314HMEPABK_SSID 0x05cb -#define BCM94314SUHMEPA_SSID 0x05cc -#define BCM94314SUHM_SSID 0x05cd -#define BCM94314HM_SSID 0x05d1 - -/* 4334 Boards */ -#define BCM94334FCAGBI_SSID 0x05df -#define BCM94334WLAGBI_SSID 0x05dd - -/* 4335 Boards */ -#define BCM94335X52 0x0114 - -/* 4345 Boards */ -#define BCM94345_SSID 0x0687 - -/* 4360 Boards */ -#define BCM94360X52C 0X0117 -#define BCM94360X52D 0X0137 -#define BCM94360X29C 0X0112 -#define BCM94360X29CP2 0X0134 -#define BCM94360X29CP3 0X013B -#define BCM94360X51 0x0111 -#define BCM94360X51P2 0x0129 -#define BCM94360X51P3 0x0142 -#define BCM94360X51A 0x0135 -#define BCM94360X51B 0x0136 -#define BCM94360CS 0x061B -#define BCM94360J28_D11AC2G 0x0c00 -#define BCM94360J28_D11AC5G 0x0c01 -#define BCM94360USBH5_D11AC5G 0x06aa -#define BCM94360MCM5 0x06d8 - -/* 4350 Boards */ -#define BCM94350X52B 0X0116 -#define BCM94350X14 0X0131 - -/* 43217 Boards */ -#define BCM943217BU_SSID 0x05d5 -#define BCM943217HM2L_SSID 0x05d6 -#define BCM943217HMITR2L_SSID 0x05d7 - -/* 43142 Boards */ -#define BCM943142HM_SSID 0x05e0 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ /* 43341 Boards */ #define BCM943341WLABGS_SSID 0x062d diff --git a/drivers/net/wireless/bcmdhd/include/bcmendian.h b/drivers/net/wireless/bcmdhd/include/bcmendian.h index 5dbf675f9ca3fd0b747b7211ea4f562bb0584ccd..ff527f69eda448e7a9a27b96f6daaabe90716ff1 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmendian.h +++ b/drivers/net/wireless/bcmdhd/include/bcmendian.h @@ -1,7 +1,25 @@ /* * Byte order utilities * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmendian.h 402715 2013-05-16 18:50:09Z $ * diff --git a/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h b/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h index fc014ae89bda48f5c0174b7ded71cdb621c5ba84..c1147ffa9b1d1a2cf915771bcce302a5a1216977 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h +++ b/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h @@ -4,9 +4,27 @@ * * Definitions subject to change without notice. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: bcmmsgbuf.h 490808 2014-07-12 00:33:13Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmmsgbuf.h 472643 2014-04-24 21:19:22Z $ */ #ifndef _bcmmsgbuf_h_ #define _bcmmsgbuf_h_ @@ -479,7 +497,7 @@ typedef struct host_txbuf_post { uint16 metadata_buf_len; /* provided data buffer len to receive data */ uint16 data_len; - uint32 rsvd; + uint32 flag2; } host_txbuf_post_t; #define BCMPCIE_PKT_FLAGS_FRAME_802_3 0x01 @@ -498,6 +516,9 @@ typedef struct host_txbuf_post { #define BCMPCIE_TXPOST_FLAGS_PRIO_SHIFT BCMPCIE_PKT_FLAGS_PRIO_SHIFT #define BCMPCIE_TXPOST_FLAGS_PRIO_MASK BCMPCIE_PKT_FLAGS_PRIO_MASK +#define BCMPCIE_PKT_FLAGS2_FORCELOWRATE_MASK 0x01 +#define BCMPCIE_PKT_FLAGS2_FORCELOWRATE_SHIFT 0 + /* H2D Txpost ring work items */ typedef union txbuf_submit_item { host_txbuf_post_t txpost; diff --git a/drivers/net/wireless/bcmdhd/include/bcmnvram.h b/drivers/net/wireless/bcmdhd/include/bcmnvram.h new file mode 100644 index 0000000000000000000000000000000000000000..d9f2b4ac8d01359e092953617cb4114316c8f021 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmnvram.h @@ -0,0 +1,272 @@ +/* + * NVRAM variable manipulation + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmnvram.h 428512 2013-10-09 02:12:11Z $ + */ + +#ifndef _bcmnvram_h_ +#define _bcmnvram_h_ + +#ifndef _LANGUAGE_ASSEMBLY + +#include <typedefs.h> +#include <bcmdefs.h> + +struct nvram_header { + uint32 magic; + uint32 len; + uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ + uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ + uint32 config_ncdl; /* ncdl values for memc */ +}; + +struct nvram_tuple { + char *name; + char *value; + struct nvram_tuple *next; +}; + +/* + * Get default value for an NVRAM variable + */ +extern char *nvram_default_get(const char *name); +/* + * validate/restore all per-interface related variables + */ +extern void nvram_validate_all(char *prefix, bool restore); + +/* + * restore specific per-interface variable + */ +extern void nvram_restore_var(char *prefix, char *name); + +/* + * Initialize NVRAM access. May be unnecessary or undefined on certain + * platforms. + */ +extern int nvram_init(void *sih); +extern int nvram_deinit(void *sih); + + +/* + * Append a chunk of nvram variables to the global list + */ +extern int nvram_append(void *si, char *vars, uint varsz); + +extern void nvram_get_global_vars(char **varlst, uint *varsz); + + +/* + * Check for reset button press for restoring factory defaults. + */ +extern int nvram_reset(void *sih); + +/* + * Disable NVRAM access. May be unnecessary or undefined on certain + * platforms. + */ +extern void nvram_exit(void *sih); + +/* + * Get the value of an NVRAM variable. The pointer returned may be + * invalid after a set. + * @param name name of variable to get + * @return value of variable or NULL if undefined + */ +extern char * nvram_get(const char *name); + +/* + * Read the reset GPIO value from the nvram and set the GPIO + * as input + */ +extern int nvram_resetgpio_init(void *sih); + +/* + * Get the value of an NVRAM variable. + * @param name name of variable to get + * @return value of variable or NUL if undefined + */ +static INLINE char * +nvram_safe_get(const char *name) +{ + char *p = nvram_get(name); + return p ? p : ""; +} + +/* + * Match an NVRAM variable. + * @param name name of variable to match + * @param match value to compare against value of variable + * @return TRUE if variable is defined and its value is string equal + * to match or FALSE otherwise + */ +static INLINE int +nvram_match(const char *name, const char *match) +{ + const char *value = nvram_get(name); + return (value && !strcmp(value, match)); +} + +/* + * Inversely match an NVRAM variable. + * @param name name of variable to match + * @param match value to compare against value of variable + * @return TRUE if variable is defined and its value is not string + * equal to invmatch or FALSE otherwise + */ +static INLINE int +nvram_invmatch(const char *name, const char *invmatch) +{ + const char *value = nvram_get(name); + return (value && strcmp(value, invmatch)); +} + +/* + * Set the value of an NVRAM variable. The name and value strings are + * copied into private storage. Pointers to previously set values + * may become invalid. The new value may be immediately + * retrieved but will not be permanently stored until a commit. + * @param name name of variable to set + * @param value value of variable + * @return 0 on success and errno on failure + */ +extern int nvram_set(const char *name, const char *value); + +/* + * Unset an NVRAM variable. Pointers to previously set values + * remain valid until a set. + * @param name name of variable to unset + * @return 0 on success and errno on failure + * NOTE: use nvram_commit to commit this change to flash. + */ +extern int nvram_unset(const char *name); + +/* + * Commit NVRAM variables to permanent storage. All pointers to values + * may be invalid after a commit. + * NVRAM values are undefined after a commit. + * @param nvram_corrupt true to corrupt nvram, false otherwise. + * @return 0 on success and errno on failure + */ +extern int nvram_commit_internal(bool nvram_corrupt); + +/* + * Commit NVRAM variables to permanent storage. All pointers to values + * may be invalid after a commit. + * NVRAM values are undefined after a commit. + * @return 0 on success and errno on failure + */ +extern int nvram_commit(void); + +/* + * Get all NVRAM variables (format name=value\0 ... \0\0). + * @param buf buffer to store variables + * @param count size of buffer in bytes + * @return 0 on success and errno on failure + */ +extern int nvram_getall(char *nvram_buf, int count); + +/* + * returns the crc value of the nvram + * @param nvh nvram header pointer + */ +uint8 nvram_calc_crc(struct nvram_header * nvh); + +extern int nvram_space; +#endif /* _LANGUAGE_ASSEMBLY */ + +/* The NVRAM version number stored as an NVRAM variable */ +#define NVRAM_SOFTWARE_VERSION "1" + +#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ +#define NVRAM_CLEAR_MAGIC 0x0 +#define NVRAM_INVALID_MAGIC 0xFFFFFFFF +#define NVRAM_VERSION 1 +#define NVRAM_HEADER_SIZE 20 +/* This definition is for precommit staging, and will be removed */ +#define NVRAM_SPACE 0x8000 +/* For CFE builds this gets passed in thru the makefile */ +#ifndef MAX_NVRAM_SPACE +#define MAX_NVRAM_SPACE 0x10000 +#endif +#define DEF_NVRAM_SPACE 0x8000 +#define ROM_ENVRAM_SPACE 0x1000 +#define NVRAM_LZMA_MAGIC 0x4c5a4d41 /* 'LZMA' */ + +#define NVRAM_MAX_VALUE_LEN 255 +#define NVRAM_MAX_PARAM_LEN 64 + +#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */ +#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */ + +/* Offsets to embedded nvram area */ +#define NVRAM_START_COMPRESSED 0x400 +#define NVRAM_START 0x1000 + +#define BCM_JUMBO_NVRAM_DELIMIT '\n' +#define BCM_JUMBO_START "Broadcom Jumbo Nvram file" + + +#if (defined(FAILSAFE_UPGRADE) || defined(CONFIG_FAILSAFE_UPGRADE) || \ + defined(__CONFIG_FAILSAFE_UPGRADE_SUPPORT__)) +#define IMAGE_SIZE "image_size" +#define BOOTPARTITION "bootpartition" +#define IMAGE_BOOT BOOTPARTITION +#define PARTIALBOOTS "partialboots" +#define MAXPARTIALBOOTS "maxpartialboots" +#define IMAGE_1ST_FLASH_TRX "flash0.trx" +#define IMAGE_1ST_FLASH_OS "flash0.os" +#define IMAGE_2ND_FLASH_TRX "flash0.trx2" +#define IMAGE_2ND_FLASH_OS "flash0.os2" +#define IMAGE_FIRST_OFFSET "image_first_offset" +#define IMAGE_SECOND_OFFSET "image_second_offset" +#define LINUX_FIRST "linux" +#define LINUX_SECOND "linux2" +#endif + +#if (defined(DUAL_IMAGE) || defined(CONFIG_DUAL_IMAGE) || \ + defined(__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__)) +/* Shared by all: CFE, Linux Kernel, and Ap */ +#define IMAGE_BOOT "image_boot" +#define BOOTPARTITION IMAGE_BOOT +/* CFE variables */ +#define IMAGE_1ST_FLASH_TRX "flash0.trx" +#define IMAGE_1ST_FLASH_OS "flash0.os" +#define IMAGE_2ND_FLASH_TRX "flash0.trx2" +#define IMAGE_2ND_FLASH_OS "flash0.os2" +#define IMAGE_SIZE "image_size" + +/* CFE and Linux Kernel shared variables */ +#define IMAGE_FIRST_OFFSET "image_first_offset" +#define IMAGE_SECOND_OFFSET "image_second_offset" + +/* Linux application variables */ +#define LINUX_FIRST "linux" +#define LINUX_SECOND "linux2" +#define POLICY_TOGGLE "toggle" +#define LINUX_PART_TO_FLASH "linux_to_flash" +#define LINUX_FLASH_POLICY "linux_flash_policy" + +#endif /* defined(DUAL_IMAGE||CONFIG_DUAL_IMAGE)||__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__ */ + +#endif /* _bcmnvram_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcie.h b/drivers/net/wireless/bcmdhd/include/bcmpcie.h index 14ccdcda2fea4e5ddd70e1fb267ef82968e5f5f4..530e2350208bf9bae152fe58f8a218abf3ba7a93 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmpcie.h +++ b/drivers/net/wireless/bcmdhd/include/bcmpcie.h @@ -2,9 +2,27 @@ * Broadcom PCIE * Software-specific definitions shared between device and host side * Explains the shared area between host and dongle - * $Copyright Open 2005 Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmpcie.h 490808 2014-07-12 00:33:13Z $ + * $Id: bcmpcie.h 472405 2014-04-23 23:46:55Z $ */ #ifndef _bcmpcie_h_ diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h index d95f8127166b84639dd920ed9266d635bcf85d09..8ecb7c2ac5b07044f775fb1e6bcdaf0a1e76ea24 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h @@ -1,7 +1,25 @@ /* * Broadcom PCI-SPI Host Controller Register Definitions * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmpcispi.h 241182 2011-02-17 21:50:03Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmperf.h b/drivers/net/wireless/bcmdhd/include/bcmperf.h index 39cfc4516d4f7a3d5e6c3ddb3237aefa81bd416c..acebfa3a2537b575f50a5845525270abdd5c50b2 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmperf.h +++ b/drivers/net/wireless/bcmdhd/include/bcmperf.h @@ -1,7 +1,25 @@ /* * Performance counters software interface. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h index a494ca28bde96b134a1e08d84ae4a15239471fe9..a0cd8dc2c0a8f369b1756640665b845cd1379b98 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h @@ -2,7 +2,25 @@ * Definitions for API from sdio common code (bcmsdh) to individual * host controller drivers. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdbus.h 408158 2013-06-17 22:15:35Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/bcmdhd/include/bcmsdh.h index aeb7dc944d5049a9e0d43df36df251e3e78c75e0..8986b0bfdc2e977b940bb677178f8b8148c222f2 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdh.h @@ -3,7 +3,25 @@ * export functions to client drivers * abstract OS and BUS specific details of SDIO * - * $ Copyright Open License Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdh.h 450676 2014-01-22 22:45:13Z $ */ @@ -31,10 +49,6 @@ extern const uint bcmsdh_msglevel; typedef struct bcmsdh_info bcmsdh_info_t; typedef void (*bcmsdh_cb_fn_t)(void *); -#if 0 && (NDISVER >= 0x0630) && 1 -extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, - void **regsva, uint irq, shared_info_t *sh); -#else extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *sdioh, ulong *regsva); /** * BCMSDH API context @@ -49,7 +63,6 @@ struct bcmsdh_info uint32 sbwad; /* Save backplane window address */ void *os_cxt; /* Pointer to per-OS private data */ }; -#endif /* Detach - freeup resources allocated in attach */ extern int bcmsdh_detach(osl_t *osh, void *sdh); diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h index 69d8e7a8cae4a9ffd59c96aa156e6d3dcd722c8d..8033fb2760f6393ceeba7094b4acb5e91897eacd 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h @@ -27,7 +27,7 @@ #ifndef __BCMSDH_SDMMC_H__ #define __BCMSDH_SDMMC_H__ -#define sd_err(x) +#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0) #define sd_trace(x) #define sd_info(x) #define sd_debug(x) @@ -57,7 +57,7 @@ /* private bus modes */ #define SDIOH_MODE_SD4 2 #define CLIENT_INTR 0x100 /* Get rid of this! */ -#define SDIOH_SDMMC_MAX_SG_ENTRIES 32 +#define SDIOH_SDMMC_MAX_SG_ENTRIES (SDPCM_MAXGLOM_SIZE+2) struct sdioh_info { osl_t *osh; /* osh handler */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h index 932686c619fe8853207e8f8689fb6c2f994afffa..e80cdc26dfdfeceb925555486d74a110b3042948 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h @@ -2,7 +2,25 @@ * Broadcom SDIO/PCMCIA * Software-specific definitions shared between device and host side * - * $Copyright Open 2005 Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdpcm.h 472405 2014-04-23 23:46:55Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h index 9c082ec1364f247ab9f8a51fa8f90434b477a2e6..b5a0caf50d087d69d84f9ae1a684ae811a887de2 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h @@ -1,7 +1,25 @@ /* * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdspi.h 294363 2011-11-06 23:02:20Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h index c1562a6eb3c343dbc6422f2a70f39421d9cc3337..46078793717e49b6158173123a5170b508c30b7c 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h @@ -1,7 +1,25 @@ /* * 'Standard' SDIO HOST CONTROLLER driver * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmsdstd.h 455390 2014-02-13 22:14:56Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmspi.h b/drivers/net/wireless/bcmdhd/include/bcmspi.h index bb0ee1503ee2963b221becedf2a459e3c7e1c032..cf814cefde5e55e90ba26917e89be11e38a6811a 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmspi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmspi.h @@ -1,7 +1,25 @@ /* * Broadcom SPI Low-Level Hardware Driver API * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmspi.h 241182 2011-02-17 21:50:03Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h b/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h new file mode 100644 index 0000000000000000000000000000000000000000..d055ff1c336417e1f263c6887632c00ae64de46a --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h @@ -0,0 +1,162 @@ +/* + * SD-SPI Protocol Conversion - BCMSDH->gSPI Translation Layer + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmspibrcm.h 373331 2012-12-07 04:46:22Z $ + */ +#ifndef _BCM_SPI_BRCM_H +#define _BCM_SPI_BRCM_H + +#ifndef SPI_MAX_IOFUNCS +/* Maximum number of I/O funcs */ +#define SPI_MAX_IOFUNCS 4 +#endif +/* global msglevel for debug messages - bitvals come from sdiovar.h */ + +#if defined(DHD_DEBUG) +#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0) +#define sd_trace(x) do { if (sd_msglevel & SDH_TRACE_VAL) printf x; } while (0) +#define sd_info(x) do { if (sd_msglevel & SDH_INFO_VAL) printf x; } while (0) +#define sd_debug(x) do { if (sd_msglevel & SDH_DEBUG_VAL) printf x; } while (0) +#define sd_data(x) do { if (sd_msglevel & SDH_DATA_VAL) printf x; } while (0) +#define sd_ctrl(x) do { if (sd_msglevel & SDH_CTRL_VAL) printf x; } while (0) +#else +#define sd_err(x) +#define sd_trace(x) +#define sd_info(x) +#define sd_debug(x) +#define sd_data(x) +#define sd_ctrl(x) +#endif + +#define sd_log(x) + +#define SDIOH_ASSERT(exp) \ + do { if (!(exp)) \ + printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ + } while (0) + +#define BLOCK_SIZE_F1 64 +#define BLOCK_SIZE_F2 2048 +#define BLOCK_SIZE_F3 2048 + +/* internal return code */ +#define SUCCESS 0 +#undef ERROR +#define ERROR 1 +#define ERROR_UF 2 +#define ERROR_OF 3 + +/* private bus modes */ +#define SDIOH_MODE_SPI 0 + +#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ +#define USE_MULTIBLOCK 0x4 + +struct sdioh_info { + uint cfg_bar; /* pci cfg address for bar */ + uint32 caps; /* cached value of capabilities reg */ + void *bar0; /* BAR0 for PCI Device */ + osl_t *osh; /* osh handler */ + void *controller; /* Pointer to SPI Controller's private data struct */ + uint lockcount; /* nest count of spi_lock() calls */ + bool client_intr_enabled; /* interrupt connnected flag */ + bool intr_handler_valid; /* client driver interrupt handler valid */ + sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ + void *intr_handler_arg; /* argument to call interrupt handler */ + bool initialized; /* card initialized */ + uint32 target_dev; /* Target device ID */ + uint32 intmask; /* Current active interrupts */ + void *sdos_info; /* Pointer to per-OS private data */ + uint32 controller_type; /* Host controller type */ + uint8 version; /* Host Controller Spec Compliance Version */ + uint irq; /* Client irq */ + uint32 intrcount; /* Client interrupts */ + uint32 local_intrcount; /* Controller interrupts */ + bool host_init_done; /* Controller initted */ + bool card_init_done; /* Client SDIO interface initted */ + bool polled_mode; /* polling for command completion */ + + bool sd_use_dma; /* DMA on CMD53 */ + bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ + /* Must be on for sd_multiblock to be effective */ + bool use_client_ints; /* If this is false, make sure to restore */ + /* polling hack in wl_linux.c:wl_timer() */ + int adapter_slot; /* Maybe dealing with multiple slots/controllers */ + int sd_mode; /* SD1/SD4/SPI */ + int client_block_size[SPI_MAX_IOFUNCS]; /* Blocksize */ + uint32 data_xfer_count; /* Current transfer */ + uint16 card_rca; /* Current Address */ + uint8 num_funcs; /* Supported funcs on client */ + uint32 card_dstatus; /* 32bit device status */ + uint32 com_cis_ptr; + uint32 func_cis_ptr[SPI_MAX_IOFUNCS]; + void *dma_buf; + ulong dma_phys; + int r_cnt; /* rx count */ + int t_cnt; /* tx_count */ + uint32 wordlen; /* host processor 16/32bits */ + uint32 prev_fun; + uint32 chip; + uint32 chiprev; + bool resp_delay_all; + bool dwordmode; + bool resp_delay_new; + + struct spierrstats_t spierrstats; +}; + +/************************************************************ + * Internal interfaces: per-port references into bcmspibrcm.c + */ + +/* Global message bits */ +extern uint sd_msglevel; + +/************************************************************** + * Internal interfaces: bcmspibrcm.c references to per-port code + */ + +/* Interrupt (de)registration routines */ +extern int spi_register_irq(sdioh_info_t *sd, uint irq); +extern void spi_free_irq(uint irq, sdioh_info_t *sd); + +/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ +extern void spi_lock(sdioh_info_t *sd); +extern void spi_unlock(sdioh_info_t *sd); + +/* Allocate/init/free per-OS private data */ +extern int spi_osinit(sdioh_info_t *sd); +extern void spi_osfree(sdioh_info_t *sd); + +#define SPI_RW_FLAG_M BITFIELD_MASK(1) /* Bit [31] - R/W Command Bit */ +#define SPI_RW_FLAG_S 31 +#define SPI_ACCESS_M BITFIELD_MASK(1) /* Bit [30] - Fixed/Incr Access */ +#define SPI_ACCESS_S 30 +#define SPI_FUNCTION_M BITFIELD_MASK(2) /* Bit [29:28] - Function Number */ +#define SPI_FUNCTION_S 28 +#define SPI_REG_ADDR_M BITFIELD_MASK(17) /* Bit [27:11] - Address */ +#define SPI_REG_ADDR_S 11 +#define SPI_LEN_M BITFIELD_MASK(11) /* Bit [10:0] - Packet length */ +#define SPI_LEN_S 0 + +#endif /* _BCM_SPI_BRCM_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h b/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h new file mode 100644 index 0000000000000000000000000000000000000000..82eba6529ac1b974e9a5987251e1827eee3362f6 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h @@ -0,0 +1,633 @@ +/* + * SROM format definition. + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmsrom_fmt.h 473704 2014-04-29 15:49:57Z $ + */ + +#ifndef _bcmsrom_fmt_h_ +#define _bcmsrom_fmt_h_ + +#define SROM_MAXREV 11 /* max revisiton supported by driver */ + +/* Maximum srom: 12 Kilobits == 1536 bytes */ +#define SROM_MAX 1536 +#define SROM_MAXW 384 +#define VARS_MAX 4096 + +/* PCI fields */ +#define PCI_F0DEVID 48 + + +#define SROM_WORDS 64 + +#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */ + +#define SROM_SSID 2 +#define SROM_SVID 3 + +#define SROM_WL1LHMAXP 29 + +#define SROM_WL1LPAB0 30 +#define SROM_WL1LPAB1 31 +#define SROM_WL1LPAB2 32 + +#define SROM_WL1HPAB0 33 +#define SROM_WL1HPAB1 34 +#define SROM_WL1HPAB2 35 + +#define SROM_MACHI_IL0 36 +#define SROM_MACMID_IL0 37 +#define SROM_MACLO_IL0 38 +#define SROM_MACHI_ET0 39 +#define SROM_MACMID_ET0 40 +#define SROM_MACLO_ET0 41 +#define SROM_MACHI_ET1 42 +#define SROM_MACMID_ET1 43 +#define SROM_MACLO_ET1 44 +#define SROM3_MACHI 37 +#define SROM3_MACMID 38 +#define SROM3_MACLO 39 + +#define SROM_BXARSSI2G 40 +#define SROM_BXARSSI5G 41 + +#define SROM_TRI52G 42 +#define SROM_TRI5GHL 43 + +#define SROM_RXPO52G 45 + +#define SROM2_ENETPHY 45 + +#define SROM_AABREV 46 +/* Fields in AABREV */ +#define SROM_BR_MASK 0x00ff +#define SROM_CC_MASK 0x0f00 +#define SROM_CC_SHIFT 8 +#define SROM_AA0_MASK 0x3000 +#define SROM_AA0_SHIFT 12 +#define SROM_AA1_MASK 0xc000 +#define SROM_AA1_SHIFT 14 + +#define SROM_WL0PAB0 47 +#define SROM_WL0PAB1 48 +#define SROM_WL0PAB2 49 + +#define SROM_LEDBH10 50 +#define SROM_LEDBH32 51 + +#define SROM_WL10MAXP 52 + +#define SROM_WL1PAB0 53 +#define SROM_WL1PAB1 54 +#define SROM_WL1PAB2 55 + +#define SROM_ITT 56 + +#define SROM_BFL 57 +#define SROM_BFL2 28 +#define SROM3_BFL2 61 + +#define SROM_AG10 58 + +#define SROM_CCODE 59 + +#define SROM_OPO 60 + +#define SROM3_LEDDC 62 + +#define SROM_CRCREV 63 + +/* SROM Rev 4: Reallocate the software part of the srom to accomodate + * MIMO features. It assumes up to two PCIE functions and 440 bytes + * of useable srom i.e. the useable storage in chips with OTP that + * implements hardware redundancy. + */ + +#define SROM4_WORDS 220 + +#define SROM4_SIGN 32 +#define SROM4_SIGNATURE 0x5372 + +#define SROM4_BREV 33 + +#define SROM4_BFL0 34 +#define SROM4_BFL1 35 +#define SROM4_BFL2 36 +#define SROM4_BFL3 37 +#define SROM5_BFL0 37 +#define SROM5_BFL1 38 +#define SROM5_BFL2 39 +#define SROM5_BFL3 40 + +#define SROM4_MACHI 38 +#define SROM4_MACMID 39 +#define SROM4_MACLO 40 +#define SROM5_MACHI 41 +#define SROM5_MACMID 42 +#define SROM5_MACLO 43 + +#define SROM4_CCODE 41 +#define SROM4_REGREV 42 +#define SROM5_CCODE 34 +#define SROM5_REGREV 35 + +#define SROM4_LEDBH10 43 +#define SROM4_LEDBH32 44 +#define SROM5_LEDBH10 59 +#define SROM5_LEDBH32 60 + +#define SROM4_LEDDC 45 +#define SROM5_LEDDC 45 + +#define SROM4_AA 46 +#define SROM4_AA2G_MASK 0x00ff +#define SROM4_AA2G_SHIFT 0 +#define SROM4_AA5G_MASK 0xff00 +#define SROM4_AA5G_SHIFT 8 + +#define SROM4_AG10 47 +#define SROM4_AG32 48 + +#define SROM4_TXPID2G 49 +#define SROM4_TXPID5G 51 +#define SROM4_TXPID5GL 53 +#define SROM4_TXPID5GH 55 + +#define SROM4_TXRXC 61 +#define SROM4_TXCHAIN_MASK 0x000f +#define SROM4_TXCHAIN_SHIFT 0 +#define SROM4_RXCHAIN_MASK 0x00f0 +#define SROM4_RXCHAIN_SHIFT 4 +#define SROM4_SWITCH_MASK 0xff00 +#define SROM4_SWITCH_SHIFT 8 + + +/* Per-path fields */ +#define MAX_PATH_SROM 4 +#define SROM4_PATH0 64 +#define SROM4_PATH1 87 +#define SROM4_PATH2 110 +#define SROM4_PATH3 133 + +#define SROM4_2G_ITT_MAXP 0 +#define SROM4_2G_PA 1 +#define SROM4_5G_ITT_MAXP 5 +#define SROM4_5GLH_MAXP 6 +#define SROM4_5G_PA 7 +#define SROM4_5GL_PA 11 +#define SROM4_5GH_PA 15 + +/* Fields in the ITT_MAXP and 5GLH_MAXP words */ +#define B2G_MAXP_MASK 0xff +#define B2G_ITT_SHIFT 8 +#define B5G_MAXP_MASK 0xff +#define B5G_ITT_SHIFT 8 +#define B5GH_MAXP_MASK 0xff +#define B5GL_MAXP_SHIFT 8 + +/* All the miriad power offsets */ +#define SROM4_2G_CCKPO 156 +#define SROM4_2G_OFDMPO 157 +#define SROM4_5G_OFDMPO 159 +#define SROM4_5GL_OFDMPO 161 +#define SROM4_5GH_OFDMPO 163 +#define SROM4_2G_MCSPO 165 +#define SROM4_5G_MCSPO 173 +#define SROM4_5GL_MCSPO 181 +#define SROM4_5GH_MCSPO 189 +#define SROM4_CDDPO 197 +#define SROM4_STBCPO 198 +#define SROM4_BW40PO 199 +#define SROM4_BWDUPPO 200 + +#define SROM4_CRCREV 219 + + +/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. + * This is acombined srom for both MIMO and SISO boards, usable in + * the .130 4Kilobit OTP with hardware redundancy. + */ + +#define SROM8_SIGN 64 + +#define SROM8_BREV 65 + +#define SROM8_BFL0 66 +#define SROM8_BFL1 67 +#define SROM8_BFL2 68 +#define SROM8_BFL3 69 + +#define SROM8_MACHI 70 +#define SROM8_MACMID 71 +#define SROM8_MACLO 72 + +#define SROM8_CCODE 73 +#define SROM8_REGREV 74 + +#define SROM8_LEDBH10 75 +#define SROM8_LEDBH32 76 + +#define SROM8_LEDDC 77 + +#define SROM8_AA 78 + +#define SROM8_AG10 79 +#define SROM8_AG32 80 + +#define SROM8_TXRXC 81 + +#define SROM8_BXARSSI2G 82 +#define SROM8_BXARSSI5G 83 +#define SROM8_TRI52G 84 +#define SROM8_TRI5GHL 85 +#define SROM8_RXPO52G 86 + +#define SROM8_FEM2G 87 +#define SROM8_FEM5G 88 +#define SROM8_FEM_ANTSWLUT_MASK 0xf800 +#define SROM8_FEM_ANTSWLUT_SHIFT 11 +#define SROM8_FEM_TR_ISO_MASK 0x0700 +#define SROM8_FEM_TR_ISO_SHIFT 8 +#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 +#define SROM8_FEM_PDET_RANGE_SHIFT 3 +#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 +#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 +#define SROM8_FEM_TSSIPOS_MASK 0x0001 +#define SROM8_FEM_TSSIPOS_SHIFT 0 + +#define SROM8_THERMAL 89 + +/* Temp sense related entries */ +#define SROM8_MPWR_RAWTS 90 +#define SROM8_TS_SLP_OPT_CORRX 91 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ +#define SROM8_FOC_HWIQ_IQSWP 92 + +#define SROM8_EXTLNAGAIN 93 + +/* Temperature delta for PHY calibration */ +#define SROM8_PHYCAL_TEMPDELTA 94 + +/* Measured power 1 & 2, 0-13 bits at offset 95, MSB 2 bits are unused for now. */ +#define SROM8_MPWR_1_AND_2 95 + + +/* Per-path offsets & fields */ +#define SROM8_PATH0 96 +#define SROM8_PATH1 112 +#define SROM8_PATH2 128 +#define SROM8_PATH3 144 + +#define SROM8_2G_ITT_MAXP 0 +#define SROM8_2G_PA 1 +#define SROM8_5G_ITT_MAXP 4 +#define SROM8_5GLH_MAXP 5 +#define SROM8_5G_PA 6 +#define SROM8_5GL_PA 9 +#define SROM8_5GH_PA 12 + +/* All the miriad power offsets */ +#define SROM8_2G_CCKPO 160 + +#define SROM8_2G_OFDMPO 161 +#define SROM8_5G_OFDMPO 163 +#define SROM8_5GL_OFDMPO 165 +#define SROM8_5GH_OFDMPO 167 + +#define SROM8_2G_MCSPO 169 +#define SROM8_5G_MCSPO 177 +#define SROM8_5GL_MCSPO 185 +#define SROM8_5GH_MCSPO 193 + +#define SROM8_CDDPO 201 +#define SROM8_STBCPO 202 +#define SROM8_BW40PO 203 +#define SROM8_BWDUPPO 204 + +/* SISO PA parameters are in the path0 spaces */ +#define SROM8_SISO 96 + +/* Legacy names for SISO PA paramters */ +#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) +#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) +#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) +#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) +#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) +#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) +#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) +#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) +#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) +#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) +#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) +#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) +#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) +#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) +#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) + +#define SROM8_CRCREV 219 + +/* SROM REV 9 */ +#define SROM9_2GPO_CCKBW20 160 +#define SROM9_2GPO_CCKBW20UL 161 +#define SROM9_2GPO_LOFDMBW20 162 +#define SROM9_2GPO_LOFDMBW20UL 164 + +#define SROM9_5GLPO_LOFDMBW20 166 +#define SROM9_5GLPO_LOFDMBW20UL 168 +#define SROM9_5GMPO_LOFDMBW20 170 +#define SROM9_5GMPO_LOFDMBW20UL 172 +#define SROM9_5GHPO_LOFDMBW20 174 +#define SROM9_5GHPO_LOFDMBW20UL 176 + +#define SROM9_2GPO_MCSBW20 178 +#define SROM9_2GPO_MCSBW20UL 180 +#define SROM9_2GPO_MCSBW40 182 + +#define SROM9_5GLPO_MCSBW20 184 +#define SROM9_5GLPO_MCSBW20UL 186 +#define SROM9_5GLPO_MCSBW40 188 +#define SROM9_5GMPO_MCSBW20 190 +#define SROM9_5GMPO_MCSBW20UL 192 +#define SROM9_5GMPO_MCSBW40 194 +#define SROM9_5GHPO_MCSBW20 196 +#define SROM9_5GHPO_MCSBW20UL 198 +#define SROM9_5GHPO_MCSBW40 200 + +#define SROM9_PO_MCS32 202 +#define SROM9_PO_LOFDM40DUP 203 +#define SROM8_RXGAINERR_2G 205 +#define SROM8_RXGAINERR_5GL 206 +#define SROM8_RXGAINERR_5GM 207 +#define SROM8_RXGAINERR_5GH 208 +#define SROM8_RXGAINERR_5GU 209 +#define SROM8_SUBBAND_PPR 210 +#define SROM8_PCIEINGRESS_WAR 211 +#define SROM9_SAR 212 + +#define SROM8_NOISELVL_2G 213 +#define SROM8_NOISELVL_5GL 214 +#define SROM8_NOISELVL_5GM 215 +#define SROM8_NOISELVL_5GH 216 +#define SROM8_NOISELVL_5GU 217 +#define SROM8_NOISECALOFFSET 218 + +#define SROM9_REV_CRC 219 + +#define SROM10_CCKPWROFFSET 218 +#define SROM10_SIGN 219 +#define SROM10_SWCTRLMAP_2G 220 +#define SROM10_CRCREV 229 + +#define SROM10_WORDS 230 +#define SROM10_SIGNATURE SROM4_SIGNATURE + + +/* SROM REV 11 */ +#define SROM11_BREV 65 + +#define SROM11_BFL0 66 +#define SROM11_BFL1 67 +#define SROM11_BFL2 68 +#define SROM11_BFL3 69 +#define SROM11_BFL4 70 +#define SROM11_BFL5 71 + +#define SROM11_MACHI 72 +#define SROM11_MACMID 73 +#define SROM11_MACLO 74 + +#define SROM11_CCODE 75 +#define SROM11_REGREV 76 + +#define SROM11_LEDBH10 77 +#define SROM11_LEDBH32 78 + +#define SROM11_LEDDC 79 + +#define SROM11_AA 80 + +#define SROM11_AGBG10 81 +#define SROM11_AGBG2A0 82 +#define SROM11_AGA21 83 + +#define SROM11_TXRXC 84 + +#define SROM11_FEM_CFG1 85 +#define SROM11_FEM_CFG2 86 + +/* Masks and offsets for FEM_CFG */ +#define SROM11_FEMCTRL_MASK 0xf800 +#define SROM11_FEMCTRL_SHIFT 11 +#define SROM11_PAPDCAP_MASK 0x0400 +#define SROM11_PAPDCAP_SHIFT 10 +#define SROM11_TWORANGETSSI_MASK 0x0200 +#define SROM11_TWORANGETSSI_SHIFT 9 +#define SROM11_PDGAIN_MASK 0x01f0 +#define SROM11_PDGAIN_SHIFT 4 +#define SROM11_EPAGAIN_MASK 0x000e +#define SROM11_EPAGAIN_SHIFT 1 +#define SROM11_TSSIPOSSLOPE_MASK 0x0001 +#define SROM11_TSSIPOSSLOPE_SHIFT 0 +#define SROM11_GAINCTRLSPH_MASK 0xf800 +#define SROM11_GAINCTRLSPH_SHIFT 11 + +#define SROM11_THERMAL 87 +#define SROM11_MPWR_RAWTS 88 +#define SROM11_TS_SLP_OPT_CORRX 89 +#define SROM11_XTAL_FREQ 90 +#define SROM11_5GB0_4080_W0_A1 91 +#define SROM11_PHYCAL_TEMPDELTA 92 +#define SROM11_MPWR_1_AND_2 93 +#define SROM11_5GB0_4080_W1_A1 94 +#define SROM11_TSSIFLOOR_2G 95 +#define SROM11_TSSIFLOOR_5GL 96 +#define SROM11_TSSIFLOOR_5GM 97 +#define SROM11_TSSIFLOOR_5GH 98 +#define SROM11_TSSIFLOOR_5GU 99 + +/* Masks and offsets for Terrmal parameters */ +#define SROM11_TEMPS_PERIOD_MASK 0xf0 +#define SROM11_TEMPS_PERIOD_SHIFT 4 +#define SROM11_TEMPS_HYSTERESIS_MASK 0x0f +#define SROM11_TEMPS_HYSTERESIS_SHIFT 0 +#define SROM11_TEMPCORRX_MASK 0xfc +#define SROM11_TEMPCORRX_SHIFT 2 +#define SROM11_TEMPSENSE_OPTION_MASK 0x3 +#define SROM11_TEMPSENSE_OPTION_SHIFT 0 + +#define SROM11_PDOFF_2G_40M_A0_MASK 0x000f +#define SROM11_PDOFF_2G_40M_A0_SHIFT 0 +#define SROM11_PDOFF_2G_40M_A1_MASK 0x00f0 +#define SROM11_PDOFF_2G_40M_A1_SHIFT 4 +#define SROM11_PDOFF_2G_40M_A2_MASK 0x0f00 +#define SROM11_PDOFF_2G_40M_A2_SHIFT 8 +#define SROM11_PDOFF_2G_40M_VALID_MASK 0x8000 +#define SROM11_PDOFF_2G_40M_VALID_SHIFT 15 + +#define SROM11_PDOFF_2G_40M 100 +#define SROM11_PDOFF_40M_A0 101 +#define SROM11_PDOFF_40M_A1 102 +#define SROM11_PDOFF_40M_A2 103 +#define SROM11_5GB0_4080_W2_A1 103 +#define SROM11_PDOFF_80M_A0 104 +#define SROM11_PDOFF_80M_A1 105 +#define SROM11_PDOFF_80M_A2 106 +#define SROM11_5GB1_4080_W0_A1 106 + +#define SROM11_SUBBAND5GVER 107 + +/* Per-path fields and offset */ +#define MAX_PATH_SROM_11 3 +#define SROM11_PATH0 108 +#define SROM11_PATH1 128 +#define SROM11_PATH2 148 + +#define SROM11_2G_MAXP 0 +#define SROM11_5GB1_4080_PA 0 +#define SROM11_2G_PA 1 +#define SROM11_5GB2_4080_PA 2 +#define SROM11_RXGAINS1 4 +#define SROM11_RXGAINS 5 +#define SROM11_5GB3_4080_PA 5 +#define SROM11_5GB1B0_MAXP 6 +#define SROM11_5GB3B2_MAXP 7 +#define SROM11_5GB0_PA 8 +#define SROM11_5GB1_PA 11 +#define SROM11_5GB2_PA 14 +#define SROM11_5GB3_PA 17 + +/* Masks and offsets for rxgains */ +#define SROM11_RXGAINS5GTRELNABYPA_MASK 0x8000 +#define SROM11_RXGAINS5GTRELNABYPA_SHIFT 15 +#define SROM11_RXGAINS5GTRISOA_MASK 0x7800 +#define SROM11_RXGAINS5GTRISOA_SHIFT 11 +#define SROM11_RXGAINS5GELNAGAINA_MASK 0x0700 +#define SROM11_RXGAINS5GELNAGAINA_SHIFT 8 +#define SROM11_RXGAINS2GTRELNABYPA_MASK 0x0080 +#define SROM11_RXGAINS2GTRELNABYPA_SHIFT 7 +#define SROM11_RXGAINS2GTRISOA_MASK 0x0078 +#define SROM11_RXGAINS2GTRISOA_SHIFT 3 +#define SROM11_RXGAINS2GELNAGAINA_MASK 0x0007 +#define SROM11_RXGAINS2GELNAGAINA_SHIFT 0 +#define SROM11_RXGAINS5GHTRELNABYPA_MASK 0x8000 +#define SROM11_RXGAINS5GHTRELNABYPA_SHIFT 15 +#define SROM11_RXGAINS5GHTRISOA_MASK 0x7800 +#define SROM11_RXGAINS5GHTRISOA_SHIFT 11 +#define SROM11_RXGAINS5GHELNAGAINA_MASK 0x0700 +#define SROM11_RXGAINS5GHELNAGAINA_SHIFT 8 +#define SROM11_RXGAINS5GMTRELNABYPA_MASK 0x0080 +#define SROM11_RXGAINS5GMTRELNABYPA_SHIFT 7 +#define SROM11_RXGAINS5GMTRISOA_MASK 0x0078 +#define SROM11_RXGAINS5GMTRISOA_SHIFT 3 +#define SROM11_RXGAINS5GMELNAGAINA_MASK 0x0007 +#define SROM11_RXGAINS5GMELNAGAINA_SHIFT 0 + +/* Power per rate */ +#define SROM11_CCKBW202GPO 168 +#define SROM11_CCKBW20UL2GPO 169 +#define SROM11_MCSBW202GPO 170 +#define SROM11_MCSBW202GPO_1 171 +#define SROM11_MCSBW402GPO 172 +#define SROM11_MCSBW402GPO_1 173 +#define SROM11_DOT11AGOFDMHRBW202GPO 174 +#define SROM11_OFDMLRBW202GPO 175 + +#define SROM11_MCSBW205GLPO 176 +#define SROM11_MCSBW205GLPO_1 177 +#define SROM11_MCSBW405GLPO 178 +#define SROM11_MCSBW405GLPO_1 179 +#define SROM11_MCSBW805GLPO 180 +#define SROM11_MCSBW805GLPO_1 181 +#define SROM11_RPCAL_2G 182 +#define SROM11_RPCAL_5GL 183 +#define SROM11_MCSBW205GMPO 184 +#define SROM11_MCSBW205GMPO_1 185 +#define SROM11_MCSBW405GMPO 186 +#define SROM11_MCSBW405GMPO_1 187 +#define SROM11_MCSBW805GMPO 188 +#define SROM11_MCSBW805GMPO_1 189 +#define SROM11_RPCAL_5GM 190 +#define SROM11_RPCAL_5GH 191 +#define SROM11_MCSBW205GHPO 192 +#define SROM11_MCSBW205GHPO_1 193 +#define SROM11_MCSBW405GHPO 194 +#define SROM11_MCSBW405GHPO_1 195 +#define SROM11_MCSBW805GHPO 196 +#define SROM11_MCSBW805GHPO_1 197 +#define SROM11_RPCAL_5GU 198 +#define SROM11_PDOFF_2G_CCK 199 +#define SROM11_MCSLR5GLPO 200 +#define SROM11_MCSLR5GMPO 201 +#define SROM11_MCSLR5GHPO 202 + +#define SROM11_SB20IN40HRPO 203 +#define SROM11_SB20IN80AND160HR5GLPO 204 +#define SROM11_SB40AND80HR5GLPO 205 +#define SROM11_SB20IN80AND160HR5GMPO 206 +#define SROM11_SB40AND80HR5GMPO 207 +#define SROM11_SB20IN80AND160HR5GHPO 208 +#define SROM11_SB40AND80HR5GHPO 209 +#define SROM11_SB20IN40LRPO 210 +#define SROM11_SB20IN80AND160LR5GLPO 211 +#define SROM11_SB40AND80LR5GLPO 212 +#define SROM11_TXIDXCAP2G 212 +#define SROM11_SB20IN80AND160LR5GMPO 213 +#define SROM11_SB40AND80LR5GMPO 214 +#define SROM11_TXIDXCAP5G 214 +#define SROM11_SB20IN80AND160LR5GHPO 215 +#define SROM11_SB40AND80LR5GHPO 216 + +#define SROM11_DOT11AGDUPHRPO 217 +#define SROM11_DOT11AGDUPLRPO 218 + +/* MISC */ +#define SROM11_PCIEINGRESS_WAR 220 +#define SROM11_SAR 221 + +#define SROM11_NOISELVL_2G 222 +#define SROM11_NOISELVL_5GL 223 +#define SROM11_NOISELVL_5GM 224 +#define SROM11_NOISELVL_5GH 225 +#define SROM11_NOISELVL_5GU 226 + +#define SROM11_RXGAINERR_2G 227 +#define SROM11_RXGAINERR_5GL 228 +#define SROM11_RXGAINERR_5GM 229 +#define SROM11_RXGAINERR_5GH 230 +#define SROM11_RXGAINERR_5GU 231 + +#define SROM11_SIGN 64 +#define SROM11_CRCREV 233 + +#define SROM11_WORDS 234 +#define SROM11_SIGNATURE 0x0634 + +typedef struct { + uint8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */ + uint8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ + uint8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */ + uint8 triso; /* TR switch isolation */ + uint8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */ +} srom_fem_t; + +#endif /* _bcmsrom_fmt_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h new file mode 100644 index 0000000000000000000000000000000000000000..6de9d3c4ad9f5c101c124a027dc1ba83eb26d33f --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h @@ -0,0 +1,1029 @@ +/* + * Table that encodes the srom formats for PCI/PCIe NICs. + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmsrom_tbl.h 471127 2014-04-17 23:24:23Z $ + */ + +#ifndef _bcmsrom_tbl_h_ +#define _bcmsrom_tbl_h_ + +#include "sbpcmcia.h" +#include "wlioctl.h" +#include <bcmsrom_fmt.h> + +typedef struct { + const char *name; + uint32 revmask; + uint32 flags; + uint16 off; + uint16 mask; +} sromvar_t; + +#define SRFL_MORE 1 /* value continues as described by the next entry */ +#define SRFL_NOFFS 2 /* value bits can't be all one's */ +#define SRFL_PRHEX 4 /* value is in hexdecimal format */ +#define SRFL_PRSIGN 8 /* value is in signed decimal format */ +#define SRFL_CCODE 0x10 /* value is in country code format */ +#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ +#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ +#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ +#define SRFL_ARRAY 0x100 /* value is in an array. All elements EXCEPT FOR THE LAST + * ONE in the array should have this flag set. + */ + + +#define SROM_DEVID_PCIE 48 + +/* Assumptions: + * - Ethernet address spans across 3 consective words + * + * Table rules: + * - Add multiple entries next to each other if a value spans across multiple words + * (even multiple fields in the same word) with each entry except the last having + * it's SRFL_MORE bit set. + * - Ethernet address entry does not follow above rule and must not have SRFL_MORE + * bit set. Its SRFL_ETHADDR bit implies it takes multiple words. + * - The last entry's name field must be NULL to indicate the end of the table. Other + * entries must have non-NULL name. + */ + +static const sromvar_t pci_sromvars[] = { +#if defined(CABLECPE) + {"devid", 0xffffff00, SRFL_PRHEX, PCI_F0DEVID, 0xffff}, +#elif defined(BCMPCIEDEV) && defined(BCMPCIEDEV_ENABLED) + {"devid", 0xffffff00, SRFL_PRHEX, SROM_DEVID_PCIE, 0xffff}, +#else + {"devid", 0xffffff00, SRFL_PRHEX|SRFL_NOVAR, PCI_F0DEVID, 0xffff}, +#endif + {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, + {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, + {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, + {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, + {"boardflags", 0x00000004, SRFL_PRHEX|SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM_BFL2, 0xffff}, + {"boardflags", 0x00000008, SRFL_PRHEX|SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM3_BFL2, 0xffff}, + {"boardflags", 0x00000010, SRFL_PRHEX|SRFL_MORE, SROM4_BFL0, 0xffff}, + {"", 0, 0, SROM4_BFL1, 0xffff}, + {"boardflags", 0x000000e0, SRFL_PRHEX|SRFL_MORE, SROM5_BFL0, 0xffff}, + {"", 0, 0, SROM5_BFL1, 0xffff}, + {"boardflags", 0xffffff00, SRFL_PRHEX|SRFL_MORE, SROM8_BFL0, 0xffff}, + {"", 0, 0, SROM8_BFL1, 0xffff}, + {"boardflags2", 0x00000010, SRFL_PRHEX|SRFL_MORE, SROM4_BFL2, 0xffff}, + {"", 0, 0, SROM4_BFL3, 0xffff}, + {"boardflags2", 0x000000e0, SRFL_PRHEX|SRFL_MORE, SROM5_BFL2, 0xffff}, + {"", 0, 0, SROM5_BFL3, 0xffff}, + {"boardflags2", 0xffffff00, SRFL_PRHEX|SRFL_MORE, SROM8_BFL2, 0xffff}, + {"", 0, 0, SROM8_BFL3, 0xffff}, + {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, + {"subvid", 0xfffffffc, SRFL_PRHEX, SROM_SVID, 0xffff}, + {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, + {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff}, + {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff}, + {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff}, + {"boardnum", 0x00000700, 0, SROM8_MACLO, 0xffff}, + {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, + {"regrev", 0x00000008, 0, SROM_OPO, 0xff00}, + {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff}, + {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff}, + {"regrev", 0x00000700, 0, SROM8_REGREV, 0x00ff}, + {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, + {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, + {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, + {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, + {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, + {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, + {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, + {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, + {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, + {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, + {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, + {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, + {"ledbh0", 0x00000700, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, + {"ledbh1", 0x00000700, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, + {"ledbh2", 0x00000700, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, + {"ledbh3", 0x00000700, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, + {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, + {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, + {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, + {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff}, + {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, + {"pa0b0", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, + {"pa0b1", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, + {"pa0b2", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, + {"pa0itssit", 0x00000700, 0, SROM8_W0_ITTMAXP, 0xff00}, + {"pa0maxpwr", 0x00000700, 0, SROM8_W0_ITTMAXP, 0x00ff}, + {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff}, + {"opo", 0x00000700, 0, SROM8_2G_OFDMPO, 0x00ff}, + {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, + {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff}, + {"aa2g", 0x00000700, 0, SROM8_AA, 0x00ff}, + {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, + {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00}, + {"aa5g", 0x00000700, 0, SROM8_AA, 0xff00}, + {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff}, + {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00}, + {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff}, + {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00}, + {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff}, + {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00}, + {"ag0", 0x00000700, 0, SROM8_AG10, 0x00ff}, + {"ag1", 0x00000700, 0, SROM8_AG10, 0xff00}, + {"ag2", 0x00000700, 0, SROM8_AG32, 0x00ff}, + {"ag3", 0x00000700, 0, SROM8_AG32, 0xff00}, + {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, + {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, + {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, + {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, + {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, + {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, + {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, + {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, + {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, + {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00}, + {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, + {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, + {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, + {"pa1b0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, + {"pa1b1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, + {"pa1b2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, + {"pa1lob0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff}, + {"pa1lob1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff}, + {"pa1lob2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff}, + {"pa1hib0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff}, + {"pa1hib1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff}, + {"pa1hib2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff}, + {"pa1itssit", 0x00000700, 0, SROM8_W1_ITTMAXP, 0xff00}, + {"pa1maxpwr", 0x00000700, 0, SROM8_W1_ITTMAXP, 0x00ff}, + {"pa1lomaxpwr", 0x00000700, 0, SROM8_W1_MAXP_LCHC, 0xff00}, + {"pa1himaxpwr", 0x00000700, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, + {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, + {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, + {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, + {"bxa2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x1800}, + {"rssisav2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x0700}, + {"rssismc2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x000f}, + {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, + {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, + {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, + {"bxa5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x1800}, + {"rssisav5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x0700}, + {"rssismc5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x000f}, + {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff}, + {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00}, + {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, + {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00}, + {"tri2g", 0x00000700, 0, SROM8_TRI52G, 0x00ff}, + {"tri5g", 0x00000700, 0, SROM8_TRI52G, 0xff00}, + {"tri5gl", 0x00000700, 0, SROM8_TRI5GHL, 0x00ff}, + {"tri5gh", 0x00000700, 0, SROM8_TRI5GHL, 0xff00}, + {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, + {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, + {"rxpo2g", 0x00000700, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, + {"rxpo5g", 0x00000700, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, + {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK}, + {"txchain", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK}, + {"tssipos2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK}, + {"tssipos5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK}, + {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, + {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, + {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, + {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, + {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, + {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, + {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, + {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, + {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, + {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, + {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, + {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, + {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, + {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, + {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, + {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, + + {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, + {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, + {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, + {"ccode", 0x00000700, SRFL_CCODE, SROM8_CCODE, 0xffff}, + {"macaddr", 0x00000700, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, + {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, + {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, + {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, + {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff}, + {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff}, + {"leddc", 0x00000700, SRFL_NOFFS|SRFL_LEDDC, SROM8_LEDDC, 0xffff}, + {"leddc", 0x000000e0, SRFL_NOFFS|SRFL_LEDDC, SROM5_LEDDC, 0xffff}, + {"leddc", 0x00000010, SRFL_NOFFS|SRFL_LEDDC, SROM4_LEDDC, 0xffff}, + {"leddc", 0x00000008, SRFL_NOFFS|SRFL_LEDDC, SROM3_LEDDC, 0xffff}, + + {"tempthresh", 0x00000700, 0, SROM8_THERMAL, 0xff00}, + {"tempoffset", 0x00000700, 0, SROM8_THERMAL, 0x00ff}, + {"rawtempsense", 0x00000700, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff}, + {"measpower", 0x00000700, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00}, + {"tempsense_slope", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x00ff}, + {"tempcorrx", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00}, + {"tempsense_option", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x0300}, + {"freqoffset_corr", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x000f}, + {"iqcal_swp_dis", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010}, + {"hw_iqcal_en", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020}, + {"elna2g", 0x00000700, 0, SROM8_EXTLNAGAIN, 0x00ff}, + {"elna5g", 0x00000700, 0, SROM8_EXTLNAGAIN, 0xff00}, + {"phycal_tempdelta", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff}, + {"temps_period", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0x0f00}, + {"temps_hysteresis", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0xf000}, + {"measpower1", 0x00000700, SRFL_PRHEX, SROM8_MPWR_1_AND_2, 0x007f}, + {"measpower2", 0x00000700, SRFL_PRHEX, SROM8_MPWR_1_AND_2, 0x3f80}, + + {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, + {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, + {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, + {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, + {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, + {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, + {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff}, + {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff}, + {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff}, + {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, + {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff}, + {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff}, + {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff}, + {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff}, + + /* power per rate from sromrev 9 */ + {"cckbw202gpo", 0x00000600, 0, SROM9_2GPO_CCKBW20, 0xffff}, + {"cckbw20ul2gpo", 0x00000600, 0, SROM9_2GPO_CCKBW20UL, 0xffff}, + {"legofdmbw202gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul2gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff}, + {"mcsbw202gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul2gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw402gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff}, + {"mcs32po", 0x00000600, 0, SROM9_PO_MCS32, 0xffff}, + {"legofdm40duppo", 0x00000600, 0, SROM9_PO_LOFDM40DUP, 0xffff}, + {"pcieingress_war", 0x00000700, 0, SROM8_PCIEINGRESS_WAR, 0xf}, + {"rxgainerr2ga0", 0x00000700, 0, SROM8_RXGAINERR_2G, 0x003f}, + {"rxgainerr2ga1", 0x00000700, 0, SROM8_RXGAINERR_2G, 0x07c0}, + {"rxgainerr2ga2", 0x00000700, 0, SROM8_RXGAINERR_2G, 0xf800}, + {"rxgainerr5gla0", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0x003f}, + {"rxgainerr5gla1", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0x07c0}, + {"rxgainerr5gla2", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0xf800}, + {"rxgainerr5gma0", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0x003f}, + {"rxgainerr5gma1", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0x07c0}, + {"rxgainerr5gma2", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0xf800}, + {"rxgainerr5gha0", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0x003f}, + {"rxgainerr5gha1", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0x07c0}, + {"rxgainerr5gha2", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0xf800}, + {"rxgainerr5gua0", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0x003f}, + {"rxgainerr5gua1", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0x07c0}, + {"rxgainerr5gua2", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0xf800}, + {"sar2g", 0x00000600, 0, SROM9_SAR, 0x00ff}, + {"sar5g", 0x00000600, 0, SROM9_SAR, 0xff00}, + {"noiselvl2ga0", 0x00000700, 0, SROM8_NOISELVL_2G, 0x001f}, + {"noiselvl2ga1", 0x00000700, 0, SROM8_NOISELVL_2G, 0x03e0}, + {"noiselvl2ga2", 0x00000700, 0, SROM8_NOISELVL_2G, 0x7c00}, + {"noiselvl5gla0", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x001f}, + {"noiselvl5gla1", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x03e0}, + {"noiselvl5gla2", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x7c00}, + {"noiselvl5gma0", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x001f}, + {"noiselvl5gma1", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x03e0}, + {"noiselvl5gma2", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x7c00}, + {"noiselvl5gha0", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x001f}, + {"noiselvl5gha1", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x03e0}, + {"noiselvl5gha2", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x7c00}, + {"noiselvl5gua0", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x001f}, + {"noiselvl5gua1", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x03e0}, + {"noiselvl5gua2", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x7c00}, + {"noisecaloffset", 0x00000300, 0, SROM8_NOISECALOFFSET, 0x00ff}, + {"noisecaloffset5g", 0x00000300, 0, SROM8_NOISECALOFFSET, 0xff00}, + {"subband5gver", 0x00000700, 0, SROM8_SUBBAND_PPR, 0x7}, + + {"cckPwrOffset", 0x00000400, 0, SROM10_CCKPWROFFSET, 0xffff}, + /* swctrlmap_2g array, note that the last element doesn't have SRFL_ARRAY flag set */ + {"swctrlmap_2g", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 1, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 2, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 3, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 4, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 5, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 6, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 7, 0xffff}, + {"", 0x00000400, SRFL_PRHEX, SROM10_SWCTRLMAP_2G + 8, 0xffff}, + + /* sromrev 11 */ + {"boardflags3", 0xfffff800, SRFL_PRHEX|SRFL_MORE, SROM11_BFL4, 0xffff}, + {"", 0, 0, SROM11_BFL5, 0xffff}, + {"boardnum", 0xfffff800, 0, SROM11_MACLO, 0xffff}, + {"macaddr", 0xfffff800, SRFL_ETHADDR, SROM11_MACHI, 0xffff}, + {"ccode", 0xfffff800, SRFL_CCODE, SROM11_CCODE, 0xffff}, + {"regrev", 0xfffff800, 0, SROM11_REGREV, 0x00ff}, + {"ledbh0", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH10, 0x00ff}, + {"ledbh1", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH10, 0xff00}, + {"ledbh2", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH32, 0x00ff}, + {"ledbh3", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH32, 0xff00}, + {"leddc", 0xfffff800, SRFL_NOFFS|SRFL_LEDDC, SROM11_LEDDC, 0xffff}, + {"aa2g", 0xfffff800, 0, SROM11_AA, 0x00ff}, + {"aa5g", 0xfffff800, 0, SROM11_AA, 0xff00}, + {"agbg0", 0xfffff800, 0, SROM11_AGBG10, 0xff00}, + {"agbg1", 0xfffff800, 0, SROM11_AGBG10, 0x00ff}, + {"agbg2", 0xfffff800, 0, SROM11_AGBG2A0, 0xff00}, + {"aga0", 0xfffff800, 0, SROM11_AGBG2A0, 0x00ff}, + {"aga1", 0xfffff800, 0, SROM11_AGA21, 0xff00}, + {"aga2", 0xfffff800, 0, SROM11_AGA21, 0x00ff}, + {"txchain", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_SWITCH_MASK}, + + {"tssiposslope2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0001}, + {"epagain2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x000e}, + {"pdgain2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x01f0}, + {"tworangetssi2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0200}, + {"papdcap2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0400}, + {"femctrl", 0xfffff800, 0, SROM11_FEM_CFG1, 0xf800}, + + {"tssiposslope5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0001}, + {"epagain5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x000e}, + {"pdgain5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x01f0}, + {"tworangetssi5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0200}, + {"papdcap5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0400}, + {"gainctrlsph", 0xfffff800, 0, SROM11_FEM_CFG2, 0xf800}, + + {"tempthresh", 0xfffff800, 0, SROM11_THERMAL, 0xff00}, + {"tempoffset", 0xfffff800, 0, SROM11_THERMAL, 0x00ff}, + {"rawtempsense", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_RAWTS, 0x01ff}, + {"measpower", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_RAWTS, 0xfe00}, + {"tempsense_slope", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0x00ff}, + {"tempcorrx", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0xfc00}, + {"tempsense_option", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0x0300}, + {"xtalfreq", 0xfffff800, 0, SROM11_XTAL_FREQ, 0xffff}, + /* Special PA Params for 4350 5G Band, 40/80 MHz BW Ant #1 */ + {"pa5gbw4080a1", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_4080_W0_A1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_4080_W1_A1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_4080_W2_A1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_4080_W0_A1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_4080_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_4080_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_4080_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_4080_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_4080_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_4080_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_4080_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_PATH2 + SROM11_5GB3_4080_PA + 2, 0xffff}, + {"phycal_tempdelta", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0x00ff}, + {"temps_period", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0x0f00}, + {"temps_hysteresis", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0xf000}, + {"measpower1", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_1_AND_2, 0x007f}, + {"measpower2", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_1_AND_2, 0x3f80}, + {"tssifloor2g", 0xfffff800, SRFL_PRHEX, SROM11_TSSIFLOOR_2G, 0x03ff}, + {"tssifloor5g", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_TSSIFLOOR_5GL, 0x03ff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_TSSIFLOOR_5GM, 0x03ff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_TSSIFLOOR_5GH, 0x03ff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_TSSIFLOOR_5GU, 0x03ff}, + {"pdoffset2g40ma0", 0xfffff800, 0, SROM11_PDOFF_2G_40M, 0x000f}, + {"pdoffset2g40ma1", 0xfffff800, 0, SROM11_PDOFF_2G_40M, 0x00f0}, + {"pdoffset2g40ma2", 0xfffff800, 0, SROM11_PDOFF_2G_40M, 0x0f00}, + {"pdoffset2g40mvalid", 0xfffff800, 0, SROM11_PDOFF_2G_40M, 0x8000}, + {"pdoffset40ma0", 0xfffff800, 0, SROM11_PDOFF_40M_A0, 0xffff}, + {"pdoffset40ma1", 0xfffff800, 0, SROM11_PDOFF_40M_A1, 0xffff}, + {"pdoffset40ma2", 0xfffff800, 0, SROM11_PDOFF_40M_A2, 0xffff}, + {"pdoffset80ma0", 0xfffff800, 0, SROM11_PDOFF_80M_A0, 0xffff}, + {"pdoffset80ma1", 0xfffff800, 0, SROM11_PDOFF_80M_A1, 0xffff}, + {"pdoffset80ma2", 0xfffff800, 0, SROM11_PDOFF_80M_A2, 0xffff}, + + {"subband5gver", 0xfffff800, SRFL_PRHEX, SROM11_SUBBAND5GVER, 0xffff}, + {"paparambwver", 0xfffff800, 0, SROM11_MCSLR5GLPO, 0xf000}, + /* Special PA Params for 4350 5G Band, 40/80 MHz BW Ant #0 */ + {"pa5gbw4080a0", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 +SROM11_5GB0_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB0_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB0_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_PATH2 + SROM11_5GB3_PA + 2, 0xffff}, + /* Special PA Params for 4335 5G Band, 40 MHz BW */ + {"pa5gbw40a0", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB0_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB0_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB0_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB1_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB1_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB1_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB2_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB2_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB2_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB3_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_5GB3_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_PATH1 + SROM11_5GB3_PA + 2, 0xffff}, + /* Special PA Params for 4335 5G Band, 80 MHz BW */ + {"pa5gbw80a0", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB0_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB0_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB0_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB1_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB2_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH2 + SROM11_5GB3_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_PATH2 + SROM11_5GB3_PA + 2, 0xffff}, + /* Special PA Params for 4335 2G Band, CCK */ + {"pa2gccka0", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_2G_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_PATH1 + SROM11_2G_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_PATH1 + SROM11_2G_PA + 2, 0xffff}, + + /* power per rate */ + {"cckbw202gpo", 0xfffff800, 0, SROM11_CCKBW202GPO, 0xffff}, + {"cckbw20ul2gpo", 0xfffff800, 0, SROM11_CCKBW20UL2GPO, 0xffff}, + {"mcsbw202gpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW202GPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW202GPO_1, 0xffff}, + {"mcsbw402gpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW402GPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW402GPO_1, 0xffff}, + {"dot11agofdmhrbw202gpo", 0xfffff800, 0, SROM11_DOT11AGOFDMHRBW202GPO, 0xffff}, + {"ofdmlrbw202gpo", 0xfffff800, 0, SROM11_OFDMLRBW202GPO, 0xffff}, + {"mcsbw205glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GLPO_1, 0xffff}, + {"mcsbw405glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GLPO_1, 0xffff}, + {"mcsbw805glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GLPO_1, 0xffff}, + {"mcsbw205gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GMPO_1, 0xffff}, + {"mcsbw405gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GMPO_1, 0xffff}, + {"mcsbw805gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GMPO_1, 0xffff}, + {"mcsbw205ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GHPO_1, 0xffff}, + {"mcsbw405ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GHPO_1, 0xffff}, + {"mcsbw805ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GHPO_1, 0xffff}, + {"mcslr5glpo", 0xfffff800, 0, SROM11_MCSLR5GLPO, 0x0fff}, + {"mcslr5gmpo", 0xfffff800, 0, SROM11_MCSLR5GMPO, 0xffff}, + {"mcslr5ghpo", 0xfffff800, 0, SROM11_MCSLR5GHPO, 0xffff}, + {"sb20in40hrpo", 0xfffff800, 0, SROM11_SB20IN40HRPO, 0xffff}, + {"sb20in80and160hr5glpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GLPO, 0xffff}, + {"sb40and80hr5glpo", 0xfffff800, 0, SROM11_SB40AND80HR5GLPO, 0xffff}, + {"sb20in80and160hr5gmpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GMPO, 0xffff}, + {"sb40and80hr5gmpo", 0xfffff800, 0, SROM11_SB40AND80HR5GMPO, 0xffff}, + {"sb20in80and160hr5ghpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GHPO, 0xffff}, + {"sb40and80hr5ghpo", 0xfffff800, 0, SROM11_SB40AND80HR5GHPO, 0xffff}, + {"sb20in40lrpo", 0xfffff800, 0, SROM11_SB20IN40LRPO, 0xffff}, + {"sb20in80and160lr5glpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GLPO, 0xffff}, + {"sb40and80lr5glpo", 0xfffff800, 0, SROM11_SB40AND80LR5GLPO, 0xffff}, + {"sb20in80and160lr5gmpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GMPO, 0xffff}, + {"sb40and80lr5gmpo", 0xfffff800, 0, SROM11_SB40AND80LR5GMPO, 0xffff}, + {"sb20in80and160lr5ghpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GHPO, 0xffff}, + {"sb40and80lr5ghpo", 0xfffff800, 0, SROM11_SB40AND80LR5GHPO, 0xffff}, + {"dot11agduphrpo", 0xfffff800, 0, SROM11_DOT11AGDUPHRPO, 0xffff}, + {"dot11agduplrpo", 0xfffff800, 0, SROM11_DOT11AGDUPLRPO, 0xffff}, + + /* Misc */ + {"sar2g", 0xfffff800, 0, SROM11_SAR, 0x00ff}, + {"sar5g", 0xfffff800, 0, SROM11_SAR, 0xff00}, + + {"noiselvl2ga0", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x001f}, + {"noiselvl2ga1", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x03e0}, + {"noiselvl2ga2", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x7c00}, + {"noiselvl5ga0", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GL, 0x001f}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GM, 0x001f}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GH, 0x001f}, + {"", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x001f}, + {"noiselvl5ga1", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GL, 0x03e0}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GM, 0x03e0}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GH, 0x03e0}, + {"", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x03e0}, + {"noiselvl5ga2", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GL, 0x7c00}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GM, 0x7c00}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_NOISELVL_5GH, 0x7c00}, + {"", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x7c00}, + + {"rxgainerr2ga0", 0xfffff800, 0, SROM11_RXGAINERR_2G, 0x003f}, + {"rxgainerr2ga1", 0xfffff800, 0, SROM11_RXGAINERR_2G, 0x07c0}, + {"rxgainerr2ga2", 0xfffff800, 0, SROM11_RXGAINERR_2G, 0xf800}, + {"rxgainerr5ga0", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GL, 0x003f}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GM, 0x003f}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GH, 0x003f}, + {"", 0xfffff800, 0, SROM11_RXGAINERR_5GU, 0x003f}, + {"rxgainerr5ga1", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GL, 0x07c0}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GM, 0x07c0}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GH, 0x07c0}, + {"", 0xfffff800, 0, SROM11_RXGAINERR_5GU, 0x07c0}, + {"rxgainerr5ga2", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GL, 0xf800}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GM, 0xf800}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_RXGAINERR_5GH, 0xf800}, + {"", 0xfffff800, 0, SROM11_RXGAINERR_5GU, 0xf800}, + {"rpcal2g", 0xfffff800, 0, SROM11_RPCAL_2G, 0xffff}, + {"rpcal5gb0", 0xfffff800, 0, SROM11_RPCAL_5GL, 0xffff}, + {"rpcal5gb1", 0xfffff800, 0, SROM11_RPCAL_5GM, 0xffff}, + {"rpcal5gb2", 0xfffff800, 0, SROM11_RPCAL_5GH, 0xffff}, + {"rpcal5gb3", 0xfffff800, 0, SROM11_RPCAL_5GU, 0xffff}, + {"txidxcap2g", 0xfffff800, 0, SROM11_TXIDXCAP2G, 0x0ff0}, + {"txidxcap5g", 0xfffff800, 0, SROM11_TXIDXCAP5G, 0x0ff0}, + {"pdoffsetcckma0", 0xfffff800, 0, SROM11_PDOFF_2G_CCK, 0x000f}, + {"pdoffsetcckma1", 0xfffff800, 0, SROM11_PDOFF_2G_CCK, 0x00f0}, + {"pdoffsetcckma2", 0xfffff800, 0, SROM11_PDOFF_2G_CCK, 0x0f00}, + {NULL, 0, 0, 0, 0} +}; + +static const sromvar_t perpath_pci_sromvars[] = { + {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, + {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, + {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, + {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, + {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, + {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, + {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, + {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff}, + {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff}, + {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, + {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff}, + {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff}, + {"maxp2ga", 0x00000700, 0, SROM8_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0x00000700, 0, SROM8_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0x00000700, 0, SROM8_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA, 0xffff}, + {"pa2gw1a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff}, + {"maxp5ga", 0x00000700, 0, SROM8_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0x00000700, 0, SROM8_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0x00000700, 0, SROM8_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA, 0xffff}, + {"pa5gw1a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff}, + {"pa5glw0a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA, 0xffff}, + {"pa5glw1a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff}, + {"pa5ghw0a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA, 0xffff}, + {"pa5ghw1a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff}, + + /* sromrev 11 */ + {"maxp2ga", 0xfffff800, 0, SROM11_2G_MAXP, 0x00ff}, + {"pa2ga", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_2G_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_2G_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_2G_PA + 2, 0xffff}, + {"rxgains5gmelnagaina", 0xfffff800, 0, SROM11_RXGAINS1, 0x0007}, + {"rxgains5gmtrisoa", 0xfffff800, 0, SROM11_RXGAINS1, 0x0078}, + {"rxgains5gmtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS1, 0x0080}, + {"rxgains5ghelnagaina", 0xfffff800, 0, SROM11_RXGAINS1, 0x0700}, + {"rxgains5ghtrisoa", 0xfffff800, 0, SROM11_RXGAINS1, 0x7800}, + {"rxgains5ghtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS1, 0x8000}, + {"rxgains2gelnagaina", 0xfffff800, 0, SROM11_RXGAINS, 0x0007}, + {"rxgains2gtrisoa", 0xfffff800, 0, SROM11_RXGAINS, 0x0078}, + {"rxgains2gtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS, 0x0080}, + {"rxgains5gelnagaina", 0xfffff800, 0, SROM11_RXGAINS, 0x0700}, + {"rxgains5gtrisoa", 0xfffff800, 0, SROM11_RXGAINS, 0x7800}, + {"rxgains5gtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS, 0x8000}, + {"maxp5ga", 0xfffff800, SRFL_ARRAY, SROM11_5GB1B0_MAXP, 0x00ff}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_5GB1B0_MAXP, 0xff00}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_5GB3B2_MAXP, 0x00ff}, + {"", 0xfffff800, 0, SROM11_5GB3B2_MAXP, 0xff00}, + {"pa5ga", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB3_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB3_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_5GB3_PA + 2, 0xffff}, + + {NULL, 0, 0, 0, 0} +}; + +#if !(defined(PHY_TYPE_HT) && defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) +#define PHY_TYPE_HT 7 /* HT-Phy value */ +#define PHY_TYPE_N 4 /* N-Phy value */ +#define PHY_TYPE_LP 5 /* LP-Phy value */ +#endif /* !(defined(PHY_TYPE_HT) && defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ +#if !defined(PHY_TYPE_AC) +#define PHY_TYPE_AC 11 /* AC-Phy value */ +#endif /* !defined(PHY_TYPE_AC) */ +#if !defined(PHY_TYPE_NULL) +#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ +#endif /* !defined(PHY_TYPE_NULL) */ + +typedef struct { + uint16 phy_type; + uint16 bandrange; + uint16 chain; + const char *vars; +} pavars_t; + +static const pavars_t pavars[] = { + /* HTPHY */ + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 2, "pa2gw0a2 pa2gw1a2 pa2gw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 2, "pa5glw0a2 pa5glw1a2 pa5glw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 2, "pa5gw0a2 pa5gw1a2 pa5gw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 2, "pa5ghw0a2 pa5ghw1a2 pa5ghw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 0, "pa5gw0a3 pa5gw1a3 pa5gw2a3"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 1, "pa5glw0a3 pa5glw1a3 pa5glw2a3"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 2, "pa5ghw0a3 pa5ghw1a3 pa5ghw2a3"}, + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND0, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND0, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND1, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND1, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND2, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND2, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, + /* LPPHY */ + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, + /* ACPHY */ + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 0, "pa2ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 1, "pa2ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 2, "pa2ga2"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 0, "pa5ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 1, "pa5ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 2, "pa5ga2"}, + {PHY_TYPE_NULL, 0, 0, ""} +}; + +/* pavars table when paparambwver is 1 */ +static const pavars_t pavars_bwver_1[] = { + /* ACPHY */ + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 0, "pa2ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gccka0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 1, "pa2ga2"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 0, "pa5ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 1, "pa5gbw40a0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 2, "pa5gbw80a0"}, + {PHY_TYPE_NULL, 0, 0, ""} +}; + +/* pavars table when paparambwver is 2 */ +static const pavars_t pavars_bwver_2[] = { + /* ACPHY */ + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 0, "pa2ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 1, "pa2ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 0, "pa5ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 1, "pa5ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 2, "pa5gbw4080a0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 3, "pa5gbw4080a1"}, + {PHY_TYPE_NULL, 0, 0, ""} +}; + +typedef struct { + uint16 phy_type; + uint16 bandrange; + const char *vars; +} povars_t; + +static const povars_t povars[] = { + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " + "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " + "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " + "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " + "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, + {PHY_TYPE_NULL, 0, ""} +}; + +typedef struct { + uint8 tag; /* Broadcom subtag name */ + uint32 revmask; /* Supported cis_sromrev */ + uint8 len; /* Length field of the tuple, note that it includes the + * subtag name (1 byte): 1 + tuple content length + */ + const char *params; +} cis_tuple_t; + +#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ +#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ +#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ +#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ + +static const cis_tuple_t cis_hnbuvars[] = { + {OTP_RAW1, 0xffffffff, 0, ""}, /* special case */ + {OTP_VERS_1, 0xffffffff, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */ + {OTP_MANFID, 0xffffffff, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */ + /* Unified OTP: tupple to embed USB manfid inside SDIO CIS */ + {HNBU_UMANFID, 0xffffffff, 8, "8usbmanfid"}, + {HNBU_SROMREV, 0xffffffff, 2, "1sromrev"}, + /* NOTE: subdevid is also written to boardtype. + * Need to write HNBU_BOARDTYPE to change it if it is different. + */ + {HNBU_CHIPID, 0xffffffff, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"}, + {HNBU_BOARDREV, 0xffffffff, 3, "2boardrev"}, + {HNBU_PAPARMS, 0xffffffff, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"}, + {HNBU_AA, 0xffffffff, 3, "1aa2g 1aa5g"}, + {HNBU_AA, 0xffffffff, 3, "1aa0 1aa1"}, /* backward compatibility */ + {HNBU_AG, 0xffffffff, 5, "1ag0 1ag1 1ag2 1ag3"}, + {HNBU_BOARDFLAGS, 0xffffffff, 21, "4boardflags 4boardflags2 4boardflags3 " + "4boardflags4 4boardflags5 "}, + {HNBU_LEDS, 0xffffffff, 17, "1ledbh0 1ledbh1 1ledbh2 1ledbh3 1ledbh4 1ledbh5 " + "1ledbh6 1ledbh7 1ledbh8 1ledbh9 1ledbh10 1ledbh11 1ledbh12 1ledbh13 1ledbh14 1ledbh15"}, + {HNBU_CCODE, 0xffffffff, 4, "2ccode 1cctl"}, + {HNBU_CCKPO, 0xffffffff, 3, "2cckpo"}, + {HNBU_OFDMPO, 0xffffffff, 5, "4ofdmpo"}, + {HNBU_PAPARMS5G, 0xffffffff, 23, "2pa1b0 2pa1b1 2pa1b2 2pa1lob0 2pa1lob1 2pa1lob2 " + "2pa1hib0 2pa1hib1 2pa1hib2 1pa1itssit " + "1pa1maxpwr 1pa1lomaxpwr 1pa1himaxpwr"}, + {HNBU_RDLID, 0xffffffff, 3, "2rdlid"}, + {HNBU_RSSISMBXA2G, 0xffffffff, 3, "0rssismf2g 0rssismc2g " + "0rssisav2g 0bxa2g"}, /* special case */ + {HNBU_RSSISMBXA5G, 0xffffffff, 3, "0rssismf5g 0rssismc5g " + "0rssisav5g 0bxa5g"}, /* special case */ + {HNBU_XTALFREQ, 0xffffffff, 5, "4xtalfreq"}, + {HNBU_TRI2G, 0xffffffff, 2, "1tri2g"}, + {HNBU_TRI5G, 0xffffffff, 4, "1tri5gl 1tri5g 1tri5gh"}, + {HNBU_RXPO2G, 0xffffffff, 2, "1rxpo2g"}, + {HNBU_RXPO5G, 0xffffffff, 2, "1rxpo5g"}, + {HNBU_BOARDNUM, 0xffffffff, 3, "2boardnum"}, + {HNBU_MACADDR, 0xffffffff, 7, "6macaddr"}, /* special case */ + {HNBU_RDLSN, 0xffffffff, 3, "2rdlsn"}, + {HNBU_BOARDTYPE, 0xffffffff, 3, "2boardtype"}, + {HNBU_LEDDC, 0xffffffff, 3, "2leddc"}, + {HNBU_RDLRNDIS, 0xffffffff, 2, "1rdlndis"}, + {HNBU_CHAINSWITCH, 0xffffffff, 5, "1txchain 1rxchain 2antswitch"}, + {HNBU_REGREV, 0xffffffff, 2, "1regrev"}, + {HNBU_FEM, 0x000007fe, 5, "0antswctl2g 0triso2g 0pdetrange2g 0extpagain2g " + "0tssipos2g 0antswctl5g 0triso5g 0pdetrange5g 0extpagain5g 0tssipos5g"}, /* special case */ + {HNBU_PAPARMS_C0, 0x000007fe, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 " + "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 2pa5gw1a0 2pa5gw2a0 " + "2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 2pa5ghw1a0 2pa5ghw2a0"}, + {HNBU_PAPARMS_C1, 0x000007fe, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 " + "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 2pa5gw1a1 2pa5gw2a1 " + "2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 2pa5ghw1a1 2pa5ghw2a1"}, + {HNBU_PO_CCKOFDM, 0xffffffff, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo " + "4ofdm5ghpo"}, + {HNBU_PO_MCS2G, 0xffffffff, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 " + "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"}, + {HNBU_PO_MCS5GM, 0xffffffff, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 " + "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"}, + {HNBU_PO_MCS5GLH, 0xffffffff, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 " + "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 " + "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 " + "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"}, + {HNBU_CCKFILTTYPE, 0xffffffff, 2, "1cckdigfilttype"}, + {HNBU_PO_CDD, 0xffffffff, 3, "2cddpo"}, + {HNBU_PO_STBC, 0xffffffff, 3, "2stbcpo"}, + {HNBU_PO_40M, 0xffffffff, 3, "2bw40po"}, + {HNBU_PO_40MDUP, 0xffffffff, 3, "2bwduppo"}, + {HNBU_RDLRWU, 0xffffffff, 2, "1rdlrwu"}, + {HNBU_WPS, 0xffffffff, 3, "1wpsgpio 1wpsled"}, + {HNBU_USBFS, 0xffffffff, 2, "1usbfs"}, + {HNBU_ELNA2G, 0xffffffff, 2, "1elna2g"}, + {HNBU_ELNA5G, 0xffffffff, 2, "1elna5g"}, + {HNBU_CUSTOM1, 0xffffffff, 5, "4customvar1"}, + {OTP_RAW, 0xffffffff, 0, ""}, /* special case */ + {HNBU_OFDMPO5G, 0xffffffff, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"}, + {HNBU_USBEPNUM, 0xffffffff, 3, "2usbepnum"}, + {HNBU_CCKBW202GPO, 0xffffffff, 7, "2cckbw202gpo 2cckbw20ul2gpo 2cckbw20in802gpo"}, + {HNBU_LEGOFDMBW202GPO, 0xffffffff, 9, "4legofdmbw202gpo 4legofdmbw20ul2gpo"}, + {HNBU_LEGOFDMBW205GPO, 0xffffffff, 25, "4legofdmbw205glpo 4legofdmbw20ul5glpo " + "4legofdmbw205gmpo 4legofdmbw20ul5gmpo 4legofdmbw205ghpo 4legofdmbw20ul5ghpo"}, + {HNBU_MCS2GPO, 0xffffffff, 17, "4mcsbw202gpo 4mcsbw20ul2gpo 4mcsbw402gpo 4mcsbw802gpo"}, + {HNBU_MCS5GLPO, 0xffffffff, 13, "4mcsbw205glpo 4mcsbw20ul5glpo 4mcsbw405glpo"}, + {HNBU_MCS5GMPO, 0xffffffff, 13, "4mcsbw205gmpo 4mcsbw20ul5gmpo 4mcsbw405gmpo"}, + {HNBU_MCS5GHPO, 0xffffffff, 13, "4mcsbw205ghpo 4mcsbw20ul5ghpo 4mcsbw405ghpo"}, + {HNBU_MCS32PO, 0xffffffff, 3, "2mcs32po"}, + {HNBU_LEG40DUPPO, 0xffffffff, 3, "2legofdm40duppo"}, + {HNBU_TEMPTHRESH, 0xffffffff, 7, "1tempthresh 0temps_period 0temps_hysteresis " + "1tempoffset 1tempsense_slope 0tempcorrx 0tempsense_option " + "1phycal_tempdelta"}, /* special case */ + {HNBU_MUXENAB, 0xffffffff, 2, "1muxenab"}, + {HNBU_FEM_CFG, 0xfffff800, 5, "0femctrl 0papdcap2g 0tworangetssi2g 0pdgain2g " + "0epagain2g 0tssiposslope2g 0gainctrlsph 0papdcap5g 0tworangetssi5g 0pdgain5g 0epagain5g " + "0tssiposslope5g"}, /* special case */ + {HNBU_ACPA_C0, 0xfffff800, 39, "2subband5gver 2maxp2ga0 2*3pa2ga0 " + "1*4maxp5ga0 2*12pa5ga0"}, + {HNBU_ACPA_C1, 0xfffff800, 37, "2maxp2ga1 2*3pa2ga1 1*4maxp5ga1 2*12pa5ga1"}, + {HNBU_ACPA_C2, 0xfffff800, 37, "2maxp2ga2 2*3pa2ga2 1*4maxp5ga2 2*12pa5ga2"}, + {HNBU_MEAS_PWR, 0xfffff800, 5, "1measpower 1measpower1 1measpower2 2rawtempsense"}, + {HNBU_PDOFF, 0xfffff800, 13, "2pdoffset40ma0 2pdoffset40ma1 2pdoffset40ma2 " + "2pdoffset80ma0 2pdoffset80ma1 2pdoffset80ma2"}, + {HNBU_ACPPR_2GPO, 0xfffff800, 13, "2dot11agofdmhrbw202gpo 2ofdmlrbw202gpo " + "2sb20in40dot11agofdm2gpo 2sb20in80dot11agofdm2gpo 2sb20in40ofdmlrbw202gpo " + "2sb20in80ofdmlrbw202gpo"}, + {HNBU_ACPPR_5GPO, 0xfffff800, 59, "4mcsbw805glpo 4mcsbw1605glpo 4mcsbw805gmpo " + "4mcsbw1605gmpo 4mcsbw805ghpo 4mcsbw1605ghpo 2mcslr5glpo 2mcslr5gmpo 2mcslr5ghpo " + "4mcsbw80p805glpo 4mcsbw80p805gmpo 4mcsbw80p805ghpo 4mcsbw80p805gx1po 2mcslr5gx1po " + "2mcslr5g80p80po 4mcsbw805gx1po 4mcsbw1605gx1po"}, + {HNBU_MCS5Gx1PO, 0xfffff800, 9, "4mcsbw205gx1po 4mcsbw405gx1po"}, + {HNBU_ACPPR_SBPO, 0xfffff800, 49, "2sb20in40hrpo 2sb20in80and160hr5glpo " + "2sb40and80hr5glpo 2sb20in80and160hr5gmpo 2sb40and80hr5gmpo 2sb20in80and160hr5ghpo " + "2sb40and80hr5ghpo 2sb20in40lrpo 2sb20in80and160lr5glpo 2sb40and80lr5glpo " + "2sb20in80and160lr5gmpo 2sb40and80lr5gmpo 2sb20in80and160lr5ghpo 2sb40and80lr5ghpo " + "4dot11agduphrpo 4dot11agduplrpo 2sb20in40and80hrpo 2sb20in40and80lrpo " + "2sb20in80and160hr5gx1po 2sb20in80and160lr5gx1po 2sb40and80hr5gx1po 2sb40and80lr5gx1po " + }, + {HNBU_ACPPR_SB8080_PO, 0xfffff800, 23, "2sb2040and80in80p80hr5glpo " + "2sb2040and80in80p80lr5glpo 2sb2040and80in80p80hr5gmpo " + "2sb2040and80in80p80lr5gmpo 2sb2040and80in80p80hr5ghpo 2sb2040and80in80p80lr5ghpo " + "2sb2040and80in80p80hr5gx1po 2sb2040and80in80p80lr5gx1po 2sb20in80p80hr5gpo " + "2sb20in80p80lr5gpo 2dot11agduppo"}, + {HNBU_NOISELVL, 0xfffff800, 16, "1noiselvl2ga0 1noiselvl2ga1 1noiselvl2ga2 " + "1*4noiselvl5ga0 1*4noiselvl5ga1 1*4noiselvl5ga2"}, + {HNBU_RXGAIN_ERR, 0xfffff800, 16, "1rxgainerr2ga0 1rxgainerr2ga1 1rxgainerr2ga2 " + "1*4rxgainerr5ga0 1*4rxgainerr5ga1 1*4rxgainerr5ga2"}, + {HNBU_AGBGA, 0xfffff800, 7, "1agbg0 1agbg1 1agbg2 1aga0 1aga1 1aga2"}, + {HNBU_USBDESC_COMPOSITE, 0xffffffff, 3, "2usbdesc_composite"}, + {HNBU_UUID, 0xffffffff, 17, "16uuid"}, + {HNBU_WOWLGPIO, 0xffffffff, 2, "1wowl_gpio"}, + {HNBU_ACRXGAINS_C0, 0xfffff800, 5, "0rxgains5gtrelnabypa0 0rxgains5gtrisoa0 " + "0rxgains5gelnagaina0 0rxgains2gtrelnabypa0 0rxgains2gtrisoa0 0rxgains2gelnagaina0 " + "0rxgains5ghtrelnabypa0 0rxgains5ghtrisoa0 0rxgains5ghelnagaina0 0rxgains5gmtrelnabypa0 " + "0rxgains5gmtrisoa0 0rxgains5gmelnagaina0"}, /* special case */ + {HNBU_ACRXGAINS_C1, 0xfffff800, 5, "0rxgains5gtrelnabypa1 0rxgains5gtrisoa1 " + "0rxgains5gelnagaina1 0rxgains2gtrelnabypa1 0rxgains2gtrisoa1 0rxgains2gelnagaina1 " + "0rxgains5ghtrelnabypa1 0rxgains5ghtrisoa1 0rxgains5ghelnagaina1 0rxgains5gmtrelnabypa1 " + "0rxgains5gmtrisoa1 0rxgains5gmelnagaina1"}, /* special case */ + {HNBU_ACRXGAINS_C2, 0xfffff800, 5, "0rxgains5gtrelnabypa2 0rxgains5gtrisoa2 " + "0rxgains5gelnagaina2 0rxgains2gtrelnabypa2 0rxgains2gtrisoa2 0rxgains2gelnagaina2 " + "0rxgains5ghtrelnabypa2 0rxgains5ghtrisoa2 0rxgains5ghelnagaina2 0rxgains5gmtrelnabypa2 " + "0rxgains5gmtrisoa2 0rxgains5gmelnagaina2"}, /* special case */ + {HNBU_TXDUTY, 0xfffff800, 9, "2tx_duty_cycle_ofdm_40_5g " + "2tx_duty_cycle_thresh_40_5g 2tx_duty_cycle_ofdm_80_5g 2tx_duty_cycle_thresh_80_5g"}, + {HNBU_PDOFF_2G, 0xfffff800, 3, "0pdoffset2g40ma0 0pdoffset2g40ma1 " + "0pdoffset2g40ma2 0pdoffset2g40mvalid"}, + {HNBU_ACPA_CCK, 0xfffff800, 7, "2*3pa2gccka0"}, + {HNBU_ACPA_40, 0xfffff800, 25, "2*12pa5gbw40a0"}, + {HNBU_ACPA_80, 0xfffff800, 25, "2*12pa5gbw80a0"}, + {HNBU_ACPA_4080, 0xfffff800, 49, "2*12pa5gbw4080a0 2*12pa5gbw4080a1"}, + {HNBU_SUBBAND5GVER, 0xfffff800, 3, "2subband5gver"}, + {HNBU_PAPARAMBWVER, 0xfffff800, 2, "1paparambwver"}, + {0xFF, 0xffffffff, 0, ""} +}; + +#endif /* _bcmsrom_tbl_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h index f0efe3d560a3b4270721641cda22d0fa8a3a5dab..cac618b68908f988336b6bcd29538cca4750dedf 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmutils.h +++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h @@ -1,9 +1,27 @@ /* * Misc useful os-independent macros and functions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmutils.h 490808 2014-07-12 00:33:13Z $ + * $Id: bcmutils.h 469595 2014-04-10 21:19:06Z $ */ #ifndef _bcmutils_h_ @@ -17,7 +35,6 @@ extern "C" { #endif - #ifdef PKTQ_LOG #include <wlioctl.h> #endif @@ -690,7 +707,10 @@ extern int bcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 field, char* buf extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); #endif +#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ + defined(WLMSG_ASSOC) || defined(WLMEDIA_PEAKRATE) extern int bcm_format_hex(char *str, const void *bytes, int len); +#endif extern const char *bcm_crypto_algo_name(uint algo); extern char *bcm_chipname(uint chipid, char *buf, uint len); @@ -714,24 +734,6 @@ typedef struct bcm_xtlv { uint8 data[1]; } bcm_xtlv_t; -/* descriptor of xtlv data src or dst */ -typedef struct { - uint16 type; - uint16 len; - void *ptr; /* ptr to memory location */ -} xtlv_desc_t; - -/* set a var from xtlv buffer */ -typedef int -(bcm_set_var_from_tlv_cbfn_t)(void *ctx, void **tlv_buf, uint16 type, uint16 len); - -struct bcm_tlvbuf { - uint16 size; - uint8 *head; /* point to head of buffer */ - uint8 *buf; /* current position of buffer */ - /* followed by the allocated buffer */ -}; - #define BCM_TLV_MAX_DATA_SIZE (255) #define BCM_XTLV_MAX_DATA_SIZE (65535) #define BCM_TLV_HDR_SIZE (OFFSETOF(bcm_tlv_t, data)) @@ -768,27 +770,6 @@ extern uint8 *bcm_copy_tlv_safe(const void *src, uint8 *dst, int dst_maxlen); /* xtlv */ extern bcm_xtlv_t *bcm_next_xtlv(bcm_xtlv_t *elt, int *buflen); -extern struct bcm_tlvbuf *bcm_xtlv_buf_alloc(void *osh, uint16 len); -extern void bcm_xtlv_buf_free(void *osh, struct bcm_tlvbuf *tbuf); -extern uint16 bcm_xtlv_buf_len(struct bcm_tlvbuf *tbuf); -extern uint16 bcm_xtlv_buf_rlen(struct bcm_tlvbuf *tbuf); -extern uint8 *bcm_xtlv_buf(struct bcm_tlvbuf *tbuf); -extern uint8 *bcm_xtlv_head(struct bcm_tlvbuf *tbuf); -extern int bcm_xtlv_put_data(struct bcm_tlvbuf *tbuf, uint16 type, const void *data, uint16 dlen); -extern int bcm_xtlv_put_8(struct bcm_tlvbuf *tbuf, uint16 type, const int8 data); -extern int bcm_xtlv_put_16(struct bcm_tlvbuf *tbuf, uint16 type, const int16 data); -extern int bcm_xtlv_put_32(struct bcm_tlvbuf *tbuf, uint16 type, const int32 data); -extern int bcm_unpack_xtlv_entry(void **tlv_buf, uint16 xpct_type, uint16 xpct_len, void *dst); -extern int bcm_skip_xtlv(void **tlv_buf); -extern int bcm_pack_xtlv_entry(void **tlv_buf, uint16 *buflen, uint16 type, uint16 len, void *src); -extern int bcm_unpack_xtlv_buf(void *ctx, - void *tlv_buf, uint16 buflen, bcm_set_var_from_tlv_cbfn_t *cbfn); -extern int -bcm_unpack_xtlv_buf_to_mem(void *tlv_buf, int *buflen, xtlv_desc_t *items); -extern int -bcm_pack_xtlv_buf_from_mem(void **tlv_buf, uint16 *buflen, xtlv_desc_t *items); -extern int -bcm_pack_xtlv_entry_from_hex_string(void **tlv_buf, uint16 *buflen, uint16 type, char *hex); /* bcmerror */ extern const char *bcmerrorstr(int bcmerror); diff --git a/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h b/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h index 5a63facfa2574379559c964db88f9b1d1058d414..95712c924862a1f1fa0f4a8497575b188889916c 100644 --- a/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h +++ b/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h @@ -1,25 +1,36 @@ /* - * Definitions for nl80211 vendor command/event access to host driver + * Definitions for nl80211 testmode access to host driver * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: brcm_nl80211.h 487126 2014-06-24 23:06:12Z $ + * $Id: brcm_nl80211.h 438755 2013-11-22 23:20:40Z $ * */ #ifndef _brcm_nl80211_h_ #define _brcm_nl80211_h_ -#define OUI_BRCM 0x001018 - -enum wl_vendor_subcmd { - BRCM_VENDOR_SCMD_UNSPEC, - BRCM_VENDOR_SCMD_PRIV_STR -}; - struct bcm_nlmsg_hdr { uint cmd; /* common ioctl definition */ - uint len; /* expected return buffer length */ + uint len; /* attached buffer length */ uint offset; /* user buffer offset */ uint set; /* get or set request optional */ uint magic; /* magic number for verification */ diff --git a/drivers/net/wireless/bcmdhd/include/circularbuf.h b/drivers/net/wireless/bcmdhd/include/circularbuf.h deleted file mode 100644 index fa939ca3a6774309609e3635a1a1a5a5694841df..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/include/circularbuf.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Initialization and support routines for self-booting compressed image. - * - * $Copyright Open Broadcom Corporation$ - * - * $Id: circularbuf.h 452258 2014-01-29 19:17:57Z $ - */ - -#ifndef __CIRCULARBUF_H_INCLUDED__ -#define __CIRCULARBUF_H_INCLUDED__ - -#include <osl.h> -#include <typedefs.h> -#include <bcmendian.h> - -/* Enumerations of return values provided by MsgBuf implementation */ -typedef enum { - CIRCULARBUF_FAILURE = -1, - CIRCULARBUF_SUCCESS -} circularbuf_ret_t; - -/* Core circularbuf circular buffer structure */ -typedef struct circularbuf_s -{ - uint16 depth; /* Depth of circular buffer */ - uint16 r_ptr; /* Read Ptr */ - uint16 w_ptr; /* Write Ptr */ - uint16 e_ptr; /* End Ptr */ - uint16 wp_ptr; /* wp_ptr/pending - scheduled for DMA. But, not yet complete. */ - uint16 rp_ptr; /* rp_ptr/pending - scheduled for DMA. But, not yet complete. */ - - uint8 *buf_addr; - void *mb_ctx; - void (*mb_ring_bell)(void *ctx); -} circularbuf_t; - -#define CBUF_ERROR_VAL 0x00000001 /* Error level tracing */ -#define CBUF_TRACE_VAL 0x00000002 /* Function level tracing */ -#define CBUF_INFORM_VAL 0x00000004 /* debug level tracing */ - -extern int cbuf_msg_level; - -#define CBUF_ERROR(args) do {if (cbuf_msg_level & CBUF_ERROR_VAL) printf args;} while (0) -#define CBUF_TRACE(args) do {if (cbuf_msg_level & CBUF_TRACE_VAL) printf args;} while (0) -#define CBUF_INFO(args) do {if (cbuf_msg_level & CBUF_INFORM_VAL) printf args;} while (0) - -#define CIRCULARBUF_START(x) ((x)->buf_addr) -#define CIRCULARBUF_WRITE_PTR(x) ((x)->w_ptr) -#define CIRCULARBUF_READ_PTR(x) ((x)->r_ptr) -#define CIRCULARBUF_END_PTR(x) ((x)->e_ptr) - -#define circularbuf_debug_print(handle) \ - CBUF_INFO(("%s:%d:\t%p rp=%4d r=%4d wp=%4d w=%4d e=%4d\n", \ - __FUNCTION__, __LINE__, \ - (void *) CIRCULARBUF_START(handle), \ - (int) (handle)->rp_ptr, (int) (handle)->r_ptr, \ - (int) (handle)->wp_ptr, (int) (handle)->w_ptr, \ - (int) (handle)->e_ptr)); - - -/* Callback registered by application/mail-box with the circularbuf implementation. - * This will be invoked by the circularbuf implementation when write is complete and - * ready for informing the peer - */ -typedef void (*mb_ring_t)(void *ctx); - - -/* Public Functions exposed by circularbuf */ -void -circularbuf_init(circularbuf_t *handle, void *buf_base_addr, uint16 total_buf_len); -void -circularbuf_register_cb(circularbuf_t *handle, mb_ring_t mb_ring_func, void *ctx); - -/* Write Functions */ -void * -circularbuf_reserve_for_write(circularbuf_t *handle, uint16 size); -void -circularbuf_write_complete(circularbuf_t *handle, uint16 bytes_written); - -/* Read Functions */ -void * -circularbuf_get_read_ptr(circularbuf_t *handle, uint16 *avail_len); -circularbuf_ret_t -circularbuf_read_complete(circularbuf_t *handle, uint16 bytes_read); - -/* - * circularbuf_get_read_ptr() updates rp_ptr by the amount that the consumer - * is supposed to read. The consumer may not read the entire amount. - * In such a case, circularbuf_revert_rp_ptr() call follows a corresponding - * circularbuf_get_read_ptr() call to revert the rp_ptr back to - * the point till which data has actually been processed. - * It is not valid if it is preceded by multiple get_read_ptr() calls - */ -circularbuf_ret_t -circularbuf_revert_rp_ptr(circularbuf_t *handle, uint16 bytes); - -#endif /* __CIRCULARBUF_H_INCLUDED__ */ diff --git a/drivers/net/wireless/bcmdhd/include/dbus.h b/drivers/net/wireless/bcmdhd/include/dbus.h new file mode 100644 index 0000000000000000000000000000000000000000..daef6c5680ded0f74d76b16510b9961c55311a50 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/dbus.h @@ -0,0 +1,582 @@ +/* + * Dongle BUS interface Abstraction layer + * target serial buses like USB, SDIO, SPI, etc. + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dbus.h 423346 2013-09-11 22:38:40Z $ + */ + +#ifndef __DBUS_H__ +#define __DBUS_H__ + +#include "typedefs.h" + +#define DBUSTRACE(args) +#define DBUSERR(args) +#define DBUSINFO(args) +#define DBUSDBGLOCK(args) + +enum { + DBUS_OK = 0, + DBUS_ERR = -200, + DBUS_ERR_TIMEOUT, + DBUS_ERR_DISCONNECT, + DBUS_ERR_NODEVICE, + DBUS_ERR_UNSUPPORTED, + DBUS_ERR_PENDING, + DBUS_ERR_NOMEM, + DBUS_ERR_TXFAIL, + DBUS_ERR_TXTIMEOUT, + DBUS_ERR_TXDROP, + DBUS_ERR_RXFAIL, + DBUS_ERR_RXDROP, + DBUS_ERR_TXCTLFAIL, + DBUS_ERR_RXCTLFAIL, + DBUS_ERR_REG_PARAM, + DBUS_STATUS_CANCELLED, + DBUS_ERR_NVRAM, + DBUS_JUMBO_NOMATCH, + DBUS_JUMBO_BAD_FORMAT, + DBUS_NVRAM_NONTXT +}; + +#define BCM_OTP_SIZE_43236 84 /* number of 16 bit values */ +#define BCM_OTP_SW_RGN_43236 24 /* start offset of SW config region */ +#define BCM_OTP_ADDR_43236 0x18000800 /* address of otp base */ + +#define ERR_CBMASK_TXFAIL 0x00000001 +#define ERR_CBMASK_RXFAIL 0x00000002 +#define ERR_CBMASK_ALL 0xFFFFFFFF + +#define DBUS_CBCTL_WRITE 0 +#define DBUS_CBCTL_READ 1 +#if defined(INTR_EP_ENABLE) +#define DBUS_CBINTR_POLL 2 +#endif /* defined(INTR_EP_ENABLE) */ + +#define DBUS_TX_RETRY_LIMIT 3 /* retries for failed txirb */ +#define DBUS_TX_TIMEOUT_INTERVAL 250 /* timeout for txirb complete, in ms */ + +#define DBUS_BUFFER_SIZE_TX 32000 +#define DBUS_BUFFER_SIZE_RX 24000 + +#define DBUS_BUFFER_SIZE_TX_NOAGG 2048 +#define DBUS_BUFFER_SIZE_RX_NOAGG 2048 + +/* DBUS types */ +enum { + DBUS_USB, + DBUS_SDIO, + DBUS_SPI, + DBUS_UNKNOWN +}; + +enum dbus_state { + DBUS_STATE_DL_PENDING, + DBUS_STATE_DL_DONE, + DBUS_STATE_UP, + DBUS_STATE_DOWN, + DBUS_STATE_PNP_FWDL, + DBUS_STATE_DISCONNECT, + DBUS_STATE_SLEEP +}; + +enum dbus_pnp_state { + DBUS_PNP_DISCONNECT, + DBUS_PNP_SLEEP, + DBUS_PNP_RESUME +}; + +enum dbus_file { + DBUS_FIRMWARE, + DBUS_NVFILE +}; + +typedef enum _DEVICE_SPEED { + INVALID_SPEED = -1, + LOW_SPEED = 1, /* USB 1.1: 1.5 Mbps */ + FULL_SPEED, /* USB 1.1: 12 Mbps */ + HIGH_SPEED, /* USB 2.0: 480 Mbps */ + SUPER_SPEED, /* USB 3.0: 4.8 Gbps */ +} DEVICE_SPEED; + +typedef struct { + int bustype; + int vid; + int pid; + int devid; + int chiprev; /* chip revsion number */ + int mtu; + int nchan; /* Data Channels */ + int has_2nd_bulk_in_ep; +} dbus_attrib_t; + +/* FIX: Account for errors related to DBUS; + * Let upper layer account for packets/bytes + */ +typedef struct { + uint32 rx_errors; + uint32 tx_errors; + uint32 rx_dropped; + uint32 tx_dropped; +} dbus_stats_t; + +/* + * Configurable BUS parameters + */ +enum { + DBUS_CONFIG_ID_RXCTL_DEFERRES = 1, + DBUS_CONFIG_ID_TXRXQUEUE +}; +typedef struct { + uint32 config_id; + union { + bool rxctl_deferrespok; + struct { + int maxrxq; + int rxbufsize; + int maxtxq; + int txbufsize; + } txrxqueue; + }; +} dbus_config_t; + +/* + * External Download Info + */ +typedef struct dbus_extdl { + uint8 *fw; + int fwlen; + uint8 *vars; + int varslen; +} dbus_extdl_t; + +struct dbus_callbacks; +struct exec_parms; + +typedef void *(*probe_cb_t)(void *arg, const char *desc, uint32 bustype, uint32 hdrlen); +typedef void (*disconnect_cb_t)(void *arg); +typedef void *(*exec_cb_t)(struct exec_parms *args); + +/* Client callbacks registered during dbus_attach() */ +typedef struct dbus_callbacks { + void (*send_complete)(void *cbarg, void *info, int status); + void (*recv_buf)(void *cbarg, uint8 *buf, int len); + void (*recv_pkt)(void *cbarg, void *pkt); + void (*txflowcontrol)(void *cbarg, bool onoff); + void (*errhandler)(void *cbarg, int err); + void (*ctl_complete)(void *cbarg, int type, int status); + void (*state_change)(void *cbarg, int state); + void *(*pktget)(void *cbarg, uint len, bool send); + void (*pktfree)(void *cbarg, void *p, bool send); +} dbus_callbacks_t; + +struct dbus_pub; +struct bcmstrbuf; +struct dbus_irb; +struct dbus_irb_rx; +struct dbus_irb_tx; +struct dbus_intf_callbacks; + +typedef struct { + void* (*attach)(struct dbus_pub *pub, void *cbarg, struct dbus_intf_callbacks *cbs); + void (*detach)(struct dbus_pub *pub, void *bus); + + int (*up)(void *bus); + int (*down)(void *bus); + int (*send_irb)(void *bus, struct dbus_irb_tx *txirb); + int (*recv_irb)(void *bus, struct dbus_irb_rx *rxirb); + int (*cancel_irb)(void *bus, struct dbus_irb_tx *txirb); + int (*send_ctl)(void *bus, uint8 *buf, int len); + int (*recv_ctl)(void *bus, uint8 *buf, int len); + int (*get_stats)(void *bus, dbus_stats_t *stats); + int (*get_attrib)(void *bus, dbus_attrib_t *attrib); + + int (*pnp)(void *bus, int evnt); + int (*remove)(void *bus); + int (*resume)(void *bus); + int (*suspend)(void *bus); + int (*stop)(void *bus); + int (*reset)(void *bus); + + /* Access to bus buffers directly */ + void *(*pktget)(void *bus, int len); + void (*pktfree)(void *bus, void *pkt); + + int (*iovar_op)(void *bus, const char *name, void *params, int plen, void *arg, int len, + bool set); + void (*dump)(void *bus, struct bcmstrbuf *strbuf); + int (*set_config)(void *bus, dbus_config_t *config); + int (*get_config)(void *bus, dbus_config_t *config); + + bool (*device_exists)(void *bus); + bool (*dlneeded)(void *bus); + int (*dlstart)(void *bus, uint8 *fw, int len); + int (*dlrun)(void *bus); + bool (*recv_needed)(void *bus); + + void *(*exec_rxlock)(void *bus, exec_cb_t func, struct exec_parms *args); + void *(*exec_txlock)(void *bus, exec_cb_t func, struct exec_parms *args); + + int (*tx_timer_init)(void *bus); + int (*tx_timer_start)(void *bus, uint timeout); + int (*tx_timer_stop)(void *bus); + + int (*sched_dpc)(void *bus); + int (*lock)(void *bus); + int (*unlock)(void *bus); + int (*sched_probe_cb)(void *bus); + + int (*shutdown)(void *bus); + + int (*recv_stop)(void *bus); + int (*recv_resume)(void *bus); + + int (*recv_irb_from_ep)(void *bus, struct dbus_irb_rx *rxirb, uint ep_idx); + + int (*readreg)(void *bus, uint32 regaddr, int datalen, uint32 *value); + + /* Add from the bottom */ +} dbus_intf_t; + +typedef struct dbus_pub { + struct osl_info *osh; + dbus_stats_t stats; + dbus_attrib_t attrib; + enum dbus_state busstate; + DEVICE_SPEED device_speed; + int ntxq, nrxq, rxsize; + void *bus; + struct shared_info *sh; + void *dev_info; +} dbus_pub_t; + +#define BUS_INFO(bus, type) (((type *) bus)->pub->bus) + +#define ALIGNED_LOCAL_VARIABLE(var, align) \ + uint8 buffer[SDALIGN+64]; \ + uint8 *var = (uint8 *)(((uintptr)&buffer[0]) & ~(align-1)) + align; + +/* + * Public Bus Function Interface + */ + +/* + * FIX: Is there better way to pass OS/Host handles to DBUS but still + * maintain common interface for all OS?? + * Under NDIS, param1 needs to be MiniportHandle + * For NDIS60, param2 is WdfDevice + * Under Linux, param1 and param2 are NULL; + */ +extern int dbus_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, void *prarg, + void *param1, void *param2); +extern int dbus_deregister(void); + +extern dbus_pub_t *dbus_attach(struct osl_info *osh, int rxsize, int nrxq, int ntxq, + void *cbarg, dbus_callbacks_t *cbs, dbus_extdl_t *extdl, struct shared_info *sh); +extern void dbus_detach(dbus_pub_t *pub); + +extern int dbus_up(dbus_pub_t *pub); +extern int dbus_down(dbus_pub_t *pub); +extern int dbus_stop(dbus_pub_t *pub); +extern int dbus_shutdown(dbus_pub_t *pub); +extern void dbus_flowctrl_rx(dbus_pub_t *pub, bool on); + +extern int dbus_send_txdata(dbus_pub_t *dbus, void *pktbuf); +extern int dbus_send_buf(dbus_pub_t *pub, uint8 *buf, int len, void *info); +extern int dbus_send_pkt(dbus_pub_t *pub, void *pkt, void *info); +extern int dbus_send_ctl(dbus_pub_t *pub, uint8 *buf, int len); +extern int dbus_recv_ctl(dbus_pub_t *pub, uint8 *buf, int len); +extern int dbus_recv_bulk(dbus_pub_t *pub, uint32 ep_idx); +extern int dbus_poll_intr(dbus_pub_t *pub); +extern int dbus_get_stats(dbus_pub_t *pub, dbus_stats_t *stats); +extern int dbus_get_attrib(dbus_pub_t *pub, dbus_attrib_t *attrib); +extern int dbus_get_device_speed(dbus_pub_t *pub); +extern int dbus_set_config(dbus_pub_t *pub, dbus_config_t *config); +extern int dbus_get_config(dbus_pub_t *pub, dbus_config_t *config); +extern void * dbus_get_devinfo(dbus_pub_t *pub); + +extern void *dbus_pktget(dbus_pub_t *pub, int len); +extern void dbus_pktfree(dbus_pub_t *pub, void* pkt); + +extern int dbus_set_errmask(dbus_pub_t *pub, uint32 mask); +extern int dbus_pnp_sleep(dbus_pub_t *pub); +extern int dbus_pnp_resume(dbus_pub_t *pub, int *fw_reload); +extern int dbus_pnp_disconnect(dbus_pub_t *pub); + +extern int dbus_iovar_op(dbus_pub_t *pub, const char *name, + void *params, int plen, void *arg, int len, bool set); + +extern void *dhd_dbus_txq(const dbus_pub_t *pub); +extern uint dhd_dbus_hdrlen(const dbus_pub_t *pub); + +/* + * Private Common Bus Interface + */ + +/* IO Request Block (IRB) */ +typedef struct dbus_irb { + struct dbus_irb *next; /* it's casted from dbus_irb_tx or dbus_irb_rx struct */ +} dbus_irb_t; + +typedef struct dbus_irb_rx { + struct dbus_irb irb; /* Must be first */ + uint8 *buf; + int buf_len; + int actual_len; + void *pkt; + void *info; + void *arg; +} dbus_irb_rx_t; + +typedef struct dbus_irb_tx { + struct dbus_irb irb; /* Must be first */ + uint8 *buf; + int len; + void *pkt; + int retry_count; + void *info; + void *arg; + void *send_buf; /* linear bufffer for LINUX when aggreagtion is enabled */ +} dbus_irb_tx_t; + +/* DBUS interface callbacks are different from user callbacks + * so, internally, different info can be passed to upper layer + */ +typedef struct dbus_intf_callbacks { + void (*send_irb_timeout)(void *cbarg, dbus_irb_tx_t *txirb); + void (*send_irb_complete)(void *cbarg, dbus_irb_tx_t *txirb, int status); + void (*recv_irb_complete)(void *cbarg, dbus_irb_rx_t *rxirb, int status); + void (*errhandler)(void *cbarg, int err); + void (*ctl_complete)(void *cbarg, int type, int status); + void (*state_change)(void *cbarg, int state); + bool (*isr)(void *cbarg, bool *wantdpc); + bool (*dpc)(void *cbarg, bool bounded); + void (*watchdog)(void *cbarg); + void *(*pktget)(void *cbarg, uint len, bool send); + void (*pktfree)(void *cbarg, void *p, bool send); + struct dbus_irb* (*getirb)(void *cbarg, bool send); + void (*rxerr_indicate)(void *cbarg, bool on); +} dbus_intf_callbacks_t; + +/* + * Porting: To support new bus, port these functions below + */ + +/* + * Bus specific Interface + * Implemented by dbus_usb.c/dbus_sdio.c + */ +extern int dbus_bus_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, void *prarg, + dbus_intf_t **intf, void *param1, void *param2); +extern int dbus_bus_deregister(void); +extern void dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp); + +/* + * Bus-specific and OS-specific Interface + * Implemented by dbus_usb_[linux/ndis].c/dbus_sdio_[linux/ndis].c + */ +extern int dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, + void *prarg, dbus_intf_t **intf, void *param1, void *param2); +extern int dbus_bus_osl_deregister(void); + +/* + * Bus-specific, OS-specific, HW-specific Interface + * Mainly for SDIO Host HW controller + */ +extern int dbus_bus_osl_hw_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, + void *prarg, dbus_intf_t **intf); +extern int dbus_bus_osl_hw_deregister(void); + +extern uint usbdev_bulkin_eps(void); +#if defined(BCM_REQUEST_FW) +extern void *dbus_get_fw_nvfile(int devid, uint8 **fw, int *fwlen, int type, + uint16 boardtype, uint16 boardrev); +extern void dbus_release_fw_nvfile(void *firmware); +#endif /* #if defined(BCM_REQUEST_FW) */ + + +#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) + /* Backward compatibility */ + typedef unsigned int gfp_t; + + #define dma_pool pci_pool + #define dma_pool_create(name, dev, size, align, alloc) \ + pci_pool_create(name, dev, size, align, alloc, GFP_DMA | GFP_ATOMIC) + #define dma_pool_destroy(pool) pci_pool_destroy(pool) + #define dma_pool_alloc(pool, flags, handle) pci_pool_alloc(pool, flags, handle) + #define dma_pool_free(pool, vaddr, addr) pci_pool_free(pool, vaddr, addr) + + #define dma_map_single(dev, addr, size, dir) pci_map_single(dev, addr, size, dir) + #define dma_unmap_single(dev, hnd, size, dir) pci_unmap_single(dev, hnd, size, dir) + #define DMA_FROM_DEVICE PCI_DMA_FROMDEVICE + #define DMA_TO_DEVICE PCI_DMA_TODEVICE +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ + +/* Availability of these functions varies (when present, they have two arguments) */ +#ifndef hc32_to_cpu + #define hc32_to_cpu(x) le32_to_cpu(x) + #define cpu_to_hc32(x) cpu_to_le32(x) + typedef unsigned int __hc32; +#else + #error Two-argument functions needed +#endif + +/* Private USB opcode base */ +#define EHCI_FASTPATH 0x31 +#define EHCI_SET_EP_BYPASS EHCI_FASTPATH +#define EHCI_SET_BYPASS_CB (EHCI_FASTPATH + 1) +#define EHCI_SET_BYPASS_DEV (EHCI_FASTPATH + 2) +#define EHCI_DUMP_STATE (EHCI_FASTPATH + 3) +#define EHCI_SET_BYPASS_POOL (EHCI_FASTPATH + 4) +#define EHCI_CLR_EP_BYPASS (EHCI_FASTPATH + 5) + +/* + * EHCI QTD structure (hardware and extension) + * NOTE that is does not need to (and does not) match its kernel counterpart + */ +#define EHCI_QTD_NBUFFERS 5 +#define EHCI_QTD_ALIGN 32 +#define EHCI_BULK_PACKET_SIZE 512 +#define EHCI_QTD_XACTERR_MAX 32 + +struct ehci_qtd { + /* Hardware map */ + volatile uint32_t qtd_next; + volatile uint32_t qtd_altnext; + volatile uint32_t qtd_status; +#define EHCI_QTD_GET_BYTES(x) (((x)>>16) & 0x7fff) +#define EHCI_QTD_IOC 0x00008000 +#define EHCI_QTD_GET_CERR(x) (((x)>>10) & 0x3) +#define EHCI_QTD_SET_CERR(x) ((x) << 10) +#define EHCI_QTD_GET_PID(x) (((x)>>8) & 0x3) +#define EHCI_QTD_SET_PID(x) ((x) << 8) +#define EHCI_QTD_ACTIVE 0x80 +#define EHCI_QTD_HALTED 0x40 +#define EHCI_QTD_BUFERR 0x20 +#define EHCI_QTD_BABBLE 0x10 +#define EHCI_QTD_XACTERR 0x08 +#define EHCI_QTD_MISSEDMICRO 0x04 + volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS]; + volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; + + /* Implementation extension */ + dma_addr_t qtd_self; /* own hardware address */ + struct ehci_qtd *obj_next; /* software link to the next QTD */ + void *rpc; /* pointer to the rpc buffer */ + size_t length; /* length of the data in the buffer */ + void *buff; /* pointer to the reassembly buffer */ + int xacterrs; /* retry counter for qtd xact error */ +} __attribute__ ((aligned(EHCI_QTD_ALIGN))); + +#define EHCI_NULL __constant_cpu_to_le32(1) /* HW null pointer shall be odd */ + +#define SHORT_READ_Q(token) (EHCI_QTD_GET_BYTES(token) != 0 && EHCI_QTD_GET_PID(token) == 1) + +/* Queue Head */ +/* NOTE This structure is slightly different from the one in the kernel; but needs to stay + * compatible + */ +struct ehci_qh { + /* Hardware map */ + volatile uint32_t qh_link; + volatile uint32_t qh_endp; + volatile uint32_t qh_endphub; + volatile uint32_t qh_curqtd; + + /* QTD overlay */ + volatile uint32_t ow_next; + volatile uint32_t ow_altnext; + volatile uint32_t ow_status; + volatile uint32_t ow_buffer [EHCI_QTD_NBUFFERS]; + volatile uint32_t ow_buffer_hi [EHCI_QTD_NBUFFERS]; + + /* Extension (should match the kernel layout) */ + dma_addr_t unused0; + void *unused1; + struct list_head unused2; + struct ehci_qtd *dummy; + struct ehci_qh *unused3; + + struct ehci_hcd *unused4; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) + struct kref unused5; + unsigned unused6; + + uint8_t unused7; + + /* periodic schedule info */ + uint8_t unused8; + uint8_t unused9; + uint8_t unused10; + uint16_t unused11; + uint16_t unused12; + uint16_t unused13; + struct usb_device *unused14; +#else + unsigned unused5; + + u8 unused6; + + /* periodic schedule info */ + u8 unused7; + u8 unused8; + u8 unused9; + unsigned short unused10; + unsigned short unused11; +#define NO_FRAME ((unsigned short)~0) +#ifdef EHCI_QUIRK_FIX + struct usb_device *unused12; +#endif /* EHCI_QUIRK_FIX */ +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ + struct ehci_qtd *first_qtd; + /* Link to the first QTD; this is an optimized equivalent of the qtd_list field */ + /* NOTE that ehci_qh in ehci.h shall reserve this word */ +} __attribute__ ((aligned(EHCI_QTD_ALIGN))); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) +/* The corresponding structure in the kernel is used to get the QH */ +struct hcd_dev { /* usb_device.hcpriv points to this */ + struct list_head unused0; + struct list_head unused1; + + /* array of QH pointers */ + void *ep[32]; +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ + +int optimize_qtd_fill_with_rpc(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd, void *rpc, + int token, int len); +int optimize_qtd_fill_with_data(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd, void *data, + int token, int len); +int optimize_submit_async(struct ehci_qtd *qtd, int epn); +void inline optimize_ehci_qtd_init(struct ehci_qtd *qtd, dma_addr_t dma); +struct ehci_qtd *optimize_ehci_qtd_alloc(gfp_t flags); +void optimize_ehci_qtd_free(struct ehci_qtd *qtd); +void optimize_submit_rx_request(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd_in, void *buf); +#endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */ + +void dbus_flowctrl_tx(void *dbi, bool on); +#endif /* __DBUS_H__ */ diff --git a/drivers/net/wireless/bcmdhd/common/include/devctrl_if/wlioctl_defs.h b/drivers/net/wireless/bcmdhd/include/devctrl_if/wlioctl_defs.h similarity index 96% rename from drivers/net/wireless/bcmdhd/common/include/devctrl_if/wlioctl_defs.h rename to drivers/net/wireless/bcmdhd/include/devctrl_if/wlioctl_defs.h index 141427c6f6ad29cf86b232474b8b73c01504f684..03bfabbe6984cd50af1681135090067d37db72e0 100644 --- a/drivers/net/wireless/bcmdhd/common/include/devctrl_if/wlioctl_defs.h +++ b/drivers/net/wireless/bcmdhd/include/devctrl_if/wlioctl_defs.h @@ -4,7 +4,25 @@ * * Definitions subject to change without notice. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wlioctl_defs.h 403826 2013-05-22 16:40:55Z $ */ @@ -14,7 +32,6 @@ #define wlioctl_defs_h -#ifndef LINUX_POSTMOGRIFY_REMOVAL @@ -316,8 +333,6 @@ /* check this magic number */ #define WLC_IOCTL_MAGIC 0x14e46c77 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* bss_info_cap_t flags */ #define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ #define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ @@ -348,14 +363,14 @@ #define CRYPTO_ALGO_AES_CCM 4 #define CRYPTO_ALGO_AES_OCB_MSDU 5 #define CRYPTO_ALGO_AES_OCB_MPDU 6 -#if !defined(BCMCCX) && !defined(BCMEXTCCX) +#if !defined(BCMEXTCCX) #define CRYPTO_ALGO_NALG 7 #else #define CRYPTO_ALGO_CKIP 7 #define CRYPTO_ALGO_CKIP_MMH 8 #define CRYPTO_ALGO_WEP_MMH 9 #define CRYPTO_ALGO_NALG 10 -#endif /* !BCMCCX && !BCMEXTCCX */ +#endif #define CRYPTO_ALGO_SMS4 11 #define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */ @@ -379,13 +394,13 @@ #define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ #define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#if defined(BCMCCX) || defined(BCMEXTCCX) +#if defined(BCMEXTCCX) #define WL_CKIP_KP (1 << 4) /* CMIC */ #define WL_CKIP_MMH (1 << 5) /* CKIP */ #else #define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ #define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -#endif /* BCMCCX || BCMEXTCCX */ +#endif #define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ /* wireless security bitvec */ @@ -393,45 +408,15 @@ #define TKIP_ENABLED 0x0002 #define AES_ENABLED 0x0004 #define WSEC_SWFLAG 0x0008 -#ifdef BCMCCX -#define CKIP_KP_ENABLED 0x0010 -#define CKIP_MIC_ENABLED 0x0020 -#endif /* BCMCCX */ #define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ -#ifdef BCMWAPI_WPI -#define SMS4_ENABLED 0x0100 -#endif /* BCMWAPI_WPI */ /* wsec macros for operating on the above definitions */ #define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED) #define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED) #define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED) -#ifdef BCMCCX -#define WSEC_CKIP_KP_ENABLED(wsec) ((wsec) & CKIP_KP_ENABLED) -#define WSEC_CKIP_MIC_ENABLED(wsec) ((wsec) & CKIP_MIC_ENABLED) -#define WSEC_CKIP_ENABLED(wsec) ((wsec) & (CKIP_KP_ENABLED|CKIP_MIC_ENABLED)) - -#ifdef BCMWAPI_WPI -#define WSEC_ENABLED(wsec) \ - ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | CKIP_KP_ENABLED | \ - CKIP_MIC_ENABLED | SMS4_ENABLED)) -#else /* BCMWAPI_WPI */ -#define WSEC_ENABLED(wsec) \ - ((wsec) & \ - (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | CKIP_KP_ENABLED | CKIP_MIC_ENABLED)) -#endif /* BCMWAPI_WPI */ -#else /* defined BCMCCX */ -#ifdef BCMWAPI_WPI -#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) -#else /* BCMWAPI_WPI */ #define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#endif /* BCMWAPI_WPI */ -#endif /* BCMCCX */ #define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) -#ifdef BCMWAPI_WAI -#define WSEC_SMS4_ENABLED(wsec) ((wsec) & SMS4_ENABLED) -#endif /* BCMWAPI_WAI */ #define MFP_CAPABLE 0x0200 #define MFP_REQUIRED 0x0400 @@ -442,21 +427,15 @@ #define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ #define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ #define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -#if defined(BCMCCX) || defined(BCMEXTCCX) +#if defined(BCMEXTCCX) #define WPA_AUTH_CCKM 0x0008 /* CCKM */ #define WPA2_AUTH_CCKM 0x0010 /* CCKM2 */ -#endif /* BCMCCX || BCMEXTCCX */ +#endif /* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ #define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ #define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ #define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */ #define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */ -#if defined(BCMWAPI_WAI) || defined(BCMWAPI_WPI) -#define WPA_AUTH_WAPI 0x0400 -#define WAPI_AUTH_NONE WPA_AUTH_NONE /* none (IBSS) */ -#define WAPI_AUTH_UNSPECIFIED 0x0400 /* over AS */ -#define WAPI_AUTH_PSK 0x0800 /* Pre-shared key */ -#endif /* BCMWAPI_WAI || BCMWAPI_WPI */ #define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ #define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ #define WPA2_AUTH_FT 0x4000 /* Fast Transition. */ @@ -626,7 +605,6 @@ #define WLC_SET_LAZYWDS 139 #define WLC_GET_BANDLIST 140 -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_GET_BAND 141 #define WLC_SET_BAND 142 #define WLC_SCB_DEAUTHENTICATE 143 @@ -666,9 +644,7 @@ /* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */ #define WLC_GET_PROTECTION_CONTROL 178 #define WLC_SET_PROTECTION_CONTROL 179 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_GET_PHYLIST 180 -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ #define WLC_DECRYPT_STATUS 182 /* ndis only */ #define WLC_GET_KEY_SEQ 183 @@ -689,9 +665,7 @@ /* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ /* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ #define WLC_SET_WSEC_TEST 200 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_TKIP_COUNTERMEASURES 202 #define WLC_GET_PIOMODE 203 #define WLC_SET_PIOMODE 204 @@ -707,7 +681,6 @@ #define WLC_START_CHANNEL_QA 214 #define WLC_GET_CHANNEL_SEL 215 #define WLC_START_CHANNEL_SEL 216 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_GET_VALID_CHANNELS 217 #define WLC_GET_FAKEFRAG 218 #define WLC_SET_FAKEFRAG 219 @@ -729,7 +702,6 @@ #define WLC_GET_KEY_PRIMARY 235 #define WLC_SET_KEY_PRIMARY 236 -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */ #define WLC_GET_ACI_ARGS 238 @@ -756,17 +728,13 @@ #define WLC_LEGACY_LINK_BEHAVIOR 259 #define WLC_GET_CHANNELS_IN_COUNTRY 260 #define WLC_GET_COUNTRY_LIST 261 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_GET_VAR 262 /* get value of named variable */ #define WLC_SET_VAR 263 /* set named variable to value */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_NVRAM_GET 264 /* deprecated */ #define WLC_NVRAM_SET 265 #define WLC_NVRAM_DUMP 266 #define WLC_REBOOT 267 -#endif /* !LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_SET_WSEC_PMK 268 -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_GET_AUTH_MODE 269 #define WLC_SET_AUTH_MODE 270 #define WLC_GET_WAKEENTRY 271 @@ -1783,13 +1751,6 @@ #define TSPEC_UNKNOWN 3 /* TSPEC unknown */ #define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ -#ifdef BCMCCX -/* "wlan_reason" iovar interface */ -#define WL_WLAN_ASSOC_REASON_NORMAL_NETWORK 0 /* normal WLAN network setup */ -#define WL_WLAN_ASSOC_REASON_ROAM_FROM_CELLULAR_NETWORK 1 /* roam from Cellular network */ -#define WL_WLAN_ASSOC_REASON_ROAM_FROM_LAN 2 /* roam from LAN */ -#define WL_WLAN_ASSOC_REASON_MAX 2 /* largest value allowed */ -#endif /* BCMCCX */ /* Software feature flag defines used by wlfeatureflag */ #ifdef WLAFTERBURNER @@ -2025,8 +1986,6 @@ #define NET_DETECT_MAX_CHANNELS 50 #endif /* NET_DETECT */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* Bit masks for radio disabled status - returned by WL_GET_RADIO */ #define WL_RADIO_SW_DISABLE (1<<0) #define WL_RADIO_HW_DISABLE (1<<1) diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h index 74334961a41d739a39e96542c008eaf4ca330c7c..63cddc85572aa57b04fa4fd618a853e4dbc0c882 100644 --- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h +++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h @@ -5,7 +5,25 @@ * * Definitions subject to change without notice. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: dhdioctl.h 438755 2013-11-22 23:20:40Z $ */ @@ -68,17 +86,14 @@ enum { #define DHD_GLOM_VAL 0x0400 #define DHD_EVENT_VAL 0x0800 #define DHD_BTA_VAL 0x1000 -#if 0 && (NDISVER >= 0x0630) && 1 -#define DHD_SCAN_VAL 0x2000 -#else #define DHD_ISCAN_VAL 0x2000 -#endif #define DHD_ARPOE_VAL 0x4000 #define DHD_REORDER_VAL 0x8000 #define DHD_WL_VAL 0x10000 #define DHD_NOCHECKDIED_VAL 0x20000 /* UTF WAR */ #define DHD_WL_VAL2 0x40000 #define DHD_PNO_VAL 0x80000 +#define DHD_RTT_VAL 0x100000 #ifdef SDTEST /* For pktgen iovar */ diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h index 101944c0f5d6750d2cedd54b827ce8f26fa8fffe..ad50e1aa47c7a1d635eeaccf320898b3296e223b 100644 --- a/drivers/net/wireless/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/bcmdhd/include/epivers.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ * @@ -12,19 +30,19 @@ #define EPI_MINOR_VERSION 201 -#define EPI_RC_NUMBER 34 +#define EPI_RC_NUMBER 2 #define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 1, 201, 34, 0 +#define EPI_VERSION 1, 201, 31, 0 -#define EPI_VERSION_NUM 0x01c92200 +#define EPI_VERSION_NUM 0x01c90200 -#define EPI_VERSION_DEV 1.201.34 +#define EPI_VERSION_DEV 1.201.31 /* Driver Version String, ASCII, 32 chars max */ -#define EPI_VERSION_STR "1.201.34 (r491657)" +#define EPI_VERSION_STR "1.201.31 (r)" #endif /* _epivers_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h.in b/drivers/net/wireless/bcmdhd/include/epivers.h.in deleted file mode 100644 index 9897e987a87c736df789bc2ae46cdd3bbcd9fb20..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/include/epivers.h.in +++ /dev/null @@ -1,30 +0,0 @@ -/* - * $Copyright Open Broadcom Corporation$ - * - * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ - * -*/ - -#ifndef _epivers_h_ -#define _epivers_h_ - -#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ - -#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ - -#define EPI_RC_NUMBER @EPI_RC_NUMBER@ - -#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ - -#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ - -#define EPI_VERSION @EPI_VERSION@ - -#define EPI_VERSION_NUM @EPI_VERSION_NUM@ - -#define EPI_VERSION_DEV @EPI_VERSION_DEV@ - -/* Driver Version String, ASCII, 32 chars max */ -#define EPI_VERSION_STR "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@)" - -#endif /* _epivers_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/epivers.sh b/drivers/net/wireless/bcmdhd/include/epivers.sh deleted file mode 100644 index 9a723527b5347804bf2c13f9fc8aedd032a33f9d..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/bcmdhd/include/epivers.sh +++ /dev/null @@ -1,333 +0,0 @@ -#! /bin/bash -# -# Create the epivers.h file from epivers.h.in -# -# Epivers.h version support svn/sparse/gclient workspaces -# -# $Id: epivers.sh 389103 2013-03-05 17:24:49Z $ -# -# Version generation works off of svn property HeadURL, if -# not set it keys its versions from current svn workspace or -# via .gclient_info deps contents -# -# GetCompVer.py return value and action needed -# i. trunk => use current date as version string -# ii. local => use SVNURL expanded by HeadURL keyword -# iii. <tag> => use it as as is -# (some components can override and say give me native ver) -# iv. empty => -# a) If TAG is specified use it -# a) If no TAG is specified use date -# -# Contact: Prakash Dhavali -# Contact: hnd-software-scm-list -# - -# If the version header file already exists, increment its build number. -# Otherwise, create a new file. -if [ -f epivers.h ]; then - - # If REUSE_VERSION is set, epivers iteration is not incremented - # This can be used precommit and continuous integration projects - if [ -n "$REUSE_VERSION" ]; then - echo "Previous epivers.h exists. Skipping version increment" - exit 0 - fi - - build=$(grep EPI_BUILD_NUMBER epivers.h | sed -e "s,.*BUILD_NUMBER[ ]*,,") - build=$(expr ${build} + 1) - echo build=${build} - sed -e "s,.*_BUILD_NUMBER.*,#define EPI_BUILD_NUMBER ${build}," \ - < epivers.h > epivers.h.new - cp -p epivers.h epivers.h.prev - mv epivers.h.new epivers.h - exit 0 - -else # epivers.h doesn't exist - - SVNCMD=${SVNCMD:-"svn --non-interactive"} - SRCBASE=${SRCBASE:-..} - NULL=/dev/null - [ -z "$VERBOSE" ] || NULL=/dev/stderr - - # Check for the in file, if not there we're in the wrong directory - if [ ! -f epivers.h.in ]; then - echo "ERROR: No epivers.h.in found" - exit 1 - fi - - # Following SVNURL should be expanded on checkout - SVNURL='$HeadURL: http://svn.sj.broadcom.com/svn/wlansvn/proj/tags/DHD/DHD_REL_1_201_34/src/include/epivers.sh $' - - # .gclient_info is created by gclient checkout/sync steps - # and contains "DEPS='<deps-url1> <deps-url2> ..." entry - GCLIENT_INFO=${GCLIENT_INFO:-${SRCBASE}/../.gclient_info} - - # In gclient, derive SVNURL from gclient_info file - if [ -s "${GCLIENT_INFO}" ]; then - source ${GCLIENT_INFO} - if [ -z "$DEPS" ]; then - echo "ERROR: DEPS entry missing in $GCLIENT_INFO" - exit 1 - else - for dep in $DEPS; do - SVNURL=${SVNURL:-$dep} - # Set SVNURL to first DEPS with /tags/ (if any) - if [[ $dep == */tags/* ]]; then - SVNURL=$dep - echo "INFO: Found gclient DEPS: $SVNURL" - break - fi - done - fi - elif [ -f "${GCLIENT_INFO}" ]; then - echo "ERROR: $GCLIENT_INFO exists, but it is empty" - exit 1 - fi - - # If SVNURL isn't expanded, extract it from svn info - if echo "$SVNURL" | egrep -vq 'HeadURL.*epivers.sh.*|http://.*/DEPS'; then - [ -n "$VERBOSE" ] && \ - echo "DBG: SVN URL ($SVNURL) wasn't expanded. Getting it from svn info" - SVNURL=$($SVNCMD info epivers.sh 2> $NULL | egrep "^URL:") - fi - - if echo "${TAG}" | grep -q "_BRANCH_\|_TWIG_"; then - branchtag=$TAG - else - branchtag="" - fi - - # If this is a tagged build, use the tag to supply the numbers - # Tag should be in the form - # <NAME>_REL_<MAJ>_<MINOR> - # or - # <NAME>_REL_<MAJ>_<MINOR>_RC<RCNUM> - # or - # <NAME>_REL_<MAJ>_<MINOR>_RC<RCNUM>_<INCREMENTAL> - - MERGERLOG=${SRCBASE}/../merger_sources.log - GETCOMPVER=getcompver.py - GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER - GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET} - - # - # If there is a local copy GETCOMPVER use it ahead of network copy - # - if [ -s "$GETCOMPVER" ]; then - GETCOMPVER_PATH="$GETCOMPVER" - elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then - GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER" - elif [ -s "$GETCOMPVER_NET" ]; then - GETCOMPVER_PATH="$GETCOMPVER_NET" - elif [ -s "$GETCOMPVER_NET_WIN" ]; then - GETCOMPVER_PATH="$GETCOMPVER_NET_WIN" - fi - - # - # If $GETCOMPVER isn't found, fetch it from SVN - # (this should be very rare) - # - if [ ! -s "$GETCOMPVER_PATH" ]; then - [ -n "$VERBOSE" ] && \ - echo "DBG: Fetching $GETCOMPVER from trunk" - - $SVNCMD export -q \ - ^/proj/trunk/src/tools/build/${GETCOMPVER} \ - ${GETCOMPVER} 2> $NULL - - GETCOMPVER_PATH=$GETCOMPVER - fi - - # Now get tag for src/include from automerger log - [ -n "$VERBOSE" ] && \ - echo "DBG: python $GETCOMPVER_PATH $MERGERLOG src/include" - - COMPTAG=$(python $GETCOMPVER_PATH $MERGERLOG src/include 2> $NULL | sed -e 's/[[:space:]]*//g') - - echo "DBG: Component Tag String Derived = $COMPTAG" - - # Process COMPTAG values - # Rule: - # If trunk is returned, use date as component tag - # If LOCAL_COMPONENT is returned, use SVN URL to get native tag - # If component is returned or empty, assign it to SVNTAG - # GetCompVer.py return value and action needed - # i. trunk => use current date as version string - # ii. local => use SVNURL expanded by HeadURL keyword - # iii. <tag> => use it as as is - # iv. empty => - # a) If TAG is specified use it - # a) If no TAG is specified use SVNURL from HeadURL - - SVNURL_VER=false - - if [ "$COMPTAG" == "" ]; then - SVNURL_VER=true - elif [ "$COMPTAG" == "LOCAL_COMPONENT" ]; then - SVNURL_VER=true - elif [ "$COMPTAG" == "trunk" ]; then - SVNTAG=$(date '+TRUNKCOMP_REL_%Y_%m_%d') - else - SVNTAG=$COMPTAG - fi - - # Given SVNURL path conventions or naming conventions, derive SVNTAG - # TO-DO: SVNTAG derivation logic can move to a central common API - # TO-DO: ${SRCBASE}/tools/build/svnurl2tag.sh - if [ "$SVNURL_VER" == "true" ]; then - case "${SVNURL}" in - *_BRANCH_*) - SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_BRANCH_/{printf "%s",$1}') - ;; - *_TWIG_*) - SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_TWIG_/{printf "%s",$1}') - ;; - *_REL_*) - SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_REL_/{printf "%s",$1}') - ;; - */branches/*) - SVNTAG=${SVNURL#*/branches/} - SVNTAG=${SVNTAG%%/*} - ;; - */proj/tags/*|*/deps/tags/*) - SVNTAG=${SVNURL#*/tags/*/} - SVNTAG=${SVNTAG%%/*} - ;; - */trunk/*) - SVNTAG=$(date '+TRUNKURL_REL_%Y_%m_%d') - ;; - *) - SVNTAG=$(date '+OTHER_REL_%Y_%m_%d') - ;; - esac - echo "DBG: Native Tag String Derived from URL: $SVNTAG" - else - echo "DBG: Native Tag String Derived: $SVNTAG" - fi - - TAG=${SVNTAG} - - # Normalize the branch name portion to "D11" in case it has underscores in it - branch_name=$(expr match "$TAG" '\(.*\)_\(BRANCH\|TWIG\|REL\)_.*') - TAG=$(echo $TAG | sed -e "s%^$branch_name%D11%") - - # Split the tag into an array on underbar or whitespace boundaries. - IFS="_ " tag=(${TAG}) - unset IFS - - tagged=1 - if [ ${#tag[*]} -eq 0 ]; then - tag=($(date '+TOT REL %Y %m %d 0 %y')); - # reconstruct a TAG from the date - TAG=${tag[0]}_${tag[1]}_${tag[2]}_${tag[3]}_${tag[4]}_${tag[5]} - tagged=0 - fi - - # Allow environment variable to override values. - # Missing values default to 0 - # - maj=${EPI_MAJOR_VERSION:-${tag[2]:-0}} - min=${EPI_MINOR_VERSION:-${tag[3]:-0}} - rcnum=${EPI_RC_NUMBER:-${tag[4]:-0}} - - # If increment field is 0, set it to date suffix if on TOB - if [ -n "$branchtag" ]; then - [ "${tag[5]:-0}" -eq 0 ] && echo "Using date suffix for incr" - today=${EPI_DATE_STR:-$(date '+%Y%m%d')} - incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-${today:-0}}} - else - incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} - fi - origincr=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} - build=${EPI_BUILD_NUMBER:-0} - - # Strip 'RC' from front of rcnum if present - rcnum=${rcnum/#RC/} - - # strip leading zero off the number (otherwise they look like octal) - maj=${maj/#0/} - min=${min/#0/} - rcnum=${rcnum/#0/} - incremental=${incremental/#0/} - origincr=${origincr/#0/} - build=${build/#0/} - - # some numbers may now be null. replace with with zero. - maj=${maj:-0} - min=${min:-0} - - rcnum=${rcnum:-0} - incremental=${incremental:-0} - origincr=${origincr:-0} - build=${build:-0} - - if [ -n "$EPI_VERSION_NUM" ]; then - vernum=$EPI_VERSION_NUM - elif [ ${tagged} -eq 1 ]; then - # vernum is 32chars max - vernum=$(printf "0x%02x%02x%02x%02x" ${maj} ${min} ${rcnum} ${origincr}) - else - vernum=$(printf "0x00%02x%02x%02x" ${tag[7]} ${min} ${rcnum}) - fi - - # make sure the size of vernum is under 32 bits. - # Otherwise, truncate. The string will keep full information. - vernum=${vernum:0:10} - - # build the string directly from the tag, irrespective of its length - # remove the name , the tag type, then replace all _ by . - tag_ver_str=${TAG/${tag[0]}_} - tag_ver_str=${tag_ver_str/${tag[1]}_} - tag_ver_str=${tag_ver_str//_/.} - - # record tag type - tagtype= - - if [ "${tag[1]}" = "BRANCH" -o "${tag[1]}" = "TWIG" ]; then - tagtype=" (TOB)" - echo "tag type: $tagtype" - fi - - echo "Effective version string: $tag_ver_str" - - if [ "$(uname -s)" == "Darwin" ]; then - # Mac does not like 2-digit numbers so convert the number to single - # digit. 5.100 becomes 5.1 - if [ $min -gt 99 ]; then - minmac=$(expr $min / 100) - else - minmac=$min - fi - epi_ver_dev="${maj}.${minmac}.0" - else - epi_ver_dev="${maj}.${min}.${rcnum}" - fi - - # Finally get version control revision number of <SRCBASE> (if any) - vc_version_num=$($SVNCMD info ${SRCBASE} 2> $NULL | awk -F': ' '/^Last Changed Rev: /{printf "%s", $2}') - - # OK, go do it - echo "maj=${maj}, min=${min}, rc=${rcnum}, inc=${incremental}, build=${build}" - - sed \ - -e "s;@EPI_MAJOR_VERSION@;${maj};" \ - -e "s;@EPI_MINOR_VERSION@;${min};" \ - -e "s;@EPI_RC_NUMBER@;${rcnum};" \ - -e "s;@EPI_INCREMENTAL_NUMBER@;${incremental};" \ - -e "s;@EPI_BUILD_NUMBER@;${build};" \ - -e "s;@EPI_VERSION@;${maj}, ${min}, ${rcnum}, ${incremental};" \ - -e "s;@EPI_VERSION_STR@;${tag_ver_str};" \ - -e "s;@EPI_VERSION_TYPE@;${tagtype};" \ - -e "s;@VERSION_TYPE@;${tagtype};" \ - -e "s;@EPI_VERSION_NUM@;${vernum};" \ - -e "s;@EPI_VERSION_DEV@;${epi_ver_dev};" \ - -e "s;@VC_VERSION_NUM@;r${vc_version_num};" \ - < epivers.h.in > epivers.h - - # In shared workspaces across different platforms, ensure that - # windows generated file is made platform neutral without CRLF - if uname -s | egrep -i -q "cygwin"; then - dos2unix epivers.h > $NULL 2>&1 - fi -fi # epivers.h diff --git a/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h b/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h index 69738bb1fdca1fa10b152fa702cc78f9316e0acb..93f353e853b87306bd6e531858113891fac49e90 100644 --- a/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h +++ b/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h @@ -1,7 +1,25 @@ /* * HND arm trap handling. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: hnd_armtrap.h 470663 2014-04-16 00:24:43Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/hnd_cons.h b/drivers/net/wireless/bcmdhd/include/hnd_cons.h index dbc83052d980ac4612d4b298ea7a44fcdaa57ee5..0b48ef8e842d9a2e5996c69f92d18b5361b62b97 100644 --- a/drivers/net/wireless/bcmdhd/include/hnd_cons.h +++ b/drivers/net/wireless/bcmdhd/include/hnd_cons.h @@ -1,7 +1,25 @@ /* * Console support for RTE - for host use only. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: hnd_cons.h 473343 2014-04-29 01:45:22Z $ */ @@ -11,7 +29,16 @@ #include <typedefs.h> #include <siutils.h> +#if defined(RWL_DONGLE) || defined(UART_REFLECTOR) +/* For Dongle uart tranport max cmd len is 256 bytes + header length (16 bytes) + * In case of ASD commands we are not sure about how much is the command size + * To be on the safe side, input buf len CBUF_LEN is increased to max (512) bytes. + */ +#define RWL_MAX_DATA_LEN (512 + 8) /* allow some extra bytes for '/n' termination */ +#define CBUF_LEN (RWL_MAX_DATA_LEN + 64) /* allow 64 bytes for header ("rwl...") */ +#else #define CBUF_LEN (128) +#endif /* RWL_DONGLE || UART_REFLECTOR */ #define LOG_BUF_LEN 1024 diff --git a/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h b/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h index 3e6878a1174717715972e6aec394f196b56df4ff..4b78a2172ee2f4ad3e7fa1a26373dacce4be8271 100644 --- a/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h +++ b/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h @@ -1,7 +1,25 @@ /* * HND generic packet pool operation primitives * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: $ */ diff --git a/drivers/net/wireless/bcmdhd/include/hnd_pktq.h b/drivers/net/wireless/bcmdhd/include/hnd_pktq.h index c27a21d581bab5a3300f6df9b754fa03e0894db8..ef3d4c8f4face58777fb084a3b267a1c4d64653a 100644 --- a/drivers/net/wireless/bcmdhd/include/hnd_pktq.h +++ b/drivers/net/wireless/bcmdhd/include/hnd_pktq.h @@ -1,7 +1,25 @@ /* * HND generic pktq operation primitives * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: $ */ diff --git a/drivers/net/wireless/bcmdhd/include/hndpmu.h b/drivers/net/wireless/bcmdhd/include/hndpmu.h index fc402b07228fabae16c764f590bb682a1845a495..9a31663302cf38cd7e95d003b7eacae4d61b69f8 100644 --- a/drivers/net/wireless/bcmdhd/include/hndpmu.h +++ b/drivers/net/wireless/bcmdhd/include/hndpmu.h @@ -1,7 +1,25 @@ /* * HND SiliconBackplane PMU support. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: hndpmu.h 471127 2014-04-17 23:24:23Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/hndsoc.h b/drivers/net/wireless/bcmdhd/include/hndsoc.h index a44c2f7c2b5f1d45d8f3899a0c16755951e40a28..947db00b487972a554e99c87348cc40a149b75a1 100644 --- a/drivers/net/wireless/bcmdhd/include/hndsoc.h +++ b/drivers/net/wireless/bcmdhd/include/hndsoc.h @@ -1,7 +1,25 @@ /* * Broadcom HND chip & on-chip-interconnect-related definitions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: hndsoc.h 473238 2014-04-28 19:14:56Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h index a7e2fe374be9a3508f1d3a776cc4d4d1987550c8..1adfb1b574219e42e19e011f0c53ae3fbf0ab881 100644 --- a/drivers/net/wireless/bcmdhd/include/linux_osl.h +++ b/drivers/net/wireless/bcmdhd/include/linux_osl.h @@ -1,9 +1,27 @@ /* * Linux OS Independent Layer * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: linux_osl.h 491170 2014-07-15 06:23:58Z $ + * $Id: linux_osl.h 474317 2014-04-30 21:49:42Z $ */ #ifndef _linux_osl_h_ @@ -33,10 +51,6 @@ extern int osl_static_mem_init(osl_t *osh, void *adapter); extern int osl_static_mem_deinit(osl_t *osh, void *adapter); extern void osl_set_bus_handle(osl_t *osh, void *bus_handle); extern void* osl_get_bus_handle(osl_t *osh); -#ifdef EXYNOS5433_PCIE_WAR -extern void exynos_pcie_set_l1_exit(void); -extern void exynos_pcie_clear_l1_exit(void); -#endif /* EXYNOS5433_PCIE_WAR */ /* Global ASSERT type */ extern uint32 g_assert_type; @@ -57,7 +71,7 @@ extern void osl_assert(const char *exp, const char *file, int line); #define ASSERT(exp) #endif /* GCC_VERSION > 30100 */ #endif /* __GNUC__ */ -#endif +#endif /* bcm_prefetch_32B */ static inline void bcm_prefetch_32B(const uint8 *addr, const int cachelines_32B) @@ -69,7 +83,7 @@ static inline void bcm_prefetch_32B(const uint8 *addr, const int cachelines_32B) case 2: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 32) : "cc"); case 1: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 0) : "cc"); } -#endif +#endif } /* microsecond delay */ @@ -173,7 +187,7 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); /* API for DMA addressing capability */ #define OSL_DMADDRWIDTH(osh, addrwidth) ({BCM_REFERENCE(osh); BCM_REFERENCE(addrwidth);}) -#if (defined(BCM47XX_CA9) && defined(__ARM_ARCH_7A__)) +#if defined(__mips__) || (defined(BCM47XX_CA9) && defined(__ARM_ARCH_7A__)) extern void osl_cache_flush(void *va, uint size); extern void osl_cache_inv(void *va, uint size); extern void osl_prefetch(const void *ptr); @@ -192,7 +206,7 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #define OSL_PREFETCH(ptr) BCM_REFERENCE(ptr) #define OSL_ARCH_IS_COHERENT() NULL -#endif +#endif /* register access macros */ #if defined(BCMSDIO) @@ -210,7 +224,7 @@ extern void osl_pcie_rreg(osl_t *osh, ulong addr, void *v, uint size); osl_pcie_rreg(osh, (uintptr)(r), (void *)&__osl_v, sizeof(*(r))); \ __osl_v; \ }) -#endif +#endif #if defined(BCM47XX_ACP_WAR) #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) @@ -225,7 +239,7 @@ extern void osl_pcie_rreg(osl_t *osh, ulong addr, void *v, uint size); #else #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) #define SELECT_BUS_READ(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) -#endif +#endif #endif /* BCM47XX_ACP_WAR */ #define OSL_ERROR(bcmerror) osl_error(bcmerror) @@ -248,7 +262,7 @@ extern int osl_error(int bcmerror); #else #define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 29) */ -#define printf(fmt, args...) printk("BCMDHD:"fmt , ## args) +#define printf(fmt, args...) printk(fmt , ## args) #include <linux/kernel.h> /* for vsn/printf's */ #include <linux/string.h> /* for mem*, str* */ /* bcopy's: Linux kernel doesn't provide these (anymore) */ @@ -258,26 +272,6 @@ extern int osl_error(int bcmerror); /* register access macros */ -#ifdef EXYNOS5433_PCIE_WAR -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - exynos_pcie_set_l1_exit(); \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): __osl_v = \ - readb((volatile uint8*)(r)); break; \ - case sizeof(uint16): __osl_v = \ - readw((volatile uint16*)(r)); break; \ - case sizeof(uint32): __osl_v = \ - readl((volatile uint32*)(r)); break; \ - } \ - exynos_pcie_clear_l1_exit(); \ - __osl_v; \ - }), \ - OSL_READ_REG(osh, r)) \ -) -#else #define R_REG(osh, r) (\ SELECT_BUS_READ(osh, \ ({ \ @@ -294,11 +288,8 @@ extern int osl_error(int bcmerror); }), \ OSL_READ_REG(osh, r)) \ ) -#endif /* EXYNOS5433_PCIE_WAR */ -#ifdef EXYNOS5433_PCIE_WAR #define W_REG(osh, r, v) do { \ - exynos_pcie_set_l1_exit(); \ SELECT_BUS_WRITE(osh, \ switch (sizeof(*(r))) { \ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ @@ -306,19 +297,7 @@ extern int osl_error(int bcmerror); case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ }, \ (OSL_WRITE_REG(osh, r, v))); \ - exynos_pcie_clear_l1_exit(); \ } while (0) -#else -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ - case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ - case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#endif /* EXYNOS5433_PCIE_WAR */ #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) @@ -340,7 +319,7 @@ extern int osl_error(int bcmerror); #define OSL_GETCYCLES(x) rdtscl((x)) #else #define OSL_GETCYCLES(x) ((x) = 0) -#endif +#endif /* dereference an address that may cause a bus exception */ #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) @@ -689,7 +668,7 @@ extern void osl_pkt_frmfwder(osl_t *osh, void *skbs, int skb_cnt, extern void osl_pkt_frmfwder(osl_t *osh, void *skbs, int skb_cnt); #define PKTFRMFWDER(osh, skbs, skb_cnt) \ osl_pkt_frmfwder(((osl_t *)osh), (void *)(skbs), (skb_cnt)) -#endif +#endif /** GMAC Forwarded packet tagging for reduced cache flush/invalidate. diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h index 006c85dd8cacb0b6434b083b24a36f7c2fbcc8d7..c0d8017e0f6a14a7268165a02866923f503db207 100644 --- a/drivers/net/wireless/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/bcmdhd/include/linuxver.h @@ -2,7 +2,25 @@ * Linux-specific abstractions to gain some independence from linux kernel versions. * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: linuxver.h 431983 2013-10-25 06:53:27Z $ */ @@ -11,7 +29,6 @@ #define _linuxver_h_ #include <typedefs.h> - #include <linux/version.h> #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) #include <linux/config.h> @@ -717,7 +734,7 @@ not match our unaligned address for < 2.6.24 * Overide latest kfifo functions with * older version to work on older kernels */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) && !defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) #define kfifo_in_spinlocked(a, b, c, d) kfifo_put(a, (u8 *)b, c) #define kfifo_out_spinlocked(a, b, c, d) kfifo_get(a, (u8 *)b, c) #define kfifo_esize(a) 1 diff --git a/drivers/net/wireless/bcmdhd/include/miniopt.h b/drivers/net/wireless/bcmdhd/include/miniopt.h index ab0360cebd10df3d5b4294dc42667af1e84d74f4..73212a88f1403e864658013df112c5e8969a99e6 100644 --- a/drivers/net/wireless/bcmdhd/include/miniopt.h +++ b/drivers/net/wireless/bcmdhd/include/miniopt.h @@ -1,8 +1,26 @@ /* * Command line options parser. * - * $Copyright Open Broadcom Corporation$ - * $Id: miniopt.h 484281 2014-06-12 22:42:26Z $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * $Id: miniopt.h 241182 2011-02-17 21:50:03Z $ */ @@ -14,8 +32,6 @@ extern "C" { #endif /* ---- Include Files ---------------------------------------------------- */ - - /* ---- Constants and Types ---------------------------------------------- */ #define MINIOPT_MAXKEY 128 /* Max options */ diff --git a/drivers/net/wireless/bcmdhd/include/msgtrace.h b/drivers/net/wireless/bcmdhd/include/msgtrace.h index 8a3f691dbb0b4c0bfe789da0b0bf5aaae83b582d..228c045a288ff3e26e5e167f504b58cdd29ffad2 100644 --- a/drivers/net/wireless/bcmdhd/include/msgtrace.h +++ b/drivers/net/wireless/bcmdhd/include/msgtrace.h @@ -1,7 +1,25 @@ /* * Trace messages sent over HBUS * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: msgtrace.h 439681 2013-11-27 15:39:50Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/osl.h b/drivers/net/wireless/bcmdhd/include/osl.h index 12b8e00b3d61a81d1819eb96da0db8a22f6e6460..1e0455af6e9b51a99d3750abe72fcd5b844ff73d 100644 --- a/drivers/net/wireless/bcmdhd/include/osl.h +++ b/drivers/net/wireless/bcmdhd/include/osl.h @@ -1,7 +1,25 @@ /* * OS Abstraction Layer * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: osl.h 474639 2014-05-01 23:52:31Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/osl_decl.h b/drivers/net/wireless/bcmdhd/include/osl_decl.h index 944945838e98c6eff4049ee90b91f97627d18c29..aafad10b5e7f5637b9958f4e83c49228f9295a84 100644 --- a/drivers/net/wireless/bcmdhd/include/osl_decl.h +++ b/drivers/net/wireless/bcmdhd/include/osl_decl.h @@ -1,7 +1,25 @@ /* * osl forward declarations * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id$ */ diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_end.h b/drivers/net/wireless/bcmdhd/include/packed_section_end.h index bde3959f350bd12d4004bb3b195cdedd64ddaf8c..08c2d5626d6ff6917916bf9f1eebe265b7bf5a82 100644 --- a/drivers/net/wireless/bcmdhd/include/packed_section_end.h +++ b/drivers/net/wireless/bcmdhd/include/packed_section_end.h @@ -15,7 +15,25 @@ * #include <packed_section_end.h> * * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * $Id: packed_section_end.h 437241 2013-11-18 07:39:24Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_start.h b/drivers/net/wireless/bcmdhd/include/packed_section_start.h index 3c22dcb276a91f05e8e340e8b9a591661c065eb2..52dec03d8c82312ec7083cb4ab46443bf6ac04e3 100644 --- a/drivers/net/wireless/bcmdhd/include/packed_section_start.h +++ b/drivers/net/wireless/bcmdhd/include/packed_section_start.h @@ -15,7 +15,25 @@ * #include <packed_section_end.h> * * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * $Id: packed_section_start.h 437241 2013-11-18 07:39:24Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/pcicfg.h b/drivers/net/wireless/bcmdhd/include/pcicfg.h index 0fae96ce00237d59ec8a90cad344150c97f6778c..3390e77a54a20e055396f113ae5eef5e6788965c 100644 --- a/drivers/net/wireless/bcmdhd/include/pcicfg.h +++ b/drivers/net/wireless/bcmdhd/include/pcicfg.h @@ -1,7 +1,25 @@ /* * pcicfg.h: PCI configuration constants and structures. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: pcicfg.h 465082 2014-03-26 17:37:28Z $ */ @@ -9,123 +27,6 @@ #ifndef _h_pcicfg_ #define _h_pcicfg_ -#ifndef LINUX_POSTMOGRIFY_REMOVAL -/* The following inside ifndef's so we don't collide with NTDDK.H */ -#ifndef PCI_MAX_BUS -#define PCI_MAX_BUS 0x100 -#endif -#ifndef PCI_MAX_DEVICES -#define PCI_MAX_DEVICES 0x20 -#endif -#ifndef PCI_MAX_FUNCTION -#define PCI_MAX_FUNCTION 0x8 -#endif - -#ifndef PCI_INVALID_VENDORID -#define PCI_INVALID_VENDORID 0xffff -#endif -#ifndef PCI_INVALID_DEVICEID -#define PCI_INVALID_DEVICEID 0xffff -#endif - - -/* Convert between bus-slot-function-register and config addresses */ - -#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -#define PCICFG_FUN_SHIFT 8 /* Function shift */ -#define PCICFG_OFF_SHIFT 0 /* Register shift */ - -#define PCICFG_BUS_MASK 0xff /* Bus mask */ -#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -#define PCICFG_FUN_MASK 7 /* Function mask */ -#define PCICFG_OFF_MASK 0xff /* Bus mask */ - -#define PCI_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ - | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ - | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ - | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) - -#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) - -/* PCIE Config space accessing MACROS */ - -#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -#define PCIECFG_OFF_SHIFT 0 /* Register shift */ - -#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -#define PCIECFG_FUN_MASK 7 /* Function mask */ -#define PCIECFG_OFF_MASK 0xfff /* Register mask */ - -#define PCIE_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ - | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ - | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ - | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) - -#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) - -/* The actual config space */ - -#define PCI_BAR_MAX 6 - -#define PCI_ROM_BAR 8 - -#define PCR_RSVDA_MAX 2 - -/* Bits in PCI bars' flags */ - -#define PCIBAR_FLAGS 0xf -#define PCIBAR_IO 0x1 -#define PCIBAR_MEM1M 0x2 -#define PCIBAR_MEM64 0x4 -#define PCIBAR_PREFETCH 0x8 -#define PCIBAR_MEM32_MASK 0xFFFFFF80 - -/* pci config status reg has a bit to indicate that capability ptr is present */ - -#define PCI_CAPPTR_PRESENT 0x0010 - -typedef struct _pci_config_regs { - uint16 vendor; - uint16 device; - uint16 command; - uint16 status; - uint8 rev_id; - uint8 prog_if; - uint8 sub_class; - uint8 base_class; - uint8 cache_line_size; - uint8 latency_timer; - uint8 header_type; - uint8 bist; - uint32 base[PCI_BAR_MAX]; - uint32 cardbus_cis; - uint16 subsys_vendor; - uint16 subsys_id; - uint32 baserom; - uint32 rsvd_a[PCR_RSVDA_MAX]; - uint8 int_line; - uint8 int_pin; - uint8 min_gnt; - uint8 max_lat; - uint8 dev_dep[192]; -} pci_config_regs; - -#define SZPCR (sizeof (pci_config_regs)) -#define MINSZPCR 64 /* offsetof (dev_dep[0] */ - -#endif /* !LINUX_POSTMOGRIFY_REMOVAL */ /* A structure for the config registers is nice, but in most * systems the config space is not memory mapped, so we need * field offsetts. :-( @@ -158,318 +59,6 @@ typedef struct _pci_config_regs { #define PCI_CFG_MINGNT 0x3e #define PCI_CFG_MAXLAT 0x3f #define PCI_CFG_DEVCTRL 0xd8 -#ifndef LINUX_POSTMOGRIFY_REMOVAL - - - -/* Classes and subclasses */ - -typedef enum { - PCI_CLASS_OLD = 0, - PCI_CLASS_DASDI, - PCI_CLASS_NET, - PCI_CLASS_DISPLAY, - PCI_CLASS_MMEDIA, - PCI_CLASS_MEMORY, - PCI_CLASS_BRIDGE, - PCI_CLASS_COMM, - PCI_CLASS_BASE, - PCI_CLASS_INPUT, - PCI_CLASS_DOCK, - PCI_CLASS_CPU, - PCI_CLASS_SERIAL, - PCI_CLASS_INTELLIGENT = 0xe, - PCI_CLASS_SATELLITE, - PCI_CLASS_CRYPT, - PCI_CLASS_DSP, - PCI_CLASS_XOR = 0xfe -} pci_classes; - -typedef enum { - PCI_DASDI_SCSI, - PCI_DASDI_IDE, - PCI_DASDI_FLOPPY, - PCI_DASDI_IPI, - PCI_DASDI_RAID, - PCI_DASDI_OTHER = 0x80 -} pci_dasdi_subclasses; - -typedef enum { - PCI_NET_ETHER, - PCI_NET_TOKEN, - PCI_NET_FDDI, - PCI_NET_ATM, - PCI_NET_OTHER = 0x80 -} pci_net_subclasses; - -typedef enum { - PCI_DISPLAY_VGA, - PCI_DISPLAY_XGA, - PCI_DISPLAY_3D, - PCI_DISPLAY_OTHER = 0x80 -} pci_display_subclasses; - -typedef enum { - PCI_MMEDIA_VIDEO, - PCI_MMEDIA_AUDIO, - PCI_MMEDIA_PHONE, - PCI_MEDIA_OTHER = 0x80 -} pci_mmedia_subclasses; - -typedef enum { - PCI_MEMORY_RAM, - PCI_MEMORY_FLASH, - PCI_MEMORY_OTHER = 0x80 -} pci_memory_subclasses; - -typedef enum { - PCI_BRIDGE_HOST, - PCI_BRIDGE_ISA, - PCI_BRIDGE_EISA, - PCI_BRIDGE_MC, - PCI_BRIDGE_PCI, - PCI_BRIDGE_PCMCIA, - PCI_BRIDGE_NUBUS, - PCI_BRIDGE_CARDBUS, - PCI_BRIDGE_RACEWAY, - PCI_BRIDGE_OTHER = 0x80 -} pci_bridge_subclasses; - -typedef enum { - PCI_COMM_UART, - PCI_COMM_PARALLEL, - PCI_COMM_MULTIUART, - PCI_COMM_MODEM, - PCI_COMM_OTHER = 0x80 -} pci_comm_subclasses; - -typedef enum { - PCI_BASE_PIC, - PCI_BASE_DMA, - PCI_BASE_TIMER, - PCI_BASE_RTC, - PCI_BASE_PCI_HOTPLUG, - PCI_BASE_OTHER = 0x80 -} pci_base_subclasses; - -typedef enum { - PCI_INPUT_KBD, - PCI_INPUT_PEN, - PCI_INPUT_MOUSE, - PCI_INPUT_SCANNER, - PCI_INPUT_GAMEPORT, - PCI_INPUT_OTHER = 0x80 -} pci_input_subclasses; - -typedef enum { - PCI_DOCK_GENERIC, - PCI_DOCK_OTHER = 0x80 -} pci_dock_subclasses; - -typedef enum { - PCI_CPU_386, - PCI_CPU_486, - PCI_CPU_PENTIUM, - PCI_CPU_ALPHA = 0x10, - PCI_CPU_POWERPC = 0x20, - PCI_CPU_MIPS = 0x30, - PCI_CPU_COPROC = 0x40, - PCI_CPU_OTHER = 0x80 -} pci_cpu_subclasses; - -typedef enum { - PCI_SERIAL_IEEE1394, - PCI_SERIAL_ACCESS, - PCI_SERIAL_SSA, - PCI_SERIAL_USB, - PCI_SERIAL_FIBER, - PCI_SERIAL_SMBUS, - PCI_SERIAL_OTHER = 0x80 -} pci_serial_subclasses; - -typedef enum { - PCI_INTELLIGENT_I2O -} pci_intelligent_subclasses; - -typedef enum { - PCI_SATELLITE_TV, - PCI_SATELLITE_AUDIO, - PCI_SATELLITE_VOICE, - PCI_SATELLITE_DATA, - PCI_SATELLITE_OTHER = 0x80 -} pci_satellite_subclasses; - -typedef enum { - PCI_CRYPT_NETWORK, - PCI_CRYPT_ENTERTAINMENT, - PCI_CRYPT_OTHER = 0x80 -} pci_crypt_subclasses; - -typedef enum { - PCI_DSP_DPIO, - PCI_DSP_OTHER = 0x80 -} pci_dsp_subclasses; - -typedef enum { - PCI_XOR_QDMA, - PCI_XOR_OTHER = 0x80 -} pci_xor_subclasses; - -/* Header types */ -#define PCI_HEADER_MULTI 0x80 -#define PCI_HEADER_MASK 0x7f -typedef enum { - PCI_HEADER_NORMAL, - PCI_HEADER_BRIDGE, - PCI_HEADER_CARDBUS -} pci_header_types; - - -/* Overlay for a PCI-to-PCI bridge */ - -#define PPB_RSVDA_MAX 2 -#define PPB_RSVDD_MAX 8 - -typedef struct _ppb_config_regs { - uint16 vendor; - uint16 device; - uint16 command; - uint16 status; - uint8 rev_id; - uint8 prog_if; - uint8 sub_class; - uint8 base_class; - uint8 cache_line_size; - uint8 latency_timer; - uint8 header_type; - uint8 bist; - uint32 rsvd_a[PPB_RSVDA_MAX]; - uint8 prim_bus; - uint8 sec_bus; - uint8 sub_bus; - uint8 sec_lat; - uint8 io_base; - uint8 io_lim; - uint16 sec_status; - uint16 mem_base; - uint16 mem_lim; - uint16 pf_mem_base; - uint16 pf_mem_lim; - uint32 pf_mem_base_hi; - uint32 pf_mem_lim_hi; - uint16 io_base_hi; - uint16 io_lim_hi; - uint16 subsys_vendor; - uint16 subsys_id; - uint32 rsvd_b; - uint8 rsvd_c; - uint8 int_pin; - uint16 bridge_ctrl; - uint8 chip_ctrl; - uint8 diag_ctrl; - uint16 arb_ctrl; - uint32 rsvd_d[PPB_RSVDD_MAX]; - uint8 dev_dep[192]; -} ppb_config_regs; - - -/* PCI CAPABILITY DEFINES */ -#define PCI_CAP_POWERMGMTCAP_ID 0x01 -#define PCI_CAP_MSICAP_ID 0x05 -#define PCI_CAP_VENDSPEC_ID 0x09 -#define PCI_CAP_PCIECAP_ID 0x10 - -/* Data structure to define the Message Signalled Interrupt facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_msi { - uint8 capID; - uint8 nextptr; - uint16 msgctrl; - uint32 msgaddr; -} pciconfig_cap_msi; -#define MSI_ENABLE 0x1 /* bit 0 of msgctrl */ - -/* Data structure to define the Power managment facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_pwrmgmt { - uint8 capID; - uint8 nextptr; - uint16 pme_cap; - uint16 pme_sts_ctrl; - uint8 pme_bridge_ext; - uint8 data; -} pciconfig_cap_pwrmgmt; - -#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */ -#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */ -#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */ -#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */ - -/* Data structure to define the PCIE capability */ -typedef struct _pciconfig_cap_pcie { - uint8 capID; - uint8 nextptr; - uint16 pcie_cap; - uint32 dev_cap; - uint16 dev_ctrl; - uint16 dev_status; - uint32 link_cap; - uint16 link_ctrl; - uint16 link_status; - uint32 slot_cap; - uint16 slot_ctrl; - uint16 slot_status; - uint16 root_ctrl; - uint16 root_cap; - uint32 root_status; -} pciconfig_cap_pcie; - -/* PCIE Enhanced CAPABILITY DEFINES */ -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCIE_ADVERRREP_CAPID 0x0001 -#define PCIE_VC_CAPID 0x0002 -#define PCIE_DEVSNUM_CAPID 0x0003 -#define PCIE_PWRBUDGET_CAPID 0x0004 - -/* PCIE Extended configuration */ -#define PCIE_ADV_CORR_ERR_MASK 0x114 -#define CORR_ERR_RE (1 << 0) /* Receiver */ -#define CORR_ERR_BT (1 << 6) /* Bad TLP */ -#define CORR_ERR_BD (1 << 7) /* Bad DLLP */ -#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */ -#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */ -#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \ - CORR_ERR_RR | CORR_ERR_RT) - -/* PCIE Root Control Register bits (Host mode only) */ -#define PCIE_RC_CORR_SERR_EN 0x0001 -#define PCIE_RC_NONFATAL_SERR_EN 0x0002 -#define PCIE_RC_FATAL_SERR_EN 0x0004 -#define PCIE_RC_PME_INT_EN 0x0008 -#define PCIE_RC_CRS_EN 0x0010 - -/* PCIE Root Capability Register bits (Host mode only) */ -#define PCIE_RC_CRS_VISIBILITY 0x0001 - -/* Header to define the PCIE specific capabilities in the extended config space */ -typedef struct _pcie_enhanced_caphdr { - uint16 capID; - uint16 cap_ver : 4; - uint16 next_ptr : 12; -} pcie_enhanced_caphdr; - - -/* Everything below is BRCM HND proprietary */ - - -/* Brcm PCI configuration registers */ -#define cap_list rsvd_a[0] -#define bar0_window dev_dep[0x80 - 0x40] -#define bar1_window dev_dep[0x84 - 0x40] -#define sprom_control dev_dep[0x88 - 0x40] -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ #define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ #define PCI_SPROM_CONTROL 0x88 /* sprom property control */ @@ -527,38 +116,6 @@ typedef struct _pcie_enhanced_caphdr { #define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ #define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL -/* On AI chips we have a second window to map DMP regs are mapped: */ -#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */ - -/* PCI_INT_STATUS */ -#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ - -/* PCI_INT_MASK */ -#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ - -#ifndef LINUX_POSTMOGRIFY_REMOVAL -/* PCI_SPROM_CONTROL */ -#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ -#define SPROM_LOCKED 0x08 /* SPROM Locked */ -#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ -#define SPROM_WRITEEN 0x10 /* SPROM write enable */ -#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ -#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */ -#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - -/* Bits in PCI command and status regs */ -#define PCI_CMD_IO 0x00000001 /* I/O enable */ -#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */ -#define PCI_CMD_MASTER 0x00000004 /* Master enable */ -#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */ -#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */ -#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */ -#define PCI_STAT_TA 0x08000000 /* target abort status */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define PCI_CONFIG_SPACE_SIZE 256 #endif /* _h_pcicfg_ */ diff --git a/drivers/net/wireless/bcmdhd/include/pcie_core.h b/drivers/net/wireless/bcmdhd/include/pcie_core.h index 73028da88e6e4a763905586cfa43587df6788b43..242a9a2685ffe297ed11e1a4bf8bae6108fde4d8 100644 --- a/drivers/net/wireless/bcmdhd/include/pcie_core.h +++ b/drivers/net/wireless/bcmdhd/include/pcie_core.h @@ -1,9 +1,27 @@ /* * BCM43XX PCIE core hardware definitions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: pcie_core.h 483003 2014-06-05 19:57:46Z $ + * $Id: pcie_core.h 468449 2014-04-07 21:50:10Z $ */ #ifndef _PCIE_CORE_H #define _PCIE_CORE_H @@ -311,12 +329,6 @@ typedef struct sbpcieregs { #define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3 */ #define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4 */ -/* PCIE2 MDIO register offsets */ -#define PCIE2_MDIO_CONTROL 0x128 -#define PCIE2_MDIO_WR_DATA 0x12C -#define PCIE2_MDIO_RD_DATA 0x130 - - /* MDIO control */ #define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ #define MDIOCTL_DIVISOR_VAL 0x2 diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11.h b/drivers/net/wireless/bcmdhd/include/proto/802.11.h index 3b900145f26d0d34540f62c0ee72cfe752f9862a..7a584f4a5784e51d74de9482525e4a9b141ed05d 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental types and constants relating to 802.11 * @@ -2889,36 +2907,6 @@ typedef struct d11cnt { #define PROXD_AF_TYPE 11 /* Wifi proximity action frame type */ #define BRCM_RELMACST_AF_TYPE 12 /* RMC action frame type */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL -/* - * This BRCM_PROP_OUI types is intended for use in events to embed additional - * data, and would not be expected to appear on the air -- but having an IE - * format allows IE frame data with extra data in events in that allows for - * more flexible parsing. - */ -#define BRCM_EVT_WL_BSS_INFO 64 - -/** - * Following is the generic structure for brcm_prop_ie (uses BRCM_PROP_OUI). - * DPT uses this format with type set to DPT_IE_TYPE - */ -BWL_PRE_PACKED_STRUCT struct brcm_prop_ie_s { - uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ - uint8 len; /* IE length */ - uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ - uint8 type; /* type of this IE */ - uint16 cap; /* DPT capabilities */ -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_prop_ie_s brcm_prop_ie_t; - -#define BRCM_PROP_IE_LEN 6 /* len of fixed part of brcm_prop ie */ - -#define DPT_IE_TYPE 2 - - -#define BRCM_SYSCAP_IE_TYPE 3 -#define WET_TUNNEL_IE_TYPE 3 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ /* brcm syscap_ie cap */ #define BRCM_SYSCAP_WET_TUNNEL 0x0100 /* Device with WET_TUNNEL support */ @@ -3522,10 +3510,6 @@ typedef struct vht_features_ie_hdr vht_features_ie_hdr_t; #define WCN_OUI "\x00\x50\xf2" /* WCN OUI */ #define WCN_TYPE 4 /* WCN type */ -#ifdef BCMWAPI_WPI -#define SMS4_KEY_LEN 16 -#define SMS4_WPI_CBC_MAC_LEN 16 -#endif /* 802.11r protocol definitions */ @@ -3588,13 +3572,6 @@ typedef struct mmic_ie mmic_ie_t; #define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" #define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" -#ifdef BCMWAPI_WAI -#define WAPI_IE_MIN_LEN 20 /* WAPI IE min length */ -#define WAPI_VERSION 1 /* WAPI version */ -#define WAPI_VERSION_LEN 2 /* WAPI version length */ -#define WAPI_OUI "\x00\x14\x72" /* WAPI OUI */ -#define WAPI_OUI_LEN DOT11_OUI_LEN /* WAPI OUI length */ -#endif /* BCMWAPI_WAI */ /* ************* WMM Parameter definitions. ************* */ #define WMM_OUI "\x00\x50\xF2" /* WNN OUI */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h index 1a53542d90188eb6cb325b43153243e76c9fd273..19d898b515e5a42c817a0923e21a1bcd8131a250 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h @@ -1,7 +1,25 @@ /* * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer) * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: 802.11_bta.h 382882 2013-02-04 23:24:31Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h index 914d2781a4e36b0ec0c521fc28a6fefe64d7fd2d..f990f21c67982572acfd8ace826509c477e1964d 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h @@ -1,7 +1,25 @@ /* * 802.11e protocol header file * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: 802.11e.h 382883 2013-02-04 23:26:09Z $ */ @@ -100,12 +118,6 @@ typedef BWL_PRE_PACKED_STRUCT struct tspec { #define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ #define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ #define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ -#ifdef BCMCCX -#define CCX_STATUS_ASSOC_DENIED_UNKNOWN 0xc8 /* unspecified QoS related failure */ -#define CCX_STATUS_ASSOC_DENIED_AP_POLICY 0xc9 /* TSPEC refused due to AP policy */ -#define CCX_STATUS_ASSOC_DENIED_NO_BW 0xca /* Assoc denied due to AP insufficient BW */ -#define CCX_STATUS_ASSOC_DENIED_BAD_PARAM 0xcb /* one or more TSPEC with invalid parameter */ -#endif /* BCMCCX */ /* 802.11e DELTS status code */ #define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h index e7eceb093bb3fdab5def80a1ba774a89e6c1f7d0..17a5430c3b67788bed6269270d9c49f05557abd4 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental types and constants relating to 802.1D * diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.3.h b/drivers/net/wireless/bcmdhd/include/proto/802.3.h index 9901a23be127ef5b39954432e5b7a3de83341861..841e6da5f1d531149adb6e6fad473d79fface6f2 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.3.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.3.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental constants relating to 802.3 * diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h index 165efabe90912245e7d79b973934065534bf8135..ac3397808035cb5f7b4f19654f110690a99e5b97 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h @@ -1,7 +1,25 @@ /* * Broadcom Ethernettype protocol definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmeth.h 445746 2013-12-30 12:57:26Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h index c1d19fd9ae7aa9e72c192888c41189000ef116af..51006b542e8226160242757e634f310ec5e1aaea 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h @@ -1,11 +1,29 @@ /* * Broadcom Event protocol definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Dependencies: proto/bcmeth.h * - * $Id: bcmevent.h 490387 2014-07-10 15:12:52Z $ + * $Id: bcmevent.h 474305 2014-04-30 20:54:29Z $ * */ @@ -121,10 +139,6 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event { #define WLC_E_IBSS_ASSOC 39 #define WLC_E_RADIO 40 #define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */ -#if defined(BCMCCX) && defined(CCX_SDK) -#define WLC_E_CCX_ASSOC_START 42 /* CCX association start */ -#define WLC_E_CCX_ASSOC_ABORT 43 /* CCX association abort */ -#endif /* BCMCCX && CCX_SDK */ #define WLC_E_PROBREQ_MSG 44 /* probe request received */ #define WLC_E_SCAN_CONFIRM_IND 45 #define WLC_E_PSK_SUP 46 /* WPA Handshake fail */ @@ -134,15 +148,10 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event { #define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */ #define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */ #define WLC_E_TRACE 52 -#ifdef WLBTAMP -#define WLC_E_BTA_HCI_EVENT 53 /* BT-AMP HCI event */ -#endif #define WLC_E_IF 54 /* I/F change (for dongle host notification) */ #define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */ #define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */ -#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */ -/* PFN best network batching event, re-use obsolete WLC_E_PFN_SCAN_COMPLETE */ -#define WLC_E_PFN_BEST_BATCHING 57 +#define WLC_E_PFN_BEST_BATCHING 57 /* PFN best network batching event */ #define WLC_E_EXTLOG_MSG 58 #define WLC_E_ACTION_FRAME 59 /* Action frame Rx */ #define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */ @@ -216,13 +225,10 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event { #define WLC_E_RSSI_LQM 133 /* Enhancement addition for WLC_E_RSSI */ #define WLC_E_PFN_GSCAN_FULL_RESULT 134 /* Full probe/beacon (IEs etc) results */ #define WLC_E_PFN_SWC 135 /* Significant change in rssi of bssids being tracked */ +#define WLC_E_PFN_SCAN_COMPLETE 138 /* PFN completed scan of network list */ #define WLC_E_RMC_EVENT 139 /* RMC event */ #define WLC_E_LAST 140 /* highest val + 1 for range checking */ -#if (WLC_E_LAST > 140) -#error "WLC_E_LAST: Invalid value for last event; must be <= 140." -#endif /* WLC_E_LAST */ - /* define an API for getting the string name of an event */ extern const char *bcmevent_get_name(uint event_type); @@ -243,9 +249,6 @@ extern const char *bcmevent_get_name(uint event_type); #define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */ #define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */ #define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */ -#ifdef BCMCCX -#define WLC_E_STATUS_CCXFASTRM 14 /* scan aborted due to CCX fast roam */ -#endif /* BCMCCX */ #define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */ #define WLC_E_STATUS_ERROR 16 /* request failed due to error */ #define WLC_E_STATUS_INVALID 0xff /* Invalid status code to init variables. */ @@ -280,21 +283,11 @@ extern const char *bcmevent_get_name(uint event_type); #define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ #define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ #define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ -#ifdef BCMCCX -#define WLC_E_PRUNE_CCXFAST_PREVAP 11 /* CCX FAST ROAM: prune previous AP */ -#endif /* def BCMCCX */ #define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ #define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ -#ifdef BCMCCX -#define WLC_E_PRUNE_CCXFAST_DROAM 14 /* CCX FAST ROAM: prune unqualified AP */ -#endif /* def BCMCCX */ #define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ #define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ #define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ -#ifdef BCMCCX -#define WLC_E_PRUNE_AP_BLOCKED 18 /* prune blocked AP */ -#define WLC_E_PRUNE_NO_DIAG_SUPPORT 19 /* prune due to diagnostic mode not supported */ -#endif /* BCMCCX */ /* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ #define WLC_E_SUP_OTHER 0 /* Other reason */ @@ -349,10 +342,6 @@ typedef struct wl_event_data_if { #define WLC_E_IF_ROLE_WDS 2 /* WDS link */ #define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */ #define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */ -#ifdef WLBTAMP -#define WLC_E_IF_ROLE_BTA_CREATOR 5 /* BT-AMP Creator */ -#define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 /* BT-AMP Acceptor */ -#endif /* WLC_E_RSSI event data */ typedef struct wl_event_data_rssi { diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h index e427bdc3b9133381438cf3712281314d7539b9bd..05813e02f233063627ad73e4b18a45c49ad4167c 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental constants relating to IP Protocol * diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h b/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h index fff148525632433df747fc4260a5fc81a9218b14..e3351da73fab0b63b7b2944c5c3aed7289b9f55d 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental constants relating to Neighbor Discovery Protocol * diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmtcp.h b/drivers/net/wireless/bcmdhd/include/proto/bcmtcp.h index 09cf24044e3ce9deddddee3d27c223119c9fe20a..84ab8054450a0be7752c7b9fbccd716fa4d400f5 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmtcp.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmtcp.h @@ -1,7 +1,25 @@ /* * Fundamental constants relating to TCP Protocol * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bcmtcp.h 458522 2014-02-27 02:26:15Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h index bc91f8421cc369394074ce08812e7741a2e13a3c..fc05ab14c97d0562fb33acbc6f13f8b9e64f18ac 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h @@ -1,7 +1,25 @@ /* * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface) * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: bt_amp_hci.h 382882 2013-02-04 23:24:31Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h index a166c5f84c0e8e9eaa561a6aa59a21e9eba9cffb..d3ef8c52ba06fa4ca2cf21e8c29911a1af4868bf 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h +++ b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h @@ -1,7 +1,25 @@ /* * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: ethernet.h 473238 2014-04-28 19:14:56Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/p2p.h b/drivers/net/wireless/bcmdhd/include/proto/p2p.h index f50d5ed7eaa58d67f83d14bd5152f369ee4a3650..be73c8b951129510906ea188fd775351d3d18c30 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/p2p.h +++ b/drivers/net/wireless/bcmdhd/include/proto/p2p.h @@ -1,5 +1,23 @@ /* - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * Fundamental types and constants relating to WFA P2P (aka WiFi Direct) * diff --git a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h index 647a217bbbcd83895ddf2e6870110d99a3dac87d..f84d0b81ab166560427271a381fbe9ba7bcaf7d2 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h +++ b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h @@ -1,7 +1,25 @@ /* * SD-SPI Protocol Standard * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sdspi.h 382882 2013-02-04 23:24:31Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/vlan.h b/drivers/net/wireless/bcmdhd/include/proto/vlan.h index ca1f461f5b91e1f6c0e62d665d105b2c35661981..a474cfd4d2fee9edb58a65ad167c12a916c8d386 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/vlan.h +++ b/drivers/net/wireless/bcmdhd/include/proto/vlan.h @@ -1,7 +1,25 @@ /* * 802.1Q VLAN protocol definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: vlan.h 382883 2013-02-04 23:26:09Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/wpa.h b/drivers/net/wireless/bcmdhd/include/proto/wpa.h index 1a27aedbf21f3096b4cbf4c9b4060e95d9dc9bb7..26fdb26b372904873271ad98b576ad502bd3cccd 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/wpa.h +++ b/drivers/net/wireless/bcmdhd/include/proto/wpa.h @@ -1,7 +1,25 @@ /* * Fundamental types and constants relating to WPA * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wpa.h 450928 2014-01-23 14:13:38Z $ */ @@ -101,22 +119,7 @@ typedef BWL_PRE_PACKED_STRUCT struct #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ #define WPA_CIPHER_BIP 6 /* WEP (104-bit) */ #define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */ -#ifdef BCMCCX -#define WPA_CIPHER_CKIP 8 /* KP with no MIC */ -#define WPA_CIPHER_CKIP_MMH 9 /* KP with MIC ("CKIP/MMH", "CKIP+CMIC") */ -#define WPA_CIPHER_WEP_MMH 10 /* MIC with no KP ("WEP/MMH", "CMIC") */ -#define IS_CCX_CIPHER(cipher) ((cipher) == WPA_CIPHER_CKIP || \ - (cipher) == WPA_CIPHER_CKIP_MMH || \ - (cipher) == WPA_CIPHER_WEP_MMH) -#endif - -#ifdef BCMWAPI_WAI -#define WAPI_CIPHER_NONE WPA_CIPHER_NONE -#define WAPI_CIPHER_SMS4 11 - -#define WAPI_CSE_WPI_SMS4 1 -#endif /* BCMWAPI_WAI */ #define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ (cipher) == WPA_CIPHER_WEP_40 || \ @@ -126,17 +129,6 @@ typedef BWL_PRE_PACKED_STRUCT struct (cipher) == WPA_CIPHER_AES_CCM || \ (cipher) == WPA_CIPHER_TPK) -#ifdef BCMWAPI_WAI -#define IS_WAPI_CIPHER(cipher) ((cipher) == WAPI_CIPHER_NONE || \ - (cipher) == WAPI_CSE_WPI_SMS4) - -/* convert WAPI_CSE_WPI_XXX to WAPI_CIPHER_XXX */ -#define WAPI_CSE_WPI_2_CIPHER(cse) ((cse) == WAPI_CSE_WPI_SMS4 ? \ - WAPI_CIPHER_SMS4 : WAPI_CIPHER_NONE) - -#define WAPI_CIPHER_2_CSE_WPI(cipher) ((cipher) == WAPI_CIPHER_SMS4 ? \ - WAPI_CSE_WPI_SMS4 : WAPI_CIPHER_NONE) -#endif /* BCMWAPI_WAI */ /* WPA TKIP countermeasures parameters */ #define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ @@ -178,19 +170,6 @@ typedef BWL_PRE_PACKED_STRUCT struct #define WPA2_PMKID_COUNT_LEN 2 -#ifdef BCMWAPI_WAI -#define WAPI_CAP_PREAUTH RSN_CAP_PREAUTH - -/* Other WAI definition */ -#define WAPI_WAI_REQUEST 0x00F1 -#define WAPI_UNICAST_REKEY 0x00F2 -#define WAPI_STA_AGING 0x00F3 -#define WAPI_MUTIL_REKEY 0x00F4 -#define WAPI_STA_STATS 0x00F5 - -#define WAPI_USK_REKEY_COUNT 0x4000000 /* 0xA00000 */ -#define WAPI_MSK_REKEY_COUNT 0x4000000 /* 0xA00000 */ -#endif /* BCMWAPI_WAI */ /* This marks the end of a packed structure section. */ #include <packed_section_end.h> diff --git a/drivers/net/wireless/bcmdhd/include/proto/wps.h b/drivers/net/wireless/bcmdhd/include/proto/wps.h new file mode 100644 index 0000000000000000000000000000000000000000..41424fa9f432755ba7bbb0900cd62fc0c9fae718 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/proto/wps.h @@ -0,0 +1,386 @@ +/* + * WPS IE definitions + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id$ + */ + +#ifndef _WPS_ +#define _WPS_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Data Element Definitions */ +#define WPS_ID_AP_CHANNEL 0x1001 +#define WPS_ID_ASSOC_STATE 0x1002 +#define WPS_ID_AUTH_TYPE 0x1003 +#define WPS_ID_AUTH_TYPE_FLAGS 0x1004 +#define WPS_ID_AUTHENTICATOR 0x1005 +#define WPS_ID_CONFIG_METHODS 0x1008 +#define WPS_ID_CONFIG_ERROR 0x1009 +#define WPS_ID_CONF_URL4 0x100A +#define WPS_ID_CONF_URL6 0x100B +#define WPS_ID_CONN_TYPE 0x100C +#define WPS_ID_CONN_TYPE_FLAGS 0x100D +#define WPS_ID_CREDENTIAL 0x100E +#define WPS_ID_DEVICE_NAME 0x1011 +#define WPS_ID_DEVICE_PWD_ID 0x1012 +#define WPS_ID_E_HASH1 0x1014 +#define WPS_ID_E_HASH2 0x1015 +#define WPS_ID_E_SNONCE1 0x1016 +#define WPS_ID_E_SNONCE2 0x1017 +#define WPS_ID_ENCR_SETTINGS 0x1018 +#define WPS_ID_ENCR_TYPE 0x100F +#define WPS_ID_ENCR_TYPE_FLAGS 0x1010 +#define WPS_ID_ENROLLEE_NONCE 0x101A +#define WPS_ID_FEATURE_ID 0x101B +#define WPS_ID_IDENTITY 0x101C +#define WPS_ID_IDENTITY_PROOF 0x101D +#define WPS_ID_KEY_WRAP_AUTH 0x101E +#define WPS_ID_KEY_IDENTIFIER 0x101F +#define WPS_ID_MAC_ADDR 0x1020 +#define WPS_ID_MANUFACTURER 0x1021 +#define WPS_ID_MSG_TYPE 0x1022 +#define WPS_ID_MODEL_NAME 0x1023 +#define WPS_ID_MODEL_NUMBER 0x1024 +#define WPS_ID_NW_INDEX 0x1026 +#define WPS_ID_NW_KEY 0x1027 +#define WPS_ID_NW_KEY_INDEX 0x1028 +#define WPS_ID_NEW_DEVICE_NAME 0x1029 +#define WPS_ID_NEW_PWD 0x102A +#define WPS_ID_OOB_DEV_PWD 0x102C +#define WPS_ID_OS_VERSION 0x102D +#define WPS_ID_POWER_LEVEL 0x102F +#define WPS_ID_PSK_CURRENT 0x1030 +#define WPS_ID_PSK_MAX 0x1031 +#define WPS_ID_PUBLIC_KEY 0x1032 +#define WPS_ID_RADIO_ENABLED 0x1033 +#define WPS_ID_REBOOT 0x1034 +#define WPS_ID_REGISTRAR_CURRENT 0x1035 +#define WPS_ID_REGISTRAR_ESTBLSHD 0x1036 +#define WPS_ID_REGISTRAR_LIST 0x1037 +#define WPS_ID_REGISTRAR_MAX 0x1038 +#define WPS_ID_REGISTRAR_NONCE 0x1039 +#define WPS_ID_REQ_TYPE 0x103A +#define WPS_ID_RESP_TYPE 0x103B +#define WPS_ID_RF_BAND 0x103C +#define WPS_ID_R_HASH1 0x103D +#define WPS_ID_R_HASH2 0x103E +#define WPS_ID_R_SNONCE1 0x103F +#define WPS_ID_R_SNONCE2 0x1040 +#define WPS_ID_SEL_REGISTRAR 0x1041 +#define WPS_ID_SERIAL_NUM 0x1042 +#define WPS_ID_SC_STATE 0x1044 +#define WPS_ID_SSID 0x1045 +#define WPS_ID_TOT_NETWORKS 0x1046 +#define WPS_ID_UUID_E 0x1047 +#define WPS_ID_UUID_R 0x1048 +#define WPS_ID_VENDOR_EXT 0x1049 +#define WPS_ID_VERSION 0x104A +#define WPS_ID_X509_CERT_REQ 0x104B +#define WPS_ID_X509_CERT 0x104C +#define WPS_ID_EAP_IDENTITY 0x104D +#define WPS_ID_MSG_COUNTER 0x104E +#define WPS_ID_PUBKEY_HASH 0x104F +#define WPS_ID_REKEY_KEY 0x1050 +#define WPS_ID_KEY_LIFETIME 0x1051 +#define WPS_ID_PERM_CFG_METHODS 0x1052 +#define WPS_ID_SEL_REG_CFG_METHODS 0x1053 +#define WPS_ID_PRIM_DEV_TYPE 0x1054 +#define WPS_ID_SEC_DEV_TYPE_LIST 0x1055 +#define WPS_ID_PORTABLE_DEVICE 0x1056 +#define WPS_ID_AP_SETUP_LOCKED 0x1057 +#define WPS_ID_APP_LIST 0x1058 +#define WPS_ID_EAP_TYPE 0x1059 +#define WPS_ID_INIT_VECTOR 0x1060 +#define WPS_ID_KEY_PROVIDED_AUTO 0x1061 +#define WPS_ID_8021X_ENABLED 0x1062 +#define WPS_ID_WEP_TRANSMIT_KEY 0x1064 +#define WPS_ID_REQ_DEV_TYPE 0x106A + +/* WSC 2.0, WFA Vendor Extension Subelements */ +#define WFA_VENDOR_EXT_ID "\x00\x37\x2A" +#define WPS_WFA_SUBID_VERSION2 0x00 +#define WPS_WFA_SUBID_AUTHORIZED_MACS 0x01 +#define WPS_WFA_SUBID_NW_KEY_SHAREABLE 0x02 +#define WPS_WFA_SUBID_REQ_TO_ENROLL 0x03 +#define WPS_WFA_SUBID_SETTINGS_DELAY_TIME 0x04 +#define WPS_WFA_SUBID_REG_CFG_METHODS 0x05 + + +/* WCN-NET Windows Rally Vertical Pairing Vendor Extensions */ +#define MS_VENDOR_EXT_ID "\x00\x01\x37" +#define WPS_MS_ID_VPI 0x1001 /* Vertical Pairing Identifier TLV */ +#define WPS_MS_ID_TRANSPORT_UUID 0x1002 /* Transport UUID TLV */ + +/* Vertical Pairing Identifier TLV Definitions */ +#define WPS_MS_VPI_TRANSPORT_NONE 0x00 /* None */ +#define WPS_MS_VPI_TRANSPORT_DPWS 0x01 /* Devices Profile for Web Services */ +#define WPS_MS_VPI_TRANSPORT_UPNP 0x02 /* uPnP */ +#define WPS_MS_VPI_TRANSPORT_SDNWS 0x03 /* Secure Devices Profile for Web Services */ +#define WPS_MS_VPI_NO_PROFILE_REQ 0x00 /* Wi-Fi profile not requested. + * Not supported in Windows 7 + */ +#define WPS_MS_VPI_PROFILE_REQ 0x01 /* Wi-Fi profile requested. */ + +/* sizes of the fixed size elements */ +#define WPS_ID_AP_CHANNEL_S 2 +#define WPS_ID_ASSOC_STATE_S 2 +#define WPS_ID_AUTH_TYPE_S 2 +#define WPS_ID_AUTH_TYPE_FLAGS_S 2 +#define WPS_ID_AUTHENTICATOR_S 8 +#define WPS_ID_CONFIG_METHODS_S 2 +#define WPS_ID_CONFIG_ERROR_S 2 +#define WPS_ID_CONN_TYPE_S 1 +#define WPS_ID_CONN_TYPE_FLAGS_S 1 +#define WPS_ID_DEVICE_PWD_ID_S 2 +#define WPS_ID_ENCR_TYPE_S 2 +#define WPS_ID_ENCR_TYPE_FLAGS_S 2 +#define WPS_ID_FEATURE_ID_S 4 +#define WPS_ID_MAC_ADDR_S 6 +#define WPS_ID_MSG_TYPE_S 1 +#define WPS_ID_SC_STATE_S 1 +#define WPS_ID_RF_BAND_S 1 +#define WPS_ID_OS_VERSION_S 4 +#define WPS_ID_VERSION_S 1 +#define WPS_ID_SEL_REGISTRAR_S 1 +#define WPS_ID_SEL_REG_CFG_METHODS_S 2 +#define WPS_ID_REQ_TYPE_S 1 +#define WPS_ID_RESP_TYPE_S 1 +#define WPS_ID_AP_SETUP_LOCKED_S 1 + +/* WSC 2.0, WFA Vendor Extension Subelements */ +#define WPS_WFA_SUBID_VERSION2_S 1 +#define WPS_WFA_SUBID_NW_KEY_SHAREABLE_S 1 +#define WPS_WFA_SUBID_REQ_TO_ENROLL_S 1 +#define WPS_WFA_SUBID_SETTINGS_DELAY_TIME_S 1 +#define WPS_WFA_SUBID_REG_CFG_METHODS_S 2 + +/* Association states */ +#define WPS_ASSOC_NOT_ASSOCIATED 0 +#define WPS_ASSOC_CONN_SUCCESS 1 +#define WPS_ASSOC_CONFIG_FAIL 2 +#define WPS_ASSOC_ASSOC_FAIL 3 +#define WPS_ASSOC_IP_FAIL 4 + +/* Authentication types */ +#define WPS_AUTHTYPE_OPEN 0x0001 +#define WPS_AUTHTYPE_WPAPSK 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_SHARED 0x0004 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_WPA 0x0008 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_WPA2 0x0010 +#define WPS_AUTHTYPE_WPA2PSK 0x0020 + +/* Config methods */ +#define WPS_CONFMET_USBA 0x0001 /* Deprecated in WSC 2.0 */ +#define WPS_CONFMET_ETHERNET 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_CONFMET_LABEL 0x0004 +#define WPS_CONFMET_DISPLAY 0x0008 +#define WPS_CONFMET_EXT_NFC_TOK 0x0010 +#define WPS_CONFMET_INT_NFC_TOK 0x0020 +#define WPS_CONFMET_NFC_INTF 0x0040 +#define WPS_CONFMET_PBC 0x0080 +#define WPS_CONFMET_KEYPAD 0x0100 +/* WSC 2.0 */ +#define WPS_CONFMET_VIRT_PBC 0x0280 +#define WPS_CONFMET_PHY_PBC 0x0480 +#define WPS_CONFMET_VIRT_DISPLAY 0x2008 +#define WPS_CONFMET_PHY_DISPLAY 0x4008 + +/* WPS error messages */ +#define WPS_ERROR_NO_ERROR 0 +#define WPS_ERROR_OOB_INT_READ_ERR 1 +#define WPS_ERROR_DECRYPT_CRC_FAIL 2 +#define WPS_ERROR_CHAN24_NOT_SUPP 3 +#define WPS_ERROR_CHAN50_NOT_SUPP 4 +#define WPS_ERROR_SIGNAL_WEAK 5 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NW_AUTH_FAIL 6 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NW_ASSOC_FAIL 7 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NO_DHCP_RESP 8 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_FAILED_DHCP_CONF 9 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_IP_ADDR_CONFLICT 10 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_FAIL_CONN_REGISTRAR 11 +#define WPS_ERROR_MULTI_PBC_DETECTED 12 +#define WPS_ERROR_ROGUE_SUSPECTED 13 +#define WPS_ERROR_DEVICE_BUSY 14 +#define WPS_ERROR_SETUP_LOCKED 15 +#define WPS_ERROR_MSG_TIMEOUT 16 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_REG_SESSION_TIMEOUT 17 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_DEV_PWD_AUTH_FAIL 18 +#define WPS_ERROR_60GHZ_NOT_SUPPORT 19 +#define WPS_ERROR_PKH_MISMATCH 20 /* Public Key Hash Mismatch */ + +/* Connection types */ +#define WPS_CONNTYPE_ESS 0x01 +#define WPS_CONNTYPE_IBSS 0x02 + +/* Device password ID */ +#define WPS_DEVICEPWDID_DEFAULT 0x0000 +#define WPS_DEVICEPWDID_USER_SPEC 0x0001 +#define WPS_DEVICEPWDID_MACHINE_SPEC 0x0002 +#define WPS_DEVICEPWDID_REKEY 0x0003 +#define WPS_DEVICEPWDID_PUSH_BTN 0x0004 +#define WPS_DEVICEPWDID_REG_SPEC 0x0005 +#define WPS_DEVICEPWDID_IBSS 0x0006 +#define WPS_DEVICEPWDID_NFC_CHO 0x0007 /* NFC-Connection-Handover */ +#define WPS_DEVICEPWDID_WFDS 0x0008 /* Wi-Fi Direct Services Specification */ + +/* Encryption type */ +#define WPS_ENCRTYPE_NONE 0x0001 +#define WPS_ENCRTYPE_WEP 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_ENCRTYPE_TKIP 0x0004 /* Deprecated in version 2.0. TKIP can only + * be advertised on the AP when Mixed Mode + * is enabled (Encryption Type is 0x000c). + */ +#define WPS_ENCRTYPE_AES 0x0008 + + +/* WPS Message Types */ +#define WPS_ID_BEACON 0x01 +#define WPS_ID_PROBE_REQ 0x02 +#define WPS_ID_PROBE_RESP 0x03 +#define WPS_ID_MESSAGE_M1 0x04 +#define WPS_ID_MESSAGE_M2 0x05 +#define WPS_ID_MESSAGE_M2D 0x06 +#define WPS_ID_MESSAGE_M3 0x07 +#define WPS_ID_MESSAGE_M4 0x08 +#define WPS_ID_MESSAGE_M5 0x09 +#define WPS_ID_MESSAGE_M6 0x0A +#define WPS_ID_MESSAGE_M7 0x0B +#define WPS_ID_MESSAGE_M8 0x0C +#define WPS_ID_MESSAGE_ACK 0x0D +#define WPS_ID_MESSAGE_NACK 0x0E +#define WPS_ID_MESSAGE_DONE 0x0F + +/* WSP private ID for local use */ +#define WPS_PRIVATE_ID_IDENTITY (WPS_ID_MESSAGE_DONE + 1) +#define WPS_PRIVATE_ID_WPS_START (WPS_ID_MESSAGE_DONE + 2) +#define WPS_PRIVATE_ID_FAILURE (WPS_ID_MESSAGE_DONE + 3) +#define WPS_PRIVATE_ID_FRAG (WPS_ID_MESSAGE_DONE + 4) +#define WPS_PRIVATE_ID_FRAG_ACK (WPS_ID_MESSAGE_DONE + 5) +#define WPS_PRIVATE_ID_EAPOL_START (WPS_ID_MESSAGE_DONE + 6) + + +/* Device Type categories for primary and secondary device types */ +#define WPS_DEVICE_TYPE_CAT_COMPUTER 1 +#define WPS_DEVICE_TYPE_CAT_INPUT_DEVICE 2 +#define WPS_DEVICE_TYPE_CAT_PRINTER 3 +#define WPS_DEVICE_TYPE_CAT_CAMERA 4 +#define WPS_DEVICE_TYPE_CAT_STORAGE 5 +#define WPS_DEVICE_TYPE_CAT_NW_INFRA 6 +#define WPS_DEVICE_TYPE_CAT_DISPLAYS 7 +#define WPS_DEVICE_TYPE_CAT_MM_DEVICES 8 +#define WPS_DEVICE_TYPE_CAT_GAME_DEVICES 9 +#define WPS_DEVICE_TYPE_CAT_TELEPHONE 10 +#define WPS_DEVICE_TYPE_CAT_AUDIO_DEVICES 11 /* WSC 2.0 */ + +/* Device Type sub categories for primary and secondary device types */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_PC 1 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_SERVER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_MEDIA_CTR 3 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_UM_PC 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_NOTEBOOK 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_DESKTOP 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_MID 7 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_NETBOOK 8 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_Keyboard 1 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_MOUSE 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_JOYSTICK 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_TRACKBALL 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_GAM_CTRL 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_REMOTE 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_TOUCHSCREEN 7 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_BIO_READER 8 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_BAR_READER 9 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_PRINTER 1 +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_SCANNER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_FAX 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_COPIER 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_ALLINONE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_DGTL_STILL 1 +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_VIDEO_CAM 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_WEB_CAM 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_SECU_CAM 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_STOR_NAS 1 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_AP 1 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_ROUTER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_SWITCH 3 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_GATEWAY 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_NW_BRIDGE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_TV 1 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_PIC_FRAME 2 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_PROJECTOR 3 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_MONITOR 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_DAR 1 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_PVR 2 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_MCX 3 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_STB 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_MS_ME 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_PVP 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_XBOX 1 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_XBOX_360 2 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_PS 3 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_GC 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_PGD 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_WM 1 +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_PSM 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_PDM 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_SSM 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_SDM 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_TUNER 1 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_SPEAKERS 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_PMP 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HEADSET 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HPHONE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_MPHONE 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HTS 7 /* WSC 2.0 */ + + +/* Device request/response type */ +#define WPS_MSGTYPE_ENROLLEE_INFO_ONLY 0x00 +#define WPS_MSGTYPE_ENROLLEE_OPEN_8021X 0x01 +#define WPS_MSGTYPE_REGISTRAR 0x02 +#define WPS_MSGTYPE_AP_WLAN_MGR 0x03 + +/* RF Band */ +#define WPS_RFBAND_24GHZ 0x01 +#define WPS_RFBAND_50GHZ 0x02 + +/* Simple Config state */ +#define WPS_SCSTATE_UNCONFIGURED 0x01 +#define WPS_SCSTATE_CONFIGURED 0x02 +#define WPS_SCSTATE_OFF 11 + +/* WPS Vendor extension key */ +#define WPS_OUI_HEADER_LEN 2 +#define WPS_OUI_HEADER_SIZE 4 +#define WPS_OUI_FIXED_HEADER_OFF 16 +#define WPS_WFA_SUBID_V2_OFF 3 +#define WPS_WFA_V2_OFF 5 + +#ifdef __cplusplus +} +#endif + +#endif /* _WPS_ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h index 597bc752c050dc19a6f4a945980e8377315b026c..1fbecedb6d1e206ffec23c49497c9269f77a723f 100644 --- a/drivers/net/wireless/bcmdhd/include/sbchipc.h +++ b/drivers/net/wireless/bcmdhd/include/sbchipc.h @@ -7,7 +7,25 @@ * * $Id: sbchipc.h 474281 2014-04-30 18:24:55Z $ * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. */ #ifndef _SBCHIPC_H diff --git a/drivers/net/wireless/bcmdhd/include/sbconfig.h b/drivers/net/wireless/bcmdhd/include/sbconfig.h index cc9223a1634b5b7101c0cc633e169fab00bf34b0..812e32557f9e32650b7f94b3aa9ef21c682377a3 100644 --- a/drivers/net/wireless/bcmdhd/include/sbconfig.h +++ b/drivers/net/wireless/bcmdhd/include/sbconfig.h @@ -1,7 +1,25 @@ /* * Broadcom SiliconBackplane hardware register definitions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbconfig.h 456346 2014-02-18 16:48:52Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/drivers/net/wireless/bcmdhd/include/sbhnddma.h index 3427a75d966542c489c67ebf173a3dd2edb2bad7..cbd9f0a2a1990d61121cbc30f994c4a3a109f791 100644 --- a/drivers/net/wireless/bcmdhd/include/sbhnddma.h +++ b/drivers/net/wireless/bcmdhd/include/sbhnddma.h @@ -2,7 +2,25 @@ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface * This supports the following chips: BCM42xx, 44xx, 47xx . * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbhnddma.h 452424 2014-01-30 09:43:39Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h index 91aa2fb1590a21d7f85aab569e5037da7dc65c29..f34fc18092a2de720e8d485733858a09cf2ccb82 100644 --- a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h +++ b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h @@ -1,7 +1,25 @@ /* * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbpcmcia.h 446298 2014-01-03 11:30:17Z $ */ @@ -84,263 +102,6 @@ #define SRI_BLANK 0x04 #define SRI_OTP 0x80 -#if !defined(LINUX_POSTMOGRIFY_REMOVAL) -/* CIS stuff */ - -/* The CIS stops where the FCRs start */ -#define CIS_SIZE PCMCIA_FCR -#define CIS_SIZE_12K 1154 /* Maximum h/w + s/w sub region size for 12k OTP */ - -/* CIS tuple length field max */ -#define CIS_TUPLE_LEN_MAX 0xff - -/* Standard tuples we know about */ - -#define CISTPL_NULL 0x00 -#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */ -#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ -#define CISTPL_FUNCID 0x21 /* Function identification */ -#define CISTPL_FUNCE 0x22 /* Function extensions */ -#define CISTPL_CFTABLE 0x1b /* Config table entry */ -#define CISTPL_END 0xff /* End of the CIS tuple chain */ - -/* Function identifier provides context for the function extentions tuple */ -#define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */ - -/* Function extensions for LANs (assumed for extensions other than SDIO) */ -#define LAN_TECH 1 /* Technology type */ -#define LAN_SPEED 2 /* Raw bit rate */ -#define LAN_MEDIA 3 /* Transmission media */ -#define LAN_NID 4 /* Node identification (aka MAC addr) */ -#define LAN_CONN 5 /* Connector standard */ - - -/* CFTable */ -#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ -#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ -#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ - -/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll - * take one for HNBU, and use "extensions" (a la FUNCE) within it. - */ - -#define CISTPL_BRCM_HNBU 0x80 - -/* Subtypes of BRCM_HNBU: */ - -#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ -#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */ -#define HNBU_BOARDREV 0x02 /* One byte board revision */ -#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1) - * or 9 (sromrev > 1) bytes - */ -#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ -#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ -#define HNBU_AA 0x06 /* Antennas available */ -#define HNBU_AG 0x07 /* Antenna gain */ -#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ -#define HNBU_LEDS 0x09 /* LED set */ -#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) - * in rev 2 - */ -#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ -#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ -#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */ -#define HNBU_PAPARMS5G 0x0e /* 5G PA params */ -#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */ -#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */ -#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */ -#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */ -#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */ -#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */ -#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */ -#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */ -#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */ -#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */ -#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */ -#define HNBU_LEDDC 0x1c /* 2 bytes; LED duty cycle */ -#define HNBU_HNBUCIS 0x1d /* what follows is proprietary HNBU CIS format */ -#define HNBU_PAPARMS_SSLPNPHY 0x1e /* SSLPNPHY PA params */ -#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f /* SSLPNPHY RSSI mid pt sel & board switch arch */ -#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */ -#define HNBU_CHAINSWITCH 0x21 /* 2 byte; txchain, rxchain */ -#define HNBU_REGREV 0x22 /* 1 byte; */ -#define HNBU_FEM 0x23 /* 2 or 4 byte: 11n frontend specification */ -#define HNBU_PAPARMS_C0 0x24 /* 8 or 30 bytes: 11n pa paramater for chain 0 */ -#define HNBU_PAPARMS_C1 0x25 /* 8 or 30 bytes: 11n pa paramater for chain 1 */ -#define HNBU_PAPARMS_C2 0x26 /* 8 or 30 bytes: 11n pa paramater for chain 2 */ -#define HNBU_PAPARMS_C3 0x27 /* 8 or 30 bytes: 11n pa paramater for chain 3 */ -#define HNBU_PO_CCKOFDM 0x28 /* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */ -#define HNBU_PO_MCS2G 0x29 /* 8 bytes: mcs2g power offset */ -#define HNBU_PO_MCS5GM 0x2a /* 8 bytes: mcs5g mid band power offset */ -#define HNBU_PO_MCS5GLH 0x2b /* 16 bytes: mcs5g low-high band power offset */ -#define HNBU_PO_CDD 0x2c /* 2 bytes: cdd2g/5g power offset */ -#define HNBU_PO_STBC 0x2d /* 2 bytes: stbc2g/5g power offset */ -#define HNBU_PO_40M 0x2e /* 2 bytes: 40Mhz channel 2g/5g power offset */ -#define HNBU_PO_40MDUP 0x2f /* 2 bytes: 40Mhz channel dup 2g/5g power offset */ - -#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */ -#define HNBU_WPS 0x31 /* 1 byte; GPIO pin for WPS button */ -#define HNBU_USBFS 0x32 /* 1 byte; 1 = USB advertises FS mode only */ -#define HNBU_BRMIN 0x33 /* 4 byte bootloader min resource mask */ -#define HNBU_BRMAX 0x34 /* 4 byte bootloader max resource mask */ -#define HNBU_PATCH 0x35 /* bootloader patch addr(2b) & data(4b) pair */ -#define HNBU_CCKFILTTYPE 0x36 /* CCK digital filter selection options */ -#define HNBU_OFDMPO5G 0x37 /* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */ -#define HNBU_ELNA2G 0x38 -#define HNBU_ELNA5G 0x39 -#define HNBU_TEMPTHRESH 0x3A /* 2 bytes - * byte1 tempthresh - * byte2 period(msb 4 bits) | hysterisis(lsb 4 bits) - */ -#define HNBU_UUID 0x3B /* 16 Bytes Hex */ - -#define HNBU_USBEPNUM 0x40 /* USB endpoint numbers */ - -/* POWER PER RATE for SROM V9 */ -#define HNBU_CCKBW202GPO 0x41 /* 2 bytes each - * CCK Power offsets for 20 MHz rates (11, 5.5, 2, 1Mbps) - * cckbw202gpo cckbw20ul2gpo - */ - -#define HNBU_LEGOFDMBW202GPO 0x42 /* 4 bytes each - * OFDM power offsets for 20 MHz Legacy rates - * (54, 48, 36, 24, 18, 12, 9, 6 Mbps) - * legofdmbw202gpo legofdmbw20ul2gpo - */ - -#define HNBU_LEGOFDMBW205GPO 0x43 /* 4 bytes each - * 5G band: OFDM power offsets for 20 MHz Legacy rates - * (54, 48, 36, 24, 18, 12, 9, 6 Mbps) - * low subband : legofdmbw205glpo legofdmbw20ul2glpo - * mid subband :legofdmbw205gmpo legofdmbw20ul2gmpo - * high subband :legofdmbw205ghpo legofdmbw20ul2ghpo - */ - -#define HNBU_MCS2GPO 0x44 /* 4 bytes each - * mcs 0-7 power-offset. LSB nibble: m0, MSB nibble: m7 - * mcsbw202gpo mcsbw20ul2gpo mcsbw402gpo - */ -#define HNBU_MCS5GLPO 0x45 /* 4 bytes each - * 5G low subband mcs 0-7 power-offset. - * LSB nibble: m0, MSB nibble: m7 - * mcsbw205glpo mcsbw20ul5glpo mcsbw405glpo - */ -#define HNBU_MCS5GMPO 0x46 /* 4 bytes each - * 5G mid subband mcs 0-7 power-offset. - * LSB nibble: m0, MSB nibble: m7 - * mcsbw205gmpo mcsbw20ul5gmpo mcsbw405gmpo - */ -#define HNBU_MCS5GHPO 0x47 /* 4 bytes each - * 5G high subband mcs 0-7 power-offset. - * LSB nibble: m0, MSB nibble: m7 - * mcsbw205ghpo mcsbw20ul5ghpo mcsbw405ghpo - */ -#define HNBU_MCS32PO 0x48 /* 2 bytes total - * mcs-32 power offset for each band/subband. - * LSB nibble: 2G band, MSB nibble: - * mcs322ghpo, mcs325gmpo, mcs325glpo, mcs322gpo - */ -#define HNBU_LEG40DUPPO 0x49 /* 2 bytes total - * Additional power offset for Legacy Dup40 transmissions. - * Applied in addition to legofdmbw20ulXpo, X=2g, 5gl, 5gm, or 5gh. - * LSB nibble: 2G band, MSB nibble: 5G band high subband. - * leg40dup5ghpo, leg40dup5gmpo, leg40dup5glpo, leg40dup2gpo - */ - -#define HNBU_PMUREGS 0x4a /* Variable length (5 bytes for each register) - * The setting of the ChipCtrl, PLL, RegulatorCtrl, Up/Down Timer and - * ResourceDependency Table registers. - */ - -#define HNBU_PATCH2 0x4b /* bootloader TCAM patch addr(4b) & data(4b) pair . - * This is required for socram rev 15 onwards. - */ - -#define HNBU_USBRDY 0x4c /* Variable length (upto 5 bytes) - * This is to indicate the USB/HSIC host controller - * that the device is ready for enumeration. - */ - -#define HNBU_USBREGS 0x4d /* Variable length - * The setting of the devcontrol, HSICPhyCtrl1 and HSICPhyCtrl2 - * registers during the USB initialization. - */ - -#define HNBU_BLDR_TIMEOUT 0x4e /* 2 bytes used for HSIC bootloader to reset chip - * on connect timeout. - * The Delay after USBConnect for timeout till dongle receives - * get_descriptor request. - */ -#define HNBU_USBFLAGS 0x4f -#define HNBU_PATCH_AUTOINC 0x50 -#define HNBU_MDIO_REGLIST 0x51 -#define HNBU_MDIOEX_REGLIST 0x52 -/* Unified OTP: tupple to embed USB manfid inside SDIO CIS */ -#define HNBU_UMANFID 0x53 -#define HNBU_PUBKEY 0x54 /* 128 byte; publick key to validate downloaded FW */ -#define HNBU_WOWLGPIO 0x55 /* 1 byte bit 7 initial polarity, bit 6..0 gpio pin */ -#define HNBU_MUXENAB 0x56 /* 1 byte to enable mux options */ -#define HNBU_GCI_CCR 0x57 /* GCI Chip control register */ - -#define HNBU_FEM_CFG 0x58 /* FEM config */ -#define HNBU_ACPA_C0 0x59 /* ACPHY PA parameters: chain 0 */ -#define HNBU_ACPA_C1 0x5a /* ACPHY PA parameters: chain 1 */ -#define HNBU_ACPA_C2 0x5b /* ACPHY PA parameters: chain 2 */ -#define HNBU_MEAS_PWR 0x5c -#define HNBU_PDOFF 0x5d -#define HNBU_ACPPR_2GPO 0x5e /* ACPHY Power-per-rate 2gpo */ -#define HNBU_ACPPR_5GPO 0x5f /* ACPHY Power-per-rate 5gpo */ -#define HNBU_ACPPR_SBPO 0x60 /* ACPHY Power-per-rate sbpo */ -#define HNBU_NOISELVL 0x61 -#define HNBU_RXGAIN_ERR 0x62 -#define HNBU_AGBGA 0x63 -#define HNBU_USBDESC_COMPOSITE 0x64 /* USB WLAN/BT composite descriptor */ -#define HNBU_PATCH_AUTOINC8 0x65 /* Auto increment patch entry for 8 byte patching */ -#define HNBU_PATCH8 0x66 /* Patch entry for 8 byte patching */ -#define HNBU_ACRXGAINS_C0 0x67 /* ACPHY rxgains: chain 0 */ -#define HNBU_ACRXGAINS_C1 0x68 /* ACPHY rxgains: chain 1 */ -#define HNBU_ACRXGAINS_C2 0x69 /* ACPHY rxgains: chain 2 */ -#define HNBU_TXDUTY 0x6a /* Tx duty cycle for ACPHY 5g 40/80 Mhz */ -#define HNBU_USBUTMI_CTL 0x6b /* 2 byte USB UTMI/LDO Control */ -#define HNBU_PDOFF_2G 0x6c -#define HNBU_USBSSPHY_UTMI_CTL0 0x6d /* 4 byte USB SSPHY UTMI Control */ -#define HNBU_USBSSPHY_UTMI_CTL1 0x6e /* 4 byte USB SSPHY UTMI Control */ -#define HNBU_USBSSPHY_UTMI_CTL2 0x6f /* 4 byte USB SSPHY UTMI Control */ -#define HNBU_USBSSPHY_SLEEP0 0x70 /* 2 byte USB SSPHY sleep */ -#define HNBU_USBSSPHY_SLEEP1 0x71 /* 2 byte USB SSPHY sleep */ -#define HNBU_USBSSPHY_SLEEP2 0x72 /* 2 byte USB SSPHY sleep */ -#define HNBU_USBSSPHY_SLEEP3 0x73 /* 2 byte USB SSPHY sleep */ -#define HNBU_USBSSPHY_MDIO 0x74 /* USB SSPHY INIT regs setting */ -#define HNBU_USB30PHY_NOSS 0x75 /* USB30 NO Super Speed */ -#define HNBU_USB30PHY_U1U2 0x76 /* USB30 PHY U1U2 Enable */ -#define HNBU_USB30PHY_REGS 0x77 /* USB30 PHY REGs update */ - -#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8 - * plus extra info appended. - */ -#define HNBU_RESERVED 0x81 /* Reserved for non-BRCM post-mfg additions */ -#define HNBU_CUSTOM1 0x82 /* 4 byte; For non-BRCM post-mfg additions */ -#define HNBU_CUSTOM2 0x83 /* Reserved; For non-BRCM post-mfg additions */ -#define HNBU_ACPAPARAM 0x84 /* ACPHY PAPARAM */ -#define HNBU_ACPA_CCK 0x86 /* ACPHY PA trimming parameters: CCK */ -#define HNBU_ACPA_40 0x87 /* ACPHY PA trimming parameters: 40 */ -#define HNBU_ACPA_80 0x88 /* ACPHY PA trimming parameters: 80 */ -#define HNBU_ACPA_4080 0x89 /* ACPHY PA trimming parameters: 40/80 */ -#define HNBU_SUBBAND5GVER 0x8a /* subband5gver */ -#define HNBU_PAPARAMBWVER 0x8b /* paparambwver */ - -#define HNBU_MCS5Gx1PO 0x8c -#define HNBU_ACPPR_SB8080_PO 0x8d - - -#endif /* !defined(LINUX_POSTMOGRIFY_REMOVAL) */ /* sbtmstatelow */ #define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ diff --git a/drivers/net/wireless/bcmdhd/include/sbsdio.h b/drivers/net/wireless/bcmdhd/include/sbsdio.h index 1395c32ae28e00e1314de80c27105465578f9b45..0196257699eb99d0d709a8d3b0b3035a42a55e9a 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsdio.h +++ b/drivers/net/wireless/bcmdhd/include/sbsdio.h @@ -4,7 +4,25 @@ * * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. * - * $Copyright Open 2003 Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbsdio.h 383835 2013-02-07 23:32:39Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h index dbbd2f6b784cc31ab05c6b46add3cf243f74c5b0..97051ce296f54890897b7dd690e6d5cff6dda8d3 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h +++ b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h @@ -2,7 +2,25 @@ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific * device core support * - * $Copyright Open 2005 Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbsdpcmdev.h 416730 2013-08-06 09:33:19Z $ */ @@ -272,10 +290,6 @@ typedef volatile struct { /* HW frame tag */ #define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ -#if !defined(NDISVER) || (NDISVER < 0x0630) #define SDPCM_HWEXT_LEN 8 -#else -#define SDPCM_HWEXT_LEN 0 -#endif /* !defined(NDISVER) || (NDISVER < 0x0630) */ #endif /* _sbsdpcmdev_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbsocram.h b/drivers/net/wireless/bcmdhd/include/sbsocram.h index 97e1a32ed76dd5243acd2fa415cc0708f6fc771b..33442f8789189d74ed3c17e6ea28784fa5db0a47 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsocram.h +++ b/drivers/net/wireless/bcmdhd/include/sbsocram.h @@ -1,9 +1,27 @@ /* * BCM47XX Sonics SiliconBackplane embedded ram core * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbsocram.h 481602 2014-05-29 22:43:34Z $ + * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $ */ #ifndef _SBSOCRAM_H diff --git a/drivers/net/wireless/bcmdhd/include/sdio.h b/drivers/net/wireless/bcmdhd/include/sdio.h index b8586b99cd88b20ea620e838ebb1d728375566fb..6b8d437b44d35d09d39acf77a0a1c37f3b068042 100644 --- a/drivers/net/wireless/bcmdhd/include/sdio.h +++ b/drivers/net/wireless/bcmdhd/include/sdio.h @@ -2,7 +2,25 @@ * SDIO spec header file * Protocol and standard (common) device definitions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sdio.h 416730 2013-08-06 09:33:19Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/sdioh.h b/drivers/net/wireless/bcmdhd/include/sdioh.h index fdb43f24d7ca6db323087ee16b2f99dbe42821cd..f2bd9ae69e36174db585ee653bf7e80ce1ced18f 100644 --- a/drivers/net/wireless/bcmdhd/include/sdioh.h +++ b/drivers/net/wireless/bcmdhd/include/sdioh.h @@ -2,7 +2,25 @@ * SDIO Host Controller Spec header file * Register map and definitions for the Standard Host Controller * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sdioh.h 345499 2012-07-18 06:59:05Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/sdiovar.h b/drivers/net/wireless/bcmdhd/include/sdiovar.h index 2795647a61666151c18cb2cd314b94fe77813b1e..5335ea18a6433135f31e7cf3e81b5bfa2bd15bcc 100644 --- a/drivers/net/wireless/bcmdhd/include/sdiovar.h +++ b/drivers/net/wireless/bcmdhd/include/sdiovar.h @@ -2,7 +2,25 @@ * Structure used by apps whose drivers access SDIO drivers. * Pulled out separately so dhdu and wlu can both use it. * - * $ Copyright Open Broadcom Corporation $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sdiovar.h 241182 2011-02-17 21:50:03Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/siutils.h b/drivers/net/wireless/bcmdhd/include/siutils.h index 6dbd5b0927cd6d25a06752627eb4530d55f10483..bf51f8ffe38080ba2bb955cf60d3532c9a7f7636 100644 --- a/drivers/net/wireless/bcmdhd/include/siutils.h +++ b/drivers/net/wireless/bcmdhd/include/siutils.h @@ -2,9 +2,27 @@ * Misc utility routines for accessing the SOC Interconnects * of Broadcom HNBU chips. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: siutils.h 481602 2014-05-29 22:43:34Z $ + * $Id: siutils.h 474902 2014-05-02 18:31:33Z $ */ #ifndef _siutils_h_ @@ -212,7 +230,6 @@ extern bool si_deviceremoved(si_t *sih); extern uint32 si_socram_size(si_t *sih); extern uint32 si_socdevram_size(si_t *sih); extern uint32 si_socram_srmem_size(si_t *sih); -extern void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda); extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect, uint8 *remap); extern bool si_socdevram_pkg(si_t *sih); extern bool si_socdevram_remap_isenb(si_t *sih); diff --git a/drivers/net/wireless/bcmdhd/include/spid.h b/drivers/net/wireless/bcmdhd/include/spid.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc51910d819e2f630a44572cda4d9f4f849f260 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/spid.h @@ -0,0 +1,165 @@ +/* + * SPI device spec header file + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: spid.h 358377 2012-09-23 11:30:22Z $ + */ + +#ifndef _SPI_H +#define _SPI_H + +/* + * Brcm SPI Device Register Map. + * + */ + +typedef volatile struct { + uint8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */ + uint8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */ + uint8 status_enable; /* 0x02, status-enable, intr with status, response_delay + * function selection, command/data error check + */ + uint8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */ + uint16 intr_reg; /* 0x04, Intr status register */ + uint16 intr_en_reg; /* 0x06, Intr mask register */ + uint32 status_reg; /* 0x08, RO, Status bits of last spi transfer */ + uint16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */ + uint16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */ + uint16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */ + uint32 test_read; /* 0x14, RO 0xfeedbead signature */ + uint32 test_rw; /* 0x18, RW */ + uint8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */ + uint8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */ + uint8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */ + uint8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */ +} spi_regs_t; + +/* SPI device register offsets */ +#define SPID_CONFIG 0x00 +#define SPID_RESPONSE_DELAY 0x01 +#define SPID_STATUS_ENABLE 0x02 +#define SPID_RESET_BP 0x03 /* (corerev >= 1) */ +#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */ +#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */ +#define SPID_STATUS_REG 0x08 /* 32 bits */ +#define SPID_F1_INFO_REG 0x0C /* 16 bits */ +#define SPID_F2_INFO_REG 0x0E /* 16 bits */ +#define SPID_F3_INFO_REG 0x10 /* 16 bits */ +#define SPID_TEST_READ 0x14 /* 32 bits */ +#define SPID_TEST_RW 0x18 /* 32 bits */ +#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */ + +/* Bit masks for SPID_CONFIG device register */ +#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */ +#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */ +#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */ +#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */ +#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */ +#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */ +#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */ + +/* Bit mask for SPID_RESPONSE_DELAY device register */ +#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */ + +/* Bit mask for SPID_STATUS_ENABLE device register */ +#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */ +#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */ +#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */ +#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */ +#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */ +#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */ + +/* Bit mask for SPID_RESET_BP device register */ +#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */ +#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */ +#define RESET_SPI 0x80 /* reset the above enabled logic */ + +/* Bit mask for SPID_INTR_REG device register */ +#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */ +#define F2_F3_FIFO_RD_UNDERFLOW 0x0002 +#define F2_F3_FIFO_WR_OVERFLOW 0x0004 +#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */ +#define DATA_ERROR 0x0010 /* Cleared by writing 1 */ +#define F2_PACKET_AVAILABLE 0x0020 +#define F3_PACKET_AVAILABLE 0x0040 +#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */ +#define MISC_INTR0 0x0100 +#define MISC_INTR1 0x0200 +#define MISC_INTR2 0x0400 +#define MISC_INTR3 0x0800 +#define MISC_INTR4 0x1000 +#define F1_INTR 0x2000 +#define F2_INTR 0x4000 +#define F3_INTR 0x8000 + +/* Bit mask for 32bit SPID_STATUS_REG device register */ +#define STATUS_DATA_NOT_AVAILABLE 0x00000001 +#define STATUS_UNDERFLOW 0x00000002 +#define STATUS_OVERFLOW 0x00000004 +#define STATUS_F2_INTR 0x00000008 +#define STATUS_F3_INTR 0x00000010 +#define STATUS_F2_RX_READY 0x00000020 +#define STATUS_F3_RX_READY 0x00000040 +#define STATUS_HOST_CMD_DATA_ERR 0x00000080 +#define STATUS_F2_PKT_AVAILABLE 0x00000100 +#define STATUS_F2_PKT_LEN_MASK 0x000FFE00 +#define STATUS_F2_PKT_LEN_SHIFT 9 +#define STATUS_F3_PKT_AVAILABLE 0x00100000 +#define STATUS_F3_PKT_LEN_MASK 0xFFE00000 +#define STATUS_F3_PKT_LEN_SHIFT 21 + +/* Bit mask for 16 bits SPID_F1_INFO_REG device register */ +#define F1_ENABLED 0x0001 +#define F1_RDY_FOR_DATA_TRANSFER 0x0002 +#define F1_MAX_PKT_SIZE 0x01FC + +/* Bit mask for 16 bits SPID_F2_INFO_REG device register */ +#define F2_ENABLED 0x0001 +#define F2_RDY_FOR_DATA_TRANSFER 0x0002 +#define F2_MAX_PKT_SIZE 0x3FFC + +/* Bit mask for 16 bits SPID_F3_INFO_REG device register */ +#define F3_ENABLED 0x0001 +#define F3_RDY_FOR_DATA_TRANSFER 0x0002 +#define F3_MAX_PKT_SIZE 0x3FFC + +/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */ +#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD + +/* Maximum number of I/O funcs */ +#define SPI_MAX_IOFUNCS 4 + +#define SPI_MAX_PKT_LEN (2048*4) + +/* Misc defines */ +#define SPI_FUNC_0 0 +#define SPI_FUNC_1 1 +#define SPI_FUNC_2 2 +#define SPI_FUNC_3 3 + +#define WAIT_F2RXFIFORDY 100 +#define WAIT_F2RXFIFORDY_DELAY 20 + +#endif /* _SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/trxhdr.h b/drivers/net/wireless/bcmdhd/include/trxhdr.h index 249527cd3420a5e1b8afd543b5caa18eebe0c382..6e55b151815ec1f1d793ea2918c91886308ddfed 100644 --- a/drivers/net/wireless/bcmdhd/include/trxhdr.h +++ b/drivers/net/wireless/bcmdhd/include/trxhdr.h @@ -1,7 +1,25 @@ /* * TRX image file header format. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: trxhdr.h 349211 2012-08-07 09:45:24Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/typedefs.h b/drivers/net/wireless/bcmdhd/include/typedefs.h index 08daa7e9103af698a2626b70ade0b08d21108214..ce593f376a05600f183b6bf4006586de8c869499 100644 --- a/drivers/net/wireless/bcmdhd/include/typedefs.h +++ b/drivers/net/wireless/bcmdhd/include/typedefs.h @@ -1,6 +1,24 @@ /* - * $Copyright Open Broadcom Corporation$ - * $Id: typedefs.h 484281 2014-06-12 22:42:26Z $ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * $Id: typedefs.h 473326 2014-04-29 00:37:35Z $ */ #ifndef _TYPEDEFS_H_ @@ -150,7 +168,7 @@ typedef long unsigned int size_t; #ifndef TYPEDEF_BOOL typedef /* @abstract@ */ unsigned char bool; -#endif /* endif TYPEDEF_BOOL */ +#endif /* define uchar, ushort, uint, ulong */ diff --git a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h index 3d54d8147846bef3daa4a9b6963b00cc04ce5ac1..937b86dc878250a15effd7eda982df9617fabb1d 100644 --- a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h +++ b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h @@ -1,5 +1,23 @@ /* -* $Copyright Open 2009 Broadcom Corporation$ +* Copyright (C) 1999-2014, Broadcom Corporation +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2 (the "GPL"), +* available at http://www.broadcom.com/licenses/GPLv2.php, with the +* following added to such license: +* +* As a special exception, the copyright holders of this software give you +* permission to link this software with independent modules, and to copy and +* distribute the resulting executable under terms of your choice, provided that +* you also meet, for each linked independent module, the terms and conditions of +* the license of that module. An independent module is a module which is not +* derived from this software. The special exception does not apply to any +* modifications of the software. +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a license +* other than the GPL, without Broadcom's express prior written consent. * $Id: wlfc_proto.h 455301 2014-02-13 12:42:13Z $ * */ @@ -109,6 +127,7 @@ #define WLFC_PKTFLAG_PKTFROMHOST 0x01 #define WLFC_PKTFLAG_PKT_REQUESTED 0x02 +#define WLFC_PKTFLAG_PKT_FORCELOWRATE 0x04 /* force low rate for this packet */ #define WL_TXSTATUS_STATUS_MASK 0xff /* allow 8 bits */ #define WL_TXSTATUS_STATUS_SHIFT 24 @@ -199,12 +218,6 @@ /* b[7:5] -reuse guard, b[4:0] -value */ #define WLFC_MAC_DESC_GET_LOOKUP_INDEX(x) ((x) & 0x1f) -#define WLFC_PKTFLAG_SET_PKTREQUESTED(x) (x) |= \ - (WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) - -#define WLFC_PKTFLAG_CLR_PKTREQUESTED(x) (x) &= \ - ~(WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) - #define WLFC_MAX_PENDING_DATALEN 120 diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h index 5835c34358ad2fa4e6f7f954d3b2b673f8257f15..cdf89ae83e70ec275c87f90a06a89cc5a2eac928 100644 --- a/drivers/net/wireless/bcmdhd/include/wlioctl.h +++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h @@ -4,7 +4,25 @@ * * Definitions subject to change without notice. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wlioctl.h 490639 2014-07-11 08:31:53Z $ */ @@ -24,20 +42,14 @@ #include <bcmwifi_rates.h> #include <devctrl_if/wlioctl_defs.h> -#if 0 && (NDISVER >= 0x0600) -#include <proto/bcmipv6.h> -#endif -#ifndef LINUX_POSTMOGRIFY_REMOVAL #include <bcm_mpool_pub.h> #include <bcmcdc.h> -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL #ifndef INTF_NAME_SIZ #define INTF_NAME_SIZ 16 @@ -75,11 +87,7 @@ typedef struct { bool assoc_approved; /* (re)association approved */ uint16 reject_reason; /* reason code for rejecting association */ struct ether_addr da; -#if 0 && (NDISVER >= 0x0620) - LARGE_INTEGER sys_time; /* current system time */ -#else int64 sys_time; /* current system time */ -#endif } assoc_decision_t; #define ACTION_FRAME_SIZE 1800 @@ -117,8 +125,6 @@ typedef struct wl_sa_query { struct ether_addr da; } wl_sa_query_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* require default structure packing */ #define BWL_DEFAULT_PACKING #include <packed_section_start.h> @@ -168,7 +174,6 @@ typedef BWL_PRE_PACKED_STRUCT struct { -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* Legacy structure to help keep backward compatible wl tool and tray app */ #define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ @@ -240,8 +245,6 @@ typedef struct wl_bss_info_108 { /* variable length Information Elements */ } wl_bss_info_108_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - #define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */ /* BSS info structure @@ -286,7 +289,15 @@ typedef struct wl_bss_info { /* variable length Information Elements */ } wl_bss_info_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL +#define WL_GSCAN_BSS_INFO_VERSION 1 /* current version of wl_gscan_bss_info struct */ +#define WL_GSCAN_INFO_FIXED_FIELD_SIZE (sizeof(wl_gscan_bss_info_t) - sizeof(wl_bss_info_t)) + +typedef struct wl_gscan_bss_info { + uint32 timestamp[2]; + wl_bss_info_t info; + /* variable length Information Elements */ +} wl_gscan_bss_info_t; + typedef struct wl_bsscfg { uint32 bsscfg_idx; @@ -367,14 +378,17 @@ struct wl_clm_dload_info { }; typedef struct wl_clm_dload_info wl_clm_dload_info_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - typedef struct wlc_ssid { uint32 SSID_len; uchar SSID[DOT11_MAX_SSID_LEN]; } wlc_ssid_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL +typedef struct wlc_ssid_ext { + bool hidden; + uint32 SSID_len; + uchar SSID[DOT11_MAX_SSID_LEN]; +} wlc_ssid_ext_t; + #define MAX_PREFERRED_AP_NUM 5 typedef struct wlc_fastssidinfo { @@ -469,7 +483,6 @@ typedef struct wl_iscan_params { /* 3 fields + size of wl_scan_params, not including variable length array */ #define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ typedef struct wl_scan_results { uint32 buflen; @@ -478,7 +491,6 @@ typedef struct wl_scan_results { wl_bss_info_t bss_info[1]; } wl_scan_results_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* size of wl_scan_results not including variable length array */ #define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) @@ -504,6 +516,14 @@ typedef struct wl_escan_result { #define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) +typedef struct wl_gscan_result { + uint32 buflen; + uint32 version; + wl_gscan_bss_info_t bss_info[1]; +} wl_gscan_result_t; + +#define WL_GSCAN_RESULTS_FIXED_SIZE (sizeof(wl_gscan_result_t) - sizeof(wl_gscan_bss_info_t)) + /* incremental scan results struct */ typedef struct wl_iscan_results { uint32 status; @@ -543,7 +563,6 @@ typedef struct wl_probe_params { struct ether_addr bssid; struct ether_addr mac; } wl_probe_params_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ typedef struct wl_rateset { @@ -628,7 +647,6 @@ typedef struct wl_join_params { */ } wl_join_params_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \ WL_ASSOC_PARAMS_FIXED_SIZE) /* scan params for extended join */ @@ -701,11 +719,9 @@ typedef struct { uint32 source; /* last detected interference source */ uint32 timestamp; /* second timestamp on interferenced flag change */ } interference_source_rep_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL typedef struct wl_country { char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in @@ -783,29 +799,6 @@ typedef struct wl_rm_rep { } wl_rm_rep_t; #define WL_RM_REP_FIXED_LEN 8 -#ifdef BCMCCX - -#define LEAP_USER_MAX 32 -#define LEAP_DOMAIN_MAX 32 -#define LEAP_PASSWORD_MAX 32 - -typedef struct wl_leap_info { - wlc_ssid_t ssid; - uint8 user_len; - uchar user[LEAP_USER_MAX]; - uint8 password_len; - uchar password[LEAP_PASSWORD_MAX]; - uint8 domain_len; - uchar domain[LEAP_DOMAIN_MAX]; -} wl_leap_info_t; - -typedef struct wl_leap_list { - uint32 buflen; - uint32 version; - uint32 count; - wl_leap_info_t leap_info[1]; -} wl_leap_list_t; -#endif /* BCMCCX */ typedef enum sup_auth_status { /* Basic supplicant authentication states */ @@ -830,7 +823,6 @@ typedef enum sup_auth_status { WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */ WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */ } sup_auth_status_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ typedef struct wl_wsec_key { uint32 index; /* key index */ @@ -887,7 +879,6 @@ typedef struct _pmkid_cand_list { #define WL_STA_ANT_MAX 4 /* max possible rx antennas */ -#ifndef LINUX_POSTMOGRIFY_REMOVAL typedef struct wl_assoc_info { uint32 req_len; uint32 resp_len; @@ -1047,8 +1038,6 @@ typedef struct { #define WL_STA_VER 4 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - #define WLC_NUMRATES 16 /* max # of rates in a rateset */ typedef struct wlc_rateset { @@ -1084,7 +1073,6 @@ typedef struct maclist { struct ether_addr ea[1]; /* variable length array of MAC addresses */ } maclist_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* get pkt count struct passed through ioctl */ typedef struct get_pktcnt { uint rx_good_pkt; @@ -1141,8 +1129,6 @@ typedef struct { uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ } wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* Linux network driver ioctl encoding */ typedef struct wl_ioctl { uint cmd; /* common ioctl definition */ @@ -1171,7 +1157,6 @@ typedef struct compat_wl_ioctl { #define WL_NUM_RATES_VHT 10 #define WL_NUM_RATES_MCS32 1 -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* * Structure for passing hardware and software @@ -1678,7 +1663,6 @@ typedef struct wl_txchain_pwr_offsets { struct tsinfo_arg { uint8 octets[3]; }; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define RATE_CCK_1MBPS 0 #define RATE_CCK_2MBPS 1 @@ -1982,7 +1966,6 @@ typedef struct { uint32 reinitreason[NREINITREASONCOUNT]; /* reinitreason counters; 0: Unknown reason */ } wl_cnt_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL typedef struct { uint16 version; /* see definition of WL_CNT_T_VERSION */ uint16 length; /* length of entire structure */ @@ -2264,7 +2247,6 @@ typedef struct { uint32 bphy_badplcp; } wl_delta_stats_t; -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ typedef struct { uint32 packets; @@ -2286,7 +2268,6 @@ typedef struct { } wl_wme_cnt_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL struct wl_msglevel2 { uint32 low; uint32 high; @@ -2559,6 +2540,10 @@ enum { #define PFN_PARTIAL_SCAN_BIT 0 #define PFN_PARTIAL_SCAN_MASK 1 +#define PFN_SWC_RSSI_WINDOW_MAX 8 +#define PFN_SWC_MAX_NUM_APS 16 +#define PFN_HOTLIST_MAX_NUM_APS 64 + /* PFN network info structure */ typedef struct wl_pfn_subnet_info { struct ether_addr BSSID; @@ -2597,6 +2582,20 @@ typedef struct wl_pfn_scanresults { wl_pfn_net_info_t netinfo[1]; } wl_pfn_scanresults_t; +typedef struct wl_pfn_significant_net { + uint16 flags; + uint16 channel; + struct ether_addr BSSID; + int8 rssi[PFN_SWC_RSSI_WINDOW_MAX]; +} wl_pfn_significant_net_t; + +typedef struct wl_pfn_swc_results { + uint32 version; + uint32 pkt_count; + uint32 total_count; + wl_pfn_significant_net_t list[1]; +} wl_pfn_swc_results_t; + /* used to report exactly one scan result */ /* plus reports detailed scan info in bss_info */ typedef struct wl_pfn_scanresult { @@ -2635,6 +2634,13 @@ typedef struct wl_pfn_bssid { /* Bit4: suppress_lost, Bit3: suppress_found */ uint16 flags; } wl_pfn_bssid_t; + +typedef struct wl_pfn_significant_bssid { + struct ether_addr macaddr; + int8 rssi_low_threshold; + int8 rssi_high_threshold; +} wl_pfn_significant_bssid_t; + #define WL_PFN_SUPPRESSFOUND_MASK 0x08 #define WL_PFN_SUPPRESSLOST_MASK 0x10 #define WL_PFN_RSSI_MASK 0xff00 @@ -2646,6 +2652,40 @@ typedef struct wl_pfn_cfg { uint16 channel_list[WL_NUMCHANNELS]; uint32 flags; } wl_pfn_cfg_t; + +#define CH_BUCKET_REPORT_REGULAR 0 +#define CH_BUCKET_REPORT_FULL_RESULT 2 + +typedef struct wl_pfn_gscan_channel_bucket { + uint16 bucket_end_index; + uint8 bucket_freq_multiple; + uint8 report_flag; +} wl_pfn_gscan_channel_bucket_t; + +#define GSCAN_SEND_ALL_RESULTS_MASK (1 << 0) +#define GSCAN_CFG_FLAGS_ONLY_MASK (1 << 7) + +typedef struct wl_pfn_gscan_cfg { + /* BIT0 1 = send probes/beacons to HOST + * BIT1 Reserved + * BIT2 Reserved + * Add any future flags here + * BIT7 1 = no other useful cfg sent + */ + uint8 flags; + /* Buffer filled threshold in % to generate an event */ + uint8 buffer_threshold; + /* No. of BSSIDs with "change" to generate an evt + * change - crosses rssi threshold/lost + */ + uint8 swc_nbssid_threshold; + /* Max=8 (for now) Size of rssi cache buffer */ + uint8 swc_rssi_window_size; + uint16 count_of_channel_buckets; + uint16 lost_ap_window; + wl_pfn_gscan_channel_bucket_t channel_bucket[1]; +} wl_pfn_gscan_cfg_t; + #define WL_PFN_REPORT_ALLNET 0 #define WL_PFN_REPORT_SSIDNET 1 #define WL_PFN_REPORT_BSSIDNET 2 @@ -2669,6 +2709,16 @@ typedef struct wl_pfn_list { wl_pfn_t pfn[1]; } wl_pfn_list_t; +#define WL_PFN_MAC_OUI_ONLY_MASK 1 +#define WL_PFN_SET_MAC_UNASSOC_MASK 2 +/* To configure pfn_macaddr */ +typedef struct wl_pfn_macaddr_cfg { + uint8 version; + uint8 flags; + struct ether_addr macaddr; +} wl_pfn_macaddr_cfg_t; +#define WL_PFN_MACADDR_CFG_VER 1 + typedef BWL_PRE_PACKED_STRUCT struct pfn_olmsg_params_t { wlc_ssid_t ssid; uint32 cipher_type; @@ -2687,8 +2737,6 @@ typedef BWL_PRE_PACKED_STRUCT struct pfn_olmsg_params_t { #define MSCAN_MAX 90 #endif -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* Service discovery */ typedef struct { uint8 transaction_id; /* Transaction id */ @@ -2832,7 +2880,6 @@ typedef struct { struct ether_addr bssid[1]; /* max ANQPO_MAX_IGNORE_BSSID */ } wl_anqpo_ignore_bssid_list_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL struct toe_ol_stats_t { /* Num of tx packets that don't need to be checksummed */ @@ -2963,7 +3010,6 @@ typedef struct wl_pkt_filter_pattern { uint32 offset; /* Offset within received packet to start pattern matching. * Offset '0' is the first byte of the ethernet header. */ - wl_pkt_decrypter_t* decrypt_ctx; /* Decrypt context */ }; uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts @@ -3405,8 +3451,6 @@ typedef struct { } wl_ioctl_overlay_t; #endif /* DONGLEOVERLAYS */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - /* 11k Neighbor Report element */ typedef struct nbr_element { uint8 id; @@ -3663,22 +3707,6 @@ BWL_PRE_PACKED_STRUCT struct hostip_id { uint8 id; } BWL_POST_PACKED_STRUCT; -#if 0 && (NDISVER >= 0x0600) -/* Return values */ -#define ND_REPLY_PEER 0x1 /* Reply was sent to service NS request from peer */ -#define ND_REQ_SINK 0x2 /* Input packet should be discarded */ -#define ND_FORCE_FORWARD 0X3 /* For the dongle to forward req to HOST */ - - -/* Neighbor Solicitation Response Offload IOVAR param */ -typedef BWL_PRE_PACKED_STRUCT struct nd_param { - struct ipv6_addr host_ip[2]; - struct ipv6_addr solicit_ip; - struct ipv6_addr remote_ip; - uint8 host_mac[ETHER_ADDR_LEN]; - uint32 offload_id; -} BWL_POST_PACKED_STRUCT nd_param_t; -#endif typedef BWL_PRE_PACKED_STRUCT struct wl_pfn_roam_thresh { uint32 pfn_alert_thresh; /* time in ms */ @@ -3777,7 +3805,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wl_pmalert_ucode_dbg { uint32 phydebug[20]; } BWL_POST_PACKED_STRUCT wl_pmalert_ucode_dbg_t; -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* Structures and constants used for "vndr_ie" IOVar interface */ #define VNDR_IE_CMD_LEN 4 /* length of the set command string: @@ -3893,7 +3920,6 @@ typedef BWL_PRE_PACKED_STRUCT struct { } BWL_POST_PACKED_STRUCT ibss_route_tbl_t; #define MAX_IBSS_ROUTE_TBL_ENTRY 64 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define TXPWR_TARGET_VERSION 0 typedef BWL_PRE_PACKED_STRUCT struct { @@ -3978,7 +4004,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wlc_ipfo_route_tbl { /* no strict structure packing */ #include <packed_section_end.h> -#ifndef LINUX_POSTMOGRIFY_REMOVAL /* Global ASSERT Logging */ #define ASSERTLOG_CUR_VER 0x0100 #define MAX_ASSRTSTR_LEN 64 @@ -3999,20 +4024,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wlc_ipfo_route_tbl { #define LOGRRC_FIX_LEN 8 #define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) -#ifdef BCMWAPI_WAI -#define IV_LEN 16 - struct wapi_sta_msg_t - { - uint16 msg_type; - uint16 datalen; - uint8 vap_mac[6]; - uint8 reserve_data1[2]; - uint8 sta_mac[6]; - uint8 reserve_data2[2]; - uint8 gsn[IV_LEN]; - uint8 wie[256]; - }; -#endif /* BCMWAPI_WAI */ /* chanim acs record */ typedef struct { @@ -5523,8 +5534,6 @@ typedef struct net_detect_wake_data { #endif /* NET_DETECT */ -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ - typedef struct bcnreq { uint8 bcn_mode; int dur; diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c index 8224ef5c89840f06f5a9fbbf089173b4799a005f..d39452b5e838f566e075a65378d3ca0236af2075 100644 --- a/drivers/net/wireless/bcmdhd/linux_osl.c +++ b/drivers/net/wireless/bcmdhd/linux_osl.c @@ -1,9 +1,27 @@ /* * Linux OS Independent Layer * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: linux_osl.c 490846 2014-07-12 13:08:59Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: linux_osl.c 474402 2014-05-01 03:50:41Z $ */ #define LINUX_PORT @@ -292,18 +310,18 @@ osl_attach(void *pdev, uint bustype, bool pkttag) int osl_static_mem_init(osl_t *osh, void *adapter) { -#ifdef CONFIG_DHD_USE_STATIC_BUF +#if defined(CONFIG_DHD_USE_STATIC_BUF) if (!bcm_static_buf && adapter) { if (!(bcm_static_buf = (bcm_static_buf_t *)wifi_platform_prealloc(adapter, 3, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) { - printf("can not alloc static buf!\n"); + printk("can not alloc static buf!\n"); bcm_static_skb = NULL; ASSERT(osh->magic == OS_HANDLE_MAGIC); kfree(osh); return -ENOMEM; } else - printf("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); + printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); sema_init(&bcm_static_buf->static_sem, 1); @@ -311,14 +329,13 @@ int osl_static_mem_init(osl_t *osh, void *adapter) bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; } -#ifdef BCMSDIO if (!bcm_static_skb && adapter) { int i; void *skb_buff_ptr = 0; bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); skb_buff_ptr = wifi_platform_prealloc(adapter, 4, 0); if (!skb_buff_ptr) { - printf("cannot alloc static buf!\n"); + printk("cannot alloc static buf!\n"); bcm_static_buf = NULL; bcm_static_skb = NULL; ASSERT(osh->magic == OS_HANDLE_MAGIC); @@ -333,7 +350,6 @@ int osl_static_mem_init(osl_t *osh, void *adapter) sema_init(&bcm_static_skb->osl_pkt_sem, 1); } -#endif /* BCMSDIO */ #endif /* CONFIG_DHD_USE_STATIC_BUF */ return 0; @@ -369,12 +385,10 @@ int osl_static_mem_deinit(osl_t *osh, void *adapter) if (bcm_static_buf) { bcm_static_buf = 0; } -#ifdef BCMSDIO if (bcm_static_skb) { bcm_static_skb = 0; } -#endif /* BCMSDIO */ -#endif /* CONFIG_DHD_USE_STATIC_BUF */ +#endif return 0; } @@ -386,6 +400,7 @@ static struct sk_buff *osl_alloc_skb(osl_t *osh, unsigned int len) #if defined(CONFIG_SPARSEMEM) && defined(CONFIG_ZONE_DMA) flags |= GFP_ATOMIC; #endif + skb = __dev_alloc_skb(len, flags); #else skb = dev_alloc_skb(len); @@ -538,11 +553,9 @@ osl_ctfpool_stats(osl_t *osh, void *b) if (bcm_static_buf) { bcm_static_buf = 0; } -#ifdef BCMSDIO if (bcm_static_skb) { bcm_static_skb = 0; } -#endif /* BCMSDIO */ #endif /* CONFIG_DHD_USE_STATIC_BUF */ bb = b; @@ -644,7 +657,7 @@ osl_pkt_frmfwder(osl_t *osh, void *skbs, int skb_cnt) #if defined(BCMDBG_CTRACE) int i; struct sk_buff *skb; -#endif +#endif #if defined(BCMDBG_CTRACE) if (skb_cnt > 1) { @@ -663,7 +676,7 @@ osl_pkt_frmfwder(osl_t *osh, void *skbs, int skb_cnt) ADD_CTRACE(osh, skb, file, line); #endif /* BCMDBG_CTRACE */ } -#endif +#endif atomic_add(skb_cnt, &osh->cmn->pktalloced); } @@ -873,7 +886,7 @@ osl_pktget_static(osl_t *osh, uint len) struct sk_buff *skb; if (len > DHD_SKB_MAX_BUFSIZE) { - printf("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); + printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); return osl_pktget(osh, len); } @@ -929,7 +942,7 @@ osl_pktget_static(osl_t *osh, uint len) #endif up(&bcm_static_skb->osl_pkt_sem); - printf("%s: all static pkt in use!\n", __FUNCTION__); + printk("%s: all static pkt in use!\n", __FUNCTION__); return osl_pktget(osh, len); } @@ -1107,7 +1120,7 @@ osl_malloc(osl_t *osh, uint size) if (i == STATIC_BUF_MAX_NUM) { up(&bcm_static_buf->static_sem); - printf("all static buff in use!\n"); + printk("all static buff in use!\n"); goto original; } @@ -1237,7 +1250,7 @@ osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced va = pci_alloc_consistent(osh->pdev, size, &pap_lin); *pap = (dmaaddr_t)pap_lin; } -#endif /* BCM47XX_CA9 && __ARM_ARCH_7A__ */ +#endif return va; } @@ -1374,7 +1387,7 @@ int osl_arch_is_coherent(void) return arch_is_coherent(); #endif } -#endif +#endif #if defined(BCMASSERT_LOG) void @@ -1394,12 +1407,12 @@ osl_assert(const char *exp, const char *file, int line) #ifdef BCMASSERT_LOG snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n", exp, basename, line); - printf("%s", tempbuf); + printk("%s", tempbuf); #endif /* BCMASSERT_LOG */ } -#endif +#endif void osl_delay(uint usec) @@ -1521,25 +1534,25 @@ void osl_ctrace_dump(osl_t *osh, struct bcmstrbuf *b) if (b != NULL) bcm_bprintf(b, " Total %d sbk not free\n", osh->ctrace_num); else - printf(" Total %d sbk not free\n", osh->ctrace_num); + printk(" Total %d sbk not free\n", osh->ctrace_num); list_for_each_entry(skb, &osh->ctrace_list, ctrace_list) { if (b != NULL) bcm_bprintf(b, "[%d] skb %p:\n", ++idx, skb); else - printf("[%d] skb %p:\n", ++idx, skb); + printk("[%d] skb %p:\n", ++idx, skb); for (i = 0; i < skb->ctrace_count; i++) { j = (skb->ctrace_start + i) % CTRACE_NUM; if (b != NULL) bcm_bprintf(b, " [%s(%d)]\n", skb->func[j], skb->line[j]); else - printf(" [%s(%d)]\n", skb->func[j], skb->line[j]); + printk(" [%s(%d)]\n", skb->func[j], skb->line[j]); } if (b != NULL) bcm_bprintf(b, "\n"); else - printf("\n"); + printk("\n"); } spin_unlock_irqrestore(&osh->ctrace_lock, flags); diff --git a/drivers/net/wireless/bcmdhd/pcie_core.c b/drivers/net/wireless/bcmdhd/pcie_core.c index 508eccb2bcce3d5f780143169dc27cf3cdba2087..1eaedf59327c13cb50bd5da1ba441294a99a4296 100644 --- a/drivers/net/wireless/bcmdhd/pcie_core.c +++ b/drivers/net/wireless/bcmdhd/pcie_core.c @@ -3,7 +3,25 @@ * Contains PCIe related functions that are shared between different driver models (e.g. firmware * builds, DHD builds, BMAC builds), in order to avoid code duplication. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: pcie_core.c 444841 2013-12-21 04:32:29Z $ */ @@ -36,20 +54,15 @@ void pcie_watchdog_reset(osl_t *osh, si_t *sih, sbpcieregs_t *sbpcieregs) PCIECFGREG_LINK_STATUS_CTRL2, PCIECFGREG_RBAR_CTRL, PCIECFGREG_PML1_SUB_CTRL1, PCIECFGREG_REG_BAR2_CONFIG, PCIECFGREG_REG_BAR3_CONFIG}; - sbpcieregs_t *pcie = NULL; uint32 origidx = si_coreidx(sih); - /* Switch to PCIE2 core */ - pcie = (sbpcieregs_t *)si_setcore(sih, PCIE2_CORE_ID, 0); - BCM_REFERENCE(pcie); - ASSERT(pcie != NULL); - /* Disable/restore ASPM Control to protect the watchdog reset */ W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL); lsc = R_REG(osh, &sbpcieregs->configdata); val = lsc & (~PCIE_ASPM_ENAB); W_REG(osh, &sbpcieregs->configdata, val); + si_setcore(sih, PCIE2_CORE_ID, 0); si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 4); OSL_DELAY(100000); diff --git a/drivers/net/wireless/bcmdhd/sbutils.c b/drivers/net/wireless/bcmdhd/sbutils.c index 4894d9aaccceb8b24fb28b2ad947fbd5f715e153..12c4559de111fed552ddf005a3aaffc12c90cb88 100644 --- a/drivers/net/wireless/bcmdhd/sbutils.c +++ b/drivers/net/wireless/bcmdhd/sbutils.c @@ -2,7 +2,25 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: sbutils.c 467150 2014-04-02 17:30:43Z $ */ diff --git a/drivers/net/wireless/bcmdhd/siutils.c b/drivers/net/wireless/bcmdhd/siutils.c index c01ab441f598c32ac5cc0c8d34ad4b0215db3759..01210254704091427ab2f58296cfcfed8a459d2d 100644 --- a/drivers/net/wireless/bcmdhd/siutils.c +++ b/drivers/net/wireless/bcmdhd/siutils.c @@ -2,9 +2,27 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: siutils.c 481602 2014-05-29 22:43:34Z $ + * $Id: siutils.c 474902 2014-05-02 18:31:33Z $ */ #include <bcm_cfg.h> @@ -1971,42 +1989,6 @@ socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type) return banksize; } -void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda) -{ - si_info_t *sii = SI_INFO(sih); - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; - uint origidx; - uint intr_val = 0; - sbsocramregs_t *regs; - bool wasup; - uint corerev; - - /* Block ints and save current core */ - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - /* Switch to SOCRAM core */ - if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) - goto done; - - if (!(wasup = si_iscoreup(sih))) - si_core_reset(sih, 0, 0); - - corerev = si_corerev(sih); - if (corerev >= 16) { - W_REG(sii->osh, ®s->bankidx, bankidx); - W_REG(sii->osh, ®s->bankpda, bankpda); - } - - /* Return to previous state and core */ - if (!wasup) - si_core_disable(sih, 0); - si_setcoreidx(sih, origidx); - -done: - INTR_RESTORE(sii, intr_val); -} - void si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap) { @@ -2414,10 +2396,6 @@ si_socram_srmem_size(si_t *sih) return (32 * 1024); } - if (CHIPID(sih->chip) == BCM43430_CHIP_ID) { - return (64 * 1024); - } - /* Block ints and save current core */ INTR_OFF(sii, intr_val); origidx = si_coreidx(sih); diff --git a/drivers/net/wireless/bcmdhd/siutils_priv.h b/drivers/net/wireless/bcmdhd/siutils_priv.h index a69fb69f5a6177efa40b62f2558c6b368d3d96d4..38c60a81a1ac32dc2f0d0167bb77f23a0f90af26 100644 --- a/drivers/net/wireless/bcmdhd/siutils_priv.h +++ b/drivers/net/wireless/bcmdhd/siutils_priv.h @@ -1,7 +1,25 @@ /* * Include file private to the SOC Interconnect support files. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: siutils_priv.h 474902 2014-05-02 18:31:33Z $ */ diff --git a/drivers/net/wireless/bcmdhd/uamp_api.h b/drivers/net/wireless/bcmdhd/uamp_api.h index e4f7e35a490c7eeb1a78d56c014427d6e5b03abd..2bd06292e2e791bd3800b9bfa7f9be4c08602627 100644 --- a/drivers/net/wireless/bcmdhd/uamp_api.h +++ b/drivers/net/wireless/bcmdhd/uamp_api.h @@ -3,7 +3,25 @@ * * Description: Universal AMP API * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: uamp_api.h 467328 2014-04-03 01:23:40Z $ * diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c index 336569c88959d4e958f5a35d5044d0b6efe3c5f8..36ab67bc88664d6605a60e44afc6861588b64ab3 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.c +++ b/drivers/net/wireless/bcmdhd/wl_android.c @@ -1,9 +1,27 @@ /* * Linux cfg80211 driver - Android related functions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_android.c 490852 2014-07-12 15:20:53Z $ + * $Id: wl_android.c 470703 2014-04-16 02:25:28Z $ */ #include <linux/module.h> @@ -31,9 +49,6 @@ #ifdef WL_CFG80211 #include <wl_cfg80211.h> #endif -#ifdef WL_NAN -#include <wl_cfgnan.h> -#endif /* WL_NAN */ /* * Android private command strings, PLEASE define new private commands here @@ -70,7 +85,6 @@ #define CMD_SETROAMMODE "SETROAMMODE" #define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA" #define CMD_MIRACAST "MIRACAST" -#define CMD_NAN "NAN_" #if defined(WL_SUPPORT_AUTO_CHANNEL) #define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS" @@ -79,11 +93,6 @@ #define CMD_KEEP_ALIVE "KEEPALIVE" /* CCX Private Commands */ -#ifdef BCMCCX -#define CMD_GETCCKM_RN "get cckm_rn" -#define CMD_SETCCKM_KRK "set cckm_krk" -#define CMD_GET_ASSOC_RES_IES "get assoc_res_ies" -#endif #ifdef PNO_SUPPORT #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" @@ -98,18 +107,7 @@ #define CMD_HAPD_MAC_FILTER "HAPD_MAC_FILTER" -#ifdef WLFBT -#define CMD_GET_FTKEY "GET_FTKEY" -#endif -#ifdef WLAIBSS -#define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT" -#define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO" -#define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL" -#define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE" -#define CMD_SETIBSSAMPDU "SETIBSSAMPDU" -#define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE" -#endif /* WLAIBSS */ #define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD" @@ -170,63 +168,6 @@ typedef struct _compat_android_wifi_priv_cmd { (JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES)) #endif /* BCMFW_ROAM_ENABLE */ -#ifdef WL_GENL -static s32 wl_genl_handle_msg(struct sk_buff *skb, struct genl_info *info); -static int wl_genl_init(void); -static int wl_genl_deinit(void); - -extern struct net init_net; -/* attribute policy: defines which attribute has which type (e.g int, char * etc) - * possible values defined in net/netlink.h - */ -static struct nla_policy wl_genl_policy[BCM_GENL_ATTR_MAX + 1] = { - [BCM_GENL_ATTR_STRING] = { .type = NLA_NUL_STRING }, - [BCM_GENL_ATTR_MSG] = { .type = NLA_BINARY }, -}; - -#define WL_GENL_VER 1 -/* family definition */ -static struct genl_family wl_genl_family = { - .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */ - .hdrsize = 0, - .name = "bcm-genl", /* Netlink I/F for Android */ - .version = WL_GENL_VER, /* Version Number */ - .maxattr = BCM_GENL_ATTR_MAX, -}; - -/* commands: mapping between the command enumeration and the actual function */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) -struct genl_ops wl_genl_ops[] = { - { - .cmd = BCM_GENL_CMD_MSG, - .flags = 0, - .policy = wl_genl_policy, - .doit = wl_genl_handle_msg, - .dumpit = NULL, - }, -}; -#else -struct genl_ops wl_genl_ops = { - .cmd = BCM_GENL_CMD_MSG, - .flags = 0, - .policy = wl_genl_policy, - .doit = wl_genl_handle_msg, - .dumpit = NULL, - -}; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) -static struct genl_multicast_group wl_genl_mcast[] = { - { .name = "bcm-genl-mcast", }, -}; -#else -static struct genl_multicast_group wl_genl_mcast = { - .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */ - .name = "bcm-genl-mcast", -}; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */ -#endif /* WL_GENL */ /** * Extern function declarations (TODO: move them to dhd_linux.h) @@ -485,7 +426,7 @@ exit: #ifndef WL_SCHED_SCAN static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) { - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; + wlc_ssid_ext_t ssids_local[MAX_PFN_LIST_COUNT]; int res = -1; int nssid = 0; cmd_tlv_t *cmd_tlv_temp; @@ -597,89 +538,6 @@ static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, i return bytes_written; } -#ifdef BCMCCX -static int wl_android_get_cckm_rn(struct net_device *dev, char *command) -{ - int error, rn; - - WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev->name)); - - error = wldev_iovar_getint(dev, "cckm_rn", &rn); - if (unlikely(error)) { - WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error)); - return -1; - } - memcpy(command, &rn, sizeof(int)); - - return sizeof(int); -} - -static int wl_android_set_cckm_krk(struct net_device *dev, char *command) -{ - int error; - unsigned char key[16]; - static char iovar_buf[WLC_IOCTL_MEDLEN]; - - WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev->name)); - - memset(iovar_buf, 0, sizeof(iovar_buf)); - memcpy(key, command+strlen("set cckm_krk")+1, 16); - - error = wldev_iovar_setbuf(dev, "cckm_krk", key, sizeof(key), - iovar_buf, WLC_IOCTL_MEDLEN, NULL); - if (unlikely(error)) - { - WL_ERR((" cckm_krk set error (%d)\n", error)); - return -1; - } - return 0; -} - -static int wl_android_get_assoc_res_ies(struct net_device *dev, char *command) -{ - int error; - u8 buf[WL_ASSOC_INFO_MAX]; - wl_assoc_info_t assoc_info; - u32 resp_ies_len = 0; - int bytes_written = 0; - - WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev->name)); - - error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL); - if (unlikely(error)) { - WL_ERR(("could not get assoc info (%d)\n", error)); - return -1; - } - - memcpy(&assoc_info, buf, sizeof(wl_assoc_info_t)); - assoc_info.req_len = htod32(assoc_info.req_len); - assoc_info.resp_len = htod32(assoc_info.resp_len); - assoc_info.flags = htod32(assoc_info.flags); - - if (assoc_info.resp_len) { - resp_ies_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp); - } - - /* first 4 bytes are ie len */ - memcpy(command, &resp_ies_len, sizeof(u32)); - bytes_written = sizeof(u32); - - /* get the association resp IE's if there are any */ - if (resp_ies_len) { - error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0, - buf, WL_ASSOC_INFO_MAX, NULL); - if (unlikely(error)) { - WL_ERR(("could not get assoc resp_ies (%d)\n", error)); - return -1; - } - - memcpy(command+sizeof(u32), buf, resp_ies_len); - bytes_written += resp_ies_len; - } - return bytes_written; -} - -#endif /* BCMCCX */ int wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist) @@ -827,34 +685,30 @@ int wl_android_wifi_on(struct net_device *dev) dhd_net_wifi_platform_set_power(dev, TRUE, WIFI_TURNON_DELAY); #ifdef BCMSDIO ret = dhd_net_bus_resume(dev, 0); -#endif /* BCMSDIO */ -#ifdef BCMPCIE - ret = dhd_net_bus_devreset(dev, FALSE); -#endif /* BCMPCIE */ +#endif if (ret == 0) break; DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n", - retry)); -#ifdef BCMPCIE - dhd_net_bus_devreset(dev, TRUE); -#endif /* BCMPCIE */ + retry+1)); dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY); - } while (retry-- > 0); + } while (retry-- >= 0); if (ret != 0) { DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n")); goto exit; } -#ifdef BCMSDIO +#if defined(BCMSDIO) || defined(BCMPCIE) ret = dhd_net_bus_devreset(dev, FALSE); +#ifdef BCMSDIO dhd_net_bus_resume(dev, 1); -#endif /* BCMSDIO */ - +#endif +#endif /* BCMSDIO || BCMPCIE */ #ifndef BCMPCIE if (!ret) { if (dhd_dev_init_ioctl(dev) < 0) ret = -EFAULT; } -#endif /* !BCMPCIE */ +#endif + if (!ret) g_wifi_on = TRUE; } @@ -880,7 +734,7 @@ int wl_android_wifi_off(struct net_device *dev) ret = dhd_net_bus_devreset(dev, TRUE); #ifdef BCMSDIO dhd_net_bus_suspend(dev); -#endif /* BCMSDIO */ +#endif #endif /* BCMSDIO || BCMPCIE */ dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY); g_wifi_on = FALSE; @@ -1360,386 +1214,6 @@ resume: return ret; } -#define NETLINK_OXYGEN 30 -#define AIBSS_BEACON_TIMEOUT 10 - -static struct sock *nl_sk = NULL; - -static void wl_netlink_recv(struct sk_buff *skb) -{ - WL_ERR(("netlink_recv called\n")); -} - -static int wl_netlink_init(void) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - struct netlink_kernel_cfg cfg = { - .input = wl_netlink_recv, - }; -#endif - - if (nl_sk != NULL) { - WL_ERR(("nl_sk already exist\n")); - return BCME_ERROR; - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) - nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, - 0, wl_netlink_recv, NULL, THIS_MODULE); -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) - nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, THIS_MODULE, &cfg); -#else - nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, &cfg); -#endif - - if (nl_sk == NULL) { - WL_ERR(("nl_sk is not ready\n")); - return BCME_ERROR; - } - - return BCME_OK; -} - -static void wl_netlink_deinit(void) -{ - if (nl_sk) { - netlink_kernel_release(nl_sk); - nl_sk = NULL; - } -} - -s32 -wl_netlink_send_msg(int pid, int type, int seq, void *data, size_t size) -{ - struct sk_buff *skb = NULL; - struct nlmsghdr *nlh = NULL; - int ret = -1; - - if (nl_sk == NULL) { - WL_ERR(("nl_sk was not initialized\n")); - goto nlmsg_failure; - } - - skb = alloc_skb(NLMSG_SPACE(size), GFP_ATOMIC); - if (skb == NULL) { - WL_ERR(("failed to allocate memory\n")); - goto nlmsg_failure; - } - - nlh = nlmsg_put(skb, 0, 0, 0, size, 0); - if (nlh == NULL) { - WL_ERR(("failed to build nlmsg, skb_tailroom:%d, nlmsg_total_size:%d\n", - skb_tailroom(skb), nlmsg_total_size(size))); - dev_kfree_skb(skb); - goto nlmsg_failure; - } - - memcpy(nlmsg_data(nlh), data, size); - nlh->nlmsg_seq = seq; - nlh->nlmsg_type = type; - - /* netlink_unicast() takes ownership of the skb and frees it itself. */ - ret = netlink_unicast(nl_sk, skb, pid, 0); - WL_DBG(("netlink_unicast() pid=%d, ret=%d\n", pid, ret)); - -nlmsg_failure: - return ret; -} - -#ifdef WLAIBSS -static int wl_android_set_ibss_txfail_event(struct net_device *dev, char *command, int total_len) -{ - int err = 0; - int retry = 0; - int pid = 0; - aibss_txfail_config_t txfail_config = {0, 0, 0, 0}; - char smbuf[WLC_IOCTL_SMLEN]; - - if (sscanf(command, CMD_SETIBSSTXFAILEVENT " %d %d", &retry, &pid) <= 0) { - WL_ERR(("Failed to get Parameter from : %s\n", command)); - return -1; - } - - /* set pid, and if the event was happened, let's send a notification through netlink */ - wl_cfg80211_set_txfail_pid(pid); - - /* If retry value is 0, it disables the functionality for TX Fail. */ - if (retry > 0) { - txfail_config.max_tx_retry = retry; - txfail_config.bcn_timeout = 0; /* 0 : disable tx fail from beacon */ - } - txfail_config.version = AIBSS_TXFAIL_CONFIG_VER_0; - txfail_config.len = sizeof(txfail_config); - - err = wldev_iovar_setbuf(dev, "aibss_txfail_config", (void *) &txfail_config, - sizeof(aibss_txfail_config_t), smbuf, WLC_IOCTL_SMLEN, NULL); - WL_DBG(("retry=%d, pid=%d, err=%d\n", retry, pid, err)); - - return ((err == 0)?total_len:err); -} - -static int wl_android_get_ibss_peer_info(struct net_device *dev, char *command, - int total_len, bool bAll) -{ - int error; - int bytes_written = 0; - void *buf = NULL; - bss_peer_list_info_t peer_list_info; - bss_peer_info_t *peer_info; - int i; - bool found = false; - struct ether_addr mac_ea; - - WL_DBG(("get ibss peer info(%s)\n", bAll?"true":"false")); - - if (!bAll) { - if (sscanf (command, "GETIBSSPEERINFO %02x:%02x:%02x:%02x:%02x:%02x", - (unsigned int *)&mac_ea.octet[0], (unsigned int *)&mac_ea.octet[1], - (unsigned int *)&mac_ea.octet[2], (unsigned int *)&mac_ea.octet[3], - (unsigned int *)&mac_ea.octet[4], (unsigned int *)&mac_ea.octet[5]) != 6) { - WL_DBG(("invalid MAC address\n")); - return -1; - } - } - - if ((buf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL)) == NULL) { - WL_ERR(("kmalloc failed\n")); - return -1; - } - - error = wldev_iovar_getbuf(dev, "bss_peer_info", NULL, 0, buf, WLC_IOCTL_MAXLEN, NULL); - if (unlikely(error)) { - WL_ERR(("could not get ibss peer info (%d)\n", error)); - kfree(buf); - return -1; - } - - memcpy(&peer_list_info, buf, sizeof(peer_list_info)); - peer_list_info.version = htod16(peer_list_info.version); - peer_list_info.bss_peer_info_len = htod16(peer_list_info.bss_peer_info_len); - peer_list_info.count = htod32(peer_list_info.count); - - WL_DBG(("ver:%d, len:%d, count:%d\n", peer_list_info.version, - peer_list_info.bss_peer_info_len, peer_list_info.count)); - - if (peer_list_info.count > 0) { - if (bAll) - bytes_written += sprintf(&command[bytes_written], "%u ", - peer_list_info.count); - - peer_info = (bss_peer_info_t *) ((void *)buf + BSS_PEER_LIST_INFO_FIXED_LEN); - - - for (i = 0; i < peer_list_info.count; i++) { - - WL_DBG(("index:%d rssi:%d, tx:%u, rx:%u\n", i, peer_info->rssi, - peer_info->tx_rate, peer_info->rx_rate)); - - if (!bAll && - memcmp(&mac_ea, &peer_info->ea, sizeof(struct ether_addr)) == 0) { - found = true; - } - - if (bAll || found) { - bytes_written += sprintf(&command[bytes_written], MACF, - ETHER_TO_MACF(peer_info->ea)); - bytes_written += sprintf(&command[bytes_written], " %u %d ", - peer_info->tx_rate/1000, peer_info->rssi); - } - - if (found) - break; - - peer_info = (bss_peer_info_t *)((void *)peer_info+sizeof(bss_peer_info_t)); - } - } - else { - WL_ERR(("could not get ibss peer info : no item\n")); - } - bytes_written += sprintf(&command[bytes_written], "%s", "\0"); - - WL_DBG(("command(%u):%s\n", total_len, command)); - WL_DBG(("bytes_written:%d\n", bytes_written)); - - kfree(buf); - return bytes_written; -} - -int wl_android_set_ibss_routetable(struct net_device *dev, char *command, int total_len) -{ - - char *pcmd = command; - char *str = NULL; - - ibss_route_tbl_t *route_tbl = NULL; - char *ioctl_buf = NULL; - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - s32 err = BCME_OK; - uint32 route_tbl_len; - uint32 entries; - char *endptr; - uint32 i = 0; - struct ipv4_addr dipaddr; - struct ether_addr ea; - - route_tbl_len = sizeof(ibss_route_tbl_t) + - (MAX_IBSS_ROUTE_TBL_ENTRY - 1) * sizeof(ibss_route_entry_t); - route_tbl = (ibss_route_tbl_t *)kzalloc(route_tbl_len, kflags); - if (!route_tbl) { - WL_ERR(("Route TBL alloc failed\n")); - return -ENOMEM; - } - ioctl_buf = kzalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); - if (!ioctl_buf) { - WL_ERR(("ioctl memory alloc failed\n")); - if (route_tbl) { - kfree(route_tbl); - } - return -ENOMEM; - } - memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN); - - /* drop command */ - str = bcmstrtok(&pcmd, " ", NULL); - - /* get count */ - str = bcmstrtok(&pcmd, " ", NULL); - if (!str) { - WL_ERR(("Invalid number parameter %s\n", str)); - err = -EINVAL; - goto exit; - } - entries = bcm_strtoul(str, &endptr, 0); - if (*endptr != '\0') { - WL_ERR(("Invalid number parameter %s\n", str)); - err = -EINVAL; - goto exit; - } - WL_INFORM(("Routing table count:%d\n", entries)); - route_tbl->num_entry = entries; - - for (i = 0; i < entries; i++) { - str = bcmstrtok(&pcmd, " ", NULL); - if (!str || !bcm_atoipv4(str, &dipaddr)) { - WL_ERR(("Invalid ip string %s\n", str)); - err = -EINVAL; - goto exit; - } - - - str = bcmstrtok(&pcmd, " ", NULL); - if (!str || !bcm_ether_atoe(str, &ea)) { - WL_ERR(("Invalid ethernet string %s\n", str)); - err = -EINVAL; - goto exit; - } - bcopy(&dipaddr, &route_tbl->route_entry[i].ipv4_addr, IPV4_ADDR_LEN); - bcopy(&ea, &route_tbl->route_entry[i].nexthop, ETHER_ADDR_LEN); - } - - route_tbl_len = sizeof(ibss_route_tbl_t) + - ((!entries?0:(entries - 1)) * sizeof(ibss_route_entry_t)); - err = wldev_iovar_setbuf(dev, "ibss_route_tbl", - route_tbl, route_tbl_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); - if (err != BCME_OK) { - WL_ERR(("Fail to set iovar %d\n", err)); - err = -EINVAL; - } - -exit: - if (route_tbl) - kfree(route_tbl); - if (ioctl_buf) - kfree(ioctl_buf); - return err; - -} - -int -wl_android_set_ibss_ampdu(struct net_device *dev, char *command, int total_len) -{ - char *pcmd = command; - char *str = NULL, *endptr = NULL; - struct ampdu_aggr aggr; - char smbuf[WLC_IOCTL_SMLEN]; - int idx; - int err = 0; - int wme_AC2PRIO[AC_COUNT][2] = { - {PRIO_8021D_VO, PRIO_8021D_NC}, /* AC_VO - 3 */ - {PRIO_8021D_CL, PRIO_8021D_VI}, /* AC_VI - 2 */ - {PRIO_8021D_BK, PRIO_8021D_NONE}, /* AC_BK - 1 */ - {PRIO_8021D_BE, PRIO_8021D_EE}}; /* AC_BE - 0 */ - - WL_DBG(("set ibss ampdu:%s\n", command)); - - memset(&aggr, 0, sizeof(aggr)); - /* Cofigure all priorities */ - aggr.conf_TID_bmap = NBITMASK(NUMPRIO); - - /* acquire parameters */ - /* drop command */ - str = bcmstrtok(&pcmd, " ", NULL); - - for (idx = 0; idx < AC_COUNT; idx++) { - bool on; - str = bcmstrtok(&pcmd, " ", NULL); - if (!str) { - WL_ERR(("Invalid parameter : %s\n", pcmd)); - return -EINVAL; - } - on = bcm_strtoul(str, &endptr, 0) ? TRUE : FALSE; - if (*endptr != '\0') { - WL_ERR(("Invalid number format %s\n", str)); - return -EINVAL; - } - if (on) { - setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][0]); - setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][1]); - } - } - - err = wldev_iovar_setbuf(dev, "ampdu_txaggr", (void *)&aggr, - sizeof(aggr), smbuf, WLC_IOCTL_SMLEN, NULL); - - return ((err == 0) ? total_len : err); -} - -int wl_android_set_ibss_antenna(struct net_device *dev, char *command, int total_len) -{ - char *pcmd = command; - char *str = NULL; - int txchain, rxchain; - int err = 0; - - WL_DBG(("set ibss antenna:%s\n", command)); - - /* acquire parameters */ - /* drop command */ - str = bcmstrtok(&pcmd, " ", NULL); - - /* TX chain */ - str = bcmstrtok(&pcmd, " ", NULL); - if (!str) { - WL_ERR(("Invalid parameter : %s\n", pcmd)); - return -EINVAL; - } - txchain = bcm_atoi(str); - - /* RX chain */ - str = bcmstrtok(&pcmd, " ", NULL); - if (!str) { - WL_ERR(("Invalid parameter : %s\n", pcmd)); - return -EINVAL; - } - rxchain = bcm_atoi(str); - - err = wldev_iovar_setint(dev, "txchain", txchain); - if (err != 0) - return err; - err = wldev_iovar_setint(dev, "rxchain", rxchain); - return ((err == 0)?total_len:err); -} -#endif /* WLAIBSS */ int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len) { @@ -1928,23 +1402,7 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) } else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; -#ifdef WL_HOST_BAND_MGMT - s32 ret = 0; - if ((ret = wl_cfg80211_set_band(net, band)) < 0) { - if (ret == BCME_UNSUPPORTED) { - /* If roam_var is unsupported, fallback to the original method */ - WL_ERR(("WL_HOST_BAND_MGMT defined, " - "but roam_band iovar unsupported in the firmware\n")); - } else { - bytes_written = -1; - goto exit; - } - } - if ((band == WLC_BAND_AUTO) || (ret == BCME_UNSUPPORTED)) - bytes_written = wldev_set_band(net, band); -#else bytes_written = wldev_set_band(net, band); -#endif /* WL_HOST_BAND_MGMT */ } else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); @@ -1983,28 +1441,6 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); } -#ifdef WL_SDO - else if (strnicmp(command, CMD_P2P_SD_OFFLOAD, strlen(CMD_P2P_SD_OFFLOAD)) == 0) { - u8 *buf = command; - u8 *cmd_id = NULL; - int len; - - cmd_id = strsep((char **)&buf, " "); - /* if buf == NULL, means no arg */ - if (buf == NULL) - len = 0; - else - len = strlen(buf); - - bytes_written = wl_cfg80211_sd_offload(net, cmd_id, buf, len); - } -#endif /* WL_SDO */ -#ifdef WL_NAN - else if (strnicmp(command, CMD_NAN, strlen(CMD_NAN)) == 0) { - bytes_written = wl_cfg80211_nan_cmd_handler(net, command, - priv_cmd.total_len); - } -#endif /* WL_NAN */ #if !defined WL_ENABLE_P2P_IF else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); @@ -2022,28 +1458,11 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); } -#ifdef WLFBT - else if (strnicmp(command, CMD_GET_FTKEY, strlen(CMD_GET_FTKEY)) == 0) { - wl_cfg80211_get_fbt_key(command); - bytes_written = FBT_KEYLEN; - } -#endif /* WLFBT */ #endif /* WL_CFG80211 */ else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0) bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len); else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len); -#ifdef BCMCCX - else if (strnicmp(command, CMD_GETCCKM_RN, strlen(CMD_GETCCKM_RN)) == 0) { - bytes_written = wl_android_get_cckm_rn(net, command); - } - else if (strnicmp(command, CMD_SETCCKM_KRK, strlen(CMD_SETCCKM_KRK)) == 0) { - bytes_written = wl_android_set_cckm_krk(net, command); - } - else if (strnicmp(command, CMD_GET_ASSOC_RES_IES, strlen(CMD_GET_ASSOC_RES_IES)) == 0) { - bytes_written = wl_android_get_assoc_res_ies(net, command); - } -#endif /* BCMCCX */ #if defined(WL_SUPPORT_AUTO_CHANNEL) else if (strnicmp(command, CMD_GET_BEST_CHANNELS, strlen(CMD_GET_BEST_CHANNELS)) == 0) { @@ -2067,27 +1486,6 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) else if (strnicmp(command, CMD_SETIBSSBEACONOUIDATA, strlen(CMD_SETIBSSBEACONOUIDATA)) == 0) bytes_written = wl_android_set_ibss_beacon_ouidata(net, command, priv_cmd.total_len); -#ifdef WLAIBSS - else if (strnicmp(command, CMD_SETIBSSTXFAILEVENT, - strlen(CMD_SETIBSSTXFAILEVENT)) == 0) - bytes_written = wl_android_set_ibss_txfail_event(net, command, priv_cmd.total_len); - else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO_ALL, - strlen(CMD_GET_IBSS_PEER_INFO_ALL)) == 0) - bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len, - TRUE); - else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO, - strlen(CMD_GET_IBSS_PEER_INFO)) == 0) - bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len, - FALSE); - else if (strnicmp(command, CMD_SETIBSSROUTETABLE, - strlen(CMD_SETIBSSROUTETABLE)) == 0) - bytes_written = wl_android_set_ibss_routetable(net, command, - priv_cmd.total_len); - else if (strnicmp(command, CMD_SETIBSSAMPDU, strlen(CMD_SETIBSSAMPDU)) == 0) - bytes_written = wl_android_set_ibss_ampdu(net, command, priv_cmd.total_len); - else if (strnicmp(command, CMD_SETIBSSANTENNAMODE, strlen(CMD_SETIBSSANTENNAMODE)) == 0) - bytes_written = wl_android_set_ibss_antenna(net, command, priv_cmd.total_len); -#endif /* WLAIBSS */ else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) { int skip = strlen(CMD_KEEP_ALIVE) + 1; bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip); @@ -2144,10 +1542,6 @@ int wl_android_init(void) } #endif -#ifdef WL_GENL - wl_genl_init(); -#endif - wl_netlink_init(); return ret; } @@ -2157,10 +1551,6 @@ int wl_android_exit(void) int ret = 0; struct io_cfg *cur, *q; -#ifdef WL_GENL - wl_genl_deinit(); -#endif /* WL_GENL */ - wl_netlink_deinit(); list_for_each_entry_safe(cur, q, &miracast_resume_list, list) { list_del(&cur->list); @@ -2175,260 +1565,9 @@ void wl_android_post_init(void) #ifdef ENABLE_4335BT_WAR bcm_bt_unlock(lock_cookie_wifi); - printf("%s: btlock released\n", __FUNCTION__); + printk("%s: btlock released\n", __FUNCTION__); #endif /* ENABLE_4335BT_WAR */ if (!dhd_download_fw_on_driverload) g_wifi_on = FALSE; } - -#ifdef WL_GENL -/* Generic Netlink Initializaiton */ -static int wl_genl_init(void) -{ - int ret; - - WL_DBG(("GEN Netlink Init\n\n")); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - /* register new family */ - ret = genl_register_family(&wl_genl_family); - if (ret != 0) - goto failure; - - /* register functions (commands) of the new family */ - ret = genl_register_ops(&wl_genl_family, &wl_genl_ops); - if (ret != 0) { - WL_ERR(("register ops failed: %i\n", ret)); - genl_unregister_family(&wl_genl_family); - goto failure; - } - - ret = genl_register_mc_group(&wl_genl_family, &wl_genl_mcast); -#else - ret = genl_register_family_with_ops_groups(&wl_genl_family, wl_genl_ops, wl_genl_mcast); -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */ - if (ret != 0) { - WL_ERR(("register mc_group failed: %i\n", ret)); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - genl_unregister_ops(&wl_genl_family, &wl_genl_ops); -#endif - genl_unregister_family(&wl_genl_family); - goto failure; - } - - return 0; - -failure: - WL_ERR(("Registering Netlink failed!!\n")); - return -1; -} - -/* Generic netlink deinit */ -static int wl_genl_deinit(void) -{ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - if (genl_unregister_ops(&wl_genl_family, &wl_genl_ops) < 0) - WL_ERR(("Unregister wl_genl_ops failed\n")); -#endif - if (genl_unregister_family(&wl_genl_family) < 0) - WL_ERR(("Unregister wl_genl_ops failed\n")); - - return 0; -} - -s32 wl_event_to_bcm_event(u16 event_type) -{ - u16 event = -1; - - switch (event_type) { - case WLC_E_SERVICE_FOUND: - event = BCM_E_SVC_FOUND; - break; - case WLC_E_P2PO_ADD_DEVICE: - event = BCM_E_DEV_FOUND; - break; - case WLC_E_P2PO_DEL_DEVICE: - event = BCM_E_DEV_LOST; - break; - /* Above events are supported from BCM Supp ver 47 Onwards */ -#ifdef BT_WIFI_HANDOVER - case WLC_E_BT_WIFI_HANDOVER_REQ: - event = BCM_E_DEV_BT_WIFI_HO_REQ; - break; -#endif /* BT_WIFI_HANDOVER */ - - default: - WL_ERR(("Event not supported\n")); - } - - return event; -} - -s32 -wl_genl_send_msg( - struct net_device *ndev, - u32 event_type, - u8 *buf, - u16 len, - u8 *subhdr, - u16 subhdr_len) -{ - int ret = 0; - struct sk_buff *skb = NULL; - void *msg; - u32 attr_type = 0; - bcm_event_hdr_t *hdr = NULL; - int mcast = 1; /* By default sent as mutlicast type */ - int pid = 0; - u8 *ptr = NULL, *p = NULL; - u32 tot_len = sizeof(bcm_event_hdr_t) + subhdr_len + len; - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - - - WL_DBG(("Enter \n")); - - /* Decide between STRING event and Data event */ - if (event_type == 0) - attr_type = BCM_GENL_ATTR_STRING; - else - attr_type = BCM_GENL_ATTR_MSG; - - skb = genlmsg_new(NLMSG_GOODSIZE, kflags); - if (skb == NULL) { - ret = -ENOMEM; - goto out; - } - - msg = genlmsg_put(skb, 0, 0, &wl_genl_family, 0, BCM_GENL_CMD_MSG); - if (msg == NULL) { - ret = -ENOMEM; - goto out; - } - - - if (attr_type == BCM_GENL_ATTR_STRING) { - /* Add a BCM_GENL_MSG attribute. Since it is specified as a string. - * make sure it is null terminated - */ - if (subhdr || subhdr_len) { - WL_ERR(("No sub hdr support for the ATTR STRING type \n")); - ret = -EINVAL; - goto out; - } - - ret = nla_put_string(skb, BCM_GENL_ATTR_STRING, buf); - if (ret != 0) { - WL_ERR(("nla_put_string failed\n")); - goto out; - } - } else { - /* ATTR_MSG */ - - /* Create a single buffer for all */ - p = ptr = kzalloc(tot_len, kflags); - if (!ptr) { - ret = -ENOMEM; - WL_ERR(("ENOMEM!!\n")); - goto out; - } - - /* Include the bcm event header */ - hdr = (bcm_event_hdr_t *)ptr; - hdr->event_type = wl_event_to_bcm_event(event_type); - hdr->len = len + subhdr_len; - ptr += sizeof(bcm_event_hdr_t); - - /* Copy subhdr (if any) */ - if (subhdr && subhdr_len) { - memcpy(ptr, subhdr, subhdr_len); - ptr += subhdr_len; - } - - /* Copy the data */ - if (buf && len) { - memcpy(ptr, buf, len); - } - - ret = nla_put(skb, BCM_GENL_ATTR_MSG, tot_len, p); - if (ret != 0) { - WL_ERR(("nla_put_string failed\n")); - goto out; - } - } - - if (mcast) { - int err = 0; - /* finalize the message */ - genlmsg_end(skb, msg); - /* NETLINK_CB(skb).dst_group = 1; */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) - if ((err = genlmsg_multicast(skb, 0, wl_genl_mcast.id, GFP_ATOMIC)) < 0) -#else - if ((err = genlmsg_multicast(&wl_genl_family, skb, 0, 0, GFP_ATOMIC)) < 0) -#endif - WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n", - attr_type, err)); - else - WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n", - attr_type, tot_len)); - } else { - NETLINK_CB(skb).dst_group = 0; /* Not in multicast group */ - - /* finalize the message */ - genlmsg_end(skb, msg); - - /* send the message back */ - if (genlmsg_unicast(&init_net, skb, pid) < 0) - WL_ERR(("genlmsg_unicast failed\n")); - } - -out: - if (p) - kfree(p); - if (ret) - nlmsg_free(skb); - - return ret; -} - -static s32 -wl_genl_handle_msg( - struct sk_buff *skb, - struct genl_info *info) -{ - struct nlattr *na; - u8 *data = NULL; - - WL_DBG(("Enter \n")); - - if (info == NULL) { - return -EINVAL; - } - - na = info->attrs[BCM_GENL_ATTR_MSG]; - if (!na) { - WL_ERR(("nlattribute NULL\n")); - return -EINVAL; - } - - data = (char *)nla_data(na); - if (!data) { - WL_ERR(("Invalid data\n")); - return -EINVAL; - } else { - /* Handle the data */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS) - WL_DBG(("%s: Data received from pid (%d) \n", __func__, - info->snd_pid)); -#else - WL_DBG(("%s: Data received from pid (%d) \n", __func__, - info->snd_portid)); -#endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */ - } - - return 0; -} -#endif /* WL_GENL */ diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h index 87e672fc9c2bf0a89ea27f1dc2c70658b8a16b17..a9e1ad3bc4b44eff7f24152ef969e88988ac7bfe 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.h +++ b/drivers/net/wireless/bcmdhd/wl_android.h @@ -1,9 +1,27 @@ /* * Linux cfg80211 driver - Android related functions * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_android.h 487838 2014-06-27 05:51:44Z $ + * $Id: wl_android.h 467328 2014-04-03 01:23:40Z $ */ #include <linux/module.h> @@ -13,14 +31,11 @@ /* If any feature uses the Generic Netlink Interface, put it here to enable WL_GENL * automatically */ -#if defined(WL_SDO) || defined(BT_WIFI_HANDOVER) || defined(WL_NAN) +#if defined(BT_WIFI_HANDOVER) #define WL_GENL #endif -#ifdef WL_GENL -#include <net/genetlink.h> -#endif /** * Android platform dependent functions, feel free to add Android specific functions here @@ -39,48 +54,6 @@ int wl_android_wifi_on(struct net_device *dev); int wl_android_wifi_off(struct net_device *dev); int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); -#ifdef WL_GENL -typedef struct bcm_event_hdr { - u16 event_type; - u16 len; -} bcm_event_hdr_t; - -/* attributes (variables): the index in this enum is used as a reference for the type, - * userspace application has to indicate the corresponding type - * the policy is used for security considerations - */ -enum { - BCM_GENL_ATTR_UNSPEC, - BCM_GENL_ATTR_STRING, - BCM_GENL_ATTR_MSG, - __BCM_GENL_ATTR_MAX -}; -#define BCM_GENL_ATTR_MAX (__BCM_GENL_ATTR_MAX - 1) - -/* commands: enumeration of all commands (functions), - * used by userspace application to identify command to be ececuted - */ -enum { - BCM_GENL_CMD_UNSPEC, - BCM_GENL_CMD_MSG, - __BCM_GENL_CMD_MAX -}; -#define BCM_GENL_CMD_MAX (__BCM_GENL_CMD_MAX - 1) - -/* Enum values used by the BCM supplicant to identify the events */ -enum { - BCM_E_UNSPEC, - BCM_E_SVC_FOUND, - BCM_E_DEV_FOUND, - BCM_E_DEV_LOST, - BCM_E_DEV_BT_WIFI_HO_REQ, - BCM_E_MAX -}; - -s32 wl_genl_send_msg(struct net_device *ndev, u32 event_type, - u8 *string, u16 len, u8 *hdr, u16 hdrlen); -#endif /* WL_GENL */ -s32 wl_netlink_send_msg(int pid, int type, int seq, void *data, size_t size); /* hostap mac mode */ #define MACLIST_MODE_DISABLED 0 diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index 13f6bbb77515039258dfb4617e31bc84a96bf7ff..73ef1959231da58810ab89544e51da6a1e3d48c2 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -1,9 +1,27 @@ /* * Linux cfg80211 driver * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: wl_cfg80211.c 491569 2014-07-16 21:28:40Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_cfg80211.c 477711 2014-05-14 08:45:17Z $ */ /* */ #include <typedefs.h> @@ -46,15 +64,14 @@ #include <wl_cfg80211.h> #include <wl_cfgp2p.h> #include <wl_android.h> -#include <wl_cfgvendor.h> -#ifdef WL_NAN -#include <wl_cfgnan.h> -#endif /* WL_NAN */ #ifdef PROP_TXSTATUS #include <dhd_wlfc.h> #endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) +#include <wl_cfgvendor.h> +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ #ifdef WL11U #if !defined(WL_ENABLE_P2P_IF) && !defined(WL_CFG80211_P2P_DEV_IF) #error You should enable 'WL_ENABLE_P2P_IF' or 'WL_CFG80211_P2P_DEV_IF' \ @@ -62,38 +79,8 @@ #endif /* !WL_ENABLE_P2P_IF && !WL_CFG80211_P2P_DEV_IF */ #endif /* WL11U */ -#ifdef BCMWAPI_WPI -/* these items should evetually go into wireless.h of the linux system headfile dir */ -#ifndef IW_ENCODE_ALG_SM4 -#define IW_ENCODE_ALG_SM4 0x20 -#endif - -#ifndef IW_AUTH_WAPI_ENABLED -#define IW_AUTH_WAPI_ENABLED 0x20 -#endif - -#ifndef IW_AUTH_WAPI_VERSION_1 -#define IW_AUTH_WAPI_VERSION_1 0x00000008 -#endif - -#ifndef IW_AUTH_CIPHER_SMS4 -#define IW_AUTH_CIPHER_SMS4 0x00000020 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK -#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT -#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 -#endif -#endif /* BCMWAPI_WPI */ -#ifdef BCMWAPI_WPI -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) -#else /* BCMWAPI_WPI */ #define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#endif /* BCMWAPI_WPI */ static struct device *cfg80211_parent_dev = NULL; /* g_bcm_cfg should be static. Do not change */ @@ -101,9 +88,7 @@ static struct bcm_cfg80211 *g_bcm_cfg = NULL; u32 wl_dbg_level = WL_DBG_ERR; #define MAX_WAIT_TIME 1500 -#ifdef WLAIBSS_MCHAN #define IBSS_IF_NAME "ibss%d" -#endif /* WLAIBSS_MCHAN */ #ifdef VSDB /* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */ @@ -141,17 +126,6 @@ u32 wl_dbg_level = WL_DBG_ERR; #define CH_MIN_5G_CHANNEL 34 #define CH_MIN_2G_CHANNEL 1 -#ifdef WLAIBSS -enum abiss_event_type { - AIBSS_EVENT_TXFAIL -}; -#endif - -enum rmc_event_type { - RMC_EVENT_NONE, - RMC_EVENT_LEADER_CHECK_FAIL -}; - /* This is to override regulatory domains defined in cfg80211 module (reg.c) * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165). @@ -273,18 +247,12 @@ common_iface_combinations[] = { #define PM_BLOCK 1 #define PM_ENABLE 0 -#ifdef BCMCCX -#ifndef WLAN_AKM_SUITE_CCKM -#define WLAN_AKM_SUITE_CCKM 0x00409600 -#endif -#define DOT11_LEAP_AUTH 0x80 /* LEAP auth frame paylod constants */ -#endif /* BCMCCX */ - #ifdef MFP #define WL_AKM_SUITE_MFP_1X 0x000FAC05 #define WL_AKM_SUITE_MFP_PSK 0x000FAC06 #endif /* MFP */ + #ifndef IBSS_COALESCE_ALLOWED #define IBSS_COALESCE_ALLOWED 0 #endif @@ -312,10 +280,8 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request); #endif /* WL_CFG80211_P2P_DEV_IF */ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -#ifdef WLAIBSS_MCHAN static bcm_struct_cfgdev* bcm_cfg80211_add_ibss_if(struct wiphy *wiphy, char *name); static s32 bcm_cfg80211_del_ibss_if(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev); -#endif /* WLAIBSS_MCHAN */ static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, @@ -369,7 +335,7 @@ static s32 wl_cfg80211_del_station(struct wiphy *wiphy, static s32 wl_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_parameters *params); #endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); #else static s32 wl_cfg80211_suspend(struct wiphy *wiphy); @@ -383,10 +349,10 @@ static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, static void wl_cfg80211_scan_abort(struct bcm_cfg80211 *cfg); static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg, struct net_device *ndev, bool aborted, bool fw_abort); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) static s32 wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, u8 *peer, enum nl80211_tdls_operation oper); -#endif /* LINUX_VERSION > KERNEL_VERSION(3,2,0) || WL_COMPAT_WIRELESS */ +#endif #ifdef WL_SCHED_SCAN static int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev); #endif @@ -442,14 +408,12 @@ wl_notify_sched_scan_results(struct bcm_cfg80211 *cfg, struct net_device *ndev, static s32 wl_notify_pfn_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data); #endif /* PNO_SUPPORT */ +#ifdef GSCAN_SUPPORT +static s32 wl_notify_gscan_event(struct bcm_cfg80211 *wl, bcm_struct_cfgdev *cfgdev, + const wl_event_msg_t *e, void *data); +#endif /* GSCAN_SUPPORT */ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_net_info, enum wl_status state, bool set); -#ifdef WL_SDO -static s32 wl_svc_resp_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_device_discovery(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); -#endif #ifdef WLTDLS static s32 wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, @@ -492,10 +456,6 @@ static s32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme); static s32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme); -#ifdef BCMWAPI_WPI -static s32 wl_set_set_wapi_ie(struct net_device *dev, - struct cfg80211_connect_params *sme); -#endif static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev); static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, size_t *join_params_size); @@ -534,10 +494,6 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy); s32 wl_cfg80211_channel_to_freq(u32 channel); -#if defined(DHCP_SCAN_SUPPRESS) -static void wl_cfg80211_work_handler(struct work_struct *work); -static void wl_cfg80211_scan_supp_timerfunc(ulong data); -#endif /* DHCP_SCAN_SUPPRESS */ static void wl_cfg80211_work_handler(struct work_struct *work); static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, @@ -615,22 +571,21 @@ int dhd_monitor_init(void *dhd_pub); int dhd_monitor_uninit(void); int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); +#ifdef ROAM_CHANNEL_CACHE +void init_roam(int ioctl_ver); +void reset_roam_cache(void); +void add_roam_cache(wl_bss_info_t *bi); +int get_roam_channel_list(int target_chan, + chanspec_t *channels, const wlc_ssid_t *ssid, int ioctl_ver); +void print_roam_cache(void); +void set_roam_band(int band); +void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver); +#define MAX_ROAM_CACHE_NUM 100 +#endif /* ROAM_CHANNEL_CACHE */ static int wl_cfg80211_delayed_roam(struct bcm_cfg80211 *cfg, struct net_device *ndev, const struct ether_addr *bssid); -#ifdef WL_SDO -s32 wl_cfg80211_sdo_init(struct bcm_cfg80211 *cfg); -s32 wl_cfg80211_sdo_deinit(struct bcm_cfg80211 *cfg); -#define MAX_SDO_PROTO 5 -wl_sdo_proto_t wl_sdo_protos [] = { - { "all", SVC_RPOTYPE_ALL }, - { "upnp", SVC_RPOTYPE_UPNP }, - { "bonjour", SVC_RPOTYPE_BONJOUR }, - { "wsd", SVC_RPOTYPE_WSD }, - { "vendor", SVC_RPOTYPE_VENDOR }, -}; -#endif static int bw2cap[] = { 0, 0, WLC_BW_CAP_20MHZ, WLC_BW_CAP_40MHZ, WLC_BW_CAP_80MHZ, WLC_BW_CAP_160MHZ, WLC_BW_CAP_160MHZ }; @@ -797,12 +752,6 @@ static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, WLAN_CIPHER_SUITE_AES_CMAC, -#ifdef BCMWAPI_WPI - WLAN_CIPHER_SUITE_SMS4, -#endif -#if defined(WLFBT) && defined(WLAN_CIPHER_SUITE_PMK) - WLAN_CIPHER_SUITE_PMK, -#endif }; #ifdef WL_SUPPORT_ACS @@ -965,7 +914,7 @@ wl_chspec_to_legacy(chanspec_t chspec) * a chanspec_t value * Returns INVCHANSPEC on error */ -chanspec_t +static chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec) { if (ioctl_version == 1) { @@ -1259,12 +1208,6 @@ s32 wl_set_tx_power(struct net_device *dev, if (dbm > 0xffff) dbm = 0xffff; txpwrqdbm = dbm * 4; -#ifdef SUPPORT_WL_TXPOWER - if (type == NL80211_TX_POWER_AUTOMATIC) - txpwrqdbm = 127; - else - txpwrqdbm |= WL_TXPWR_OVERRIDE; -#endif /* SUPPORT_WL_TXPOWER */ err = wldev_iovar_setbuf_bsscfg(dev, "qtxpower", (void *)&txpwrqdbm, sizeof(txpwrqdbm), cfg->ioctl_buf, WLC_IOCTL_SMLEN, 0, &cfg->ioctl_buf_sync); @@ -1397,9 +1340,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, WL_DBG(("if name: %s, type: %d\n", name, type)); switch (type) { case NL80211_IFTYPE_ADHOC: -#ifdef WLAIBSS_MCHAN return bcm_cfg80211_add_ibss_if(wiphy, (char *)name); -#endif /* WLAIBSS_MCHAN */ case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: @@ -1414,13 +1355,11 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, #endif /* WL_CFG80211_P2P_DEV_IF */ case NL80211_IFTYPE_STATION: #ifdef DUAL_STA -#ifdef WLAIBSS_MCHAN if (cfg->ibss_cfgdev) { WL_ERR(("AIBSS is already operational. " " AIBSS & DUALSTA can't be used together \n")); return NULL; } -#endif /* WLAIBSS_MCHAN */ if (!name) { WL_ERR(("Interface name not provided \n")); return NULL; @@ -1622,10 +1561,8 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) #endif /* WL_CFG80211_P2P_DEV_IF */ dev = cfgdev_to_wlc_ndev(cfgdev, cfg); -#ifdef WLAIBSS_MCHAN if (cfgdev == cfg->ibss_cfgdev) return bcm_cfg80211_del_ibss_if(wiphy, cfgdev); -#endif /* WLAIBSS_MCHAN */ #ifdef DUAL_STA if (cfgdev == cfg->bss_cfgdev) @@ -2067,20 +2004,8 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req continue; if (request->channels[i]->band == IEEE80211_BAND_2GHZ) { -#ifdef WL_HOST_BAND_MGMT - if (cfg->curr_band == WLC_BAND_5G) { - WL_DBG(("In 5G only mode, omit 2G channel:%d\n", channel)); - continue; - } -#endif /* WL_HOST_BAND_MGMT */ chanspec |= WL_CHANSPEC_BAND_2G; } else { -#ifdef WL_HOST_BAND_MGMT - if (cfg->curr_band == WLC_BAND_2G) { - WL_DBG(("In 2G only mode, omit 5G channel:%d\n", channel)); - continue; - } -#endif /* WL_HOST_BAND_MGMT */ chanspec |= WL_CHANSPEC_BAND_5G; } @@ -2150,10 +2075,10 @@ wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size) return err; } -#if defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME) #define FIRST_SCAN_ACTIVE_DWELL_TIME_MS 40 bool g_first_broadcast_scan = TRUE; -#endif +#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */ static s32 wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev, @@ -2173,9 +2098,9 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev, u16 *default_chan_list = NULL; wl_uint32_list_t *list; struct net_device *dev = NULL; -#if defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME) bool is_first_init_2g_scan = false; -#endif +#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */ p2p_scan_purpose_t p2p_scan_purpose = P2P_SCAN_PURPOSE_MIN; WL_DBG(("Enter \n")); @@ -2189,16 +2114,55 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev, /* LEGACY SCAN TRIGGER */ WL_SCAN((" LEGACY E-SCAN START\n")); -#if defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME) if (!request) { err = -EINVAL; goto exit; } if (ndev == bcmcfg_to_prmry_ndev(cfg) && g_first_broadcast_scan == true) { +#ifdef USE_INITIAL_2G_SCAN + struct ieee80211_channel tmp_channel_list[CH_MAX_2G_CHANNEL]; + /* allow one 5G channel to add previous connected channel in 5G */ + bool allow_one_5g_channel = TRUE; + j = 0; + for (i = 0; i < request->n_channels; i++) { + int tmp_chan = ieee80211_frequency_to_channel + (request->channels[i]->center_freq); + if (tmp_chan > CH_MAX_2G_CHANNEL) { + if (allow_one_5g_channel) + allow_one_5g_channel = FALSE; + else + continue; + } + if (j > CH_MAX_2G_CHANNEL) { + WL_ERR(("Index %d exceeds max 2.4GHz channels %d" + " and previous 5G connected channel\n", + j, CH_MAX_2G_CHANNEL)); + break; + } + bcopy(request->channels[i], &tmp_channel_list[j], + sizeof(struct ieee80211_channel)); + WL_SCAN(("channel of request->channels[%d]=%d\n", i, tmp_chan)); + j++; + } + if ((j > 0) && (j <= CH_MAX_2G_CHANNEL)) { + for (i = 0; i < j; i++) + bcopy(&tmp_channel_list[i], request->channels[i], + sizeof(struct ieee80211_channel)); + + request->n_channels = j; + is_first_init_2g_scan = true; + } + else + WL_ERR(("Invalid number of 2.4GHz channels %d\n", j)); + + WL_SCAN(("request->n_channels=%d\n", request->n_channels)); +#else /* USE_INITIAL_SHORT_DWELL_TIME */ is_first_init_2g_scan = true; +#endif /* USE_INITIAL_2G_SCAN */ g_first_broadcast_scan = false; } -#endif +#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */ /* if scan request is not empty parse scan request paramters */ if (request != NULL) { @@ -2220,11 +2184,11 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev, } wl_scan_prep(¶ms->params, request); -#if defined(USE_INITIAL_SHORT_DWELL_TIME) +#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME) /* Override active_time to reduce scan time if it's first bradcast scan. */ if (is_first_init_2g_scan) params->params.active_time = FIRST_SCAN_ACTIVE_DWELL_TIME_MS; -#endif +#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */ params->version = htod32(ESCAN_REQ_VERSION); params->action = htod16(action); @@ -2266,19 +2230,8 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev, n_valid_chan = dtoh32(list->count); for (i = 0; i < num_chans; i++) { -#ifdef WL_HOST_BAND_MGMT - int channel_band = 0; -#endif /* WL_HOST_BAND_MGMT */ _freq = request->channels[i]->center_freq; channel = ieee80211_frequency_to_channel(_freq); -#ifdef WL_HOST_BAND_MGMT - channel_band = (channel > CH_MAX_2G_CHANNEL) ? - WLC_BAND_5G : WLC_BAND_2G; - if ((cfg->curr_band != WLC_BAND_AUTO) && - (cfg->curr_band != channel_band) && - !IS_P2P_SOCIAL_CHANNEL(channel)) - continue; -#endif /* WL_HOST_BAND_MGMT */ /* ignore DFS channels */ if (request->channels[i]->flags & @@ -2460,11 +2413,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -#ifdef WL_SDO - if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { - wl_cfg80211_pause_sdo(ndev, cfg); - } -#endif /* Arm scan timeout timer */ mod_timer(&cfg->scan_timeout, jiffies + msecs_to_jiffies(WL_SCAN_TIMER_INTERVAL_MS)); @@ -2565,17 +2513,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if (cfg->p2p_supported) { if (p2p_on(cfg) && p2p_scan(cfg)) { -#ifdef WL_SDO - if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { - /* We shouldn't be getting p2p_find while discovery - * offload is in progress - */ - WL_SD(("P2P_FIND: Discovery offload is in progress." - " Do nothing\n")); - err = -EINVAL; - goto scan_out; - } -#endif /* find my listen channel */ cfg->afx_hdl->my_listen_chan = wl_find_listen_channel(cfg, request->ie, @@ -2644,11 +2581,6 @@ scan_out: cfg->scan_request = NULL; spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags); -#ifdef WL_SDO - if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { - wl_cfg80211_resume_sdo(ndev, cfg); - } -#endif return err; } @@ -2880,7 +2812,6 @@ wl_cfg80211_ibss_vsie_delete(struct net_device *dev) return ret; } -#ifdef WLAIBSS_MCHAN static bcm_struct_cfgdev* bcm_cfg80211_add_ibss_if(struct wiphy *wiphy, char *name) { @@ -2964,45 +2895,6 @@ fail: return NULL; } -static s32 -bcm_cfg80211_del_ibss_if(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) -{ - int err = 0; - struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); - struct net_device *ndev = NULL; - struct net_device *primary_ndev = NULL; - s32 timeout; - - if (!cfgdev || cfg->ibss_cfgdev != cfgdev || ETHER_ISNULLADDR(&cfg->ibss_if_addr.octet)) - return -EINVAL; - ndev = (struct net_device *)cfgdev_to_ndev(cfg->ibss_cfgdev); - primary_ndev = bcmcfg_to_prmry_ndev(cfg); - - cfg->bss_pending_op = TRUE; - memset(&cfg->if_event_info, 0, sizeof(cfg->if_event_info)); - err = wldev_iovar_setbuf(primary_ndev, "aibss_ifdel", &cfg->ibss_if_addr, - sizeof(cfg->ibss_if_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, NULL); - if (err) { - WL_ERR(("IOVAR aibss_ifdel failed with error %d\n", err)); - goto fail; - } - timeout = wait_event_interruptible_timeout(cfg->netif_change_event, - !cfg->bss_pending_op, msecs_to_jiffies(MAX_WAIT_TIME)); - if (timeout <= 0 || cfg->bss_pending_op) { - WL_ERR(("timeout in waiting IF_DEL event\n")); - goto fail; - } - - wl_cfg80211_remove_if(cfg, cfg->if_event_info.ifidx, ndev); - cfg->ibss_cfgdev = NULL; - return 0; - -fail: - cfg->bss_pending_op = FALSE; - return -1; -} -#endif /* WLAIBSS_MCHAN */ - #if defined(DUAL_STA) || defined(DUAL_STA_STATIC_IF) s32 wl_cfg80211_add_del_bss(struct bcm_cfg80211 *cfg, @@ -3221,7 +3113,7 @@ wl_cfg80211_del_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) wl_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true); } - ndev = (struct net_device *)cfgdev_to_ndev(cfg->bss_cfgdev); + ndev = cfgdev_to_ndev(cfg->bss_cfgdev); primary_ndev = bcmcfg_to_prmry_ndev(cfg); cfg->bss_pending_op = TRUE; @@ -3251,6 +3143,44 @@ wl_cfg80211_del_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) } #endif /* defined(DUAL_STA) || defined(DUAL_STA_STATIC_IF) */ +static s32 +bcm_cfg80211_del_ibss_if(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + struct net_device *ndev = NULL; + struct net_device *primary_ndev = NULL; + s32 timeout; + + if (!cfgdev || cfg->ibss_cfgdev != cfgdev || ETHER_ISNULLADDR(&cfg->ibss_if_addr.octet)) + return -EINVAL; + ndev = cfgdev_to_ndev(cfg->ibss_cfgdev); + primary_ndev = bcmcfg_to_prmry_ndev(cfg); + + cfg->bss_pending_op = TRUE; + memset(&cfg->if_event_info, 0, sizeof(cfg->if_event_info)); + err = wldev_iovar_setbuf(primary_ndev, "aibss_ifdel", &cfg->ibss_if_addr, + sizeof(cfg->ibss_if_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, NULL); + if (err) { + WL_ERR(("IOVAR aibss_ifdel failed with error %d\n", err)); + goto fail; + } + timeout = wait_event_interruptible_timeout(cfg->netif_change_event, + !cfg->bss_pending_op, msecs_to_jiffies(MAX_WAIT_TIME)); + if (timeout <= 0 || cfg->bss_pending_op) { + WL_ERR(("timeout in waiting IF_DEL event\n")); + goto fail; + } + + wl_cfg80211_remove_if(cfg, cfg->if_event_info.ifidx, ndev); + cfg->ibss_cfgdev = NULL; + return 0; + +fail: + cfg->bss_pending_op = FALSE; + return -1; +} + static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) @@ -3267,9 +3197,6 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, chanspec_t chanspec = 0; u32 param[2] = {0, 0}; u32 bw_cap = 0; -#if defined(WLAIBSS) && defined(WLAIBSS_PS) - s32 atim = 10; -#endif /* WLAIBSS & WLAIBSS_PS */ WL_TRACE(("In\n")); RETURN_EIO_IF_NOT_UP(cfg); @@ -3390,22 +3317,6 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_DISABLED); wldev_iovar_setint(dev, "wsec", 0); -#ifdef WLAIBSS - /* Enable custom ibss features */ - err = wldev_iovar_setint(dev, "aibss", TRUE); - - if (unlikely(err)) { - WL_ERR(("Enable custom IBSS mode failed (%d)\n", err)); - return err; - } -#ifdef WLAIBSS_PS - err = wldev_ioctl(dev, WLC_SET_ATIM, &atim, sizeof(int), true); - if (unlikely(err)) { - WL_ERR(("Enable custom IBSS ATIM mode failed (%d)\n", err)); - return err; - } -#endif /* WLAIBSS_PS */ -#endif /* WLAIBSS */ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true); @@ -3426,10 +3337,6 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } wl_update_prof(cfg, dev, NULL, &join_params.ssid, WL_PROF_SSID); wl_update_prof(cfg, dev, NULL, &cfg->channel, WL_PROF_CHAN); -#ifdef WLAIBSS - cfg->aibss_txfail_seq = 0; /* initialize the sequence */ -#endif /* WLAIBSS */ - cfg->rmc_event_seq = 0; /* initialize rmcfail sequence */ return err; } @@ -3461,7 +3368,6 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return err; } - #ifdef MFP static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa) { @@ -3500,6 +3406,7 @@ static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa) } #endif /* MFP */ + static s32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -3515,15 +3422,9 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) val = WPA_AUTH_PSK | -#ifdef BCMCCX - WPA_AUTH_CCKM | -#endif WPA_AUTH_UNSPECIFIED; else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) val = WPA2_AUTH_PSK| -#ifdef BCMCCX - WPA2_AUTH_CCKM | -#endif WPA2_AUTH_UNSPECIFIED; else val = WPA_AUTH_DISABLED; @@ -3531,13 +3432,6 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) if (is_wps_conn(sme)) val = WPA_AUTH_DISABLED; -#ifdef BCMWAPI_WPI - if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { - WL_DBG((" * wl_set_wpa_version, set wpa_auth" - " to WPA_AUTH_WAPI 0x400")); - val = WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED; - } -#endif WL_DBG(("setting wpa_auth to 0x%0x\n", val)); err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); if (unlikely(err)) { @@ -3549,33 +3443,6 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) return err; } -#ifdef BCMWAPI_WPI -static s32 -wl_set_set_wapi_ie(struct net_device *dev, struct cfg80211_connect_params *sme) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(cfg, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } - - WL_DBG((" %s \n", __FUNCTION__)); - - if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { - err = wldev_iovar_setbuf_bsscfg(dev, "wapiie", sme->ie, sme->ie_len, - cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync); - - if (unlikely(err)) { - WL_ERR(("===> set_wapi_ie Error (%d)\n", err)); - return err; - } - } else - WL_DBG((" * skip \n")); - return err; -} -#endif /* BCMWAPI_WPI */ static s32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) @@ -3603,12 +3470,6 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) val = WL_AUTH_OPEN_SHARED; WL_DBG(("automatic\n")); break; -#ifdef BCMCCX - case NL80211_AUTHTYPE_NETWORK_EAP: - WL_DBG(("network eap\n")); - val = DOT11_LEAP_AUTH; - break; -#endif default: val = 2; WL_ERR(("invalid auth type (%d)\n", sme->auth_type)); @@ -3640,9 +3501,6 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) u8 rsn_cap[2]; #endif /* MFP */ -#ifdef BCMWAPI_WPI - s32 val = 0; -#endif s32 bssidx; if (wl_cfgp2p_find_idx(cfg, dev, &bssidx) != BCME_OK) { WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); @@ -3662,36 +3520,12 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_CIPHER_SUITE_AES_CMAC: pval = AES_ENABLED; break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - val = SMS4_ENABLED; - pval = SMS4_ENABLED; - break; -#endif default: WL_ERR(("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0])); return -EINVAL; } } -#if defined(BCMSUP_4WAY_HANDSHAKE) && defined(WLAN_AKM_SUITE_FT_8021X) - /* Ensure in-dongle supplicant is turned on when FBT wants to do the 4-way - * handshake. - * Note that the FW feature flag only exists on kernels that support the - * FT-EAP AKM suite. - */ - if (cfg->wdev->wiphy->features & NL80211_FEATURE_FW_4WAY_HANDSHAKE) { - if (pval == AES_ENABLED) - err = wldev_iovar_setint_bsscfg(dev, "sup_wpa", 1, bssidx); - else - err = wldev_iovar_setint_bsscfg(dev, "sup_wpa", 0, bssidx); - - if (err) { - WL_ERR(("FBT: Error setting sup_wpa (%d)\n", err)); - return err; - } - } -#endif /* BCMSUP_4WAY_HANDSHAKE && WLAN_AKM_SUITE_FT_8021X */ if (sme->crypto.cipher_group) { switch (sme->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: @@ -3707,12 +3541,6 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_CIPHER_SUITE_AES_CMAC: gval = AES_ENABLED; break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - val = SMS4_ENABLED; - gval = SMS4_ENABLED; - break; -#endif default: WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group)); @@ -3729,15 +3557,8 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) /* WPS-2.0 allows no security */ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); } else { -#ifdef BCMWAPI_WPI - if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_SMS4) { - WL_DBG((" NO, is_wps_conn, WAPI set to SMS4_ENABLED")); - err = wldev_iovar_setint_bsscfg(dev, "wsec", val, bssidx); - } else { -#endif WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC")); wsec_val = pval | gval; - #ifdef MFP if (pval == AES_ENABLED) { if (((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len, @@ -3773,12 +3594,10 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) } } #endif /* MFP */ + WL_DBG((" Set WSEC to fW 0x%x \n", wsec_val)); err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec_val, bssidx); -#ifdef BCMWAPI_WPI - } -#endif } if (unlikely(err)) { WL_ERR(("error (%d)\n", err)); @@ -3812,9 +3631,6 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) return err; } if (val & (WPA_AUTH_PSK | -#ifdef BCMCCX - WPA_AUTH_CCKM | -#endif WPA_AUTH_UNSPECIFIED)) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: @@ -3823,20 +3639,12 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_AKM_SUITE_PSK: val = WPA_AUTH_PSK; break; -#ifdef BCMCCX - case WLAN_AKM_SUITE_CCKM: - val = WPA_AUTH_CCKM; - break; -#endif default: WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } else if (val & (WPA2_AUTH_PSK | -#ifdef BCMCCX - WPA2_AUTH_CCKM | -#endif WPA2_AUTH_UNSPECIFIED)) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: @@ -3853,43 +3661,12 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_AKM_SUITE_PSK: val = WPA2_AUTH_PSK; break; -#if defined(WLFBT) && defined(WLAN_AKM_SUITE_FT_8021X) - case WLAN_AKM_SUITE_FT_8021X: - val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT; - break; -#endif -#if defined(WLFBT) && defined(WLAN_AKM_SUITE_FT_PSK) - case WLAN_AKM_SUITE_FT_PSK: - val = WPA2_AUTH_PSK | WPA2_AUTH_FT; - break; -#endif -#ifdef BCMCCX - case WLAN_AKM_SUITE_CCKM: - val = WPA2_AUTH_CCKM; - break; -#endif - default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); - return -EINVAL; - } - } -#ifdef BCMWAPI_WPI - else if (val & (WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED)) { - switch (sme->crypto.akm_suites[0]) { - case WLAN_AKM_SUITE_WAPI_CERT: - val = WAPI_AUTH_UNSPECIFIED; - break; - case WLAN_AKM_SUITE_WAPI_PSK: - val = WAPI_AUTH_PSK; - break; default: WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } -#endif WL_DBG(("setting wpa_auth to %d\n", val)); err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); @@ -3925,17 +3702,9 @@ wl_set_set_sharedkey(struct net_device *dev, WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions, sec->cipher_pairwise)); if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | -#ifdef BCMWAPI_WPI - NL80211_WPA_VERSION_2 | NL80211_WAPI_VERSION_1)) && -#else NL80211_WPA_VERSION_2)) && -#endif (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | -#ifdef BCMWAPI_WPI - WLAN_CIPHER_SUITE_WEP104 | WLAN_CIPHER_SUITE_SMS4))) -#else WLAN_CIPHER_SUITE_WEP104))) -#endif { memset(&key, 0, sizeof(key)); key.len = (u32) sme->key_len; @@ -3953,11 +3722,6 @@ wl_set_set_sharedkey(struct net_device *dev, case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - key.algo = CRYPTO_ALGO_SMS4; - break; -#endif default: WL_ERR(("Invalid algorithm (%d)\n", sme->crypto.ciphers_pairwise[0])); @@ -4020,6 +3784,10 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, wl_extjoin_params_t *ext_join_params; struct wl_join_params join_params; size_t join_params_size; +#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) + dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); + s32 roam_trigger[2] = {0, 0}; +#endif /* ROAM_AP_ENV_DETECTION */ s32 err = 0; wpa_ie_fixed_t *wpa_ie; bcm_tlv_t *wpa2_ie; @@ -4028,9 +3796,12 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, u32 chan_cnt = 0; struct ether_addr bssid; s32 bssidx; +#ifdef ROAM_CHANNEL_CACHE + chanspec_t chanspec_list[MAX_ROAM_CACHE_NUM]; +#endif /* ROAM_CHANNEL_CACHE */ int ret; int wait_cnt; - + bool use_chan_cache = FALSE; WL_DBG(("In\n")); if (unlikely(!sme->ssid)) { @@ -4049,11 +3820,9 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, /* * Cancel ongoing scan to sync up with sme state machine of cfg80211. */ -#if (!defined(ESCAN_RESULT_PATCH) || defined(CUSTOMER_HW10)) if (cfg->scan_request) { wl_notify_escan_complete(cfg, dev, true, true); } -#endif #ifdef WL_SCHED_SCAN if (cfg->sched_scan_req) { wl_cfg80211_sched_scan_stop(wiphy, bcmcfg_to_prmry_ndev(cfg)); @@ -4152,23 +3921,47 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return err; } } +#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) + if (dhd->roam_env_detection) { + bool is_roamtrig_reset = TRUE; + bool is_roam_env_ok = (wldev_iovar_setint(dev, "roam_env_detection", + AP_ENV_DETECT_NOT_USED) == BCME_OK); + if (is_roamtrig_reset && is_roam_env_ok) { + roam_trigger[0] = WL_AUTO_ROAM_TRIGGER; + roam_trigger[1] = WLC_BAND_ALL; + err = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, + sizeof(roam_trigger), true); + if (unlikely(err)) { + WL_ERR((" failed to restore roam_trigger for auto env" + " detection\n")); + } + } + } +#endif /* ROAM_ENABLE && ROAM_AP_ENV_DETECTION */ if (chan) { cfg->channel = ieee80211_frequency_to_channel(chan->center_freq); chan_cnt = 1; WL_DBG(("channel (%d), center_req (%d), %d channels\n", cfg->channel, chan->center_freq, chan_cnt)); - } else + } else { +#ifdef ROAM_CHANNEL_CACHE + wlc_ssid_t ssid; + int band; + use_chan_cache = TRUE; + err = wldev_get_band(dev, &band); + if (!err) { + set_roam_band(band); + } + cfg->channel = 0; -#ifdef BCMWAPI_WPI - WL_DBG(("1. enable wapi auth\n")); - if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { - WL_DBG(("2. set wapi ie \n")); - err = wl_set_set_wapi_ie(dev, sme); - if (unlikely(err)) - return err; - } else - WL_DBG(("2. Not wapi ie \n")); -#endif + memcpy(ssid.SSID, sme->ssid, sme->ssid_len); + ssid.SSID_len = sme->ssid_len; + chan_cnt = get_roam_channel_list(cfg->channel, chanspec_list, &ssid, ioctl_version); +#else + cfg->channel = 0; +#endif /* ROAM_CHANNEL_CACHE */ + + } WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len)); WL_DBG(("3. set wapi version \n")); err = wl_set_wpa_version(dev, sme); @@ -4176,20 +3969,11 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, WL_ERR(("Invalid wpa_version\n")); return err; } -#ifdef BCMWAPI_WPI - if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) - WL_DBG(("4. WAPI Dont Set wl_set_auth_type\n")); - else { - WL_DBG(("4. wl_set_auth_type\n")); -#endif err = wl_set_auth_type(dev, sme); if (unlikely(err)) { WL_ERR(("Invalid auth type\n")); return err; } -#ifdef BCMWAPI_WPI - } -#endif err = wl_set_set_cipher(dev, sme); if (unlikely(err)) { @@ -4242,18 +4026,23 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(&ext_join_params->assoc.bssid, ðer_bcast, ETH_ALEN); ext_join_params->assoc.chanspec_num = chan_cnt; if (chan_cnt) { - u16 channel, band, bw, ctl_sb; - chanspec_t chspec; - channel = cfg->channel; - band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G - : WL_CHANSPEC_BAND_5G; - bw = WL_CHANSPEC_BW_20; - ctl_sb = WL_CHANSPEC_CTL_SB_NONE; - chspec = (channel | band | bw | ctl_sb); - ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - ext_join_params->assoc.chanspec_list[0] |= chspec; - ext_join_params->assoc.chanspec_list[0] = - wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]); + if (use_chan_cache) { + memcpy(ext_join_params->assoc.chanspec_list, chanspec_list, + sizeof(chanspec_t) * chan_cnt); + } else { + u16 channel, band, bw, ctl_sb; + chanspec_t chspec; + channel = cfg->channel; + band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G + : WL_CHANSPEC_BAND_5G; + bw = WL_CHANSPEC_BW_20; + ctl_sb = WL_CHANSPEC_CTL_SB_NONE; + chspec = (channel | band | bw | ctl_sb); + ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; + ext_join_params->assoc.chanspec_list[0] |= chspec; + ext_join_params->assoc.chanspec_list[0] = + wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]); + } } ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num); if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { @@ -4336,7 +4125,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, /* * Cancel ongoing scan to sync up with sme state machine of cfg80211. */ -#if (!defined(ESCAN_RESULT_PATCH) || defined(CUSTOMER_HW10)) +#if !defined(ESCAN_RESULT_PATCH) /* Let scan aborted by F/W */ if (cfg->scan_request) { wl_notify_escan_complete(cfg, dev, true, true); @@ -4547,12 +4336,6 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, key.algo = CRYPTO_ALGO_AES_CCM; WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - key.algo = CRYPTO_ALGO_SMS4; - WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); - break; -#endif default: WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); return -EINVAL; @@ -4669,50 +4452,10 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, val = AES_ENABLED; WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - key.algo = CRYPTO_ALGO_SMS4; - WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); - val = SMS4_ENABLED; - break; -#endif /* BCMWAPI_WPI */ -#if defined(WLFBT) && defined(WLAN_CIPHER_SUITE_PMK) - case WLAN_CIPHER_SUITE_PMK: { - int j; - wsec_pmk_t pmk; - char keystring[WSEC_MAX_PSK_LEN + 1]; - char* charptr = keystring; - uint len; - struct wl_security *sec; - - sec = wl_read_prof(cfg, dev, WL_PROF_SEC); - if (sec->wpa_auth == WLAN_AKM_SUITE_8021X) { - err = wldev_iovar_setbuf(dev, "okc_info_pmk", params->key, - WSEC_MAX_PSK_LEN / 2, keystring, sizeof(keystring), NULL); - if (err) { - /* could fail in case that 'okc' is not supported */ - WL_INFORM(("Setting 'okc_info_pmk' failed, err=%d\n", err)); - } - } - /* copy the raw hex key to the appropriate format */ - for (j = 0; j < (WSEC_MAX_PSK_LEN / 2); j++) { - sprintf(charptr, "%02x", params->key[j]); - charptr += 2; - } - len = strlen(keystring); - pmk.key_len = htod16(len); - bcopy(keystring, pmk.key, len); - pmk.flags = htod16(WSEC_PASSPHRASE); - - err = wldev_ioctl(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk), true); - if (err) - return err; - } break; -#endif /* WLFBT && WLAN_CIPHER_SUITE_PMK */ - default: - WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); - return -EINVAL; - } + default: + WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); + return -EINVAL; + } /* Set the new key/index */ if ((mode == WL_MODE_IBSS) && (val & (TKIP_ENABLED | AES_ENABLED))) { @@ -4819,7 +4562,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); return err; } - switch (WSEC_ENABLED(wsec)) { + switch (wsec & ~SES_OW_ENABLED) { case WEP_ENABLED: sec = wl_read_prof(cfg, dev, WL_PROF_SEC); if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { @@ -4838,19 +4581,6 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); break; -#ifdef BCMWAPI_WPI - case WLAN_CIPHER_SUITE_SMS4: - key.algo = CRYPTO_ALGO_SMS4; - WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); - break; -#endif -#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED) - /* to connect to mixed mode AP */ - case (AES_ENABLED | TKIP_ENABLED): /* TKIP CCMP */ - params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); - break; -#endif default: WL_ERR(("Invalid algo (0x%x)\n", wsec)); return -EINVAL; @@ -4878,7 +4608,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, s32 rate; s32 err = 0; sta_info_t *sta; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) s8 eabuf[ETHER_ADDR_STR_LEN]; #endif dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); @@ -4898,7 +4628,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, sta->idle = dtoh32(sta->idle); sta->in = dtoh32(sta->in); sinfo->inactive_time = sta->idle * 1000; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) if (sta->flags & WL_STA_ASSOC) { sinfo->filled |= STATION_INFO_CONNECTED_TIME; sinfo->connected_time = sta->in; @@ -5102,7 +4832,7 @@ static s32 wl_cfg80211_resume(struct wiphy *wiphy) return err; } -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) #else static s32 wl_cfg80211_suspend(struct wiphy *wiphy) @@ -5148,7 +4878,7 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, struct net_device *primary_dev = bcmcfg_to_prmry_ndev(cfg); if (!pmk_list) { - printf("pmk_list is NULL\n"); + printk("pmk_list is NULL\n"); return -EINVAL; } /* pmk list is supported only for STA interface i.e. primary interface @@ -5974,10 +5704,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, bool channel_type_valid, #endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3, 7, 0) */ unsigned int wait, const u8* buf, size_t len, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) bool no_cck, #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) bool dont_wait_for_ack, #endif u64 *cookie) @@ -6162,17 +5892,6 @@ wl_cfg80211_change_bss(struct wiphy *wiphy, { s32 err = 0; s32 ap_isolate = 0; -#if defined(SUPPORT_HOSTAPD_BGN_MODE) - dhd_pub_t *dhd; - s32 gmode = -1, nmode = -1; - s32 gmode_prev = -1, nmode_prev = -1; - struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); -#if defined(WL_ENABLE_P2P_IF) - if (cfg->p2p_net == dev) - dev = bcmcfg_to_prmry_ndev(cfg); -#endif - dhd = (dhd_pub_t *)(cfg->pub); -#endif /* SUPPORT_HOSTAPD_BGN_MODE */ if (params->use_cts_prot >= 0) { } @@ -6184,22 +5903,6 @@ wl_cfg80211_change_bss(struct wiphy *wiphy, } if (params->basic_rates) { -#if defined(SUPPORT_HOSTAPD_BGN_MODE) - switch ((int)(params->basic_rates[params->basic_rates_len -1])) { - case 22: /* B only , rate 11 */ - gmode = 0; - nmode = 0; - break; - case 108: /* G only , rate 54 */ - gmode = 2; - nmode = 0; - break; - default: - gmode = -1; - nmode = -1; - break; - } -#endif /* SUPPORT_HOSTAPD_BGN_MODE */ } if (params->ap_isolate >= 0) { @@ -6212,58 +5915,8 @@ wl_cfg80211_change_bss(struct wiphy *wiphy, } if (params->ht_opmode >= 0) { -#if defined(SUPPORT_HOSTAPD_BGN_MODE) - nmode = 1; - gmode = 1; - } else { - nmode = 0; -#endif /* SUPPORT_HOSTAPD_BGN_MODE */ - } - -#if defined(SUPPORT_HOSTAPD_BGN_MODE) - err = wldev_iovar_getint(dev, "nmode", &nmode_prev); - if (unlikely(err)) { - WL_ERR(("error reading nmode (%d)\n", err)); - } - if (nmode == nmode_prev) { - nmode = -1; - } - err = wldev_ioctl(dev, WLC_GET_GMODE, &gmode_prev, sizeof(gmode_prev), 0); - if (unlikely(err)) { - WL_ERR(("error reading gmode (%d)\n", err)); } - if (gmode == gmode_prev) { - gmode = -1; - } - - if (((dhd->op_mode & DHD_FLAG_HOSTAP_MODE) == DHD_FLAG_HOSTAP_MODE) && - ((gmode > -1) || (nmode > -1))) { - s32 val = 0; - - err = wldev_ioctl(dev, WLC_DOWN, &val, sizeof(s32), true); - if (unlikely(err)) - WL_ERR(("WLC_DOWN command failed:[%d]\n", err)); - if (nmode > -1) { - err = wldev_iovar_setint(dev, "nmode", nmode); - if (unlikely(err)) - WL_ERR(("nmode command failed:mode[%d]:err[%d]\n", nmode, err)); - } - - if (gmode > -1) { - err = wldev_ioctl(dev, WLC_SET_GMODE, &gmode, sizeof(s32), true); - if (unlikely(err)) - WL_ERR(("WLC_SET_GMODE command failed:mode[%d]:err[%d]\n", - gmode, err)); - } - - val = 0; - err = wldev_ioctl(dev, WLC_UP, &val, sizeof(s32), true); - if (unlikely(err)) - WL_ERR(("WLC_UP command failed:err[%d]\n", err)); - - } -#endif /* SUPPORT_HOSTAPD_BGN_MODE */ return 0; } @@ -6396,14 +6049,12 @@ wl_validate_opensecurity(struct net_device *dev, s32 bssidx) WL_ERR(("auth error %d\n", err)); return BCME_ERROR; } -#ifndef CUSTOMER_HW10 /* for WEP Support */ /* set wsec */ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); if (err < 0) { WL_ERR(("wsec error %d\n", err)); return BCME_ERROR; } -#endif /* CUSTOMER_HW10 */ /* set upper-layer auth */ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", WPA_AUTH_NONE, bssidx); @@ -6454,11 +6105,6 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) case WPA_CIPHER_AES_CCM: gval = AES_ENABLED; break; -#ifdef BCMWAPI_WPI - case WAPI_CIPHER_SMS4: - gval = SMS4_ENABLED; - break; -#endif default: WL_ERR(("No Security Info\n")); break; @@ -6483,11 +6129,6 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) case WPA_CIPHER_AES_CCM: pval = AES_ENABLED; break; -#ifdef BCMWAPI_WPI - case WAPI_CIPHER_SMS4: - pval = SMS4_ENABLED; - break; -#endif default: WL_ERR(("No Security Info\n")); } @@ -6701,230 +6342,6 @@ exit: return 0; } -#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED) -static u32 wl_get_cipher_type(uint8 type) -{ - u32 ret = 0; - switch (type) { - case WPA_CIPHER_NONE: - ret = 0; - break; - case WPA_CIPHER_WEP_40: - case WPA_CIPHER_WEP_104: - ret = WEP_ENABLED; - break; - case WPA_CIPHER_TKIP: - ret = TKIP_ENABLED; - break; - case WPA_CIPHER_AES_CCM: - ret = AES_ENABLED; - break; -#ifdef BCMWAPI_WPI - case WAPI_CIPHER_SMS4: - ret = SMS4_ENABLED; - break; -#endif - default: - WL_ERR(("No Security Info\n")); - } - return ret; -} - -static u32 wl_get_suite_auth_key_mgmt_type(uint8 type) -{ - u32 ret = 0; - switch (type) { - case RSN_AKM_NONE: - ret = WPA_AUTH_NONE; - break; - case RSN_AKM_UNSPECIFIED: - ret = WPA_AUTH_UNSPECIFIED; - break; - case RSN_AKM_PSK: - ret = WPA_AUTH_PSK; - break; - default: - WL_ERR(("No Key Mgmt Info\n")); - } - return ret; -} - -static s32 -wl_validate_wpaie_wpa2ie(struct net_device *dev, wpa_ie_fixed_t *wpaie, - bcm_tlv_t *wpa2ie, s32 bssidx) -{ - wpa_suite_mcast_t *mcast; - wpa_suite_ucast_t *ucast; - wpa_suite_auth_key_mgmt_t *mgmt; - u16 auth = 0; /* d11 open authentication */ - u16 count; - s32 err = BCME_OK; - u32 wme_bss_disable; - u16 suite_count; - u8 rsn_cap[2]; - s32 len = 0; - u32 i; - u32 wsec1, wsec2, wsec; - u32 pval = 0; - u32 gval = 0; - u32 wpa_auth = 0; - u32 wpa_auth1 = 0; - u32 wpa_auth2 = 0; - u8* ptmp; - - if (wpaie == NULL || wpa2ie == NULL) - goto exit; - - WL_DBG(("Enter \n")); - len = wpaie->length; /* value length */ - len -= WPA_IE_TAG_FIXED_LEN; - /* check for multicast cipher suite */ - if (len < WPA_SUITE_LEN) { - WL_INFORM(("no multicast cipher suite\n")); - goto exit; - } - - /* pick up multicast cipher */ - mcast = (wpa_suite_mcast_t *)&wpaie[1]; - len -= WPA_SUITE_LEN; - if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_CIPHER(mcast->type)) { - gval |= wl_get_cipher_type(mcast->type); - } - } - WL_ERR(("\nwpa ie validate\n")); - WL_ERR(("wpa ie mcast cipher = 0x%X\n", gval)); - - /* Check for unicast suite(s) */ - if (len < WPA_IE_SUITE_COUNT_LEN) { - WL_INFORM(("no unicast suite\n")); - goto exit; - } - - /* walk thru unicast cipher list and pick up what we recognize */ - ucast = (wpa_suite_ucast_t *)&mcast[1]; - count = ltoh16_ua(&ucast->count); - len -= WPA_IE_SUITE_COUNT_LEN; - for (i = 0; i < count && len >= WPA_SUITE_LEN; - i++, len -= WPA_SUITE_LEN) { - if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_CIPHER(ucast->list[i].type)) { - pval |= wl_get_cipher_type(ucast->list[i].type); - } - } - } - WL_ERR(("wpa ie ucast count =%d, cipher = 0x%X\n", count, pval)); - - /* FOR WPS , set SEC_OW_ENABLED */ - wsec1 = (pval | gval | SES_OW_ENABLED); - WL_ERR(("wpa ie wsec = 0x%X\n", wsec1)); - - len -= (count - i) * WPA_SUITE_LEN; - /* Check for auth key management suite(s) */ - if (len < WPA_IE_SUITE_COUNT_LEN) { - WL_INFORM((" no auth key mgmt suite\n")); - goto exit; - } - /* walk thru auth management suite list and pick up what we recognize */ - mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count]; - count = ltoh16_ua(&mgmt->count); - len -= WPA_IE_SUITE_COUNT_LEN; - for (i = 0; i < count && len >= WPA_SUITE_LEN; - i++, len -= WPA_SUITE_LEN) { - if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { - if (IS_WPA_AKM(mgmt->list[i].type)) { - - wpa_auth1 |= wl_get_suite_auth_key_mgmt_type(mgmt->list[i].type); - } - } - - } - WL_ERR(("wpa ie wpa_suite_auth_key_mgmt count=%d, key_mgmt = 0x%X\n", count, wpa_auth1)); - WL_ERR(("\nwpa2 ie validate\n")); - - pval = 0; - gval = 0; - len = wpa2ie->len; - /* check the mcast cipher */ - mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN]; - ptmp = mcast->oui; - gval = wl_get_cipher_type(ptmp[DOT11_OUI_LEN]); - - WL_ERR(("wpa2 ie mcast cipher = 0x%X\n", gval)); - if ((len -= WPA_SUITE_LEN) <= 0) - { - WL_ERR(("P:wpa2 ie len[%d]", len)); - return BCME_BADLEN; - } - - /* check the unicast cipher */ - ucast = (wpa_suite_ucast_t *)&mcast[1]; - suite_count = ltoh16_ua(&ucast->count); - WL_ERR((" WPA2 ucast cipher count=%d\n", suite_count)); - pval |= wl_get_cipher_type(ucast->list[0].type); - - if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) <= 0) - return BCME_BADLEN; - - WL_ERR(("wpa2 ie ucast cipher = 0x%X\n", pval)); - - /* FOR WPS , set SEC_OW_ENABLED */ - wsec2 = (pval | gval | SES_OW_ENABLED); - WL_ERR(("wpa2 ie wsec = 0x%X\n", wsec2)); - - /* check the AKM */ - mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count]; - suite_count = ltoh16_ua(&mgmt->count); - ptmp = (u8 *)&mgmt->list[0]; - wpa_auth2 = wl_get_suite_auth_key_mgmt_type(ptmp[DOT11_OUI_LEN]); - WL_ERR(("wpa ie wpa_suite_auth_key_mgmt count=%d, key_mgmt = 0x%X\n", count, wpa_auth2)); - - if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) { - rsn_cap[0] = *(u8 *)&mgmt->list[suite_count]; - rsn_cap[1] = *((u8 *)&mgmt->list[suite_count] + 1); - if (rsn_cap[0] & (RSN_CAP_16_REPLAY_CNTRS << RSN_CAP_PTK_REPLAY_CNTR_SHIFT)) { - wme_bss_disable = 0; - } else { - wme_bss_disable = 1; - } - WL_DBG(("P:rsn_cap[0]=[0x%X]:wme_bss_disabled[%d]\n", rsn_cap[0], wme_bss_disable)); - - /* set wme_bss_disable to sync RSN Capabilities */ - err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx); - if (err < 0) { - WL_ERR(("wme_bss_disable error %d\n", err)); - return BCME_ERROR; - } - } else { - WL_DBG(("There is no RSN Capabilities. remained len %d\n", len)); - } - - wsec = (wsec1 | wsec2); - wpa_auth = (wpa_auth1 | wpa_auth2); - WL_ERR(("wpa_wpa2 wsec=0x%X wpa_auth=0x%X\n", wsec, wpa_auth)); - - /* set auth */ - err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); - if (err < 0) { - WL_ERR(("auth error %d\n", err)); - return BCME_ERROR; - } - /* set wsec */ - err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); - if (err < 0) { - WL_ERR(("wsec error %d\n", err)); - return BCME_ERROR; - } - /* set upper-layer auth */ - err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); - if (err < 0) { - WL_ERR(("wpa_auth error %d\n", err)); - return BCME_ERROR; - } -exit: - return 0; -} -#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */ static s32 wl_cfg80211_bcn_validate_sec( @@ -6946,15 +6363,6 @@ wl_cfg80211_bcn_validate_sec( WL_DBG(("SoftAP: validating security")); /* If wpa2_ie or wpa_ie is present validate it */ -#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED) - if ((ies->wpa_ie != NULL && ies->wpa2_ie != NULL)) { - if (wl_validate_wpaie_wpa2ie(dev, ies->wpa_ie, ies->wpa2_ie, bssidx) < 0) { - cfg->ap_info->security_mode = false; - return BCME_ERROR; - } - } - else { -#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */ if ((ies->wpa2_ie || ies->wpa_ie) && ((wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0 || wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0))) { @@ -6988,9 +6396,6 @@ wl_cfg80211_bcn_validate_sec( ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, GFP_KERNEL); } -#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED) - } -#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */ if (!ies->wpa2_ie && !ies->wpa_ie) { wl_validate_opensecurity(dev, bssidx); cfg->ap_info->security_mode = false; @@ -7005,7 +6410,7 @@ wl_cfg80211_bcn_validate_sec( } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) static s32 wl_cfg80211_bcn_set_params( struct cfg80211_ap_settings *info, struct net_device *dev, @@ -7057,7 +6462,7 @@ static s32 wl_cfg80211_bcn_set_params( return err; } -#endif /* LINUX_VERSION >= VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif static s32 wl_cfg80211_parse_ies(u8 *ptr, u32 len, struct parsed_ies *ies) @@ -7106,6 +6511,9 @@ wl_cfg80211_bcn_bringup_ap( #ifdef DISABLE_11H_SOFTAP s32 spect = 0; #endif /* DISABLE_11H_SOFTAP */ +#ifdef MAX_GO_CLIENT_CNT + s32 bss_maxassoc = MAX_GO_CLIENT_CNT; +#endif s32 err = BCME_OK; WL_DBG(("Enter dev_role: %d\n", dev_role)); @@ -7138,6 +6546,13 @@ wl_cfg80211_bcn_bringup_ap( WL_ERR(("GO Bring up error %d\n", err)); goto exit; } +#ifdef MAX_GO_CLIENT_CNT + err = wldev_iovar_setint_bsscfg(dev, "bss_maxassoc", bss_maxassoc, bssidx); + if (unlikely(err)) { + WL_ERR(("bss_maxassoc error (%d)\n", err)); + goto exit; + } +#endif } else WL_DBG(("Bss is already up\n")); } else if ((dev_role == NL80211_IFTYPE_AP) && @@ -7158,8 +6573,7 @@ wl_cfg80211_bcn_bringup_ap( goto exit; } #ifdef DISABLE_11H_SOFTAP - err = wldev_ioctl(dev, WLC_SET_SPECT_MANAGMENT, - &spect, sizeof(s32), true); + err = wldev_ioctl(dev, WLC_SET_SPECT_MANAGMENT, &spect, sizeof(s32), true); if (err < 0) { WL_ERR(("SET SPECT_MANAGMENT error %d\n", err)); goto exit; @@ -7193,7 +6607,7 @@ exit: return err; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) s32 wl_cfg80211_parse_ap_ies( struct net_device *dev, @@ -7285,7 +6699,7 @@ wl_cfg80211_set_ies( return err; } -#endif /* LINUX_VERSION >= VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif static s32 wl_cfg80211_hostapd_sec( struct net_device *dev, @@ -7307,91 +6721,22 @@ static s32 wl_cfg80211_hostapd_sec( cfg->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL); } -#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED) - if (ies->wpa_ie != NULL && ies->wpa2_ie != NULL) { - WL_ERR(("update bss - wpa_ie and wpa2_ie is not null\n")); + if ((ies->wpa_ie != NULL || ies->wpa2_ie != NULL)) { if (!cfg->ap_info->security_mode) { /* change from open mode to security mode */ update_bss = true; - cfg->ap_info->wpa_ie = - kmemdup(ies->wpa_ie, + if (ies->wpa_ie != NULL) { + cfg->ap_info->wpa_ie = kmemdup(ies->wpa_ie, ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, GFP_KERNEL); - cfg->ap_info->rsn_ie = - kmemdup(ies->wpa2_ie, + } else { + cfg->ap_info->rsn_ie = kmemdup(ies->wpa2_ie, ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, GFP_KERNEL); - } else { - /* change from (WPA or WPA2 or WPA/WPA2) to WPA/WPA2 mixed mode */ - if (cfg->ap_info->wpa_ie) { - if (memcmp(cfg->ap_info->wpa_ie, - ies->wpa_ie, ies->wpa_ie->length + - WPA_RSN_IE_TAG_FIXED_LEN)) { - kfree(cfg->ap_info->wpa_ie); - update_bss = true; - cfg->ap_info->wpa_ie = kmemdup(ies->wpa_ie, - ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - } - else { - update_bss = true; - cfg->ap_info->wpa_ie = - kmemdup(ies->wpa_ie, - ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - if (cfg->ap_info->rsn_ie) { - if (memcmp(cfg->ap_info->rsn_ie, - ies->wpa2_ie, - ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) { - update_bss = true; - kfree(cfg->ap_info->rsn_ie); - cfg->ap_info->rsn_ie = - kmemdup(ies->wpa2_ie, - ies->wpa2_ie->len + - WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } } - else { - update_bss = true; - cfg->ap_info->rsn_ie = - kmemdup(ies->wpa2_ie, - ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - } - WL_ERR(("update_bss=%d\n", update_bss)); - if (update_bss) { - cfg->ap_info->security_mode = true; - wl_cfgp2p_bss(cfg, dev, bssidx, 0); - if (wl_validate_wpaie_wpa2ie(dev, ies->wpa_ie, - ies->wpa2_ie, bssidx) < 0) { - return BCME_ERROR; - } - wl_cfgp2p_bss(cfg, dev, bssidx, 1); - } - - } - else -#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */ - if ((ies->wpa_ie != NULL || ies->wpa2_ie != NULL)) { - if (!cfg->ap_info->security_mode) { - /* change from open mode to security mode */ - update_bss = true; - if (ies->wpa_ie != NULL) { - cfg->ap_info->wpa_ie = kmemdup(ies->wpa_ie, - ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } else { - cfg->ap_info->rsn_ie = kmemdup(ies->wpa2_ie, - ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, - GFP_KERNEL); - } - } else if (cfg->ap_info->wpa_ie) { - /* change from WPA2 mode to WPA mode */ - if (ies->wpa_ie != NULL) { + } else if (cfg->ap_info->wpa_ie) { + /* change from WPA2 mode to WPA mode */ + if (ies->wpa_ie != NULL) { update_bss = true; kfree(cfg->ap_info->rsn_ie); cfg->ap_info->rsn_ie = NULL; @@ -7514,7 +6859,7 @@ wl_cfg80211_change_station( } #endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) static s32 wl_cfg80211_start_ap( struct wiphy *wiphy, @@ -7531,6 +6876,15 @@ wl_cfg80211_start_ap( if (dev == bcmcfg_to_prmry_ndev(cfg)) { WL_DBG(("Start AP req on primary iface: Softap\n")); dev_role = NL80211_IFTYPE_AP; + if (!cfg->ap_info) { + if ((cfg->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) { + WL_ERR(("%s: struct ap_info re-allocated\n", __FUNCTION__)); + } else { + WL_ERR(("%s: struct ap_info re-allocation failed\n", __FUNCTION__)); + err = -ENOMEM; + goto fail; + } + } } #if defined(WL_ENABLE_P2P_IF) else if (dev == cfg->p2p_net) { @@ -7554,14 +6908,14 @@ wl_cfg80211_start_ap( if (!check_dev_role_integrity(cfg, dev_role)) goto fail; -#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && !defined(WL_COMPAT_WIRELESS)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) if ((err = wl_cfg80211_set_channel(wiphy, dev, dev->ieee80211_ptr->preset_chandef.chan, NL80211_CHAN_HT20) < 0)) { WL_ERR(("Set channel failed \n")); goto fail; } -#endif /* ((LINUX_VERSION >= VERSION(3, 6, 0) && !WL_COMPAT_WIRELESS) */ +#endif if ((err = wl_cfg80211_bcn_set_params(info, dev, dev_role, bssidx)) < 0) { @@ -7921,12 +7275,29 @@ fail: return err; } -#endif /* LINUX_VERSION < VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif #ifdef WL_SCHED_SCAN #define PNO_TIME 30 #define PNO_REPEAT 4 #define PNO_FREQ_EXPO_MAX 2 +static bool +is_ssid_in_list(struct cfg80211_ssid *ssid, struct cfg80211_ssid *ssid_list, int count) +{ + int i; + + if (!ssid || !ssid_list) + return FALSE; + + for (i = 0; i < count; i++) { + if (ssid->ssid_len == ssid_list[i].ssid_len) { + if (strncmp(ssid->ssid, ssid_list[i].ssid, ssid->ssid_len) == 0) + return TRUE; + } + } + return FALSE; +} + static int wl_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev, @@ -7935,10 +7306,11 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, ushort pno_time = PNO_TIME; int pno_repeat = PNO_REPEAT; int pno_freq_expo_max = PNO_FREQ_EXPO_MAX; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; + wlc_ssid_ext_t ssids_local[MAX_PFN_LIST_COUNT]; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); struct cfg80211_ssid *ssid = NULL; - int ssid_count = 0; + struct cfg80211_ssid *hidden_ssid_list = NULL; + int ssid_cnt = 0; int i; int ret = 0; @@ -7957,30 +7329,29 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, memset(&ssids_local, 0, sizeof(ssids_local)); - if (request->n_match_sets > 0) { - for (i = 0; i < request->n_match_sets; i++) { - ssid = &request->match_sets[i].ssid; - memcpy(ssids_local[i].SSID, ssid->ssid, ssid->ssid_len); - ssids_local[i].SSID_len = ssid->ssid_len; - WL_PNO((">>> PNO filter set for ssid (%s) \n", ssid->ssid)); - ssid_count++; - } - } - - if (request->n_ssids > 0) { - for (i = 0; i < request->n_ssids; i++) { - /* Active scan req for ssids */ - WL_PNO((">>> Active scan req for ssid (%s) \n", request->ssids[i].ssid)); - - /* match_set ssids is a supert set of n_ssid list, so we need - * not add these set seperately - */ + if (request->n_ssids > 0) + hidden_ssid_list = request->ssids; + + for (i = 0; i < request->n_match_sets && ssid_cnt < MAX_PFN_LIST_COUNT; i++) { + ssid = &request->match_sets[i].ssid; + /* No need to include null ssid */ + if (ssid->ssid_len) { + memcpy(ssids_local[ssid_cnt].SSID, ssid->ssid, ssid->ssid_len); + ssids_local[ssid_cnt].SSID_len = ssid->ssid_len; + if (is_ssid_in_list(ssid, hidden_ssid_list, request->n_ssids)) { + ssids_local[ssid_cnt].hidden = TRUE; + WL_PNO((">>> PNO hidden SSID (%s) \n", ssid->ssid)); + } else { + ssids_local[ssid_cnt].hidden = FALSE; + WL_PNO((">>> PNO non-hidden SSID (%s) \n", ssid->ssid)); + } + ssid_cnt++; } } - if (ssid_count) { - if ((ret = dhd_dev_pno_set_for_ssid(dev, ssids_local, request->n_match_sets, - pno_time, pno_repeat, pno_freq_expo_max, NULL, 0)) < 0) { + if (ssid_cnt) { + if ((ret = dhd_dev_pno_set_for_ssid(dev, ssids_local, ssid_cnt, pno_time, + pno_repeat, pno_freq_expo_max, NULL, 0)) < 0) { WL_ERR(("PNO setup failed!! ret=%d \n", ret)); return -EINVAL; } @@ -8259,17 +7630,17 @@ static struct cfg80211_ops wl_cfg80211_ops = { .mgmt_tx = wl_cfg80211_mgmt_tx, .mgmt_frame_register = wl_cfg80211_mgmt_frame_register, .change_bss = wl_cfg80211_change_bss, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) .set_channel = wl_cfg80211_set_channel, -#endif /* ((LINUX_VERSION < VERSION(3, 6, 0)) || WL_COMPAT_WIRELESS */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(WL_COMPAT_WIRELESS) +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) .set_beacon = wl_cfg80211_add_set_beacon, .add_beacon = wl_cfg80211_add_set_beacon, #else .change_beacon = wl_cfg80211_change_beacon, .start_ap = wl_cfg80211_start_ap, .stop_ap = wl_cfg80211_stop_ap, -#endif /* LINUX_VERSION < KERNEL_VERSION(3,4,0) && !WL_COMPAT_WIRELESS */ +#endif #ifdef WL_SCHED_SCAN .sched_scan_start = wl_cfg80211_sched_scan_start, .sched_scan_stop = wl_cfg80211_sched_scan_stop, @@ -8280,9 +7651,9 @@ static struct cfg80211_ops wl_cfg80211_ops = { .change_station = wl_cfg80211_change_station, .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait, #endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VERSION >= (3,2,0) */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) .tdls_oper = wl_cfg80211_tdls_oper, -#endif /* LINUX_VERSION > VERSION(3, 2, 0) || WL_COMPAT_WIRELESS */ +#endif #ifdef WL_SUPPORT_ACS .dump_survey = wl_cfg80211_dump_survey, #endif /* WL_SUPPORT_ACS */ @@ -8360,7 +7731,7 @@ static const struct wiphy_wowlan_support brcm_wowlan_support = { static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, void *context) { s32 err = 0; -#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) || defined(WL_COMPAT_WIRELESS)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) dhd_pub_t *dhd = (dhd_pub_t *)context; BCM_REFERENCE(dhd); @@ -8426,12 +7797,12 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev #endif /* !WL_POWERSAVE_DISABLED */ wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && !defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS | #endif WIPHY_FLAG_4ADDR_STATION; -#if (defined(ROAM_ENABLE) || defined(BCMFW_ROAM_ENABLE)) && ((LINUX_VERSION_CODE >= \ - KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS)) && !0 +#if (defined(ROAM_ENABLE) || defined(BCMFW_ROAM_ENABLE)) && (LINUX_VERSION_CODE >= \ + KERNEL_VERSION(3, 2, 0)) /* Please use supplicant ver >= 76 if FW_ROAM is enabled * If driver advertises FW_ROAM, older supplicant wouldn't * send the BSSID & Freq in the connect req command. This @@ -8442,7 +7813,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev */ wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_OFFCHAN_TX; #endif @@ -8458,7 +7829,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->max_acl_mac_addrs = MAX_NUM_MAC_FILT; #endif -#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) || defined(WL_COMPAT_WIRELESS)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) /* Supplicant distinguish between the SoftAP mode and other * modes (e.g. P2P, WPS, HS2.0) when it builds the probe * response frame from Supplicant MR1 and Kernel 3.4.0 or @@ -8477,7 +7848,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->reg_notifier = wl_cfg80211_reg_notifier; #endif /* CONFIG_CFG80211_INTERNAL_REGDB */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; #endif @@ -8503,11 +7874,14 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev #endif wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); - WL_DBG(("Registering Vendor80211)\n")); - err = cfgvendor_attach(wdev->wiphy); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) + WL_ERR(("Registering Vendor80211\n")); + err = wl_cfgvendor_attach(wdev->wiphy); if (unlikely(err < 0)) { WL_ERR(("Couldn not attach vendor commands (%d)\n", err)); } +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ + /* Now we can register wiphy with cfg80211 module */ err = wiphy_register(wdev->wiphy); @@ -8534,7 +7908,9 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg) } wiphy = wdev->wiphy; - cfgvendor_detach(wdev->wiphy); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) + wl_cfgvendor_detach(wdev->wiphy); +#endif /* if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ wiphy_unregister(wdev->wiphy); wdev->wiphy->dev.parent = NULL; @@ -8555,12 +7931,22 @@ static s32 wl_inform_bss(struct bcm_cfg80211 *cfg) bss_list = cfg->bss_list; WL_DBG(("scanned AP count (%d)\n", bss_list->count)); +#ifdef ROAM_CHANNEL_CACHE + reset_roam_cache(); +#endif /* ROAM_CHANNEL_CACHE */ bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { +#ifdef ROAM_CHANNEL_CACHE + add_roam_cache(bi); +#endif /* ROAM_CHANNEL_CACHE */ err = wl_inform_single_bss(cfg, bi, false); if (unlikely(err)) break; } +#ifdef ROAM_CHANNEL_CACHE + /* print_roam_cache(); */ + update_roam_cache(cfg, ioctl_version); +#endif /* ROAM_CHANNEL_CACHE */ return err; } @@ -8624,7 +8010,7 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, struct wl_bss_info *bi offsetof(struct wl_cfg80211_bss_info, frame_buf)); notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) + wl_get_ielen(cfg); -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) freq = ieee80211_channel_to_frequency(notif_bss_info->channel); (void)band->band; #else @@ -8753,8 +8139,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, u32 reason = ntoh32(e->reason); u32 len = ntoh32(e->datalen); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) \ - && !defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) bool isfree = false; u8 *mgmt_frame; u8 bsscfgidx = e->bsscfgidx; @@ -8770,7 +8155,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, channel_info_t ci; #else struct station_info sinfo; -#endif /* (LINUX_VERSION < VERSION(3,2,0)) && !WL_CFG80211_STA_EVENT && !WL_COMPAT_WIRELESS */ +#endif WL_DBG(("event %d status %d reason %d\n", event, ntoh32(e->status), reason)); /* if link down, bsscfg is disabled. */ @@ -8787,8 +8172,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, bcmevent_get_name(event), event, ntoh32(e->status), reason)); } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) \ - && !defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) WL_DBG(("Enter \n")); if (!len && (event == WLC_E_DEAUTH)) { len = 2; /* reason code field */ @@ -8851,7 +8235,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, kfree(body); return -EINVAL; } -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) freq = ieee80211_channel_to_frequency(channel); (void)band->band; #else @@ -8865,23 +8249,23 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, isfree = true; if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); #else cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -#endif /* LINUX_VERSION >= VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif } else if (event == WLC_E_DISASSOC_IND) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); #else cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -#endif /* LINUX_VERSION >= VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); #else cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -#endif /* LINUX_VERSION >= VERSION(3,4,0) || WL_COMPAT_WIRELESS */ +#endif } exit: @@ -8906,7 +8290,7 @@ exit: } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); } -#endif /* LINUX_VERSION < VERSION(3,2,0) && !WL_CFG80211_STA_EVENT && !WL_COMPAT_WIRELESS */ +#endif return err; } @@ -9017,7 +8401,7 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, wl_link_up(cfg); act = true; if (!wl_get_drv_status(cfg, DISCONNECTING, ndev)) { - printf("wl_bss_connect_done succeeded with " MACDBG "\n", + printk("wl_bss_connect_done succeeded with " MACDBG "\n", MAC2STRDBG((u8*)(&e->addr))); wl_bss_connect_done(cfg, ndev, e, data, true); WL_DBG(("joined in BSS network \"%s\"\n", @@ -9039,7 +8423,7 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, /* WLAN_REASON_UNSPECIFIED is used for hang up event in Android */ reason = (reason == WLAN_REASON_UNSPECIFIED)? 0 : reason; - printf("link down if %s may call cfg80211_disconnected. " + printk("link down if %s may call cfg80211_disconnected. " "event : %d, reason=%d from " MACDBG "\n", ndev->name, event, ntoh32(e->reason), MAC2STRDBG((u8*)(&e->addr))); @@ -9071,7 +8455,7 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } } else if (wl_get_drv_status(cfg, CONNECTING, ndev)) { - printf("link down, during connecting\n"); + printk("link down, during connecting\n"); #ifdef ESCAN_RESULT_PATCH if ((memcmp(connect_req_bssid, broad_bssid, ETHER_ADDR_LEN) == 0) || (memcmp(&e->addr, broad_bssid, ETHER_ADDR_LEN) == 0) || @@ -9087,7 +8471,7 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, complete(&cfg->iface_disable); } else if (wl_is_nonetwork(cfg, e)) { - printf("connect failed event=%d e->status %d e->reason %d \n", + printk("connect failed event=%d e->status %d e->reason %d \n", event, (int)ntoh32(e->status), (int)ntoh32(e->reason)); /* Clean up any pending scan request */ if (cfg->scan_request) @@ -9104,64 +8488,6 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, return err; } -void wl_cfg80211_set_rmc_pid(int pid) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - if (pid > 0) - cfg->rmc_event_pid = pid; - WL_DBG(("set pid for rmc event : pid=%d\n", pid)); -} - -#ifdef WLAIBSS -void wl_cfg80211_set_txfail_pid(int pid) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - if (pid > 0) - cfg->aibss_txfail_pid = pid; - WL_DBG(("set pid for aibss fail event : pid=%d\n", pid)); -} - -static s32 -wl_notify_aibss_txfail(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) -{ - u32 evt = ntoh32(e->event_type); - int ret = -1; - - if (cfg->aibss_txfail_pid != 0) { - ret = wl_netlink_send_msg(cfg->aibss_txfail_pid, AIBSS_EVENT_TXFAIL, - cfg->aibss_txfail_seq++, (void *)&e->addr, ETHER_ADDR_LEN); - } - - WL_DBG(("txfail : evt=%d, pid=%d, ret=%d, mac=" MACF "\n", - evt, cfg->aibss_txfail_pid, ret, ETHERP_TO_MACF(&e->addr))); - return ret; -} -#endif /* WLAIBSS */ - -static s32 -wl_notify_rmc_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) -{ - u32 evt = ntoh32(e->event_type); - u32 reason = ntoh32(e->reason); - int ret = -1; - - switch (reason) { - case WLC_E_REASON_RMC_AR_LOST: - case WLC_E_REASON_RMC_AR_NO_ACK: - if (cfg->rmc_event_pid != 0) { - ret = wl_netlink_send_msg(cfg->rmc_event_pid, - RMC_EVENT_LEADER_CHECK_FAIL, - cfg->rmc_event_seq++, NULL, 0); - } - break; - default: - break; - } - WL_DBG(("rmcevent : evt=%d, pid=%d, ret=%d\n", evt, cfg->rmc_event_pid, ret)); - return ret; -} static s32 wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, @@ -9269,8 +8595,20 @@ static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev) static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, size_t *join_params_size) { +#ifndef ROAM_CHANNEL_CACHE chanspec_t chanspec = 0; +#endif + if (ch != 0) { +#ifdef ROAM_CHANNEL_CACHE + int n_channels; + + n_channels = get_roam_channel_list(ch, join_params->params.chanspec_list, + &join_params->ssid, ioctl_version); + join_params->params.chanspec_num = htod32(n_channels); + *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + + join_params->params.chanspec_num * sizeof(chanspec_t); +#else join_params->params.chanspec_num = 1; join_params->params.chanspec_list[0] = ch; @@ -9292,6 +8630,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); +#endif /* ROAM_CHANNEL_CACHE */ WL_DBG(("join_params->params.chanspec_list[0]= %X, %d channels\n", join_params->params.chanspec_list[0], join_params->params.chanspec_num)); @@ -9312,6 +8651,10 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 err = 0; struct wiphy *wiphy; u32 channel; +#ifdef ROAM_CHANNEL_CACHE + struct ieee80211_channel *cur_channel; + u32 freq, band; +#endif /* ROAM_CHANNEL_CACHE */ wiphy = bcmcfg_to_wiphy(cfg); @@ -9350,6 +8693,16 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, beacon_interval = cpu_to_le16(bi->beacon_period); } else { WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); +#ifdef ROAM_CHANNEL_CACHE +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) + freq = ieee80211_channel_to_frequency(channel); +#else + band = (channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + freq = ieee80211_channel_to_frequency(channel, band); +#endif + cur_channel = ieee80211_get_channel(wiphy, freq); + bss->channel = cur_channel; +#endif /* ROAM_CHANNEL_CACHE */ #if defined(WL_CFG80211_P2P_DEV_IF) ie = (u8 *)bss->ies->data; ie_len = bss->ies->len; @@ -9400,19 +8753,14 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, struct wl_connect_info *conn_info = wl_to_conn(cfg); s32 err = 0; u8 *curbssid; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); struct ieee80211_supported_band *band; struct ieee80211_channel *notify_channel = NULL; u32 *channel; u32 freq; -#endif /* LINUX_VERSION > 2.6.39 || WL_COMPAT_WIRELESS */ +#endif -#ifdef WLFBT - uint32 data_len = 0; - if (data) - data_len = ntoh32(e->datalen); -#endif /* WLFBT */ wl_get_assoc_ies(cfg, ndev); wl_update_prof(cfg, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); @@ -9420,7 +8768,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, wl_update_bss_info(cfg, ndev, true); wl_update_pmklist(ndev, cfg->pmk_list, err); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) /* channel info for cfg80211_roamed introduced in 2.6.39-rc1 */ channel = (u32 *)wl_read_prof(cfg, ndev, WL_PROF_CHAN); if (*channel <= CH_MAX_2G_CHANNEL) @@ -9429,21 +8777,15 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, band = wiphy->bands[IEEE80211_BAND_5GHZ]; freq = ieee80211_channel_to_frequency(*channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); -#endif /* LINUX_VERSION > 2.6.39 || WL_COMPAT_WIRELESS */ -#ifdef WLFBT - /* back up the given FBT key for the further supplicant request, - * currently not checking the FBT is enabled for current BSS in DHD, - * because the supplicant decides to take it or not. - */ - if (data && (data_len == FBT_KEYLEN)) { - memcpy(cfg->fbt_key, data, FBT_KEYLEN); - } -#endif /* WLFBT */ - printf("wl_bss_roaming_done succeeded to " MACDBG "\n", +#endif + printk("wl_bss_roaming_done succeeded to " MACDBG "\n", MAC2STRDBG((u8*)(&e->addr))); +#ifdef PCIE_FULL_DONGLE + wl_roam_flowring_cleanup(cfg); +#endif /* PCIE_FULL_DONGLE */ cfg80211_roamed(ndev, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || defined(WL_COMPAT_WIRELESS) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) notify_channel, #endif curbssid, @@ -9462,9 +8804,10 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, { struct wl_connect_info *conn_info = wl_to_conn(cfg); struct wl_security *sec = wl_read_prof(cfg, ndev, WL_PROF_SEC); -#if defined(CUSTOM_SET_CPUCORE) +#if (defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION)) || \ + defined(CUSTOM_SET_CPUCORE) dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); -#endif +#endif /* (ROAM_ENABLE && ROAM_AP_ENV_DETECTION) || CUSTOM_SET_CPUCORE */ s32 err = 0; u8 *curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID); if (!sec) { @@ -9501,6 +8844,11 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, wl_update_bss_info(cfg, ndev, false); wl_update_pmklist(ndev, cfg->pmk_list, err); wl_set_drv_status(cfg, CONNECTED, ndev); +#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) + if (dhd->roam_env_detection) + wldev_iovar_setint(ndev, "roam_env_detection", + AP_ENV_INDETERMINATE); +#endif /* ROAM_AP_ENV_DETECTION */ if (ndev != bcmcfg_to_prmry_ndev(cfg)) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) init_completion(&cfg->iface_disable); @@ -9613,6 +8961,82 @@ wl_notify_pfn_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } #endif /* PNO_SUPPORT */ +#ifdef GSCAN_SUPPORT +static s32 +wl_notify_gscan_event(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, + const wl_event_msg_t *e, void *data) +{ + s32 err = 0; + u32 event = be32_to_cpu(e->event_type); + void *ptr; + int send_evt_bytes = 0; + int batch_event_result_dummy = 0; + struct net_device *ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); + struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); + u32 len = ntoh32(e->datalen); + + switch (event) { + case WLC_E_PFN_SWC: + ptr = dhd_dev_swc_scan_event(ndev, data, &send_evt_bytes); + if (send_evt_bytes) { + wl_cfgvendor_send_async_event(wiphy, ndev, + GOOGLE_GSCAN_SIGNIFICANT_EVENT, ptr, send_evt_bytes); + kfree(ptr); + } + break; + case WLC_E_PFN_BEST_BATCHING: + err = dhd_dev_retrieve_batch_scan(ndev); + if (err < 0) { + WL_ERR(("Batch retrieval already in progress %d\n", err)); + } else { + wl_cfgvendor_send_async_event(wiphy, ndev, + GOOGLE_GSCAN_BATCH_SCAN_EVENT, + &batch_event_result_dummy, sizeof(int)); + } + break; + case WLC_E_PFN_SCAN_COMPLETE: + batch_event_result_dummy = WIFI_SCAN_COMPLETE; + wl_cfgvendor_send_async_event(wiphy, ndev, + GOOGLE_SCAN_COMPLETE_EVENT, + &batch_event_result_dummy, sizeof(int)); + break; + case WLC_E_PFN_BSSID_NET_FOUND: + ptr = dhd_dev_hotlist_scan_event(ndev, data, &send_evt_bytes, + HOTLIST_FOUND); + if (ptr) { + wl_cfgvendor_send_hotlist_event(wiphy, ndev, + ptr, send_evt_bytes, GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT); + dhd_dev_gscan_hotlist_cache_cleanup(ndev, HOTLIST_FOUND); + } + break; + case WLC_E_PFN_BSSID_NET_LOST: + /* WLC_E_PFN_BSSID_NET_LOST is conflict shared with WLC_E_PFN_SCAN_ALLGONE + * We currently do not use WLC_E_PFN_SCAN_ALLGONE, so if we get it, ignore + */ + if (len) { + ptr = dhd_dev_hotlist_scan_event(ndev, data, &send_evt_bytes, + HOTLIST_LOST); + if (ptr) { + wl_cfgvendor_send_hotlist_event(wiphy, ndev, + ptr, send_evt_bytes, GOOGLE_GSCAN_GEOFENCE_LOST_EVENT); + dhd_dev_gscan_hotlist_cache_cleanup(ndev, HOTLIST_LOST); + } + } + break; + case WLC_E_PFN_GSCAN_FULL_RESULT: + ptr = dhd_dev_process_full_gscan_result(ndev, data, &send_evt_bytes); + if (ptr) { + wl_cfgvendor_send_async_event(wiphy, ndev, + GOOGLE_SCAN_FULL_RESULTS_EVENT, ptr, send_evt_bytes); + kfree(ptr); + } + break; + + } + return err; +} +#endif /* GSCAN_SUPPORT */ + static s32 wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data) @@ -9796,7 +9220,7 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, WL_ERR(("No valid band")); return -EINVAL; } -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) freq = ieee80211_channel_to_frequency(channel); (void)band->band; #else @@ -9830,13 +9254,6 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, (void) p2p_act_frm; } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { -#ifdef WL_SDO - if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { - WL_ERR(("SD offload is in progress. Don't report the" - "frame via rx_mgmt path\n")); - goto exit; - } -#endif sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) (&mgmt_frame[DOT11_MGMT_HDR_LEN]); @@ -10072,6 +9489,9 @@ wl_notify_sched_scan_results(struct bcm_cfg80211 *cfg, struct net_device *ndev, } wl_set_drv_status(cfg, SCANNING, ndev); +#ifdef CUSTOM_SET_SHORT_DWELL_TIME + net_set_short_dwell_time(ndev, FALSE); +#endif #if FULL_ESCAN_ON_PFN_NET_FOUND WL_PNO((">>> Doing Full ESCAN on PNO event\n")); err = wl_do_escan(cfg, wiphy, ndev, NULL); @@ -10144,26 +9564,21 @@ static void wl_init_event_handler(struct bcm_cfg80211 *cfg) #ifdef PNO_SUPPORT cfg->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status; #endif /* PNO_SUPPORT */ -#ifdef WL_SDO - cfg->evt_handler[WLC_E_SERVICE_FOUND] = wl_svc_resp_handler; - cfg->evt_handler[WLC_E_P2PO_ADD_DEVICE] = wl_notify_device_discovery; - cfg->evt_handler[WLC_E_P2PO_DEL_DEVICE] = wl_notify_device_discovery; -#endif +#ifdef GSCAN_SUPPORT + cfg->evt_handler[WLC_E_PFN_BEST_BATCHING] = wl_notify_gscan_event; + cfg->evt_handler[WLC_E_PFN_SCAN_COMPLETE] = wl_notify_gscan_event; + cfg->evt_handler[WLC_E_PFN_GSCAN_FULL_RESULT] = wl_notify_gscan_event; + cfg->evt_handler[WLC_E_PFN_SWC] = wl_notify_gscan_event; + cfg->evt_handler[WLC_E_PFN_BSSID_NET_FOUND] = wl_notify_gscan_event; + cfg->evt_handler[WLC_E_PFN_BSSID_NET_LOST] = wl_notify_gscan_event; +#endif /* GSCAN_SUPPORT */ #ifdef WLTDLS cfg->evt_handler[WLC_E_TDLS_PEER_EVENT] = wl_tdls_event_handler; #endif /* WLTDLS */ cfg->evt_handler[WLC_E_BSSID] = wl_notify_roaming_status; -#ifdef WLAIBSS - cfg->evt_handler[WLC_E_AIBSS_TXFAIL] = wl_notify_aibss_txfail; -#endif /* WLAIBSS */ #ifdef BT_WIFI_HANDOVER cfg->evt_handler[WLC_E_BT_WIFI_HANDOVER_REQ] = wl_notify_bt_wifi_handover_req; #endif -#ifdef WL_NAN - cfg->evt_handler[WLC_E_NAN] = wl_cfgnan_notify_nan_status; - cfg->evt_handler[WLC_E_PROXD] = wl_cfgnan_notify_proxd_status; -#endif /* WL_NAN */ - cfg->evt_handler[WLC_E_RMC_EVENT] = wl_notify_rmc_status; } #if defined(STATIC_WL_PRIV_STRUCT) @@ -10497,11 +9912,6 @@ static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg, wl_clr_p2p_status(cfg, SCANNING); wl_clr_drv_status(cfg, SCANNING, dev); spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags); -#ifdef WL_SDO - if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS) && !in_atomic()) { - wl_cfg80211_resume_sdo(ndev, cfg); - } -#endif return err; } @@ -10599,11 +10009,6 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, int cur_len = WL_SCAN_RESULTS_FIXED_SIZE; list = wl_escan_get_buf(cfg, FALSE); if (scan_req_match(cfg)) { -#ifdef WL_HOST_BAND_MGMT - s32 channel = 0; - s32 channel_band = 0; - chanspec_t chspec; -#endif /* WL_HOST_BAND_MGMT */ /* p2p scan && allow only probe response */ if ((cfg->p2p->search_state != WL_P2P_DISC_ST_SCAN) && (bi->flags & WL_BSS_FLAGS_FROM_BEACON)) @@ -10614,19 +10019,6 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, " response/beacon\n")); goto exit; } -#ifdef WL_HOST_BAND_MGMT - chspec = wl_chspec_driver_to_host(bi->chanspec); - channel = wf_chspec_ctlchan(chspec); - channel_band = CHSPEC2WLC_BAND(chspec); - - if ((cfg->curr_band == WLC_BAND_5G) && - (channel_band == WLC_BAND_2G)) { - /* Avoid sending the GO results in band conflict */ - if (wl_cfgp2p_retreive_p2pattrib(p2p_ie, - P2P_SEID_GROUP_ID) != NULL) - goto exit; - } -#endif /* WL_HOST_BAND_MGMT */ } for (i = 0; i < list->count; i++) { bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length)) @@ -10927,45 +10319,23 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_ } for_each_ndev(cfg, iter, next) { - if (!wl_get_drv_status(cfg, CONNECTED, iter->ndev)) - continue; if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, sizeof(pm), true)) != 0) { if (err == -ENODEV) WL_DBG(("%s:netdev not ready\n", iter->ndev->name)); else WL_ERR(("%s:error (%d)\n", iter->ndev->name, err)); + } else { wl_cfg80211_update_power_mode(iter->ndev); } } } else { - /* add PM Enable timer to go to power save mode - * if supplicant control pm mode, it will be cleared or - * updated by wl_cfg80211_set_power_mgmt() if not - for static IP & HW4 P2P, - * PM will be configured when timer expired - */ - /* - * before calling pm_enable_timer, we need to set PM -1 for all ndev + * Re-enable PM2 mode for static IP and roaming event */ - pm = PM_OFF; - if (!_net_info->pm_block) { - for_each_ndev(cfg, iter, next) { - if (iter->pm_restore) - continue; - /* Save the current power mode */ - err = wldev_ioctl(iter->ndev, WLC_GET_PM, &iter->pm, - sizeof(iter->pm), false); - WL_DBG(("%s:power save %s\n", iter->ndev->name, - iter->pm ? "enabled" : "disabled")); - if (!err && iter->pm) { - iter->pm_restore = true; - } - } - } + pm = PM_FAST; + for_each_ndev(cfg, iter, next) { - if (!wl_get_drv_status(cfg, CONNECTED, iter->ndev)) - continue; if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, sizeof(pm), true)) != 0) { if (err == -ENODEV) @@ -10978,9 +10348,6 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_ if (cfg->pm_enable_work_on) { wl_add_remove_pm_enable_work(cfg, FALSE, WL_HANDLER_DEL); } - - cfg->pm_enable_work_on = true; - wl_add_remove_pm_enable_work(cfg, TRUE, WL_HANDLER_NOTUSE); } #if defined(WLTDLS) #if defined(DISABLE_TDLS_IN_P2P) @@ -11099,7 +10466,7 @@ static void wl_deinit_priv(struct bcm_cfg80211 *cfg) } } -#if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT) +#if defined(WL_ENABLE_P2P_IF) static s32 wl_cfg80211_attach_p2p(void) { struct bcm_cfg80211 *cfg = g_bcm_cfg; @@ -11126,25 +10493,21 @@ static s32 wl_cfg80211_detach_p2p(void) } else wdev = cfg->p2p_wdev; -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT if (!wdev) { WL_ERR(("Invalid Ptr\n")); return -EINVAL; } -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ wl_cfgp2p_unregister_ndev(cfg); cfg->p2p_wdev = NULL; cfg->p2p_net = NULL; -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT WL_DBG(("Freeing 0x%08x \n", (unsigned int)wdev)); kfree(wdev); -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ return 0; } -#endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */ +#endif s32 wl_cfg80211_attach_post(struct net_device *ndev) { @@ -11277,11 +10640,11 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *context) g_bcm_cfg = cfg; -#if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT) +#if defined(WL_ENABLE_P2P_IF) err = wl_cfg80211_attach_p2p(); if (err) goto cfg80211_attach_out; -#endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */ +#endif return err; @@ -11323,9 +10686,9 @@ void wl_cfg80211_detach(void *para) #if defined(WL_CFG80211_P2P_DEV_IF) wl_cfgp2p_del_p2p_disc_if(cfg->p2p_wdev, cfg); #endif /* WL_CFG80211_P2P_DEV_IF */ -#if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT) +#if defined(WL_ENABLE_P2P_IF) wl_cfg80211_detach_p2p(); -#endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */ +#endif wl_cfg80211_ibss_vsie_free(cfg); wl_deinit_priv(cfg); @@ -11425,11 +10788,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) } if (ndev != bcmcfg_to_prmry_ndev(cfg) && cfg->p2p_supported) { - if ((cfg->bss_cfgdev) && - (ndev == cfgdev_to_wlc_ndev(cfg->bss_cfgdev, cfg))) { - /* Event is corresponding to the secondary STA interface */ - WL_DBG(("DualSta event (%d), proceed to enqueue it \n", event_type)); - } else if (ndev != wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION) && + if (ndev != wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION) && #if defined(WL_ENABLE_P2P_IF) (ndev != (cfg->p2p_net ? cfg->p2p_net : wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE))) && @@ -11753,7 +11112,7 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap) else index = *n_cnt; if (index < array_size) { -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) band_chan_arr[index].center_freq = ieee80211_channel_to_frequency(channel); #else @@ -11936,9 +11295,6 @@ s32 wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) static s32 __wl_cfg80211_up(struct bcm_cfg80211 *cfg) { s32 err = 0; -#ifdef WL_HOST_BAND_MGMT - s32 ret = 0; -#endif /* WL_HOST_BAND_MGMT */ struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg); struct wireless_dev *wdev = ndev->ieee80211_ptr; @@ -11967,28 +11323,6 @@ static s32 __wl_cfg80211_up(struct bcm_cfg80211 *cfg) err = dhd_monitor_init(cfg->pub); -#ifdef WL_HOST_BAND_MGMT - /* By default the curr_band is initialized to BAND_AUTO */ - if ((ret = wl_cfg80211_set_band(ndev, WLC_BAND_AUTO)) < 0) { - if (ret == BCME_UNSUPPORTED) { - /* Don't fail the initialization, lets just - * fall back to the original method - */ - WL_ERR(("WL_HOST_BAND_MGMT defined, " - "but roam_band iovar not supported \n")); - } else { - WL_ERR(("roam_band failed. ret=%d", ret)); - err = -1; - } - } -#endif /* WL_HOST_BAND_MGMT */ -#if defined(DHCP_SCAN_SUPPRESS) - /* wlan scan_supp timer and work thread info */ - init_timer(&cfg->scan_supp_timer); - cfg->scan_supp_timer.data = (ulong)cfg; - cfg->scan_supp_timer.function = wl_cfg80211_scan_supp_timerfunc; - INIT_WORK(&cfg->wlan_work, wl_cfg80211_work_handler); -#endif /* DHCP_SCAN_SUPPRESS */ INIT_DELAYED_WORK(&cfg->pm_enable_work, wl_cfg80211_work_handler); wl_set_drv_status(cfg, READY, ndev); return err; @@ -12000,10 +11334,9 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) unsigned long flags; struct net_info *iter, *next; struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg); -#if defined(WL_CFG80211) && (defined(WL_ENABLE_P2P_IF)|| \ - defined(WL_NEWCFG_PRIVCMD_SUPPORT)) +#if defined(WL_CFG80211) && defined(WL_ENABLE_P2P_IF) struct net_device *p2p_net = cfg->p2p_net; -#endif /* WL_CFG80211 && (WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT) */ +#endif u32 bssidx = 0; #ifdef PROP_TXSTATUS_VSDB #if defined(BCMSDIO) @@ -12014,10 +11347,6 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) /* Delete pm_enable_work */ wl_add_remove_pm_enable_work(cfg, FALSE, WL_HANDLER_DEL); -#ifdef WL_NAN - wl_cfgnan_stop_handler(ndev, g_bcm_cfg, NULL, NULL); -#endif /* WL_NAN */ - if (cfg->p2p_supported) { wl_clr_p2p_status(cfg, GO_NEG_PHASE); #ifdef PROP_TXSTATUS_VSDB @@ -12035,14 +11364,6 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) #endif /* PROP_TXSTATUS_VSDB */ } -#if defined(DHCP_SCAN_SUPPRESS) - /* Force clear of scan_suppress */ - if (cfg->scan_suppressed) - wl_cfg80211_scan_suppress(ndev, 0); - if (timer_pending(&cfg->scan_supp_timer)) - del_timer_sync(&cfg->scan_supp_timer); - cancel_work_sync(&cfg->wlan_work); -#endif /* DHCP_SCAN_SUPPRESS */ /* If primary BSS is operational (for e.g SoftAP), bring it down */ if (!(wl_cfgp2p_find_idx(cfg, ndev, &bssidx)) && @@ -12057,9 +11378,6 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) for_each_ndev(cfg, iter, next) wl_set_drv_status(cfg, SCAN_ABORTING, iter->ndev); -#ifdef WL_SDO - wl_cfg80211_sdo_deinit(cfg); -#endif spin_lock_irqsave(&cfg->cfgdrv_lock, flags); if (cfg->scan_request) { @@ -12080,11 +11398,10 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) } bcmcfg_to_prmry_ndev(cfg)->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; -#if defined(WL_CFG80211) && (defined(WL_ENABLE_P2P_IF)|| \ - defined(WL_NEWCFG_PRIVCMD_SUPPORT)) +#if defined(WL_CFG80211) && defined(WL_ENABLE_P2P_IF) if (p2p_net) dev_close(p2p_net); -#endif /* WL_CFG80211 && (WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT) */ +#endif wl_flush_eq(cfg); wl_link_down(cfg); if (cfg->p2p_supported) @@ -12097,9 +11414,6 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) cfg->ap_info = NULL; } dhd_monitor_uninit(); -#ifdef WLAIBSS_MCHAN - bcm_cfg80211_del_ibss_if(cfg->wdev->wiphy, cfg->ibss_cfgdev); -#endif /* WLAIBSS_MCHAN */ #if defined(DUAL_STA) || defined(DUAL_STA_STATIC_IF) /* Clean up if not removed already */ @@ -12144,18 +11458,14 @@ s32 wl_cfg80211_up(void *para) if (unlikely(err)) return err; } -#if defined(BCMSUP_4WAY_HANDSHAKE) && defined(WLAN_AKM_SUITE_FT_8021X) - if (dhd->fw_4way_handshake) - cfg->wdev->wiphy->features |= NL80211_FEATURE_FW_4WAY_HANDSHAKE; -#endif err = __wl_cfg80211_up(cfg); if (unlikely(err)) WL_ERR(("__wl_cfg80211_up failed\n")); +#ifdef ROAM_CHANNEL_CACHE + init_roam(ioctl_version); +#endif mutex_unlock(&cfg->usr_sync); -#ifdef WLAIBSS_MCHAN - bcm_cfg80211_add_ibss_if(cfg->wdev->wiphy, IBSS_IF_NAME); -#endif /* WLAIBSS_MCHAN */ #ifdef DUAL_STA_STATIC_IF #ifdef DUAL_STA @@ -12480,7 +11790,7 @@ s32 wl_cfg80211_channel_to_freq(u32 channel) { int freq = 0; -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) freq = ieee80211_channel_to_frequency(channel); #else { @@ -12495,893 +11805,48 @@ s32 wl_cfg80211_channel_to_freq(u32 channel) return freq; } -#ifdef WL_SDO -#define MAX_QR_LEN NLMSG_GOODSIZE - -typedef struct wl_cfg80211_dev_info { - u16 band; - u16 freq; - s16 rssi; - u16 ie_len; - u8 bssid[ETH_ALEN]; -} wl_cfg80211_dev_info_t; +#ifdef WLTDLS static s32 -wl_notify_device_discovery(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) -{ - int err = 0; - u32 event = ntoh32(e->event_type); - wl_cfg80211_dev_info_t info; - struct wl_bss_info *bi = NULL; - struct net_device *ndev = NULL; - u8 *buf = NULL; - u32 buflen = 0; - u16 channel = 0; - wl_escan_result_t *escan_result; - - WL_SD(("Enter. type:%d \n", event)); +wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, + const wl_event_msg_t *e, void *data) { - if ((event != WLC_E_P2PO_ADD_DEVICE) && (event != WLC_E_P2PO_DEL_DEVICE)) { - WL_ERR(("Unknown Event\n")); - return -EINVAL; - } + struct net_device *ndev = NULL; + u32 reason = ntoh32(e->reason); + s8 *msg = NULL; ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); - mutex_lock(&cfg->usr_sync); - if (event == WLC_E_P2PO_DEL_DEVICE) { - WL_SD(("DEV_LOST MAC:"MACDBG" \n", MAC2STRDBG(e->addr.octet))); - err = wl_genl_send_msg(ndev, event, (u8 *)e->addr.octet, ETH_ALEN, 0, 0); - } else { - - escan_result = (wl_escan_result_t *) data; - - if (dtoh16(escan_result->bss_count) != 1) { - WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count)); - err = -EINVAL; - goto exit; - } - - bi = escan_result->bss_info; - buflen = dtoh32(bi->length); - if (unlikely(buflen > WL_BSS_INFO_MAX)) { - WL_DBG(("Beacon is larger than buffer. Discarding\n")); - err = -EINVAL; - goto exit; - } - - /* Update sub-header */ - bzero(&info, sizeof(wl_cfg80211_dev_info_t)); - channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec)); - info.freq = wl_cfg80211_channel_to_freq(channel); - info.rssi = wl_rssi_offset(dtoh16(bi->RSSI)); - memcpy(info.bssid, &bi->BSSID, ETH_ALEN); - info.ie_len = buflen; - - WL_SD(("DEV_FOUND band:%x Freq:%d rssi:%x "MACDBG" \n", - info.band, info.freq, info.rssi, MAC2STRDBG(info.bssid))); - - buf = ((u8 *) bi) + bi->ie_offset; - err = wl_genl_send_msg(ndev, event, buf, - buflen, (u8 *)&info, sizeof(wl_cfg80211_dev_info_t)); - } -exit: - mutex_unlock(&cfg->usr_sync); - return err; -} - -s32 -wl_cfg80211_sdo_init(struct bcm_cfg80211 *cfg) -{ - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - - if (cfg->sdo) { - WL_SD(("SDO already initialized\n")); - return 0; + switch (reason) { + case WLC_E_TDLS_PEER_DISCOVERED : + msg = " TDLS PEER DISCOVERD "; + break; + case WLC_E_TDLS_PEER_CONNECTED : +#ifdef PCIE_FULL_DONGLE + dhd_tdls_update_peer_info(ndev, TRUE, (uint8 *)&e->addr.octet[0]); +#endif /* PCIE_FULL_DONGLE */ + msg = " TDLS PEER CONNECTED "; + break; + case WLC_E_TDLS_PEER_DISCONNECTED : +#ifdef PCIE_FULL_DONGLE + dhd_tdls_update_peer_info(ndev, FALSE, (uint8 *)&e->addr.octet[0]); +#endif /* PCIE_FULL_DONGLE */ + msg = "TDLS PEER DISCONNECTED "; + break; } - - cfg->sdo = kzalloc(sizeof(sd_offload_t), kflags); - if (!cfg->sdo) { - WL_ERR(("malloc failed for SDO \n")); - return -ENOMEM; + if (msg) { + WL_ERR(("%s: " MACDBG " on %s ndev\n", msg, MAC2STRDBG((u8*)(&e->addr)), + (bcmcfg_to_prmry_ndev(cfg) == ndev) ? "primary" : "secondary")); } + return 0; - return 0; } +#endif /* WLTDLS */ -s32 -wl_cfg80211_sdo_deinit(struct bcm_cfg80211 *cfg) -{ - s32 bssidx; - int ret = 0; - int sdo_pause = 0; - if (!cfg || !cfg->p2p) { - WL_ERR(("Wl %p or cfg->p2p %p is null\n", - cfg, cfg ? cfg->p2p : 0)); - return 0; - } - - bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - if (!cfg->sdo) { - WL_DBG(("SDO Not Initialized. Do nothing. \n")); - return 0; - } - if (cfg->sdo->dd_state && - (ret = wldev_iovar_setbuf_bsscfg(bcmcfg_to_prmry_ndev(cfg), - "p2po_stop", (void*)&sdo_pause, sizeof(sdo_pause), - cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, NULL)) < 0) { - WL_ERR(("p2po_stop Failed :%d\n", ret)); - } - kfree(cfg->sdo); - cfg->sdo = NULL; - - WL_SD(("SDO Deinit Done \n")); - - return 0; -} - -s32 -wl_cfg80211_resume_sdo(struct net_device *dev, struct bcm_cfg80211 *cfg) -{ - wl_sd_listen_t sd_listen; - int ret = 0; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - - WL_DBG(("Enter\n")); - - if (!cfg->sdo) { - return -EINVAL; - } - - if (dev == NULL) - dev = bcmcfg_to_prmry_ndev(cfg); - - /* Disable back the ESCAN events for the offload */ - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, false); - - /* Resume according to the saved state */ - if (cfg->sdo->dd_state == WL_DD_STATE_SEARCH) { - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_find", NULL, 0, - cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, NULL)) < 0) { - WL_ERR(("p2po_find Failed :%d\n", ret)); - } - } else if (cfg->sdo->dd_state == WL_DD_STATE_LISTEN) { - sd_listen.interval = cfg->sdo->sd_listen.interval; - sd_listen.period = cfg->sdo->sd_listen.period; - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen", (void*)&sd_listen, - sizeof(wl_sd_listen_t), cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, NULL)) < 0) { - WL_ERR(("p2po_listen Failed :%d\n", ret)); - } - - } - - /* p2po_stop clears of the eventmask for GAS. Set it back */ - wl_add_remove_eventmsg(dev, WLC_E_SERVICE_FOUND, true); - wl_add_remove_eventmsg(dev, WLC_E_GAS_FRAGMENT_RX, true); - wl_add_remove_eventmsg(dev, WLC_E_GAS_COMPLETE, true); - - WL_SD(("SDO Resumed \n")); - - return ret; -} - -s32 wl_cfg80211_pause_sdo(struct net_device *dev, struct bcm_cfg80211 *cfg) -{ - - int ret = 0; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - int sdo_pause = 1; - - WL_DBG(("Enter \n")); - - if (!cfg->sdo) { - WL_ERR(("SDO not initialized \n")); - return -EINVAL; - } - - if (dev == NULL) - dev = bcmcfg_to_prmry_ndev(cfg); - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_stop", - (void*)&sdo_pause, sizeof(sdo_pause), - cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_stop Failed :%d\n", ret)); - } - - /* Enable back the ESCAN events for the SCAN */ - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, true); - - WL_SD(("SDO Paused \n")); - - return ret; -} - -static s32 -wl_svc_resp_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) -{ - u32 event = ntoh32(e->event_type); - struct net_device *ndev = NULL; - u8 *dst_mac = (u8 *)e->addr.octet; - int ret = 0; - wl_event_sd_t *gas = NULL; - int status = ntoh32(e->status); - sdo_event_t sdo_hdr; - u32 data_len = ntoh32(e->datalen); - u8 *data_ptr = NULL; - u32 tot_len = 0; - - - WL_SD(("Enter event_type:%d status:%d\n", event, status)); - - if (!cfg->sdo) { - WL_ERR(("SDO Not initialized \n")); - return -EINVAL; - } - - if (!(cfg->sdo->sd_state & WL_SD_SEARCH_SVC)) { - /* We are not searching for any service. Drop - * any bogus Event - */ - WL_ERR(("Bogus SDO Event. Do nothing.. \n")); - return -1; - } - - ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); - - mutex_lock(&cfg->usr_sync); - if (event == WLC_E_SERVICE_FOUND) { - - if ((status != WLC_E_STATUS_SUCCESS) && (status != WLC_E_STATUS_PARTIAL)) { - WL_ERR(("WLC_E_SERVICE_FOUND: unknown status \n")); - goto exit; - } - - gas = (wl_event_sd_t *)data; - if (!gas) { - ret = -EINVAL; - goto exit; - } - - bzero(&sdo_hdr, sizeof(sdo_event_t)); - sdo_hdr.freq = wl_cfg80211_channel_to_freq(gas->channel); - sdo_hdr.count = gas->count; - memcpy(sdo_hdr.addr, dst_mac, ETH_ALEN); - data_ptr = (char *)gas->tlv; - tot_len = data_len - (sizeof(wl_event_sd_t) - sizeof(wl_sd_tlv_t)); - - WL_SD(("WLC_E_SERVICE_FOUND "MACDBG" data_len:%d tlv_count:%d \n", - MAC2STRDBG(dst_mac), data_len, sdo_hdr.count)); - - if (tot_len > NLMSG_DEFAULT_SIZE) { - WL_ERR(("size(%u) > %lu not supported \n", tot_len, NLMSG_DEFAULT_SIZE)); - ret = -ENOMEM; - goto exit; - } - - if (wl_genl_send_msg(ndev, event, data_ptr, - tot_len, (u8 *)&sdo_hdr, sizeof(sdo_event_t)) < 0) - WL_ERR(("Couldn't send up the NETLINK Event \n")); - else - WL_SD(("GAS event sent up \n")); - } else { - WL_ERR(("Unsupported Event: %d \n", event)); - } - -exit: - mutex_unlock(&cfg->usr_sync); - return ret; -} - -s32 wl_cfg80211_DsdOffloadParseProto(char* proto_str, u8* proto) -{ - s32 len = -1; - int i = 0; - - for (i = 0; i < MAX_SDO_PROTO; i++) { - if (strncmp(proto_str, wl_sdo_protos[i].str, strlen(wl_sdo_protos[i].str)) == 0) { - WL_SD(("Matching proto (%d) found \n", wl_sdo_protos[i].val)); - *proto = wl_sdo_protos[i].val; - len = strlen(wl_sdo_protos[i].str); - break; - } - } - return len; -} - -/* - * register to search for a UPnP service - * ./DRIVER P2P_SD_REQ upnp 0x10urn:schemas-upnporg:device:InternetGatewayDevice:1 - * - * Enable discovery - * ./cfg p2po_find -*/ -#define UPNP_QUERY_VER_OFFSET 3 -s32 wl_sd_handle_sd_req( - struct net_device *dev, - u8 * buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = 0; - wl_sd_qr_t *sdreq; - u8 proto = 0; - s32 ret = 0; - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - u32 tot_len = len + sizeof(wl_sd_qr_t); - u16 version = 0; - - if (wl_cfgp2p_find_idx(cfg, dev, &bssidx) != BCME_OK) { - WL_ERR(("find_idx failed\n")); - return -EINVAL; - } - /* Check for the least arg length expected */ - if (!buf || (len < strlen("all"))) { - WL_ERR(("Wrong Arg\n")); - return -EINVAL; - } - - if (tot_len > WLC_IOCTL_MAXLEN) { - WL_ERR(("Length > %lu not supported \n", MAX_QR_LEN)); - return -EINVAL; - } - - sdreq = kzalloc(tot_len, kflags); - if (!sdreq) { - WL_ERR(("malloc failed\n")); - return -ENOMEM; - } - - WL_SD(("%s Len: %d\n", buf, len)); - if ((ret = wl_cfg80211_DsdOffloadParseProto(buf, &proto)) < 0) { - WL_ERR(("Unknown proto \n")); - goto exit; - } - - sdreq->protocol = proto; - buf += ret; - buf++; /* skip the space */ - sdreq->transaction_id = simple_strtoul(buf, NULL, 16); - WL_SD(("transaction_id:%d\n", sdreq->transaction_id)); - buf += sizeof(sdreq->transaction_id); - - if (*buf == '\0') { - WL_SD(("No Query present. Proto:%d \n", proto)); - sdreq->query_len = 0; - } else { - buf++; /* skip the space */ - /* UPNP version needs to put as binary val */ - if (sdreq->protocol == SVC_RPOTYPE_UPNP) { - /* Extract UPNP version */ - version = simple_strtoul(buf, NULL, 16); - buf = buf + UPNP_QUERY_VER_OFFSET; - buf[0] = version; - WL_SD(("Upnp version: 0x%x \n", version)); - } - - len = strlen(buf); - WL_SD(("Len after stripping proto: %d Query: %s\n", len, buf)); - /* copy the query part */ - memcpy(sdreq->qrbuf, buf, len); - sdreq->query_len = len; - } - - /* Enable discovery */ - if ((ret = wl_cfgp2p_enable_discovery(cfg, dev, NULL, 0)) < 0) { - WL_ERR(("cfgp2p_enable discovery failed")); - goto exit; - } - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_sd_req_resp", (void*)sdreq, - tot_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("Find SVC Failed \n")); - goto exit; - } - - cfg->sdo->sd_state |= WL_SD_SEARCH_SVC; - -exit: - kfree(sdreq); - return ret; -} - -s32 wl_sd_handle_sd_cancel_req( - struct net_device *dev, - u8 *buf) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - - if (wldev_iovar_setbuf_bsscfg(dev, "p2po_sd_cancel", NULL, - 0, cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, &cfg->ioctl_buf_sync) < 0) { - WL_ERR(("Cancel SD Failed \n")); - return -EINVAL; - } - - cfg->sdo->sd_state &= ~WL_SD_SEARCH_SVC; - - return 0; -} - -/* - * register a UPnP service to be discovered - * ./cfg P2P_SD_SVC_ADD upnp 0x10urn:schemas-upnporg:device:InternetGatewayDevice:1 0x10uu - * id:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnporg:device:InternetGate - * wayDevice:1 -*/ -s32 wl_sd_handle_sd_add_svc( - struct net_device *dev, - u8 * buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = 0; - wl_sd_qr_t *sdreq; - u8 proto = 0; - u16 version = 0; - s32 ret = 0; - u8 *resp = NULL; - u8 *query = NULL; - u32 tot_len = len + sizeof(wl_sd_qr_t); - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - - if (!buf || !len) - return -EINVAL; - - WL_SD(("%s Len: %d\n", buf, len)); - if (tot_len > WLC_IOCTL_MAXLEN) { - WL_ERR(("Query-Resp length > %d not supported \n", WLC_IOCTL_MAXLEN)); - return -ENOMEM; - } - - sdreq = kzalloc(tot_len, kflags); - if (!sdreq) { - WL_ERR(("malloc failed\n")); - return -ENOMEM; - } - - if ((ret = wl_cfg80211_DsdOffloadParseProto(buf, &proto)) < 0) { - WL_ERR(("Unknown Proto \n")); - goto exit; - } - - sdreq->protocol = proto; - buf += ret; - - if (*buf == '\0') { - WL_ERR(("No Query Resp pair present \n")); - ret = -EINVAL; - goto exit; - } - - buf++; /* Skip the space */ - len = strlen(buf); - query = strsep((char **)&buf, " "); - if (!query || !buf) { - WL_ERR(("No Query RESP Present\n")); - ret = -EINVAL; - goto exit; - } - resp = buf; - - if (sdreq->protocol == SVC_RPOTYPE_UPNP) { - /* Extract UPNP version */ - version = simple_strtoul(query, NULL, 16); - query = query + UPNP_QUERY_VER_OFFSET; - resp = resp + UPNP_QUERY_VER_OFFSET; - query[0] = version; - resp[0] = version; - WL_SD(("Upnp version: 0x%x \n", version)); - } - - sdreq->query_len = strlen(query); - sdreq->response_len = strlen(buf); - WL_SD(("query:%s len:%u \n", query, sdreq->query_len)); - WL_SD(("resp:%s len:%u \n", buf, sdreq->response_len)); - - memcpy(sdreq->qrbuf, query, sdreq->query_len); - memcpy((sdreq->qrbuf + sdreq->query_len), resp, sdreq->response_len); - - /* Enable discovery */ - if ((ret = wl_cfgp2p_enable_discovery(cfg, dev, NULL, 0)) < 0) { - WL_ERR(("cfgp2p_enable discovery failed")); - goto exit; - } - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_addsvc", (void*)sdreq, - tot_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("FW Failed in doing p2po_addsvc. RET:%d \n", ret)); - goto exit; - } - - cfg->sdo->sd_state |= WL_SD_ADV_SVC; - -exit: - kfree(sdreq); - return ret; -} - -s32 wl_sd_handle_sd_del_svc( - struct net_device *dev, - u8 * buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = 0; - wl_sd_qr_t *sdreq; - u8 proto = 0; - s32 ret = 0; - u32 tot_len = len + sizeof(wl_sd_qr_t); - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - u16 version = 0; - - if (wl_cfgp2p_find_idx(cfg, dev, &bssidx) != BCME_OK) { - WL_ERR(("find_idx failed\n")); - return -EINVAL; - } - - sdreq = (wl_sd_qr_t *)kzalloc(tot_len, kflags); - if (!sdreq) { - WL_ERR(("malloc failed\n")); - ret = -ENOMEM; - goto exit; - } - - /* Check for the least arg length expected */ - if (buf && len >= strlen("all")) { - WL_DBG(("%s Len: %d\n", buf, len)); - if ((ret = wl_cfg80211_DsdOffloadParseProto(buf, &proto)) < 0) { - WL_ERR(("Unknown Proto \n")); - goto exit; - } - sdreq->protocol = proto; - buf += ret; - - if (*buf == ' ') { - /* Query present */ - buf++; /* Skip the space */ - /* UPNP version needs to put as binary val */ - if (sdreq->protocol == SVC_RPOTYPE_UPNP) { - /* Extract UPNP version */ - version = simple_strtoul(buf, NULL, 16); - buf = buf + UPNP_QUERY_VER_OFFSET; - buf[0] = version; - WL_SD(("Upnp version: 0x%x \n", version)); - } - memcpy(sdreq->qrbuf, buf, strlen(buf)); - sdreq->query_len = strlen(buf); - WL_SD(("Query to be deleted:%s len:%d\n", buf, sdreq->query_len)); - } - } else { - /* ALL */ - proto = 0; - } - - sdreq->protocol = proto; - WL_SD(("Proto: %d \n", proto)); - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_delsvc", (void*)sdreq, - tot_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("FW Failed in doing sd_delsvc. ret=%d \n", ret)); - goto exit; - } - - cfg->sdo->sd_state &= ~WL_SD_ADV_SVC; - -exit: - if (sdreq) - kfree(sdreq); - - return ret; -} - -s32 wl_sd_handle_sd_stop_discovery( - struct net_device *dev, - u8 * buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - int ret = 0; - int sdo_pause = 0; - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_stop", (void*)&sdo_pause, - sizeof(sdo_pause), cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_stop Failed :%d\n", ret)); - return -1; - } - - if (wldev_iovar_setint(dev, "mpc", 1) < 0) { - /* Setting of MPC failed */ - WL_ERR(("mpc enabling back failed\n")); - return -1; - } - - /* clear the states */ - cfg->sdo->dd_state = WL_DD_STATE_IDLE; - wl_clr_p2p_status(cfg, DISC_IN_PROGRESS); - - bzero(&cfg->sdo->sd_listen, sizeof(wl_sd_listen_t)); - - /* Remove ESCAN from waking up the host if ofind/olisten is enabled */ - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, true); - - return ret; -} - -s32 wl_sd_handle_sd_find( - struct net_device *dev, - u8 * buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - int ret = 0; - s32 disc_bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - vndr_ie_setbuf_t *ie_setbuf; - vndr_ie_t *vndrie; - vndr_ie_buf_t *vndriebuf; - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - int tot_len = 0; - uint channel = 0; - - u8 p2pie_buf[] = { - 0x09, 0x02, 0x02, 0x00, 0x27, 0x0c, 0x06, 0x05, 0x00, - 0x55, 0x53, 0x04, 0x51, 0x0b, 0x11, 0x05, 0x00, 0x55, - 0x53, 0x04, 0x51, 0x0b - }; - - /* Enable discovery */ - if ((ret = wl_cfgp2p_enable_discovery(cfg, dev, NULL, 0)) < 0) { - WL_ERR(("cfgp2p_enable discovery failed")); - return -1; - } - - if (buf && strncmp(buf, "chan=", strlen("chan=")) == 0) { - buf += strlen("chan="); - channel = simple_strtol(buf, NULL, 10); - WL_SD(("listen_chan to be set:%d\n", channel)); - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen_channel", (void*)&channel, - sizeof(channel), cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_listen_channel Failed :%d\n", ret)); - return -1; - } - } - - tot_len = sizeof(vndr_ie_setbuf_t) + sizeof(p2pie_buf); - ie_setbuf = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags); - if (!ie_setbuf) { - WL_ERR(("IE memory alloc failed\n")); - return -ENOMEM; - } - - /* Apply the p2p_ie for p2po_find */ - strcpy(ie_setbuf->cmd, "add"); - - vndriebuf = &ie_setbuf->vndr_ie_buffer; - vndriebuf->iecount = htod32(1); - vndriebuf->vndr_ie_list[0].pktflag = htod32(16); - - vndrie = &vndriebuf->vndr_ie_list[0].vndr_ie_data; - - vndrie->id = (uchar) DOT11_MNG_PROPR_ID; - vndrie->len = sizeof(p2pie_buf); - memcpy(vndrie->oui, WFA_OUI, WFA_OUI_LEN); - memcpy(vndrie->data, p2pie_buf, sizeof(p2pie_buf)); - - /* Remove ESCAN from waking up the host if SDO is enabled */ - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, false); - - if (wldev_iovar_setbuf_bsscfg(dev, "ie", (void*)ie_setbuf, - tot_len, cfg->ioctl_buf, WLC_IOCTL_SMLEN, - disc_bssidx, &cfg->ioctl_buf_sync) < 0) { - WL_ERR(("p2p add_ie failed \n")); - ret = -EINVAL; - goto exit; - } else - WL_SD(("p2p add_ie applied successfully len:%d \n", tot_len)); - - if (wldev_iovar_setint(dev, "mpc", 0) < 0) { - /* Setting of MPC failed */ - WL_ERR(("mpc disabling faild\n")); - ret = -1; - goto exit; - } - - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_find", NULL, 0, - cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_find Failed :%d\n", ret)); - ret = -1; - goto exit; - } - - /* set the states */ - cfg->sdo->dd_state = WL_DD_STATE_SEARCH; - wl_set_p2p_status(cfg, DISC_IN_PROGRESS); - -exit: - if (ie_setbuf) - kfree(ie_setbuf); - - /* Incase of failure enable back the ESCAN event */ - if (ret) - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, true); - - return ret; -} - -s32 wl_sd_handle_sd_listen( - struct net_device *dev, - u8 *buf, - int len) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); - wl_sd_listen_t sd_listen; - int ret = 0; - u8 * ptr = NULL; - uint channel = 0; - - /* Just in case if it is not enabled */ - if ((ret = wl_cfgp2p_enable_discovery(cfg, dev, NULL, 0)) < 0) { - WL_ERR(("cfgp2p_enable discovery failed")); - return -1; - } - - if (wldev_iovar_setint(dev, "mpc", 0) < 0) { - /* Setting of MPC failed */ - WL_ERR(("mpc disabling faild\n")); - return -1; - } - - bzero(&sd_listen, sizeof(wl_sd_listen_t)); - - if (len) { - ptr = strsep((char **)&buf, " "); - if (ptr == NULL) { - /* period and duration given wrongly */ - WL_ERR(("Arguments in wrong format \n")); - return -EINVAL; - } - else if (strncmp(ptr, "chan=", strlen("chan=")) == 0) { - sd_listen.interval = 65535; - sd_listen.period = 65535; - ptr += strlen("chan="); - channel = simple_strtol(ptr, NULL, 10); - } - else { - sd_listen.period = simple_strtol(ptr, NULL, 10); - ptr = strsep((char **)&buf, " "); - if (ptr == NULL) { - WL_ERR(("Arguments in wrong format \n")); - return -EINVAL; - } - sd_listen.interval = simple_strtol(ptr, NULL, 10); - if (buf && strncmp(buf, "chan=", strlen("chan=")) == 0) { - buf += strlen("chan="); - channel = simple_strtol(buf, NULL, 10); - } - } - WL_SD(("listen_period:%d, listen_interval:%d and listen_channel:%d\n", - sd_listen.period, sd_listen.interval, channel)); - } - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen_channel", (void*)&channel, - sizeof(channel), cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_listen_channel Failed :%d\n", ret)); - return -1; - } - - WL_SD(("p2po_listen period:%d interval:%d \n", - sd_listen.period, sd_listen.interval)); - if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen", (void*)&sd_listen, - sizeof(wl_sd_listen_t), cfg->ioctl_buf, WLC_IOCTL_SMLEN, - bssidx, &cfg->ioctl_buf_sync)) < 0) { - WL_ERR(("p2po_listen Failed :%d\n", ret)); - return -1; - } - - /* Remove ESCAN from waking up the host if ofind/olisten is enabled */ - wl_add_remove_eventmsg(dev, WLC_E_ESCAN_RESULT, false); - - /* Store the extended listen values for use in sdo_resume */ - cfg->sdo->sd_listen.interval = sd_listen.interval; - cfg->sdo->sd_listen.period = sd_listen.period; - - /* set the states */ - cfg->sdo->dd_state = WL_DD_STATE_LISTEN; - wl_set_p2p_status(cfg, DISC_IN_PROGRESS); - - return 0; -} - -s32 wl_cfg80211_sd_offload(struct net_device *dev, char *cmd, char* buf, int len) -{ - int ret = 0; - struct bcm_cfg80211 *cfg = g_bcm_cfg; - - WL_SD(("Entry cmd:%s arg_len:%d \n", cmd, len)); - - if (!cfg->sdo) { - WL_SD(("Initializing SDO \n")); - if ((ret = wl_cfg80211_sdo_init(cfg)) < 0) - goto exit; - } - - if (strncmp(cmd, "P2P_SD_REQ", strlen("P2P_SD_REQ")) == 0) { - ret = wl_sd_handle_sd_req(dev, buf, len); - } else if (strncmp(cmd, "P2P_SD_CANCEL_REQ", strlen("P2P_SD_CANCEL_REQ")) == 0) { - ret = wl_sd_handle_sd_cancel_req(dev, buf); - } else if (strncmp(cmd, "P2P_SD_SVC_ADD", strlen("P2P_SD_SVC_ADD")) == 0) { - ret = wl_sd_handle_sd_add_svc(dev, buf, len); - } else if (strncmp(cmd, "P2P_SD_SVC_DEL", strlen("P2P_SD_SVC_DEL")) == 0) { - ret = wl_sd_handle_sd_del_svc(dev, buf, len); - } else if (strncmp(cmd, "P2P_SD_FIND", strlen("P2P_SD_FIND")) == 0) { - ret = wl_sd_handle_sd_find(dev, buf, len); - } else if (strncmp(cmd, "P2P_SD_LISTEN", strlen("P2P_SD_LISTEN")) == 0) { - ret = wl_sd_handle_sd_listen(dev, buf, len); - } else if (strncmp(cmd, "P2P_SD_STOP", strlen("P2P_STOP")) == 0) { - ret = wl_sd_handle_sd_stop_discovery(dev, buf, len); - } else { - WL_ERR(("Request for Unsupported CMD:%s \n", buf)); - ret = -EINVAL; - } - -exit: - return ret; -} -#endif /* WL_SDO */ - -#ifdef WLTDLS -static s32 -wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) { - - struct net_device *ndev = NULL; - u32 reason = ntoh32(e->reason); - s8 *msg = NULL; - - ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); - - switch (reason) { - case WLC_E_TDLS_PEER_DISCOVERED : - msg = " TDLS PEER DISCOVERD "; - break; - case WLC_E_TDLS_PEER_CONNECTED : -#ifdef PCIE_FULL_DONGLE - dhd_tdls_update_peer_info(ndev, TRUE, (uint8 *)&e->addr.octet[0]); -#endif /* PCIE_FULL_DONGLE */ - msg = " TDLS PEER CONNECTED "; - break; - case WLC_E_TDLS_PEER_DISCONNECTED : -#ifdef PCIE_FULL_DONGLE - dhd_tdls_update_peer_info(ndev, FALSE, (uint8 *)&e->addr.octet[0]); -#endif /* PCIE_FULL_DONGLE */ - msg = "TDLS PEER DISCONNECTED "; - break; - } - if (msg) { - WL_ERR(("%s: " MACDBG " on %s ndev\n", msg, MAC2STRDBG((u8*)(&e->addr)), - (bcmcfg_to_prmry_ndev(cfg) == ndev) ? "primary" : "secondary")); - } - return 0; - -} -#endif /* WLTDLS */ - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS) -static s32 -wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, - u8 *peer, enum nl80211_tdls_operation oper) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) +static s32 +wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, + u8 *peer, enum nl80211_tdls_operation oper) { s32 ret = 0; #ifdef WLTDLS @@ -13427,7 +11892,7 @@ out: #endif /* WLTDLS */ return ret; } -#endif /* LINUX_VERSION > VERSION(3,2,0) || WL_COMPAT_WIRELESS */ +#endif s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, enum wl_management_type type) @@ -14160,93 +12625,7 @@ exit: } #endif /* WL11U */ -#ifdef WL_HOST_BAND_MGMT -s32 -wl_cfg80211_set_band(struct net_device *ndev, int band) -{ - struct bcm_cfg80211 *cfg = g_bcm_cfg; - int ret = 0; - char ioctl_buf[50]; - if ((band < WLC_BAND_AUTO) || (band > WLC_BAND_2G)) { - WL_ERR(("Invalid band\n")); - return -EINVAL; - } - - if ((ret = wldev_iovar_setbuf(ndev, "roam_band", &band, - sizeof(int), ioctl_buf, sizeof(ioctl_buf), NULL)) < 0) { - WL_ERR(("seting roam_band failed code=%d\n", ret)); - return ret; - } - - WL_DBG(("Setting band to %d\n", band)); - cfg->curr_band = band; - - return 0; -} -#endif /* WL_HOST_BAND_MGMT */ - -#if defined(DHCP_SCAN_SUPPRESS) -static void wl_cfg80211_scan_supp_timerfunc(ulong data) -{ - struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)data; - - WL_DBG(("Enter \n")); - schedule_work(&cfg->wlan_work); -} - -int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress) -{ - int ret = 0; - struct wireless_dev *wdev; - struct bcm_cfg80211 *cfg; - if (!dev || ((suppress != 0) && (suppress != 1))) { - ret = -EINVAL; - goto exit; - } - wdev = ndev_to_wdev(dev); - if (!wdev) { - ret = -EINVAL; - goto exit; - } - cfg = (struct bcm_cfg80211 *)wiphy_priv(wdev->wiphy); - if (!cfg) { - ret = -EINVAL; - goto exit; - } - - if (suppress == cfg->scan_suppressed) { - WL_DBG(("No change in scan_suppress state. Ignoring cmd..\n")); - return 0; - } - - if (timer_pending(&cfg->scan_supp_timer)) - del_timer_sync(&cfg->scan_supp_timer); - - if ((ret = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, - &suppress, sizeof(int), true)) < 0) { - WL_ERR(("Scan suppress setting failed ret:%d \n", ret)); - } else { - WL_DBG(("Scan suppress %s \n", suppress ? "Enabled" : "Disabled")); - cfg->scan_suppressed = suppress; - } - - /* If scan_suppress is set, Start a timer to monitor it (just incase) */ - if (cfg->scan_suppressed) { - if (ret) { - WL_ERR(("Retry scan_suppress reset at a later time \n")); - mod_timer(&cfg->scan_supp_timer, - jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_RETRY)); - } else { - WL_DBG(("Start wlan_timer to clear of scan_suppress \n")); - mod_timer(&cfg->scan_supp_timer, - jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_TIMEOUT)); - } - } -exit: - return ret; -} -#endif /* DHCP_SCAN_SUPPRESS */ int wl_cfg80211_scan_stop(bcm_struct_cfgdev *cfgdev) { @@ -14326,13 +12705,6 @@ static void wl_cfg80211_work_handler(struct work_struct * work) } } } -#if defined(DHCP_SCAN_SUPPRESS) - else if (cfg->scan_suppressed) { - /* There is pending scan_suppress. Clean it */ - WL_ERR(("Clean up from timer after %d msec\n", WL_SCAN_SUPPRESS_TIMEOUT)); - wl_cfg80211_scan_suppress(bcmcfg_to_prmry_ndev(cfg), 0); - } -#endif /* DHCP_SCAN_SUPPRESS */ } u8 @@ -14364,13 +12736,6 @@ wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action) return BCME_OK; } -#ifdef WLFBT -void -wl_cfg80211_get_fbt_key(uint8 *key) -{ - memcpy(key, g_bcm_cfg->fbt_key, FBT_KEYLEN); -} -#endif /* WLFBT */ static int wl_cfg80211_delayed_roam(struct bcm_cfg80211 *cfg, struct net_device *ndev, @@ -14444,11 +12809,3 @@ wl_cfg80211_set_mac_acl(struct wiphy *wiphy, struct net_device *cfgdev, return ret; } #endif /* WL_CFG80211_ACL */ - -#ifdef WL_NAN -int -wl_cfg80211_nan_cmd_handler(struct net_device *ndev, char *cmd, int cmd_len) -{ - return wl_cfgnan_cmd_handler(ndev, g_bcm_cfg, cmd, cmd_len); -} -#endif /* WL_NAN */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h index 692b33a31d20443a9dcce248040070341084af67..62abf2f346168ef68337d19343ac3f21403bf99f 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h @@ -1,9 +1,27 @@ /* * Linux cfg80211 driver * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfg80211.h 491407 2014-07-16 09:23:04Z $ + * $Id: wl_cfg80211.h 472818 2014-04-25 08:07:56Z $ */ /** @@ -54,16 +72,16 @@ struct wl_ibss; #define WL_ERR(args) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - printf(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ - printf args; \ + printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ + printk args; \ } \ } while (0) #else /* defined(DHD_DEBUG) */ #define WL_ERR(args) \ do { \ if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \ - printf(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ - printf args; \ + printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ + printk args; \ } \ } while (0) #endif /* defined(DHD_DEBUG) */ @@ -75,8 +93,8 @@ do { \ #define WL_INFORM(args) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - printf(KERN_INFO "CFG80211-INFO) %s : ", __func__); \ - printf args; \ + printk(KERN_INFO "CFG80211-INFO) %s : ", __func__); \ + printk args; \ } \ } while (0) @@ -87,8 +105,8 @@ do { \ #define WL_SCAN(args) \ do { \ if (wl_dbg_level & WL_DBG_SCAN) { \ - printf(KERN_INFO "CFG80211-SCAN) %s :", __func__); \ - printf args; \ + printk(KERN_INFO "CFG80211-SCAN) %s :", __func__); \ + printk args; \ } \ } while (0) #ifdef WL_TRACE @@ -97,8 +115,8 @@ do { \ #define WL_TRACE(args) \ do { \ if (wl_dbg_level & WL_DBG_TRACE) { \ - printf(KERN_INFO "CFG80211-TRACE) %s :", __func__); \ - printf args; \ + printk(KERN_INFO "CFG80211-TRACE) %s :", __func__); \ + printk args; \ } \ } while (0) #ifdef WL_TRACE_HW4 @@ -109,8 +127,8 @@ do { \ #define WL_DBG(args) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printf(KERN_DEBUG "CFG80211-DEBUG) %s :", __func__); \ - printf args; \ + printk(KERN_DEBUG "CFG80211-DEBUG) %s :", __func__); \ + printk args; \ } \ } while (0) #else /* !(WL_DBG_LEVEL > 0) */ @@ -161,12 +179,6 @@ do { \ #define WL_PM_ENABLE_TIMEOUT 10000 -#ifdef WLAIBSS -/* Custom AIBSS beacon parameters */ -#define AIBSS_INITIAL_MIN_BCN_DUR 500 -#define AIBSS_MIN_BCN_DUR 5000 -#define AIBSS_BCN_FLOOD_DUR 5000 -#endif /* WLAIBSS */ /* driver status */ enum wl_status { @@ -440,58 +452,11 @@ struct parsed_ies { u32 wpa2_ie_len; }; -#ifdef WL_SDO -/* Service discovery */ -typedef struct { - uint8 transaction_id; /* Transaction ID */ - uint8 protocol; /* Service protocol type */ - uint16 query_len; /* Length of query */ - uint16 response_len; /* Length of response */ - uint8 qrbuf[1]; -} wl_sd_qr_t; - -typedef struct { - uint16 period; /* extended listen period */ - uint16 interval; /* extended listen interval */ -} wl_sd_listen_t; - -#define WL_SD_STATE_IDLE 0x0000 -#define WL_SD_SEARCH_SVC 0x0001 -#define WL_SD_ADV_SVC 0x0002 - -enum wl_dd_state { - WL_DD_STATE_IDLE, - WL_DD_STATE_SEARCH, - WL_DD_STATE_LISTEN -}; - -#define MAX_SDO_PROTO_STR_LEN 20 -typedef struct wl_sdo_proto { - char str[MAX_SDO_PROTO_STR_LEN]; - u32 val; -} wl_sdo_proto_t; - -typedef struct sd_offload { - u32 sd_state; - enum wl_dd_state dd_state; - wl_sd_listen_t sd_listen; -} sd_offload_t; - -typedef struct sdo_event { - u8 addr[ETH_ALEN]; - uint16 freq; /* channel Freq */ - uint8 count; /* Tlv count */ - uint16 update_ind; -} sdo_event_t; -#endif /* WL_SDO */ #ifdef WL11U /* Max length of Interworking element */ #define IW_IES_MAX_BUF_LEN 9 #endif -#ifdef WLFBT -#define FBT_KEYLEN 32 -#endif #define MAX_EVENT_BUF_NUM 16 typedef struct wl_eventmsg_buf { u16 num; @@ -598,9 +563,6 @@ struct bcm_cfg80211 { struct net_info *_net_info, enum wl_status state, bool set); unsigned long interrested_state; wlc_ssid_t hostapd_ssid; -#ifdef WL_SDO - sd_offload_t *sdo; -#endif #ifdef WL11U bool wl11u; u8 iw_ie[IW_IES_MAX_BUF_LEN]; @@ -610,9 +572,6 @@ struct bcm_cfg80211 { #ifdef WL_SCHED_SCAN struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ #endif /* WL_SCHED_SCAN */ -#ifdef WL_HOST_BAND_MGMT - u8 curr_band; -#endif /* WL_HOST_BAND_MGMT */ bool scan_suppressed; struct timer_list scan_supp_timer; struct work_struct wlan_work; @@ -622,24 +581,12 @@ struct bcm_cfg80211 { struct delayed_work pm_enable_work; vndr_ie_setbuf_t *ibss_vsie; /* keep the VSIE for IBSS */ int ibss_vsie_len; -#ifdef WLAIBSS - u32 aibss_txfail_pid; - u32 aibss_txfail_seq; -#endif /* WLAIBSS */ - u32 rmc_event_pid; - u32 rmc_event_seq; -#ifdef WLAIBSS_MCHAN struct ether_addr ibss_if_addr; bcm_struct_cfgdev *ibss_cfgdev; /* For AIBSS */ -#endif /* WLAIBSS_MCHAN */ bcm_struct_cfgdev *bss_cfgdev; /* For DUAL STA/STA+AP */ s32 cfgdev_bssidx; bool bss_pending_op; /* indicate where there is a pending IF operation */ -#ifdef WLFBT - uint8 fbt_key[FBT_KEYLEN]; -#endif bool roam_offload; - bool nan_running; }; @@ -855,7 +802,7 @@ wl_get_netinfo_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) #if defined(WL_CFG80211_P2P_DEV_IF) #define ndev_to_cfgdev(ndev) ndev_to_wdev(ndev) -#define cfgdev_to_ndev(cfgdev) cfgdev ? (cfgdev->netdev) : NULL +#define cfgdev_to_ndev(cfgdev) (cfgdev->netdev) #define discover_cfgdev(cfgdev, cfg) (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) #else #define ndev_to_cfgdev(ndev) (ndev) @@ -944,15 +891,6 @@ extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); void* wl_cfg80211_btcoex_init(struct net_device *ndev); void wl_cfg80211_btcoex_deinit(void); -#ifdef WL_SDO -extern s32 wl_cfg80211_sdo_init(struct bcm_cfg80211 *cfg); -extern s32 wl_cfg80211_sdo_deinit(struct bcm_cfg80211 *cfg); -extern s32 wl_cfg80211_sd_offload(struct net_device *net, char *cmd, char* buf, int len); -extern s32 wl_cfg80211_pause_sdo(struct net_device *dev, struct bcm_cfg80211 *cfg); -extern s32 wl_cfg80211_resume_sdo(struct net_device *dev, struct bcm_cfg80211 *cfg); - -#endif - #ifdef WL_SUPPORT_AUTO_CHANNEL #define CHANSPEC_BUF_SIZE 1024 #define CHAN_SEL_IOCTL_DELAY 300 @@ -966,28 +904,18 @@ extern s32 wl_cfg80211_resume_sdo(struct net_device *dev, struct bcm_cfg80211 *c extern s32 wl_cfg80211_get_best_channels(struct net_device *dev, char* command, int total_len); #endif /* WL_SUPPORT_AUTO_CHANNEL */ - -extern int wl_cfg80211_ether_atoe(const char *a, struct ether_addr *n); -extern int wl_cfg80211_hex_str_to_bin(unsigned char *data, int dlen, char *str); extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); extern s32 wl_mode_to_nl80211_iftype(s32 mode); int wl_cfg80211_do_driver_init(struct net_device *net); void wl_cfg80211_enable_trace(bool set, u32 level); extern s32 wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify); extern s32 wl_cfg80211_if_is_group_owner(void); -extern chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec); extern chanspec_t wl_ch_host_to_driver(u16 channel); extern s32 wl_set_tx_power(struct net_device *dev, enum nl80211_tx_power_setting type, s32 dbm); extern s32 wl_get_tx_power(struct net_device *dev, s32 *dbm); extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); extern void wl_stop_wait_next_action_frame(struct bcm_cfg80211 *cfg, struct net_device *ndev); -#ifdef WL_HOST_BAND_MGMT -extern s32 wl_cfg80211_set_band(struct net_device *ndev, int band); -#endif /* WL_HOST_BAND_MGMT */ -#if defined(DHCP_SCAN_SUPPRESS) -extern int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress); -#endif /* OEM_ANDROID */ extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set); extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev, struct bcm_cfg80211 *cfg, wl_eventmsg_buf_t *ev); @@ -1006,14 +934,6 @@ extern void wl_cfg80211_update_power_mode(struct net_device *dev); #define wl_escan_init_sync_id(a) extern void wl_cfg80211_ibss_vsie_set_buffer(vndr_ie_setbuf_t *ibss_vsie, int ibss_vsie_len); extern s32 wl_cfg80211_ibss_vsie_delete(struct net_device *dev); -#ifdef WLAIBSS -extern void wl_cfg80211_set_txfail_pid(int pid); -#endif /* WLAIBSS */ -extern void wl_cfg80211_set_rmc_pid(int pid); - -#ifdef WLFBT -extern void wl_cfg80211_get_fbt_key(uint8 *key); -#endif /* Action frame specific functions */ extern u8 wl_get_action_category(void *frame, u32 frame_len); @@ -1037,10 +957,4 @@ struct net_device *wl_cfg80211_get_remain_on_channel_ndev(struct bcm_cfg80211 *c extern int wl_cfg80211_get_ioctl_version(void); extern int wl_cfg80211_enable_roam_offload(struct net_device *dev, bool enable); - -#ifdef WL_NAN -extern int wl_cfg80211_nan_cmd_handler(struct net_device *ndev, char *cmd, - int cmd_len); -#endif /* WL_NAN */ - #endif /* _wl_cfg80211_h_ */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c b/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c index c8a16ce551feba64950880743a27bb9a46b79e0b..0220da12d47970be540f10a664bf684fad96aaf1 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c @@ -1,7 +1,25 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_cfg_btcoex.c 467328 2014-04-03 01:23:40Z $ */ @@ -419,10 +437,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *co if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { WL_TRACE_HW4(("DHCP session starts\n")); -#if defined(DHCP_SCAN_SUPPRESS) - /* Suppress scan during the DHCP */ - wl_cfg80211_scan_suppress(dev, 1); -#endif /* OEM_ANDROID */ #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 1; @@ -474,10 +488,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *co else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { -#if defined(DHCP_SCAN_SUPPRESS) - /* Since DHCP is complete, enable the scan back */ - wl_cfg80211_scan_suppress(dev, 0); -#endif /* OEM_ANDROID */ #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 0; diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c index 21208172c53047e9924ce8e8446846bde3356698..70904f18398395b7d9a70889d8528b62730e7956 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c +++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c @@ -1,9 +1,27 @@ /* * Linux cfgp2p driver * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: wl_cfgp2p.c 490694 2014-07-11 14:37:00Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_cfgp2p.c 472818 2014-04-25 08:07:56Z $ * */ #include <typedefs.h> @@ -55,23 +73,6 @@ static const struct net_device_ops wl_cfgp2p_if_ops = { }; #endif /* WL_ENABLE_P2P_IF */ -#if defined(WL_NEWCFG_PRIVCMD_SUPPORT) -static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev); -static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd); - -static int wl_cfgp2p_if_dummy(struct net_device *net) -{ - return 0; -} - -static const struct net_device_ops wl_cfgp2p_if_ops = { - .ndo_open = wl_cfgp2p_if_dummy, - .ndo_stop = wl_cfgp2p_if_dummy, - .ndo_do_ioctl = wl_cfgp2p_do_ioctl, - .ndo_start_xmit = wl_cfgp2p_start_xmit, -}; -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ - bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len) { wifi_p2p_pub_act_frame_t *pact_frm; @@ -399,11 +400,11 @@ wl_cfgp2p_ifadd(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); if (unlikely(err < 0)) - printf("'cfg p2p_ifadd' error %d\n", err); + printk("'cfg p2p_ifadd' error %d\n", err); else if (if_type == WL_P2P_IF_GO) { err = wldev_ioctl(ndev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); if (unlikely(err < 0)) - printf("'cfg scb_timeout' error %d\n", err); + printk("'cfg scb_timeout' error %d\n", err); } return err; } @@ -424,7 +425,7 @@ wl_cfgp2p_ifdisable(struct bcm_cfg80211 *cfg, struct ether_addr *mac) ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); if (unlikely(ret < 0)) { - printf("'cfg p2p_ifdis' error %d\n", ret); + printk("'cfg p2p_ifdis' error %d\n", ret); } return ret; } @@ -445,7 +446,7 @@ wl_cfgp2p_ifdel(struct bcm_cfg80211 *cfg, struct ether_addr *mac) ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); if (unlikely(ret < 0)) { - printf("'cfg p2p_ifdel' error %d\n", ret); + printk("'cfg p2p_ifdel' error %d\n", ret); } return ret; } @@ -479,11 +480,11 @@ wl_cfgp2p_ifchange(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); if (unlikely(err < 0)) { - printf("'cfg p2p_ifupd' error %d\n", err); + printk("'cfg p2p_ifupd' error %d\n", err); } else if (if_type == WL_P2P_IF_GO) { err = wldev_ioctl(netdev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); if (unlikely(err < 0)) - printf("'cfg scb_timeout' error %d\n", err); + printk("'cfg scb_timeout' error %d\n", err); } return err; } @@ -1590,7 +1591,7 @@ wl_cfgp2p_listen_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ if (ndev && (ndev->ieee80211_ptr != NULL)) { #if defined(WL_CFG80211_P2P_DEV_IF) - cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id, + cfg80211_remain_on_channel_expired(bcmcfg_to_p2p_wdev(cfg), cfg->last_roc_id, &cfg->remain_on_chan, GFP_KERNEL); #else cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id, @@ -1646,7 +1647,7 @@ wl_cfgp2p_cancel_listen(struct bcm_cfg80211 *cfg, struct net_device *ndev, if (notify) { #if defined(WL_CFG80211_P2P_DEV_IF) if (wdev) - cfg80211_remain_on_channel_expired(wdev, cfg->last_roc_id, + cfg80211_remain_on_channel_expired(bcmcfg_to_p2p_wdev(cfg), cfg->last_roc_id, &cfg->remain_on_chan, GFP_KERNEL); #else if (ndev && ndev->ieee80211_ptr) @@ -2345,15 +2346,13 @@ struct ethtool_ops cfgp2p_ethtool_ops = { }; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -#if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT) +#if defined(WL_ENABLE_P2P_IF) s32 wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg) { int ret = 0; struct net_device* net = NULL; -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT struct wireless_dev *wdev = NULL; -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 }; if (cfg->p2p_net) { @@ -2367,14 +2366,12 @@ wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg) return -ENODEV; } -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); if (unlikely(!wdev)) { WL_ERR(("Could not allocate wireless device\n")); free_netdev(net); return -ENOMEM; } -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ strncpy(net->name, "p2p%d", sizeof(net->name) - 1); net->name[IFNAMSIZ - 1] = '\0'; @@ -2396,44 +2393,36 @@ wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg) /* Register with a dummy MAC addr */ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT wdev->wiphy = cfg->wdev->wiphy; wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); net->ieee80211_ptr = wdev; -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) net->ethtool_ops = &cfgp2p_ethtool_ops; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy)); /* Associate p2p0 network interface with new wdev */ wdev->netdev = net; -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ ret = register_netdev(net); if (ret) { CFGP2P_ERR((" register_netdevice failed (%d)\n", ret)); free_netdev(net); -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT kfree(wdev); -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ return -ENODEV; } /* store p2p net ptr for further reference. Note that iflist won't have this * entry as there corresponding firmware interface is a "Hidden" interface. */ -#ifndef WL_NEWCFG_PRIVCMD_SUPPORT cfg->p2p_wdev = wdev; -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ cfg->p2p_net = net; - printf("%s: P2P Interface Registered\n", net->name); + printk("%s: P2P Interface Registered\n", net->name); return ret; } @@ -2486,7 +2475,7 @@ static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd return ret; } -#endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */ +#endif #if defined(WL_ENABLE_P2P_IF) static int wl_cfgp2p_if_open(struct net_device *net) @@ -2547,13 +2536,8 @@ wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg) WL_TRACE(("Enter\n")); if (cfg->p2p_wdev) { - CFGP2P_ERR(("p2p_wdev defined already.\n")); -#if (defined(CUSTOMER_HW10) && defined(CONFIG_ARCH_ODIN)) wl_cfgp2p_del_p2p_disc_if(cfg->p2p_wdev, cfg); CFGP2P_ERR(("p2p_wdev deleted.\n")); -#else - return ERR_PTR(-ENFILE); -#endif } wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); @@ -2565,16 +2549,12 @@ wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg) memset(&primary_mac, 0, sizeof(primary_mac)); get_primary_mac(cfg, &primary_mac); wl_cfgp2p_generate_bss_mac(&primary_mac, - &cfg->p2p->dev_addr, &cfg->p2p->int_addr); + &cfg->p2p->dev_addr, &cfg->p2p->int_addr); wdev->wiphy = cfg->wdev->wiphy; wdev->iftype = NL80211_IFTYPE_P2P_DEVICE; memcpy(wdev->address, &cfg->p2p->dev_addr, ETHER_ADDR_LEN); -#if defined(WL_NEWCFG_PRIVCMD_SUPPORT) - if (cfg->p2p_net) - memcpy(cfg->p2p_net->dev_addr, &cfg->p2p->dev_addr, ETHER_ADDR_LEN); -#endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ /* store p2p wdev ptr for further reference. */ cfg->p2p_wdev = wdev; diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h index d35780c41f54e222aec47edcf3f22c8c0f5005f5..f4c7c4ff9b14e2e62b0307315c6f422eb90838f0 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h +++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h @@ -1,7 +1,25 @@ /* * Linux cfgp2p driver * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_cfgp2p.h 472818 2014-04-25 08:07:56Z $ */ @@ -56,7 +74,7 @@ struct p2p_saved_ie { }; struct p2p_bss { - u32 bssidx; + s32 bssidx; struct net_device *dev; struct p2p_saved_ie saved_ie; void *private_data; @@ -134,30 +152,30 @@ enum wl_cfgp2p_status { #define CFGP2P_ERR(args) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - printf(KERN_INFO CFGP2P_ERROR_TEXT "%s : ", __func__); \ - printf args; \ + printk(KERN_INFO CFGP2P_ERROR_TEXT "%s : ", __func__); \ + printk args; \ } \ } while (0) #define CFGP2P_INFO(args) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - printf(KERN_INFO "CFGP2P-INFO) %s : ", __func__); \ - printf args; \ + printk(KERN_INFO "CFGP2P-INFO) %s : ", __func__); \ + printk args; \ } \ } while (0) #define CFGP2P_DBG(args) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printf(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__); \ - printf args; \ + printk(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__); \ + printk args; \ } \ } while (0) #define CFGP2P_ACTION(args) \ do { \ if (wl_dbg_level & WL_DBG_P2P_ACTION) { \ - printf(KERN_DEBUG "CFGP2P-ACTION) %s :", __func__); \ - printf args; \ + printk(KERN_DEBUG "CFGP2P-ACTION) %s :", __func__); \ + printk args; \ } \ } while (0) #define INIT_TIMER(timer, func, duration, extra_delay) \ @@ -189,9 +207,6 @@ enum wl_cfgp2p_status { #endif /* (LINUX_VERSION >= VERSION(3, 8, 0)) */ #ifndef WL_CFG80211_P2P_DEV_IF -#ifdef WL_NEWCFG_PRIVCMD_SUPPORT -#undef WL_NEWCFG_PRIVCMD_SUPPORT -#endif #endif /* WL_CFG80211_P2P_DEV_IF */ #if defined(WL_ENABLE_P2P_IF) && (defined(WL_CFG80211_P2P_DEV_IF) || \ diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c new file mode 100644 index 0000000000000000000000000000000000000000..5f3e70cff0e46019bd5fb1f48716413cd461472d --- /dev/null +++ b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c @@ -0,0 +1,1343 @@ +/* + * Linux cfg80211 Vendor Extension Code + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_cfgvendor.c 473890 2014-04-30 01:55:06Z $ +*/ + +/* + * New vendor interface additon to nl80211/cfg80211 to allow vendors + * to implement proprietary features over the cfg80211 stack. +*/ + +#include <typedefs.h> +#include <linuxver.h> +#include <osl.h> +#include <linux/kernel.h> + +#include <bcmutils.h> +#include <bcmwifi_channels.h> +#include <bcmendian.h> +#include <proto/ethernet.h> +#include <proto/802.11.h> +#include <linux/if_arp.h> +#include <asm/uaccess.h> + + +#include <dngl_stats.h> +#include <dhd.h> +#include <dhdioctl.h> +#include <wlioctl.h> +#include <dhd_cfg80211.h> +#ifdef PNO_SUPPORT +#include <dhd_pno.h> +#endif /* PNO_SUPPORT */ +#ifdef RTT_SUPPORT +#include <dhd_rtt.h> +#endif /* RTT_SUPPORT */ +#include <proto/ethernet.h> +#include <linux/kernel.h> +#include <linux/kthread.h> +#include <linux/netdevice.h> +#include <linux/sched.h> +#include <linux/etherdevice.h> +#include <linux/wireless.h> +#include <linux/ieee80211.h> +#include <linux/wait.h> +#include <net/cfg80211.h> +#include <net/rtnetlink.h> + +#include <wlioctl.h> +#include <wldev_common.h> +#include <wl_cfg80211.h> +#include <wl_cfgp2p.h> +#include <wl_android.h> +#include <wl_cfgvendor.h> +#ifdef PROP_TXSTATUS +#include <dhd_wlfc.h> +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) + +/* + * This API is to be used for asynchronous vendor events. This + * shouldn't be used in response to a vendor command from its + * do_it handler context (instead wl_cfgvendor_send_cmd_reply should + * be used). + */ +int wl_cfgvendor_send_async_event(struct wiphy *wiphy, + struct net_device *dev, int event_id, const void *data, int len) +{ + u16 kflags; + struct sk_buff *skb; + + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_event_alloc(wiphy, len, event_id, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + return -ENOMEM; + } + + /* Push the data to the skb */ + nla_put_nohdr(skb, len, data); + + cfg80211_vendor_event(skb, kflags); + + return 0; +} + +static int wl_cfgvendor_send_cmd_reply(struct wiphy *wiphy, + struct net_device *dev, const void *data, int len) +{ + struct sk_buff *skb; + + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + return -ENOMEM; + } + + /* Push the data to the skb */ + nla_put_nohdr(skb, len, data); + + return cfg80211_vendor_cmd_reply(skb); +} + +static int wl_cfgvendor_get_feature_set(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int reply; + + reply = dhd_dev_get_feature_set(bcmcfg_to_prmry_ndev(cfg)); + + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + &reply, sizeof(int)); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + + return err; +} + +static int wl_cfgvendor_get_feature_set_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + struct sk_buff *skb; + int *reply; + int num, mem_needed, i; + + reply = dhd_dev_get_feature_set_matrix(bcmcfg_to_prmry_ndev(cfg), &num); + + if (!reply) { + WL_ERR(("Could not get feature list matrix\n")); + err = -EINVAL; + return err; + } + + mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * num) + + ATTRIBUTE_U32_LEN; + + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + err = -ENOMEM; + goto exit; + } + + nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, num); + for (i = 0; i < num; i++) { + nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, reply[i]); + } + + err = cfg80211_vendor_cmd_reply(skb); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); +exit: + kfree(reply); + return err; +} + +static int wl_cfgvendor_set_pno_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type; + uint8 pno_random_mac_oui[DOT11_OUI_LEN]; + + type = nla_type(data); + + if (type == ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI) { + memcpy(pno_random_mac_oui, nla_data(data), DOT11_OUI_LEN); + + err = dhd_dev_pno_set_mac_oui(bcmcfg_to_prmry_ndev(cfg), pno_random_mac_oui); + + if (unlikely(err)) + WL_ERR(("Bad OUI, could not set:%d \n", err)); + + } else { + err = -1; + } + + return err; +} + +static int wl_cfgvendor_set_nodfs_flag(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type; + u32 nodfs; + + type = nla_type(data); + if (type == ANDR_WIFI_ATTRIBUTE_NODFS_SET) { + nodfs = nla_get_u32(data); + err = dhd_dev_set_nodfs(bcmcfg_to_prmry_ndev(cfg), nodfs); + } else { + err = -1; + } + return err; +} + +#ifdef GSCAN_SUPPORT +int wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy, + struct net_device *dev, void *data, int len, wl_vendor_event_t event) +{ + u16 kflags; + const void *ptr; + struct sk_buff *skb; + int malloc_len, total, iter_cnt_to_send, cnt; + gscan_results_cache_t *cache = (gscan_results_cache_t *)data; + + total = len/sizeof(wifi_gscan_result_t); + while (total > 0) { + malloc_len = (total * sizeof(wifi_gscan_result_t)) + VENDOR_DATA_OVERHEAD; + if (malloc_len > NLMSG_DEFAULT_SIZE) { + malloc_len = NLMSG_DEFAULT_SIZE; + } + iter_cnt_to_send = + (malloc_len - VENDOR_DATA_OVERHEAD)/sizeof(wifi_gscan_result_t); + total = total - iter_cnt_to_send; + + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_event_alloc(wiphy, malloc_len, event, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + return -ENOMEM; + } + + while (cache && iter_cnt_to_send) { + ptr = (const void *) &cache->results[cache->tot_consumed]; + + if (iter_cnt_to_send < (cache->tot_count - cache->tot_consumed)) + cnt = iter_cnt_to_send; + else + cnt = (cache->tot_count - cache->tot_consumed); + + iter_cnt_to_send -= cnt; + cache->tot_consumed += cnt; + /* Push the data to the skb */ + nla_append(skb, cnt * sizeof(wifi_gscan_result_t), ptr); + if (cache->tot_consumed == cache->tot_count) + cache = cache->next; + + } + + cfg80211_vendor_event(skb, kflags); + } + + return 0; +} + + +static int wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + dhd_pno_gscan_capabilities_t *reply = NULL; + uint32 reply_len = 0; + + + reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_CAPABILITIES, NULL, &reply_len); + if (!reply) { + WL_ERR(("Could not get capabilities\n")); + err = -EINVAL; + return err; + } + + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + reply, reply_len); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + + kfree(reply); + return err; +} + +static int wl_cfgvendor_gscan_get_channel_list(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0, type, band; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + uint16 *reply = NULL; + uint32 reply_len = 0, num_channels, mem_needed; + struct sk_buff *skb; + + type = nla_type(data); + + if (type == GSCAN_ATTRIBUTE_BAND) { + band = nla_get_u32(data); + } else { + return -1; + } + + reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_CHANNEL_LIST, &band, &reply_len); + + if (!reply) { + WL_ERR(("Could not get channel list\n")); + err = -EINVAL; + return err; + } + num_channels = reply_len/ sizeof(uint32); + mem_needed = reply_len + VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 2); + + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + err = -ENOMEM; + goto exit; + } + + nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channels); + nla_put(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, reply_len, reply); + + err = cfg80211_vendor_cmd_reply(skb); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); +exit: + kfree(reply); + return err; +} + +static int wl_cfgvendor_gscan_get_batch_results(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_results_cache_t *results, *iter; + uint32 reply_len, complete = 0, num_results_iter; + int32 mem_needed; + wifi_gscan_result_t *ptr; + uint16 num_scan_ids, num_results; + struct sk_buff *skb; + struct nlattr *scan_hdr; + + dhd_dev_wait_batch_results_complete(bcmcfg_to_prmry_ndev(cfg)); + dhd_dev_pno_lock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + results = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GET_BATCH_RESULTS, NULL, &reply_len); + + if (!results) { + WL_ERR(("No results to send %d\n", err)); + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + results, 0); + + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + return err; + } + num_scan_ids = reply_len & 0xFFFF; + num_results = (reply_len & 0xFFFF0000) >> 16; + mem_needed = (num_results * sizeof(wifi_gscan_result_t)) + + (num_scan_ids * GSCAN_BATCH_RESULT_HDR_LEN) + + VENDOR_REPLY_OVERHEAD + SCAN_RESULTS_COMPLETE_FLAG_LEN; + + if (mem_needed > (int32)NLMSG_DEFAULT_SIZE) { + mem_needed = (int32)NLMSG_DEFAULT_SIZE; + complete = 0; + } else { + complete = 1; + } + + WL_TRACE(("complete %d mem_needed %d max_mem %d\n", complete, mem_needed, + (int)NLMSG_DEFAULT_SIZE)); + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); + if (unlikely(!skb)) { + WL_ERR(("skb alloc failed")); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + return -ENOMEM; + } + iter = results; + + nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, complete); + + mem_needed = mem_needed - (SCAN_RESULTS_COMPLETE_FLAG_LEN + VENDOR_REPLY_OVERHEAD); + + while (iter && ((mem_needed - GSCAN_BATCH_RESULT_HDR_LEN) > 0)) { + scan_hdr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); + nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_ID, iter->scan_id); + nla_put_u8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, iter->flag); + num_results_iter = + (mem_needed - GSCAN_BATCH_RESULT_HDR_LEN)/sizeof(wifi_gscan_result_t); + + if ((iter->tot_count - iter->tot_consumed) < num_results_iter) + num_results_iter = iter->tot_count - iter->tot_consumed; + + nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num_results_iter); + if (num_results_iter) { + ptr = &iter->results[iter->tot_consumed]; + iter->tot_consumed += num_results_iter; + nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, + num_results_iter * sizeof(wifi_gscan_result_t), ptr); + } + nla_nest_end(skb, scan_hdr); + mem_needed -= GSCAN_BATCH_RESULT_HDR_LEN + + (num_results_iter * sizeof(wifi_gscan_result_t)); + iter = iter->next; + } + + dhd_dev_gscan_batch_cache_cleanup(bcmcfg_to_prmry_ndev(cfg)); + dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); + + return cfg80211_vendor_cmd_reply(skb); +} + +static int wl_cfgvendor_initiate_gscan(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type, tmp = len; + int run = 0xFF; + int flush = 0; + const struct nlattr *iter; + + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + if (type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) + run = nla_get_u32(iter); + else if (type == GSCAN_ATTRIBUTE_FLUSH_FEATURE) + flush = nla_get_u32(iter); + } + + if (run != 0xFF) { + err = dhd_dev_pno_run_gscan(bcmcfg_to_prmry_ndev(cfg), run, flush); + + if (unlikely(err)) + WL_ERR(("Could not run gscan:%d \n", err)); + return err; + } else { + return -1; + } + + +} + +static int wl_cfgvendor_enable_full_scan_result(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int type; + bool real_time = FALSE; + + type = nla_type(data); + + if (type == GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS) { + real_time = nla_get_u32(data); + + err = dhd_dev_pno_enable_full_scan_result(bcmcfg_to_prmry_ndev(cfg), real_time); + + if (unlikely(err)) + WL_ERR(("Could not run gscan:%d \n", err)); + + } else { + err = -1; + } + + return err; +} + +static int wl_cfgvendor_set_scan_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_scan_params_t *scan_param; + int j = 0; + int type, tmp, tmp1, tmp2, k = 0; + const struct nlattr *iter, *iter1, *iter2; + struct dhd_pno_gscan_channel_bucket *ch_bucket; + + scan_param = kzalloc(sizeof(gscan_scan_params_t), GFP_KERNEL); + if (!scan_param) { + WL_ERR(("Could not set GSCAN scan cfg, mem alloc failure\n")); + err = -EINVAL; + return err; + + } + + scan_param->scan_fr = PNO_SCAN_MIN_FW_SEC; + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + + if (j >= GSCAN_MAX_CH_BUCKETS) + break; + + switch (type) { + case GSCAN_ATTRIBUTE_BASE_PERIOD: + scan_param->scan_fr = nla_get_u32(iter)/1000; + break; + case GSCAN_ATTRIBUTE_NUM_BUCKETS: + scan_param->nchannel_buckets = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_CH_BUCKET_1: + case GSCAN_ATTRIBUTE_CH_BUCKET_2: + case GSCAN_ATTRIBUTE_CH_BUCKET_3: + case GSCAN_ATTRIBUTE_CH_BUCKET_4: + case GSCAN_ATTRIBUTE_CH_BUCKET_5: + case GSCAN_ATTRIBUTE_CH_BUCKET_6: + case GSCAN_ATTRIBUTE_CH_BUCKET_7: + nla_for_each_nested(iter1, iter, tmp1) { + type = nla_type(iter1); + ch_bucket = + scan_param->channel_bucket; + + switch (type) { + case GSCAN_ATTRIBUTE_BUCKET_ID: + break; + case GSCAN_ATTRIBUTE_BUCKET_PERIOD: + ch_bucket[j].bucket_freq_multiple = + nla_get_u32(iter1)/1000; + break; + case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: + ch_bucket[j].num_channels = + nla_get_u32(iter1); + break; + case GSCAN_ATTRIBUTE_BUCKET_CHANNELS: + nla_for_each_nested(iter2, iter1, tmp2) { + if (k >= PFN_SWC_RSSI_WINDOW_MAX) + break; + ch_bucket[j].chan_list[k] = + nla_get_u32(iter2); + k++; + } + k = 0; + break; + case GSCAN_ATTRIBUTE_BUCKETS_BAND: + ch_bucket[j].band = (uint16) + nla_get_u32(iter1); + break; + case GSCAN_ATTRIBUTE_REPORT_EVENTS: + ch_bucket[j].report_flag = (uint8) + nla_get_u32(iter1); + break; + } + } + j++; + break; + } + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_SCAN_CFG_ID, scan_param, 0) < 0) { + WL_ERR(("Could not set GSCAN scan cfg\n")); + err = -EINVAL; + } + + kfree(scan_param); + return err; + +} + +static int wl_cfgvendor_hotlist_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_hotlist_scan_params_t *hotlist_params; + int tmp, tmp1, tmp2, type, j = 0, dummy; + const struct nlattr *outer, *inner, *iter; + uint8 flush = 0; + struct bssid_t *pbssid; + + hotlist_params = (gscan_hotlist_scan_params_t *)kzalloc(len, GFP_KERNEL); + if (!hotlist_params) { + WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); + return -1; + } + + hotlist_params->lost_ap_window = GSCAN_LOST_AP_WINDOW_DEFAULT; + + nla_for_each_attr(iter, data, len, tmp2) { + type = nla_type(iter); + switch (type) { + case GSCAN_ATTRIBUTE_HOTLIST_BSSIDS: + pbssid = hotlist_params->bssid; + nla_for_each_nested(outer, iter, tmp) { + nla_for_each_nested(inner, outer, tmp1) { + type = nla_type(inner); + + switch (type) { + case GSCAN_ATTRIBUTE_BSSID: + memcpy(&(pbssid[j].macaddr), + nla_data(inner), ETHER_ADDR_LEN); + break; + case GSCAN_ATTRIBUTE_RSSI_LOW: + pbssid[j].rssi_reporting_threshold = + (int8) nla_get_u8(inner); + break; + case GSCAN_ATTRIBUTE_RSSI_HIGH: + dummy = (int8) nla_get_u8(inner); + break; + } + } + j++; + } + hotlist_params->nbssid = j; + break; + case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: + flush = nla_get_u8(iter); + break; + case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: + hotlist_params->lost_ap_window = nla_get_u32(iter); + break; + } + + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_GEOFENCE_SCAN_CFG_ID, hotlist_params, flush) < 0) { + WL_ERR(("Could not set GSCAN HOTLIST cfg\n")); + err = -EINVAL; + goto exit; + } +exit: + kfree(hotlist_params); + return err; +} +static int wl_cfgvendor_set_batch_scan_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0, tmp, type; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_batch_params_t batch_param; + const struct nlattr *iter; + + batch_param.mscan = batch_param.bestn = 0; + batch_param.buffer_threshold = GSCAN_BATCH_NO_THR_SET; + + nla_for_each_attr(iter, data, len, tmp) { + type = nla_type(iter); + + switch (type) { + case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: + batch_param.bestn = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: + batch_param.mscan = nla_get_u32(iter); + break; + case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: + batch_param.buffer_threshold = nla_get_u32(iter); + break; + } + } + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_BATCH_SCAN_CFG_ID, &batch_param, 0) < 0) { + WL_ERR(("Could not set batch cfg\n")); + err = -EINVAL; + return err; + } + + return err; +} + +static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + gscan_swc_params_t *significant_params; + int tmp, tmp1, tmp2, type, j = 0; + const struct nlattr *outer, *inner, *iter; + uint8 flush = 0; + wl_pfn_significant_bssid_t *pbssid; + + significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL); + if (!significant_params) { + WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); + return -1; + } + + + nla_for_each_attr(iter, data, len, tmp2) { + type = nla_type(iter); + + switch (type) { + case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: + flush = nla_get_u8(iter); + break; + case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: + significant_params->rssi_window = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: + significant_params->lost_ap_window = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_MIN_BREACHING: + significant_params->swc_threshold = nla_get_u16(iter); + break; + case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS: + pbssid = significant_params->bssid_elem_list; + nla_for_each_nested(outer, iter, tmp) { + nla_for_each_nested(inner, outer, tmp1) { + switch (nla_type(inner)) { + case GSCAN_ATTRIBUTE_BSSID: + memcpy(&(pbssid[j].macaddr), + nla_data(inner), + ETHER_ADDR_LEN); + break; + case GSCAN_ATTRIBUTE_RSSI_HIGH: + pbssid[j].rssi_high_threshold = + (int8) nla_get_u8(inner); + break; + case GSCAN_ATTRIBUTE_RSSI_LOW: + pbssid[j].rssi_low_threshold = + (int8) nla_get_u8(inner); + break; + } + } + j++; + } + break; + } + } + significant_params->nbssid = j; + + if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), + DHD_PNO_SIGNIFICANT_SCAN_CFG_ID, significant_params, flush) < 0) { + WL_ERR(("Could not set GSCAN significant cfg\n")); + err = -EINVAL; + goto exit; + } +exit: + kfree(significant_params); + return err; +} +#endif /* GSCAN_SUPPORT */ + +#ifdef RTT_SUPPORT +void wl_cfgvendor_rtt_evt(void *ctx, void *rtt_data) +{ + struct wireless_dev *wdev = (struct wireless_dev *)ctx; + struct wiphy *wiphy; + struct sk_buff *skb; + uint32 tot_len = NLMSG_DEFAULT_SIZE, entry_len = 0; + gfp_t kflags; + rtt_report_t *rtt_report = NULL; + rtt_result_t *rtt_result = NULL; + struct list_head *rtt_list; + wiphy = wdev->wiphy; + + WL_DBG(("In\n")); + /* Push the data to the skb */ + if (!rtt_data) { + WL_ERR(("rtt_data is NULL\n")); + goto exit; + } + rtt_list = (struct list_head *)rtt_data; + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + /* Alloc the SKB for vendor_event */ + skb = cfg80211_vendor_event_alloc(wiphy, tot_len, GOOGLE_RTT_COMPLETE_EVENT, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + goto exit; + } + /* fill in the rtt results on each entry */ + list_for_each_entry(rtt_result, rtt_list, list) { + entry_len = 0; + entry_len = sizeof(rtt_report_t); + rtt_report = kzalloc(entry_len, kflags); + if (!rtt_report) { + WL_ERR(("rtt_report alloc failed")); + goto exit; + } + rtt_report->addr = rtt_result->peer_mac; + rtt_report->num_measurement = 1; /* ONE SHOT */ + rtt_report->status = rtt_result->err_code; + rtt_report->type = (rtt_result->TOF_type == TOF_TYPE_ONE_WAY) ? RTT_ONE_WAY: RTT_TWO_WAY; + rtt_report->peer = rtt_result->target_info->peer; + rtt_report->channel = rtt_result->target_info->channel; + rtt_report->rssi = rtt_result->avg_rssi; + /* tx_rate */ + rtt_report->tx_rate = rtt_result->tx_rate; + /* RTT */ + rtt_report->rtt = rtt_result->meanrtt; + rtt_report->rtt_sd = rtt_result->sdrtt/10; + /* convert to centi meter */ + if (rtt_result->distance != 0xffffffff) + rtt_report->distance = (rtt_result->distance >> 2) * 25; + else /* invalid distance */ + rtt_report->distance = -1; + rtt_report->ts = rtt_result->ts; + nla_append(skb, entry_len, rtt_report); + kfree(rtt_report); + } + cfg80211_vendor_event(skb, kflags); +exit: + return; +} + +static int wl_cfgvendor_rtt_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) { + int err = 0, rem, rem1, rem2, type; + rtt_config_params_t rtt_param; + rtt_target_info_t* rtt_target = NULL; + const struct nlattr *iter, *iter1, *iter2; + int8 eabuf[ETHER_ADDR_STR_LEN]; + int8 chanbuf[CHANSPEC_STR_LEN]; + int32 feature_set = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + feature_set = dhd_dev_get_feature_set(bcmcfg_to_prmry_ndev(cfg)); + + WL_DBG(("In\n")); + err = dhd_dev_rtt_register_noti_callback(wdev->netdev, wdev, wl_cfgvendor_rtt_evt); + if (err < 0) { + WL_ERR(("failed to register rtt_noti_callback\n")); + goto exit; + } + memset(&rtt_param, 0, sizeof(rtt_param)); + nla_for_each_attr(iter, data, len, rem) { + type = nla_type(iter); + switch (type) { + case RTT_ATTRIBUTE_TARGET_CNT: + rtt_param.rtt_target_cnt = nla_get_u8(iter); + if (rtt_param.rtt_target_cnt > RTT_MAX_TARGET_CNT) { + WL_ERR(("exceed max target count : %d\n", + rtt_param.rtt_target_cnt)); + err = BCME_RANGE; + goto exit; + } + break; + case RTT_ATTRIBUTE_TARGET_INFO: + rtt_target = rtt_param.target_info; + nla_for_each_nested(iter1, iter, rem1) { + nla_for_each_nested(iter2, iter1, rem2) { + type = nla_type(iter2); + switch (type) { + case RTT_ATTRIBUTE_TARGET_MAC: + memcpy(&rtt_target->addr, nla_data(iter2), + ETHER_ADDR_LEN); + break; + case RTT_ATTRIBUTE_TARGET_TYPE: + rtt_target->type = nla_get_u8(iter2); + if (!(feature_set & WIFI_FEATURE_D2D_RTT)) { + if (rtt_target->type == RTT_TWO_WAY || + rtt_target->type == RTT_INVALID) { + WL_ERR(("doesn't support RTT type : %d\n", + rtt_target->type)); + err = -EINVAL; + goto exit; + } else if (rtt_target->type == RTT_AUTO) { + rtt_target->type = RTT_ONE_WAY; + } + } else { + if (rtt_target->type == RTT_INVALID) { + WL_ERR(("doesn't support RTT type : %d\n", + rtt_target->type)); + err = -EINVAL; + goto exit; + } + } + break; + case RTT_ATTRIBUTE_TARGET_PEER: + rtt_target->peer= nla_get_u8(iter2); + if (rtt_target->peer != RTT_PEER_AP) { + WL_ERR(("doesn't support peer type : %d\n", + rtt_target->peer)); + err = -EINVAL; + goto exit; + } + break; + case RTT_ATTRIBUTE_TARGET_CHAN: + memcpy(&rtt_target->channel, nla_data(iter2), + sizeof(rtt_target->channel)); + break; + case RTT_ATTRIBUTE_TARGET_MODE: + rtt_target->continuous = nla_get_u8(iter2); + break; + case RTT_ATTRIBUTE_TARGET_INTERVAL: + rtt_target->interval = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT: + rtt_target->measure_cnt = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_PKT: + rtt_target->ftm_cnt = nla_get_u32(iter2); + break; + case RTT_ATTRIBUTE_TARGET_NUM_RETRY: + rtt_target->retry_cnt = nla_get_u32(iter2); + } + } + /* convert to chanspec value */ + rtt_target->chanspec = dhd_rtt_convert_to_chspec(rtt_target->channel); + if (rtt_target->chanspec == 0) { + WL_ERR(("Channel is not valid \n")); + goto exit; + } + WL_INFORM(("Target addr %s, Channel : %s for RTT \n", + bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf), + wf_chspec_ntoa(rtt_target->chanspec, chanbuf))); + rtt_target++; + } + break; + } + } + WL_DBG(("leave :target_cnt : %d\n", rtt_param.rtt_target_cnt)); + if (dhd_dev_rtt_set_cfg(bcmcfg_to_prmry_ndev(cfg), &rtt_param) < 0) { + WL_ERR(("Could not set RTT configuration\n")); + err = -EINVAL; + } +exit: + return err; +} + +static int wl_cfgvendor_rtt_cancel_config(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int err = 0, rem, type, target_cnt = 0; + const struct nlattr *iter; + struct ether_addr *mac_list = NULL, *mac_addr = NULL; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + + nla_for_each_attr(iter, data, len, rem) { + type = nla_type(iter); + switch (type) { + case RTT_ATTRIBUTE_TARGET_CNT: + target_cnt = nla_get_u8(iter); + mac_list = (struct ether_addr *)kzalloc(target_cnt * ETHER_ADDR_LEN , GFP_KERNEL); + if (mac_list == NULL) { + WL_ERR(("failed to allocate mem for mac list\n")); + goto exit; + } + mac_addr = &mac_list[0]; + break; + case RTT_ATTRIBUTE_TARGET_MAC: + if (mac_addr) + memcpy(mac_addr++, nla_data(iter), ETHER_ADDR_LEN); + else { + WL_ERR(("mac_list is NULL\n")); + goto exit; + } + break; + } + if (dhd_dev_rtt_cancel_cfg(bcmcfg_to_prmry_ndev(cfg), mac_list, target_cnt) < 0) { + WL_ERR(("Could not cancel RTT configuration\n")); + err = -EINVAL; + goto exit; + } + } +exit: + if (mac_list) + kfree(mac_list); + return err; +} +static int wl_cfgvendor_rtt_get_capability(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int len) +{ + int err = 0; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + rtt_capabilities_t capability; + + err = dhd_dev_rtt_capability(bcmcfg_to_prmry_ndev(cfg), &capability); + if (unlikely(err)) { + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + goto exit; + } + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + &capability, sizeof(capability)); + + if (unlikely(err)) { + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + } +exit: + return err; +} + +#endif /* RTT_SUPPORT */ +static int wl_cfgvendor_priv_string_handler(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int err = 0; + int data_len = 0; + + bzero(cfg->ioctl_buf, WLC_IOCTL_MAXLEN); + + if (strncmp((char *)data, BRCM_VENDOR_SCMD_CAPA, strlen(BRCM_VENDOR_SCMD_CAPA)) == 0) { + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "cap", NULL, 0, + cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); + if (unlikely(err)) { + WL_ERR(("error (%d)\n", err)); + return err; + } + data_len = strlen(cfg->ioctl_buf); + cfg->ioctl_buf[data_len] = '\0'; + } + + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + cfg->ioctl_buf, data_len+1); + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + else + WL_INFORM(("Vendor Command reply sent successfully!\n")); + + return err; +} + +#ifdef LINKSTAT_SUPPORT +#define NUM_RATE 32 +#define NUM_PEER 1 +#define NUM_CHAN 11 +static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + static char iovar_buf[WLC_IOCTL_MAXLEN]; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + int err = 0; + wifi_iface_stat *iface; + wifi_radio_stat *radio; + wl_wme_cnt_t *wl_wme_cnt; + wl_cnt_t *wl_cnt; + char *output; + + WL_INFORM(("%s: Enter \n", __func__)); + + bzero(cfg->ioctl_buf, WLC_IOCTL_MAXLEN); + bzero(iovar_buf, WLC_IOCTL_MAXLEN); + + output = cfg->ioctl_buf; + radio = (wifi_radio_stat *)output; + + /* delete becauseof not support + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "radiostat", NULL, 0, + iovar_buf, WLC_IOCTL_MAXLEN, NULL); + if (unlikely(err)) { + WL_ERR(("1 error (%d) - size = %zu\n", err, sizeof(wifi_radio_stat))); + return err; + } + memcpy(output, iovar_buf, sizeof(wifi_radio_stat)); + */ + radio->num_channels = NUM_CHAN; + output += sizeof(wifi_radio_stat); + output += (NUM_CHAN*sizeof(wifi_channel_stat)); + + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "wme_counters", NULL, 0, + iovar_buf, WLC_IOCTL_MAXLEN, NULL); + if (unlikely(err)) { + WL_ERR(("error (%d)\n", err)); + return err; + } + wl_wme_cnt = (wl_wme_cnt_t *)iovar_buf; + iface = (wifi_iface_stat *)output; + + iface->ac[WIFI_AC_VO].ac = WIFI_AC_VO; + iface->ac[WIFI_AC_VO].tx_mpdu = wl_wme_cnt->tx[AC_VO].packets; + iface->ac[WIFI_AC_VO].rx_mpdu = wl_wme_cnt->rx[AC_VO].packets; + iface->ac[WIFI_AC_VO].mpdu_lost = wl_wme_cnt->tx_failed[WIFI_AC_VO].packets; + + iface->ac[WIFI_AC_VI].ac = WIFI_AC_VI; + iface->ac[WIFI_AC_VI].tx_mpdu = wl_wme_cnt->tx[AC_VI].packets; + iface->ac[WIFI_AC_VI].rx_mpdu = wl_wme_cnt->rx[AC_VI].packets; + iface->ac[WIFI_AC_VI].mpdu_lost = wl_wme_cnt->tx_failed[WIFI_AC_VI].packets; + + iface->ac[WIFI_AC_BE].ac = WIFI_AC_BE; + iface->ac[WIFI_AC_BE].tx_mpdu = wl_wme_cnt->tx[AC_BE].packets; + iface->ac[WIFI_AC_BE].rx_mpdu = wl_wme_cnt->rx[AC_BE].packets; + iface->ac[WIFI_AC_BE].mpdu_lost = wl_wme_cnt->tx_failed[WIFI_AC_BE].packets; + + iface->ac[WIFI_AC_BK].ac = WIFI_AC_BK; + iface->ac[WIFI_AC_BK].tx_mpdu = wl_wme_cnt->tx[AC_BK].packets; + iface->ac[WIFI_AC_BK].rx_mpdu = wl_wme_cnt->rx[AC_BK].packets; + iface->ac[WIFI_AC_BK].mpdu_lost = wl_wme_cnt->tx_failed[WIFI_AC_BK].packets; + bzero(iovar_buf, WLC_IOCTL_MAXLEN); + + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "counters", NULL, 0, + iovar_buf, WLC_IOCTL_MAXLEN, NULL); + if (unlikely(err)) { + WL_ERR(("error (%d) - size = %zu\n", err, sizeof(wl_cnt_t))); + return err; + } + wl_cnt = (wl_cnt_t *)iovar_buf; + iface->ac[WIFI_AC_BE].retries = wl_cnt->txretry; + iface->beacon_rx = wl_cnt->rxbeaconmbss; + + err = wldev_get_rssi(bcmcfg_to_prmry_ndev(cfg), &iface->rssi_mgmt); + if (unlikely(err)) { + WL_ERR(("get_rssi error (%d)\n", err)); + return err; + } + + iface->num_peers = NUM_PEER; + iface->peer_info->num_rate = NUM_RATE; + + bzero(iovar_buf, WLC_IOCTL_MAXLEN); + output = (char *)iface + sizeof(wifi_iface_stat) + NUM_PEER*sizeof(wifi_peer_info); + + /* delete becauseof not support + err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "ratestat", NULL, 0, + iovar_buf, WLC_IOCTL_MAXLEN, NULL); + if (unlikely(err)) { + WL_ERR(("3 error (%d) - size = %zu\n", err, NUM_RATE*sizeof(wifi_rate_stat))); + return err; + } + memcpy(output, iovar_buf, NUM_RATE*sizeof(wifi_rate_stat)); + */ + err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), + cfg->ioctl_buf, sizeof(wifi_radio_stat)+NUM_CHAN*sizeof(wifi_channel_stat)+ + sizeof(wifi_iface_stat)+NUM_PEER*sizeof(wifi_peer_info)+ + NUM_RATE*sizeof(wifi_rate_stat)); + if (unlikely(err)) + WL_ERR(("Vendor Command reply failed ret:%d \n", err)); + + return err; +} +#endif /* LINKSTAT_SUPPORT */ + +static const struct wiphy_vendor_command wl_vendor_cmds [] = { + { + { + .vendor_id = OUI_BRCM, + .subcmd = BRCM_VENDOR_SCMD_PRIV_STR + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_priv_string_handler + }, +#ifdef GSCAN_SUPPORT + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_capabilities + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_scan_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_batch_scan_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_initiate_gscan + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_enable_full_scan_result + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_HOTLIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_hotlist_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_significant_change_cfg + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_batch_results + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_gscan_get_channel_list + }, +#endif /* GSCAN_SUPPORT */ +#ifdef RTT_SUPPORT + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_set_config + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_CANCEL_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_cancel_config + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = RTT_SUBCMD_GETCAPABILITY + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_rtt_get_capability + }, +#endif /* RTT_SUPPORT */ + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_get_feature_set + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_get_feature_set_matrix + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_PNO_RANDOM_MAC_OUI + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_pno_mac_oui + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = ANDR_WIFI_NODFS_CHANNELS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_set_nodfs_flag + + }, +#ifdef LINKSTAT_SUPPORT + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = LSTATS_SUBCMD_GET_INFO + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wl_cfgvendor_lstats_get_info + }, +#endif /* LINKSTAT_SUPPORT */ +}; + +static const struct nl80211_vendor_cmd_info wl_vendor_events [] = { + { OUI_BRCM, BRCM_VENDOR_EVENT_UNSPEC }, + { OUI_BRCM, BRCM_VENDOR_EVENT_PRIV_STR }, +#ifdef GSCAN_SUPPORT + { OUI_GOOGLE, GOOGLE_GSCAN_SIGNIFICANT_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_BATCH_SCAN_EVENT }, + { OUI_GOOGLE, GOOGLE_SCAN_FULL_RESULTS_EVENT }, +#endif /* GSCAN_SUPPORT */ +#ifdef RTT_SUPPORT + { OUI_GOOGLE, GOOGLE_RTT_COMPLETE_EVENT }, +#endif /* RTT_SUPPORT */ +#ifdef GSCAN_SUPPORT + { OUI_GOOGLE, GOOGLE_SCAN_COMPLETE_EVENT }, + { OUI_GOOGLE, GOOGLE_GSCAN_GEOFENCE_LOST_EVENT } +#endif /* GSCAN_SUPPORT */ +}; + +int wl_cfgvendor_attach(struct wiphy *wiphy) +{ + + WL_INFORM(("Vendor: Register BRCM cfg80211 vendor cmd(0x%x) interface \n", + NL80211_CMD_VENDOR)); + + wiphy->vendor_commands = wl_vendor_cmds; + wiphy->n_vendor_commands = ARRAY_SIZE(wl_vendor_cmds); + wiphy->vendor_events = wl_vendor_events; + wiphy->n_vendor_events = ARRAY_SIZE(wl_vendor_events); + + return 0; +} + +int wl_cfgvendor_detach(struct wiphy *wiphy) +{ + WL_INFORM(("Vendor: Unregister BRCM cfg80211 vendor interface \n")); + + wiphy->vendor_commands = NULL; + wiphy->vendor_events = NULL; + wiphy->n_vendor_commands = 0; + wiphy->n_vendor_events = 0; + + return 0; +} +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.h b/drivers/net/wireless/bcmdhd/wl_cfgvendor.h index a98c2c2b1f2a4ff93743d35fd214a2721bc03565..5bc840fc18e4099d8a1f9a0181e674c59ebe63ef 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgvendor.h +++ b/drivers/net/wireless/bcmdhd/wl_cfgvendor.h @@ -1,9 +1,27 @@ /* * Linux cfg80211 Vendor Extension Code * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation * - * $Id: wl_cfgvendor.h 455257 2014-02-20 08:10:24Z $ + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_cfgvendor.h 473890 2014-04-30 01:55:06Z $ */ /* @@ -14,24 +32,229 @@ #ifndef _wl_cfgvendor_h_ #define _wl_cfgvendor_h_ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) && !defined(VENDOR_EXT_SUPPORT) -#define VENDOR_EXT_SUPPORT -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0) && !VENDOR_EXT_SUPPORT */ +#define OUI_BRCM 0x001018 +#define OUI_GOOGLE 0x001A11 +#define BRCM_VENDOR_SUBCMD_PRIV_STR 1 +#define ATTRIBUTE_U32_LEN (NLA_HDRLEN + 4) +#define VENDOR_ID_OVERHEAD ATTRIBUTE_U32_LEN +#define VENDOR_SUBCMD_OVERHEAD ATTRIBUTE_U32_LEN +#define VENDOR_DATA_OVERHEAD (NLA_HDRLEN) + +#define SCAN_RESULTS_COMPLETE_FLAG_LEN ATTRIBUTE_U32_LEN +#define SCAN_INDEX_HDR_LEN (NLA_HDRLEN) +#define SCAN_ID_HDR_LEN ATTRIBUTE_U32_LEN +#define SCAN_FLAGS_HDR_LEN ATTRIBUTE_U32_LEN +#define GSCAN_NUM_RESULTS_HDR_LEN ATTRIBUTE_U32_LEN +#define GSCAN_RESULTS_HDR_LEN (NLA_HDRLEN) +#define GSCAN_BATCH_RESULT_HDR_LEN (SCAN_INDEX_HDR_LEN + SCAN_ID_HDR_LEN + \ + SCAN_FLAGS_HDR_LEN + \ + GSCAN_NUM_RESULTS_HDR_LEN + \ + GSCAN_RESULTS_HDR_LEN) + +#define VENDOR_REPLY_OVERHEAD (VENDOR_ID_OVERHEAD + \ + VENDOR_SUBCMD_OVERHEAD + \ + VENDOR_DATA_OVERHEAD) +typedef enum { + /* don't use 0 as a valid subcommand */ + VENDOR_NL80211_SUBCMD_UNSPECIFIED, + + /* define all vendor startup commands between 0x0 and 0x0FFF */ + VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001, + VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF, + + /* define all GScan related commands between 0x1000 and 0x10FF */ + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, + + /* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF, + + /* define all RTT related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, + + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, + + ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300, + ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF, + /* This is reserved for future usage */ + +} ANDROID_VENDOR_SUB_COMMAND; + +enum wl_vendor_subcmd { + BRCM_VENDOR_SCMD_UNSPEC, + BRCM_VENDOR_SCMD_PRIV_STR, + GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, + GSCAN_SUBCMD_SET_CONFIG, + GSCAN_SUBCMD_SET_SCAN_CONFIG, + GSCAN_SUBCMD_ENABLE_GSCAN, + GSCAN_SUBCMD_GET_SCAN_RESULTS, + GSCAN_SUBCMD_SCAN_RESULTS, + GSCAN_SUBCMD_SET_HOTLIST, + GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, + GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, + GSCAN_SUBCMD_GET_CHANNEL_LIST, + ANDR_WIFI_SUBCMD_GET_FEATURE_SET, + ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, + ANDR_WIFI_PNO_RANDOM_MAC_OUI, + ANDR_WIFI_NODFS_CHANNELS, + RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, + RTT_SUBCMD_CANCEL_CONFIG, + RTT_SUBCMD_GETCAPABILITY, + + LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, + /* Add more sub commands here */ + VENDOR_SUBCMD_MAX +}; + +enum gscan_attributes { + GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, + GSCAN_ATTRIBUTE_BASE_PERIOD, + GSCAN_ATTRIBUTE_BUCKETS_BAND, + GSCAN_ATTRIBUTE_BUCKET_ID, + GSCAN_ATTRIBUTE_BUCKET_PERIOD, + GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, + GSCAN_ATTRIBUTE_BUCKET_CHANNELS, + GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, + GSCAN_ATTRIBUTE_REPORT_THRESHOLD, + GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, + GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, + + GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, + GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, + GSCAN_ATTRIBUTE_FLUSH_FEATURE, + GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS, + GSCAN_ATTRIBUTE_REPORT_EVENTS, + /* remaining reserved for additional attributes */ + GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, + GSCAN_ATTRIBUTE_FLUSH_RESULTS, + GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ + GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ + GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ + GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ + GSCAN_ATTRIBUTE_NUM_CHANNELS, + GSCAN_ATTRIBUTE_CHANNEL_LIST, -enum wl_vendor_event { + /* remaining reserved for additional attributes */ + + GSCAN_ATTRIBUTE_SSID = 40, + GSCAN_ATTRIBUTE_BSSID, + GSCAN_ATTRIBUTE_CHANNEL, + GSCAN_ATTRIBUTE_RSSI, + GSCAN_ATTRIBUTE_TIMESTAMP, + GSCAN_ATTRIBUTE_RTT, + GSCAN_ATTRIBUTE_RTTSD, + + /* remaining reserved for additional attributes */ + + GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, + GSCAN_ATTRIBUTE_RSSI_LOW, + GSCAN_ATTRIBUTE_RSSI_HIGH, + GSCAN_ATTRIBUTE_HOSTLIST_BSSID_ELEM, + GSCAN_ATTRIBUTE_HOTLIST_FLUSH, + + /* remaining reserved for additional attributes */ + GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, + GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, + GSCAN_ATTRIBUTE_MIN_BREACHING, + GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, + GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, + GSCAN_ATTRIBUTE_MAX +}; + +enum gscan_bucket_attributes { + GSCAN_ATTRIBUTE_CH_BUCKET_1, + GSCAN_ATTRIBUTE_CH_BUCKET_2, + GSCAN_ATTRIBUTE_CH_BUCKET_3, + GSCAN_ATTRIBUTE_CH_BUCKET_4, + GSCAN_ATTRIBUTE_CH_BUCKET_5, + GSCAN_ATTRIBUTE_CH_BUCKET_6, + GSCAN_ATTRIBUTE_CH_BUCKET_7 +}; + +enum gscan_ch_attributes { + GSCAN_ATTRIBUTE_CH_ID_1, + GSCAN_ATTRIBUTE_CH_ID_2, + GSCAN_ATTRIBUTE_CH_ID_3, + GSCAN_ATTRIBUTE_CH_ID_4, + GSCAN_ATTRIBUTE_CH_ID_5, + GSCAN_ATTRIBUTE_CH_ID_6, + GSCAN_ATTRIBUTE_CH_ID_7 +}; + +enum rtt_attributes { + RTT_ATTRIBUTE_TARGET_CNT, + RTT_ATTRIBUTE_TARGET_INFO, + RTT_ATTRIBUTE_TARGET_MAC, + RTT_ATTRIBUTE_TARGET_TYPE, + RTT_ATTRIBUTE_TARGET_PEER, + RTT_ATTRIBUTE_TARGET_CHAN, + RTT_ATTRIBUTE_TARGET_MODE, + RTT_ATTRIBUTE_TARGET_INTERVAL, + RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT, + RTT_ATTRIBUTE_TARGET_NUM_PKT, + RTT_ATTRIBUTE_TARGET_NUM_RETRY +}; + +typedef enum wl_vendor_event { BRCM_VENDOR_EVENT_UNSPEC, - BRCM_VENDOR_EVENT_PRIV_STR + BRCM_VENDOR_EVENT_PRIV_STR, + GOOGLE_GSCAN_SIGNIFICANT_EVENT, + GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT, + GOOGLE_GSCAN_BATCH_SCAN_EVENT, + GOOGLE_SCAN_FULL_RESULTS_EVENT, + GOOGLE_RTT_COMPLETE_EVENT, + GOOGLE_SCAN_COMPLETE_EVENT, + GOOGLE_GSCAN_GEOFENCE_LOST_EVENT +} wl_vendor_event_t; + +enum andr_wifi_attr { + ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, + ANDR_WIFI_ATTRIBUTE_FEATURE_SET, + ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, + ANDR_WIFI_ATTRIBUTE_NODFS_SET, }; +typedef enum wl_vendor_gscan_attribute { + ATTR_START_GSCAN, + ATTR_STOP_GSCAN, + ATTR_SET_SCAN_BATCH_CFG_ID, /* set batch scan params */ + ATTR_SET_SCAN_GEOFENCE_CFG_ID, /* set list of bssids to track */ + ATTR_SET_SCAN_SIGNIFICANT_CFG_ID, /* set list of bssids, rssi threshold etc.. */ + ATTR_SET_SCAN_CFG_ID, /* set common scan config params here */ + ATTR_GET_GSCAN_CAPABILITIES_ID, + /* Add more sub commands here */ + ATTR_GSCAN_MAX +} wl_vendor_gscan_attribute_t; + +typedef enum gscan_batch_attribute { + ATTR_GSCAN_BATCH_BESTN, + ATTR_GSCAN_BATCH_MSCAN, + ATTR_GSCAN_BATCH_BUFFER_THRESHOLD +} gscan_batch_attribute_t; + +typedef enum gscan_geofence_attribute { + ATTR_GSCAN_NUM_HOTLIST_BSSID, + ATTR_GSCAN_HOTLIST_BSSID +} gscan_geofence_attribute_t; + +typedef enum gscan_complete_event { + WIFI_SCAN_BUFFER_FULL, + WIFI_SCAN_COMPLETE +} gscan_complete_event_t; + /* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */ #define BRCM_VENDOR_SCMD_CAPA "cap" -#ifdef VENDOR_EXT_SUPPORT -extern int cfgvendor_attach(struct wiphy *wiphy); -extern int cfgvendor_detach(struct wiphy *wiphy); -#else -static INLINE int cfgvendor_attach(struct wiphy *wiphy) { return 0; } -static INLINE int cfgvendor_detach(struct wiphy *wiphy) { return 0; } -#endif /* VENDOR_EXT_SUPPORT */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) +extern int wl_cfgvendor_attach(struct wiphy *wiphy); +extern int wl_cfgvendor_detach(struct wiphy *wiphy); +extern int wl_cfgvendor_send_async_event(struct wiphy *wiphy, + struct net_device *dev, int event_id, const void *data, int len); +extern int wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy, + struct net_device *dev, void *data, int len, wl_vendor_event_t event); +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ #endif /* _wl_cfgvendor_h_ */ diff --git a/drivers/net/wireless/bcmdhd/wl_dbg.h b/drivers/net/wireless/bcmdhd/wl_dbg.h index 2e36495ff469e6fe6cc5fb36c1b230e6a64f21c8..083d0c3ff55b37cfa5d1459ee9aee9d6e7b9da04 100644 --- a/drivers/net/wireless/bcmdhd/wl_dbg.h +++ b/drivers/net/wireless/bcmdhd/wl_dbg.h @@ -2,7 +2,25 @@ * Minimal debug/trace/assert driver definitions for * Broadcom 802.11 Networking Adapter. * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_dbg.h 472390 2014-04-23 23:32:01Z $ */ @@ -17,14 +35,7 @@ extern uint32 wl_msg_level2; #define WL_TIMESTAMP() -#if 0 && (VERSION_MAJOR > 9) -extern int osl_printf(const char *fmt, ...); -#include <IOKit/apple80211/IO8Log.h> -#define WL_PRINT(args) do { osl_printf args; } while (0) -#define RELEASE_PRINT(args) do { WL_PRINT(args); IO8Log args; } while (0) -#else #define WL_PRINT(args) do { WL_TIMESTAMP(); printf args; } while (0) -#endif #if defined(EVENT_LOG_COMPILE) && defined(WLMSG_SRSCAN) #define _WL_SRSCAN(fmt, ...) EVENT_LOG(EVENT_LOG_TAG_SRSCAN, fmt, ##__VA_ARGS__) @@ -177,203 +188,6 @@ extern int osl_printf(const char *fmt, ...); #define WL_ERROR(args) #define WL_TRACE(args) -#ifndef LINUX_POSTMOGRIFY_REMOVAL -#ifdef WLMSG_PRHDRS -#define WL_PRHDRS_MSG(args) WL_PRINT(args) -#define WL_PRHDRS(i, p, f, t, r, l) wlc_print_hdrs(i, p, f, t, r, l) -#else -#define WL_PRHDRS_MSG(args) -#define WL_PRHDRS(i, p, f, t, r, l) -#endif -#ifdef WLMSG_PRPKT -#define WL_PRPKT(m, b, n) prhex(m, b, n) -#else -#define WL_PRPKT(m, b, n) -#endif -#ifdef WLMSG_INFORM -#define WL_INFORM(args) WL_PRINT(args) -#else -#define WL_INFORM(args) -#endif -#define WL_TMP(args) -#ifdef WLMSG_OID -#define WL_OID(args) WL_PRINT(args) -#else -#define WL_OID(args) -#endif -#define WL_RATE(args) -#ifdef WLMSG_ASSOC -#define WL_ASSOC(args) WL_PRINT(args) -#else -#define WL_ASSOC(args) -#endif -#define WL_PRUSR(m, b, n) -#ifdef WLMSG_PS -#define WL_PS(args) WL_PRINT(args) -#else -#define WL_PS(args) -#endif -#ifdef WLMSG_ROAM -#define WL_ROAM(args) WL_PRINT(args) -#else -#define WL_ROAM(args) -#endif -#define WL_PORT(args) -#define WL_DUAL(args) -#define WL_REGULATORY(args) - -#ifdef WLMSG_MPC -#define WL_MPC(args) WL_PRINT(args) -#else -#define WL_MPC(args) -#endif -#define WL_APSTA(args) -#define WL_APSTA_BCN(args) -#define WL_APSTA_TX(args) -#define WL_APSTA_TSF(args) -#define WL_APSTA_BSSID(args) -#define WL_BA(args) -#define WL_MBSS(args) -#define WL_MODE_SWITCH(args) -#define WL_PROTO(args) - -#define WL_CAC(args) -#define WL_AMSDU(args) -#define WL_AMPDU(args) -#define WL_FFPLD(args) -#define WL_MCHAN(args) - -/* Define WLMSG_DFS automatically for WLTEST builds */ - -#ifdef WLMSG_DFS -#define WL_DFS(args) do {if (wl_msg_level & WL_DFS_VAL) WL_PRINT(args);} while (0) -#else /* WLMSG_DFS */ -#define WL_DFS(args) -#endif /* WLMSG_DFS */ -#define WL_WOWL(args) -#ifdef WLMSG_SCAN -#define WL_SCAN(args) WL_PRINT(args) -#else -#define WL_SCAN(args) -#endif -#define WL_COEX(args) -#define WL_RTDC(w, s, i, j) -#define WL_RTDC2(w, s, i, j) -#define WL_CHANINT(args) -#ifdef WLMSG_BTA -#define WL_BTA(args) WL_PRINT(args) -#else -#define WL_BTA(args) -#endif -#define WL_WMF(args) -#define WL_P2P(args) -#define WL_ITFR(args) -#define WL_TDLS(args) -#define WL_MCNX(args) -#define WL_PROT(args) -#define WL_PSTA(args) -#define WL_TBTT(args) -#define WL_TRF_MGMT(args) -#define WL_L2FILTER(args) -#define WL_MQ(args) -#define WL_P2PO(args) -#define WL_WNM(args) -#define WL_TXBF(args) -#define WL_CHANLOG(w, s, i, j) -#define WL_NET_DETECT(args) - -#define WL_ERROR_ON() 0 -#define WL_TRACE_ON() 0 -#ifdef WLMSG_PRHDRS -#define WL_PRHDRS_ON() 1 -#else -#define WL_PRHDRS_ON() 0 -#endif -#ifdef WLMSG_PRPKT -#define WL_PRPKT_ON() 1 -#else -#define WL_PRPKT_ON() 0 -#endif -#ifdef WLMSG_INFORM -#define WL_INFORM_ON() 1 -#else -#define WL_INFORM_ON() 0 -#endif -#ifdef WLMSG_OID -#define WL_OID_ON() 1 -#else -#define WL_OID_ON() 0 -#endif -#define WL_TMP_ON() 0 -#define WL_RATE_ON() 0 -#ifdef WLMSG_ASSOC -#define WL_ASSOC_ON() 1 -#else -#define WL_ASSOC_ON() 0 -#endif -#define WL_PORT_ON() 0 -#ifdef WLMSG_WSEC -#define WL_WSEC_ON() 1 -#define WL_WSEC_DUMP_ON() 1 -#else -#define WL_WSEC_ON() 0 -#define WL_WSEC_DUMP_ON() 0 -#endif -#ifdef WLMSG_MPC -#define WL_MPC_ON() 1 -#else -#define WL_MPC_ON() 0 -#endif -#define WL_REGULATORY_ON() 0 - -#define WL_APSTA_ON() 0 -#define WL_BA_ON() 0 -#define WL_MBSS_ON() 0 -#define WL_MODE_SWITCH_ON() 0 -#ifdef WLMSG_DFS -#define WL_DFS_ON() 1 -#else /* WLMSG_DFS */ -#define WL_DFS_ON() 0 -#endif /* WLMSG_DFS */ -#ifdef WLMSG_SCAN -#define WL_SCAN_ON() 1 -#else -#define WL_SCAN_ON() 0 -#endif -#ifdef WLMSG_BTA -#define WL_BTA_ON() 1 -#else -#define WL_BTA_ON() 0 -#endif -#define WL_WMF_ON() 0 -#define WL_P2P_ON() 0 -#define WL_MCHAN_ON() 0 -#define WL_TDLS_ON() 0 -#define WL_MCNX_ON() 0 -#define WL_PROT_ON() 0 -#define WL_TBTT_ON() 0 -#define WL_PWRSEL_ON() 0 -#define WL_L2FILTER_ON() 0 -#define WL_MQ_ON() 0 -#define WL_P2PO_ON() 0 -#define WL_TXBF_ON() 0 -#define WL_CHANLOG_ON() 0 - -#define WL_AMPDU_UPDN(args) -#define WL_AMPDU_RX(args) -#define WL_AMPDU_ERR(args) -#define WL_AMPDU_TX(args) -#define WL_AMPDU_CTL(args) -#define WL_AMPDU_HW(args) -#define WL_AMPDU_HWTXS(args) -#define WL_AMPDU_HWDBG(args) -#define WL_AMPDU_STAT(args) -#define WL_AMPDU_ERR_ON() 0 -#define WL_AMPDU_HW_ON() 0 -#define WL_AMPDU_HWTXS_ON() 0 - -#define WL_WNM_ON() 0 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WL_APSTA_UPDN(args) #define WL_APSTA_RX(args) #ifdef WLMSG_WSEC diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c index 32bd8e59d270dd97d2975a9ec3eafe846b6bfc13..6a0b6761179327e927d2d96723bc8695f4004603 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/bcmdhd/wl_iw.c @@ -1,7 +1,25 @@ /* * Linux Wireless Extensions support * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_iw.c 467328 2014-04-03 01:23:40Z $ */ @@ -27,32 +45,6 @@ typedef const struct si_pub si_t; #include <wl_dbg.h> #include <wl_iw.h> -#ifdef BCMWAPI_WPI -/* these items should evetually go into wireless.h of the linux system headfile dir */ -#ifndef IW_ENCODE_ALG_SM4 -#define IW_ENCODE_ALG_SM4 0x20 -#endif - -#ifndef IW_AUTH_WAPI_ENABLED -#define IW_AUTH_WAPI_ENABLED 0x20 -#endif - -#ifndef IW_AUTH_WAPI_VERSION_1 -#define IW_AUTH_WAPI_VERSION_1 0x00000008 -#endif - -#ifndef IW_AUTH_CIPHER_SMS4 -#define IW_AUTH_CIPHER_SMS4 0x00000020 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK -#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 -#endif - -#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT -#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 -#endif -#endif /* BCMWAPI_WPI */ /* Broadcom extensions to WEXT, linux upstream has obsoleted WEXT */ #ifndef IW_AUTH_KEY_MGMT_FT_802_1X @@ -1322,42 +1314,6 @@ ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) } #endif /* WIRELESS_EXT > 17 */ -#ifdef BCMWAPI_WPI -static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, - size_t len, int uppercase) -{ - size_t i; - char *pos = buf, *end = buf + buf_size; - int ret; - if (buf_size == 0) - return 0; - for (i = 0; i < len; i++) { - ret = snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", - data[i]); - if (ret < 0 || ret >= end - pos) { - end[-1] = '\0'; - return pos - buf; - } - pos += ret; - } - end[-1] = '\0'; - return pos - buf; -} - -/** - * wpa_snprintf_hex - Print data as a hex string into a buffer - * @buf: Memory area to use as the output buffer - * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) - * @data: Data to be printed - * @len: Length of data in bytes - * Returns: Number of bytes written - */ -static int -wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -{ - return _wpa_snprintf_hex(buf, buf_size, data, len, 0); -} -#endif /* BCMWAPI_WPI */ static int wl_iw_handle_scanresults_ies(char **event_p, char *end, @@ -1366,10 +1322,6 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end, #if WIRELESS_EXT > 17 struct iw_event iwe; char *event; -#ifdef BCMWAPI_WPI - char *buf; - int custom_event_len; -#endif event = *event_p; if (bi->ie_length) { @@ -1424,38 +1376,6 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end, } } -#ifdef BCMWAPI_WPI - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WAPI_ID))) { - WL_TRACE(("%s: found a WAPI IE...\n", __FUNCTION__)); -#ifdef WAPI_IE_USE_GENIE - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -#else /* using CUSTOM event */ - iwe.cmd = IWEVCUSTOM; - custom_event_len = strlen("wapi_ie=") + 2*(ie->len + 2); - iwe.u.data.length = custom_event_len; - - buf = kmalloc(custom_event_len+1, GFP_KERNEL); - if (buf == NULL) - { - WL_ERROR(("malloc(%d) returned NULL...\n", custom_event_len)); - break; - } - - memcpy(buf, "wapi_ie=", 8); - wpa_snprintf_hex(buf + 8, 2+1, &(ie->id), 1); - wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); - wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); - kfree(buf); -#endif /* WAPI_IE_USE_GENIE */ - break; - } -#endif /* BCMWAPI_WPI */ *event_p = event; } @@ -2368,21 +2288,6 @@ wl_iw_set_wpaie( char *extra ) { -#if defined(BCMWAPI_WPI) - uchar buf[WLC_IOCTL_SMLEN] = {0}; - uchar *p = buf; - int wapi_ie_size; - - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - - if (extra[0] == DOT11_MNG_WAPI_ID) - { - wapi_ie_size = iwp->length; - memcpy(p, extra, iwp->length); - dev_wlc_bufvar_set(dev, "wapiie", buf, wapi_ie_size); - } - else -#endif dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); return 0; @@ -2525,14 +2430,6 @@ wl_iw_set_encodeext( case IW_ENCODE_ALG_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; break; -#ifdef BCMWAPI_WPI - case IW_ENCODE_ALG_SM4: - key.algo = CRYPTO_ALGO_SMS4; - if (iwe->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - key.flags &= ~WL_PRIMARY_KEY; - } - break; -#endif default: break; } @@ -2682,10 +2579,6 @@ wl_iw_set_wpaauth( val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; else if (paramval & IW_AUTH_WPA_VERSION_WPA2) val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; -#ifdef BCMWAPI_WPI - else if (paramval & IW_AUTH_WAPI_VERSION_1) - val = WAPI_AUTH_UNSPECIFIED; -#endif WL_TRACE(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) return error; @@ -2713,11 +2606,6 @@ wl_iw_set_wpaauth( val |= TKIP_ENABLED; if (cipher_combined & IW_AUTH_CIPHER_CCMP) val |= AES_ENABLED; -#ifdef BCMWAPI_WPI - val &= ~SMS4_ENABLED; - if (cipher_combined & IW_AUTH_CIPHER_SMS4) - val |= SMS4_ENABLED; -#endif if (iw->privacy_invoked && !val) { WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " @@ -2774,10 +2662,6 @@ wl_iw_set_wpaauth( if (paramval & (IW_AUTH_KEY_MGMT_FT_802_1X | IW_AUTH_KEY_MGMT_FT_PSK)) val |= WPA2_AUTH_FT; } -#ifdef BCMWAPI_WPI - if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT)) - val = WAPI_AUTH_UNSPECIFIED; -#endif WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) return error; @@ -2860,29 +2744,6 @@ wl_iw_set_wpaauth( #endif /* WIRELESS_EXT > 17 */ -#ifdef BCMWAPI_WPI - - case IW_AUTH_WAPI_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) - return error; - if (paramval) { - val |= SMS4_ENABLED; - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { - WL_ERROR(("%s: setting wsec to 0x%0x returned error %d\n", - __FUNCTION__, val, error)); - return error; - } - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", WAPI_AUTH_UNSPECIFIED))) { - WL_ERROR(("%s: setting wpa_auth(%d) returned %d\n", - __FUNCTION__, WAPI_AUTH_UNSPECIFIED, - error)); - return error; - } - } - - break; - -#endif /* BCMWAPI_WPI */ default: break; diff --git a/drivers/net/wireless/bcmdhd/wl_iw.h b/drivers/net/wireless/bcmdhd/wl_iw.h index dfadb0c3951d6ffe6ccd46127079a612e2091565..95b2abdbd7c58a548c2bca7ada5d92d6ab20f76f 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.h +++ b/drivers/net/wireless/bcmdhd/wl_iw.h @@ -1,9 +1,27 @@ /* * Linux Wireless Extensions support * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_iw.h 488316 2014-06-30 15:22:21Z $ + * $Id: wl_iw.h 467328 2014-04-03 01:23:40Z $ */ #ifndef _wl_iw_h_ @@ -37,7 +55,7 @@ #define TXPOWER_SET_CMD "TXPOWER" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" /* Structure to keep global parameters */ typedef struct wl_iw_extra_params { diff --git a/drivers/net/wireless/bcmdhd/wl_linux_mon.c b/drivers/net/wireless/bcmdhd/wl_linux_mon.c index ccf2c8ddd878895f6188090c1dc0495219428773..2dc6aeb15808329114f8f3ea4d7eba85305bae5e 100644 --- a/drivers/net/wireless/bcmdhd/wl_linux_mon.c +++ b/drivers/net/wireless/bcmdhd/wl_linux_mon.c @@ -1,7 +1,25 @@ /* * Broadcom Dongle Host Driver (DHD), Linux monitor network interface * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wl_linux_mon.c 467328 2014-04-03 01:23:40Z $ */ @@ -41,7 +59,7 @@ int dhd_monitor_uninit(void); #ifndef DHD_MAX_IFS #define DHD_MAX_IFS 16 #endif -#define MON_PRINT(format, ...) printf("DHD-MON: %s " format, __func__, ##__VA_ARGS__) +#define MON_PRINT(format, ...) printk("DHD-MON: %s " format, __func__, ##__VA_ARGS__) #define MON_TRACE MON_PRINT typedef struct monitor_interface { diff --git a/drivers/net/wireless/bcmdhd/wl_roam.c b/drivers/net/wireless/bcmdhd/wl_roam.c new file mode 100644 index 0000000000000000000000000000000000000000..3fc9e7670b73428904acd2724cda82d3d18b415a --- /dev/null +++ b/drivers/net/wireless/bcmdhd/wl_roam.c @@ -0,0 +1,308 @@ +/* + * Linux cfg80211 driver + * + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: wl_roam.c 477711 2014-05-14 08:45:17Z $ + */ + + +#include <typedefs.h> +#include <osl.h> +#include <bcmwifi_channels.h> +#include <wlioctl.h> +#include <bcmutils.h> +#include <wl_cfg80211.h> +#include <wldev_common.h> + +#define MAX_ROAM_CACHE 100 +#define MAX_CHANNEL_LIST 20 +#define MAX_SSID_BUFSIZE 36 + +#define ROAMSCAN_MODE_NORMAL 0 +#define ROAMSCAN_MODE_WES 1 + +typedef struct { + chanspec_t chanspec; + int ssid_len; + char ssid[DOT11_MAX_SSID_LEN]; +} roam_channel_cache; + +typedef struct { + int n; + chanspec_t channels[MAX_CHANNEL_LIST]; +} channel_list_t; + +static int n_roam_cache = 0; +static int roam_band = WLC_BAND_AUTO; +static roam_channel_cache roam_cache[MAX_ROAM_CACHE]; +static uint band2G, band5G, band_bw; + +void init_roam(int ioctl_ver) +{ +#ifdef D11AC_IOTYPES + if (ioctl_ver == 1) { + /* legacy chanspec */ + band2G = WL_LCHANSPEC_BAND_2G; + band5G = WL_LCHANSPEC_BAND_5G; + band_bw = WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE; + } else { + band2G = WL_CHANSPEC_BAND_2G; + band5G = WL_CHANSPEC_BAND_5G; + band_bw = WL_CHANSPEC_BW_20; + } +#else + band2G = WL_CHANSPEC_BAND_2G; + band5G = WL_CHANSPEC_BAND_5G; + band_bw = WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; +#endif /* D11AC_IOTYPES */ + + n_roam_cache = 0; + roam_band = WLC_BAND_AUTO; + +} + + +void set_roam_band(int band) +{ + roam_band = band; +} + +void reset_roam_cache(void) +{ + n_roam_cache = 0; +} + +void add_roam_cache(wl_bss_info_t *bi) +{ + int i; + uint8 channel; + char chanbuf[CHANSPEC_STR_LEN]; + + + if (n_roam_cache >= MAX_ROAM_CACHE) + return; + + if (bi->SSID_len > DOT11_MAX_SSID_LEN) + return; + + for (i = 0; i < n_roam_cache; i++) { + if ((roam_cache[i].ssid_len == bi->SSID_len) && + (roam_cache[i].chanspec == bi->chanspec) && + (memcmp(roam_cache[i].ssid, bi->SSID, bi->SSID_len) == 0)) { + /* identical one found, just return */ + return; + } + } + + roam_cache[n_roam_cache].ssid_len = bi->SSID_len; + channel = wf_chspec_ctlchan(bi->chanspec); + WL_DBG(("CHSPEC = %s, CTL %d\n", wf_chspec_ntoa_ex(bi->chanspec, chanbuf), channel)); + roam_cache[n_roam_cache].chanspec = + (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw | channel; + memcpy(roam_cache[n_roam_cache].ssid, bi->SSID, bi->SSID_len); + + n_roam_cache++; +} + +static bool is_duplicated_channel(const chanspec_t *channels, + int n_channels, chanspec_t new) +{ + int i; + + for (i = 0; i < n_channels; i++) { + if (channels[i] == new) + return TRUE; + } + + return FALSE; +} + +int get_roam_channel_list(int target_chan, chanspec_t *channels, + const wlc_ssid_t *ssid, int ioctl_ver) +{ + int i, n = 0; + char chanbuf[CHANSPEC_STR_LEN]; + if (target_chan) { + /* first index is filled with the given target channel */ + channels[n++] = (target_chan & WL_CHANSPEC_CHAN_MASK) | + (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw; + WL_DBG((" %s: %03d 0x%04X\n", __FUNCTION__, target_chan, channels[0])); + } + + for (i = 0; i < n_roam_cache; i++) { + chanspec_t ch = roam_cache[i].chanspec; + bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); + bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch); + bool band_match = ((roam_band == WLC_BAND_AUTO) || + ((roam_band == WLC_BAND_2G) && is_2G) || + ((roam_band == WLC_BAND_5G) && is_5G)); + + /* XXX: JIRA:SW4349-173 : 80p80 Support Required */ + ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw; + if ((roam_cache[i].ssid_len == ssid->SSID_len) && + band_match && !is_duplicated_channel(channels, n, ch) && + (memcmp(roam_cache[i].ssid, ssid->SSID, ssid->SSID_len) == 0)) { + /* match found, add it */ + WL_DBG(("%s: channel = %s\n", __FUNCTION__, + wf_chspec_ntoa_ex(ch, chanbuf))); + channels[n++] = ch; + } + } + + return n; +} + + +void print_roam_cache(void) +{ + int i; + + WL_DBG((" %d cache\n", n_roam_cache)); + + for (i = 0; i < n_roam_cache; i++) { + roam_cache[i].ssid[roam_cache[i].ssid_len] = 0; + WL_DBG(("0x%02X %02d %s\n", roam_cache[i].chanspec, + roam_cache[i].ssid_len, roam_cache[i].ssid)); + } +} + +static void add_roamcache_channel(channel_list_t *channels, chanspec_t ch) +{ + int i; + + if (channels->n >= MAX_CHANNEL_LIST) /* buffer full */ + return; + + for (i = 0; i < channels->n; i++) { + if (channels->channels[i] == ch) /* already in the list */ + return; + } + + channels->channels[i] = ch; + channels->n++; + + WL_DBG((" RCC: %02d 0x%04X\n", + ch & WL_CHANSPEC_CHAN_MASK, ch)); +} + +void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver) +{ + int error, i, prev_channels; + channel_list_t channel_list; + char iobuf[WLC_IOCTL_SMLEN]; + struct net_device *dev = bcmcfg_to_prmry_ndev(cfg); + wlc_ssid_t ssid; + + if (!wl_get_drv_status(cfg, CONNECTED, dev)) { + WL_DBG(("Not associated\n")); + return; + } + + /* need to read out the current cache list + as the firmware may change dynamically + */ + error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0, + (void *)&channel_list, sizeof(channel_list), NULL); + + WL_DBG(("%d AP, %d cache item(s), err=%d\n", n_roam_cache, channel_list.n, error)); + + error = wldev_get_ssid(dev, &ssid); + if (error) { + WL_ERR(("Failed to get SSID, err=%d\n", error)); + return; + } + + prev_channels = channel_list.n; + for (i = 0; i < n_roam_cache; i++) { + chanspec_t ch = roam_cache[i].chanspec; + bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); + bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch); + bool band_match = ((roam_band == WLC_BAND_AUTO) || + ((roam_band == WLC_BAND_2G) && is_2G) || + ((roam_band == WLC_BAND_5G) && is_5G)); + + if ((roam_cache[i].ssid_len == ssid.SSID_len) && + band_match && (memcmp(roam_cache[i].ssid, ssid.SSID, ssid.SSID_len) == 0)) { + /* match found, add it */ + /* XXX: JIRA:SW4349-173 : 80p80 Support Required */ + ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw; + add_roamcache_channel(&channel_list, ch); + } + } + if (prev_channels != channel_list.n) { + /* channel list updated */ + error = wldev_iovar_setbuf(dev, "roamscan_channels", &channel_list, + sizeof(channel_list), iobuf, sizeof(iobuf), NULL); + if (error) { + WL_ERR(("Failed to update roamscan channels, error = %d\n", error)); + } + } +} + +void wl_update_roamscan_cache_by_band(struct net_device *dev, int band) +{ + int i, error, ioctl_ver, wes_mode; + channel_list_t chanlist_before, chanlist_after; + char iobuf[WLC_IOCTL_SMLEN]; + + roam_band = band; + if (band == WLC_BAND_AUTO) + return; + + error = wldev_iovar_getint(dev, "roamscan_mode", &wes_mode); + if (error) { + WL_ERR(("Failed to get roamscan mode, error = %d\n", error)); + return; + } + /* in case of WES mode, then skip the update */ + if (wes_mode) + return; + + error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0, + (void *)&chanlist_before, sizeof(channel_list_t), NULL); + if (error) { + WL_ERR(("Failed to get roamscan channels, error = %d\n", error)); + return; + } + ioctl_ver = wl_cfg80211_get_ioctl_version(); + chanlist_after.n = 0; + /* filtering by the given band */ + for (i = 0; i < chanlist_before.n; i++) { + chanspec_t chspec = chanlist_before.channels[i]; + bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(chspec) : CHSPEC_IS2G(chspec); + bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(chspec) : CHSPEC_IS5G(chspec); + bool band_match = ((band == WLC_BAND_2G) && is_2G) || + ((band == WLC_BAND_5G) && is_5G); + if (band_match) { + chanlist_after.channels[chanlist_after.n++] = chspec; + } + } + + if (chanlist_before.n == chanlist_after.n) + return; + + error = wldev_iovar_setbuf(dev, "roamscan_channels", &chanlist_after, + sizeof(channel_list_t), iobuf, sizeof(iobuf), NULL); + if (error) { + WL_ERR(("Failed to update roamscan channels, error = %d\n", error)); + } +} diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c index 29d1d9566054513cc3df9116bfc83700716d6508..11ffa5caba407e8e8910e3beeea1016a175217d3 100644 --- a/drivers/net/wireless/bcmdhd/wldev_common.c +++ b/drivers/net/wireless/bcmdhd/wldev_common.c @@ -1,7 +1,25 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wldev_common.c 467328 2014-04-03 01:23:40Z $ */ @@ -23,8 +41,8 @@ #define WLDEV_ERROR(args) \ do { \ - printf(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \ - printf args; \ + printk(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \ + printk args; \ } while (0) extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd); @@ -335,7 +353,7 @@ int wldev_set_country( return error; } - if ((error < 0) || + if ((error < 0) || dhd_force_country_change(dev) || (strncmp(country_code, cspec.country_abbrev, WLC_CNTRY_BUF_SZ) != 0)) { if (user_enforced) { diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h index 6de214845f928f55252a4ad3a6e785be965190ef..7944ef62cf2be9cb14579ae754741d4c8a6e2615 100644 --- a/drivers/net/wireless/bcmdhd/wldev_common.h +++ b/drivers/net/wireless/bcmdhd/wldev_common.h @@ -1,7 +1,25 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * $Copyright Open Broadcom Corporation$ + * Copyright (C) 1999-2014, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. * * $Id: wldev_common.h 467328 2014-04-03 01:23:40Z $ */ @@ -73,6 +91,7 @@ extern int dhd_net_wifi_platform_set_power(struct net_device *dev, bool on, extern void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_code, wl_country_t *cspec); extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify); +extern bool dhd_force_country_change(struct net_device *dev); extern void dhd_bus_band_set(struct net_device *dev, uint band); extern int wldev_set_country(struct net_device *dev, char *country_code, bool notify, bool user_enforced); @@ -83,7 +102,7 @@ extern int net_os_wake_lock_timeout_enable(struct net_device *dev, int val); extern int net_os_set_dtim_skip(struct net_device *dev, int val); extern int net_os_set_suspend_disable(struct net_device *dev, int val); extern int net_os_set_suspend(struct net_device *dev, int val, int force); -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, +extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid, int max, int *bytes_left); /* Get the link speed from dongle, speed is in kpbs */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ef58a7719a42bf98a8b76fc5bc14f1987d30fb95..f16e8c0565877250867cafd48c81697dc1036cce 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2579,7 +2579,7 @@ struct wiphy_vendor_command { struct nl80211_vendor_cmd_info info; u32 flags; int (*doit)(struct wiphy *wiphy, struct wireless_dev *wdev, - void *data, int data_len); + const void *data, int data_len); }; /**