From 6513b9fbdd0dfafa1cbf4eb12ce272667243de6e Mon Sep 17 00:00:00 2001 From: Alex Zhao Date: Mon, 4 Jul 2022 17:44:58 +0800 Subject: [PATCH] net: wireless: update bcmdhd driver to 101.10.361.20 Signed-off-by: Alex Zhao Change-Id: I7beac9c4e228865b7a07a0d2f88e2968ac7e5e8e --- .../rockchip_wlan/rkwifi/bcmdhd/Makefile | 64 +- .../rockchip_wlan/rkwifi/bcmdhd/bcmbloom.c | 2 + .../rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c | 2 +- .../rkwifi/bcmdhd/bcmsdh_linux.c | 6 + .../rkwifi/bcmdhd/bcmsdh_sdmmc.c | 3 +- .../rockchip_wlan/rkwifi/bcmdhd/bcmutils.c | 2 + .../rockchip_wlan/rkwifi/bcmdhd/bcmxtlv.c | 2 + .../rockchip_wlan/rkwifi/bcmdhd/dbus.c | 28 +- .../rkwifi/bcmdhd/dbus_usb_linux.c | 2 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd.h | 3 + .../rockchip_wlan/rkwifi/bcmdhd/dhd_bus.h | 1 + .../rockchip_wlan/rkwifi/bcmdhd/dhd_common.c | 244 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_config.c | 161 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_config.h | 18 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_csi.c | 3 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_csi.h | 1 - .../rockchip_wlan/rkwifi/bcmdhd/dhd_dbg.h | 30 +- .../rkwifi/bcmdhd/dhd_flowring.c | 33 + .../rkwifi/bcmdhd/dhd_flowring.h | 1 + .../rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c | 7 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c | 689 ++++-- .../rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h | 3 + .../rkwifi/bcmdhd/dhd_linux_exportfs.c | 22 +- .../rkwifi/bcmdhd/dhd_linux_pktdump.c | 267 ++- .../rkwifi/bcmdhd/dhd_linux_pktdump.h | 3 + .../rkwifi/bcmdhd/dhd_linux_platdev.c | 6 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_msgbuf.c | 10 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c | 244 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.h | 6 + .../rkwifi/bcmdhd/dhd_pcie_linux.c | 50 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c | 285 ++- .../rkwifi/bcmdhd/dhd_static_buf.c | 18 +- .../rkwifi/bcmdhd/include/bcmsdh.h | 1 + .../rkwifi/bcmdhd/include/bcmsdh_sdmmc.h | 10 - .../rkwifi/bcmdhd/include/bcmutils.h | 2 - .../rkwifi/bcmdhd/include/dhdioctl.h | 4 +- .../rkwifi/bcmdhd/include/epivers.h | 2 +- .../rkwifi/bcmdhd/include/linux_osl.h | 2 +- .../rkwifi/bcmdhd/include/linuxver.h | 32 +- .../rockchip_wlan/rkwifi/bcmdhd/linux_osl.c | 85 +- .../rockchip_wlan/rkwifi/bcmdhd/linux_pkt.c | 24 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_android.c | 67 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_android.h | 6 +- .../rkwifi/bcmdhd/wl_android_ext.c | 523 +++-- .../rkwifi/bcmdhd/wl_android_ext.h | 37 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c | 288 ++- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.h | 58 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.c | 4 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.h | 23 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.c | 5 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h | 31 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgscan.c | 39 +- .../rkwifi/bcmdhd/wl_cfgvendor.c | 661 +++++- .../rkwifi/bcmdhd/wl_cfgvendor.h | 96 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfgvif.c | 77 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_escan.c | 60 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_escan.h | 10 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_event.c | 7 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_event.h | 1 - .../rockchip_wlan/rkwifi/bcmdhd/wl_ext_genl.c | 8 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c | 2001 ++++++++++++----- .../rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.h | 16 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_iw.c | 30 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_iw.h | 10 +- .../rkwifi/bcmdhd/wl_linux_mon.c | 2 +- .../rkwifi/bcmdhd/wldev_common.c | 10 +- 66 files changed, 4847 insertions(+), 1601 deletions(-) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile index f1203c86081b..6c280074043a 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile @@ -2,7 +2,7 @@ # bcmdhd MODULE_NAME := bcmdhd -#CONFIG_BCMDHD := m +CONFIG_BCMDHD ?= m #CONFIG_BCMDHD_SDIO := y #CONFIG_BCMDHD_PCIE := y @@ -15,11 +15,15 @@ CONFIG_BCMDHD_PROPTXSTATUS := y CONFIG_BCMDHD_AG := y CONFIG_DHD_USE_STATIC_BUF := y #CONFIG_BCMDHD_STATIC_BUF_IN_DHD := y -CONFIG_BCMDHD_VTS := y +CONFIG_BCMDHD_ANDROID_VERSION := 12 CONFIG_BCMDHD_AUTO_SELECT := y CONFIG_BCMDHD_DEBUG := y +#CONFIG_BCMDHD_TIMESTAMP := y #CONFIG_BCMDHD_WAPI := y #CONFIG_BCMDHD_RANDOM_MAC := y +#CONFIG_BCMDHD_REQUEST_FW := y +#CONFIG_BCMDHD_MULTIPLE_DRIVER := y +#CONFIG_BCMDHD_DWDS := y CONFIG_BCMDHD_TPUT := y CONFIG_MACH_PLATFORM := y @@ -71,12 +75,13 @@ ifneq ($(CONFIG_CFG80211),) DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK DHDCFLAGS += -DSPECIFIC_MAC_GEN_SCHEME DHDCFLAGS += -DWL_IFACE_MGMT - DHDCFLAGS += -DWLFBT + DHDCFLAGS += -DWLFBT -DWL_GCMP_SUPPORT DHDCFLAGS += -DWL_EXT_RECONNECT DHDCFLAGS += -DDHD_LOSSLESS_ROAMING DHDCFLAGS += -DGTK_OFFLOAD_SUPPORT + DHDCFLAGS += -DRESTART_AP_WAR # DHDCFLAGS += -DWL_STATIC_IF -# DHDCFLAGS += -DWL_CLIENT_SAE + DHDCFLAGS += -DWL_CLIENT_SAE -DWL_OWE endif #BCMDHD_SDIO @@ -110,6 +115,7 @@ DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_STATS -DDHD_LB_TXP DHDCFLAGS += -DDHD_PKTID_AUDIT_ENABLED DHDCFLAGS += -DINSMOD_FW_LOAD DHDCFLAGS += -DCHIP_INTR_CONTROL +#DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100 DHDCFLAGS += -DDHD_CONTROL_PCIE_ASPM_WIFI_TURNON ifeq ($(CONFIG_BCMDHD_OOB),y) DHDCFLAGS += -DCUSTOMER_OOB -DBCMPCIE_OOB_HOST_WAKE -DHW_OOB @@ -148,6 +154,11 @@ else DHDCFLAGS += -DBUS_TYPE=\"\" endif +ifeq ($(CONFIG_BCMDHD_TIMESTAMP),y) + DHDCFLAGS += -DKERNEL_TIMESTAMP + DHDCFLAGS += -DSYSTEM_TIMESTAMP +endif + #PROPTXSTATUS ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y) ifneq ($(CONFIG_BCMDHD_USB),) @@ -167,19 +178,23 @@ ifeq ($(CONFIG_64BIT),y) endif # For Android VTS -ifeq ($(CONFIG_BCMDHD_VTS),y) +ifneq ($(CONFIG_BCMDHD_ANDROID_VERSION),) + DHDCFLAGS += -DANDROID_VERSION=$(CONFIG_BCMDHD_ANDROID_VERSION) DHDCFLAGS += -DDHD_NOTIFY_MAC_CHANGED ifneq ($(CONFIG_CFG80211),) DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT + DHDCFLAGS += -DWL_SAR_TX_POWER # DHDCFLAGS += -DLINKSTAT_SUPPORT DHDCFLAGS += -DCUSTOM_COUNTRY_CODE -DDHD_GET_VALID_CHANNELS DHDCFLAGS += -DDEBUGABILITY -DDBG_PKT_MON # DHDCFLAGS += -DDHD_LOG_DUMP DHDCFLAGS += -DDHD_FW_COREDUMP DHDCFLAGS += -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT - DHDCFLAGS += -DDHD_WAKE_STATUS + DHDCFLAGS += -DDHD_WAKE_STATUS -DWL_LATENCY_MODE DHDOFILES += dhd_rtt.o bcm_app_utils.o endif +else + DHDCFLAGS += -DANDROID_VERSION=0 endif # For Debug @@ -220,13 +235,26 @@ endif DHDCFLAGS :=$(filter-out -DWL_STATIC_IF,$(DHDCFLAGS)) endif +# EasyMesh ifeq ($(CONFIG_BCMDHD_EASYMESH),y) DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS)) DHDCFLAGS :=$(filter-out -DDHD_LOG_DUMP,$(DHDCFLAGS)) - DHDCFLAGS += -DWLEASYMESH -DWL_STATIC_IF -DWLDWDS -DFOURADDR_AUTO_BRG + DHDCFLAGS += -DWLEASYMESH + CONFIG_BCMDHD_DWDS := y endif -#CSI_SUPPORT +# DWDS +ifeq ($(CONFIG_BCMDHD_DWDS),y) +ifneq ($(CONFIG_CFG80211),) + DHDCFLAGS += -DWLDWDS -DFOURADDR_AUTO_BRG +ifneq ($(CONFIG_BCMDHD_SDIO),) + DHDCFLAGS += -DRXF_DEQUEUE_ON_BUSY +endif + DHDCFLAGS += -DWL_STATIC_IF +endif +endif + +# CSI_SUPPORT ifeq ($(CONFIG_CSI_SUPPORT),y) DHDCFLAGS += -DCSI_SUPPORT DHDOFILES += dhd_csi.o @@ -256,6 +284,9 @@ endif # For WAPI ifeq ($(CONFIG_BCMDHD_WAPI),y) DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI +ifeq ($(CONFIG_BCMDHD_ANDROID_VERSION),11) + DHDCFLAGS += -DCFG80211_WAPI_BKPORT +endif endif # For scan random mac @@ -279,7 +310,7 @@ ifneq ($(CONFIG_BCMDHD_SDIO),) endif endif -ifeq ($(CONFIG_BCMDHD),m) +ifeq ($(CONFIG_AP6XXX),m) DHDCFLAGS += -DBCMDHD_MODULAR endif @@ -292,6 +323,19 @@ endif DHDCFLAGS += -DCUSTOMER_HW_ROCKCHIP endif +ifeq ($(CONFIG_BCMDHD_REQUEST_FW),y) + DHDCFLAGS += -DDHD_LINUX_STD_FW_API + DHDCFLAGS += -DDHD_FW_NAME="\"fw_bcmdhd.bin\"" + DHDCFLAGS += -DDHD_NVRAM_NAME="\"nvram.txt\"" + DHDCFLAGS += -DDHD_CLM_NAME="\"clm_bcmdhd.blob\"" +else +ifeq ($(CONFIG_BCMDHD_FW_PATH),) + DHDCFLAGS += -DCONFIG_BCMDHD_FW_PATH="\"/system/etc/firmware/fw_bcmdhd.bin\"" + DHDCFLAGS += -DCONFIG_BCMDHD_NVRAM_PATH="\"/system/etc/firmware/nvram.txt\"" + DHDCFLAGS += -DCONFIG_BCMDHD_CLM_PATH="\"/system/etc/firmware/clm_bcmdhd.blob\"" +endif +endif + ifeq ($(CONFIG_BCMDHD_AG),y) DHDCFLAGS += -DBAND_AG endif @@ -317,7 +361,7 @@ BCMDHD_ROOT = $(src) EXTRA_CFLAGS = $(DHDCFLAGS) EXTRA_CFLAGS += -DDHD_COMPILED=\"$(BCMDHD_ROOT)\" EXTRA_CFLAGS += -I$(BCMDHD_ROOT)/include/ -I$(BCMDHD_ROOT)/ -ifeq ($(CONFIG_BCMDHD),m) +ifeq ($(CONFIG_AP6XXX),m) EXTRA_LDFLAGS += --strip-debug endif diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmbloom.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmbloom.c index 7660c882b9f6..2fe8a4a58511 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmbloom.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmbloom.c @@ -24,7 +24,9 @@ #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) #include +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) */ #ifdef BCMDRIVER #include diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c index 8019a01d9d87..538f0562069c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c @@ -937,7 +937,7 @@ bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab) } uint -bcmsdh_set_mode(void *sdh, uint mode) +bcmsdh_set_mode(void *sdh, uint mode) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; return (sdioh_set_mode(bcmsdh->sdioh, mode)); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_linux.c index d2971180fdb9..5bd32c5ca493 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_linux.c @@ -346,6 +346,12 @@ bcmsdh_unregister(void) bcmsdh_unregister_client_driver(); } +void *bcmsdh_get_dev(bcmsdh_info_t *sdh) +{ + bcmsdh_os_info_t *bcmsdh_osinfo = sdh->os_cxt; + return bcmsdh_osinfo->dev; +} + void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh) { #if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc.c index 7e010c257270..2ac448c5d25f 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc.c @@ -1094,8 +1094,7 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by } if (err_ret) { - if ((regaddr == 0x1001F) && ((err_ret == -ETIMEDOUT) || (err_ret == -EILSEQ) - || (err_ret == -EIO))) { + if (regaddr == 0x1001F) { /* XXX: Read/Write to SBSDIO_FUNC1_SLEEPCSR could return -110(timeout) * or -84(CRC) error in case the host tries to wake the device up. * Skip error log message if err code is -110 or -84 when accessing diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmutils.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmutils.c index 809b6bd91d44..63d237e7e648 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmutils.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmutils.c @@ -23,7 +23,9 @@ #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) #include +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) */ #ifdef BCMDRIVER #include #include diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmxtlv.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmxtlv.c index ddc6351cee18..91d5747f8581 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmxtlv.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmxtlv.c @@ -24,7 +24,9 @@ #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) #include +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) */ #ifdef BCMDRIVER #include diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus.c index c76a77b29214..4ce1ffa90385 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus.c @@ -32,6 +32,7 @@ */ +#include #include "osl.h" #include "dbus.h" #include @@ -51,7 +52,7 @@ #include #include #include -#endif +#endif @@ -59,7 +60,7 @@ #ifndef VARS_MAX #define VARS_MAX 8192 #endif -#endif +#endif #ifdef DBUS_USB_LOOPBACK extern bool is_loopback_pkt(void *buf); @@ -943,7 +944,7 @@ dbus_do_download(dhd_bus_t *dhd_bus) DBUS_FIRMWARE, 0, 0); if (!dhd_bus->firmware) return DBUS_ERR; -#endif +#endif dhd_bus->image = dhd_bus->fw; dhd_bus->image_len = (uint32)dhd_bus->fwlen; @@ -1519,7 +1520,7 @@ dbus_attach(osl_t *osh, int rxsize, int nrxq, int ntxq, dhd_pub_t *pub, dhd_bus->extdl.varslen = extdl->varslen; } } -#endif +#endif return (dhd_bus_t *)dhd_bus; @@ -1625,7 +1626,7 @@ int dbus_download_firmware(dhd_bus_t *pub, char *pfw_path, char *pnv_path) return err; } -#endif +#endif /** * higher layer requests us to 'up' the interface to the dongle. Prerequisite is that firmware (not @@ -2325,7 +2326,7 @@ uint16 boardtype, uint16 boardrev, int8 **nvram, int *nvram_len) return DBUS_JUMBO_NOMATCH; } /* dbus_select_nvram */ -#endif +#endif #define DBUS_NRXQ 50 #define DBUS_NTXQ 100 @@ -2573,6 +2574,19 @@ dhd_bus_chiprev(struct dhd_bus *bus) return bus->pub.attrib.chiprev; } +struct device * +dhd_bus_to_dev(struct dhd_bus *bus) +{ + struct usb_device *pdev; + + pdev = (struct usb_device *)bus->pub.dev_info; + + if (pdev) + return &pdev->dev; + else + return NULL; +} + void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) { @@ -2682,7 +2696,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) #if !defined(IGNORE_ETH0_DOWN) /* Restore flow control */ dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF); -#endif +#endif dhd_os_wd_timer(dhdp, dhd_watchdog_ms); DBUSTRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c index 173a4b980087..ccf018b07cff 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c @@ -2160,7 +2160,7 @@ dbus_usbos_intf_up(void *bus) return DBUS_ERR; } } -#endif +#endif if (usbos_info->ctl_urb) { usbos_info->ctl_in_pipe = usb_rcvctrlpipe(usbos_info->usb, 0); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h index d167cab0e800..3b70e18bf5f6 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h @@ -34,6 +34,7 @@ #define _dhd_h_ #if defined(LINUX) +#include #include #include #include @@ -2724,6 +2725,8 @@ void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size); #endif /* DHD_FW_COREDUMP */ #if defined(linux) || defined(LINUX) +int dhd_os_get_img_fwreq(const struct firmware **fw, char *file_path); +void dhd_os_close_img_fwreq(const struct firmware *fw); #if defined(DHD_SSSR_DUMP) void dhd_write_sssr_dump(dhd_pub_t *dhdp, uint32 dump_mode); #endif /* DHD_SSSR_DUMP */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_bus.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_bus.h index 5618b0206739..3614d4869203 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_bus.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_bus.h @@ -90,6 +90,7 @@ extern int dhd_bus_oob_intr_register(dhd_pub_t *dhdp); extern void dhd_bus_oob_intr_unregister(dhd_pub_t *dhdp); extern void dhd_bus_oob_intr_set(dhd_pub_t *dhdp, bool enable); extern int dhd_bus_get_oob_irq_num(dhd_pub_t *dhdp); +extern struct device * dhd_bus_to_dev(struct dhd_bus *bus); extern void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub); extern void dhd_bus_dev_pm_relax(dhd_pub_t *dhdpub); extern bool dhd_bus_dev_pm_enabled(dhd_pub_t *dhdpub); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c index fe68437cba0d..817484a47d79 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c @@ -1669,7 +1669,7 @@ dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) } #endif /* DHD_WET */ - DHD_ERROR(("%s bufsize: %d free: %d", __FUNCTION__, buflen, strbuf->size)); + DHD_ERROR(("%s bufsize: %d free: %d\n", __FUNCTION__, buflen, strbuf->size)); /* return remaining buffer length */ return (!strbuf->size ? BCME_BUFTOOSHORT : strbuf->size); } @@ -7804,6 +7804,82 @@ static int traffic_mgmt_add_dwm_filter(dhd_pub_t *dhd, } #endif /* BCM_ROUTER_DHD */ +#ifdef DHD_LINUX_STD_FW_API +int dhd_get_download_buffer(dhd_pub_t *dhd, char *file_path, download_type_t component, + char ** buffer, int *length) +{ + int ret = BCME_ERROR; + const struct firmware *fw = NULL; +#ifdef SUPPORT_OTA_UPDATE + uint8 *buf = NULL; + int len = 0; + ota_update_info_t *ota_info = &dhd->ota_update_info; +#endif /* SUPPORT_OTA_UPDATE */ + +#ifdef SUPPORT_OTA_UPDATE + if (component == CLM_BLOB) { + if (ota_info->clm_len) { + DHD_ERROR(("Using OTA CLM_BLOB\n")); + buf = ota_info->clm_buf; + len = ota_info->clm_len; + } + } + else if (component == NVRAM) { + if (ota_info->nvram_len) { + DHD_ERROR(("Using OTA NVRAM.\n")); + buf = ota_info->nvram_buf; + len = ota_info->nvram_len; + } + } +#endif /* SUPPORT_OTA_UPDATE */ + +#ifdef SUPPORT_OTA_UPDATE + if (len) { + *buffer = (char *)buf; + *length = len; + } + else +#endif /* SUPPORT_OTA_UPDATE */ + { + if (file_path) { + ret = dhd_os_get_img_fwreq(&fw, file_path); + if (ret < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + ret)); + goto err; + } else { + if ((fw->size <= 0 || fw->size > *length)) { + DHD_ERROR(("fw->size = %d, *length = %d\n", fw->size, *length)); + *length = fw->size; + goto err; + } + *buffer = VMALLOCZ(dhd->osh, fw->size); + if (*buffer == NULL) { + DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", + __FUNCTION__, (int)fw->size)); + ret = BCME_NOMEM; + goto err; + } + *length = fw->size; + ret = memcpy_s(*buffer, fw->size, fw->data, fw->size); + if (ret != BCME_OK) { + DHD_ERROR(("%s: memcpy_s failed, err : %d\n", + __FUNCTION__, ret)); + goto err; + } + ret = BCME_OK; + } + } + } +err: + if (fw) { + dhd_os_close_img_fwreq(fw); + } + return ret; +} + +#else + /* Given filename and download type, returns a buffer pointer and length * for download to f/w. Type can be FW or NVRAM. * @@ -7923,6 +7999,7 @@ err: return ret; } +#endif /* DHD_LINUX_STD_FW_API */ int dhd_download_2_dongle(dhd_pub_t *dhd, char *iovar, uint16 flag, uint16 dload_type, @@ -7963,9 +8040,9 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf, { int chunk_len; -#if !defined(LINUX) && !defined(linux) +#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API) int cumulative_len = 0; -#endif /* !LINUX && !linux */ +#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */ int size2alloc; unsigned char *new_buf; int err = 0, data_offset; @@ -7977,7 +8054,7 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf, if ((new_buf = (unsigned char *)MALLOCZ(dhd->osh, size2alloc)) != NULL) { do { -#if !defined(LINUX) && !defined(linux) +#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API) if (len >= MAX_CHUNK_LEN) chunk_len = MAX_CHUNK_LEN; else @@ -7994,7 +8071,7 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf, err = BCME_ERROR; goto exit; } -#endif /* !LINUX && !linux */ +#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */ if (len - chunk_len == 0) dl_flag |= DL_END; @@ -8005,13 +8082,13 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf, len = len - chunk_len; } while ((len > 0) && (err == 0)); -#if !defined(LINUX) && !defined(linux) +#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API) MFREE(dhd->osh, new_buf, size2alloc); #endif /* !LINUX && !linux */ } else { err = BCME_NOMEM; } -#if defined(LINUX) || defined(linux) +#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API) exit: if (new_buf) { MFREE(dhd->osh, new_buf, size2alloc); @@ -8258,7 +8335,7 @@ int dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) { char *clm_blob_path; - int len; + int len = 0, memblock_len = 0; char *memblock = NULL; int err = BCME_OK; char iovbuf[WLC_IOCTL_SMLEN]; @@ -8272,7 +8349,11 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) clm_blob_path = clm_path; DHD_TRACE(("clm path from module param:%s\n", clm_path)); } else { +#ifdef DHD_LINUX_STD_FW_API + clm_blob_path = DHD_CLM_NAME; +#else clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; +#endif /* DHD_LINUX_STD_FW_API */ } /* If CLM blob file is found on the filesystem, download the file. @@ -8280,11 +8361,21 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) * validate the country code before proceeding with the initialization. * If country code is not valid, fail the initialization. */ -#if !defined(LINUX) && !defined(linux) +#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API) len = MAX_CLM_BUF_SIZE; dhd_get_download_buffer(dhd, clm_blob_path, CLM_BLOB, &memblock, &len); +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAX_CLM_BUF_SIZE; +#endif /* DHD_LINUX_STD_FW_API */ #else memblock = dhd_os_open_image1(dhd, (char *)clm_blob_path); + len = dhd_os_get_image_size(memblock); + BCM_REFERENCE(memblock_len); +#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */ + +#if defined(LINUX) || defined(linux) if (memblock == NULL) { printf("%s: Ignore clm file %s\n", __FUNCTION__, clm_path); #if defined(DHD_BLOB_EXISTENCE_CHECK) @@ -8301,8 +8392,6 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) #endif /* DHD_BLOB_EXISTENCE_CHECK */ goto exit; } - - len = dhd_os_get_image_size(memblock); #endif /* !LINUX && !linux */ if ((len > 0) && (len < MAX_CLM_BUF_SIZE) && memblock) { @@ -8368,10 +8457,10 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) exit: if (memblock) { -#if defined(LINUX) || defined(linux) +#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API) dhd_os_close_image1(dhd, memblock); #else - dhd_free_download_buffer(dhd, memblock, MAX_CLM_BUF_SIZE); + dhd_free_download_buffer(dhd, memblock, memblock_len); #endif /* LINUX || linux */ } @@ -8384,7 +8473,11 @@ void dhd_free_download_buffer(dhd_pub_t *dhd, void *buffer, int length) #ifdef CACHE_FW_IMAGES return; #endif +#if defined(DHD_LINUX_STD_FW_API) + VMFREE(dhd->osh, buffer, length); +#else MFREE(dhd->osh, buffer, length); +#endif /* DHD_LINUX_STD_FW_API */ } #ifdef REPORT_FATAL_TIMEOUTS @@ -9063,8 +9156,13 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size, int32 i = 0; uint8 *pfw_id = NULL; uint32 fwid = 0; +#ifdef DHD_LINUX_STD_FW_API + int err = 0; + const struct firmware *fw = NULL; +#else void *file = NULL; int file_len = 0; +#endif /* DHD_LINUX_STD_FW_API */ char fwid_str[FWID_STR_LEN]; uint32 hdr_logstrs_size = 0; @@ -9097,6 +9195,23 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size, * both logstrs.bin and fw bin */ +#ifdef DHD_LINUX_STD_FW_API + err = dhd_os_get_img_fwreq(&fw, st_str_file_path); + if (err < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + err)); + goto error; + } + memset(fwid_str, 0, sizeof(fwid_str)); + err = memcpy_s(fwid_str, (sizeof(fwid_str) - 1), + &(fw->data[fw->size - (sizeof(fwid_str) - 1)]), + (sizeof(fwid_str) - 1)); + if (err) { + DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n", + __FUNCTION__, err)); + goto error; + } +#else /* read the FWID from fw bin */ file = dhd_os_open_image1(NULL, st_str_file_path); if (!file) { @@ -9119,6 +9234,7 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size, DHD_ERROR(("%s: read fw file failed !\n", __FUNCTION__)); goto error; } +#endif /* DHD_LINUX_STD_FW_API */ pfw_id = (uint8 *)bcmstrnstr(fwid_str, sizeof(fwid_str) - 1, FWID_STR_1, strlen(FWID_STR_1)); if (!pfw_id) { @@ -9156,9 +9272,15 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size, hdr_logstrs_size = hdr->logstrs_size; error: +#ifdef DHD_LINUX_STD_FW_API + if (fw) { + dhd_os_close_img_fwreq(fw); + } +#else if (file) { dhd_os_close_image1(NULL, file); } +#endif /* DHD_LINUX_STD_FW_API */ if (match_fail) { return BCME_DECERR; } @@ -9223,6 +9345,101 @@ error: return BCME_OK; } /* dhd_parse_logstrs_file */ +#ifdef DHD_LINUX_STD_FW_API +int dhd_parse_map_file(osl_t *osh, void *ptr, uint32 *ramstart, uint32 *rodata_start, + uint32 *rodata_end) +{ + char *raw_fmts = NULL, *raw_fmts_loc = NULL; + uint32 read_size = READ_NUM_BYTES, offset = 0; + int error = 0; + char * cptr = NULL; + char c; + uint8 count = 0; + uint32 size = 0; + + *ramstart = 0; + *rodata_start = 0; + *rodata_end = 0; + size = (uint32)(((struct firmware *)ptr)->size); + + /* Allocate 1 byte more than read_size to terminate it with NULL */ + raw_fmts = MALLOCZ(osh, read_size + 1); + if (raw_fmts == NULL) { + DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__)); + goto fail; + } + + /* read ram start, rodata_start and rodata_end values from map file */ + while (count != ALL_MAP_VAL) + { + /* Bound check for size before doing memcpy() */ + if ((offset + read_size) > size) { + read_size = size - offset; + } + + error = memcpy_s(raw_fmts, read_size, + (((char *)((struct firmware *)ptr)->data) + offset), read_size); + if (error) { + DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n", + __FUNCTION__, error)); + goto fail; + } + /* End raw_fmts with NULL as strstr expects NULL terminated strings */ + raw_fmts[read_size] = '\0'; + + /* Get ramstart address */ + raw_fmts_loc = raw_fmts; + if (!(count & RAMSTART_BIT) && + (cptr = bcmstrnstr(raw_fmts_loc, read_size, ramstart_str, + strlen(ramstart_str)))) { + cptr = cptr - BYTES_AHEAD_NUM; + sscanf(cptr, "%x %c text_start", ramstart, &c); + count |= RAMSTART_BIT; + } + + /* Get ram rodata start address */ + raw_fmts_loc = raw_fmts; + if (!(count & RDSTART_BIT) && + (cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_start_str, + strlen(rodata_start_str)))) { + cptr = cptr - BYTES_AHEAD_NUM; + sscanf(cptr, "%x %c rodata_start", rodata_start, &c); + count |= RDSTART_BIT; + } + + /* Get ram rodata end address */ + raw_fmts_loc = raw_fmts; + if (!(count & RDEND_BIT) && + (cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_end_str, + strlen(rodata_end_str)))) { + cptr = cptr - BYTES_AHEAD_NUM; + sscanf(cptr, "%x %c rodata_end", rodata_end, &c); + count |= RDEND_BIT; + } + + if ((offset + read_size) >= size) { + break; + } + + memset(raw_fmts, 0, read_size); + offset += (read_size - GO_BACK_FILE_POS_NUM_BYTES); + } + +fail: + if (raw_fmts) { + MFREE(osh, raw_fmts, read_size + 1); + raw_fmts = NULL; + } + if (count == ALL_MAP_VAL) { + return BCME_OK; + } + else { + DHD_ERROR(("%s: readmap error 0X%x \n", __FUNCTION__, + count)); + return BCME_ERROR; + } +} /* dhd_parse_map_file */ +#else int dhd_parse_map_file(osl_t *osh, void *file, uint32 *ramstart, uint32 *rodata_start, uint32 *rodata_end) { @@ -9320,6 +9537,7 @@ fail: } } /* dhd_parse_map_file */ +#endif /* DHD_LINUX_STD_FW_API */ #ifdef PCIE_FULL_DONGLE int diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c index 14ace7d870ff..dac725e0e305 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c @@ -48,19 +48,19 @@ uint dump_msg_level = 0; #define CONFIG_MSG(x, args...) \ do { \ if (config_msg_level & CONFIG_MSG_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIXS "%s : " x, __func__, ## args); \ + printf("%s : " x, __func__, ## args); \ } \ } while (0) #define CONFIG_ERROR(x, args...) \ do { \ if (config_msg_level & CONFIG_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIXS "CONFIG-ERROR) %s : " x, __func__, ## args); \ + printf("CONFIG-ERROR) %s : " x, __func__, ## args); \ } \ } while (0) #define CONFIG_TRACE(x, args...) \ do { \ if (config_msg_level & CONFIG_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "CONFIG-TRACE) %s : " x, __func__, ## args); \ + printf("CONFIG-TRACE) %s : " x, __func__, ## args); \ } \ } while (0) @@ -1146,7 +1146,10 @@ dhd_conf_set_tput_patch(dhd_pub_t *dhd) if (conf->tput_patch) { conf->mtu = 1500; - conf->pktsetsum = TRUE; +/* set pktsetsum false by default since this will cause to + * the checksum is wrong of downloaded file +*/ + conf->pktsetsum = FALSE; #ifdef BCMSDIO conf->dhd_dpc_prio = 98; /* need to check if CPU can support multi-core first, @@ -1251,14 +1254,73 @@ dhd_conf_dump_tput_patch(dhd_pub_t *dhd) } #endif /* DHD_TPUT_PATCH */ +#ifdef DHD_LINUX_STD_FW_API +#define FIRMWARE_CLASS_PATH "/sys/module/firmware_class/parameters/path" +static int +dhd_conf_get_fw_path(char *path, int len) +{ + char *pch; + int err, path_len = 0; + + err = dhd_read_file(FIRMWARE_CLASS_PATH, path, len); + if(err < 0){ + CONFIG_ERROR("firmware path can not read %d\n", err); + } else { + pch = strchr(path, '\n'); + if (pch) + *pch = '\0'; + CONFIG_TRACE("path = %s\n", path); + path_len = strlen(path); + } + + return path_len; +} + +static void +dhd_conf_get_filename(char *pFilename) +{ + const char *pName = NULL; + + if ((pFilename) && (*pFilename)) { + // back/reverse search the '/' + pName = strrchr(pFilename, '/'); + if (NULL == pName) { + pName = pFilename; + } else { + if (pName[1]) { + pName++; + } else { + pName = NULL; + } + } + } + + if (pName) + strcpy(pFilename, pName); + return; +} +#endif /* DHD_LINUX_STD_FW_API */ + void dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path) { int ag_type; +#ifdef DHD_LINUX_STD_FW_API + char path[WLC_IOCTL_SMLEN]; + int path_len; +#endif /* External conf takes precedence if specified */ dhd_conf_preinit(dhd); +#ifdef DHD_LINUX_STD_FW_API + // preprocess the filename to only left 'name' + dhd_conf_get_filename(fw_path); + dhd_conf_get_filename(nv_path); + dhd_conf_get_filename(dhd->clm_path); + dhd_conf_get_filename(dhd->conf_path); +#endif + if (dhd->conf_path[0] == '\0') { dhd_conf_copy_path(dhd, "config.txt", dhd->conf_path, nv_path); } @@ -1269,11 +1331,6 @@ dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path) dhd_conf_set_conf_name_by_chip(dhd, dhd->conf_path); #endif - dhd_conf_read_config(dhd, dhd->conf_path); -#ifdef DHD_TPUT_PATCH - dhd_conf_dump_tput_patch(dhd); -#endif - ag_type = dhd_conf_set_fw_name_by_chip(dhd, fw_path); dhd_conf_set_nv_name_by_chip(dhd, nv_path, ag_type); dhd_conf_set_clm_name_by_chip(dhd, dhd->clm_path, ag_type); @@ -1282,10 +1339,28 @@ dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path) dhd_conf_set_nv_name_by_mac(dhd, nv_path); #endif +#ifdef DHD_LINUX_STD_FW_API + memset(path, 0, sizeof(path)); + path_len = dhd_conf_get_fw_path(path, sizeof(path)); + snprintf(path+path_len, WLC_IOCTL_SMLEN, "%s", fw_path); + CONFIG_MSG("Final fw_path=%s\n", path); + snprintf(path+path_len, WLC_IOCTL_SMLEN, "%s", nv_path); + CONFIG_MSG("Final nv_path=%s\n", path); + snprintf(path+path_len, WLC_IOCTL_SMLEN, "%s", dhd->clm_path); + CONFIG_MSG("Final clm_path=%s\n", path); + snprintf(path+path_len, WLC_IOCTL_SMLEN, "%s", dhd->conf_path); + CONFIG_MSG("Final conf_path=%s\n", path); +#else CONFIG_MSG("Final fw_path=%s\n", fw_path); CONFIG_MSG("Final nv_path=%s\n", nv_path); CONFIG_MSG("Final clm_path=%s\n", dhd->clm_path); CONFIG_MSG("Final conf_path=%s\n", dhd->conf_path); +#endif + + dhd_conf_read_config(dhd, dhd->conf_path); +#ifdef DHD_TPUT_PATCH + dhd_conf_dump_tput_patch(dhd); +#endif } int @@ -3938,6 +4013,14 @@ dhd_conf_read_pcie_params(dhd_pub_t *dhd, char *full_param, uint len_param) conf->flow_ring_queue_threshold = (int)simple_strtol(data, NULL, 10); CONFIG_MSG("flow_ring_queue_threshold = %d\n", conf->flow_ring_queue_threshold); } + else if (!strncmp("d2h_intr_control=", full_param, len_param)) { + conf->d2h_intr_control = (int)simple_strtol(data, NULL, 10); + CONFIG_MSG("d2h_intr_control = %d\n", conf->d2h_intr_control); + } + else if (!strncmp("enq_hdr_pkt=", full_param, len_param)) { + conf->enq_hdr_pkt = (int)simple_strtol(data, NULL, 0); + CONFIG_MSG("enq_hdr_pkt = 0x%x\n", conf->enq_hdr_pkt); + } else return false; @@ -4367,33 +4450,37 @@ int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) { int bcmerror = -1, chip_match = -1; - uint len = 0, start_pos=0, end_pos=0; - void *image = NULL; + uint len = 0, memblock_len = 0, start_pos=0, end_pos=0; char *memblock = NULL; char *bufp, *pick = NULL, *pch; bool conf_file_exists; uint len_param; + len = MAXSZ_CONFIG; + conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); if (!conf_file_exists) { CONFIG_MSG("config path %s\n", conf_path); return (0); } - if (conf_file_exists) { - image = dhd_os_open_image1(dhd, conf_path); - if (image == NULL) { - CONFIG_MSG("Ignore config file %s\n", conf_path); - goto err; - } - } + if (conf_file_exists) + bcmerror = dhd_get_download_buffer(dhd, conf_path, NVRAM, &memblock, + (int *)&len); + else + bcmerror = dhd_get_download_buffer(dhd, NULL, NVRAM, &memblock, (int *)&len); - memblock = MALLOC(dhd->osh, MAXSZ_CONFIG); - if (memblock == NULL) { - CONFIG_ERROR("Failed to allocate memory %d bytes\n", MAXSZ_CONFIG); + if (bcmerror != BCME_OK) { + CONFIG_MSG("Ignore config file %s\n", conf_path); goto err; } +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAXSZ_CONFIG; +#endif /* DHD_LINUX_STD_FW_API */ + pick = MALLOC(dhd->osh, MAXSZ_BUF); if (!pick) { CONFIG_ERROR("Failed to allocate memory %d bytes\n", MAXSZ_BUF); @@ -4401,9 +4488,6 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) } /* Read variables */ - if (conf_file_exists) { - len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image); - } if (len > 0 && len < MAXSZ_CONFIG) { bufp = (char *)memblock; bufp[len] = 0; @@ -4487,10 +4571,7 @@ err: MFREE(dhd->osh, pick, MAXSZ_BUF); if (memblock) - MFREE(dhd->osh, memblock, MAXSZ_CONFIG); - - if (image) - dhd_os_close_image1(dhd, image); + dhd_free_download_buffer(dhd, memblock, memblock_len); return bcmerror; } @@ -4587,7 +4668,7 @@ dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable) CONFIG_MSG("txglom_ext=%d, txglom_bucket_size=%d\n", conf->txglom_ext, conf->txglom_bucket_size); CONFIG_MSG("txglom_mode=%s\n", - conf->txglom_mode==SDPCM_TXGLOM_MDESC?"multi-desc":"copy"); + conf->txglom_mode==SDPCM_TXGLOM_MDESC?"multi-desc":"copy"); CONFIG_MSG("txglomsize=%d, deferred_tx_len=%d\n", conf->txglomsize, conf->deferred_tx_len); CONFIG_MSG("txinrx_thres=%d, dhd_txminmax=%d\n", @@ -4682,8 +4763,7 @@ dhd_conf_postinit_ioctls(dhd_pub_t *dhd) dhd_conf_set_wl_cmd(dhd, wl_preinit, TRUE); #if defined(BCMSDIO) - if (conf->chip == BCM43751_CHIP_ID || conf->chip == BCM43752_CHIP_ID || - conf->chip == BCM4375_CHIP_ID) { + if (conf->chip == BCM43751_CHIP_ID || conf->chip == BCM43752_CHIP_ID) { char ampdu_mpdu[] = "ampdu_mpdu=32"; dhd_conf_set_wl_cmd(dhd, ampdu_mpdu, TRUE); } else { @@ -4711,6 +4791,12 @@ dhd_conf_postinit_ioctls(dhd_pub_t *dhd) char txack_alive[] = "txack_alive=0"; dhd_conf_set_wl_cmd(dhd, txack_alive, TRUE); } +#ifdef WLDWDS + { + char dwds[] = "dwds=1"; + dhd_conf_set_wl_cmd(dhd, dwds, TRUE); + } +#endif /* WLDWDS */ #if defined(WLEASYMESH) if (conf->fw_type == FW_TYPE_EZMESH) { if (conf->chip == BCM4359_CHIP_ID) { @@ -4792,7 +4878,8 @@ dhd_conf_preinit(dhd_pub_t *dhd) strcpy(conf->cspec.country_abbrev, "ALL"); strcpy(conf->cspec.ccode, "ALL"); conf->cspec.rev = 0; - } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || + } + else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID || @@ -4800,7 +4887,8 @@ dhd_conf_preinit(dhd_pub_t *dhd) strcpy(conf->cspec.country_abbrev, "CN"); strcpy(conf->cspec.ccode, "CN"); conf->cspec.rev = 38; - } else { + } + else { strcpy(conf->cspec.country_abbrev, "CN"); strcpy(conf->cspec.ccode, "CN"); conf->cspec.rev = 0; @@ -4869,6 +4957,8 @@ dhd_conf_preinit(dhd_pub_t *dhd) conf->bus_deepsleep_disable = 1; conf->flow_ring_queue_threshold = FLOW_RING_QUEUE_THRESHOLD; conf->d2h_intr_method = -1; + conf->d2h_intr_control = -1; + conf->enq_hdr_pkt = 0; #endif conf->dpc_cpucore = -1; conf->rxf_cpucore = -1; @@ -5046,6 +5136,11 @@ dhd_conf_preinit(dhd_pub_t *dhd) conf->txglomsize = SDPCM_MAXGLOM_SIZE; #endif init_waitqueue_head(&conf->event_complete); +#ifdef CUSTOMER_HW_ROCKCHIP +#ifdef BCMPCIE + conf->d2h_intr_control = 0; +#endif +#endif return 0; } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h index c053f07d4f70..815e9c458b93 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h @@ -22,7 +22,11 @@ #define FW_TYPE_AG 1 #define FW_PATH_AUTO_SELECT 1 +#ifdef BCMDHD_MDRIVER +#define CONFIG_PATH_AUTO_SELECT +#else //#define CONFIG_PATH_AUTO_SELECT +#endif extern char firmware_path[MOD_PARAM_PATHLEN]; #if defined(BCMSDIO) || defined(BCMPCIE) extern uint dhd_rxbound; @@ -64,9 +68,10 @@ typedef struct wl_chip_nv_path_list_ctrl { struct wl_chip_nv_path *m_chip_nv_path_head; } wl_chip_nv_path_list_ctrl_t; +#define MAX_CTRL_CHANSPECS 256 typedef struct wl_channel_list { uint32 count; - uint32 channel[WL_NUMCHANNELS]; + uint32 channel[MAX_CTRL_CHANSPECS]; } wl_channel_list_t; typedef struct wmes_param { @@ -187,6 +192,13 @@ enum conn_state { CONN_STATE_GROUPKEY_M2 = 24, }; +enum enq_pkt_type { + ENQ_PKT_TYPE_EAPOL = (1 << (0)), + ENQ_PKT_TYPE_ARP = (1 << (1)), + ENQ_PKT_TYPE_DHCP = (1 << (2)), + ENQ_PKT_TYPE_ICMP = (1 << (3)), +}; + typedef struct dhd_conf { uint devid; uint chip; @@ -283,6 +295,8 @@ typedef struct dhd_conf { int bus_deepsleep_disable; int flow_ring_queue_threshold; int d2h_intr_method; + int d2h_intr_control; + int enq_hdr_pkt; #endif int dpc_cpucore; int rxf_cpucore; @@ -433,6 +447,8 @@ void dhd_conf_detach(dhd_pub_t *dhd); void *dhd_get_pub(struct net_device *dev); int wl_pattern_atoh(char *src, char *dst); int dhd_conf_suspend_resume_sta(dhd_pub_t *dhd, int ifidx, int suspend); +/* Add to adjust 802.1x priority */ +extern void pktset8021xprio(void *pkt, int prio); #ifdef BCMSDIO extern int dhd_bus_sleep(dhd_pub_t *dhdp, bool sleep, uint32 *intstatus); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.c index f61cced09958..5cacb9c80365 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.c @@ -84,7 +84,7 @@ dhd_csi_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) dump_len = p_event->header.cfr_dump_length; if (dump_len < MAX_EVENT_SIZE) { bcopy(&p_event->data, &ptr->entry.data, dump_len); - } else { + } else { /* for big csi data */ uint8 *p = (uint8 *)&ptr->entry.data; remain = p_event->header.remain_length; @@ -217,4 +217,3 @@ dhd_csi_dump_list(dhd_pub_t *dhd, char *buf) return length; } - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.h index 448753c1b160..e1c0aaaac6dc 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_csi.h @@ -74,4 +74,3 @@ void dhd_csi_clean_list(dhd_pub_t *dhd); int dhd_csi_dump_list(dhd_pub_t *dhd, char *buf); #endif /* __DHD_CSI_H__ */ - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_dbg.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_dbg.h index 48b9c487838e..c955e38fcc46 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_dbg.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_dbg.h @@ -120,9 +120,9 @@ extern char* dhd_dbg_get_system_timestamp(void); #endif /* DHD_LOG_DUMP */ #if defined(CUSTOMER_DBG_SYSTEM_TIME) && defined(DHD_DEBUGABILITY_LOG_DUMP_RING) -#define DBG_PRINT_PREFIX "[%s][dhd] ", dhd_dbg_get_system_timestamp() +#define DBG_PRINT_PREFIX "[%s][dhd][wlan]", dhd_dbg_get_system_timestamp() #else -#define DBG_PRINT_PREFIX "[dhd] " +#define DBG_PRINT_PREFIX #endif #define DBG_PRINT_SYSTEM_TIME pr_cont(DBG_PRINT_PREFIX) @@ -163,8 +163,7 @@ do { \ #define DHD_ERROR(args) \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ DHD_LOG_DUMP_WRITE_TS; \ DHD_LOG_DUMP_WRITE args; \ } \ @@ -238,8 +237,7 @@ do { \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ if (dhd_msg_level & DHD_ERROR_MEM_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ } \ DHD_LOG_DUMP_WRITE args; \ } \ @@ -248,8 +246,7 @@ do { \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ if (dhd_msg_level & DHD_IOVAR_MEM_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ } \ DHD_LOG_DUMP_WRITE args; \ } \ @@ -264,8 +261,7 @@ do { \ #define DHD_EVENT(args) \ do { \ if (dhd_msg_level & DHD_EVENT_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ DHD_LOG_DUMP_WRITE_PRSRV_TS; \ DHD_LOG_DUMP_WRITE_PRSRV args; \ } \ @@ -274,7 +270,6 @@ do { \ do { \ if (dhd_msg_level & DHD_EVENT_VAL) { \ if (dhd_msg_level & DHD_PRSRV_MEM_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ printf args; \ } \ DHD_LOG_DUMP_WRITE_TS; \ @@ -290,8 +285,7 @@ do { \ do { \ if (dhd_msg_level & DHD_EVENT_VAL) { \ if (dhd_msg_level & DHD_MSGTRACE_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ DHD_LOG_DUMP_WRITE_TS; \ DHD_LOG_DUMP_WRITE args; \ } \ @@ -300,8 +294,7 @@ do { \ #define DHD_ERROR_EX(args) \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ DHD_LOG_DUMP_WRITE_EX_TS; \ DHD_LOG_DUMP_WRITE_EX args; \ } \ @@ -309,8 +302,7 @@ do { \ #define DHD_MSGTRACE_LOG(args) \ do { \ if (dhd_msg_level & DHD_MSGTRACE_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ } \ DHD_LOG_DUMP_WRITE_TS; \ DHD_LOG_DUMP_WRITE args; \ @@ -319,8 +311,7 @@ do { \ #define DHD_ERROR_ROAM(args) \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ - DBG_PRINT_SYSTEM_TIME; \ - pr_cont args; \ + printf args; \ DHD_LOG_DUMP_WRITE_ROAM_TS; \ DHD_LOG_DUMP_WRITE_ROAM args; \ } \ @@ -352,6 +343,7 @@ do { \ #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_RPM(args) do {if (dhd_msg_level & DHD_RPM_VAL) printf args;} while (0) #define DHD_PKT_MON(args) do {if (dhd_msg_level & DHD_PKT_MON_VAL) printf args;} while (0) #if defined(DHD_LOG_DUMP) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.c index 08411767a90e..12218c260ce7 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.c @@ -210,6 +210,39 @@ done: return ret; } +int BCMFASTPATH +(dhd_flow_queue_enqueue_head)(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt) +{ + int ret = BCME_OK; + + ASSERT(queue != NULL); + + if (dhd_flow_queue_throttle(queue)) { + queue->failures++; + ret = (*queue->cb)(queue, pkt); + goto done; + } + + if (queue->head) { + FLOW_QUEUE_PKT_SETNEXT(pkt, queue->head); + queue->head = pkt; + + } else { + queue->head = pkt; + FLOW_QUEUE_PKT_SETNEXT(pkt, NULL); + queue->tail = pkt; /* at tail */ + } + + queue->len++; + /* increment parent's cummulative length */ + DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_CLEN_PTR(queue)); + /* increment grandparent's cummulative length */ + DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_L2CLEN_PTR(queue)); + +done: + return ret; +} + /** Dequeue an 802.3 packet from a flow ring's queue, from head (FIFO) */ void * BCMFASTPATH(dhd_flow_queue_dequeue)(dhd_pub_t *dhdp, flow_queue_t *queue) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.h index 873ca68a1213..404ea4c0e370 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_flowring.h @@ -307,6 +307,7 @@ extern void dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max); extern void dhd_flow_queue_reinit(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 int dhd_flow_queue_enqueue_head(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); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c index 39095e887a2a..05b735fcdf3e 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c @@ -404,10 +404,14 @@ int dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter) adapter->index = 0; } err = dhd_wlan_init_gpio(adapter); + if (err) + goto exit; #ifdef DHD_STATIC_IN_DRIVER - dhd_static_buf_init(); + err = dhd_static_buf_init(); #endif + +exit: return err; } @@ -419,4 +423,3 @@ void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter) #endif dhd_wlan_deinit_gpio(adapter); } - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c index bee40a506197..c52dd98a2cdc 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c @@ -65,7 +65,9 @@ #include #include #include +#if defined(CUSTOMER_HW_ROCKCHIP) && defined(BCMPCIE) #include +#endif /* CUSTOMER_HW_ROCKCHIP && BCMPCIE */ #include #include @@ -633,8 +635,8 @@ extern void dhd_netdev_free(struct net_device *ndev); static dhd_if_t * dhd_get_ifp_by_ndev(dhd_pub_t *dhdp, struct net_device *ndev); #if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) -static void dhd_bridge_dev_set(dhd_info_t * dhd, int ifidx, struct net_device * dev); -#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */ +static void dhd_bridge_dev_set(dhd_info_t *dhd, int ifidx, struct net_device *sdev); +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ #if (defined(DHD_WET) || defined(DHD_MCAST_REGEN) || defined(DHD_L2_FILTER)) /* update rx_pkt_chainable state of dhd interface */ @@ -837,20 +839,19 @@ module_param(tpoweron_scale, uint, 0644); #endif /* FORCE_TPOWERON */ #ifdef SHOW_LOGTRACE -#if defined(CUSTOMER_HW4_DEBUG) -#define WIFI_PATH "/etc/wifi/" -static char *logstrs_path = VENDOR_PATH WIFI_PATH"logstrs.bin"; -char *st_str_file_path = VENDOR_PATH WIFI_PATH"rtecdc.bin"; -static char *map_file_path = VENDOR_PATH WIFI_PATH"rtecdc.map"; -static char *rom_st_str_file_path = VENDOR_PATH WIFI_PATH"roml.bin"; -static char *rom_map_file_path = VENDOR_PATH WIFI_PATH"roml.map"; +#ifdef DHD_LINUX_STD_FW_API +static char *logstrs_path = "logstrs.bin"; +char *st_str_file_path = "rtecdc.bin"; +static char *map_file_path = "rtecdc.map"; +static char *rom_st_str_file_path = "roml.bin"; +static char *rom_map_file_path = "roml.map"; #else static char *logstrs_path = PLATFORM_PATH"logstrs.bin"; char *st_str_file_path = PLATFORM_PATH"rtecdc.bin"; static char *map_file_path = PLATFORM_PATH"rtecdc.map"; static char *rom_st_str_file_path = PLATFORM_PATH"roml.bin"; static char *rom_map_file_path = PLATFORM_PATH"roml.map"; -#endif /* CUSTOMER_HW4_DEBUG */ +#endif /* DHD_LINUX_STD_FW_API */ static char *ram_file_str = "rtecdc"; static char *rom_file_str = "roml"; @@ -3072,7 +3073,7 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr, bool skip_stop) dhd_ifname(&dhd->pub, ifidx), addr, ret)); goto exit; } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); + dev_addr_set(dhd->iflist[ifidx]->net, addr); if (ifidx == 0) memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN); WL_MSG(dhd_ifname(&dhd->pub, ifidx), "MACID %pM is overwritten\n", addr); @@ -3262,7 +3263,7 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event) struct wl_if_event_info info; #if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) struct net_device *ndev = NULL; -#endif +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ #else struct net_device *ndev; #endif /* WL_CFG80211 && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ @@ -3315,13 +3316,13 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event) mac_addr = NULL; } -#ifdef WLEASYMESH +#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) if ((ndev = wl_cfg80211_post_ifcreate(dhd->pub.info->iflist[0]->net, &info, mac_addr, if_event->name, true)) == NULL) #else if (wl_cfg80211_post_ifcreate(dhd->pub.info->iflist[0]->net, &info, mac_addr, NULL, true) == NULL) -#endif +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ { /* Do the post interface create ops */ DHD_ERROR(("Post ifcreate ops failed. Returning \n")); @@ -3363,6 +3364,10 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event) } #endif /* PCIE_FULL_DONGLE */ +#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) + dhd_bridge_dev_set(dhd, ifidx, ndev); +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ + done: #ifdef DHD_AWDL if (ret != BCME_OK && is_awdl_iface) { @@ -3371,11 +3376,6 @@ done: #endif /* DHD_AWDL */ MFREE(dhd->pub.osh, if_event, sizeof(dhd_if_event_t)); -#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) - if (dhd->pub.info->iflist[ifidx]) { - dhd_bridge_dev_set(dhd, ifidx, ndev); - } -#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */ DHD_OS_WAKE_UNLOCK(&dhd->pub); dhd_net_if_unlock_local(dhd); @@ -3408,17 +3408,15 @@ dhd_ifdel_event_handler(void *handle, void *event_info, u8 event) ifidx = if_event->event.ifidx; DHD_TRACE(("Removing interface with idx %d\n", ifidx)); -#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) - if (dhd->pub.info->iflist[ifidx]) { - dhd_bridge_dev_set(dhd, ifidx, NULL); - } -#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */ if (!dhd->pub.info->iflist[ifidx]) { /* No matching netdev found */ DHD_ERROR(("Netdev not found! Do nothing.\n")); goto done; } +#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) + dhd_bridge_dev_set(dhd, ifidx, NULL); +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ #if defined(WL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) if (if_event->event.ifidx > 0) { /* Do the post interface del ops */ @@ -3519,7 +3517,7 @@ int dhd_op_if_update(dhd_pub_t *dhdpub, int ifidx) (unsigned char)buf[3], (unsigned char)buf[4], (unsigned char)buf[5])); memcpy(dhdinfo->iflist[ifp->idx]->mac_addr, buf, ETHER_ADDR_LEN); if (dhdinfo->iflist[ifp->idx]->net) { - memcpy(dhdinfo->iflist[ifp->idx]->net->dev_addr, buf, ETHER_ADDR_LEN); + dev_addr_set(dhdinfo->iflist[ifp->idx]->net, buf); } } @@ -3662,7 +3660,7 @@ dhd_set_mac_address(struct net_device *dev, void *addr) * available). Store the address and return. macaddr will be applied * from interface create context. */ - (void)memcpy_s(dev->dev_addr, ETH_ALEN, dhdif->mac_addr, ETH_ALEN); + dev_addr_set(dev, dhdif->mac_addr); #ifdef DHD_NOTIFY_MAC_CHANGED #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) dev_open(dev, NULL); @@ -3793,7 +3791,7 @@ int dhd_sendup(dhd_pub_t *dhdp, int ifidx, void *p) bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE, __FUNCTION__, __LINE__); #if defined(WL_MONITOR) && defined(BCMSDIO) - if (dhd_monitor_enabled(dhdp, ifidx)) + if (dhd_monitor_enabled(dhdp, ifidx)) dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx); else #endif /* WL_MONITOR && BCMSDIO */ @@ -5667,7 +5665,7 @@ dhd_check_shinfo_nrfrags(dhd_pub_t *dhdp, void *pktbuf, shinfo = skb_shinfo(skb); if (shinfo->nr_frags) { -#ifdef CONFIG_64BIT +#ifdef BCMDMA64OSL DHD_ERROR(("!!Invalid nr_frags: %u pa.loaddr: 0x%llx pa.hiaddr: 0x%llx " "skb: 0x%llx skb_data: 0x%llx skb_head: 0x%llx skb_tail: 0x%llx " "skb_end: 0x%llx skb_len: %u shinfo: 0x%llx pktid: %u\n", @@ -6515,7 +6513,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) } #else #if defined(WL_MONITOR) && defined(BCMSDIO) - if (dhd_monitor_enabled(dhdp, ifidx)) + if (dhd_monitor_enabled(dhdp, ifidx)) dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx); else #endif /* WL_MONITOR && BCMSDIO */ @@ -7065,7 +7063,7 @@ dhd_rxf_thread(void *data) bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE, __FUNCTION__, __LINE__); #if defined(WL_MONITOR) && defined(BCMSDIO) - if (dhd_monitor_enabled(pub, 0)) + if (dhd_monitor_enabled(pub, 0)) dhd_rx_mon_pkt_sdio(pub, skb, 0); else #endif /* WL_MONITOR && BCMSDIO */ @@ -9445,7 +9443,7 @@ dhd_open(struct net_device *net) #endif /* dhd_sync_with_dongle has been called in dhd_bus_start or wl_android_wifi_on */ - memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); + dev_addr_set(net, dhd->pub.mac.octet); #ifdef TOE /* Get current TOE mode from dongle */ @@ -9570,15 +9568,16 @@ dhd_open(struct net_device *net) exit: mutex_unlock(&dhd->pub.ndev_op_sync); -#if defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(NO_POWER_OFF_AFTER_OPEN) - dhd_download_fw_on_driverload = TRUE; - dhd_driver_init_done = TRUE; -#elif defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(ENABLE_INSMOD_NO_POWER_OFF) - dhd_download_fw_on_driverload = FALSE; - dhd_driver_init_done = TRUE; -#endif if (ret) { dhd_stop(net); + } else { +#if defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(NO_POWER_OFF_AFTER_OPEN) + dhd_download_fw_on_driverload = TRUE; + dhd_driver_init_done = TRUE; +#elif defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(ENABLE_INSMOD_NO_POWER_OFF) + dhd_download_fw_on_driverload = FALSE; + dhd_driver_init_done = TRUE; +#endif } DHD_OS_WAKE_UNLOCK(&dhd->pub); @@ -10441,15 +10440,22 @@ dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock) unregister_netdev(ifp->net); else unregister_netdevice(ifp->net); +#if defined(WLDWDS) && defined(WL_EXT_IAPSTA) + if (ifp->dwds) { + wl_ext_iapsta_dettach_dwds_netdev(ifp->net, ifidx, ifp->bssidx); + } else +#endif /* WLDWDS && WL_EXT_IAPSTA */ + { #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_dettach_netdev(ifp->net, ifidx); + wl_ext_iapsta_dettach_netdev(ifp->net, ifidx); #endif /* WL_EXT_IAPSTA */ #ifdef WL_ESCAN - wl_escan_event_dettach(ifp->net, ifidx); + wl_escan_event_dettach(ifp->net, ifidx); #endif /* WL_ESCAN */ #ifdef WL_EVENT - wl_ext_event_dettach_netdev(ifp->net, ifidx); + wl_ext_event_dettach_netdev(ifp->net, ifidx); #endif /* WL_EVENT */ + } } ifp->net = NULL; DHD_GENERAL_LOCK(dhdpub, flags); @@ -10608,13 +10614,13 @@ static int dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) { struct file *filep = NULL; - struct kstat stat; #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + struct kstat stat; mm_segment_t fs; + int error = 0; #endif char *raw_fmts = NULL; int logstrs_size = 0; - int error = 0; if (control_logtrace != LOGTRACE_PARSED_FMT) { DHD_ERROR_NO_HW4(("%s : turned off logstr parsing\n", __FUNCTION__)); @@ -10632,12 +10638,16 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) DHD_ERROR_NO_HW4(("%s: Failed to open the file %s \n", __FUNCTION__, logstrs_path)); goto fail; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) error = vfs_stat(logstrs_path, &stat); if (error) { DHD_ERROR_NO_HW4(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path)); goto fail; } logstrs_size = (int) stat.size; +#else + logstrs_size = dhd_os_get_image_size(filep); +#endif if (logstrs_size == 0) { DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__)); @@ -10739,10 +10749,15 @@ static int dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, uint32 lr, char *lr_fn) { +#ifdef DHD_LINUX_STD_FW_API + const struct firmware *fw = NULL; + uint32 size = 0, mem_offset = 0; +#else struct file *filep = NULL; #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) mm_segment_t fs; #endif +#endif /* DHD_LINUX_STD_FW_API */ char *raw_fmts = NULL, *raw_fmts_loc = NULL, *cptr = NULL; uint32 read_size = READ_NUM_BYTES; int err = BCME_ERROR; @@ -10769,6 +10784,15 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, return BCME_ERROR; } +#ifdef DHD_LINUX_STD_FW_API + err = dhd_os_get_img_fwreq(&fw, fname); + if (err < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + err)); + goto fail; + } + size = fw->size; +#else #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) fs = get_fs(); set_fs(KERNEL_DS); @@ -10779,6 +10803,7 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, DHD_ERROR(("%s: Failed to open %s \n", __FUNCTION__, fname)); goto fail; } +#endif /* DHD_LINUX_STD_FW_API */ if (pc_fn == NULL) { count |= PC_FOUND_BIT; @@ -10788,6 +10813,20 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, } while (count != ALL_ADDR_VAL) { +#ifdef DHD_LINUX_STD_FW_API + /* Bound check for size before doing memcpy() */ + if ((mem_offset + read_size) > size) { + read_size = size - mem_offset; + } + + err = memcpy_s(raw_fmts, read_size, + ((char *)(fw->data) + mem_offset), read_size); + if (err) { + DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n", + __FUNCTION__, err)); + goto fail; + } +#else err = dhd_os_read_file(filep, raw_fmts, read_size); if (err < 0) { DHD_ERROR(("%s: map file read failed err:%d \n", @@ -10795,6 +10834,7 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, goto fail; } +#endif /* DHD_LINUX_STD_FW_API */ /* End raw_fmts with NULL as strstr expects NULL terminated * strings */ @@ -10885,7 +10925,14 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, } offset += (len + 1); } +#ifdef DHD_LINUX_STD_FW_API + if ((mem_offset + read_size) >= size) { + break; + } + memset(raw_fmts, 0, read_size); + mem_offset += (read_size -(len + 1)); +#else if (err < (int)read_size) { /* * since we reset file pos back to earlier pos by @@ -10903,10 +10950,16 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, * the string and addr even if it comes as splited in next read. */ dhd_os_seek_file(filep, -(len + 1)); +#endif /* DHD_LINUX_STD_FW_API */ DHD_TRACE(("%s: seek %d \n", __FUNCTION__, -(len + 1))); } fail: +#ifdef DHD_LINUX_STD_FW_API + if (fw) { + dhd_os_close_img_fwreq(fw); + } +#else if (!IS_ERR(filep)) filp_close(filep, NULL); @@ -10914,6 +10967,7 @@ fail: set_fs(fs); #endif +#endif /* DHD_LINUX_STD_FW_API */ if (!(count & PC_FOUND_BIT)) { sprintf(pc_fn, "0x%08x", pc); } @@ -10924,6 +10978,330 @@ fail: } #endif /* DHD_COREDUMP */ +#ifdef DHD_LINUX_STD_FW_API +static int +dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) +{ + char *raw_fmts = NULL; + int logstrs_size = 0; + int error = 0; + const struct firmware *fw = NULL; + + if (control_logtrace != LOGTRACE_PARSED_FMT) { + DHD_ERROR_NO_HW4(("%s : turned off logstr parsing\n", __FUNCTION__)); + return BCME_ERROR; + } + + error = dhd_os_get_img_fwreq(&fw, logstrs_path); + if (error < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + error)); + goto fail; + } + + logstrs_size = (int)fw->size; + if (logstrs_size == 0) { + DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__)); + goto fail; + } + + if (temp->raw_fmts != NULL) { + raw_fmts = temp->raw_fmts; /* reuse already malloced raw_fmts */ + } else { + raw_fmts = MALLOC(osh, logstrs_size); + if (raw_fmts == NULL) { + DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__)); + goto fail; + } + } + error = memcpy_s(raw_fmts, logstrs_size, (char *)(fw->data), logstrs_size); + if (error) { + DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n", + __FUNCTION__, error)); + goto fail; + } + if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp) == BCME_OK) { + dhd_os_close_img_fwreq(fw); + DHD_ERROR(("%s: return ok\n", __FUNCTION__)); + return BCME_OK; + } + +fail: + if (fw) { + dhd_os_close_img_fwreq(fw); + } + if (raw_fmts) { + MFREE(osh, raw_fmts, logstrs_size); + } + if (temp->fmts != NULL) { + MFREE(osh, temp->fmts, temp->num_fmts * sizeof(char *)); + } + + temp->fmts = NULL; + temp->raw_fmts = NULL; + + return BCME_ERROR; +} + +static int +dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start, + uint32 *rodata_end) +{ + int err = BCME_ERROR; + const struct firmware *fw = NULL; + + if (fname == NULL) { + DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__)); + return BCME_ERROR; + } + + err = dhd_os_get_img_fwreq(&fw, fname); + if (err < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + err)); + goto fail; + } + + if ((err = dhd_parse_map_file(osh, (struct firmware *)fw, ramstart, + rodata_start, rodata_end)) < 0) { + goto fail; + } + +fail: + if (fw) { + dhd_os_close_img_fwreq(fw); + } + + return err; +} + +static int +dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file) +{ + char *raw_fmts = NULL; + uint32 logstrs_size = 0; + int error = 0; + uint32 ramstart = 0; + uint32 rodata_start = 0; + uint32 rodata_end = 0; + uint32 logfilebase = 0; + const struct firmware *fw = NULL; + + error = dhd_read_map(osh, map_file, &ramstart, &rodata_start, &rodata_end); + if (error != BCME_OK) { + DHD_ERROR(("readmap Error!! \n")); + /* don't do event log parsing in actual case */ + if (strstr(str_file, ram_file_str) != NULL) { + temp->raw_sstr = NULL; + } else if (strstr(str_file, rom_file_str) != NULL) { + temp->rom_raw_sstr = NULL; + } + return error; + } + DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n", + ramstart, rodata_start, rodata_end)); + + /* Full file size is huge. Just read required part */ + logstrs_size = rodata_end - rodata_start; + logfilebase = rodata_start - ramstart; + + if (logstrs_size == 0) { + DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__)); + goto fail1; + } + + if (strstr(str_file, ram_file_str) != NULL && temp->raw_sstr != NULL) { + raw_fmts = temp->raw_sstr; /* reuse already malloced raw_fmts */ + } else if (strstr(str_file, rom_file_str) != NULL && temp->rom_raw_sstr != NULL) { + raw_fmts = temp->rom_raw_sstr; /* reuse already malloced raw_fmts */ + } else { + raw_fmts = MALLOC(osh, logstrs_size); + + if (raw_fmts == NULL) { + DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__)); + goto fail; + } + } + + error = dhd_os_get_img_fwreq(&fw, str_file); + if (error < 0 || (fw == NULL) || (fw->size < logfilebase)) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + error)); + goto fail; + } + + error = memcpy_s(raw_fmts, logstrs_size, (char *)((fw->data) + logfilebase), + logstrs_size); + if (error) { + DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n", + __FUNCTION__, error)); + goto fail; + } + + if (strstr(str_file, ram_file_str) != NULL) { + temp->raw_sstr = raw_fmts; + temp->raw_sstr_size = logstrs_size; + temp->rodata_start = rodata_start; + temp->rodata_end = rodata_end; + } else if (strstr(str_file, rom_file_str) != NULL) { + temp->rom_raw_sstr = raw_fmts; + temp->rom_raw_sstr_size = logstrs_size; + temp->rom_rodata_start = rodata_start; + temp->rom_rodata_end = rodata_end; + } + + if (fw) { + dhd_os_close_img_fwreq(fw); + } + + return BCME_OK; + +fail: + if (raw_fmts) { + MFREE(osh, raw_fmts, logstrs_size); + } + +fail1: + if (fw) { + dhd_os_close_img_fwreq(fw); + } + + if (strstr(str_file, ram_file_str) != NULL) { + temp->raw_sstr = NULL; + } else if (strstr(str_file, rom_file_str) != NULL) { + temp->rom_raw_sstr = NULL; + } + + return error; +} /* dhd_init_static_strs_array */ +#else +static int +dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) +{ + struct file *filep = NULL; + struct kstat stat; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + mm_segment_t fs; +#endif + char *raw_fmts = NULL; + int logstrs_size = 0; + int error = 0; + + if (control_logtrace != LOGTRACE_PARSED_FMT) { + DHD_ERROR_NO_HW4(("%s : turned off logstr parsing\n", __FUNCTION__)); + return BCME_ERROR; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + fs = get_fs(); + set_fs(KERNEL_DS); +#endif + + filep = dhd_filp_open(logstrs_path, O_RDONLY, 0); + + if (IS_ERR(filep) || (filep == NULL)) { + DHD_ERROR_NO_HW4(("%s: Failed to open the file %s \n", + __FUNCTION__, logstrs_path)); + goto fail; + } + error = dhd_vfs_stat(logstrs_path, &stat); + if (error) { + DHD_ERROR_NO_HW4(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path)); + goto fail; + } + logstrs_size = (int) stat.size; + + if (logstrs_size == 0) { + DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__)); + goto fail1; + } + + if (temp->raw_fmts != NULL) { + raw_fmts = temp->raw_fmts; /* reuse already malloced raw_fmts */ + } else { + raw_fmts = MALLOC(osh, logstrs_size); + if (raw_fmts == NULL) { + DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__)); + goto fail; + } + } + + if (dhd_vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) != logstrs_size) { + DHD_ERROR_NO_HW4(("%s: Failed to read file %s\n", __FUNCTION__, logstrs_path)); + goto fail; + } + + if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp) + == BCME_OK) { + dhd_filp_close(filep, NULL); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(fs); +#endif + return BCME_OK; + } + + fail: + if (raw_fmts) { + MFREE(osh, raw_fmts, logstrs_size); + } + if (temp->fmts != NULL) { + MFREE(osh, temp->fmts, temp->num_fmts * sizeof(char *)); + } + + fail1: + if (!IS_ERR(filep)) + dhd_filp_close(filep, NULL); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(fs); +#endif + temp->fmts = NULL; + temp->raw_fmts = NULL; + + return BCME_ERROR; +} + +static int +dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start, + uint32 *rodata_end) +{ + struct file *filep = NULL; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + mm_segment_t fs; +#endif + int err = BCME_ERROR; + + if (fname == NULL) { + DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__)); + return BCME_ERROR; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + fs = get_fs(); + set_fs(KERNEL_DS); +#endif + + filep = dhd_filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filep) || (filep == NULL)) { + DHD_ERROR_NO_HW4(("%s: Failed to open %s \n", __FUNCTION__, fname)); + goto fail; + } + + if ((err = dhd_parse_map_file(osh, filep, ramstart, + rodata_start, rodata_end)) < 0) + goto fail; + +fail: + if (!IS_ERR(filep)) + dhd_filp_close(filep, NULL); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + set_fs(fs); +#endif + + return err; +} + static int dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file) { @@ -11042,7 +11420,7 @@ fail1: return error; } /* dhd_init_static_strs_array */ - +#endif /* DHD_LINUX_STD_FW_API */ #endif /* SHOW_LOGTRACE */ #ifdef BT_OVER_PCIE @@ -11840,7 +12218,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen dhd->dhd_state = dhd_state; dhd_found++; - + #ifdef CSI_SUPPORT dhd_csi_init(&dhd->pub); #endif /* CSI_SUPPORT */ @@ -11964,7 +12342,6 @@ int dhd_bus_get_fw_mode(dhd_pub_t *dhdp) } extern char * nvram_get(const char *name); - bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) { int fw_len; @@ -11983,7 +12360,6 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) int fw_path_len = sizeof(dhdinfo->fw_path); int nv_path_len = sizeof(dhdinfo->nv_path); - /* Update firmware and nvram path. The path may be from adapter info or module parameter * The path from adapter info is used for initialization only (as it won't change). * @@ -11996,12 +12372,17 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) /* set default firmware and nvram path for built-in type driver */ // if (!dhd_download_fw_on_driverload) { +#ifdef DHD_LINUX_STD_FW_API + fw = DHD_FW_NAME; + nv = DHD_NVRAM_NAME; +#else #ifdef CONFIG_BCMDHD_FW_PATH fw = VENDOR_PATH CONFIG_BCMDHD_FW_PATH; #endif /* CONFIG_BCMDHD_FW_PATH */ #ifdef CONFIG_BCMDHD_NVRAM_PATH nv = VENDOR_PATH CONFIG_BCMDHD_NVRAM_PATH; #endif /* CONFIG_BCMDHD_NVRAM_PATH */ +#endif /* DHD_LINUX_STD_FW_API */ // } /* check if we need to initialize the path */ @@ -12519,8 +12900,10 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd_bus_l1ss_enable_rc_ep(dhdp->bus, TRUE); #endif /* BT_OVER_PCIE */ +#if defined(CUSTOMER_HW_ROCKCHIP) && defined(BCMPCIE) if (IS_ENABLED(CONFIG_PCIEASPM_ROCKCHIP_WIFI_EXTENSION)) rk_dhd_bus_l1ss_enable_rc_ep(dhdp->bus, TRUE); +#endif /* CUSTOMER_HW_ROCKCHIP && BCMPCIE */ #if defined(CONFIG_ARCH_EXYNOS) && defined(BCMPCIE) #if !defined(CONFIG_SOC_EXYNOS8890) && !defined(SUPPORT_EXYNOS7420) @@ -15482,9 +15865,7 @@ dhd_legacy_preinit_ioctls(dhd_pub_t *dhd) setbit(mask, WLC_E_ADDTS_IND); setbit(mask, WLC_E_DELTS_IND); #endif /* WL_BCNRECV */ -#ifdef CUSTOMER_HW6 setbit(mask, WLC_E_COUNTRY_CODE_CHANGED); -#endif /* CUSTOMER_HW6 */ /* Write updated Event mask */ eventmask_msg->ver = EVENTMSGS_VER; @@ -16674,7 +17055,7 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock) * XXX Linux 2.6.25 does not like a blank MAC address, so use a * dummy address until the interface is brought up. */ - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); + dev_addr_set(net, temp_addr); if (ifidx == 0) printf("%s\n", dhd_version); @@ -16714,16 +17095,23 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock) } #endif /* BCM_ROUTER_DHD && HNDCTF */ +#if defined(WLDWDS) && defined(WL_EXT_IAPSTA) + if (ifp->dwds) { + wl_ext_iapsta_attach_dwds_netdev(net, ifidx, ifp->bssidx); + } else +#endif /* WLDWDS && WL_EXT_IAPSTA */ + { #ifdef WL_EVENT - wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx); + wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx); #endif /* WL_EVENT */ #ifdef WL_ESCAN - wl_escan_event_attach(net, ifidx); + wl_escan_event_attach(net, ifidx); #endif /* WL_ESCAN */ #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx); - wl_ext_iapsta_attach_name(net, ifidx); + wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx); + wl_ext_iapsta_attach_name(net, ifidx); #endif /* WL_EXT_IAPSTA */ + } #if defined(CONFIG_TIZEN) net_stat_tizen_register(net); @@ -17519,7 +17907,10 @@ _dhd_module_init(void) int err; int retry = POWERUP_MAX_RETRY; - printf("%s: in %s\n", __FUNCTION__, dhd_version); + printk(KERN_ERR PERCENT_S DHD_LOG_PREFIXS "%s: in %s\n", + PRINTF_SYSTEM_TIME, __FUNCTION__, dhd_version); + if (ANDROID_VERSION > 0) + printf("ANDROID_VERSION = %d\n", ANDROID_VERSION); #ifdef DHD_BUZZZ_LOG_ENABLED dhd_buzzz_attach(); @@ -18122,6 +18513,30 @@ exit: #endif /* DHD_PCIE_RUNTIMEPM */ +#ifdef DHD_LINUX_STD_FW_API +int +dhd_os_get_img_fwreq(const struct firmware **fw, char *file_path) +{ + int ret = BCME_ERROR; + + ret = request_firmware(fw, file_path, dhd_bus_to_dev(g_dhd_pub->bus)); + if (ret < 0) { + DHD_ERROR(("%s: request_firmware %s err: %d\n", __FUNCTION__, file_path, ret)); + /* convert to BCME_NOTFOUND error for error handling */ + ret = BCME_NOTFOUND; + } else + DHD_ERROR(("%s: %s (%zu bytes) open success\n", __FUNCTION__, file_path, (*fw)->size)); + + return ret; +} + +void +dhd_os_close_img_fwreq(const struct firmware *fw) +{ + release_firmware(fw); +} +#endif /* DHD_LINUX_STD_FW_API */ + void * dhd_os_open_image1(dhd_pub_t *pub, char *filename) { @@ -21666,7 +22081,7 @@ void dhd_set_version_info(dhd_pub_t *dhdp, char *fw) return; i = snprintf(&info_string[i], sizeof(info_string) - i, - "\n Chip: %x Rev %x", dhd_conf_get_chip(dhdp), + "\n%s Chip: %x Rev %x", DHD_LOG_PREFIXS, dhd_conf_get_chip(dhdp), dhd_conf_get_chiprev(dhdp)); } @@ -24146,6 +24561,7 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) struct file *fp = NULL; #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) mm_segment_t old_fs; + struct kstat stat; #endif loff_t pos = 0; char dump_path[128]; @@ -24153,10 +24569,10 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) unsigned long flags = 0; size_t log_size = 0; size_t fspace_remain = 0; - struct kstat stat; char time_str[128]; unsigned int len = 0; log_dump_section_hdr_t sec_hdr; + uint32 file_size = 0; DHD_ERROR(("%s: ENTER \n", __FUNCTION__)); @@ -24222,15 +24638,24 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) #endif /* CONFIG_X86 && OEM_ANDROID */ } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) ret = vfs_stat(dump_path, &stat); if (ret < 0) { DHD_ERROR(("file stat error, err = %d\n", ret)); goto exit2; } + file_size = stat.size; +#else + file_size = dhd_os_get_image_size(fp); + if (file_size <= 0) { + DHD_ERROR(("%s: get file size fails ! %d\n", __FUNCTION__, file_size)); + goto exit2; + } +#endif /* if some one else has changed the file */ if (dhdp->last_file_posn != 0 && - stat.size < dhdp->last_file_posn) { + file_size < dhdp->last_file_posn) { dhdp->last_file_posn = 0; } @@ -25788,6 +26213,39 @@ dhd_send_trap_to_fw_for_timeout(dhd_pub_t * pub, timeout_reasons_t reason) } #endif /* REPORT_FATAL_TIMEOUTS */ +char* +dhd_dbg_get_system_timestamp(void) +{ + static char timebuf[DEBUG_DUMP_TIME_BUF_LEN]; + struct osl_timespec tv; + unsigned long local_time; + struct rtc_time tm; + + memset_s(timebuf, DEBUG_DUMP_TIME_BUF_LEN, 0, DEBUG_DUMP_TIME_BUF_LEN); + osl_do_gettimeofday(&tv); + local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + scnprintf(timebuf, DEBUG_DUMP_TIME_BUF_LEN, + "%02d:%02d:%02d.%06lu", + tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec); + return timebuf; +} + +char* +dhd_log_dump_get_timestamp(void) +{ + static char buf[32]; + u64 ts_nsec; + unsigned long rem_nsec; + + ts_nsec = local_clock(); + rem_nsec = DIV_AND_MOD_U64_BY_U32(ts_nsec, NSEC_PER_SEC); + snprintf(buf, sizeof(buf), "%5lu.%06lu", + (unsigned long)ts_nsec, rem_nsec / NSEC_PER_USEC); + + return buf; +} + #ifdef DHD_LOG_DUMP bool dhd_log_dump_ecntr_enabled(void) @@ -26161,24 +26619,6 @@ dhd_log_dump_write(int type, char *binary_data, } #ifdef DHD_DEBUGABILITY_LOG_DUMP_RING -char* -dhd_dbg_get_system_timestamp(void) -{ - static char timebuf[DEBUG_DUMP_TIME_BUF_LEN]; - struct timeval tv; - unsigned long local_time; - struct rtc_time tm; - - memset_s(timebuf, DEBUG_DUMP_TIME_BUF_LEN, 0, DEBUG_DUMP_TIME_BUF_LEN); - do_gettimeofday(&tv); - local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); - rtc_time_to_tm(local_time, &tm); - scnprintf(timebuf, DEBUG_DUMP_TIME_BUF_LEN, - "%02d:%02d:%02d.%06lu", - tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec); - return timebuf; -} - extern struct dhd_dbg_ring_buf g_ring_buf; void dhd_dbg_ring_write(int type, char *binary_data, @@ -26220,21 +26660,6 @@ dhd_dbg_ring_write(int type, char *binary_data, return; } #endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */ - -char* -dhd_log_dump_get_timestamp(void) -{ - static char buf[32]; - u64 ts_nsec; - unsigned long rem_nsec; - - ts_nsec = local_clock(); - rem_nsec = DIV_AND_MOD_U64_BY_U32(ts_nsec, NSEC_PER_SEC); - snprintf(buf, sizeof(buf), "%5lu.%06lu", - (unsigned long)ts_nsec, rem_nsec / NSEC_PER_USEC); - - return buf; -} #endif /* DHD_LOG_DUMP */ #ifdef DHD_PCIE_NATIVE_RUNTIMEPM @@ -27354,7 +27779,11 @@ dhd_print_kirqstats(dhd_pub_t *dhd, unsigned int irq_num) char tmp_buf[KIRQ_PRINT_BUF_LEN]; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) + desc = irq_data_to_desc(irq_get_irq_data(irq_num)); +#else desc = irq_to_desc(irq_num); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) if (!desc) { DHD_ERROR(("%s : irqdesc is not found \n", __FUNCTION__)); return; @@ -29816,65 +30245,69 @@ bool dhd_os_wd_timer_enabled(void *bus) #if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG) /* This function is to automatically add/del interface to the bridged dev that priamy dev is in */ -static void dhd_bridge_dev_set(dhd_info_t *dhd, int ifidx, struct net_device *dev) +static void +dhd_bridge_dev_set(dhd_info_t *dhd, int ifidx, struct net_device *sdev) { - struct net_device *primary_ndev = NULL, *br_dev = NULL; - int cmd; - struct ifreq ifr; + struct net_device *pdev = NULL, *br_dev = NULL; + int i, err = 0; - /* add new interface to bridge dev */ - if (dev) { - int found = 0, i; - DHD_ERROR(("bssidx %d\n", dhd->pub.info->iflist[ifidx]->bssidx)); - for (i = 0 ; i < ifidx; i++) { - DHD_ERROR(("bssidx %d %d\n", i, dhd->pub.info->iflist[i]->bssidx)); - /* search the primary interface */ - if (dhd->pub.info->iflist[i]->bssidx == dhd->pub.info->iflist[ifidx]->bssidx) { - primary_ndev = dhd->pub.info->iflist[i]->net; - DHD_ERROR(("%dst is primary dev %s\n", i, primary_ndev->name)); - found = 1; + if (sdev) { + /* search the primary interface wlan1(wl0.1) with same bssidx */ + for (i = 0; i < ifidx; i++) { + if (dhd->iflist[i]->bssidx == dhd->iflist[ifidx]->bssidx) { + pdev = dhd->pub.info->iflist[i]->net; + WL_MSG(sdev->name, "found primary dev %s\n", pdev->name); break; } } - if (found == 0) { - DHD_ERROR(("Can not find primary dev %s\n", dev->name)); + if (!pdev) { + WL_MSG(sdev->name, "can not find primary dev\n"); return; } - cmd = SIOCBRADDIF; - ifr.ifr_ifindex = dev->ifindex; - } else { /* del interface from bridge dev */ - primary_ndev = dhd->pub.info->iflist[ifidx]->net; - cmd = SIOCBRDELIF; - ifr.ifr_ifindex = primary_ndev->ifindex; + } else { + pdev = dhd->iflist[ifidx]->net; } + /* if primary net device is bridged */ - if (primary_ndev->priv_flags & IFF_BRIDGE_PORT) { + if (pdev->priv_flags & IFF_BRIDGE_PORT) { rtnl_lock(); /* get bridge device */ - br_dev = netdev_master_upper_dev_get(primary_ndev); + br_dev = netdev_master_upper_dev_get(pdev); if (br_dev) { const struct net_device_ops *ops = br_dev->netdev_ops; - DHD_ERROR(("br %s pri %s\n", br_dev->name, primary_ndev->name)); if (ops) { - if (cmd == SIOCBRADDIF) { - DHD_ERROR(("br call ndo_add_slave\n")); - ops->ndo_add_slave(br_dev, dev); + if (sdev) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + err = ops->ndo_add_slave(br_dev, sdev, NULL); +#else + err = ops->ndo_add_slave(br_dev, sdev); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) */ + if (err) + WL_MSG(sdev->name, "add to %s failed %d\n", br_dev->name, err); + else + WL_MSG(sdev->name, "slave added to %s\n", br_dev->name); /* Also bring wds0.x interface up automatically */ - dev_change_flags(dev, dev->flags | IFF_UP); - } - else { - DHD_ERROR(("br call ndo_del_slave\n")); - ops->ndo_del_slave(br_dev, primary_ndev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) + dev_change_flags(sdev, sdev->flags | IFF_UP, NULL); +#else + dev_change_flags(sdev, sdev->flags | IFF_UP); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) */ + } else { + err = ops->ndo_del_slave(br_dev, pdev); + if (err) + WL_MSG(pdev->name, "del from %s failed %d\n", br_dev->name, err); + else + WL_MSG(pdev->name, "slave deleted from %s\n", br_dev->name); } } } else { - DHD_ERROR(("no br dev\n")); + WL_MSG(pdev->name, "not bridged\n"); } rtnl_unlock(); } else { - DHD_ERROR(("device %s is not bridged\n", primary_ndev->name)); + WL_MSG(pdev->name, "not bridged\n"); } } -#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */ +#endif /* WLDWDS && FOURADDR_AUTO_BRG */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h index 531505d6bd04..2f2c409dfd67 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h @@ -407,6 +407,9 @@ typedef struct dhd_if { bool recv_reassoc_evt; bool post_roam_evt; #endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */ +#ifdef WLDWDS + bool dwds; /* DWDS interface */ +#endif /* WLDWDS */ #ifdef WLEASYMESH uint8 _1905_al_ucast[ETHER_ADDR_LEN]; uint8 _1905_al_mcast[ETHER_ADDR_LEN]; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c index ef5b0cc794bd..702553175924 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c @@ -177,6 +177,7 @@ dhd_dbg_ring_proc_destroy(dhd_pub_t *dhdp) * ----------------------------------------------------------------------------- */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #if defined(DHD_TRACE_WAKE_LOCK) extern atomic_t trace_wklock_onoff; @@ -1030,6 +1031,7 @@ done: return ret; } #endif /* PWRSTATS_SYSFS */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ /* * Generic Attribute Structure for DHD. @@ -1046,6 +1048,7 @@ struct dhd_attr { ssize_t(*store)(struct dhd_info *, const char *, size_t count); }; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #if defined(DHD_TRACE_WAKE_LOCK) static struct dhd_attr dhd_attr_wklock = __ATTR(wklock_trace, 0660, show_wklock_trace, wklock_trace_onoff); @@ -1119,10 +1122,12 @@ static struct dhd_attr dhd_attr_nvram_path = static struct dhd_attr dhd_attr_pwrstats_path = __ATTR(power_stats, 0660, show_pwrstats_path, NULL); #endif /* PWRSTATS_SYSFS */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ #define to_dhd(k) container_of(k, struct dhd_info, dhd_kobj) #define to_attr(a) container_of(a, struct dhd_attr, attr) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #ifdef DHD_MAC_ADDR_EXPORT struct ether_addr sysfs_mac_addr; static ssize_t @@ -1154,6 +1159,7 @@ set_mac_addr(struct dhd_info *dev, const char *buf, size_t count) static struct dhd_attr dhd_attr_macaddr = __ATTR(mac_addr, 0660, show_mac_addr, set_mac_addr); #endif /* DHD_MAC_ADDR_EXPORT */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ #ifdef DHD_FW_COREDUMP /* @@ -1262,6 +1268,7 @@ void dhd_get_memdump_info(dhd_pub_t *dhd) DHD_ERROR(("%s: MEMDUMP ENABLED = %u\n", __FUNCTION__, dhd->memdump_enabled)); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #ifdef DHD_EXPORT_CNTL_FILE static ssize_t show_memdump_info(struct dhd_info *dev, char *buf) @@ -1303,6 +1310,7 @@ set_memdump_info(struct dhd_info *dev, const char *buf, size_t count) static struct dhd_attr dhd_attr_memdump = __ATTR(memdump, 0660, show_memdump_info, set_memdump_info); #endif /* DHD_EXPORT_CNTL_FILE */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ #endif /* DHD_FW_COREDUMP */ #ifdef BCMASSERT_LOG @@ -1362,6 +1370,7 @@ void dhd_get_assert_info(dhd_pub_t *dhd) #endif /* !DHD_EXPORT_CNTL_FILE */ } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #ifdef DHD_EXPORT_CNTL_FILE static ssize_t show_assert_info(struct dhd_info *dev, char *buf) @@ -1396,8 +1405,10 @@ set_assert_info(struct dhd_info *dev, const char *buf, size_t count) static struct dhd_attr dhd_attr_assert = __ATTR(assert, 0660, show_assert_info, set_assert_info); #endif /* DHD_EXPORT_CNTL_FILE */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ #endif /* BCMASSERT_LOG */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #ifdef DHD_EXPORT_CNTL_FILE #if defined(WRITE_WLANINFO) static ssize_t @@ -1889,10 +1900,12 @@ store_adps_bam_list(struct dhd_info *dev, const char *buf, size_t count) static struct dhd_attr dhd_attr_adps_bam = __ATTR(bad_ap_list, 0660, show_adps_bam_list, store_adps_bam_list); #endif /* DHD_ADPS_BAM_EXPORT && WL_BAM */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ -#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS uint32 report_hang_privcmd_err = 1; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) +#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS static ssize_t show_hang_privcmd_err(struct dhd_info *dev, char *buf) { @@ -2350,6 +2363,7 @@ static struct attribute *default_file_attrs[] = { #endif /* AGG_H2D_DB */ NULL }; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ /* * wifi kobject show function, the "attr" attribute specifices to which @@ -2406,7 +2420,9 @@ static struct sysfs_ops dhd_sysfs_ops = { static struct kobj_type dhd_ktype = { .sysfs_ops = &dhd_sysfs_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) .default_attrs = default_file_attrs, +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ }; #ifdef CSI_SUPPORT @@ -2436,6 +2452,7 @@ static struct bin_attribute dhd_attr_csi = { * sysfs for dhd_lb */ #ifdef DHD_LB +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) #if defined(DHD_LB_TXP) static ssize_t show_lbtxp(struct dhd_info *dev, char *buf) @@ -2830,6 +2847,7 @@ static struct attribute *debug_lb_attrs[] = { &dhd_tx_cpu.attr, NULL }; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ #define to_dhd_lb(k) container_of(k, struct dhd_info, dhd_lb_kobj) @@ -2888,7 +2906,9 @@ static struct sysfs_ops dhd_sysfs_lb_ops = { static struct kobj_type dhd_lb_ktype = { .sysfs_ops = &dhd_sysfs_lb_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)) .default_attrs = debug_lb_attrs, +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) */ }; #endif /* DHD_LB */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c index ad5fe13c9706..028bc762a526 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c @@ -41,8 +41,8 @@ #include #include -#define DHD_PKTDUMP(arg) printk arg -#define DHD_PKTDUMP_MEM(arg) printk arg +#define DHD_PKTDUMP(arg) printf arg +#define DHD_PKTDUMP_MEM(arg) printf arg #define PACKED_STRUCT __attribute__ ((packed)) #define EAPOL_HDR_LEN 4 @@ -200,12 +200,12 @@ static const char tx_pktfate[][30] = { do { \ if (dump_msg_level & DUMP_EAPOL_VAL) { \ if (tx) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [TX] : (%s) %s (%s)"TXFATE_FMT"\n", \ + DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s)"TXFATE_FMT"\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [RX] : (%s) %s (%s)\n", \ + DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s)\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf)); \ } \ @@ -216,12 +216,12 @@ static const char tx_pktfate[][30] = { do { \ if (dump_msg_level & DUMP_EAPOL_VAL) { \ if (tx) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [TX] : (%s) %s (%s)"DBGREPLAY TXFATE_FMT"\n", \ + DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s)"DBGREPLAY TXFATE_FMT"\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ REPLAY_FMT(eap_key), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [RX] : (%s) %s (%s)"DBGREPLAY"\n", \ + DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s)"DBGREPLAY"\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ REPLAY_FMT(eap_key))); \ @@ -233,14 +233,14 @@ static const char tx_pktfate[][30] = { do { \ if (dump_msg_level & DUMP_EAPOL_VAL) { \ if (tx) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [TX] : (%s) %s (%s) " \ + DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s) " \ "ver %d, type %d"TXFATE_FMT"\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ eapol_hdr->version, eapol_hdr->type, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [RX] : (%s) %s (%s) " \ + DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s) " \ "ver %d, type %d\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ @@ -253,7 +253,7 @@ static const char tx_pktfate[][30] = { do { \ if (dump_msg_level & DUMP_EAPOL_VAL) { \ if (tx) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [TX] : (%s) %s (%s) " \ + DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s) " \ "ver %d type %d keytype %d keyinfo 0x%02X"TXFATE_FMT"\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ @@ -261,7 +261,7 @@ static const char tx_pktfate[][30] = { (uint32)hton16(eap_key->key_info), \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] 802_1X " x " [RX] : (%s) %s (%s) " \ + DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s) " \ "ver %d type %d keytype %d keyinfo 0x%02X\n", \ ifname, ## args, \ tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \ @@ -1047,36 +1047,12 @@ dhd_check_dhcp(uint8 *pktdata) return TRUE; } -#ifdef DHD_DHCP_DUMP #define BOOTP_CHADDR_LEN 16 #define BOOTP_SNAME_LEN 64 #define BOOTP_FILE_LEN 128 #define BOOTP_MIN_DHCP_OPT_LEN 312 #define BOOTP_MAGIC_COOKIE_LEN 4 -#define DHCP_MSGTYPE_DISCOVER 1 -#define DHCP_MSGTYPE_OFFER 2 -#define DHCP_MSGTYPE_REQUEST 3 -#define DHCP_MSGTYPE_DECLINE 4 -#define DHCP_MSGTYPE_ACK 5 -#define DHCP_MSGTYPE_NAK 6 -#define DHCP_MSGTYPE_RELEASE 7 -#define DHCP_MSGTYPE_INFORM 8 - -#define DHCP_PRINT(str) \ - do { \ - if (tx) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] " str " %8s[%8s] [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ - ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \ - tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ - TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ - } else { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] " str " %8s[%8s] [RX] : %s(%s) %s %s(%s)\n", \ - ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \ - tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf)); \ - } \ - } while (0) - typedef struct bootp_fmt { struct ipv4_hdr iph; struct bcmudp_hdr udph; @@ -1096,8 +1072,32 @@ typedef struct bootp_fmt { uint8 file_name[BOOTP_FILE_LEN]; uint8 options[BOOTP_MIN_DHCP_OPT_LEN]; } PACKED_STRUCT bootp_fmt_t; - static const uint8 bootp_magic_cookie[4] = { 99, 130, 83, 99 }; + +#ifdef DHD_DHCP_DUMP +#define DHCP_MSGTYPE_DISCOVER 1 +#define DHCP_MSGTYPE_OFFER 2 +#define DHCP_MSGTYPE_REQUEST 3 +#define DHCP_MSGTYPE_DECLINE 4 +#define DHCP_MSGTYPE_ACK 5 +#define DHCP_MSGTYPE_NAK 6 +#define DHCP_MSGTYPE_RELEASE 7 +#define DHCP_MSGTYPE_INFORM 8 + +#define DHCP_PRINT(str) \ + do { \ + if (tx) { \ + DHD_PKTDUMP(("[%s] " str " %8s[%8s] [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ + ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \ + tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ + TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ + } else { \ + DHD_PKTDUMP(("[%s] " str " %8s[%8s] [RX] : %s(%s) %s %s(%s)\n", \ + ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \ + tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf)); \ + } \ + } while (0) + static char dhcp_ops[][10] = { "NA", "REQUEST", "REPLY" }; @@ -1193,12 +1193,12 @@ dhd_check_icmp(uint8 *pktdata) #define ICMP_PING_PRINT(str) \ do { \ if (tx) { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s) SEQNUM=%d" \ + DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) SEQNUM=%d" \ TXFATE_FMT"\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, seqnum, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [RX] : %s(%s) %s %s(%s) SEQNUM=%d\n", \ + DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) SEQNUM=%d\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, seqnum)); \ } \ @@ -1207,12 +1207,12 @@ dhd_check_icmp(uint8 *pktdata) #define ICMP_PRINT(str) \ do { \ if (tx) { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s) TYPE=%d, CODE=%d" \ + DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) TYPE=%d, CODE=%d" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, type, code, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [RX] : %s(%s) %s %s(%s) TYPE=%d," \ + DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) TYPE=%d," \ " CODE=%d\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, type, code)); \ } \ @@ -1293,18 +1293,18 @@ dhd_check_arp(uint8 *pktdata, uint16 ether_type) do { \ if (tx) { \ if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ + DHD_PKTDUMP(("[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ + DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [RX] : %s(%s) %s %s(%s)\n", \ + DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s)\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf)); \ } \ @@ -1314,18 +1314,18 @@ dhd_check_arp(uint8 *pktdata, uint16 ether_type) do { \ if (tx) { \ if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \ + DHD_PKTDUMP(("[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \ + DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode, \ TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] "str " [RX] : %s(%s) %s %s(%s) op_code=%d\n", \ + DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) op_code=%d\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode)); \ } \ @@ -1429,18 +1429,18 @@ static const char dns_opcode_types[][11] = { do { \ if (tx) { \ if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \ + DHD_PKTDUMP(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ id, DNSOPCODE(opcode), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \ + DHD_PKTDUMP_MEM(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ id, DNSOPCODE(opcode), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s\n", \ + DHD_PKTDUMP_MEM(("[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, tx?"->":"<-", \ tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode))); \ } \ @@ -1450,18 +1450,18 @@ static const char dns_opcode_types[][11] = { do { \ if (tx) { \ if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \ - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \ + DHD_PKTDUMP(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode), \ GET_DNS_RCODE(flags), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \ + DHD_PKTDUMP_MEM(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \ TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode), \ GET_DNS_RCODE(flags), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \ } \ } else { \ - DHD_PKTDUMP_MEM((DHD_LOG_PREFIX "[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d\n", \ + DHD_PKTDUMP_MEM(("[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d\n", \ ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \ tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \ id, DNSOPCODE(opcode), GET_DNS_RCODE(flags))); \ @@ -1557,13 +1557,13 @@ dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen, bool if (protocol != ETHER_TYPE_BRCM) { if (pktdata[0] == 0xFF) { - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] %s BROADCAST DUMP - %s\n", + DHD_PKTDUMP(("[%s] %s BROADCAST DUMP - %s\n", dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype)); } else if (pktdata[0] & 1) { - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] %s MULTICAST DUMP " MACDBG " - %s\n", + DHD_PKTDUMP(("[%s] %s MULTICAST DUMP " MACDBG " - %s\n", dhd_ifname(dhdp, ifidx), tx?"TX":"RX", MAC2STRDBG(pktdata), pkttype)); } else { - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] %s DUMP - %s\n", + DHD_PKTDUMP(("[%s] %s DUMP - %s\n", dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype)); } #ifdef DHD_RX_FULL_DUMP @@ -1571,8 +1571,165 @@ dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen, bool #endif /* DHD_RX_FULL_DUMP */ } else { - DHD_PKTDUMP((DHD_LOG_PREFIX "[%s] %s DUMP - %s\n", + DHD_PKTDUMP(("[%s] %s DUMP - %s\n", dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype)); } } #endif /* DHD_RX_DUMP */ + +#ifdef BCMPCIE +static bool +dhd_is_eapol_pkt(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen) +{ + eapol_header_t *eapol_hdr = (eapol_header_t *)pktdata; + + eapol_hdr = (eapol_header_t *)pktdata; + + if (eapol_hdr->type == EAP_PACKET) { + return TRUE; + } else if (eapol_hdr->type == EAPOL_START) { + return TRUE; + } else if (eapol_hdr->type == EAPOL_KEY) { + return TRUE; + } else { + return TRUE; + } + return FALSE; +} + +static bool +dhd_is_arp_pkt(dhd_pub_t *dhdp, uint8 *pktdata) +{ + uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN]; + struct bcmarp *arph = (struct bcmarp *)pkt; + uint16 opcode; + + /* validation check */ + if (arph->htype != hton16(HTYPE_ETHERNET) || + arph->hlen != ETHER_ADDR_LEN || + arph->plen != 4) { + return FALSE; + } + + opcode = ntoh16(arph->oper); + if (opcode == ARP_OPC_REQUEST) { + return TRUE; + } else if (opcode == ARP_OPC_REPLY) { + return TRUE; + } else { + return TRUE; + } + return FALSE; +} + +static bool +dhd_is_dhcp_pkt(dhd_pub_t *dhdp, uint8 *pktdata) +{ + bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN]; + struct ipv4_hdr *iph = &b->iph; + uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len); + int len, opt_len; + + /* check IP header */ + if ((IPV4_HLEN(iph) < IPV4_HLEN_MIN) || + IP_VER(iph) != IP_VER_4 || + IPV4_PROT(iph) != IP_PROT_UDP) { + return FALSE; + } + + /* check UDP port for bootp (67, 68) */ + if (b->udph.src_port != htons(DHCP_PORT_SERVER) && + b->udph.src_port != htons(DHCP_PORT_CLIENT) && + b->udph.dst_port != htons(DHCP_PORT_SERVER) && + b->udph.dst_port != htons(DHCP_PORT_CLIENT)) { + return FALSE; + } + + /* check header length */ + if (ntohs(iph->tot_len) < ntohs(b->udph.len) + sizeof(struct bcmudp_hdr)) { + return FALSE; + } + + len = ntohs(b->udph.len) - sizeof(struct bcmudp_hdr); + opt_len = len - (sizeof(*b) - sizeof(struct ipv4_hdr) - + sizeof(struct bcmudp_hdr) - sizeof(b->options)); + + /* parse bootp options */ + if (opt_len >= BOOTP_MAGIC_COOKIE_LEN && + !memcmp(b->options, bootp_magic_cookie, BOOTP_MAGIC_COOKIE_LEN)) { + ptr = &b->options[BOOTP_MAGIC_COOKIE_LEN]; + while (ptr < end && *ptr != 0xff) { + opt = ptr++; + if (*opt == 0) { + continue; + } + ptr += *ptr + 1; + if (ptr >= end) { + break; + } + if (*opt == DHCP_OPT_MSGTYPE) { + if (opt[1]) { + return TRUE; + } + } + } + } + + return FALSE; +} + +static bool +dhd_is_icmp_pkt(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen) +{ + uint8 *pkt; + struct ipv4_hdr *iph; + + pkt = (uint8 *)&pktdata[ETHER_HDR_LEN]; + iph = (struct ipv4_hdr *)pkt; + + /* check IP header */ + if ((IPV4_HLEN(iph) < IPV4_HLEN_MIN) || + IP_VER(iph) != IP_VER_4 || + IPV4_PROT(iph) != IP_PROT_ICMP) { + return FALSE; + } + + /* check header length */ + if (ntohs(iph->tot_len) - IPV4_HLEN(iph) < sizeof(struct bcmicmp_hdr)) { + return FALSE; + } + + return TRUE; +} + +bool +dhd_match_pkt_type(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen) +{ + struct ether_header *eh; + uint16 ether_type; + bool match = FALSE; + + if (!pktdata || pktlen < ETHER_HDR_LEN) { + return match; + } + + eh = (struct ether_header *)pktdata; + ether_type = ntoh16(eh->ether_type); + if ((dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_EAPOL) && + ether_type == ETHER_TYPE_802_1X) { + match = dhd_is_eapol_pkt(dhd, pktdata, pktlen); + } + else if ((dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_ARP) && + ntoh16(eh->ether_type) == ETHER_TYPE_ARP) { + match = dhd_is_arp_pkt(dhd, pktdata); + } + else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { + if (dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_ICMP) + match = dhd_is_icmp_pkt(dhd, pktdata, pktlen); + if (!match && dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_DHCP) + match = dhd_is_dhcp_pkt(dhd, pktdata); + } + + return match; +} +#endif /* BCMPCIE */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h index 7d7ce72b4ff6..96a160ae33fa 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h @@ -59,6 +59,9 @@ enum pkt_type { extern msg_eapol_t dhd_is_4way_msg(uint8 *pktdata); extern void dhd_dump_pkt(dhd_pub_t *dhd, int ifidx, uint8 *pktdata, uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate); +#ifdef BCMPCIE +extern bool dhd_match_pkt_type(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen); +#endif /* BCMPCIE */ #ifdef DHD_PKTDUMP_ROAM extern void dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn); extern void dhd_dump_pkt_init(dhd_pub_t *dhdp); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c index 1718cb8dfc8e..21aaa1f7b1b8 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c @@ -570,12 +570,12 @@ static int wifi_ctrlfunc_register_drv(void) } adapter->name = "DHD generic adapter"; adapter->index = -1; -#ifdef BCMDHD_MDRIVER +#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER) #ifdef BCMSDIO adapter->index = 0; -#elif BCMPCIE +#elif defined(BCMPCIE) adapter->index = 1; -#elif BCMUSB +#elif defined(BCMDBUS) adapter->index = 2; #endif #endif diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_msgbuf.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_msgbuf.c index 9d09de23a799..2262533f53a5 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_msgbuf.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_msgbuf.c @@ -4156,10 +4156,11 @@ dhd_prot_init(dhd_pub_t *dhd) * only if dongle does not support EDL */ #ifdef EWP_EDL - if (dhd->bus->api.fw_rev >= PCIE_SHARED_VERSION_6 && !dhd->dongle_edl_support) { + if (dhd->bus->api.fw_rev >= PCIE_SHARED_VERSION_6 && !dhd->dongle_edl_support) #else - if (dhd->bus->api.fw_rev >= PCIE_SHARED_VERSION_6) { + if (dhd->bus->api.fw_rev >= PCIE_SHARED_VERSION_6) #endif /* EWP_EDL */ + { if ((ret = dhd_prot_init_info_rings(dhd)) != BCME_OK) { /* For now log and proceed, further clean up action maybe necessary * when we have more clarity. @@ -13650,8 +13651,9 @@ dhd_prot_debug_info_print(dhd_pub_t *dhd) prot->device_ipc_version, prot->host_ipc_version, prot->active_ipc_version)); - DHD_ERROR(("d2h_intr_method -> %s\n", - dhd->bus->d2h_intr_method ? "PCIE_MSI" : "PCIE_INTX")); + DHD_ERROR(("d2h_intr_method -> %s d2h_intr_control -> %s\n", + dhd->bus->d2h_intr_method ? "PCIE_MSI" : "PCIE_INTX", + dhd->bus->d2h_intr_control ? "HOST_IRQ" : "D2H_INTMASK")); DHD_ERROR(("max Host TS bufs to post: %d, posted %d\n", prot->max_tsbufpost, prot->cur_ts_bufs_posted)); DHD_ERROR(("max INFO bufs to post: %d, posted %d\n", diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c index 31dd226e836e..035f51bb50d5 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c @@ -102,6 +102,7 @@ #if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON) #include #endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */ +#include #define EXTENDED_PCIE_DEBUG_DUMP 1 /* Enable Extended pcie registers dump */ @@ -1080,6 +1081,13 @@ int dhdpcie_bus_attach(osl_t *osh, dhd_bus_t **bus_ptr, bus->d2h_intr_method = PCIE_INTX; #endif /* DHD_MSI_SUPPORT */ + /* For MSI, use host irq based control and for INTX use D2H INTMASK based control */ + if (bus->d2h_intr_method == PCIE_MSI) { + bus->d2h_intr_control = PCIE_HOST_IRQ_CTRL; + } else { + bus->d2h_intr_control = PCIE_D2H_INTMASK_CTRL; + } + #ifdef DHD_HP2P bus->hp2p_txcpl_max_items = DHD_MAX_ITEMS_HPP_TXCPL_RING; bus->hp2p_rxcpl_max_items = DHD_MAX_ITEMS_HPP_RXCPL_RING; @@ -1545,16 +1553,16 @@ skip_intstatus_read: bus->isr_intr_disable_count++; -#ifdef CHIP_INTR_CONTROL - dhdpcie_bus_intr_disable(bus); /* Disable interrupt using IntMask!! */ -#else - /* For Linux, Macos etc (otherthan NDIS) instead of disabling - * dongle interrupt by clearing the IntMask, disable directly - * interrupt from the host side, so that host will not recieve - * any interrupts at all, even though dongle raises interrupts - */ - dhdpcie_disable_irq_nosync(bus); /* Disable interrupt!! */ -#endif /* HOST_INTR_CONTROL */ + if (bus->d2h_intr_control == PCIE_D2H_INTMASK_CTRL) { + dhdpcie_bus_intr_disable(bus); /* Disable interrupt using IntMask!! */ + } else { + /* For Linux, Macos etc (otherthan NDIS) instead of disabling + * dongle interrupt by clearing the IntMask, disable directly + * interrupt from the host side, so that host will not recieve + * any interrupts at all, even though dongle raises interrupts + */ + dhdpcie_disable_irq_nosync(bus); /* Disable interrupt!! */ + } bus->intdis = TRUE; #ifdef DHD_FLOW_RING_STATUS_TRACE @@ -1779,6 +1787,7 @@ dhdpcie_cc_watchdog_reset(dhd_bus_t *bus) (WD_SSRESET_PCIE_F0_EN | WD_SSRESET_PCIE_ALL_FN_EN); pcie_watchdog_reset(bus->osh, bus->sih, WD_ENABLE_MASK, wd_en); } + void dhdpcie_dongle_reset(dhd_bus_t *bus) { @@ -2358,7 +2367,11 @@ dhdpcie_dongle_attach(dhd_bus_t *bus) bus->deep_sleep = TRUE; #endif +#ifdef CUSTOMER_HW_ROCKCHIP bus->idma_enabled = FALSE; +#else + bus->idma_enabled = TRUE; +#endif bus->ifrm_enabled = TRUE; #ifdef BCMINTERNAL bus->dma_chan = 0; @@ -2565,10 +2578,11 @@ dhdpcie_advertise_bus_cleanup(dhd_pub_t *dhdp) timeleft = dhd_os_busbusy_wait_negation(dhdp, &dhdp->dhd_bus_busy_state); #ifdef LINUX - if ((timeleft == 0) || (timeleft == 1)) { + if ((timeleft == 0) || (timeleft == 1)) #else - if (timeleft == 0) { + if (timeleft == 0) #endif + { /* XXX This condition ideally should not occur, this means some * bus usage context is not clearing the respective usage bit, print * dhd_bus_busy_state and crash the host for further debugging. @@ -3553,6 +3567,11 @@ dhd_set_bus_params(struct dhd_bus *bus) bus->pollrate = 1; printf("%s: set polling mode %d\n", __FUNCTION__, bus->dhd->conf->dhd_poll); } + if (bus->dhd->conf->d2h_intr_control >= 0) + bus->d2h_intr_control = bus->dhd->conf->d2h_intr_control; + printf("d2h_intr_method -> %s(%d); d2h_intr_control -> %s(%d)\n", + bus->d2h_intr_method ? "PCIE_MSI" : "PCIE_INTX", bus->d2h_intr_method, + bus->d2h_intr_control ? "HOST_IRQ" : "D2H_INTMASK", bus->d2h_intr_control); } /** @@ -3977,6 +3996,118 @@ exit: } #endif /* BCMINTERNAL */ +#ifdef DHD_LINUX_STD_FW_API +static int +dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path) +{ + int bcmerror = BCME_ERROR; + int offset = 0; + int len = 0; + bool store_reset; + int offset_end = bus->ramsize; + const struct firmware *fw = NULL; + int buf_offset = 0, residual_len = 0; +#ifdef CHECK_DOWNLOAD_FW + uint8 *memptr_tmp = NULL; // terence: check downloaded firmware is correct +#endif + +#if defined(DHD_FW_MEM_CORRUPTION) + if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) { + dhd_tcm_test_enable = TRUE; + } else { + dhd_tcm_test_enable = FALSE; + } +#endif /* DHD_FW_MEM_CORRUPTION */ + DHD_ERROR(("%s: dhd_tcm_test_enable %u\n", __FUNCTION__, dhd_tcm_test_enable)); + /* TCM check */ + if (dhd_tcm_test_enable && !dhd_bus_tcm_test(bus)) { + DHD_ERROR(("dhd_bus_tcm_test failed\n")); + bcmerror = BCME_ERROR; + goto err; + } + + DHD_ERROR(("%s: download firmware %s\n", __FUNCTION__, pfw_path)); + + /* check if CR4/CA7 */ + store_reset = (si_setcore(bus->sih, ARMCR4_CORE_ID, 0) || + si_setcore(bus->sih, ARMCA7_CORE_ID, 0)); + + bcmerror = dhd_os_get_img_fwreq(&fw, bus->fw_path); + if (bcmerror < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + bcmerror)); + goto err; + } +#ifdef CHECK_DOWNLOAD_FW + if (bus->dhd->conf->fwchk) { + memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); + if (memptr_tmp == NULL) { + DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); + goto err; + } + } +#endif + residual_len = fw->size; + while (residual_len) { + len = MIN(residual_len, MEMBLOCK); + + /* if address is 0, store the reset instruction to be written in 0 */ + if (store_reset) { + ASSERT(offset == 0); + bus->resetinstr = *(((uint32*)fw->data + buf_offset)); + /* Add start of RAM address to the address given by user */ + offset += bus->dongle_ram_base; + offset_end += offset; + store_reset = FALSE; + } + + bcmerror = dhdpcie_bus_membytes(bus, TRUE, offset, + (uint8 *)fw->data + buf_offset, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, MEMBLOCK, offset)); + goto err; + } +#ifdef CHECK_DOWNLOAD_FW + if (bus->dhd->conf->fwchk) { + bcmerror = dhdpcie_bus_membytes(bus, FALSE, offset, memptr_tmp, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, MEMBLOCK, offset)); + goto err; + } + if (memcmp(memptr_tmp, (uint8 *)fw->data + buf_offset, len)) { + DHD_ERROR(("%s: Downloaded image is corrupted at 0x%08x\n", __FUNCTION__, offset)); + bcmerror = BCME_ERROR; + goto err; + } else + DHD_INFO(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__)); + } +#endif + offset += MEMBLOCK; + + if (offset >= offset_end) { + DHD_ERROR(("%s: invalid address access to %x (offset end: %x)\n", + __FUNCTION__, offset, offset_end)); + bcmerror = BCME_ERROR; + goto err; + } + residual_len -= len; + buf_offset += len; + } +err: +#ifdef CHECK_DOWNLOAD_FW + if (memptr_tmp) + MFREE(bus->dhd->osh, memptr_tmp, MEMBLOCK + DHD_SDALIGN); +#endif + if (fw) { + dhd_os_close_img_fwreq(fw); + } + return bcmerror; +} /* dhdpcie_download_code_file */ + +#else + /** * Downloads a file containing firmware into dongle memory. In case of a .bea file, the DHD * is updated with the event logging partitions within that file as well. @@ -4092,15 +4223,21 @@ dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path) goto err; } residual_len = total_len; +#endif /* CACHE_FW_IMAGE */ /* Download image with MEMBLOCK size */ - while (residual_len) { +#if defined(CACHE_FW_IMAGES) + while (residual_len) +#else + /* Download image with MEMBLOCK size */ + while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, imgbuf))) +#endif /* CACHE_FW_IMAGE */ + { +#if defined(CACHE_FW_IMAGES) len = MIN(residual_len, MEMBLOCK); memcpy(memptr, dnld_buf + buf_offset, len); residual_len -= len; buf_offset += len; #else - /* Download image with MEMBLOCK size */ - while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, imgbuf))) { if (len < 0) { DHD_ERROR(("%s: dhd_os_get_image_block failed (%d)\n", __FUNCTION__, len)); bcmerror = BCME_ERROR; @@ -4177,6 +4314,7 @@ err: return bcmerror; } /* dhdpcie_download_code_file */ +#endif /* DHD_LINUX_STD_FW_API */ #ifdef CUSTOMER_HW4_DEBUG #define MIN_NVRAMVARS_SIZE 128 @@ -4186,7 +4324,7 @@ static int dhdpcie_download_nvram(struct dhd_bus *bus) { int bcmerror = BCME_ERROR; - uint len; + uint len, memblock_len = 0; char * memblock = NULL; char *bufp; char *pnv_path; @@ -4233,6 +4371,11 @@ dhdpcie_download_nvram(struct dhd_bus *bus) } else { nvram_uefi_exists = TRUE; } +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAX_NVRAMBUF_SIZE; +#endif /* DHD_LINUX_STD_FW_API */ DHD_ERROR(("%s: dhd_get_download_buffer len %d\n", __FUNCTION__, len)); @@ -4293,7 +4436,7 @@ err: if (local_alloc) { MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); } else { - dhd_free_download_buffer(bus->dhd, memblock, MAX_NVRAMBUF_SIZE); + dhd_free_download_buffer(bus->dhd, memblock, memblock_len); } } @@ -5669,6 +5812,7 @@ BCMFASTPATH(dhd_bus_txdata)(struct dhd_bus *bus, void *txp, uint8 ifidx) void *ntxp = NULL; uint8 prio = PKTPRIO(txp); #endif + uint8 *pktdata = (uint8 *)PKTDATA(bus->dhd->osh, txp); if (!bus->dhd->flowid_allocator) { DHD_ERROR(("%s: Flow ring not intited yet \n", __FUNCTION__)); @@ -5757,6 +5901,10 @@ BCMFASTPATH(dhd_bus_txdata)(struct dhd_bus *bus, void *txp, uint8 ifidx) } } #else /* !(defined(BCM_ROUTER_DHD) && defined(HNDCTF)) */ + if (dhd_match_pkt_type(bus->dhd, pktdata, (uint32)PKTLEN(bus->dhd->osh, txp))) { + if ((ret = dhd_flow_queue_enqueue_head(bus->dhd, queue, txp)) != BCME_OK) + txp_pend = txp; + } else if ((ret = dhd_flow_queue_enqueue(bus->dhd, queue, txp)) != BCME_OK) txp_pend = txp; #endif /* defined(BCM_ROUTER_DHD) && defined(HNDCTF */ @@ -5794,6 +5942,13 @@ BCMFASTPATH(dhd_bus_txdata)(struct dhd_bus *bus, void *txp, uint8 ifidx) } } #else /* !(defined(BCM_ROUTER_DHD) && defined(HNDCTF)) */ + if (dhd_match_pkt_type(bus->dhd, pktdata, (uint32)PKTLEN(bus->dhd->osh, txp))) { + if ((ret = dhd_flow_queue_enqueue_head(bus->dhd, queue, txp_pend)) != BCME_OK) { + DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags); + txp = txp_pend; + goto toss; + } + } else if ((ret = dhd_flow_queue_enqueue(bus->dhd, queue, txp_pend)) != BCME_OK) { DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags); txp = txp_pend; @@ -9272,11 +9427,13 @@ dhd_bus_dump_dar_registers(struct dhd_bus *bus) dar_erraddr_val = si_corereg(bus->sih, bus->sih->buscoreidx, dar_erraddr_reg, 0, 0); dar_pcie_mbint_val = si_corereg(bus->sih, bus->sih->buscoreidx, dar_pcie_mbint_reg, 0, 0); - DHD_ERROR(("%s: dar_clk_ctrl(0x%x:0x%x) dar_pwr_ctrl(0x%x:0x%x) dar_intstat(0x%x:0x%x)\n", + DHD_RPM(("%s: dar_clk_ctrl(0x%x:0x%x) dar_pwr_ctrl(0x%x:0x%x) " + "dar_intstat(0x%x:0x%x)\n", __FUNCTION__, dar_clk_ctrl_reg, dar_clk_ctrl_val, dar_pwr_ctrl_reg, dar_pwr_ctrl_val, dar_intstat_reg, dar_intstat_val)); - DHD_ERROR(("%s: dar_errlog(0x%x:0x%x) dar_erraddr(0x%x:0x%x) dar_pcie_mbint(0x%x:0x%x)\n", + DHD_RPM(("%s: dar_errlog(0x%x:0x%x) dar_erraddr(0x%x:0x%x) " + "dar_pcie_mbint(0x%x:0x%x)\n", __FUNCTION__, dar_errlog_reg, dar_errlog_val, dar_erraddr_reg, dar_erraddr_val, dar_pcie_mbint_reg, dar_pcie_mbint_val)); } @@ -9294,7 +9451,7 @@ dhd_bus_hostready(struct dhd_bus *bus) return; } - DHD_ERROR(("%s : Read PCICMD Reg: 0x%08X\n", __FUNCTION__, + DHD_ERROR_MEM(("%s : Read PCICMD Reg: 0x%08X\n", __FUNCTION__, dhd_pcie_config_read(bus, PCI_CFG_CMD, sizeof(uint32)))); dhd_bus_dump_dar_registers(bus); @@ -9304,7 +9461,7 @@ dhd_bus_hostready(struct dhd_bus *bus) #endif /* defined(DHD_MMIO_TRACE) */ si_corereg(bus->sih, bus->sih->buscoreidx, dhd_bus_db1_addr_get(bus), ~0, 0x12345678); bus->hostready_count ++; - DHD_ERROR(("%s: Ring Hostready:%d\n", __FUNCTION__, bus->hostready_count)); + DHD_ERROR_MEM(("%s: Ring Hostready:%d\n", __FUNCTION__, bus->hostready_count)); } /* Clear INTSTATUS */ @@ -9345,7 +9502,6 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) uint32 zero = 0; #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */ - printf("%s: state=%d\n", __FUNCTION__, state); if (bus->dhd == NULL) { DHD_ERROR(("%s: bus not inited\n", __FUNCTION__)); return BCME_ERROR; @@ -9396,7 +9552,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) } /* Suspend */ - DHD_ERROR(("%s: Entering suspend state\n", __FUNCTION__)); + DHD_RPM(("%s: Entering suspend state\n", __FUNCTION__)); bus->dhd->dhd_watchdog_ms_backup = dhd_watchdog_ms; if (bus->dhd->dhd_watchdog_ms_backup) { @@ -9546,7 +9702,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) #endif /* OEM_ANDROID */ if (bus->wait_for_d3_ack) { - DHD_ERROR(("%s: Got D3 Ack \n", __FUNCTION__)); + DHD_RPM(("%s: Got D3 Ack \n", __FUNCTION__)); /* Got D3 Ack. Suspend the bus */ #ifdef OEM_ANDROID if (active) { @@ -9808,7 +9964,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) #endif /* PCIE_OOB */ } else { /* Resume */ - DHD_ERROR(("%s: Entering resume state\n", __FUNCTION__)); + DHD_RPM(("%s: Entering resume state\n", __FUNCTION__)); bus->last_resume_start_time = OSL_LOCALTIME_NS(); /** @@ -11219,7 +11375,7 @@ dhdpcie_pme_active(osl_t *osh, bool enable) } pme_csr = OSL_PCI_READ_CONFIG(osh, cap_ptr + PME_CSR_OFFSET, sizeof(uint32)); - DHD_ERROR(("%s : pme_sts_ctrl 0x%x\n", __FUNCTION__, pme_csr)); + DHD_RPM(("%s : pme_sts_ctrl 0x%x\n", __FUNCTION__, pme_csr)); pme_csr |= PME_CSR_PME_STAT; if (enable) { @@ -11713,8 +11869,9 @@ void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) dhdp->bus->inband_host_sleep_exit_to_cnt); } #endif /* PCIE_INB_DW */ - bcm_bprintf(strbuf, "d2h_intr_method -> %s\n", - dhdp->bus->d2h_intr_method ? "PCIE_MSI" : "PCIE_INTX"); + bcm_bprintf(strbuf, "d2h_intr_method -> %s d2h_intr_control -> %s\n", + dhdp->bus->d2h_intr_method ? "PCIE_MSI" : "PCIE_INTX", + dhdp->bus->d2h_intr_control ? "HOST_IRQ" : "D2H_INTMASK"); bcm_bprintf(strbuf, "\n\nDB7 stats - db7_send_cnt: %d, db7_trap_cnt: %d, " "max duration: %lld (%lld - %lld), db7_timing_error_cnt: %d\n", @@ -12303,7 +12460,7 @@ dhdpcie_bus_ringbell_fast(struct dhd_bus *bus, uint32 value) { /* Skip once bus enters low power state (D3_INFORM/D3_ACK) */ if (__DHD_CHK_BUS_IN_LPS(bus)) { - DHD_ERROR(("%s: trying to ring the doorbell after D3 inform %d\n", + DHD_RPM(("%s: trying to ring the doorbell after D3 inform %d\n", __FUNCTION__, bus->bus_low_power_state)); return; } @@ -12347,7 +12504,7 @@ dhdpcie_bus_ringbell_2_fast(struct dhd_bus *bus, uint32 value, bool devwake) { /* Skip once bus enters low power state (D3_INFORM/D3_ACK) */ if (__DHD_CHK_BUS_IN_LPS(bus)) { - DHD_ERROR(("%s: trying to ring the doorbell after D3 inform %d\n", + DHD_RPM(("%s: trying to ring the doorbell after D3 inform %d\n", __FUNCTION__, bus->bus_low_power_state)); return; } @@ -12488,18 +12645,18 @@ BCMFASTPATH(dhd_bus_dpc)(struct dhd_bus *bus) #ifdef DHD_READ_INTSTATUS_IN_DPC INTR_ON: #endif /* DHD_READ_INTSTATUS_IN_DPC */ -#ifdef CHIP_INTR_CONTROL - dhdpcie_bus_intr_enable(bus); /* Enable back interrupt using Intmask!! */ - bus->dpc_intr_enable_count++; -#else - /* For Linux, Macos etc (otherthan NDIS) enable back the host interrupts - * which has been disabled in the dhdpcie_bus_isr() - */ - if ((dhdpcie_irq_disabled(bus)) && (!dhd_query_bus_erros(bus->dhd))) { - dhdpcie_enable_irq(bus); /* Enable back interrupt!! */ + if (bus->d2h_intr_control == PCIE_D2H_INTMASK_CTRL) { + dhdpcie_bus_intr_enable(bus); /* Enable back interrupt using Intmask!! */ bus->dpc_intr_enable_count++; + } else { + /* For Linux, Macos etc (otherthan NDIS) enable back the host interrupts + * which has been disabled in the dhdpcie_bus_isr() + */ + if ((dhdpcie_irq_disabled(bus)) && (!dhd_query_bus_erros(bus->dhd))) { + dhdpcie_enable_irq(bus); /* Enable back interrupt!! */ + bus->dpc_intr_enable_count++; + } } -#endif /* HOST_INTR_CONTROL */ bus->dpc_exit_time = OSL_LOCALTIME_NS(); } else { bus->resched_dpc_time = OSL_LOCALTIME_NS(); @@ -12621,7 +12778,7 @@ dhd_bus_handle_d3_ack(dhd_bus_t *bus) #endif /* !NDIS */ DHD_SET_BUS_LPS_D3_ACKED(bus); - DHD_ERROR(("%s: D3_ACK Recieved\n", __FUNCTION__)); + DHD_RPM(("%s: D3_ACK Recieved\n", __FUNCTION__)); if (bus->dhd->dhd_induce_error == DHD_INDUCE_D3_ACK_TIMEOUT) { /* Set bus_low_power_state to DHD_BUS_D3_ACK_RECIEVED */ @@ -12639,6 +12796,7 @@ dhd_bus_handle_d3_ack(dhd_bus_t *bus) DHD_ERROR(("%s: Inducing D3 ACK timeout\n", __FUNCTION__)); } } + void dhd_bus_handle_mb_data(dhd_bus_t *bus, uint32 d2h_mb_data) { @@ -13125,7 +13283,7 @@ dhdpci_bus_read_frames(dhd_bus_t *bus) /* Do not process rest of ring buf once bus enters low power state (D3_INFORM/D3_ACK) */ if (DHD_CHK_BUS_IN_LPS(bus)) { - DHD_ERROR(("%s: Bus is in power save state (%d). " + DHD_RPM(("%s: Bus is in power save state (%d). " "Skip processing rest of ring buffers.\n", __FUNCTION__, bus->bus_low_power_state)); return FALSE; @@ -15561,7 +15719,7 @@ dhd_get_rpm_state(dhd_pub_t *dhd) void dhd_set_rpm_state(dhd_pub_t *dhd, bool state) { - DHD_ERROR(("%s: %d\n", __FUNCTION__, state)); + DHD_RPM(("%s: %d\n", __FUNCTION__, state)); dhd->bus->rpm_enabled = state; } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.h index 82de49149c76..e18bc2bd5d68 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.h @@ -402,6 +402,7 @@ typedef struct dhd_bus { #endif /* PCIE_OOB */ bool irq_registered; bool d2h_intr_method; + bool d2h_intr_control; #ifdef SUPPORT_LINKDOWN_RECOVERY #if defined(CONFIG_ARCH_MSM) || (defined(CONFIG_ARCH_EXYNOS) && \ !defined(SUPPORT_EXYNOS7420)) @@ -601,6 +602,11 @@ enum { PCIE_MSI = 1 }; +enum { + PCIE_D2H_INTMASK_CTRL = 0, + PCIE_HOST_IRQ_CTRL = 1 +}; + static INLINE bool __dhd_check_bus_in_lps(dhd_bus_t *bus) { diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c index 1d0442916575..0d2cd973a616 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c @@ -47,7 +47,9 @@ #include #include #include +#ifdef CUSTOMER_HW_ROCKCHIP #include +#endif /* CUSTOMER_HW_ROCKCHIP */ #ifdef OEM_ANDROID #ifdef CONFIG_ARCH_MSM #if defined(CONFIG_PCI_MSM) || defined(CONFIG_ARCH_MSM8996) @@ -618,8 +620,10 @@ dhd_bus_is_rc_ep_l1ss_capable(dhd_bus_t *bus) uint32 rc_l1ss_cap; uint32 ep_l1ss_cap; +#ifdef CUSTOMER_HW_ROCKCHIP if (IS_ENABLED(CONFIG_PCIEASPM_ROCKCHIP_WIFI_EXTENSION)) return rk_dhd_bus_is_rc_ep_l1ss_capable(bus); +#endif /* RC Extendend Capacility */ rc_l1ss_cap = dhdpcie_access_cap(bus->rc_dev, PCIE_EXTCAP_ID_L1SS, PCIE_EXTCAP_L1SS_CONTROL_OFFSET, TRUE, FALSE, 0); @@ -707,7 +711,9 @@ static int dhdpcie_pm_suspend(struct device *dev) dhdpcie_info_t *pch = pci_get_drvdata(pdev); dhd_bus_t *bus = NULL; unsigned long flags; + int msglevel = dhd_msg_level; + printf("%s: Enter\n", __FUNCTION__); if (pch) { bus = pch->bus; } @@ -725,12 +731,15 @@ static int dhdpcie_pm_suspend(struct device *dev) DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(bus->dhd); DHD_GENERAL_UNLOCK(bus->dhd, flags); + dhd_msg_level |= DHD_RPM_VAL; if (bus->dhd->up) ret = dhdpcie_set_suspend_resume(bus, TRUE); DHD_GENERAL_LOCK(bus->dhd, flags); DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(bus->dhd); dhd_os_busbusy_wake(bus->dhd); + dhd_msg_level = msglevel; + printf("%s: Exit ret=%d\n", __FUNCTION__, ret); DHD_GENERAL_UNLOCK(bus->dhd, flags); return ret; @@ -761,7 +770,9 @@ static int dhdpcie_pm_resume(struct device *dev) dhdpcie_info_t *pch = pci_get_drvdata(pdev); dhd_bus_t *bus = NULL; unsigned long flags; + int msglevel = dhd_msg_level; + printf("%s: Enter\n", __FUNCTION__); if (pch) { bus = pch->bus; } @@ -773,12 +784,15 @@ static int dhdpcie_pm_resume(struct device *dev) DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(bus->dhd); DHD_GENERAL_UNLOCK(bus->dhd, flags); + dhd_msg_level |= DHD_RPM_VAL; if (bus->dhd->up) ret = dhdpcie_set_suspend_resume(bus, FALSE); DHD_GENERAL_LOCK(bus->dhd, flags); DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd); dhd_os_busbusy_wake(bus->dhd); + dhd_msg_level = msglevel; + printf("%s: Exit ret=%d\n", __FUNCTION__, ret); DHD_GENERAL_UNLOCK(bus->dhd, flags); return ret; @@ -809,6 +823,7 @@ static int dhdpcie_pci_suspend(struct pci_dev * pdev, pm_message_t state) unsigned long flags; uint32 i = 0; + printf("%s: Enter\n", __FUNCTION__); if (pch) { bus = pch->bus; } @@ -861,6 +876,7 @@ static int dhdpcie_pci_suspend(struct pci_dev * pdev, pm_message_t state) DHD_GENERAL_LOCK(bus->dhd, flags); DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(bus->dhd); dhd_os_busbusy_wake(bus->dhd); + printf("%s: Exit ret=%d\n", __FUNCTION__, ret); DHD_GENERAL_UNLOCK(bus->dhd, flags); return ret; @@ -925,6 +941,7 @@ static int dhdpcie_pci_resume(struct pci_dev *pdev) dhd_bus_t *bus = NULL; unsigned long flags; + printf("%s: Enter\n", __FUNCTION__); if (pch) { bus = pch->bus; } @@ -942,6 +959,7 @@ static int dhdpcie_pci_resume(struct pci_dev *pdev) DHD_GENERAL_LOCK(bus->dhd, flags); DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd); dhd_os_busbusy_wake(bus->dhd); + printf("%s: Exit ret=%d\n", __FUNCTION__, ret); DHD_GENERAL_UNLOCK(bus->dhd, flags); #ifdef DHD_CFG80211_SUSPEND_RESUME @@ -970,6 +988,7 @@ dhdpcie_set_suspend_resume(dhd_bus_t *bus, bool state) } mutex_lock(&bus->pm_lock); #endif /* DHD_PCIE_RUNTIMEPM */ + DHD_RPM(("%s: Enter state=%d\n", __FUNCTION__, state)); /* When firmware is not loaded do the PCI bus */ /* suspend/resume only */ @@ -999,6 +1018,7 @@ dhdpcie_set_suspend_resume(dhd_bus_t *bus, bool state) } } #endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */ + DHD_RPM(("%s: Exit ret=%d\n", __FUNCTION__, ret)); #ifdef DHD_PCIE_RUNTIMEPM mutex_unlock(&bus->pm_lock); @@ -1117,7 +1137,7 @@ extern void dhd_dpc_tasklet_kill(dhd_pub_t *dhdp); static void dhdpcie_suspend_dump_cfgregs(struct dhd_bus *bus, char *suspend_state) { - DHD_ERROR(("%s: BaseAddress0(0x%x)=0x%x, " + DHD_RPM(("%s: BaseAddress0(0x%x)=0x%x, " "BaseAddress1(0x%x)=0x%x PCIE_CFG_PMCSR(0x%x)=0x%x " "PCI_BAR1_WIN(0x%x)=(0x%x)\n", suspend_state, @@ -1147,7 +1167,7 @@ static int dhdpcie_suspend_dev(struct pci_dev *dev) return BCME_ERROR; } #endif /* OEM_ANDROID && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ - DHD_ERROR(("%s: Enter\n", __FUNCTION__)); + DHD_RPM(("%s: Enter\n", __FUNCTION__)); #if defined(CONFIG_SOC_EXYNOS9810) || defined(CONFIG_SOC_EXYNOS9820) || \ defined(CONFIG_SOC_EXYNOS9830) || defined(CONFIG_SOC_EXYNOS2100) || \ defined(CONFIG_SOC_EXYNOS1000) @@ -1218,7 +1238,7 @@ static int dhdpcie_resume_dev(struct pci_dev *dev) #if defined(OEM_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) pci_load_and_free_saved_state(dev, &pch->state); #endif /* OEM_ANDROID && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ - DHD_ERROR(("%s: Enter\n", __FUNCTION__)); + DHD_RPM(("%s: Enter\n", __FUNCTION__)); #ifdef OEM_ANDROID // dev->state_saved = TRUE; #endif /* OEM_ANDROID */ @@ -1953,12 +1973,12 @@ void dhdpcie_dump_resource(dhd_bus_t *bus) } /* BAR0 */ - DHD_ERROR(("%s: BAR0(VA): 0x%pK, BAR0(PA): "PRINTF_RESOURCE", SIZE: %d\n", + DHD_RPM(("%s: BAR0(VA): 0x%pK, BAR0(PA): "PRINTF_RESOURCE", SIZE: %d\n", __FUNCTION__, pch->regs, pci_resource_start(bus->dev, 0), DONGLE_REG_MAP_SIZE)); /* BAR1 */ - DHD_ERROR(("%s: BAR1(VA): 0x%pK, BAR1(PA): "PRINTF_RESOURCE", SIZE: %d\n", + DHD_RPM(("%s: BAR1(VA): 0x%pK, BAR1(PA): "PRINTF_RESOURCE", SIZE: %d\n", __FUNCTION__, pch->tcm, pci_resource_start(bus->dev, 2), pch->bar1_size)); } @@ -2393,14 +2413,15 @@ dhdpcie_enable_irq(dhd_bus_t *bus) int dhdpcie_irq_disabled(dhd_bus_t *bus) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) - struct irq_desc *desc = irq_to_desc(bus->dev->irq); + struct irq_desc *desc = NULL; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)) + desc = irq_data_to_desc(irq_get_irq_data(bus->dev->irq)); +#else + desc = irq_to_desc(bus->dev->irq); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) /* depth will be zero, if enabled */ return desc->depth; -#else - /* return ERROR by default as there is no support for lower versions */ - return BCME_ERROR; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */ } #if defined(CONFIG_ARCH_EXYNOS) @@ -3137,7 +3158,7 @@ bool dhd_runtimepm_state(dhd_pub_t *dhd) bus->idlecount = 0; if (DHD_BUS_BUSY_CHECK_IDLE(dhd) && !DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhd) && !DHD_CHECK_CFG_IN_PROGRESS(dhd) && !dhd_os_check_wakelock_all(bus->dhd)) { - DHD_ERROR(("%s: DHD Idle state!! - idletime :%d, wdtick :%d \n", + DHD_RPM(("%s: DHD Idle state!! - idletime :%d, wdtick :%d \n", __FUNCTION__, bus->idletime, dhd_runtimepm_ms)); bus->bus_wake = 0; DHD_BUS_BUSY_SET_RPM_SUSPEND_IN_PROGRESS(dhd); @@ -3216,7 +3237,7 @@ bool dhd_runtimepm_state(dhd_pub_t *dhd) smp_wmb(); wake_up(&bus->rpm_queue); - DHD_ERROR(("%s : runtime resume ended \n", __FUNCTION__)); + DHD_RPM(("%s : runtime resume ended \n", __FUNCTION__)); return TRUE; } else { DHD_GENERAL_UNLOCK(dhd, flags); @@ -3257,7 +3278,8 @@ bool dhd_runtime_bus_wake(dhd_bus_t *bus, bool wait, void *func_addr) DHD_GENERAL_UNLOCK(bus->dhd, flags); - DHD_ERROR_RLMT(("Runtime Resume is called in %pf\n", func_addr)); + if (dhd_msg_level & DHD_RPM_VAL) + DHD_ERROR_RLMT(("%s: Runtime Resume is called in %pf\n", __FUNCTION__, func_addr)); smp_wmb(); wake_up(&bus->rpm_queue); /* No need to wake up the RPM state thread */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c index b648dfe85ce6..ed5c314eafee 100644 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c @@ -3389,7 +3389,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) if (bus->dhd->conf->rxcnt_timeout) max_rxcnt = bus->dhd->conf->rxcnt_timeout; - else + else max_rxcnt = MAX_CNTL_RX_TIMEOUT; if (bus->dhd->rxcnt_timeout >= max_rxcnt) { #ifdef DHD_PM_CONTROL_FROM_FILE @@ -3868,6 +3868,57 @@ xfer_done: return bcmerror; } +#if defined(BCMSDIO_RXLIM_POST) || defined(BCMSDIO_TXSEQ_SYNC) +static void +dhdsdio_txseq_sync(dhd_bus_t *bus, sdpcm_shared_t *sh) +{ + struct dhd_conf *conf = bus->dhd->conf; + + if (sh->flags & SDPCM_SHARED_RXLIM_POST) { +#ifdef BCMSDIO_RXLIM_POST + if (conf->rxlim_en) { + if (sh->msgtrace_addr) { + bus->rxlim_en = TRUE; + bus->rxlim_addr = sh->msgtrace_addr; + DHD_INFO(("%s: RXLIM_POST enabled with rxlim_addr=0x%x\n", + __FUNCTION__, bus->rxlim_addr)); + } else { + DHD_INFO(("%s: RXLIM_POST not enabled in fw\n", __FUNCTION__)); + } + } else +#endif /* BCMSDIO_RXLIM_POST */ +#ifdef BCMSDIO_TXSEQ_SYNC + if (conf->txseq_sync) { + uint8 val = 0; + sh->txseq_sync_addr = ltoh32(sh->txseq_sync_addr); + DHD_INFO(("%s: TXSEQ_SYNC enabled\n", __FUNCTION__)); + if (0 == dhdsdio_membytes(bus, FALSE, sh->txseq_sync_addr, (uint8 *)&val, 1)) { + if (bus->tx_seq != val) { + DHD_INFO(("%s: Sync tx_seq from %d to %d\n", + __FUNCTION__, bus->tx_seq, val)); + bus->tx_seq = val; + bus->tx_max = bus->tx_seq + 4; + } + } + } else +#endif /* BCMSDIO_TXSEQ_SYNC */ + { + DHD_INFO(("%s: rxlim_en and txseq_sync not enabled in config.txt\n", __FUNCTION__)); + } + sh->flags &= ~SDPCM_SHARED_RXLIM_POST; + } + else { +#ifdef BCMSDIO_RXLIM_POST + bus->rxlim_en = 0; +#endif /* BCMSDIO_RXLIM_POST */ +#ifdef BCMSDIO_TXSEQ_SYNC + conf->txseq_sync = FALSE; +#endif /* BCMSDIO_TXSEQ_SYNC */ + DHD_INFO(("%s: TXSEQ_SYNC and RXLIM_POST not supported in fw\n", __FUNCTION__)); + } +} +#endif /* BCMSDIO_RXLIM_POST || BCMSDIO_TXSEQ_SYNC */ + static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) { @@ -3934,41 +3985,9 @@ dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) sh->console_addr = ltoh32(sh->console_addr); sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); -#ifdef BCMSDIO_RXLIM_POST - if (sh->flags & SDPCM_SHARED_RXLIM_POST) { - if (bus->dhd->conf->rxlim_en) - bus->rxlim_en = !!sh->msgtrace_addr; - bus->rxlim_addr = sh->msgtrace_addr; - DHD_INFO(("%s: rxlim_en=%d, rxlim enable=%d, rxlim_addr=%d\n", - __FUNCTION__, - bus->dhd->conf->rxlim_en, bus->rxlim_en, bus->rxlim_addr)); - sh->flags &= ~SDPCM_SHARED_RXLIM_POST; - } else { - bus->rxlim_en = 0; - DHD_INFO(("%s: FW has no rx limit post support\n", __FUNCTION__)); - } -#endif /* BCMSDIO_RXLIM_POST */ - -#ifdef BCMSDIO_TXSEQ_SYNC - if (bus->dhd->conf->txseq_sync) { - sh->txseq_sync_addr = ltoh32(sh->txseq_sync_addr); - if (sh->flags & SDPCM_SHARED_TXSEQ_SYNC) { - uint8 val = 0; - DHD_INFO(("%s: TXSEQ_SYNC enabled in fw\n", __FUNCTION__)); - if (0 == dhdsdio_membytes(bus, FALSE, sh->txseq_sync_addr, (uint8 *)&val, 1)) { - if (bus->tx_seq != val) { - DHD_INFO(("%s: Sync tx_seq from %d to %d\n", - __FUNCTION__, bus->tx_seq, val)); - bus->tx_seq = val; - bus->tx_max = bus->tx_seq + 4; - } - } - sh->flags &= ~SDPCM_SHARED_TXSEQ_SYNC; - } else { - bus->dhd->conf->txseq_sync = FALSE; - } - } -#endif /* BCMSDIO_TXSEQ_SYNC */ +#if defined(BCMSDIO_RXLIM_POST) || defined(BCMSDIO_TXSEQ_SYNC) + dhdsdio_txseq_sync(bus, sh); +#endif /* * XXX - Allow a sdpcm_shared_t version mismatch between dhd structure @@ -8217,7 +8236,7 @@ dhd_bus_dump_txpktstatics(dhd_pub_t *dhdp) printk("\n"); printk(KERN_CONT DHD_LOG_PREFIXS); } - } + } printk("\n"); printk(KERN_CONT DHD_LOG_PREFIXS); for (i=0;itx_statics.glom_max;i++) { @@ -8240,7 +8259,7 @@ dhd_bus_dump_txpktstatics(dhd_pub_t *dhdp) printk("\n"); printk(KERN_CONT DHD_LOG_PREFIXS); } - } + } printk("\n"); if (total) { printf("%s: data(%d)/glom(%d)=%d, glom_max=%d\n", @@ -8257,7 +8276,7 @@ dhd_bus_dump_txpktstatics(dhd_pub_t *dhdp) printk(KERN_CONT DHD_LOG_PREFIXS); for (i=0; i<10; i++) { printk(KERN_CONT "[%d]: %d, ", i, dhdp->conf->kso_try_array[i]); - } + } printk("\n"); #endif } @@ -8609,6 +8628,13 @@ int dhd_bus_get_oob_irq_num(dhd_pub_t *dhdp) return irq_num; } +#ifdef LINUX +struct device *dhd_bus_to_dev(struct dhd_bus *bus) +{ + return (struct device *)bcmsdh_get_dev(bus->sdh); +} +#endif /* LINUX */ + void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub) { #ifdef LINUX @@ -10057,6 +10083,7 @@ dhdsdio_suspend(void *context) /* resume all interface network queue. */ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF); } + bus->dhd->hostsleep = 2; DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(bus->dhd); dhd_os_busbusy_wake(bus->dhd); DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags); @@ -10088,6 +10115,7 @@ dhdsdio_resume(void *context) DHD_LINUX_GENERAL_LOCK(bus->dhd, flags); DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd); + bus->dhd->hostsleep = 0; bus->dhd->busstate = DHD_BUS_DATA; dhd_os_busbusy_wake(bus->dhd); /* resume all interface network queue. */ @@ -10228,6 +10256,144 @@ err: } #endif /* BCMEMBEDIMAGE */ +#ifdef DHD_LINUX_STD_FW_API +static int +dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) +{ + int bcmerror = -1; + int offset = 0; + int len; + uint8 *memblock = NULL, *memptr; +#ifdef CHECK_DOWNLOAD_FW + uint8 *memptr_tmp = NULL; // terence: check downloaded firmware is correct +#endif + uint memblock_size = MEMBLOCK; +#ifdef DHD_DEBUG_DOWNLOADTIME + unsigned long initial_jiffies = 0; + uint firmware_sz = 0; +#endif + int offset_end = bus->ramsize; + const struct firmware *fw = NULL; + int buf_offset = 0, residual_len = 0; + + DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, pfw_path)); + + /* XXX: Should succeed in opening image if it is actually given through registry + * entry or in module param. + */ + bcmerror = dhd_os_get_img_fwreq(&fw, bus->fw_path); + if (bcmerror < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + bcmerror)); + goto err; + } + residual_len = fw->size; + + /* Update the dongle image download block size depending on the F1 block size */ +#ifndef NDIS + if (sd_f1_blocksize == 512) + memblock_size = MAX_MEMBLOCK; +#endif /* !NDIS */ + + memptr = memblock = MALLOC(bus->dhd->osh, memblock_size + DHD_SDALIGN); + if (memblock == NULL) { + DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, + memblock_size)); + goto err; + } + if ((uint32)(uintptr)memblock % DHD_SDALIGN) + memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); + +#ifdef CHECK_DOWNLOAD_FW + if (bus->dhd->conf->fwchk) { + memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); + if (memptr_tmp == NULL) { + DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); + goto err; + } + } +#endif + +#ifdef DHD_DEBUG_DOWNLOADTIME + initial_jiffies = jiffies; +#endif + + /* Download image */ + while (residual_len) { + len = MIN(residual_len, memblock_size); + bcopy((uint8 *)fw->data + buf_offset, (uint8 *)memptr, len); + /* check if CR4 */ + if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { + /* if address is 0, store the reset instruction to be written in 0 */ + + if (offset == 0) { + bus->resetinstr = *(((uint32*)memptr)); + /* Add start of RAM address to the address given by user */ + offset += bus->dongle_ram_base; + offset_end += offset; + } + } + + bcmerror = dhdsdio_membytes(bus, TRUE, offset, (uint8 *)memptr, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, memblock_size, offset)); + goto err; + } + +#ifdef CHECK_DOWNLOAD_FW + if (bus->dhd->conf->fwchk) { + bcmerror = dhdsdio_membytes(bus, FALSE, offset, memptr_tmp, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, MEMBLOCK, offset)); + goto err; + } + if (memcmp(memptr_tmp, memptr, len)) { + DHD_ERROR(("%s: Downloaded image is corrupted at 0x%08x\n", __FUNCTION__, offset)); + bcmerror = BCME_ERROR; + goto err; + } else + DHD_INFO(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__)); + } +#endif + + offset += memblock_size; +#ifdef DHD_DEBUG_DOWNLOADTIME + firmware_sz += len; +#endif + if (offset >= offset_end) { + DHD_ERROR(("%s: invalid address access to %x (offset end: %x)\n", + __FUNCTION__, offset, offset_end)); + bcmerror = BCME_ERROR; + goto err; + } + residual_len -= len; + buf_offset += len; + } + +#ifdef DHD_DEBUG_DOWNLOADTIME + DHD_ERROR(("Firmware download time for %u bytes: %u ms\n", + firmware_sz, jiffies_to_msecs(jiffies - initial_jiffies))); +#endif + +err: + if (memblock) + MFREE(bus->dhd->osh, memblock, memblock_size + DHD_SDALIGN); +#ifdef CHECK_DOWNLOAD_FW + if (bus->dhd->conf->fwchk) { + if (memptr_tmp) + MFREE(bus->dhd->osh, memptr_tmp, MEMBLOCK + DHD_SDALIGN); + } +#endif + + if (fw) { + dhd_os_close_img_fwreq(fw); + } + + return bcmerror; +} +#else static int dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) { @@ -10268,6 +10434,9 @@ dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) memblock_size)); goto err; } + if ((uint32)(uintptr)memblock % DHD_SDALIGN) + memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); + #ifdef CHECK_DOWNLOAD_FW if (bus->dhd->conf->fwchk) { memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); @@ -10277,8 +10446,6 @@ dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) } } #endif - if ((uint32)(uintptr)memblock % DHD_SDALIGN) - memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); #ifdef DHD_DEBUG_DOWNLOADTIME initial_jiffies = jiffies; @@ -10360,6 +10527,7 @@ err: return bcmerror; } +#endif /* DHD_LINUX_STD_FW_API */ #ifdef DHD_UCODE_DOWNLOAD /* Currently supported only for the chips in which ucode RAM is AXI addressable */ @@ -10495,8 +10663,7 @@ static int dhdsdio_download_nvram(struct dhd_bus *bus) { int bcmerror = -1; - uint len; - void * image = NULL; + uint len, memblock_len = 0; char * memblock = NULL; char *bufp; char *pnv_path; @@ -10506,24 +10673,21 @@ dhdsdio_download_nvram(struct dhd_bus *bus) nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0')); - /* For Get nvram from UEFI */ - if (nvram_file_exists) { - image = dhd_os_open_image1(bus->dhd, pnv_path); - if (image == NULL) { - printf("%s: Open nvram file failed %s\n", __FUNCTION__, pnv_path); - goto err; - } - } + len = MAX_NVRAMBUF_SIZE; + if (nvram_file_exists) + bcmerror = dhd_get_download_buffer(bus->dhd, pnv_path, NVRAM, &memblock, + (int *)&len); + else + bcmerror = dhd_get_download_buffer(bus->dhd, NULL, NVRAM, &memblock, (int *)&len); - memblock = MALLOC(bus->dhd->osh, MAX_NVRAMBUF_SIZE); - if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MAX_NVRAMBUF_SIZE)); + if (bcmerror != BCME_OK) goto err; - } - /* For Get nvram from image or UEFI (when image == NULL ) */ - len = dhd_os_get_image_block(memblock, MAX_NVRAMBUF_SIZE, image); +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAX_NVRAMBUF_SIZE; +#endif /* DHD_LINUX_STD_FW_API */ if (len > 0 && len < MAX_NVRAMBUF_SIZE) { bufp = (char *)memblock; @@ -10548,10 +10712,7 @@ dhdsdio_download_nvram(struct dhd_bus *bus) err: if (memblock) - MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); - - if (image) - dhd_os_close_image1(bus->dhd, image); + dhd_free_download_buffer(bus->dhd, memblock, memblock_len); return bcmerror; } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_static_buf.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_static_buf.c index bf9ad205ab3f..cfbf3053667d 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_static_buf.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_static_buf.c @@ -7,7 +7,7 @@ #include #include -#define DHD_STATIC_VERSION_STR "101.10.361.12 (wlan=r892223-20210928-1)" +#define DHD_STATIC_VERSION_STR "101.10.361.18 (wlan=r892223-20220519-1)" #define STATIC_ERROR_LEVEL (1 << 0) #define STATIC_TRACE_LEVEL (1 << 1) #define STATIC_MSG_LEVEL (1 << 0) @@ -173,7 +173,7 @@ void *wlan_static_dhd_event_ring_buf[MAX_NUM_ADAPTERS] = {NULL}; void *wlan_static_nan_event_ring_buf[MAX_NUM_ADAPTERS] = {NULL}; #if defined(BCMDHD_SDIO) || defined(BCMDHD_PCIE) -static struct sk_buff *wlan_static_skb[MAX_NUM_ADAPTERS][WLAN_SKB_BUF_NUM]; +static struct sk_buff *wlan_static_skb[MAX_NUM_ADAPTERS][WLAN_SKB_BUF_NUM] = {{NULL}}; #endif /* BCMDHD_SDIO | BCMDHD_PCIE */ void * @@ -184,11 +184,15 @@ dhd_wlan_mem_prealloc( int section, unsigned long size) { #ifndef BCMDHD_MDRIVER - uint bus_type = 0; int index = 0; #endif + +#ifdef BCMDHD_MDRIVER DHD_STATIC_MSG("bus_type %d, index %d, sectoin %d, size %ld\n", bus_type, index, section, size); +#else + DHD_STATIC_MSG("sectoin %d, size %ld\n", section, size); +#endif if (section == DHD_PREALLOC_PROT) return wlan_static_prot[index]; @@ -338,7 +342,9 @@ dhd_wlan_mem_prealloc( return NULL; } +#ifndef DHD_STATIC_IN_DRIVER EXPORT_SYMBOL(dhd_wlan_mem_prealloc); +#endif static void dhd_deinit_wlan_mem(int index) @@ -584,11 +590,11 @@ dhd_init_wlan_mem(int index) DHD_PREALLOC_NAN_EVENT_RING, NAN_EVENT_RING_SIZE); #endif /* BCMDHD_UNUSE_MEM */ - DHD_STATIC_MSG("prealloc ok for index %d: %ld(%ldK)\n", index, size, size/1024); + DHD_STATIC_MSG("prealloc ok for index %d: %ld(%ldK)\n", index, size, size/1024); return 0; err_mem_alloc: - DHD_STATIC_ERROR("Failed to allocate memory for index %d\n", index); + DHD_STATIC_ERROR("Failed to allocate memory for index %d\n", index); return -ENOMEM; } @@ -615,7 +621,7 @@ dhd_static_buf_init(void) dhd_deinit_wlan_mem(i); } - return 0; + return ret; } #ifdef DHD_STATIC_IN_DRIVER diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh.h index 81c3438993c2..3ed679b049d2 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh.h @@ -256,6 +256,7 @@ extern void bcmsdh_oob_intr_unregister(bcmsdh_info_t *sdh); extern void bcmsdh_oob_intr_set(bcmsdh_info_t *sdh, bool enable); extern int bcmsdh_get_oob_intr_num(bcmsdh_info_t *bcmsdh); #endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */ +extern void *bcmsdh_get_dev(bcmsdh_info_t *sdh); extern void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *sdh); extern void bcmsdh_dev_relax(bcmsdh_info_t *sdh); extern bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *sdh); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh_sdmmc.h index d9a67e073a80..c79682e2567c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh_sdmmc.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh_sdmmc.h @@ -24,7 +24,6 @@ #ifndef __BCMSDH_SDMMC_H__ #define __BCMSDH_SDMMC_H__ -#ifdef BCMDBG #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) @@ -32,15 +31,6 @@ #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) #define sd_cost(x) do { if (sd_msglevel & SDH_COST_VAL) printf x; } while (0) -#else -#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) -#define sd_data(x) -#define sd_ctrl(x) -#define sd_cost(x) do { if (sd_msglevel & SDH_COST_VAL) printf x; } while (0) -#endif #define sd_sync_dma(sd, read, nbytes) #define sd_init_dma(sd) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmutils.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmutils.h index 32e8adab643d..2971d8b38d63 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmutils.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmutils.h @@ -194,8 +194,6 @@ extern void *pktlast(osl_t *osh, void *p); extern uint pktsegcnt(osl_t *osh, void *p); extern uint8 *pktdataoffset(osl_t *osh, void *p, uint offset); extern void *pktoffset(osl_t *osh, void *p, uint offset); -/* Add to adjust 802.1x priority */ -extern void pktset8021xprio(void *pkt, int prio); #ifdef WLCSO extern uint pkttotlen_no_sfhtoe_hdr(osl_t *osh, void *p, uint toe_hdr_len); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/dhdioctl.h index d94b6db7a730..6404b2cdc211 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/dhdioctl.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/dhdioctl.h @@ -262,8 +262,10 @@ typedef enum dhd_iface_mgmt_policy { #define DHD_MSGTRACE_VAL 0x200000 #define DHD_FWLOG_VAL 0x400000 #define DHD_DBGIF_VAL 0x800000 -#ifdef DHD_PCIE_NATIVE_RUNTIMEPM +#ifdef DHD_PCIE_RUNTIMEPM #define DHD_RPM_VAL 0x1000000 +#else +#define DHD_RPM_VAL DHD_ERROR_VAL #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */ #define DHD_PKT_MON_VAL 0x2000000 #define DHD_PKT_MON_DUMP_VAL 0x4000000 diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h index c8d442284c1c..ac7bdb4a278c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h @@ -45,7 +45,7 @@ #elif (defined (BCMDBG_ASSERT) && !defined (BCMDBG_ASSERT_DISABLED)) #define EPI_VERSION_STR "101.10.361 (wlan=r892223 ASSRT)" #else -#define EPI_VERSION_STR "101.10.361.16 (wlan=r892223-20220221-1)" +#define EPI_VERSION_STR "101.10.361.20 (wlan=r892223-20220701-3)" #endif /* BCMINTERNAL */ #endif /* _epivers_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linux_osl.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linux_osl.h index 516114600336..a0a0937bcdf2 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linux_osl.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linux_osl.h @@ -350,7 +350,7 @@ extern uint64 osl_systztime_us(void); #define OSL_LOCALTIME_NS() osl_localtime_ns() #define OSL_GET_LOCALTIME(sec, usec) osl_get_localtime((sec), (usec)) #define OSL_SYSTZTIME_US() osl_systztime_us() -#define printf(fmt, args...) printk(DHD_LOG_PREFIXS fmt , ## args) +#define printf(fmt, args...) printk(PERCENT_S DHD_LOG_PREFIXS fmt, PRINTF_SYSTEM_TIME, ## args) #include /* for vsn/printf's */ #include /* for mem*, str* */ /* bcopy's: Linux kernel doesn't provide these (anymore) */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linuxver.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linuxver.h index 734dda252f07..66f38d2c02a4 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linuxver.h @@ -623,12 +623,26 @@ typedef struct { /* ANDREY: new MACROs to start stop threads(OLD kthread API STYLE) */ /* requires tsk_ctl_t tsk argument, the caller's priv data is passed in owner ptr */ /* note this macro assumes there may be only one context waiting on thread's completion */ +#ifdef KERNEL_TIMESTAMP +extern char *dhd_log_dump_get_timestamp(void); +#ifdef SYSTEM_TIMESTAMP +extern char* dhd_dbg_get_system_timestamp(void); +#define PRINTF_SYSTEM_TIME dhd_log_dump_get_timestamp(), dhd_dbg_get_system_timestamp() +#define PERCENT_S "[%s][%s]" +#else +#define PRINTF_SYSTEM_TIME dhd_log_dump_get_timestamp() +#define PERCENT_S "[%s]" +#endif +#else +#define PRINTF_SYSTEM_TIME "" +#define PERCENT_S "%s" +#endif #ifndef DHD_LOG_PREFIX #define DHD_LOG_PREFIX "[dhd]" #endif #define DHD_LOG_PREFIXS DHD_LOG_PREFIX" " #ifdef DHD_DEBUG -#define printf_thr(fmt, args...) printk(DHD_LOG_PREFIXS fmt , ## args) +#define printf_thr(fmt, args...) printk(PERCENT_S DHD_LOG_PREFIXS fmt, PRINTF_SYSTEM_TIME, ## args) #define DBG_THR(args) do {printf_thr args;} while (0) #else #define DBG_THR(x) @@ -927,5 +941,21 @@ int kernel_read_compat(struct file *file, loff_t offset, char *addr, unsigned lo #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) #define netdev_tx_t int #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)) +#define complete_and_exit(a, b) kthread_complete_and_exit(a, b) +#else +#define dev_addr_set(net, addr) memcpy(net->dev_addr, addr, ETHER_ADDR_LEN) +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0) */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)) +#define netif_rx_ni(skb) netif_rx(skb) +#define pci_free_consistent(a, b, c, d) dma_free_coherent(&((struct pci_dev *)a)->dev, b, c, d) +#define pci_map_single(a, b, c, d) dma_map_single(&((struct pci_dev *)a)->dev, b, c, d) +#define pci_unmap_single(a, b, c, d) dma_unmap_single(&((struct pci_dev *)a)->dev, b, c, d) +#define pci_dma_mapping_error(a, b) dma_mapping_error(&((struct pci_dev *)a)->dev, b) +#ifndef PCI_DMA_TODEVICE +#define PCI_DMA_TODEVICE 1 +#define PCI_DMA_FROMDEVICE 2 +#endif +#endif #endif /* _linuxver_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_osl.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_osl.c index b88c03118f41..af52d836bf9f 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_osl.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_osl.c @@ -200,11 +200,11 @@ osl_dma_map_dump(osl_t *osh) osl_get_localtime(&ts_sec, &ts_usec); if (map_log && unmap_log) { - printk("%s: map_idx=%d unmap_idx=%d " + printf("%s: map_idx=%d unmap_idx=%d " "current time=[%5lu.%06lu]\n", __FUNCTION__, map_log->idx, unmap_log->idx, (unsigned long)ts_sec, (unsigned long)ts_usec); - printk("%s: dhd_map_log(pa)=0x%llx size=%d," + printf("%s: dhd_map_log(pa)=0x%llx size=%d," " dma_unmap_log(pa)=0x%llx size=%d\n", __FUNCTION__, (uint64)__virt_to_phys((ulong)(map_log->map)), (uint32)(sizeof(dhd_map_item_t) * map_log->items), @@ -253,7 +253,7 @@ osl_dma_map_logging(osl_t *osh, void *handle, dmaaddr_t pa, uint32 len) uint32 idx; if (log == NULL) { - printk("%s: log is NULL\n", __FUNCTION__); + printf("%s: log is NULL\n", __FUNCTION__); return; } @@ -277,14 +277,15 @@ osl_error(int bcmerror) /* Array bounds covered by ASSERT in osl_attach */ return linuxbcmerrormap[-bcmerror]; } + +osl_t * +osl_attach(void *pdev, uint bustype, bool pkttag #ifdef SHARED_OSL_CMN -osl_t * -osl_attach(void *pdev, uint bustype, bool pkttag, void **osl_cmn) -{ -#else -osl_t * -osl_attach(void *pdev, uint bustype, bool pkttag) + , void **osl_cmn +#endif /* SHARED_OSL_CMN */ +) { +#ifndef SHARED_OSL_CMN void **osl_cmn = NULL; #endif /* SHARED_OSL_CMN */ osl_t *osh; @@ -364,12 +365,12 @@ osl_attach(void *pdev, uint bustype, bool pkttag) #ifdef DHD_MAP_LOGGING osh->dhd_map_log = osl_dma_map_log_init(DHD_MAP_LOG_SIZE); if (osh->dhd_map_log == NULL) { - printk("%s: Failed to alloc dhd_map_log\n", __FUNCTION__); + printf("%s: Failed to alloc dhd_map_log\n", __FUNCTION__); } osh->dhd_unmap_log = osl_dma_map_log_init(DHD_MAP_LOG_SIZE); if (osh->dhd_unmap_log == NULL) { - printk("%s: Failed to alloc dhd_unmap_log\n", __FUNCTION__); + printf("%s: Failed to alloc dhd_unmap_log\n", __FUNCTION__); } #endif /* DHD_MAP_LOGGING */ @@ -490,7 +491,7 @@ osl_pci_read_config(osl_t *osh, uint offset, uint size) #ifdef BCMDBG if (retry < PCI_CFG_RETRY) - printk("PCI CONFIG READ access to %d required %d retries\n", offset, + printf("PCI CONFIG READ access to %d required %d retries\n", offset, (PCI_CFG_RETRY - retry)); #endif /* BCMDBG */ @@ -520,7 +521,7 @@ osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) #ifdef BCMDBG if (retry < PCI_CFG_RETRY) - printk("PCI CONFIG WRITE access to %d required %d retries\n", offset, + printf("PCI CONFIG WRITE access to %d required %d retries\n", offset, (PCI_CFG_RETRY - retry)); #endif /* BCMDBG */ } @@ -616,7 +617,7 @@ osl_malloc(osl_t *osh, uint size) if (i == STATIC_BUF_MAX_NUM) { OSL_STATIC_BUF_UNLOCK(&bcm_static_buf->static_lock, irq_flags); - printk("all static buff in use!\n"); + printf("all static buff in use!\n"); goto original; } @@ -809,7 +810,7 @@ osl_debug_malloc(osl_t *osh, uint size, int line, const char* file) const char* basename; unsigned long flags = 0; if (!size) { - printk("%s: allocating zero sized mem at %s line %d\n", __FUNCTION__, file, line); + printf("%s: allocating zero sized mem at %s line %d\n", __FUNCTION__, file, line); ASSERT(0); } @@ -876,7 +877,7 @@ osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, const char* file) p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); if (p->size == 0) { - printk("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n", + printf("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n", addr, size, line, file); prhex("bcm_mem_link_t", (void *)p, sizeof(*p)); ASSERT(p->size); @@ -884,19 +885,19 @@ osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, const char* file) } if (p->size != size) { - printk("%s: dealloca size does not match alloc size\n", __FUNCTION__); - printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); - printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file); + printf("%s: dealloca size does not match alloc size\n", __FUNCTION__); + printf("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); + printf("Alloc size %d line %d file %s\n", p->size, p->line, p->file); prhex("bcm_mem_link_t", (void *)p, sizeof(*p)); ASSERT(p->size == size); return; } if (osh && ((osl_t*)p->osh)->cmn != osh->cmn) { - printk("osl_debug_mfree: alloc osh %p does not match dealloc osh %p\n", + printf("osl_debug_mfree: alloc osh %p does not match dealloc osh %p\n", ((osl_t*)p->osh)->cmn, osh->cmn); - printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); - printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file); + printf("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); + printf("Alloc size %d line %d file %s\n", p->size, p->line, p->file); prhex("bcm_mem_link_t", (void *)p, sizeof(*p)); ASSERT(((osl_t*)p->osh)->cmn == osh->cmn); return; @@ -928,7 +929,7 @@ osl_debug_vmalloc(osl_t *osh, uint size, int line, const char* file) const char* basename; unsigned long flags = 0; if (!size) { - printk("%s: allocating zero sized mem at %s line %d\n", __FUNCTION__, file, line); + printf("%s: allocating zero sized mem at %s line %d\n", __FUNCTION__, file, line); ASSERT(0); } @@ -990,25 +991,25 @@ osl_debug_vmfree(osl_t *osh, void *addr, uint size, int line, const char* file) ASSERT(osh == NULL || osh->magic == OS_HANDLE_MAGIC); if (p->size == 0) { - printk("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n", + printf("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n", addr, size, line, file); ASSERT(p->size); return; } if (p->size != size) { - printk("%s: dealloca size does not match alloc size\n", __FUNCTION__); - printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); - printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file); + printf("%s: dealloca size does not match alloc size\n", __FUNCTION__); + printf("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); + printf("Alloc size %d line %d file %s\n", p->size, p->line, p->file); ASSERT(p->size == size); return; } if (osh && ((osl_t*)p->osh)->cmn != osh->cmn) { - printk("osl_debug_mfree: alloc osh %p does not match dealloc osh %p\n", + printf("osl_debug_mfree: alloc osh %p does not match dealloc osh %p\n", ((osl_t*)p->osh)->cmn, osh->cmn); - printk("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); - printk("Alloc size %d line %d file %s\n", p->size, p->line, p->file); + printf("Dealloc addr %p size %d at line %d file %s\n", addr, size, line, file); + printf("Alloc size %d line %d file %s\n", p->size, p->line, p->file); ASSERT(((osl_t*)p->osh)->cmn == osh->cmn); return; } @@ -1046,7 +1047,7 @@ osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b) if (b != NULL) bcm_bprintf(b, " Address Size File:line\n"); else - printk(" Address Size File:line\n"); + printf(" Address Size File:line\n"); for (p = osh->cmn->dbgmem_list; p; p = p->next) { if (b != NULL) @@ -1073,7 +1074,7 @@ osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b) if (b != NULL) bcm_bprintf(b, "Vmem\n Address Size File:line\n"); else - printk("Vmem\n Address Size File:line\n"); + printf("Vmem\n Address Size File:line\n"); for (p = osh->cmn->dbgvmem_list; p; p = p->next) { if (b != NULL) @@ -1204,7 +1205,7 @@ BCMFASTPATH(osl_dma_map)(osl_t *osh, void *va, uint size, int direction, void *p ret = pci_dma_mapping_error(osh->pdev, map_addr); if (ret) { - printk("%s: Failed to map memory\n", __FUNCTION__); + printf("%s: Failed to map memory\n", __FUNCTION__); PHYSADDRLOSET(ret_addr, 0); PHYSADDRHISET(ret_addr, 0); } else { @@ -1296,8 +1297,8 @@ osl_assert(const char *exp, const char *file, int line) /* Print assert message and give it time to be written to /var/log/messages */ if (!in_interrupt() && g_assert_type != 1 && g_assert_type != 3) { const int delay = 3; - printk("%s", tempbuf); - printk("panic in %d seconds\n", delay); + printf("%s", tempbuf); + printf("panic in %d seconds\n", delay); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(delay * HZ); } @@ -1305,16 +1306,16 @@ osl_assert(const char *exp, const char *file, int line) switch (g_assert_type) { case 0: - printk("%s", tempbuf); + printf("%s", tempbuf); BUG(); break; case 1: /* fall through */ case 3: - printk("%s", tempbuf); + printf("%s", tempbuf); break; case 2: - printk("%s", tempbuf); + printf("%s", tempbuf); BUG(); break; default: @@ -1516,11 +1517,11 @@ osl_printf(const char *format, ...) va_end(args); if (len > sizeof(printbuf)) { - printk("osl_printf: buffer overrun\n"); + printf("osl_printf: buffer overrun\n"); return (0); } - return (printk("%s", printbuf)); + return (printf("%s", printbuf)); } int @@ -1731,7 +1732,7 @@ osl_os_open_image(char *filename) * ??? */ if (IS_ERR(fp)) { - printk("ERROR %ld: Unable to open file %s\n", PTR_ERR(fp), filename); + printf("ERROR %ld: Unable to open file %s\n", PTR_ERR(fp), filename); fp = NULL; } @@ -1839,7 +1840,7 @@ osl_timer_init(osl_t *osh, const char *name, void (*fn)(void *arg), void *arg) osl_timer_t *t; BCM_REFERENCE(fn); if ((t = MALLOCZ(NULL, sizeof(osl_timer_t))) == NULL) { - printk(KERN_ERR "osl_timer_init: out of memory, malloced %d bytes\n", + printf(KERN_ERR "osl_timer_init: out of memory, malloced %d bytes\n", (int)sizeof(osl_timer_t)); return (NULL); } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_pkt.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_pkt.c index cb4dd05c1bfe..f32f8e450795 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_pkt.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_pkt.c @@ -73,12 +73,12 @@ int osl_static_mem_init(osl_t *osh, void *adapter) if (!bcm_static_buf && adapter) { if (!(bcm_static_buf = (bcm_static_buf_t *)wifi_platform_prealloc(adapter, DHD_PREALLOC_OSL_BUF, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) { - printk("can not alloc static buf!\n"); + printf("can not alloc static buf!\n"); bcm_static_skb = NULL; ASSERT(osh->magic == OS_HANDLE_MAGIC); return -ENOMEM; } else { - printk("succeed to alloc static buf\n"); + printf("succeed to alloc static buf\n"); } spin_lock_init(&bcm_static_buf->static_lock); @@ -93,7 +93,7 @@ int osl_static_mem_init(osl_t *osh, void *adapter) bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); skb_buff_ptr = wifi_platform_prealloc(adapter, DHD_PREALLOC_SKB_BUF, 0); if (!skb_buff_ptr) { - printk("cannot alloc static buf!\n"); + printf("cannot alloc static buf!\n"); bcm_static_buf = NULL; bcm_static_skb = NULL; ASSERT(osh->magic == OS_HANDLE_MAGIC); @@ -347,14 +347,14 @@ BCMFASTPATH(linux_pktfree)(osl_t *osh, void *p, bool send) #if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_CTRLBUF) if (skb && (skb->mac_len == PREALLOC_USED_MAGIC)) { - printk("%s: pkt %p is from static pool\n", + printf("%s: pkt %p is from static pool\n", __FUNCTION__, p); dump_stack(); return; } if (skb && (skb->mac_len == PREALLOC_FREE_MAGIC)) { - printk("%s: pkt %p is from static pool and not in used\n", + printf("%s: pkt %p is from static pool and not in used\n", __FUNCTION__, p); dump_stack(); return; @@ -409,7 +409,7 @@ osl_pktget_static(osl_t *osh, uint len) return linux_pktget(osh, len); if (len > DHD_SKB_MAX_BUFSIZE) { - printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); + printf("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); return linux_pktget(osh, len); } @@ -452,7 +452,7 @@ osl_pktget_static(osl_t *osh, uint len) } OSL_STATIC_PKT_UNLOCK(&bcm_static_skb->osl_pkt_lock, flags); - printk("%s: all static pkt in use!\n", __FUNCTION__); + printf("%s: all static pkt in use!\n", __FUNCTION__); return NULL; #else down(&bcm_static_skb->osl_pkt_sem); @@ -523,7 +523,7 @@ osl_pktget_static(osl_t *osh, uint len) #endif /* ENHANCED_STATIC_BUF */ up(&bcm_static_skb->osl_pkt_sem); - printk("%s: all static pkt in use!\n", __FUNCTION__); + printf("%s: all static pkt in use!\n", __FUNCTION__); return linux_pktget(osh, len); #endif /* DHD_USE_STATIC_CTRLBUF */ } @@ -552,14 +552,14 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) for (i = 0; i < STATIC_PKT_2PAGE_NUM; i++) { if (p == bcm_static_skb->skb_8k[i]) { if (bcm_static_skb->pkt_use[i] == 0) { - printk("%s: static pkt idx %d(%p) is double free\n", + printf("%s: static pkt idx %d(%p) is double free\n", __FUNCTION__, i, p); } else { bcm_static_skb->pkt_use[i] = 0; } if (skb->mac_len != PREALLOC_USED_MAGIC) { - printk("%s: static pkt idx %d(%p) is not in used\n", + printf("%s: static pkt idx %d(%p) is not in used\n", __FUNCTION__, i, p); } @@ -570,7 +570,7 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) } OSL_STATIC_PKT_UNLOCK(&bcm_static_skb->osl_pkt_lock, flags); - printk("%s: packet %p does not exist in the pool\n", __FUNCTION__, p); + printf("%s: packet %p does not exist in the pool\n", __FUNCTION__, p); #else down(&bcm_static_skb->osl_pkt_sem); for (i = 0; i < STATIC_PKT_1PAGE_NUM; i++) { @@ -685,7 +685,7 @@ 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 - printk(" Total %d sbk not free\n", osh->ctrace_num); + printf(" Total %d sbk not free\n", osh->ctrace_num); list_for_each_entry(skb, &osh->ctrace_list, ctrace_list) { if (b != NULL) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.c index 3741f4c216cf..ae863e1f653c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.c @@ -93,19 +93,19 @@ uint android_msg_level = ANDROID_ERROR_LEVEL | ANDROID_MSG_LEVEL; #define ANDROID_ERROR_MSG(x, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIXS "ANDROID-ERROR) " x, ## args); \ + printf("ANDROID-ERROR) " x, ## args); \ } \ } while (0) #define ANDROID_TRACE_MSG(x, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "ANDROID-TRACE) " x, ## args); \ + printf("ANDROID-TRACE) " x, ## args); \ } \ } while (0) #define ANDROID_INFO_MSG(x, args...) \ do { \ if (android_msg_level & ANDROID_INFO_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "ANDROID-INFO) " x, ## args); \ + printf("ANDROID-INFO) " x, ## args); \ } \ } while (0) #define ANDROID_ERROR(x) ANDROID_ERROR_MSG x @@ -4901,10 +4901,10 @@ 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); + if (ret) + goto retry_power; #endif /* BCMSDIO */ -#ifdef BCMPCIE ret = dhd_net_bus_devreset(dev, FALSE); -#endif /* BCMPCIE */ #ifdef WBRC if (dhdp->dhd_induce_bh_error == DHD_INDUCE_BH_ON_FAIL_ONCE) { ANDROID_ERROR(("%s: dhd_induce_bh_error = %d\n", @@ -4921,14 +4921,30 @@ int wl_android_wifi_on(struct net_device *dev) ret = BCME_ERROR; } #endif /* WBRC */ + if (ret) + goto retry_power; +#if defined(BCMSDIO) || defined(BCMDBUS) +#ifdef BCMSDIO + dhd_net_bus_resume(dev, 1); +#endif /* BCMSDIO */ + ret = dhd_dev_init_ioctl(dev); + if (ret < 0) { + goto retry_bus; + } +#endif /* BCMSDIO || BCMDBUS */ if (ret == 0) { break; } +#if defined(BCMSDIO) || defined(BCMDBUS) +retry_bus: +#ifdef BCMSDIO + dhd_net_bus_suspend(dev); +#endif /* BCMSDIO */ +#endif /* BCMSDIO || BCMDBUS */ +retry_power: ANDROID_ERROR(("failed to power up wifi chip, retry again (%d left) **\n\n", retry)); -#ifdef BCMPCIE dhd_net_bus_devreset(dev, TRUE); -#endif /* BCMPCIE */ dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY); #ifdef WBRC /* Inform BT reset which will internally wait till BT reset is done */ @@ -4944,41 +4960,16 @@ int wl_android_wifi_on(struct net_device *dev) #endif /* BCM_DETECT_TURN_ON_FAILURE */ goto exit; } -#if defined(BCMSDIO) || defined(BCMDBUS) - ret = dhd_net_bus_devreset(dev, FALSE); - if (ret) - goto err; -#ifdef BCMSDIO - dhd_net_bus_resume(dev, 1); -#endif /* BCMSDIO */ -#endif /* BCMSDIO || BCMDBUS */ -#if defined(BCMSDIO) || defined(BCMDBUS) - if (!ret) { - if (dhd_dev_init_ioctl(dev) < 0) { - ret = -EFAULT; - goto err; - } - } -#endif /* BCMSDIO || BCMDBUS */ g_wifi_on = TRUE; } exit: - WL_MSG(dev->name, "Success\n"); + if (ret) + WL_MSG(dev->name, "Failed %d\n", ret); + else + WL_MSG(dev->name, "Success\n"); dhd_net_if_unlock(dev); return ret; - -#if defined(BCMSDIO) || defined(BCMDBUS) -err: - dhd_net_bus_devreset(dev, TRUE); -#ifdef BCMSDIO - dhd_net_bus_suspend(dev); -#endif /* BCMSDIO */ - dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY); - WL_MSG(dev->name, "Failed\n"); - dhd_net_if_unlock(dev); - return ret; -#endif /* BCMSDIO || BCMDBUS */ } int wl_android_wifi_off(struct net_device *dev, bool on_failure) @@ -13372,7 +13363,7 @@ wl_cfg80211_static_if_open(struct net_device *net) if (cfg->static_ndev_state[static_ifidx] != NDEV_STATE_FW_IF_CREATED) { #ifdef CUSTOM_MULTI_MAC if (!wifi_platform_get_mac_addr(dhd->info->adapter, hw_ether, static_ifidx+1)) - memcpy(net->dev_addr, hw_ether, ETHER_ADDR_LEN); + dev_addr_set(net, hw_ether); #endif wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, net->dev_addr); if (!wdev) { @@ -13424,7 +13415,7 @@ wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211 *cfg, wdev = new_ndev->ieee80211_ptr; ASSERT(wdev); wdev->iftype = iface_type; - (void)memcpy_s(new_ndev->dev_addr, ETH_ALEN, addr, ETH_ALEN); + dev_addr_set(new_ndev, addr); } cfg->static_ndev_state[static_ifidx] = NDEV_STATE_FW_IF_CREATED; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.h index 5887c473e20f..cdd34b9164cc 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef WL_EXT_IAPSTA #ifdef WL_ESCAN #include @@ -42,7 +43,6 @@ #endif #include #endif -#include /* If any feature uses the Generic Netlink Interface, put it here to enable WL_GENL * automatically @@ -87,7 +87,7 @@ typedef struct _compat_android_wifi_priv_cmd { #define WL_MSG(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_MSG_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] %s : " arg1, name, __func__, ## args); \ + printf("[%s] %s : " arg1, name, __func__, ## args); \ } \ } while (0) @@ -105,7 +105,7 @@ do { \ memcmp(&static_tmp, cmp, size)) { \ __err_ts = __cur_ts; \ memcpy(static_tmp, cmp, size); \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] %s : [%u times] " arg1, \ + printf("[%s] %s : [%u times] " arg1, \ name, __func__, __err_cnt, ## args); \ __err_cnt = 0; \ } else { \ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c index 5bba057eb258..4b884dfc5427 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c @@ -35,25 +35,25 @@ #define AEXT_ERROR(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] AEXT-ERROR) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AEXT-ERROR) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define AEXT_TRACE(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] AEXT-TRACE) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AEXT-TRACE) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define AEXT_INFO(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_INFO_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] AEXT-INFO) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AEXT-INFO) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define AEXT_DBG(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_DBG_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] AEXT-DBG) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AEXT-DBG) %s : " arg1, name, __func__, ## args); \ } \ } while (0) @@ -163,22 +163,23 @@ typedef struct auth_name_map_t { const auth_name_map_t auth_name_map[] = { {WL_AUTH_OPEN_SYSTEM, WPA_AUTH_DISABLED, "open"}, {WL_AUTH_SHARED_KEY, WPA_AUTH_DISABLED, "shared"}, - {WL_AUTH_OPEN_SYSTEM, WPA_AUTH_PSK, "wpapsk"}, - {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_PSK, "wpa2psk"}, - {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa2psksha256"}, - {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_FT|WPA2_AUTH_PSK, "wpa2psk-ft"}, - {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_UNSPECIFIED, "wpa2eap"}, - {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_FT|WPA2_AUTH_UNSPECIFIED, "wpa2eap-ft"}, - {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK, "wpa3psk"}, - {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK, "wpa3psk"}, - {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK, "wpa3psk"}, - {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK, "wpa3psk"}, - {WL_AUTH_OPEN_SYSTEM, 0x20, "wpa3psk"}, - {WL_AUTH_SAE_KEY, 0x20, "wpa3psk"}, - {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3psksha256"}, - {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3psksha256"}, - {WL_AUTH_OPEN_SYSTEM, 0x20|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3psksha256"}, - {WL_AUTH_SAE_KEY, 0x20|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3psksha256"}, + {WL_AUTH_OPEN_SYSTEM, WPA_AUTH_PSK, "wpa/psk"}, + {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_PSK, "wpa2/psk"}, + {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa2/psk/sha256"}, + {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_FT|WPA2_AUTH_PSK, "wpa2/psk/ft"}, + {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_UNSPECIFIED, "wpa2/eap"}, + {WL_AUTH_OPEN_SYSTEM, WPA2_AUTH_FT|WPA2_AUTH_UNSPECIFIED, "wpa2/eap/ft"}, + {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK, "wpa3/psk"}, + {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK, "wpa3sae/psk"}, + {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK, "wpa3/psk"}, + {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK, "wpa3sae/psk"}, + {WL_AUTH_OPEN_SYSTEM, 0x20, "wpa3/psk"}, + {WL_AUTH_SAE_KEY, 0x20, "wpa3sae/psk"}, + {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3/psk/sha256"}, + {WL_AUTH_SAE_KEY, WPA3_AUTH_SAE_PSK|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3sae/psk/sha256"}, + {WL_AUTH_OPEN_SYSTEM, 0x20|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3/psk/sha256"}, + {WL_AUTH_SAE_KEY, 0x20|WPA2_AUTH_PSK_SHA256|WPA2_AUTH_PSK, "wpa3sae/psk/sha256"}, + {WL_AUTH_OPEN_SYSTEM, WPA3_AUTH_OWE, "owe"}, }; typedef struct wsec_name_map_t { @@ -191,7 +192,7 @@ const wsec_name_map_t wsec_name_map[] = { {WEP_ENABLED, "wep"}, {TKIP_ENABLED, "tkip"}, {AES_ENABLED, "aes"}, - {TKIP_ENABLED|AES_ENABLED, "tkipaes"}, + {TKIP_ENABLED|AES_ENABLED, "tkip/aes"}, }; static int wl_ext_wl_iovar(struct net_device *dev, char *command, int total_len); @@ -409,6 +410,29 @@ wl_ext_chspec_driver_to_host(int ioctl_ver, chanspec_t chanspec) } #endif /* WL_EXT_IAPSTA || WL_CFG80211 || WL_ESCAN */ +chanspec_band_t +wl_ext_wlcband_to_chanspec_band(int band) +{ + chanspec_band_t chanspec_band = WLC_BAND_INVALID; + + switch (band) { +#ifdef WL_6G_BAND + case WLC_BAND_6G: + chanspec_band = WL_CHANSPEC_BAND_6G; + break; +#endif /* WL_6G_BAND */ + case WLC_BAND_5G: + chanspec_band = WL_CHANSPEC_BAND_5G; + break; + case WLC_BAND_2G: + chanspec_band = WL_CHANSPEC_BAND_2G; + break; + default: + break; + } + return chanspec_band; +} + bool wl_ext_check_scan(struct net_device *dev, dhd_pub_t *dhdp) { @@ -584,10 +608,10 @@ wl_ext_bss_iovar_war(struct net_device *ndev, s32 *val) } int -wl_ext_set_chanspec(struct net_device *dev, int ioctl_ver, - uint16 channel, chanspec_t *ret_chspec) +wl_ext_set_chanspec(struct net_device *dev, struct wl_chan_info *chan_info, + chanspec_t *ret_chspec) { - s32 _chan = channel; + s32 _chan = chan_info->chan; chanspec_t chspec = 0; chanspec_t fw_chspec = 0; u32 bw = WL_CHANSPEC_BW_20; @@ -598,53 +622,53 @@ wl_ext_set_chanspec(struct net_device *dev, int ioctl_ver, u32 band; u32 bw_cap; } param = {0, 0}; - uint band; + chanspec_band_t chanspec_band = 0; + int ioctl_ver; - if (_chan <= CH_MAX_2G_CHANNEL) - band = IEEE80211_BAND_2GHZ; - else - band = IEEE80211_BAND_5GHZ; - - if (band == IEEE80211_BAND_5GHZ) { - param.band = WLC_BAND_5G; - err = wl_ext_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - if (err) { - if (err != BCME_UNSUPPORTED) { - AEXT_ERROR(dev->name, "bw_cap failed, %d\n", err); - return err; - } else { - err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap); - if (bw_cap != WLC_N_BW_20ALL) - bw = WL_CHANSPEC_BW_40; - } - } else { - if (WL_BW_CAP_80MHZ(iovar_buf[0])) - bw = WL_CHANSPEC_BW_80; - else if (WL_BW_CAP_40MHZ(iovar_buf[0])) - bw = WL_CHANSPEC_BW_40; - else - bw = WL_CHANSPEC_BW_20; - - } + if ((chan_info->band != WLC_BAND_2G) && (chan_info->band != WLC_BAND_5G) && + (chan_info->band != WLC_BAND_6G)) { + AEXT_ERROR(dev->name, "bad band %d\n", chan_info->band); + return BCME_BADBAND; + } + + param.band = chan_info->band; + err = wl_ext_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + if (err) { + if (err != BCME_UNSUPPORTED) { + AEXT_ERROR(dev->name, "bw_cap failed, %d\n", err); + return err; + } else { + err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap); + if (bw_cap != WLC_N_BW_20ALL) + bw = WL_CHANSPEC_BW_40; + } + } else { + if (WL_BW_CAP_80MHZ(iovar_buf[0])) + bw = WL_CHANSPEC_BW_80; + else if (WL_BW_CAP_40MHZ(iovar_buf[0])) + bw = WL_CHANSPEC_BW_40; + else + bw = WL_CHANSPEC_BW_20; } - else if (band == IEEE80211_BAND_2GHZ) - bw = WL_CHANSPEC_BW_20; set_channel: - chspec = wf_channel2chspec(_chan, bw); + chanspec_band = wl_ext_wlcband_to_chanspec_band(chan_info->band); + chspec = wf_create_chspec_from_primary(chan_info->chan, bw, chanspec_band); if (wf_chspec_valid(chspec)) { + wl_ext_get_ioctl_ver(dev, &ioctl_ver); fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec); if (fw_chspec != INVCHANSPEC) { if ((err = wl_ext_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) { if (bw == WL_CHANSPEC_BW_80) goto change_bw; err = wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1); - WL_MSG(dev->name, "channel %d\n", _chan); + WL_MSG(dev->name, "channel %s-%d\n", CHSPEC2BANDSTR(chspec), _chan); } else if (err) { AEXT_ERROR(dev->name, "failed to set chanspec error %d\n", err); } else - WL_MSG(dev->name, "channel %d, 0x%x\n", channel, chspec); + WL_MSG(dev->name, "channel %s-%d(0x%x)\n", + CHSPEC2BANDSTR(chspec), chan_info->chan, chspec); } else { AEXT_ERROR(dev->name, "failed to convert host chanspec to fw chanspec\n"); err = BCME_ERROR; @@ -670,20 +694,35 @@ change_bw: static int wl_ext_channel(struct net_device *dev, char* command, int total_len) { + struct wl_chan_info chan_info; int ret; - int channel=0; + char band[16]=""; + int channel = 0; channel_info_t ci; int bytes_written = 0; chanspec_t fw_chspec; - int ioctl_ver = 0; AEXT_TRACE(dev->name, "cmd %s", command); - sscanf(command, "%*s %d", &channel); + sscanf(command, "%*s %d %s", &channel, band); + if (strnicmp(band, "band=auto", strlen("band=auto")) == 0) { + chan_info.band = WLC_BAND_AUTO; + } +#ifdef WL_6G_BAND + else if (strnicmp(band, "band=6g", strlen("band=6g")) == 0) { + chan_info.band = WLC_BAND_6G; + } +#endif /* WL_6G_BAND */ + else if (strnicmp(band, "band=5g", strlen("band=5g")) == 0) { + chan_info.band = WLC_BAND_5G; + } + else if (strnicmp(band, "band=2g", strlen("band=2g")) == 0) { + chan_info.band = WLC_BAND_2G; + } if (channel > 0) { - wl_ext_get_ioctl_ver(dev, &ioctl_ver); - ret = wl_ext_set_chanspec(dev, ioctl_ver, channel, &fw_chspec); + chan_info.chan = channel; + ret = wl_ext_set_chanspec(dev, &chan_info, &fw_chspec); } else { if (!(ret = wl_ext_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) { @@ -835,7 +874,7 @@ wl_ext_connect(struct net_device *dev, struct wl_conn_info *conn_info) u32 chan_cnt = 0; s8 *iovar_buf = NULL; int ioctl_ver = 0; - char sec[32]; + char sec[64]; wl_ext_get_ioctl_ver(dev, &ioctl_ver); @@ -1041,9 +1080,9 @@ wl_ext_get_sec(struct net_device *dev, int ifmode, char *sec, int total_len, boo } bool -wl_ext_dfs_chan(uint16 chan) +wl_ext_dfs_chan(struct wl_chan_info *chan_info) { - if (chan >= 52 && chan <= 144) + if (chan_info->band == WLC_BAND_5G && chan_info->chan >= 52 && chan_info->chan <= 144) return TRUE; return FALSE; } @@ -1053,6 +1092,7 @@ wl_ext_get_default_chan(struct net_device *dev, uint16 *chan_2g, uint16 *chan_5g, bool nodfs) { struct dhd_pub *dhd = dhd_get_pub(dev); + struct wl_chan_info chan_info; uint16 chan_tmp = 0, chan = 0; wl_uint32_list_t *list; u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; @@ -1074,7 +1114,9 @@ wl_ext_get_default_chan(struct net_device *dev, if (chan_tmp <= 13 && !*chan_2g) { *chan_2g = chan_tmp; } else if (chan_tmp >= 36 && chan_tmp <= 161 && !*chan_5g) { - if (wl_ext_dfs_chan(chan_tmp) && nodfs) + chan_info.band = WLC_BAND_5G; + chan_info.chan = chan_tmp; + if (wl_ext_dfs_chan(&chan_info) && nodfs) continue; else *chan_5g = chan_tmp; @@ -2592,7 +2634,7 @@ wl_ext_get_country(struct net_device *dev, char *data, char *command, if (data) { char *country_code = data; char *rev_info_delim = country_code + 2; /* 2 bytes of country code */ - int revinfo = -1; + int revinfo = 0; if ((rev_info_delim) && (strnicmp(rev_info_delim, "/", strlen("/")) == 0) && (rev_info_delim + 1)) { revinfo = bcm_atoi(rev_info_delim + 1); @@ -2686,6 +2728,7 @@ wl_ext_wl_iovar(struct net_device *dev, char *command, int total_len) int bytes_written=-1; const wl_ext_iovar_tpl_t *tpl = wl_ext_iovar_tpl_list; int tpl_count = ARRAY_SIZE(wl_ext_iovar_tpl_list); + char *pEnd; AEXT_TRACE(dev->name, "cmd %s\n", command); pick_tmp = command; @@ -2699,14 +2742,14 @@ wl_ext_wl_iovar(struct net_device *dev, char *command, int total_len) goto exit; memset(name, 0 , sizeof (name)); - cmd = (int)simple_strtol(pch, NULL, 0); - if (cmd == 0) { + cmd = bcm_strtoul(pch, &pEnd, 0); + if (cmd == 0 || strlen(pEnd)) { strcpy(name, pch); } data = bcmstrtok(&pick_tmp, "", 0); // pick data - if (data && cmd == 0) { + if (data && (cmd == 0|| strlen(pEnd))) { cmd = WLC_SET_VAR; - } else if (cmd == 0) { + } else if (cmd == 0|| strlen(pEnd)) { cmd = WLC_GET_VAR; } @@ -2884,6 +2927,85 @@ wl_android_ext_priv_cmd(struct net_device *net, char *command, return ret; } +#define CH_MIN_5G_CHANNEL 34 +int +wl_construct_ctl_chanspec_list(struct net_device *dev, wl_uint32_list_t *chan_list) +{ + void *list; + u32 i, channel; + chanspec_t chspec = 0; + s32 err = BCME_OK; + bool legacy_chan_info = FALSE; + u16 list_count; + +#define LOCAL_BUF_LEN 4096 + list = kmalloc(LOCAL_BUF_LEN, GFP_KERNEL); + if (list == NULL) { + WL_ERR(("failed to allocate local buf\n")); + return -ENOMEM; + } + + err = wl_ext_iovar_getbuf(dev, "chan_info_list", NULL, + 0, list, LOCAL_BUF_LEN, NULL); + if (err == BCME_UNSUPPORTED) { + err = wl_ext_iovar_getbuf(dev, "chanspecs", NULL, + 0, list, LOCAL_BUF_LEN, NULL); + if (err != BCME_OK) { + WL_ERR(("get chanspecs err(%d)\n", err)); + kfree(list); + return err; + } + /* Update indicating legacy chan info usage */ + legacy_chan_info = TRUE; + } else if (err != BCME_OK) { + WL_ERR(("get chan_info_list err(%d)\n", err)); + kfree(list); + return err; + } + + list_count = legacy_chan_info ? ((wl_uint32_list_t *)list)->count : + ((wl_chanspec_list_v1_t *)list)->count; + for (i = 0; i < dtoh32(list_count); i++) { + if (legacy_chan_info) { + chspec = (chanspec_t)dtoh32(((wl_uint32_list_t *)list)->element[i]); + } else { + chspec = (chanspec_t)dtoh32 + (((wl_chanspec_list_v1_t *)list)->chspecs[i].chanspec); + } + chspec = wl_chspec_driver_to_host(chspec); + channel = wf_chspec_ctlchan(chspec); + + if (!CHSPEC_IS20(chspec)) { + continue; + } + if (CHSPEC_IS2G(chspec) && (channel >= CH_MIN_2G_CHANNEL) && + (channel <= CH_MAX_2G_CHANNEL)) { + chan_list->element[chan_list->count] = chspec; + chan_list->count++; + } +#ifdef WL_6G_BAND + else if (CHSPEC_IS6G(chspec) && (channel >= CH_MIN_6G_CHANNEL) && + (channel <= CH_MAX_6G_CHANNEL)) { + if (channel == 2) + continue; + chan_list->element[chan_list->count] = chspec; + chan_list->count++; + } +#endif /* WL_6G_BAND */ + else if (CHSPEC_IS5G(chspec) && (channel >= CH_MIN_5G_CHANNEL) && + (channel <= 165)) { + chan_list->element[chan_list->count] = chspec; + chan_list->count++; + } else { + continue; + } + } + + kfree(list); +#undef LOCAL_BUF_LEN + return err; +} + #if defined(WL_CFG80211) || defined(WL_ESCAN) int wl_ext_get_distance(struct net_device *net, u32 band) @@ -2938,8 +3060,7 @@ wl_ext_get_best_channel(struct net_device *net, #else wl_scan_results_t *bss_list, #endif /* BSSCACHE */ - int ioctl_ver, int *best_2g_ch, int *best_5g_ch -) + int ioctl_ver, int *best_2g_ch, int *best_5g_ch, int *best_6g_ch) { struct wl_bss_info *bi = NULL; /* must be initialized */ s32 i, j; @@ -2947,41 +3068,69 @@ wl_ext_get_best_channel(struct net_device *net, wl_bss_cache_t *node; #endif /* BSSCACHE */ int b_band[CH_MAX_2G_CHANNEL]={0}, a_band1[4]={0}, a_band4[5]={0}; - s32 cen_ch, distance, distance_2g, distance_5g, ch, min_ap=999; - u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; +#ifdef WL_6G_BAND + int six_g_band5[24]={0}, six_g_band6[5]={0}, six_g_band7[18]={0}, six_g_band8[13]={0}; + s32 distance_6g; +#endif /* WL_6G_BAND */ + s32 cen_ch, distance, distance_2g, distance_5g, chanspec, min_ap=999; + u8 valid_chan_list[sizeof(u32)*(MAX_CTRL_CHANSPECS + 1)]; wl_uint32_list_t *list; int ret; - chanspec_t chanspec; - struct dhd_pub *dhd = dhd_get_pub(net); + chanspec_t chspec; + u32 channel; memset(b_band, -1, sizeof(b_band)); memset(a_band1, -1, sizeof(a_band1)); memset(a_band4, -1, sizeof(a_band4)); +#ifdef WL_6G_BAND + memset(six_g_band5, -1, sizeof(six_g_band5)); + memset(six_g_band6, -1, sizeof(six_g_band6)); + memset(six_g_band7, -1, sizeof(six_g_band7)); + memset(six_g_band8, -1, sizeof(six_g_band8)); +#endif /* WL_6G_BAND */ memset(valid_chan_list, 0, sizeof(valid_chan_list)); list = (wl_uint32_list_t *)(void *) valid_chan_list; - list->count = htod32(WL_NUMCHANNELS); - ret = wl_ext_ioctl(net, WLC_GET_VALID_CHANNELS, &valid_chan_list, - sizeof(valid_chan_list), 0); - if (ret<0) { + + ret = wl_construct_ctl_chanspec_list(net, list); + if (ret < 0) { AEXT_ERROR(net->name, "get channels failed with %d\n", ret); return 0; } else { - for (i = 0; i < dtoh32(list->count); i++) { - ch = dtoh32(list->element[i]); - if (!dhd_conf_match_channel(dhd, ch)) - continue; - if (ch < CH_MAX_2G_CHANNEL) - b_band[ch-1] = 0; - else if (ch <= 48) - a_band1[(ch-36)/4] = 0; - else if (ch >= 149 && ch <= 161) - a_band4[(ch-149)/4] = 0; + for (i = 0; i < list->count; i++) { + chspec = list->element[i]; + channel = wf_chspec_ctlchan(chspec); + if (CHSPEC_IS2G(chspec) && (channel >= CH_MIN_2G_CHANNEL) && + (channel <= CH_MAX_2G_CHANNEL)) { + b_band[channel-1] = 0; + } +#ifdef WL_6G_BAND + else if (CHSPEC_IS6G(chspec) && (channel >= CH_MIN_6G_CHANNEL) && + (channel <= CH_MAX_6G_CHANNEL)) { + if (channel <= 93) + six_g_band5[(channel-1)/4] = 0; + else if (channel >= 97 && channel <= 109) + six_g_band6[(channel-97)/4] = 0; + else if (channel >= 117 && channel <= 181) + six_g_band7[(channel-117)/4] = 0; + else if (channel >= 189 && channel <= 221) + six_g_band8[(channel-189)/4] = 0; + } +#endif /* WL_6G_BAND */ + else if (CHSPEC_IS5G(chspec) && channel >= CH_MIN_5G_CHANNEL) { + if (channel <= 48) + a_band1[(channel-36)/4] = 0; + else if (channel >= 149 && channel <= 161) + a_band4[(channel-149)/4] = 0; + } } } distance_2g = wl_ext_get_distance(net, WLC_BAND_2G); distance_5g = wl_ext_get_distance(net, WLC_BAND_5G); +#ifdef WL_6G_BAND + distance_6g = wl_ext_get_distance(net, WLC_BAND_6G); +#endif /* WL_6G_BAND */ #if defined(BSSCACHE) node = bss_cache_ctrl->m_cache_head; @@ -3013,14 +3162,45 @@ wl_ext_get_best_channel(struct net_device *net, if (b_band[j] >= 0 && abs(cen_ch-(1+j)) <= distance) b_band[j] += 1; } - } else { + } +#ifdef WL_6G_BAND + else if (CHSPEC_IS6G(chanspec)) { + distance += distance_6g; + if (cen_ch <= 93) { + for (j=0; j= 0 && abs(cen_ch-(93+j*4)) <= distance) + six_g_band5[j] += 1; + } + } + else if (channel >= 97 && channel <= 109) { + for (j=0; j= 0 && abs(cen_ch-(97+j*4)) <= distance) + six_g_band6[j] += 1; + } + } + else if (channel >= 117 && channel <= 181) { + for (j=0; j= 0 && abs(cen_ch-(117+j*4)) <= distance) + six_g_band7[j] += 1; + } + } + else if (channel >= 189 && channel <= 221) { + for (j=0; j= 0 && abs(cen_ch-(189+j*4)) <= distance) + six_g_band8[j] += 1; + } + } + } +#endif /* WL_6G_BAND */ + else { distance += distance_5g; if (cen_ch <= 48) { for (j=0; j= 0 && abs(cen_ch-(36+j*4)) <= distance) a_band1[j] += 1; } - } else if (cen_ch >= 149) { + } + else if (cen_ch >= 149) { for (j=0; j= 0 && abs(cen_ch-(149+j*4)) <= distance) a_band4[j] += 1; @@ -3054,27 +3234,80 @@ wl_ext_get_best_channel(struct net_device *net, *best_5g_ch = i*4 + 149; } } +#ifdef WL_6G_BAND + *best_6g_ch = 0; + min_ap = 999; + for (i=0; i= 0) { + min_ap = six_g_band5[i]; + *best_6g_ch = i*4 + 1; + } + } + for (i=0; i= 0) { + min_ap = six_g_band6[i]; + *best_6g_ch = i*4 + 97; + } + } + for (i=0; i= 0) { + min_ap = six_g_band7[i]; + *best_6g_ch = i*4 + 117; + } + } + for (i=0; i= 0) { + min_ap = six_g_band8[i]; + *best_6g_ch = i*4 + 189; + } + } +#endif /* WL_6G_BAND */ if (android_msg_level & ANDROID_INFO_LEVEL) { struct bcmstrbuf strbuf; char *tmp_buf = NULL; - tmp_buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL); + tmp_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); if (tmp_buf == NULL) { AEXT_ERROR(net->name, "Failed to allocate buffer of %d bytes\n", WLC_IOCTL_SMLEN); goto exit; } - bcm_binit(&strbuf, tmp_buf, WLC_IOCTL_SMLEN); + bcm_binit(&strbuf, tmp_buf, WLC_IOCTL_MEDLEN); + bcm_bprintf(&strbuf, "2g: "); for (j=0; jname, "\n%s", strbuf.origbuf); if (tmp_buf) { kfree(tmp_buf); @@ -3094,6 +3327,7 @@ wl_ext_fw_apcs(struct net_device *dev, uint32 band) int channel = 0, chosen = 0, retry = 0, ret = 0, spect = 0; u8 *reqbuf = NULL; uint32 buf_size; + chanspec_band_t acs_band = WLC_BAND_INVALID; ret = wldev_ioctl_get(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect)); if (ret) { @@ -3116,35 +3350,20 @@ wl_ext_fw_apcs(struct net_device *dev, uint32 band) } memset(reqbuf, 0, CHANSPEC_BUF_SIZE); - if (band == WLC_BAND_AUTO) { - AEXT_INFO(dev->name, "ACS full channel scan \n"); - reqbuf[0] = htod32(0); - } else if (band == WLC_BAND_5G) { - AEXT_INFO(dev->name, "ACS 5G band scan \n"); - ret = wl_android_get_band_chanspecs(dev, (void *)reqbuf, CHANSPEC_BUF_SIZE, - WL_CHANSPEC_BAND_5G, false); - if (ret < 0) { - AEXT_ERROR(dev->name, "ACS 5g chanspec retreival failed! \n"); - goto done; - } - } else if (band == WLC_BAND_2G) { - /* - * If channel argument is not provided/ argument 20 is provided, - * Restrict channel to 2GHz, 20MHz BW, No SB - */ - AEXT_INFO(dev->name, "ACS 2G band scan \n"); - ret = wl_android_get_band_chanspecs(dev, (void *)reqbuf, CHANSPEC_BUF_SIZE, - WL_CHANSPEC_BAND_2G, false); - if (ret < 0) { - AEXT_ERROR(dev->name, "ACS 2g chanspec retreival failed! \n"); - goto done; - } - } else { - AEXT_ERROR(dev->name, "ACS: No band chosen\n"); + acs_band = wl_ext_wlcband_to_chanspec_band(band); + if ((uint32)acs_band == WLC_BAND_INVALID) { + acs_band = WL_CHANSPEC_BAND_2G; + } + + if ((ret = wl_android_get_band_chanspecs(dev, reqbuf, CHANSPEC_BUF_SIZE, + acs_band, true)) < 0) { + WL_ERR(("ACS chanspec retrieval failed!\n")); goto done; } - buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE; + AEXT_INFO(dev->name, "ACS chanspec band 0x%x\n", acs_band); + + buf_size = CHANSPEC_BUF_SIZE; ret = wldev_ioctl_set(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf, buf_size); if (ret < 0) { @@ -3154,7 +3373,7 @@ wl_ext_fw_apcs(struct net_device *dev, uint32 band) } /* Wait for auto channel selection, max 3000 ms */ - if ((band == WLC_BAND_2G) || (band == WLC_BAND_5G)) { + if ((band == WLC_BAND_2G) || (band == WLC_BAND_5G) || (band == WLC_BAND_6G)) { OSL_SLEEP(500); } else { /* @@ -3174,24 +3393,12 @@ wl_ext_fw_apcs(struct net_device *dev, uint32 band) chosen = dtoh32(chosen); } - if (chosen) { - int chosen_band; - int apcs_band; -#ifdef D11AC_IOTYPES - if (wl_cfg80211_get_ioctl_version() == 1) { - channel = LCHSPEC_CHANNEL((chanspec_t)chosen); - } else { - channel = CHSPEC_CHANNEL((chanspec_t)chosen); - } -#else - channel = CHSPEC_CHANNEL((chanspec_t)chosen); -#endif /* D11AC_IOTYPES */ - apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band; - chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G; - if (apcs_band == chosen_band) { - WL_MSG(dev->name, "selected channel = %d\n", channel); - break; - } + if (wf_chspec_valid((chanspec_t)chosen)) { + channel = wf_chspec_ctlchan((chanspec_t)chosen); + acs_band = CHSPEC_BAND((chanspec_t)chosen); + WL_MSG(dev->name, "selected channel = %d(band %d)\n", + channel, CHSPEC2WLC_BAND((chanspec_t)chosen)); + break; } AEXT_INFO(dev->name, "%d tried, ret = %d, chosen = 0x%x\n", (APCS_MAX_RETRY - retry), ret, chosen); @@ -3228,18 +3435,35 @@ wl_ext_drv_scan(struct net_device *dev, uint32 band, bool fast_scan) } memset(&scan_info, 0, sizeof(wl_scan_info_t)); if (band == WLC_BAND_2G || band == WLC_BAND_AUTO) { - for (i=0; i<13; i++) - scan_info.channels.channel[i] = i + 1; + for (i=0; i<13; i++) { + scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(i+1, + WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G); + } cnt += 13; } if (band == WLC_BAND_5G || band == WLC_BAND_AUTO) { - for (i=0; i<4; i++) - scan_info.channels.channel[i+cnt] = 36 + i*4; + for (i=0; i<4; i++) { + scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(36+i*4, + WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G); + } cnt += 4; - for (i=0; i<4; i++) - scan_info.channels.channel[i+cnt] = 149 + i*4; + for (i=0; i<4; i++) { + scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(149+i*4, + WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G); + } cnt += 4; } +#ifdef WL_6G_BAND + if (band == WLC_BAND_6G || band == WLC_BAND_AUTO) { + for (i=0; i<59; i++) { + scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(1+i*4, + WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_6G); + } + cnt += 59; + } +#endif /* WL_6G_BAND */ + if (band == WLC_BAND_2G) + fast_scan = FALSE; scan_info.channels.count = cnt; if (fast_scan) scan_info.scan_time = 40; @@ -3279,6 +3503,10 @@ wl_ext_drv_apcs(struct net_device *dev, uint32 band) if (escan->escan_state == ESCAN_STATE_IDLE) { if (band == WLC_BAND_5G) channel = escan->best_5g_ch; +#ifdef WL_6G_BAND + else if (band == WLC_BAND_6G) + channel = escan->best_6g_ch; +#endif /* WL_6G_BAND */ else channel = escan->best_2g_ch; WL_MSG(dev->name, "selected channel = %d\n", channel); @@ -4039,4 +4267,3 @@ wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) wl_free_bss_cache(bss_cache_ctrl); } #endif /* BSSCACHE */ - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.h index 4d161fe1738f..a8f88626d6f8 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.h @@ -1,6 +1,12 @@ #ifndef _wl_android_ext_ #define _wl_android_ext_ + +typedef struct wl_chan_info { + uint band; + uint16 chan; +} wl_chan_info_t; + typedef struct bcol_gtk_para { int enable; int ptk_len; @@ -10,6 +16,7 @@ typedef struct bcol_gtk_para { #define ACS_FW_BIT (1<<0) #define ACS_DRV_BIT (1<<1) int wl_ext_autochannel(struct net_device *dev, uint acs, uint32 band); +chanspec_band_t wl_ext_wlcband_to_chanspec_band(int band); int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len, int *bytes_written); void wl_ext_get_sec(struct net_device *dev, int ifmode, char *sec, int total_len, bool dump); @@ -19,6 +26,7 @@ int wl_ext_set_scan_time(struct net_device *dev, int scan_time, void wl_ext_wait_event_complete(struct dhd_pub *dhd, int ifidx); int wl_ext_add_del_ie(struct net_device *dev, uint pktflag, char *ie_data, const char* add_del_cmd); #ifdef WL_ESCAN +int wl_construct_ctl_chanspec_list(struct net_device *dev, wl_uint32_list_t *chan_list); int wl_ext_drv_scan(struct net_device *dev, uint band, bool fast_scan); #endif #ifdef WL_EXT_GENL @@ -41,11 +49,11 @@ int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name, struct mutex* buf_sync); chanspec_t wl_ext_chspec_driver_to_host(int ioctl_ver, chanspec_t chanspec); chanspec_t wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec); -bool wl_ext_dfs_chan(uint16 chan); +bool wl_ext_dfs_chan(struct wl_chan_info *chan_info); uint16 wl_ext_get_default_chan(struct net_device *dev, uint16 *chan_2g, uint16 *chan_5g, bool nodfs); -int wl_ext_set_chanspec(struct net_device *dev, int ioctl_ver, - uint16 channel, chanspec_t *ret_chspec); +int wl_ext_set_chanspec(struct net_device *dev, struct wl_chan_info *chan_info, + chanspec_t *ret_chspec); int wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver); #endif #if defined(WL_CFG80211) || defined(WL_ESCAN) @@ -117,7 +125,7 @@ void wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); void wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); void wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid); void wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); -void wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list); +void wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_v109_t *ss_list); int wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg); int16 wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr); #endif @@ -145,7 +153,7 @@ typedef struct wl_bss_cache { struct wl_bss_cache *next; int dirty; struct osl_timespec tv; - wl_scan_results_t results; + wl_scan_results_v109_t results; } wl_bss_cache_t; typedef struct wl_bss_cache_ctrl { @@ -161,16 +169,27 @@ void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, #if defined(RSSIAVG) wl_rssi_cache_ctrl_t *rssi_cache_ctrl, #endif - wl_scan_results_t *ss_list); + wl_scan_results_v109_t *ss_list); void wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl); #endif int wl_ext_get_best_channel(struct net_device *net, #if defined(BSSCACHE) wl_bss_cache_ctrl_t *bss_cache_ctrl, #else - wl_scan_results_t *bss_list, + wl_scan_results_v109_t *bss_list, #endif - int ioctl_ver, int *best_2g_ch, int *best_5g_ch + int ioctl_ver, int *best_2g_ch, int *best_5g_ch, int *best_6g_ch ); -#endif +#ifdef WL_6G_BAND +#define CHSPEC2BANDSTR(chspec) (CHSPEC_IS2G(chspec) ? "2g" : CHSPEC_IS5G(chspec) ? \ + "5g" : CHSPEC_IS6G(chspec) ? "6g" : "0g") +#define WLCBAND2STR(band) ((band == WLC_BAND_2G) ? "2g" : (band == WLC_BAND_5G) ? \ + "5g" : (band == WLC_BAND_6G) ? "6g" : "0g") +#else +#define CHSPEC2BANDSTR(chspec) (CHSPEC_IS2G(chspec) ? "2g" : CHSPEC_IS5G(chspec) ? \ + "5g" : "0g") +#define WLCBAND2STR(band) ((band == WLC_BAND_2G) ? "2g" : (band == WLC_BAND_5G) ? \ + "5g" : "0g") +#endif /* WL_6G_BAND */ +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c index 276156cbed53..666c5d931ebd 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c @@ -3719,15 +3719,19 @@ wl_cfg80211_post_ifcreate(struct net_device *ndev, #ifdef WLDWDS /* set wds0.x to 4addr interface here */ if (event->role == WLC_E_IF_ROLE_WDS) { - WL_MSG(ndev->name, "set vwdev 4addr to %s\n", event->name); + struct dhd_if *ifp = dhd_get_ifp(cfg->pub, event->ifidx); + ifp->dwds = TRUE; + WL_MSG(event->name, "set to 4addr\n"); wdev->use_4addr = true; } #endif /* WLDWDS */ SET_NETDEV_DEV(new_ndev, wiphy_dev(wdev->wiphy)); - memcpy(new_ndev->dev_addr, addr, ETH_ALEN); + dev_addr_set(new_ndev, addr); #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_ifadding(new_ndev, event->ifidx); + if (event->role != WLC_E_IF_ROLE_WDS) { + wl_ext_iapsta_ifadding(new_ndev, event->ifidx); + } #endif /* WL_EXT_IAPSTA */ if (wl_cfg80211_register_if(cfg, event->ifidx, new_ndev, rtnl_lock_reqd) != BCME_OK) { @@ -3759,7 +3763,7 @@ wl_cfg80211_post_ifcreate(struct net_device *ndev, wl_set_drv_status(cfg, AP_CREATING, new_ndev); } #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_update_iftype(new_ndev, event->ifidx, wl_iftype); + wl_ext_iapsta_update_iftype(new_ndev, wl_iftype); #endif WL_INFORM_MEM(("Network Interface (%s) registered with host." @@ -4190,10 +4194,11 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, s32 err = 0; size_t join_params_size; chanspec_t chanspec = 0; + char sec[64]; WL_TRACE(("In\n")); RETURN_EIO_IF_NOT_UP(cfg); - WL_INFORM_MEM(("IBSS JOIN BSSID:" MACDBG "\n", MAC2STRDBG(params->bssid))); + WL_INFORM_MEM(("IBSS JOIN\n")); if (!params->ssid || params->ssid_len <= 0 || params->ssid_len > DOT11_MAX_SSID_LEN) { WL_ERR(("Invalid parameter\n")); @@ -4205,7 +4210,12 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, chan = params->channel; #endif /* WL_CFG80211_P2P_DEV_IF */ if (chan) { - cfg->channel = wl_freq_to_chanspec(chan->center_freq); +#ifdef WL_EXT_IAPSTA + chanspec = wl_freq_to_chanspec(chan->center_freq); + wl_ext_iapsta_update_iftype(dev, WL_IF_TYPE_IBSS); + chanspec = wl_ext_iapsta_update_channel(dev, chanspec); +#endif /* WL_EXT_IAPSTA */ + cfg->channel = chanspec; } if (wl_get_drv_status(cfg, CONNECTED, dev)) { struct wlc_ssid *lssid = (struct wlc_ssid *)wl_read_prof(cfg, dev, WL_PROF_SSID); @@ -4228,6 +4238,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); if (!bss) { if (IBSS_INITIAL_SCAN_ALLOWED == TRUE) { + int retry = 4; memcpy(ssid.ssid, params->ssid, params->ssid_len); ssid.ssid_len = params->ssid_len; do { @@ -4245,7 +4256,13 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, */ /* wait 4 secons till scan done.... */ - schedule_timeout_interruptible(msecs_to_jiffies(4000)); +// schedule_timeout_interruptible(msecs_to_jiffies(4000)); + while (retry--) { + if (!wl_get_drv_status_all(cfg, SCANNING)) { + break; + } + wl_delay(150); + } bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); @@ -4314,6 +4331,10 @@ 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); + wl_ext_get_sec(dev, 0, sec, sizeof(sec), TRUE); + WL_MSG(dev->name, "Join IBSS %pM ssid \"%s\", len (%d), channel=%d, sec=%s\n", + &join_params.params.bssid, join_params.ssid.SSID, join_params.ssid.SSID_len, + wf_chspec_ctlchan(chanspec), sec); err = wldev_ioctl_set(dev, WLC_SET_SSID, &join_params, join_params_size); if (unlikely(err)) { @@ -4352,7 +4373,7 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) RETURN_EIO_IF_NOT_UP(cfg); wl_link_down(cfg); - WL_INFORM_MEM(("Leave IBSS\n")); + WL_MSG(dev->name, "Leave IBSS\n"); curbssid = wl_read_prof(cfg, dev, WL_PROF_BSSID); wl_set_drv_status(cfg, DISCONNECTING, dev); scbval.val = 0; @@ -6171,7 +6192,7 @@ void wl_conn_debug_info(struct bcm_cfg80211 *cfg, struct net_device *dev, wlcfg_assoc_info_t *info) { struct wl_security *sec = wl_read_prof(cfg, dev, WL_PROF_SEC); - char sec_info[32]; + char sec_info[64]; u32 chanspec = info->chanspecs[0]; u32 chan_cnt = info->chan_cnt; s32 cur_rssi = 0, target_rssi = 0; @@ -6191,14 +6212,16 @@ wl_conn_debug_info(struct bcm_cfg80211 *cfg, struct net_device *dev, wlcfg_assoc if (!err) cur_rssi = dtoh32(scb_val.val); WL_MSG(dev->name, "Reconnecting with " MACDBG " ssid \"%s\", len (%d), " - "channel=%d(chan_cnt=%d), sec=%s, rssi=%d => %d\n", + "channel=%s-%d(chan_cnt=%d), sec=%s, rssi=%d => %d\n", MAC2STRDBG((u8*)(&info->bssid)), info->ssid, info->ssid_len, - wf_chspec_ctlchan(chanspec), chan_cnt, sec_info, cur_rssi, target_rssi); + CHSPEC2BANDSTR(chanspec), wf_chspec_ctlchan(chanspec), chan_cnt, + sec_info, cur_rssi, target_rssi); } else { WL_MSG(dev->name, "Connecting with " MACDBG " ssid \"%s\", len (%d), " - "channel=%d(chan_cnt=%d), sec=%s, rssi=%d\n", + "channel=%s-%d(chan_cnt=%d), sec=%s, rssi=%d\n", MAC2STRDBG((u8*)(&info->bssid)), info->ssid, info->ssid_len, - wf_chspec_ctlchan(chanspec), chan_cnt, sec_info, target_rssi); + CHSPEC2BANDSTR(chanspec), wf_chspec_ctlchan(chanspec), chan_cnt, + sec_info, target_rssi); } if (wl_dbg_level & WL_DBG_DBG) { WL_MSG(dev->name, "akm:0x%x auth:0x%x wpaver:0x%x pwise:0x%x gwise:0x%x\n", @@ -6251,7 +6274,7 @@ wl_handle_join(struct bcm_cfg80211 *cfg, } #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_update_channel(dev, wf_chspec_ctlchan(assoc_info->chanspecs[0])); + wl_ext_iapsta_update_channel(dev, assoc_info->chanspecs[0]); #endif /* print relevant info for debug purpose */ wl_conn_debug_info(cfg, dev, assoc_info); @@ -6304,7 +6327,7 @@ wl_handle_reassoc(struct bcm_cfg80211 *cfg, struct net_device *dev, reassoc_params->chanspec_num = htod32(chan_cnt); #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_update_channel(dev, wf_chspec_ctlchan(chanspec)); + wl_ext_iapsta_update_channel(dev, chanspec); #endif /* print relevant info for debug purpose */ wl_conn_debug_info(cfg, dev, info); @@ -7793,7 +7816,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, STA_INFO_BIT(INFO_TX_PACKETS) | STA_INFO_BIT(INFO_TX_FAILED)); get_station_err: -#ifndef BCMDBUS +#if 0 if (err && (err != -ENODATA)) { /* Disconnect due to zero BSSID or error to get RSSI */ scb_val_t scbval; @@ -10316,6 +10339,35 @@ s32 wl_mode_to_nl80211_iftype(s32 mode) return err; } +static bool +wl_is_ccode_change_allowed(struct net_device *net) +{ + struct wireless_dev *wdev = ndev_to_wdev(net); + struct wiphy *wiphy = wdev->wiphy; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + struct net_info *iter, *next; + + /* Country code isn't allowed change on AP/GO, NDP established */ + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); + for_each_ndev(cfg, iter, next) { + GCC_DIAGNOSTIC_POP(); + if (iter->ndev) { + if (wl_get_drv_status(cfg, AP_CREATED, iter->ndev)) { + WL_ERR(("AP active. skip coutry ccode change")); + return false; + } + } + } + +#ifdef WL_NAN + if (wl_cfgnan_is_enabled(cfg) && wl_cfgnan_is_dp_active(net)) { + WL_ERR(("NDP established. skip coutry ccode change")); + return false; + } +#endif /* WL_NAN */ + return true; +} + static bool wl_is_ccode_change_required(struct net_device *net, char *country_code, int revinfo) @@ -10394,6 +10446,73 @@ wl_cfg80211_cleanup_connection(struct net_device *net, bool user_enforced) #endif /* WL_NAN */ } +static int wl_copy_regd(const struct ieee80211_regdomain *regd_orig, + struct ieee80211_regdomain *regd_copy) +{ + int i; + + if (memcpy_s(regd_copy, sizeof(*regd_copy), regd_orig, sizeof(*regd_orig))) { + return BCME_ERROR; + } + for (i = 0; i < regd_orig->n_reg_rules; i++) { + if (memcpy_s(®d_copy->reg_rules[i], sizeof(regd_copy->reg_rules[i]), + ®d_orig->reg_rules[i], sizeof(regd_orig->reg_rules[i]))) { + return BCME_ERROR; + } + } + return BCME_OK; +} + +static void wl_notify_regd(struct wiphy *wiphy, char *country_code) +{ + struct ieee80211_regdomain *regd_copy = NULL; + int regd_len; + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + + regd_len = sizeof(brcm_regdom) + (brcm_regdom.n_reg_rules * + sizeof(struct ieee80211_reg_rule)); + + regd_copy = (struct ieee80211_regdomain *)MALLOCZ(cfg->osh, regd_len); + if (!regd_copy) { + WL_ERR(("failed to alloc regd_copy\n")); + return; + } + + /* the upper layer function below requires non-const type */ + if (wl_copy_regd(&brcm_regdom, regd_copy)) { + WL_ERR(("failed to copy new regd\n")); + goto exit; + } + + if (country_code) { + if (memcpy_s(regd_copy->alpha2, sizeof(regd_copy->alpha2), + country_code, WL_CCODE_LEN)) { + WL_ERR(("failed to copy new ccode:%s\n", country_code)); + goto exit; + } + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + if (rtnl_is_locked()) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) + wiphy_lock(wiphy); + regulatory_set_wiphy_regd_sync(wiphy, regd_copy); + wiphy_unlock(wiphy); +#else + regulatory_set_wiphy_regd_sync_rtnl(wiphy, regd_copy); +#endif /* LINUX_VERSION > 5.12.0 */ + } else { + regulatory_set_wiphy_regd(wiphy, regd_copy); + } +#else + wiphy_apply_custom_regulatory(wiphy, regd_copy); +#endif /* LINUX_VERSION > 4.0.0 */ + +exit: + MFREE(cfg->osh, regd_copy, regd_len); + return; +} + s32 wl_cfg80211_set_country_code(struct net_device *net, char *country_code, bool notify, bool user_enforced, int revinfo) @@ -10415,12 +10534,25 @@ wl_cfg80211_set_country_code(struct net_device *net, char *country_code, goto exit; } + if (wl_is_ccode_change_allowed(net) == false) { + WL_ERR(("country code change isn't allowed during AP role/NAN connected\n")); + ret = BCME_EPERM; + goto exit; + } + wl_cfg80211_cleanup_connection(net, user_enforced); + /* Store before applying - so that if event comes earlier that is handled properly */ + if (strlcpy(cfg->country, country_code, WL_CCODE_LEN) >= WLC_CNTRY_BUF_SZ) { + WL_ERR(("country code copy failed :%d\n", ret)); + goto exit; + } + ret = wldev_set_country(net, country_code, notify, revinfo); if (ret < 0) { WL_ERR(("set country Failed :%d\n", ret)); + bzero(cfg->country, sizeof(cfg->country)); goto exit; } @@ -10430,10 +10562,12 @@ wl_cfg80211_set_country_code(struct net_device *net, char *country_code, */ if (!IS_REGDOM_SELF_MANAGED(wiphy)) { regulatory_hint(wiphy, country_code); + } else { + wl_notify_regd(wiphy, country_code); } exit: - return ret; + return OSL_ERROR(ret); } #ifdef CONFIG_CFG80211_INTERNAL_REGDB @@ -10521,12 +10655,10 @@ static void wl_config_custom_regulatory(struct wiphy *wiphy) { -#if defined(WL_SELF_MANAGED_REGDOM) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) /* Use self managed regulatory domain */ wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED | REGULATORY_IGNORE_STALE_KICKOFF; - wiphy->regd = &brcm_regdom; WL_DBG(("Self managed regdom\n")); return; #else /* WL_SELF_MANAGED_REGDOM && KERNEL >= 4.0 */ @@ -10540,7 +10672,7 @@ void wl_config_custom_regulatory(struct wiphy *wiphy) #else /* KERNEL VER >= 3.14 */ wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ - wiphy_apply_custom_regulatory(wiphy, &brcm_regdom); + wl_notify_regd(wiphy, NULL); WL_DBG(("apply custom regulatory\n")); #endif /* WL_SELF_MANAGED_REGDOM && KERNEL >= 4.0 */ } @@ -10753,13 +10885,6 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->max_num_csa_counters = WL_MAX_NUM_CSA_COUNTERS; #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 12, 0) */ - /* Now we can register wiphy with cfg80211 module */ - err = wiphy_register(wdev->wiphy); - if (unlikely(err < 0)) { - WL_ERR(("Couldn not register wiphy device (%d)\n", err)); - wiphy_free(wdev->wiphy); - } - #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \ (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 3, 0))) && defined(WL_IFACE_COMB_NUM_CHANNELS) /* Workaround for a cfg80211 bug */ @@ -10791,6 +10916,23 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN; #endif /* WL_SCAN_TYPE */ + /* Now we can register wiphy with cfg80211 module */ + err = wiphy_register(wdev->wiphy); + if (unlikely(err < 0)) { + WL_ERR(("Couldn not register wiphy device (%d)\n", err)); + wiphy_free(wdev->wiphy); + return err; + } + + /* set wiphy->regd through reg_process_self_managed_hints + * need to call it after wiphy_register + * since wiphy_register adds rdev to cfg80211_rdev_list + */ + if (IS_REGDOM_SELF_MANAGED(wdev->wiphy)) { + rtnl_lock(); + wl_notify_regd(wdev->wiphy, NULL); + rtnl_unlock(); + } return err; } @@ -10815,8 +10957,7 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg) wdev->wiphy->wowlan = NULL; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ #endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */ -#if defined(WL_SELF_MANAGED_REGDOM) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) /* Making regd ptr NULL, to avoid reference/freeing by regulatory unregister */ wiphy->regd = NULL; #endif /* WL_SELF_MANAGED_REGDOM && KERNEL >= 4.0 */ @@ -11308,9 +11449,8 @@ wl_notify_connect_status_ibss(struct bcm_cfg80211 *cfg, struct net_device *ndev, MACDBG "), ignore it\n", MAC2STRDBG(cur_bssid))); return err; } - WL_INFORM_MEM(("[%s] IBSS BSSID is changed from " MACDBG " to " MACDBG "\n", - ndev->name, MAC2STRDBG(cur_bssid), - MAC2STRDBG((const u8 *)&e->addr))); + WL_MSG(ndev->name, "IBSS BSSID is changed from " MACDBG " to " MACDBG "\n", + MAC2STRDBG(cur_bssid), MAC2STRDBG((const u8 *)&e->addr)); wl_get_assoc_ies(cfg, ndev); wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID); wl_update_bss_info(cfg, ndev, false); @@ -11322,8 +11462,8 @@ wl_notify_connect_status_ibss(struct bcm_cfg80211 *cfg, struct net_device *ndev, } else { /* New connection */ - WL_INFORM_MEM(("[%s] IBSS connected to " MACDBG "\n", - ndev->name, MAC2STRDBG((const u8 *)&e->addr))); + WL_MSG(ndev->name, "IBSS connected to " MACDBG "\n", + MAC2STRDBG((const u8 *)&e->addr)); wl_link_up(cfg); wl_get_assoc_ies(cfg, ndev); wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID); @@ -13800,6 +13940,7 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, WL_ERR(("ssid_len=0. Indicate assoc event failure\n")); completed = false; sec->auth_assoc_res_status = WLAN_STATUS_UNSPECIFIED_FAILURE; + wl_clr_drv_status(cfg, CONNECTED, ndev); } } @@ -14459,19 +14600,76 @@ exit: return err; } -#ifdef CUSTOMER_HW6 +static void +wl_map_brcm_specifc_country_code(char *country_code) +{ + /* If country code is default locale, change the domain to world domain + * Default locale formats: AA, ZZ, XA-XZ, QM-QZ + */ + if (!strcmp("AA", country_code) || !strcmp("ZZ", country_code) || + ((country_code[0] == 'X') && (country_code[1] >= 'A') && + (country_code[1] <= 'Z')) || ((country_code[0] == 'Q') && + (country_code[1] >= 'M') && (country_code[1] <= 'Z'))) { + WL_DBG(("locale mapped to world domain\n")); + country_code[0] = '0'; + country_code[1] = '0'; + } +} + static s32 wl_cfg80211_ccode_evt_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data) { s32 err = 0; + struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); + char country_str[WLC_CNTRY_BUF_SZ] = { 0 }; + struct net_device *dev = bcmcfg_to_prmry_ndev(cfg); + wl_country_t cspec = {{0}, 0, {0}}; + + if (strlcpy(country_str, data, WL_CCODE_LEN + 1) >= WLC_CNTRY_BUF_SZ) { + return -EINVAL; + } + + if (strncmp(cfg->country, country_str, WL_CCODE_LEN) == 0) { + /* If country code is updated from command context, skip wiphy update */ + WL_MSG(dev->name, "No change in country (%s)\n", country_str); + return BCME_OK; + } + + WL_MSG(dev->name, "Updating new country %s\n", country_str); + + strlcpy(cspec.country_abbrev, country_str, WL_CCODE_LEN + 1); + strlcpy(cspec.ccode, country_str, WL_CCODE_LEN + 1); + err = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec); + if (err) + dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec); + err = dhd_conf_set_country(dhd_get_pub(dev), &cspec); + if (err < 0) { + WL_ERR(("set country for %s as %s rev %d failed\n", + country_str, cspec.ccode, cspec.rev)); + } + dhd_conf_fix_country(dhd_get_pub(dev)); + /* Indicate to upper layer for regdom change */ - WL_INFORM_MEM(("Received country code change event\n")); err = wl_update_wiphybands(cfg, true); + if (err != BCME_OK) { + WL_ERR(("update wiphy bands failed\n")); + return err; + } + + wl_map_brcm_specifc_country_code(country_str); + + if (!IS_REGDOM_SELF_MANAGED(wiphy)) { + err = regulatory_hint(wiphy, country_str); + if (err) { + WL_ERR(("update country change failed\n")); + return err; + } + WL_DBG_MEM(("regulatory hint notified for ccode change\n")); + } return err; } -#endif /* CUSTOMER_HW6 */ static void wl_init_conf(struct wl_conf *conf) { @@ -14575,9 +14773,7 @@ static void wl_init_event_handler(struct bcm_cfg80211 *cfg) cfg->evt_handler[WLC_E_ADPS] = wl_adps_event_handler; #endif /* WL_BAM */ cfg->evt_handler[WLC_E_PSK_SUP] = wl_cfg80211_sup_event_handler; -#ifdef CUSTOMER_HW6 cfg->evt_handler[WLC_E_COUNTRY_CODE_CHANGED] = wl_cfg80211_ccode_evt_handler; -#endif /* CUSTOMER_HW6 */ #ifdef WL_BCNRECV cfg->evt_handler[WLC_E_BCNRECV_ABORTED] = wl_bcnrecv_aborted_event_handler; #endif /* WL_BCNRECV */ @@ -15632,7 +15828,7 @@ wl_cfg80211_net_attach(struct net_device *primary_ndev) } #ifdef WL_STATIC_IF /* Register dummy n/w iface. FW init will happen only from dev_open */ -#ifdef WLEASYMESH +#ifdef WLDWDS ntype = NL80211_IFTYPE_AP; #else ntype = NL80211_IFTYPE_STATION; @@ -16858,13 +17054,7 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) if (notify) { if (!IS_REGDOM_SELF_MANAGED(wiphy)) { WL_UPDATE_CUSTOM_REGULATORY(wiphy); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) - rtnl_unlock(); -#endif - wiphy_apply_custom_regulatory(wiphy, &brcm_regdom); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) - rtnl_lock(); -#endif + wl_notify_regd(wiphy, NULL); } } @@ -22729,7 +22919,7 @@ wl_cfg80211_mgmt_auth_tx(struct net_device *dev, bcm_struct_cfgdev *cfgdev, ack = false; } else { err = wldev_iovar_setbuf(dev, "assoc_mgr_cmd", ambuf, param_len, - cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync); + cfg->ioctl_buf, WLC_IOCTL_MEDLEN, &cfg->ioctl_buf_sync); if (unlikely(err)) { WL_ERR(("Failed to send auth(%d)\n", err)); ack = false; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.h index 26d2141b42e0..63b8199ec7a2 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.h @@ -332,6 +332,13 @@ extern char *dhd_dbg_get_system_timestamp(void); #endif /* SUPPORT_AP_RADIO_PWRSAVE */ #ifdef BCMWAPI_WPI +#ifdef CFG80211_WAPI_BKPORT +#define IS_WAPI_VER(version) (version == NL80211_WAPI_VERSION_1) +#undef WLAN_AKM_SUITE_WAPI_PSK +#define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC13 +#undef WLAN_AKM_SUITE_WAPI_CERT +#define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC14 +#else #ifdef OEM_ANDROID #undef NL80211_WAPI_VERSION_1 #define NL80211_WAPI_VERSION_1 0 @@ -354,6 +361,7 @@ extern char *dhd_dbg_get_system_timestamp(void); #define NL80211_WAPI_VERSION_1 1 << 2 #define IS_WAPI_VER(version) (version & NL80211_WAPI_VERSION_1) #endif /* OEM_ANDROID */ +#endif /* CFG80211_WAPI_BKPORT */ #endif /* BCMWAPI_WPI */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) @@ -425,19 +433,19 @@ extern char *dhd_dbg_get_system_timestamp(void); #define CFG80211_TRACE_TEXT USER_PREFIX_CFG80211 #define CFG80211_DEBUG_TEXT USER_PREFIX_CFG80211 #else -#define CFG80211_INFO_TEXT DHD_LOG_PREFIXS "CFG80211-INFO) " +#define CFG80211_INFO_TEXT "CFG80211-INFO) " /* Samsung want to print INFO2 instead of ERROR * because most of case, ERROR message is not a real ERROR. * but it can be regarded as real error case for Tester */ #ifdef CUSTOMER_HW4_DEBUG -#define CFG80211_ERROR_TEXT DHD_LOG_PREFIXS "CFG80211-INFO2) " +#define CFG80211_ERROR_TEXT "CFG80211-INFO2) " #else -#define CFG80211_ERROR_TEXT DHD_LOG_PREFIXS "CFG80211-ERROR) " +#define CFG80211_ERROR_TEXT "CFG80211-ERROR) " #endif /* CUSTOMER_HW4_DEBUG */ -#define CFG80211_SCAN_TEXT DHD_LOG_PREFIXS "CFG80211-SCAN) " -#define CFG80211_TRACE_TEXT DHD_LOG_PREFIXS "CFG80211-TRACE) " -#define CFG80211_DEBUG_TEXT DHD_LOG_PREFIXS "CFG80211-DEBUG) " +#define CFG80211_SCAN_TEXT "CFG80211-SCAN) " +#define CFG80211_TRACE_TEXT "CFG80211-TRACE) " +#define CFG80211_DEBUG_TEXT "CFG80211-DEBUG) " #endif /* defined(CUSTOMER_DBG_PREFIX_ENABLE) */ #ifdef DHD_DEBUG @@ -445,8 +453,7 @@ extern char *dhd_dbg_get_system_timestamp(void); #define WL_ERR_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ } \ @@ -455,8 +462,7 @@ do { \ #define WL_ERR_KERN_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_ERR_KERN(x) WL_ERR_KERN_MSG x @@ -473,8 +479,7 @@ do { \ #define WL_DBG_MEM_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ } \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ @@ -484,8 +489,7 @@ do { \ #define WL_INFORM_MEM_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ } \ @@ -494,8 +498,7 @@ do { \ #define WL_ERR_EX_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_EX_TS_FN; \ DHD_LOG_DUMP_WRITE_EX(x, ## args); \ } \ @@ -510,8 +513,7 @@ do { \ #define WL_ERR_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_ERR(x) WL_ERR_MSG x @@ -526,8 +528,7 @@ do { \ #define WL_ERR_MSG(x, args...) \ do { \ if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_ERROR_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_ERR(x) WL_ERR_MSG x @@ -572,8 +573,7 @@ do { \ #define WL_INFORM_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_INFO_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_INFORM(x) WL_INFORM_MSG x @@ -584,8 +584,7 @@ do { \ #define WL_SCAN_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_SCAN) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_SCAN_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_SCAN_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_SCAN(x) WL_SCAN_MSG x @@ -595,8 +594,7 @@ do { \ #define WL_TRACE_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_TRACE) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_TRACE_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_TRACE_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_TRACE(x) WL_TRACE_MSG x @@ -607,8 +605,7 @@ do { \ #define WL_TRACE_HW4_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_TRACE_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_TRACE_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_TRACE_HW4(x) WL_TRACE_HW4_MSG x @@ -619,8 +616,7 @@ do { \ #define WL_DBG_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFG80211_DEBUG_TEXT "%s : " x, __func__, ## args); \ + printf(CFG80211_DEBUG_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define WL_DBG(x) WL_DBG_MSG x @@ -1967,6 +1963,7 @@ struct bcm_cfg80211 { bool p2p_6g_enabled; /* P2P 6G support enabled */ #endif /* WL_P2P_6G */ u32 halpid; + u8 country[WLC_CNTRY_BUF_SZ]; #if defined(RSSIAVG) wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl; @@ -1977,6 +1974,7 @@ struct bcm_cfg80211 { int autochannel; int best_2g_ch; int best_5g_ch; + int best_6g_ch; }; /* Max auth timeout allowed in case of EAP is 70sec, additional 5 sec for diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.c index 16012df02573..878495e41df8 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.c @@ -3960,7 +3960,7 @@ wl_cfgnan_cache_svc_info(struct bcm_cfg80211 *cfg, goto fail; } if (cmd_data->sde_control_flag & NAN_SDE_CF_RANGING_REQUIRED) { - WL_TRACE(("%s: updating ranging info, enabling", __FUNCTION__)); + WL_TRACE(("%s: updating ranging info, enabling\n", __FUNCTION__)); svc_info->status = 1; svc_info->ranging_interval = cmd_data->ranging_intvl_msec; svc_info->ranging_ind = cmd_data->ranging_indication; @@ -3968,7 +3968,7 @@ wl_cfgnan_cache_svc_info(struct bcm_cfg80211 *cfg, svc_info->egress_limit = cmd_data->egress_limit; svc_info->ranging_required = 1; } else { - WL_TRACE(("%s: updating ranging info, disabling", __FUNCTION__)); + WL_TRACE(("%s: updating ranging info, disabling\n", __FUNCTION__)); svc_info->status = 0; svc_info->ranging_interval = 0; svc_info->ranging_ind = 0; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.h index 90bb286bdc5e..703e64571433 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgnan.h @@ -95,8 +95,8 @@ #define NMR2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7] #define NMRSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" -#define NAN_DBG_ENTER() {WL_DBG(("Enter: %s\n", __FUNCTION__));} -#define NAN_DBG_EXIT() {WL_DBG(("Exit: %s\n", __FUNCTION__));} +#define NAN_DBG_ENTER() {WL_DBG(("Enter\n"));} +#define NAN_DBG_EXIT() {WL_DBG(("Exit\n"));} /* Service Control Type length */ #define NAN_SVC_CONTROL_TYPE_MASK ((1 << NAN_SVC_CONTROL_TYPE_LEN) - 1) @@ -217,6 +217,7 @@ #define NAN_RNG_GEOFENCE_MAX_RETRY_CNT 3u +#define NAN_MAX_CHANNEL_INFO_SUPPORTED 4u /* * Discovery Beacon Interval config, * Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW. @@ -384,6 +385,17 @@ typedef struct nan_mac_list { uint8 *list; } nan_mac_list_t; +typedef struct nan_channel_info { + uint32 channel; + uint32 bandwidth; + uint32 nss; +} nan_channel_info_t; + +typedef struct nan_ndl_sched_info { + uint32 num_channels; + nan_channel_info_t channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED]; +} nan_ndl_sched_info_t; + typedef struct wl_nan_sid_beacon_tune { uint8 sid_enable; /* flag for sending service id in beacon */ uint8 sid_count; /* Limit for number of SIDs to be included in Beacons */ @@ -946,7 +958,12 @@ typedef enum { NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL = 224, NAN_ATTRIBUTE_NSS = 225, NAN_ATTRIBUTE_ENABLE_RANGING = 226, - NAN_ATTRIBUTE_DW_EARLY_TERM = 227 + NAN_ATTRIBUTE_DW_EARLY_TERM = 227, + NAN_ATTRIBUTE_CHANNEL_INFO = 228, + NAN_ATTRIBUTE_NUM_CHANNELS = 229, + NAN_ATTRIBUTE_INSTANT_MODE_ENABLE = 230, + NAN_ATTRIBUTE_INSTANT_COMM_CHAN = 231, + NAN_ATTRIBUTE_MAX = 232 } NAN_ATTRIBUTE; enum geofence_suspend_reason { diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.c index 01a04f069ce4..05a7edffdd4e 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.c @@ -2403,7 +2403,7 @@ wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg) #endif /* Register with a dummy MAC addr */ - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); + dev_addr_set(net, temp_addr); #ifndef WL_NEWCFG_PRIVCMD_SUPPORT wdev->wiphy = cfg->wdev->wiphy; @@ -2622,8 +2622,7 @@ wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg) #if defined(WL_NEWCFG_PRIVCMD_SUPPORT) if (cfg->p2p_net) - memcpy(cfg->p2p_net->dev_addr, wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE), - ETHER_ADDR_LEN); + dev_addr_set(cfg->p2p_net, wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE)); #endif /* WL_NEWCFG_PRIVCMD_SUPPORT */ /* store p2p wdev ptr for further reference. */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h index aee2a94425a4..58a161a254b5 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h @@ -140,21 +140,20 @@ enum wl_cfgp2p_status { * but it can be regarded as real error case for Tester */ #ifdef CUSTOMER_HW4_DEBUG -#define CFGP2P_ERROR_TEXT DHD_LOG_PREFIXS "CFGP2P-INFO2) " +#define CFGP2P_ERROR_TEXT "CFGP2P-INFO2) " #else -#define CFGP2P_ERROR_TEXT DHD_LOG_PREFIXS "CFGP2P-ERROR) " +#define CFGP2P_ERROR_TEXT "CFGP2P-ERROR) " #endif /* CUSTOMER_HW4_DEBUG */ -#define CFGP2P_INFO_TEXT DHD_LOG_PREFIXS "CFGP2P-INFO) " -#define CFGP2P_ACTION_TEXT DHD_LOG_PREFIXS "CFGP2P-ACTION) " -#define CFGP2P_DEBUG_TEXT DHD_LOG_PREFIXS "CFGP2P-DEBUG) " +#define CFGP2P_INFO_TEXT "CFGP2P-INFO) " +#define CFGP2P_ACTION_TEXT "CFGP2P-ACTION) " +#define CFGP2P_DEBUG_TEXT "CFGP2P-DEBUG) " #endif /* defined(CUSTOMER_DBG_PREFIX_ENABLE) */ #ifdef DHD_LOG_DUMP #define CFGP2P_ERR_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_ERROR_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ } \ @@ -163,8 +162,7 @@ enum wl_cfgp2p_status { #define CFGP2P_INFO_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_INFO_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_INFO_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ } \ @@ -173,8 +171,7 @@ enum wl_cfgp2p_status { #define CFGP2P_ACTION_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_P2P_ACTION) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_ACTION_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_ACTION_TEXT "%s : " x, __func__, ## args); \ DHD_LOG_DUMP_WRITE_TS_FN; \ DHD_LOG_DUMP_WRITE(x, ## args); \ } \ @@ -184,24 +181,21 @@ enum wl_cfgp2p_status { #define CFGP2P_ERR_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_ERROR_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_ERROR_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define CFGP2P_ERR(x) CFGP2P_ERR_MSG x #define CFGP2P_INFO_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_INFO_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_INFO_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define CFGP2P_INFO(x) CFGP2P_INFO_MSG x #define CFGP2P_ACTION_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_P2P_ACTION) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_ACTION_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_ACTION_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define CFGP2P_ACTION(x) CFGP2P_ACTION_MSG x @@ -210,8 +204,7 @@ enum wl_cfgp2p_status { #define CFGP2P_DBG_MSG(x, args...) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(CFGP2P_DEBUG_TEXT "%s : " x, __func__, ## args); \ + printf(CFGP2P_DEBUG_TEXT "%s : " x, __func__, ## args); \ } \ } while (0) #define CFGP2P_DBG(x) CFGP2P_DBG_MSG x diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgscan.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgscan.c index a3d617b09fe9..27805f6ab6e9 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgscan.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgscan.c @@ -641,10 +641,10 @@ wl_inform_bss(struct bcm_cfg80211 *cfg) if (cfg->autochannel && ndev) { #if defined(BSSCACHE) wl_ext_get_best_channel(ndev, &cfg->g_bss_cache_ctrl, ioctl_version, - &cfg->best_2g_ch, &cfg->best_5g_ch); + &cfg->best_2g_ch, &cfg->best_5g_ch, &cfg->best_6g_ch); #else wl_ext_get_best_channel(ndev, bss_list, ioctl_version, - &cfg->best_2g_ch, &cfg->best_5g_ch); + &cfg->best_2g_ch, &cfg->best_5g_ch, &cfg->best_6g_ch); #endif } @@ -1576,29 +1576,24 @@ chanspec_t wl_freq_to_chanspec(int freq) static void wl_cfgscan_populate_scan_channel(struct bcm_cfg80211 *cfg, struct ieee80211_channel **channels, u32 n_channels, - u16 *channel_list, u32 target_channel) + u16 *channel_list, struct wl_chan_info *chan_info) { - u32 i = 0; - u32 chanspec = 0; - u32 channel; + u32 i, chanspec = 0; for (i=0; icenter_freq); - if (channel != target_channel) - continue; - if (!dhd_conf_match_channel(cfg->pub, channel)) - return; - chanspec = wl_freq_to_chanspec(channels[i]->center_freq); if (chanspec == INVCHANSPEC) { WL_ERR(("Invalid chanspec! Skipping channel\n")); continue; } - - channel_list[0] = chanspec; - break; + if (chan_info->band == CHSPEC2WLC_BAND(chanspec) && + chan_info->chan == wf_chspec_ctlchan(chanspec)) { + channel_list[0] = chanspec; + break; + } } - WL_SCAN(("chan: %d, chanspec: %x\n", target_channel, chanspec)); + WL_SCAN(("chan: %s-%d, chanspec: %x\n", + WLCBAND2STR(chan_info->band), chan_info->chan, chanspec)); } #endif @@ -1768,6 +1763,7 @@ wl_scan_prep(struct bcm_cfg80211 *cfg, struct net_device *ndev, void *scan_param struct cfg80211_scan_request *request) { #ifdef SCAN_SUPPRESS + struct wl_chan_info chan_info; u32 channel; #endif wl_scan_params_t *params = NULL; @@ -1847,14 +1843,14 @@ wl_scan_prep(struct bcm_cfg80211 *cfg, struct net_device *ndev, void *scan_param cur_offset = channel_offset; /* Copy channel array if applicable */ #ifdef SCAN_SUPPRESS - channel = wl_ext_scan_suppress(ndev, scan_params, cfg->scan_params_v2); + channel = wl_ext_scan_suppress(ndev, scan_params, cfg->scan_params_v2, &chan_info); if (channel) { n_channels = 1; if ((n_channels > 0) && chan_list) { if (len >= (scan_param_size + (n_channels * sizeof(u16)))) { wl_cfgscan_populate_scan_channel(cfg, request->channels, request->n_channels, - chan_list, channel); + chan_list, &chan_info); cur_offset += (n_channels * (sizeof(u16))); } } @@ -2643,12 +2639,13 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } } - mutex_lock(&cfg->scan_sync); #ifdef WL_EXT_IAPSTA - if (wl_ext_in4way_sync(ndev, STA_FAKE_SCAN_IN_CONNECT, WL_EXT_STATUS_SCANNING, NULL)) + if (wl_ext_in4way_sync(ndev, STA_FAKE_SCAN_IN_CONNECT, WL_EXT_STATUS_SCANNING, NULL)) { + mutex_lock(&cfg->scan_sync); goto scan_success; - else + } #endif + mutex_lock(&cfg->scan_sync); err = wl_do_escan(cfg, wiphy, ndev, request); if (likely(!err)) { goto scan_success; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.c index f6672a9a4042..fa08b8f44e18 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.c @@ -8520,12 +8520,12 @@ static int wl_cfgvendor_dbg_get_rx_pkt_fates(struct wiphy *wiphy, #endif /* DBG_PKT_MON */ #ifdef KEEP_ALIVE +/* max size of IP packet for keep alive */ +#define MKEEP_ALIVE_IP_PKT_MAX 256 + static int wl_cfgvendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { - /* max size of IP packet for keep alive */ - const int MKEEP_ALIVE_IP_PKT_MAX = 256; - int ret = BCME_OK, rem, type; uint8 mkeep_alive_id = 0; uint8 *ip_pkt = NULL; @@ -8645,6 +8645,15 @@ static int wl_cfgvendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_de #endif /* KEEP_ALIVE */ #if defined(PKT_FILTER_SUPPORT) && defined(APF) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) +const struct nla_policy apf_atrribute_policy[APF_ATTRIBUTE_MAX] = { + [APF_ATTRIBUTE_VERSION] = { .type = NLA_U32 }, + [APF_ATTRIBUTE_MAX_LEN] = { .type = NLA_U32 }, + [APF_ATTRIBUTE_PROGRAM] = { .type = NLA_BINARY }, + [APF_ATTRIBUTE_PROGRAM_LEN] = { .type = NLA_U32 }, +}; +#endif /* LINUX_VERSION >= 5.3 */ + static int wl_cfgvendor_apf_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) @@ -9033,6 +9042,306 @@ exit: } #endif /* WL_SAR_TX_POWER */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) +const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = { + [ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_FEATURE_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_RANDOM_MAC_OUI] = { .type = NLA_NUL_STRING, .len = 3 }, + [ANDR_WIFI_ATTRIBUTE_NODFS_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_COUNTRY] = { .type = NLA_NUL_STRING, .len = 3 }, + [ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE] = { .type = NLA_U8 }, + [ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_LATENCY_MODE] = { .type = NLA_U32, .len = sizeof(uint32) }, + [ANDR_WIFI_ATTRIBUTE_RANDOM_MAC] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO] = { .type = NLA_S8 }, + [ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION] = { .type = NLA_S8 }, + [ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_VOIP_MODE] = { .type = NLA_U32, .len = sizeof(uint32) }, + [ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER] = { .type = NLA_U32, .len = sizeof(uint32) }, +}; + +const struct nla_policy dump_buf_policy[DUMP_BUF_ATTR_MAX] = { + [DUMP_BUF_ATTR_MEMDUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C0_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C0_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C1_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C1_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C2_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C2_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_DIG_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_DIG_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_TIMESTAMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_GENERAL_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_ECNTRS] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SPECIAL_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_DHD_DUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_EXT_TRAP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_HEALTH_CHK] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PRESERVE_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_COOKIE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_FLOWRING_DUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTLOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTLOG_DEBUG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_STATUS_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_AXI_ERROR] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_RTT_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SDTC_ETB_DUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTID_MAP_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTID_UNMAP_LOG] = { .type = NLA_BINARY }, +}; + +const struct nla_policy brcm_drv_attr_policy[BRCM_ATTR_DRIVER_MAX] = { + [BRCM_ATTR_DRIVER_CMD] = { .type = NLA_NUL_STRING }, + [BRCM_ATTR_DRIVER_KEY_PMK] = { .type = NLA_BINARY, .len = WSEC_MAX_PASSPHRASE_LEN }, + [BRCM_ATTR_DRIVER_FEATURE_FLAGS] = { .type = NLA_BINARY, .len = + ((BRCM_WLAN_VENDOR_FEATURES_MAX / 8) + 1) }, + [BRCM_ATTR_DRIVER_RAND_MAC] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [BRCM_ATTR_SAE_PWE] = { .type = NLA_U32 }, +}; + +#ifdef RTT_SUPPORT +const struct nla_policy rtt_attr_policy[RTT_ATTRIBUTE_MAX] = { + [RTT_ATTRIBUTE_TARGET_CNT] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_INFO] = { .type = NLA_NESTED }, + [RTT_ATTRIBUTE_TARGET_MAC] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [RTT_ATTRIBUTE_TARGET_TYPE] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_PEER] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_CHAN] = { .type = NLA_BINARY }, + [RTT_ATTRIBUTE_TARGET_PERIOD] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_BURST] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_LCI] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_LCR] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_BURST_DURATION] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_PREAMBLE] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_BW] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_RESULTS_COMPLETE] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_RESULTS_PER_TARGET] = { .type = NLA_NESTED }, + [RTT_ATTRIBUTE_RESULT_CNT] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_RESULT] = { .type = NLA_BINARY, .len = sizeof(rtt_result_t) }, + [RTT_ATTRIBUTE_RESULT_DETAIL] = { .type = NLA_BINARY, + .len = sizeof(struct rtt_result_detail) }, +}; +#endif /* RTT_SUPPORT */ + +#ifdef KEEP_ALIVE +const struct nla_policy mkeep_alive_attr_policy[MKEEP_ALIVE_ATTRIBUTE_MAX] = { + [MKEEP_ALIVE_ATTRIBUTE_ID] = { .type = NLA_U8 }, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = { .type = NLA_BINARY, .len = MKEEP_ALIVE_IP_PKT_MAX }, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = { .type = NLA_U16 }, + [MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = { .type = NLA_U32 }, + [MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE] = { .type = NLA_U16 } +}; +#endif /* KEEP_ALIVE */ +#ifdef WL_NAN +const struct nla_policy nan_attr_policy[NAN_ATTRIBUTE_MAX] = { + [NAN_ATTRIBUTE_2G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_5G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_CLUSTER_LOW] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_CLUSTER_HIGH] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SID_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SUB_SID_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SYNC_DISC_2G_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDF_2G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDF_5G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_HOP_COUNT_LIMIT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RANDOM_TIME] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_MASTER_PREF] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_OUI] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_WARMUP_TIME] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_24G_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_5G_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_CONF_CLUSTER_VAL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_DWELL_TIME] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCAN_PERIOD] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_DWELL_TIME_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCAN_PERIOD_5G] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_AVAIL_BIT_MAP] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENTRY_CONTROL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_CLOSE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_MIDDLE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_PROXIMITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_CLOSE_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_MIDDLE_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_PROXIMITY_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_WINDOW_SIZE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_CIPHER_SUITE_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCID_LEN] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SCID] = { .type = NLA_BINARY, .len = MAX_SCID_LEN }, + [NAN_ATTRIBUTE_2G_AWAKE_DW] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_5G_AWAKE_DW] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_DISC_IND_CFG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_CMD_USE_NDPE] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENABLE_MERGE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_NSS] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENABLE_RANGING] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_DW_EARLY_TERM] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_TRANSAC_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_PUBLISH_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO] = { .type = NLA_BINARY, .len = + NAN_MAX_SERVICE_SPECIFIC_INFO_LEN }, + [NAN_ATTRIBUTE_SUBSCRIBE_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SUBSCRIBE_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PERIOD] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_TTL] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_NAME_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_NAME] = { .type = NLA_BINARY, .len = WL_NAN_SVC_HASH_LEN }, + [NAN_ATTRIBUTE_PEER_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_INST_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SUBSCRIBE_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SUBSCRIBE_MATCH] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_MATCH] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SERVICERESPONSEFILTER] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_USESERVICERESPONSEFILTER] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_RX_MATCH_FILTER] = { .type = NLA_BINARY, .len = MAX_MATCH_FILTER_LEN }, + [NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_TX_MATCH_FILTER] = { .type = NLA_BINARY, .len = MAX_MATCH_FILTER_LEN }, + [NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_MAC_ADDR_LIST] = { .type = NLA_BINARY, .len = + (NAN_SRF_MAX_MAC*ETHER_ADDR_LEN) }, + [NAN_ATTRIBUTE_TX_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_SECURITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RECV_IND_CFG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_KEY_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_KEY_LEN] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_KEY_DATA] = { .type = NLA_BINARY, .len = NAN_MAX_PMK_LEN }, + [NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN] = { .type = NLA_U16, .len = + sizeof(uint16) }, + [NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO] = { .type = NLA_BINARY, .len = + MAX_SDEA_SVC_INFO_LEN }, + [NAN_ATTRIBUTE_SECURITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RANGING_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_INGRESS_LIMIT] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_EGRESS_LIMIT] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_INDICATION] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SVC_RESPONDER_POLICY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_NDP_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_IFACE] = { .type = NLA_BINARY, .len = IFNAMSIZ+1 }, + [NAN_ATTRIBUTE_QOS] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSP_CODE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_INST_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_IF_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_NO_CONFIG_AVAIL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_CHANNEL_INFO] = { .type = NLA_BINARY, .len = + sizeof(nan_channel_info_t) * NAN_MAX_CHANNEL_INFO_SUPPORTED }, + [NAN_ATTRIBUTE_NUM_CHANNELS] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_INSTANT_MODE_ENABLE] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_INSTANT_COMM_CHAN] = { .type = NLA_U32, .len = sizeof(uint32) }, +}; +#endif /* WL_NAN */ + +const struct nla_policy gscan_attr_policy[GSCAN_ATTRIBUTE_MAX] = { + [GSCAN_ATTRIBUTE_BAND] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_NUM_CHANNELS] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_CHANNEL_LIST] = { .type = NLA_BINARY }, + [GSCAN_ATTRIBUTE_WHITELIST_SSID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_SSID_LEN }, + [GSCAN_ATTRIBUTE_NUM_WL_SSID] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WL_SSID_LEN] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WL_SSID_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM] = { .type = NLA_NESTED }, + /* length is sizeof(wl_ssid_whitelist_t) * MAX_SSID_WHITELIST_NUM */ + [GSCAN_ATTRIBUTE_NUM_BSSID] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_PREF_LIST] = { .type = NLA_NESTED }, + /* length is sizeof(wl_bssid_pref_list_t) * MAX_BSSID_PREF_LIST_NUM */ + [GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_PREF] = { .type = NLA_BINARY, .len = ETH_ALEN }, + [GSCAN_ATTRIBUTE_RSSI_MODIFIER] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BLACKLIST_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, + [GSCAN_ATTRIBUTE_ROAM_STATE_SET] = { .type = NLA_U32 }, +}; + +#ifdef DHD_WAKE_STATUS +const struct nla_policy wake_stat_attr_policy[WAKE_STAT_ATTRIBUTE_MAX] = { + [WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT] = { .type = NLA_U32 }, +#ifdef CUSTOM_WAKE_REASON_STATS + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE] = { .type = NLA_BINARY, + .len = (MAX_WAKE_REASON_STATS * sizeof(int))}, +#else + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE] = { .type = NLA_BINARY, + .len = (WLC_E_LAST * sizeof(uint))}, +#endif /* CUSTOM_WAKE_REASON_STATS */ + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, +}; +#endif /* DHD_WAKE_STATUS */ + +#ifdef RSSI_MONITOR_SUPPORT +const struct nla_policy rssi_monitor_attr_policy[RSSI_MONITOR_ATTRIBUTE_MAX] = { + [RSSI_MONITOR_ATTRIBUTE_MAX_RSSI] = { .type = NLA_U32 }, + [RSSI_MONITOR_ATTRIBUTE_MIN_RSSI] = { .type = NLA_U32 }, + [RSSI_MONITOR_ATTRIBUTE_START] = { .type = NLA_U32 } +}; +#endif /* RSSI_MONITOR_SUPPORT */ + + +const struct nla_policy hal_start_attr_policy[SET_HAL_START_ATTRIBUTE_MAX] = { + [0] = { .strict_start_type = 0 }, + [SET_HAL_START_ATTRIBUTE_DEINIT] = { .type = NLA_UNSPEC }, + [SET_HAL_START_ATTRIBUTE_PRE_INIT] = { .type = NLA_NUL_STRING }, + [SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID] = { .type = NLA_U32 }, +}; + +const struct nla_policy andr_dbg_policy[DEBUG_ATTRIBUTE_MAX] = { + [DEBUG_ATTRIBUTE_GET_DRIVER] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_GET_FW] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_ID] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_RING_NAME] = { .type = NLA_NUL_STRING }, + [DEBUG_ATTRIBUTE_RING_FLAGS] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_LEVEL] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_TIME_INTVAL] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_FW_DUMP_LEN] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_FW_DUMP_DATA] = { .type = NLA_U64 }, + [DEBUG_ATTRIBUTE_FW_ERR_CODE] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_RING_DATA] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_STATUS] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_NUM] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_PKT_FATE_NUM] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_PKT_FATE_DATA] = { .type = NLA_U64 }, + [DEBUG_ATTRIBUTE_HANG_REASON] = { .type = NLA_BINARY }, +}; +#endif /* LINUX_VERSION >= 5.3 */ + static struct wiphy_vendor_command wl_vendor_cmds [] = { { { @@ -9040,7 +9349,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_PRIV_STR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_priv_string_handler + .doit = wl_cfgvendor_priv_string_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef BCM_PRIV_CMD_SUPPORT { @@ -9049,7 +9362,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_BCM_STR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_priv_bcm_handler + .doit = wl_cfgvendor_priv_bcm_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* BCM_PRIV_CMD_SUPPORT */ #if defined(WL_SAE) || defined(WL_CLIENT_SAE) @@ -9068,7 +9385,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_connect_params_handler + .doit = wl_cfgvendor_connect_params_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9076,7 +9397,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_START_AP_PARAMS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_start_ap_params_handler + .doit = wl_cfgvendor_start_ap_params_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef GSCAN_SUPPORT { @@ -9143,7 +9468,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_gscan_get_channel_list + .doit = wl_cfgvendor_gscan_get_channel_list, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */ #ifdef RTT_SUPPORT @@ -9153,7 +9482,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_SET_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_set_config + .doit = wl_cfgvendor_rtt_set_config, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9161,7 +9494,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_CANCEL_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_cancel_config + .doit = wl_cfgvendor_rtt_cancel_config, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9169,7 +9506,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_GETCAPABILITY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_get_capability + .doit = wl_cfgvendor_rtt_get_capability, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9177,7 +9518,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_GETAVAILCHANNEL }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_get_responder_info + .doit = wl_cfgvendor_rtt_get_responder_info, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9185,7 +9530,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_SET_RESPONDER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_set_responder + .doit = wl_cfgvendor_rtt_set_responder, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9193,7 +9542,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_CANCEL_RESPONDER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_cancel_responder + .doit = wl_cfgvendor_rtt_cancel_responder, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* RTT_SUPPORT */ { @@ -9202,7 +9555,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_feature_set + .doit = wl_cfgvendor_get_feature_set, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9210,7 +9567,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .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 + .doit = wl_cfgvendor_get_feature_set_matrix, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9218,7 +9579,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_RANDOM_MAC_OUI }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_rand_mac_oui + .doit = wl_cfgvendor_set_rand_mac_oui, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef CUSTOM_FORCE_NODFS_FLAG { @@ -9227,7 +9592,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_NODFS_CHANNELS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_nodfs_flag + .doit = wl_cfgvendor_set_nodfs_flag, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* CUSTOM_FORCE_NODFS_FLAG */ { @@ -9236,7 +9605,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_SET_COUNTRY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_country + .doit = wl_cfgvendor_set_country, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef LINKSTAT_SUPPORT { @@ -9294,7 +9667,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_SSID_WHITELIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_ssid_whitelist + .doit = wl_cfgvendor_set_ssid_whitelist, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { @@ -9303,7 +9680,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_BSSID_BLACKLIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_bssid_blacklist + .doit = wl_cfgvendor_set_bssid_blacklist, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* GSCAN_SUPPORT || ROAMEXP_SUPPORT */ #ifdef ROAMEXP_SUPPORT @@ -9313,7 +9694,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_FW_ROAM_POLICY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_fw_roaming_state + .doit = wl_cfgvendor_set_fw_roaming_state, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9330,7 +9715,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_VER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_version + .doit = wl_cfgvendor_dbg_get_version, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef DHD_LOG_DUMP { @@ -9339,7 +9728,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_FILE_DUMP_BUF }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_file_dump + .doit = wl_cfgvendor_dbg_file_dump, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = dump_buf_policy, + .maxattr = DUMP_BUF_ATTR_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHD_LOG_DUMP */ @@ -9358,7 +9751,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_MEM_DUMP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_mem_dump + .doit = wl_cfgvendor_dbg_get_mem_dump, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9366,7 +9763,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_START_LOGGING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_start_logging + .doit = wl_cfgvendor_dbg_start_logging, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9382,7 +9783,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RING_STATUS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_ring_status + .doit = wl_cfgvendor_dbg_get_ring_status, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9390,7 +9795,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RING_DATA }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_ring_data + .doit = wl_cfgvendor_dbg_get_ring_data, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DEBUGABILITY */ { @@ -9416,7 +9825,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_TX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_tx_pkt_fates + .doit = wl_cfgvendor_dbg_get_tx_pkt_fates, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9424,7 +9837,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_rx_pkt_fates + .doit = wl_cfgvendor_dbg_get_rx_pkt_fates, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DBG_PKT_MON */ #ifdef KEEP_ALIVE @@ -9434,7 +9851,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_start_mkeep_alive + .doit = wl_cfgvendor_start_mkeep_alive, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = mkeep_alive_attr_policy, + .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9442,7 +9863,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_stop_mkeep_alive + .doit = wl_cfgvendor_stop_mkeep_alive, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = mkeep_alive_attr_policy, + .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* KEEP_ALIVE */ #ifdef WL_NAN @@ -9452,7 +9877,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_ENABLE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_start_handler + .doit = wl_cfgvendor_nan_start_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9460,7 +9889,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DISABLE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_stop_handler + .doit = wl_cfgvendor_nan_stop_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9468,7 +9901,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_config_handler + .doit = wl_cfgvendor_nan_config_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9476,7 +9913,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_REQUEST_PUBLISH }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_req_publish + .doit = wl_cfgvendor_nan_req_publish, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9484,7 +9925,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_REQUEST_SUBSCRIBE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_req_subscribe + .doit = wl_cfgvendor_nan_req_subscribe, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9492,7 +9937,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CANCEL_PUBLISH }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_cancel_publish + .doit = wl_cfgvendor_nan_cancel_publish, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9500,7 +9949,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CANCEL_SUBSCRIBE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_cancel_subscribe + .doit = wl_cfgvendor_nan_cancel_subscribe, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9508,7 +9961,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_TRANSMIT }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_transmit + .doit = wl_cfgvendor_nan_transmit, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9525,7 +9982,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_IFACE_CREATE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_iface_create + .doit = wl_cfgvendor_nan_data_path_iface_create, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9533,7 +9994,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_IFACE_DELETE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_iface_delete + .doit = wl_cfgvendor_nan_data_path_iface_delete, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9541,7 +10006,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_REQUEST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_request + .doit = wl_cfgvendor_nan_data_path_request, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9549,7 +10018,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_RESPONSE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_response + .doit = wl_cfgvendor_nan_data_path_response, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9557,7 +10030,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_END }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_end + .doit = wl_cfgvendor_nan_data_path_end, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef WL_NAN_DISC_CACHE { @@ -9566,7 +10043,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_SEC_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_sec_info + .doit = wl_cfgvendor_nan_data_path_sec_info, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_NAN_DISC_CACHE */ { @@ -9583,7 +10064,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_ENABLE_MERGE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_enable_merge + .doit = wl_cfgvendor_nan_enable_merge, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_NAN */ #if defined(PKT_FILTER_SUPPORT) && defined(APF) @@ -9593,7 +10078,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = APF_SUBCMD_GET_CAPABILITIES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_apf_get_capabilities + .doit = wl_cfgvendor_apf_get_capabilities, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = apf_atrribute_policy, + .maxattr = APF_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { @@ -9602,7 +10091,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = APF_SUBCMD_SET_FILTER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_apf_set_filter + .doit = wl_cfgvendor_apf_set_filter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = apf_atrribute_policy, + .maxattr = APF_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* PKT_FILTER_SUPPORT && APF */ #ifdef NDO_CONFIG_SUPPORT @@ -9612,7 +10105,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_CONFIG_ND_OFFLOAD }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_configure_nd_offload + .doit = wl_cfgvendor_configure_nd_offload, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* NDO_CONFIG_SUPPORT */ #ifdef RSSI_MONITOR_SUPPORT @@ -9622,7 +10119,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_rssi_monitor + .doit = wl_cfgvendor_set_rssi_monitor, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rssi_monitor_attr_policy, + .maxattr = RSSI_MONITOR_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* RSSI_MONITOR_SUPPORT */ #ifdef DHD_WAKE_STATUS @@ -9632,7 +10133,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_WAKE_REASON_STATS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_wake_reason_stats + .doit = wl_cfgvendor_get_wake_reason_stats, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = wake_stat_attr_policy, + .maxattr = WAKE_STAT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHD_WAKE_STATUS */ #ifdef DHDTCPACK_SUPPRESS @@ -9642,7 +10147,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_CONFIG_TCPACK_SUP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_tcpack_sup_mode + .doit = wl_cfgvendor_set_tcpack_sup_mode, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHDTCPACK_SUPPRESS */ #if !defined(BCMSUP_4WAY_HANDSHAKE) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) @@ -9652,7 +10161,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_PMK }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_pmk + .doit = wl_cfgvendor_set_pmk, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* !BCMSUP_4WAY_HANDSHAKE || LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) */ { @@ -9661,7 +10174,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_GET_FEATURES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_driver_feature + .doit = wl_cfgvendor_get_driver_feature, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #if defined(WL_CFG80211) && defined(DHD_FILE_DUMP_EVENT) { @@ -9680,7 +10197,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_SET_HAL_START }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_hal_started + .doit = wl_cfgvendor_set_hal_started, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = hal_start_attr_policy, + .maxattr = SET_HAL_START_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9696,7 +10217,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_SET_HAL_PID }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_hal_pid + .doit = wl_cfgvendor_set_hal_pid, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = hal_start_attr_policy, + .maxattr = SET_HAL_START_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_CFG80211 */ #ifdef WL_LATENCY_MODE @@ -9706,7 +10231,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_LATENCY_MODE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_latency_mode + .doit = wl_cfgvendor_set_latency_mode, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_LATENCY_MODE */ #ifdef WL_P2P_RAND @@ -9716,7 +10245,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_MAC }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV, - .doit = wl_cfgvendor_set_p2p_rand_mac + .doit = wl_cfgvendor_set_p2p_rand_mac, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_P2P_RAND */ #ifdef WL_SAR_TX_POWER @@ -9726,7 +10259,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_TX_POWER_SCENARIO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV, - .doit = wl_cfgvendor_tx_power_scenario + .doit = wl_cfgvendor_tx_power_scenario, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ } #endif /* WL_SAR_TX_POWER */ @@ -9786,7 +10323,9 @@ wl_cfgvendor_apply_cmd_policy(struct wiphy *wiphy) WL_INFORM(("Apply CMD_RAW_DATA policy\n")); for (i = 0; i < n_cmds; i++) { - wl_vendor_cmds[i].policy = VENDOR_CMD_RAW_DATA; + if (wl_vendor_cmds[i].policy == NULL) { + wl_vendor_cmds[i].policy = VENDOR_CMD_RAW_DATA; + } } } #endif /* LINUX VER >= 5.3 */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.h index 9fc40f7dc1e7..231163d229c5 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvendor.h @@ -387,6 +387,9 @@ enum gscan_ch_attributes { }; enum rtt_attributes { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + RTT_ATTRIBUTE_INVALID, +#endif RTT_ATTRIBUTE_TARGET_CNT, RTT_ATTRIBUTE_TARGET_INFO, RTT_ATTRIBUTE_TARGET_MAC, @@ -403,17 +406,23 @@ enum rtt_attributes { RTT_ATTRIBUTE_TARGET_BURST_DURATION, RTT_ATTRIBUTE_TARGET_PREAMBLE, RTT_ATTRIBUTE_TARGET_BW, - RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, + RTT_ATTRIBUTE_RESULTS_COMPLETE, RTT_ATTRIBUTE_RESULTS_PER_TARGET, RTT_ATTRIBUTE_RESULT_CNT, RTT_ATTRIBUTE_RESULT, - RTT_ATTRIBUTE_RESULT_DETAIL + RTT_ATTRIBUTE_RESULT_DETAIL, + /* Add any new RTT_ATTRIBUTE prior to RTT_ATTRIBUTE_MAX */ + RTT_ATTRIBUTE_MAX }; enum wifi_rssi_monitor_attr { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + RSSI_MONITOR_ATTRIBUTE_INVALID, +#endif RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, - RSSI_MONITOR_ATTRIBUTE_START + RSSI_MONITOR_ATTRIBUTE_START, + RSSI_MONITOR_ATTRIBUTE_MAX }; enum wifi_sae_key_attr { @@ -423,25 +432,30 @@ enum wifi_sae_key_attr { }; enum debug_attributes { - DEBUG_ATTRIBUTE_GET_DRIVER = 0, - DEBUG_ATTRIBUTE_GET_FW = 1, - DEBUG_ATTRIBUTE_RING_ID = 2, - DEBUG_ATTRIBUTE_RING_NAME = 3, - DEBUG_ATTRIBUTE_RING_FLAGS = 4, - DEBUG_ATTRIBUTE_LOG_LEVEL = 5, - DEBUG_ATTRIBUTE_LOG_TIME_INTVAL = 6, - DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE = 7, - DEBUG_ATTRIBUTE_FW_DUMP_LEN = 8, - DEBUG_ATTRIBUTE_FW_DUMP_DATA = 9, - DEBUG_ATTRIBUTE_FW_ERR_CODE = 10, - DEBUG_ATTRIBUTE_RING_DATA = 11, - DEBUG_ATTRIBUTE_RING_STATUS = 12, - DEBUG_ATTRIBUTE_RING_NUM = 13, - DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN = 14, - DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA = 15, - DEBUG_ATTRIBUTE_PKT_FATE_NUM = 16, - DEBUG_ATTRIBUTE_PKT_FATE_DATA = 17, - DEBUG_ATTRIBUTE_HANG_REASON = 18 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + DEBUG_ATTRIBUTE_INVALID, +#endif + DEBUG_ATTRIBUTE_GET_DRIVER, + DEBUG_ATTRIBUTE_GET_FW, + DEBUG_ATTRIBUTE_RING_ID, + DEBUG_ATTRIBUTE_RING_NAME, + DEBUG_ATTRIBUTE_RING_FLAGS, + DEBUG_ATTRIBUTE_LOG_LEVEL, + DEBUG_ATTRIBUTE_LOG_TIME_INTVAL, + DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE, + DEBUG_ATTRIBUTE_FW_DUMP_LEN, + DEBUG_ATTRIBUTE_FW_DUMP_DATA, + DEBUG_ATTRIBUTE_FW_ERR_CODE, + DEBUG_ATTRIBUTE_RING_DATA, + DEBUG_ATTRIBUTE_RING_STATUS, + DEBUG_ATTRIBUTE_RING_NUM, + DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN, + DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA, + DEBUG_ATTRIBUTE_PKT_FATE_NUM, + DEBUG_ATTRIBUTE_PKT_FATE_DATA, + DEBUG_ATTRIBUTE_HANG_REASON, + /* Please add new attributes from here to sync up old HAL */ + DEBUG_ATTRIBUTE_MAX }; typedef enum { @@ -512,18 +526,26 @@ typedef enum { DUMP_BUF_ATTR_PKTLOG_DEBUG = 21, DUMP_BUF_ATTR_STATUS_LOG = 22, DUMP_BUF_ATTR_AXI_ERROR = 23, - DUMP_BUF_ATTR_RTT_LOG = 24 + DUMP_BUF_ATTR_RTT_LOG = 24, + DUMP_BUF_ATTR_SDTC_ETB_DUMP = 25, + DUMP_BUF_ATTR_PKTID_MAP_LOG = 26, + DUMP_BUF_ATTR_PKTID_UNMAP_LOG = 27, /* Please add new attributes from here to sync up old HAL */ + DUMP_BUF_ATTR_MAX } EWP_DUMP_CMD_ATTRIBUTE; enum mkeep_alive_attributes { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + MKEEP_ALIVE_ATTRIBUTE_INVALID, +#endif MKEEP_ALIVE_ATTRIBUTE_ID, MKEEP_ALIVE_ATTRIBUTE_IP_PKT, MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, - MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE + MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE, + MKEEP_ALIVE_ATTRIBUTE_MAX }; typedef enum wl_vendor_event { @@ -578,6 +600,9 @@ typedef enum wl_vendor_event { } wl_vendor_event_t; enum andr_wifi_attr { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + ANDR_WIFI_ATTRIBUTE_INVALID, +#endif ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, ANDR_WIFI_ATTRIBUTE_RANDOM_MAC_OUI, @@ -587,13 +612,20 @@ enum andr_wifi_attr { ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE, ANDR_WIFI_ATTRIBUTE_LATENCY_MODE, ANDR_WIFI_ATTRIBUTE_RANDOM_MAC, - ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO + ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, + ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION, + ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW, + ANDR_WIFI_ATTRIBUTE_VOIP_MODE, + ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER, + /* Any new ANDR_WIFI attribute add prior to the ANDR_WIFI_ATTRIBUTE_MAX */ + ANDR_WIFI_ATTRIBUTE_MAX }; enum apf_attributes { APF_ATTRIBUTE_VERSION, APF_ATTRIBUTE_MAX_LEN, APF_ATTRIBUTE_PROGRAM, - APF_ATTRIBUTE_PROGRAM_LEN + APF_ATTRIBUTE_PROGRAM_LEN, + APF_ATTRIBUTE_MAX }; typedef enum wl_vendor_gscan_attribute { @@ -627,6 +659,9 @@ typedef enum gscan_complete_event { #ifdef DHD_WAKE_STATUS enum wake_stat_attributes { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || (ANDROID_VERSION >= 12) + WAKE_STAT_ATTRIBUTE_INVALID, +#endif WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT, WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE, WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT, @@ -646,7 +681,10 @@ enum wake_stat_attributes { WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS, WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT, WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT, - WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT + WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT, + WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO, + /* Please add new attributes from here to sync up old HAL */ + WAKE_STAT_ATTRIBUTE_MAX }; typedef struct rx_data_cnt_details_t { @@ -713,7 +751,9 @@ typedef struct wifi_roaming_capabilities { typedef enum { SET_HAL_START_ATTRIBUTE_DEINIT = 0x0001, SET_HAL_START_ATTRIBUTE_PRE_INIT = 0x0002, - SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003 + SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003, + /* Add any new HAL_START attribute prior to SET_HAL_START_ATTRIBUTE_MAX */ + SET_HAL_START_ATTRIBUTE_MAX } SET_HAL_START_ATTRIBUTE; /* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvif.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvif.c index 7a2d01faa96d..e3b60013b640 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvif.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgvif.c @@ -1342,7 +1342,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, WL_INFORM_MEM(("[%s] cfg_iftype changed to %d\n", ndev->name, type)); #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_update_iftype(ndev, netinfo->ifidx, wl_iftype); + wl_ext_iapsta_update_iftype(ndev, wl_iftype); #endif fail: @@ -1545,38 +1545,34 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, u32 bw = WL_CHANSPEC_BW_20; s32 err = BCME_OK; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); -#if defined(CUSTOM_SET_CPUCORE) || defined(APSTA_RESTRICTED_CHANNEL) || defined(WL_EXT_IAPSTA) +#if defined(CUSTOM_SET_CPUCORE) || defined(APSTA_RESTRICTED_CHANNEL) dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); - enum nl80211_band band; - s32 _chan; #endif /* CUSTOM_SET_CPUCORE || APSTA_RESTRICTED_CHANNEL */ u16 center_freq = chan->center_freq; dev = ndev_to_wlc_ndev(dev, cfg); #ifdef WL_EXT_IAPSTA - _chan = ieee80211_frequency_to_channel(chan->center_freq); if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) { u16 wl_iftype = 0; u16 wl_mode = 0; + + chspec = wl_freq_to_chanspec(chan->center_freq); if (cfg80211_to_wl_iftype(dev->ieee80211_ptr->iftype, &wl_iftype, &wl_mode) < 0) { WL_ERR(("Unknown interface type:0x%x\n", dev->ieee80211_ptr->iftype)); return -EINVAL; } - wl_ext_iapsta_update_iftype(dev, dhd_net2idx(dhd->info, dev), wl_iftype); - _chan = wl_ext_iapsta_update_channel(dev, _chan); - } - if (CHANNEL_IS_5G(_chan)) - band = NL80211_BAND_5GHZ; - else - band = NL80211_BAND_2GHZ; - center_freq = ieee80211_channel_to_frequency(_chan, band); + wl_ext_iapsta_update_iftype(dev, wl_iftype); + chspec = wl_ext_iapsta_update_channel(dev, chspec); + center_freq = wl_channel_to_frequency(wf_chspec_primary20_chan(chspec), + CHSPEC_BAND(chspec)); + } else #endif chspec = wl_freq_to_chanspec(center_freq); - WL_MSG(dev->name, "netdev_ifidx(%d), chan_type(%d) target channel(%d) \n", - dev->ifindex, channel_type, CHSPEC_CHANNEL(chspec)); + WL_MSG(dev->name, "netdev_ifidx(%d), chan_type(%d) target channel(%s-%d) \n", + dev->ifindex, channel_type, CHSPEC2BANDSTR(chspec), CHSPEC_CHANNEL(chspec)); #ifdef WL_P2P_6G if (!(cfg->p2p_6g_enabled)) { @@ -2804,7 +2800,7 @@ wl_cfg80211_set_ap_role( } #ifdef WLEASYMESH else if (dhd->conf->fw_type == FW_TYPE_EZMESH) { - WL_MSG(dev->name, "Getting AP mode ok, set map and dwds"); + WL_MSG(dev->name, "Getting AP mode ok, set map and dwds\n"); err = wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32)); if (err < 0) { WL_ERR(("WLC_DOWN error %d\n", err)); @@ -2821,7 +2817,7 @@ wl_cfg80211_set_ap_role( WL_ERR(("wl dwds 1 error %d\n", err)); return err; } - WL_MSG(dev->name, "Get AP %d", (int)ap); + WL_MSG(dev->name, "Get AP %d\n", (int)ap); } #endif /* WLEASYMESH*/ @@ -2839,10 +2835,10 @@ wl_cfg80211_set_ap_role( if (wl_get_drv_status_all(cfg, CONNECTED) > 0) { #ifdef WLEASYMESH if (dhd->conf->fw_type == FW_TYPE_EZMESH) { - WL_MSG(dev->name, "do wl down"); + WL_MSG(dev->name, "do wl down\n"); } else { #endif /* WLEASYMESH */ - WL_ERR(("Concurrent i/f operational. can't do wl down")); + WL_ERR(("Concurrent i/f operational. can't do wl down\n")); return BCME_ERROR; #ifdef WLEASYMESH } @@ -2872,7 +2868,7 @@ wl_cfg80211_set_ap_role( #ifdef WLEASYMESH //For FrontHaulAP if (dhd->conf->fw_type == FW_TYPE_EZMESH) { - WL_MSG(dev->name, "wl map 2"); + WL_MSG(dev->name, "wl map 2\n"); err = wldev_iovar_setint(dev, "map", 2); if (err < 0) { WL_ERR(("wl map 2 error %d\n", err)); @@ -2985,7 +2981,7 @@ wl_cfg80211_bcn_bringup_ap( s32 err = BCME_OK; dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); s32 is_rsdb_supported = BCME_ERROR; - char sec[32]; + char sec[64]; #if defined (BCMDONGLEHOST) is_rsdb_supported = DHD_OPMODE_SUPPORTED(cfg->pub, DHD_FLAG_RSDB_MODE); @@ -3090,6 +3086,14 @@ wl_cfg80211_bcn_bringup_ap( } #endif /* SOFTAP_UAPSD_OFF */ +#ifdef WLDWDS + err = wldev_iovar_setint(dev, "dwds", 1); + if (err < 0) { + WL_ERR(("set dwds error %d\n", err)); + goto exit; + } +#endif /* WLDWDS */ + err = wldev_ioctl_set(dev, WLC_UP, &ap, sizeof(s32)); if (unlikely(err)) { WL_ERR(("WLC_UP error (%d)\n", err)); @@ -3131,12 +3135,23 @@ wl_cfg80211_bcn_bringup_ap( } if (dhd->conf->chip == BCM43430_CHIP_ID && bssidx > 0 && (wsec & (TKIP_ENABLED|AES_ENABLED))) { + struct net_device *primary_ndev = bcmcfg_to_prmry_ndev(cfg); + struct ether_addr bssid; + int ret = 0; wsec |= WSEC_SWFLAG; // terence 20180628: fix me, this is a workaround err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); if (err < 0) { WL_ERR(("wsec error %d\n", err)); goto exit; } + bzero(&bssid, sizeof(bssid)); + ret = wldev_ioctl_get(primary_ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN); + if (ret != BCME_NOTASSOCIATED && memcmp(ðer_null, &bssid, ETHER_ADDR_LEN)) { + scb_val_t scbval; + bzero(&scbval, sizeof(scb_val_t)); + scbval.val = WLAN_REASON_DEAUTH_LEAVING; + wldev_ioctl_set(primary_ndev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); + } } if ((wsec == WEP_ENABLED) && cfg->wep_key.len) { WL_DBG(("Applying buffered WEP KEY \n")); @@ -3622,7 +3637,7 @@ wl_cfg80211_start_ap( } wl_wlfc_enable(cfg, TRUE); #ifdef WL_EXT_IAPSTA - wl_ext_iapsta_update_iftype(dev, dhd_net2idx(dhd->info, dev), WL_IF_TYPE_AP); + wl_ext_iapsta_update_iftype(dev, WL_IF_TYPE_AP); #endif /* WL_EXT_IAPSTA */ #ifdef PKT_FILTER_SUPPORT /* Disable packet filter */ @@ -3720,7 +3735,7 @@ wl_cfg80211_start_ap( /* Set IEs to FW */ if ((err = wl_cfg80211_set_ies(dev, &info->beacon, bssidx)) < 0) WL_ERR(("Set IEs failed \n")); - + #ifdef WLDWDS if (dev->ieee80211_ptr->use_4addr) { if ((err = wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx, @@ -3757,6 +3772,9 @@ wl_cfg80211_start_ap( } } #endif /* SUPPORT_AP_RADIO_PWRSAVE */ +#ifdef WL_EXT_IAPSTA + wl_ext_in4way_sync(dev, 0, WL_EXT_STATUS_AP_ENABLING, NULL); +#endif fail: if (err) { WL_ERR(("ADD/SET beacon failed\n")); @@ -3852,6 +3870,9 @@ wl_cfg80211_stop_ap( err = -EINVAL; goto exit; } +#ifdef WL_EXT_IAPSTA + wl_ext_in4way_sync(dev, 0, WL_EXT_STATUS_AP_DISABLING, NULL); +#endif /* Free up resources */ wl_cfg80211_cleanup_if(dev); @@ -4542,6 +4563,11 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, wl_ext_in4way_sync(ndev, AP_WAIT_STA_RECONNECT, WL_EXT_STATUS_STA_CONNECTED, (void *)&e->addr); #endif +#ifdef STA_MGMT + if (!wl_ext_add_sta_info(ndev, (u8 *)&e->addr)) { + return -EINVAL; + } +#endif /* STA_MGMT */ cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC); #ifdef WL_WPS_SYNC wl_wps_session_update(ndev, WPS_STATE_LINKUP, e->addr.octet); @@ -4564,6 +4590,11 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev, wl_ext_in4way_sync(ndev, AP_WAIT_STA_RECONNECT, WL_EXT_STATUS_STA_DISCONNECTED, (void *)&e->addr); #endif +#ifdef STA_MGMT + if (!wl_ext_del_sta_info(ndev, (u8 *)&e->addr)) { + return -EINVAL; + } +#endif /* STA_MGMT */ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); #ifdef WL_WPS_SYNC wl_wps_session_update(ndev, WPS_STATE_LINKDOWN, e->addr.octet); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.c index 41f13a67590d..3311f4c9b1ae 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.c @@ -10,25 +10,25 @@ #define ESCAN_ERROR(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] ESCAN-ERROR) %s : " arg1, name, __func__, ## args); \ + printf("[%s] ESCAN-ERROR) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define ESCAN_TRACE(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] ESCAN-TRACE) %s : " arg1, name, __func__, ## args); \ + printf("[%s] ESCAN-TRACE) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define ESCAN_SCAN(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_SCAN_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] ESCAN-SCAN) %s : " arg1, name, __func__, ## args); \ + printf("[%s] ESCAN-SCAN) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define ESCAN_DBG(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_DBG_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] ESCAN-DBG) %s : " arg1, name, __func__, ## args); \ + printf("[%s] ESCAN-DBG) %s : " arg1, name, __func__, ## args); \ } \ } while (0) @@ -43,8 +43,14 @@ #define wl_escan_get_buf(a) ((wl_scan_results_t *) (a)->escan_buf) -#define for_each_bss(list, bss, __i) \ +#if defined(WL_WIRELESS_EXT) +extern int wl_iw_handle_scanresults_ies(char **event_p, char *end, + struct iw_request_info *info, wl_bss_info_t *bi); +#define for_each_bss_wext(list, bss, __i) \ for (__i = 0; __i < list->count && __i < IW_MAX_AP; __i++, bss = next_bss(list, bss)) +#endif +#define for_each_bss(list, bss, __i) \ + for (__i = 0; __i < list->count; __i++, bss = next_bss(list, bss)) #define wl_escan_set_sync_id(a) ((a) = htod16(0x1234)) @@ -277,7 +283,7 @@ wl_escan_inform_bss(struct net_device *dev, struct wl_escan_info *escan) wl_reset_bss_cache(&escan->g_bss_cache_ctrl); if (escan->autochannel) wl_ext_get_best_channel(dev, &escan->g_bss_cache_ctrl, - escan->ioctl_ver, &escan->best_2g_ch, &escan->best_5g_ch); + escan->ioctl_ver, &escan->best_2g_ch, &escan->best_5g_ch, &escan->best_6g_ch); #else bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { @@ -285,7 +291,7 @@ wl_escan_inform_bss(struct net_device *dev, struct wl_escan_info *escan) } if (escan->autochannel) wl_ext_get_best_channel(dev, bss_list, escan->ioctl_ver, - &escan->best_2g_ch, &escan->best_5g_ch); + &escan->best_2g_ch, &escan->best_5g_ch, &escan->best_6g_ch); #endif return err; @@ -689,7 +695,6 @@ wl_escan_prep(struct net_device *dev, struct wl_escan_info *escan, int i = 0, j = 0; wlc_ssid_t ssid_tmp; u32 n_channels = 0; - uint channel; chanspec_t chanspec; u32 n_ssids = 0; wl_scan_params_t *params = NULL; @@ -742,7 +747,7 @@ wl_escan_prep(struct net_device *dev, struct wl_escan_info *escan, params->scan_type = DOT11_SCANTYPE_ACTIVE; params->nprobes = htod32(-1); if (scan_info->scan_time) - params_v2->active_time = htod32(scan_info->scan_time); + params->active_time = htod32(scan_info->scan_time); else params->active_time = htod32(-1); params->passive_time = htod32(-1); @@ -754,29 +759,19 @@ wl_escan_prep(struct net_device *dev, struct wl_escan_info *escan, cur_offset = channel_offset; - n_channels = dtoh32(list->count); + n_channels = list->count; /* Copy channel array if applicable */ ESCAN_SCAN(dev->name, "### List of channelspecs to scan ###\n"); if (n_channels > 0) { for (i = 0; i < n_channels; i++) { - channel = dtoh32(list->element[i]); - if (!dhd_conf_match_channel(escan->pub, channel)) - continue; - chanspec = WL_CHANSPEC_BW_20; + chanspec = list->element[i]; if (chanspec == INVCHANSPEC) { ESCAN_ERROR(dev->name, "Invalid chanspec! Skipping channel\n"); continue; } - if (channel <= CH_MAX_2G_CHANNEL) { - chanspec |= WL_CHANSPEC_BAND_2G; - } else { - chanspec |= WL_CHANSPEC_BAND_5G; - } - chan_list[j] = channel; - chan_list[j] &= WL_CHANSPEC_CHAN_MASK; - chan_list[j] |= chanspec; + chan_list[j] = chanspec; ESCAN_SCAN(dev->name, "Chan : %d, Channel spec: %x\n", - channel, chan_list[j]); + CHSPEC_CHANNEL(chanspec), chanspec); chan_list[j] = wl_chspec_host_to_driver(escan->ioctl_ver, chan_list[j]); j++; @@ -895,7 +890,7 @@ wl_escan_set_scan(struct net_device *dev, wl_scan_info_t *scan_info) wl_escan_params_t *params = NULL; u32 n_channels = 0; wl_uint32_list_t *list; - u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; + u8 valid_chan_list[sizeof(u32)*(MAX_CTRL_CHANSPECS + 1)]; mutex_lock(&escan->usr_sync); if (escan->escan_state == ESCAN_STATE_DOWN) { @@ -917,7 +912,7 @@ wl_escan_set_scan(struct net_device *dev, wl_scan_info_t *scan_info) goto exit2; } - ESCAN_TRACE(dev->name, "Enter \n"); + ESCAN_TRACE(dev->name, "Enter\n"); if (escan->scan_params_v2) { params_size = (WL_SCAN_PARAMS_V2_FIXED_SIZE + @@ -934,18 +929,16 @@ wl_escan_set_scan(struct net_device *dev, wl_scan_info_t *scan_info) if (scan_info->channels.count) { memcpy(list, &scan_info->channels, sizeof(wl_channel_list_t)); } else { - list->count = htod32(WL_NUMCHANNELS); - err = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, - sizeof(valid_chan_list), false); + err = wl_construct_ctl_chanspec_list(dev, list); if (err != 0) { ESCAN_ERROR(dev->name, "get channels failed with %d\n", err); goto exit; } } - n_channels = dtoh32(list->count); + n_channels = list->count; /* Allocate space for populating ssids in wl_escan_params_t struct */ - if (dtoh32(list->count) % 2) + if (list->count % 2) /* If n_channels is odd, add a padd of u16 */ params_size += sizeof(u16) * (n_channels + 1); else @@ -1150,7 +1143,7 @@ wl_escan_merge_scan_list(struct net_device *dev, u8 *cur_bssid, bss_list = escan->bss_list; bi = next_bss(bss_list, bi); - for_each_bss(bss_list, bi, i) + for_each_bss_wext(bss_list, bi, i) { if (!memcmp(&bi->BSSID, cur_bssid, ETHER_ADDR_LEN)) { ESCAN_SCAN(dev->name, "skip connected AP %pM\n", cur_bssid); @@ -1379,7 +1372,7 @@ wl_escan_mesh_info_ie(struct net_device *dev, u8 *parse, u32 len, } bool -wl_escan_mesh_info(struct net_device *dev, struct wl_escan_info *escan, +wl_escan_mesh_info(struct net_device *dev, struct wl_escan_info *escan, struct ether_addr *peer_bssid, struct wl_mesh_params *mesh_info) { int i = 0; @@ -1450,7 +1443,7 @@ exit: } bool -wl_escan_mesh_peer(struct net_device *dev, struct wl_escan_info *escan, +wl_escan_mesh_peer(struct net_device *dev, struct wl_escan_info *escan, wlc_ssid_t *cur_ssid, uint16 cur_chan, bool sae, struct wl_mesh_params *mesh_info) { @@ -1759,4 +1752,3 @@ exit: } #endif /* WL_ESCAN */ - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.h index 5fbbd27ffc94..c77660d06f3e 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.h @@ -2,9 +2,11 @@ #ifndef _wl_escan_ #define _wl_escan_ #include +#if defined(WL_WIRELESS_EXT) #include -#include +#endif /* WL_WIRELESS_EXT */ #include +#include #include #define ESCAN_BUF_SIZE (64 * 1024) @@ -39,6 +41,7 @@ typedef struct wl_escan_info { int autochannel; int best_2g_ch; int best_5g_ch; + int best_6g_ch; #if defined(RSSIAVG) wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl; @@ -62,7 +65,7 @@ typedef struct wl_mesh_params { uint16 master_channel; uint hop_cnt; struct ether_addr peer_bssid[MAX_HOP_LIST]; - uint16 scan_channel; + uint32 scan_channel; } wl_mesh_params_t; bool wl_escan_mesh_info(struct net_device *dev, struct wl_escan_info *escan, struct ether_addr *peer_bssid, @@ -73,8 +76,10 @@ bool wl_escan_mesh_peer(struct net_device *dev, #endif /* WLMESH */ int wl_escan_set_scan(struct net_device *dev, wl_scan_info_t *scan_info); +#if defined(WL_WIRELESS_EXT) int wl_escan_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra); +#endif int wl_escan_attach(struct net_device *dev); void wl_escan_detach(struct net_device *dev); int wl_escan_event_attach(struct net_device *dev, int ifidx); @@ -83,4 +88,3 @@ int wl_escan_up(struct net_device *dev); void wl_escan_down(struct net_device *dev); #endif /* _wl_escan_ */ - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.c index f7ec74d8ad30..a89f3cdba775 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.c @@ -2,24 +2,23 @@ #include #ifdef WL_EVENT #include -#include #define EVENT_ERROR(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] EVENT-ERROR) %s : " arg1, name, __func__, ## args); \ + printf("[%s] EVENT-ERROR) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define EVENT_TRACE(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] EVENT-TRACE) %s : " arg1, name, __func__, ## args); \ + printf("[%s] EVENT-TRACE) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define EVENT_DBG(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_DBG_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] EVENT-DBG) %s : " arg1, name, __func__, ## args); \ + printf("[%s] EVENT-DBG) %s : " arg1, name, __func__, ## args); \ } \ } while (0) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.h index 0dfc7b235ed7..cae71544a05c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_event.h @@ -16,4 +16,3 @@ void wl_ext_event_deregister(struct net_device *dev, dhd_pub_t *dhd, uint32 event, void *cb_func); void wl_ext_event_send(void *params, const wl_event_msg_t * e, void *data); #endif - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_ext_genl.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_ext_genl.c index 044e56aebef2..e9bf46d4c7c7 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_ext_genl.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_ext_genl.c @@ -7,19 +7,19 @@ #define AGENL_ERROR(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] AGENL-ERROR) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AGENL-ERROR) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define AGENL_TRACE(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] AGENL-TRACE) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AGENL-TRACE) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define AGENL_INFO(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_INFO_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] AGENL-INFO) %s : " arg1, name, __func__, ## args); \ + printf("[%s] AGENL-INFO) %s : " arg1, name, __func__, ## args); \ } \ } while (0) @@ -419,7 +419,7 @@ wl_ext_genl_send(struct genl_params *zconf, struct net_device *dev, zconf->send_retry_cnt = 0; - return 0; + return 0; } static int diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c index 93e8445fffcb..bd23fde26ea5 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #ifdef WL_CFG80211 @@ -15,25 +16,25 @@ #define IAPSTA_ERROR(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIX "[%s] IAPSTA-ERROR) %s : " arg1, name, __func__, ## args); \ + printf("[%s] IAPSTA-ERROR) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define IAPSTA_TRACE(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] IAPSTA-TRACE) %s : " arg1, name, __func__, ## args); \ + printf("[%s] IAPSTA-TRACE) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define IAPSTA_INFO(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_INFO_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] IAPSTA-INFO) %s : " arg1, name, __func__, ## args); \ + printf("[%s] IAPSTA-INFO) %s : " arg1, name, __func__, ## args); \ } \ } while (0) #define IAPSTA_DBG(name, arg1, args...) \ do { \ if (android_msg_level & ANDROID_DBG_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIX "[%s] IAPSTA-DBG) %s : " arg1, name, __func__, ## args); \ + printf("[%s] IAPSTA-DBG) %s : " arg1, name, __func__, ## args); \ } \ } while (0) @@ -64,6 +65,14 @@ extern int disable_proptx; #define STA_RECONNECT_RETRY_TIMEOUT 300 #define STA_EAPOL_TIMEOUT 100 #define STA_EMPTY_SCAN_MAX 6 +#define AP_RESTART_TIMEOUT 1 +#define AP_TXBCNFRM_TIMEOUT 10 +#ifdef RXF0OVFL_REINIT_WAR +#define RXF0OVFL_POLLING_TIMEOUT 1 +#define RXF0OVFL_THRESHOLD 100 +#endif /* RXF0OVFL_REINIT_WAR */ + +#define MAX_DWDS_IF_NUM 4 enum wl_if_list { IF_PIF, @@ -120,6 +129,37 @@ typedef enum ENCMODE { ENC_TKIPAES } encmode_t; +#ifdef STA_MGMT +typedef struct wl_sta_info { + int ifidx; + struct ether_addr bssid; + struct list_head list; +} wl_sta_info_t; +#endif /* STA_MGMT */ + +#ifdef TPUT_MONITOR +typedef struct wl_tput_info { + unsigned long last_tx; + unsigned long last_rx; + struct osl_timespec tput_ts; + int32 tput_tx; + int32 tput_rx; + int32 tput_tx_kb; + int32 tput_rx_kb; +} wl_tput_info_t; +#endif /* TPUT_MONITOR */ + +#ifdef WLDWDS +typedef struct wl_dwds_info { + struct net_device *dev; + int ifidx; + uint8 bssidx; +#ifdef TPUT_MONITOR + struct wl_tput_info tput_info; +#endif /* TPUT_MONITOR */ +} wl_dwds_info_t; +#endif /* WLDWDS */ + typedef struct wl_if_info { struct net_device *dev; ifmode_t ifmode; @@ -134,7 +174,7 @@ typedef struct wl_if_info { bgnmode_t bgnmode; int hidden; int maxassoc; - uint16 channel; + struct wl_chan_info chan_info; authmode_t amode; encmode_t emode; bool vsdb; @@ -159,13 +199,7 @@ typedef struct wl_if_info { uint16 prev_channel; uint16 post_channel; #ifdef TPUT_MONITOR - unsigned long last_tx; - unsigned long last_rx; - struct osl_timespec tput_ts; - int32 tput_tx; - int32 tput_rx; - int32 tput_tx_kb; - int32 tput_rx_kb; + struct wl_tput_info tput_info; #endif /* TPUT_MONITOR */ timer_list_compat_t connect_timer; #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) @@ -186,10 +220,20 @@ typedef struct wl_if_info { #endif /* EAPOL_DYNAMATIC_RESEND */ #endif /* EAPOL_RESEND */ int empty_scan; +#ifdef RESTART_AP_WAR + timer_list_compat_t restart_ap_timer; +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + timer_list_compat_t reset_ap_timer; + uint32 txbcnfrm; +#endif /* RESET_AP_WAR */ } wl_if_info_t; typedef struct wl_apsta_params { struct wl_if_info if_info[MAX_IF_NUM]; +#ifdef WLDWDS + struct wl_dwds_info dwds_info[MAX_DWDS_IF_NUM]; +#endif /* WLDWDS */ struct dhd_pub *dhd; int ioctl_ver; bool init; @@ -229,6 +273,15 @@ typedef struct wl_apsta_params { #ifdef EAPOL_RESEND spinlock_t eapol_lock; #endif /* EAPOL_RESEND */ +#ifdef STA_MGMT + struct list_head sta_list; +#endif /* STA_MGMT */ +#ifdef RXF0OVFL_REINIT_WAR + timer_list_compat_t rxf0ovfl_timer; + uint32 rxbeaconmbss; + uint32 rxf0ovfl; + int war_reason; +#endif /* RXF0OVFL_REINIT_WAR */ } wl_apsta_params_t; enum wifi_isam_status { @@ -244,7 +297,10 @@ enum wifi_isam_reason { ISAM_RC_MESH_ACS = 1, ISAM_RC_TPUT_MONITOR = 2, ISAM_RC_AP_ACS = 3, - ISAM_RC_EAPOL_RESEND = 4 + ISAM_RC_AP_RESTART = 4, + ISAM_RC_AP_RESET = 5, + ISAM_RC_EAPOL_RESEND = 6, + ISAM_RC_RXF0OVFL_REINIT = 7 }; #define wl_get_isam_status(cur_if, stat) \ @@ -632,18 +688,40 @@ wl_ext_set_emode(struct wl_apsta_params *apsta_params, return 0; } -static u32 -wl_ext_get_chanspec(struct wl_apsta_params *apsta_params, - struct net_device *dev) +static void +wl_ext_set_chan_info(struct wl_if_info *cur_if, uint band, uint16 chan) +{ + cur_if->chan_info.band = band; + cur_if->chan_info.chan = chan; +} + +static bool +wl_ext_associated(struct net_device *dev) { - int ret = 0; struct ether_addr bssid; - u32 chanspec = 0; + int ret = 0; ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); if (ret != BCME_NOTASSOCIATED && memcmp(ðer_null, &bssid, ETHER_ADDR_LEN)) { + return TRUE; + } + + return FALSE; +} + +static u32 +wl_ext_get_chanspec(struct wl_apsta_params *apsta_params, + struct net_device *dev, struct wl_chan_info *chan_info) +{ + u32 chanspec = 0; + + if (wl_ext_associated(dev)) { if (wl_ext_iovar_getint(dev, "chanspec", (s32 *)&chanspec) == BCME_OK) { chanspec = wl_ext_chspec_driver_to_host(apsta_params->ioctl_ver, chanspec); + if (chan_info) { + chan_info->band = CHSPEC2WLC_BAND(chanspec); + chan_info->chan = wf_chspec_ctlchan(chanspec); + } return chanspec; } } @@ -652,75 +730,65 @@ wl_ext_get_chanspec(struct wl_apsta_params *apsta_params, } static uint16 -wl_ext_get_chan(struct wl_apsta_params *apsta_params, struct net_device *dev) +wl_ext_get_chan(struct wl_apsta_params *apsta_params, + struct net_device *dev, struct wl_chan_info *chan_info) { - int ret = 0; uint16 chan = 0, ctl_chan; - struct ether_addr bssid; u32 chanspec = 0; - - ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); - if (ret != BCME_NOTASSOCIATED && memcmp(ðer_null, &bssid, ETHER_ADDR_LEN)) { - if (wl_ext_iovar_getint(dev, "chanspec", (s32 *)&chanspec) == BCME_OK) { - chanspec = wl_ext_chspec_driver_to_host(apsta_params->ioctl_ver, chanspec); - ctl_chan = wf_chspec_ctlchan(chanspec); - chan = (u16)(ctl_chan & 0x00FF); - return chan; - } + + chanspec = wl_ext_get_chanspec(apsta_params, dev, chan_info); + if (chanspec) { + ctl_chan = wf_chspec_ctlchan(chanspec); + chan = (u16)(ctl_chan & 0x00FF); } - return 0; + return chan; } static chanspec_t wl_ext_chan_to_chanspec(struct wl_apsta_params *apsta_params, - struct net_device *dev, uint16 channel) + struct net_device *dev, struct wl_chan_info *chan_info) { - s32 _chan = channel; - chanspec_t chspec = 0; - chanspec_t fw_chspec = 0; + chanspec_band_t chanspec_band; + chanspec_t chspec = 0, fw_chspec = 0; u32 bw = WL_CHANSPEC_BW_20; - s32 err = BCME_OK; - s32 bw_cap = 0; + s32 err = BCME_OK, bw_cap = 0; s8 iovar_buf[WLC_IOCTL_SMLEN]; struct { u32 band; u32 bw_cap; } param = {0, 0}; - uint band; - if (_chan <= CH_MAX_2G_CHANNEL) - band = IEEE80211_BAND_2GHZ; - else - band = IEEE80211_BAND_5GHZ; - - if (band == IEEE80211_BAND_5GHZ) { - param.band = WLC_BAND_5G; - err = wl_ext_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - if (err) { - if (err != BCME_UNSUPPORTED) { - IAPSTA_ERROR(dev->name, "bw_cap failed, %d\n", err); - return err; - } else { - err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap); - if (bw_cap != WLC_N_BW_20ALL) - bw = WL_CHANSPEC_BW_40; - } - } else { - if (WL_BW_CAP_80MHZ(iovar_buf[0])) - bw = WL_CHANSPEC_BW_80; - else if (WL_BW_CAP_40MHZ(iovar_buf[0])) - bw = WL_CHANSPEC_BW_40; - else - bw = WL_CHANSPEC_BW_20; - } + if ((chan_info->band != WLC_BAND_2G) && (chan_info->band != WLC_BAND_5G) && + (chan_info->band != WLC_BAND_6G)) { + IAPSTA_ERROR(dev->name, "bad band %d\n", chan_info->band); + return BCME_BADBAND; + } + + param.band = chan_info->band; + err = wl_ext_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + if (err) { + if (err != BCME_UNSUPPORTED) { + IAPSTA_ERROR(dev->name, "bw_cap failed, %d\n", err); + return err; + } else { + err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap); + if (bw_cap != WLC_N_BW_20ALL) + bw = WL_CHANSPEC_BW_40; + } + } else { + if (WL_BW_CAP_80MHZ(iovar_buf[0])) + bw = WL_CHANSPEC_BW_80; + else if (WL_BW_CAP_40MHZ(iovar_buf[0])) + bw = WL_CHANSPEC_BW_40; + else + bw = WL_CHANSPEC_BW_20; } - else if (band == IEEE80211_BAND_2GHZ) - bw = WL_CHANSPEC_BW_20; set_channel: - chspec = wf_channel2chspec(_chan, bw); + chanspec_band = wl_ext_wlcband_to_chanspec_band(chan_info->band); + chspec = wf_create_chspec_from_primary(chan_info->chan, bw, chanspec_band); if (wf_chspec_valid(chspec)) { fw_chspec = wl_ext_chspec_host_to_driver(apsta_params->ioctl_ver, chspec); if (fw_chspec == INVCHANSPEC) { @@ -769,14 +837,11 @@ wl_ext_assoclist(struct net_device *dev, char *data, char *command, assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST); ret = wl_ext_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), 0); if (ret) - return -1; + return 0; maxassoc = dtoh32(assoc_maclist->count); - bytes_written += snprintf(command+bytes_written, total_len, - "%2s: %12s", - "no", "------addr------"); for (i=0; iea[i]); + "\n#%02d: %pM", i, &assoc_maclist->ea[i]); } return bytes_written; @@ -809,7 +874,7 @@ wl_ext_send_event_msg(struct net_device *dev, int event, int status) bzero(&msg, sizeof(wl_event_msg_t)); - msg.ifidx = hton32(cur_if->ifidx); + msg.ifidx = dhd_net2idx(dhd->info, dev); msg.event_type = hton32(event); msg.status = hton32(status); memcpy(&msg.addr, &cur_if->bssid, ETHER_ADDR_LEN); @@ -827,17 +892,23 @@ wl_ext_send_event_msg(struct net_device *dev, int event, int status) static void wl_ext_connect_timeout(unsigned long data) { - struct wl_if_info *cur_if = (struct wl_if_info *)data; + struct net_device *dev = (struct net_device *)data; + struct wl_if_info *cur_if; - if (!cur_if) { - IAPSTA_ERROR("wlan", "cur_if is not ready\n"); + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); return; } + + cur_if = wl_get_cur_if(dev); + if (!cur_if) + return; + #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) cur_if->assoc_info.reassoc = 0; #endif /* WL_EXT_RECONNECT && WL_CFG80211 */ - IAPSTA_ERROR(cur_if->dev->name, "timer expired\n"); - wl_ext_send_event_msg(cur_if->dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS); + IAPSTA_ERROR(dev->name, "timer expired\n"); + wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS); } #if defined(WL_CFG80211) || (defined(WLMESH) && defined(WL_ESCAN)) @@ -851,7 +922,7 @@ wl_ext_if_enabled(struct wl_apsta_params *apsta_params, ifmode_t ifmode) tmp_if = &apsta_params->if_info[i]; if (tmp_if && tmp_if->ifmode == ifmode && wl_get_isam_status(tmp_if, IF_READY)) { - if (wl_ext_get_chan(apsta_params, tmp_if->dev)) { + if (wl_ext_associated(tmp_if->dev)) { target_if = tmp_if; break; } @@ -939,7 +1010,7 @@ wl_ext_mesh_peer_status(struct net_device *dev, char *data, char *command, peer_buf = kmalloc(peer_len, GFP_KERNEL); if (peer_buf == NULL) { IAPSTA_ERROR(dev->name, "Failed to allocate buffer of %d bytes\n", - peer_len); + peer_len); return -1; } cur_if = wl_get_cur_if(dev); @@ -969,25 +1040,21 @@ wl_ext_mesh_peer_status(struct net_device *dev, char *data, char *command, static void wl_mesh_timer(unsigned long data) { - wl_event_msg_t msg; - struct wl_if_info *mesh_if = (struct wl_if_info *)data; + struct net_device *dev = (struct net_device *)data; struct dhd_pub *dhd; + wl_event_msg_t msg; - if (!mesh_if) { - IAPSTA_ERROR("wlan", "mesh_if is not ready\n"); + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); return; } - if (!mesh_if->dev) { - IAPSTA_ERROR("wlan", "ifidx %d is not ready\n", mesh_if->ifidx); - return; - } - dhd = dhd_get_pub(mesh_if->dev); + dhd = dhd_get_pub(dev); bzero(&msg, sizeof(wl_event_msg_t)); - IAPSTA_TRACE(mesh_if->dev->name, "timer expired\n"); + IAPSTA_TRACE(dev->name, "timer expired\n"); - msg.ifidx = mesh_if->ifidx; + msg.ifidx = dhd_net2idx(dhd->info, dev); msg.event_type = hton32(WLC_E_RESERVED); msg.reason = hton32(ISAM_RC_MESH_ACS); wl_ext_event_send(dhd->event_params, &msg, NULL); @@ -1073,7 +1140,8 @@ wl_mesh_clear_mesh_info(struct wl_apsta_params *apsta_params, ret = wl_mesh_clear_vndr_ie(mesh_if->dev, mesh_oui); memset(mesh_info, 0, sizeof(struct wl_mesh_params)); if (scan) { - mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev); + mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev, + &mesh_if->chan_info); wl_ext_mod_timer(&mesh_if->delay_scan, 0, 100); } @@ -1097,7 +1165,7 @@ wl_mesh_update_vndr_ie(struct wl_apsta_params *apsta_params, vndr_ie = kmalloc(vndr_ie_len, GFP_KERNEL); if (vndr_ie == NULL) { IAPSTA_ERROR(mesh_if->dev->name, "Failed to allocate buffer of %d bytes\n", - WLC_IOCTL_MEDLEN); + WLC_IOCTL_MEDLEN); ret = -1; goto exit; } @@ -1123,7 +1191,7 @@ wl_mesh_update_vndr_ie(struct wl_apsta_params *apsta_params, peer_bssid = (uint8 *)&mesh_info->peer_bssid[i]; bytes_written += snprintf(vndr_ie+bytes_written, vndr_ie_len, "%02x%02x%02x%02x%02x%02x", - peer_bssid[0], peer_bssid[1], peer_bssid[2], + peer_bssid[0], peer_bssid[1], peer_bssid[2], peer_bssid[3], peer_bssid[4], peer_bssid[5]); } @@ -1132,7 +1200,7 @@ wl_mesh_update_vndr_ie(struct wl_apsta_params *apsta_params, if (!ret) { IAPSTA_INFO(mesh_if->dev->name, "mbssid=%pM, mchannel=%d, hop=%d, pbssid=%pM\n", &mesh_info->master_bssid, mesh_info->master_channel, mesh_info->hop_cnt, - mesh_info->peer_bssid); + mesh_info->peer_bssid); } exit: @@ -1153,7 +1221,8 @@ wl_mesh_update_master_info(struct wl_apsta_params *apsta_params, if (sta_if) { wldev_ioctl(mesh_if->dev, WLC_GET_BSSID, &mesh_info->master_bssid, ETHER_ADDR_LEN, 0); - mesh_info->master_channel = wl_ext_get_chan(apsta_params, mesh_if->dev); + mesh_info->master_channel = wl_ext_get_chan(apsta_params, mesh_if->dev, + &mesh_if->chan_info); mesh_info->hop_cnt = 0; memset(mesh_info->peer_bssid, 0, MAX_HOP_LIST*ETHER_ADDR_LEN); if (!wl_mesh_update_vndr_ie(apsta_params, mesh_if)) @@ -1179,7 +1248,7 @@ wl_mesh_update_mesh_info(struct wl_apsta_params *apsta_params, dump_buf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); if (dump_buf == NULL) { IAPSTA_ERROR(mesh_if->dev->name, "Failed to allocate buffer of %d bytes\n", - WLC_IOCTL_MAXLEN); + WLC_IOCTL_MAXLEN); return FALSE; } count = wl_mesh_get_peer_results(mesh_if->dev, dump_buf, WLC_IOCTL_MAXLEN); @@ -1222,14 +1291,15 @@ wl_mesh_update_mesh_info(struct wl_apsta_params *apsta_params, if (!mesh_info->master_channel) { wlc_ssid_t cur_ssid; - char sec[32]; + char sec[64]; bool sae = FALSE; memset(&peer_mesh_info, 0, sizeof(struct wl_mesh_params)); wl_ext_ioctl(mesh_if->dev, WLC_GET_SSID, &cur_ssid, sizeof(cur_ssid), 0); wl_ext_get_sec(mesh_if->dev, mesh_if->ifmode, sec, sizeof(sec), FALSE); if (strnicmp(sec, "sae/sae", strlen("sae/sae")) == 0) sae = TRUE; - cur_chan = wl_ext_get_chan(apsta_params, mesh_if->dev); + cur_chan = wl_ext_get_chan(apsta_params, mesh_if->dev, + &mesh_if->chan_info); bss_found = wl_escan_mesh_peer(mesh_if->dev, mesh_if->escan, &cur_ssid, cur_chan, sae, &peer_mesh_info); @@ -1264,7 +1334,8 @@ wl_mesh_event_handler(struct wl_apsta_params *apsta_params, (event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS && reason == WLC_E_REASON_INITIAL_ASSOC))) { if (!wl_mesh_update_master_info(apsta_params, mesh_if)) { - mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev); + mesh_info->scan_channel = wl_ext_get_chan(apsta_params, &mesh_if->dev, + mesh_if->chan_info); wl_ext_mod_timer(&mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO, 0); } } @@ -1276,7 +1347,8 @@ wl_mesh_event_handler(struct wl_apsta_params *apsta_params, else if (wl_get_isam_status(mesh_if, AP_CREATED) && (event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) && reason == DOT11_SC_SUCCESS) { - mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev); + mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev, + &mesh_if->chan_info); wl_ext_mod_timer(&mesh_if->delay_scan, 0, 100); } else if (event_type == WLC_E_DISASSOC_IND || event_type == WLC_E_DEAUTH_IND || @@ -1290,8 +1362,10 @@ wl_mesh_event_handler(struct wl_apsta_params *apsta_params, wl_scan_info_t scan_info; memset(&scan_info, 0, sizeof(wl_scan_info_t)); wl_ext_ioctl(mesh_if->dev, WLC_GET_SSID, &scan_info.ssid, sizeof(wlc_ssid_t), 0); - scan_info.channels.count = 1; - scan_info.channels.channel[0] = mesh_info->scan_channel; + if (mesh_info->scan_channel) { + scan_info.channels.count = 1; + scan_info.channels.channel[0] = mesh_info->scan_channel; + } ret = wl_escan_set_scan(mesh_if->dev, &scan_info); if (ret) wl_ext_mod_timer(&mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO, 0); @@ -1330,7 +1404,7 @@ wl_mesh_escan_attach(dhd_pub_t *dhd, struct wl_if_info *mesh_if) IAPSTA_TRACE(mesh_if->dev->name, "Enter\n"); mesh_if->escan = dhd->escan; - init_timer_compat(&mesh_if->delay_scan, wl_mesh_timer, mesh_if); + init_timer_compat(&mesh_if->delay_scan, wl_mesh_timer, mesh_if->dev); return 0; } @@ -1350,7 +1424,7 @@ wl_mesh_update_peer_path(struct wl_if_info *mesh_if, char *command, dump_buf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); if (dump_buf == NULL) { IAPSTA_ERROR(mesh_if->dev->name, "Failed to allocate buffer of %d bytes\n", - WLC_IOCTL_MAXLEN); + WLC_IOCTL_MAXLEN); return FALSE; } count = wl_mesh_get_peer_results(mesh_if->dev, dump_buf, WLC_IOCTL_MAXLEN); @@ -1395,7 +1469,6 @@ wl_ext_isam_peer_path(struct net_device *dev, char *command, int total_len) struct wl_apsta_params *apsta_params = dhd->iapsta_params; struct wl_mesh_params *mesh_info = &apsta_params->mesh_info; struct wl_if_info *tmp_if; - uint16 chan = 0; char *dump_buf = NULL; int dump_len = WLC_IOCTL_MEDLEN; int dump_written = 0; @@ -1409,17 +1482,16 @@ wl_ext_isam_peer_path(struct net_device *dev, char *command, int total_len) dump_buf = kmalloc(dump_len, GFP_KERNEL); if (dump_buf == NULL) { IAPSTA_ERROR(dev->name, "Failed to allocate buffer of %d bytes\n", - dump_len); + dump_len); return -1; } } for (i=0; iif_info[i]; if (tmp_if->dev && tmp_if->ifmode == IMESH_MODE && apsta_params->macs) { - chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (chan) { + if (wl_ext_associated(tmp_if->dev)) { dump_written += snprintf(dump_buf+dump_written, dump_len, - DHD_LOG_PREFIX "[%s-%c] mbssid=%pM, mchan=%d, hop=%d, pbssid=%pM", + DHD_LOG_PREFIXS "[%s-%c] mbssid=%pM, mchan=%d, hop=%d, pbssid=%pM", tmp_if->ifname, tmp_if->prefix, &mesh_info->master_bssid, mesh_info->master_channel, mesh_info->hop_cnt, &mesh_info->peer_bssid); @@ -1486,6 +1558,7 @@ static int wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, bool force_enable, int wait_up) { + struct wl_chan_info *chan_info = &cur_if->chan_info; s8 iovar_buf[WLC_IOCTL_SMLEN]; struct { s32 cfg; @@ -1495,33 +1568,32 @@ wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, chanspec_t fw_chspec; u32 timeout; wlc_ssid_t ssid = { 0, {0} }; - uint16 chan = 0; + uint32 chanspec = 0; - if (cur_if->ifmode != IAP_MODE) { + if (cur_if->ifmode != IAP_MODE && cur_if->ifmode != IGO_MODE) { IAPSTA_ERROR(cur_if->ifname, "Wrong ifmode\n"); return 0; } - if (wl_ext_dfs_chan(cur_if->channel) && !apsta_params->radar && !force_enable) { + if (wl_ext_dfs_chan(chan_info) && !apsta_params->radar && !force_enable) { WL_MSG(cur_if->ifname, "[%c] skip DFS channel %d\n", - cur_if->prefix, cur_if->channel); + cur_if->prefix, chan_info->chan); return 0; - } else if (!cur_if->channel) { + } else if (!chan_info->chan) { WL_MSG(cur_if->ifname, "[%c] no valid channel\n", cur_if->prefix); return 0; } WL_MSG(cur_if->ifname, "[%c] Turning on...\n", cur_if->prefix); - wl_ext_set_chanspec(cur_if->dev, apsta_params->ioctl_ver, cur_if->channel, - &fw_chspec); + wl_ext_set_chanspec(cur_if->dev, chan_info, &fw_chspec); wl_clr_isam_status(cur_if, AP_CREATED); wl_set_isam_status(cur_if, AP_CREATING); if (apstamode == IAPONLY_MODE) { wl_ext_ioctl(cur_if->dev, WLC_UP, NULL, 0, 1); } else { - bss_setbuf.cfg = 0xffffffff; + bss_setbuf.cfg = 0xffffffff; bss_setbuf.val = htod32(1); wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), iovar_buf, WLC_IOCTL_SMLEN, NULL); @@ -1541,9 +1613,10 @@ wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, } wl_ext_ioctl(cur_if->dev, WLC_GET_SSID, &ssid, sizeof(ssid), 0); - chan = wl_ext_get_chan(apsta_params, cur_if->dev); - WL_MSG(cur_if->ifname, "[%c] enabled with SSID: \"%s\" on channel %d\n", - cur_if->prefix, ssid.SSID, chan); + chanspec = wl_ext_get_chanspec(apsta_params, cur_if->dev, chan_info); + WL_MSG(cur_if->ifname, "[%c] enabled with SSID: \"%s\" on channel %s-%d(0x%x)\n", + cur_if->prefix, ssid.SSID, CHSPEC2BANDSTR(chanspec), + chan_info->chan, chanspec); wl_clr_isam_status(cur_if, AP_CREATING); @@ -1553,22 +1626,34 @@ wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, } static bool -wl_ext_diff_band(uint16 chan1, uint16 chan2) +wl_ext_same_chan(struct wl_chan_info *chan_info_1, + struct wl_chan_info *chan_info_2) { - if ((chan1 <= CH_MAX_2G_CHANNEL && chan2 > CH_MAX_2G_CHANNEL) || - (chan1 > CH_MAX_2G_CHANNEL && chan2 <= CH_MAX_2G_CHANNEL)) { + if (chan_info_1->band == chan_info_2->band && + chan_info_1->chan == chan_info_2->chan) { + return TRUE; + } + return FALSE; +} + +static bool +wl_ext_rsdb_band(uint band_1, uint band_2) +{ + if ((band_1 == WLC_BAND_2G && band_2 != WLC_BAND_2G) || + (band_2 == WLC_BAND_2G && band_1 != WLC_BAND_2G)) { return TRUE; } return FALSE; } static uint16 -wl_ext_same_band(struct wl_apsta_params *apsta_params, +wl_ext_get_same_band_chan(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, bool nodfs) { struct wl_if_info *tmp_if; - uint16 tmp_chan, target_chan = 0; + struct wl_chan_info chan_info; wl_prio_t max_prio; + uint16 chan = 0; int i; // find the max prio @@ -1577,33 +1662,41 @@ wl_ext_same_band(struct wl_apsta_params *apsta_params, tmp_if = &apsta_params->if_info[i]; if (cur_if != tmp_if && wl_get_isam_status(tmp_if, IF_READY) && tmp_if->prio > max_prio) { - tmp_chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (wl_ext_dfs_chan(tmp_chan) && nodfs) + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info); + if (wl_ext_dfs_chan(&chan_info) && nodfs) continue; - if (tmp_chan && !wl_ext_diff_band(cur_if->channel, tmp_chan)) { - target_chan = tmp_chan; + if (chan_info.chan && (cur_if->chan_info.band == chan_info.band)) { + chan = chan_info.chan; max_prio = tmp_if->prio; } } } - return target_chan; + return chan; } static uint16 wl_ext_get_vsdb_chan(struct wl_apsta_params *apsta_params, - struct wl_if_info *cur_if, struct wl_if_info *target_if) + const struct wl_if_info *cur_if, const struct wl_if_info *target_if) { - uint16 target_chan = 0, cur_chan = cur_if->channel; + struct wl_chan_info chan_info; + uint cur_band = cur_if->chan_info.band; + uint16 cur_chan = cur_if->chan_info.chan; + uint target_band; + uint16 target_chan; if (cur_if->vsdb && target_if->vsdb) return 0; - target_chan = wl_ext_get_chan(apsta_params, target_if->dev); + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + target_chan = wl_ext_get_chan(apsta_params, target_if->dev, &chan_info); if (target_chan) { - IAPSTA_INFO(cur_if->ifname, "cur_chan=%d, target_chan=%d\n", - cur_chan, target_chan); - if (wl_ext_diff_band(cur_chan, target_chan)) { + target_band = chan_info.band; + IAPSTA_INFO(cur_if->ifname, "cur_chan=%s-%d, target_chan=%s-%d\n", + WLCBAND2STR(cur_band), cur_chan, + WLCBAND2STR(target_band), target_chan); + if (wl_ext_rsdb_band(cur_band, target_band)) { if (!apsta_params->rsdb) return target_chan; } else { @@ -1620,23 +1713,25 @@ wl_ext_rsdb_core_conflict(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { struct wl_if_info *tmp_if; - uint16 cur_chan, tmp_chan; + struct wl_chan_info cur_chan_info, tmp_chan_info; int i; if (apsta_params->rsdb) { - cur_chan = wl_ext_get_chan(apsta_params, cur_if->dev); + memset(&cur_chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &cur_chan_info); for (i=0; iif_info[i]; if (tmp_if != cur_if && wl_get_isam_status(tmp_if, IF_READY) && tmp_if->prio > cur_if->prio) { - tmp_chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (!tmp_chan) + memset(&tmp_chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, tmp_if->dev, &tmp_chan_info); + if (!tmp_chan_info.chan) continue; - if (wl_ext_diff_band(cur_chan, tmp_chan) && - wl_ext_diff_band(cur_chan, cur_if->channel)) + if (wl_ext_rsdb_band(cur_chan_info.band, tmp_chan_info.band) && + wl_ext_rsdb_band(cur_chan_info.band, cur_if->chan_info.chan)) return TRUE; - else if (!wl_ext_diff_band(cur_chan, tmp_chan) && - wl_ext_diff_band(cur_chan, cur_if->channel)) + else if (!wl_ext_rsdb_band(cur_chan_info.band, tmp_chan_info.band) && + wl_ext_rsdb_band(cur_chan_info.band, cur_if->chan_info.chan)) return TRUE; } } @@ -1651,11 +1746,11 @@ wl_ext_trigger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_ bool core_conflict = FALSE; if (wl_ext_master_if(cur_if) && (apsta_params->csa & CSA_DRV_BIT)) { - if (!cur_if->channel) { + if (!cur_if->chan_info.chan) { WL_MSG(cur_if->ifname, "[%c] no valid channel\n", cur_if->prefix); - } else if (wl_ext_dfs_chan(cur_if->channel) && !apsta_params->radar) { + } else if (wl_ext_dfs_chan(&cur_if->chan_info) && !apsta_params->radar) { WL_MSG(cur_if->ifname, "[%c] skip DFS channel %d\n", - cur_if->prefix, cur_if->channel); + cur_if->prefix, cur_if->chan_info.chan); wl_ext_if_down(apsta_params, cur_if); } else { wl_chan_switch_t csa_arg; @@ -1663,14 +1758,14 @@ wl_ext_trigger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_ csa_arg.mode = 1; csa_arg.count = 3; csa_arg.chspec = wl_ext_chan_to_chanspec(apsta_params, cur_if->dev, - cur_if->channel); + &cur_if->chan_info); core_conflict = wl_ext_rsdb_core_conflict(apsta_params, cur_if); if (core_conflict) { WL_MSG(cur_if->ifname, "[%c] Skip CSA due to rsdb core conflict\n", cur_if->prefix); } else if (csa_arg.chspec) { WL_MSG(cur_if->ifname, "[%c] Trigger CSA to channel %d(0x%x)\n", - cur_if->prefix, cur_if->channel, csa_arg.chspec); + cur_if->prefix, cur_if->chan_info.chan, csa_arg.chspec); wl_set_isam_status(cur_if, AP_CREATING); wl_ext_iovar_setbuf(cur_if->dev, "csa", &csa_arg, sizeof(csa_arg), iovar_buf, sizeof(iovar_buf), NULL); @@ -1690,128 +1785,125 @@ static void wl_ext_move_cur_dfs_channel(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { - uint16 other_chan = 0, cur_chan = cur_if->channel; + struct wl_chan_info *cur_chan_info = &cur_if->chan_info; + uint cur_band = cur_chan_info->band; + uint16 cur_chan = cur_chan_info->chan, auto_chan = 0; uint16 chan_2g = 0, chan_5g = 0; - uint32 auto_band = WLC_BAND_2G; - - if (wl_ext_master_if(cur_if) && wl_ext_dfs_chan(cur_if->channel) && - !apsta_params->radar) { + if (!apsta_params->radar && wl_ext_master_if(cur_if) && + wl_ext_dfs_chan(cur_chan_info)) { wl_ext_get_default_chan(cur_if->dev, &chan_2g, &chan_5g, TRUE); if (!chan_2g && !chan_5g) { - cur_if->channel = 0; + cur_chan_info->chan = 0; WL_MSG(cur_if->ifname, "[%c] no valid channel\n", cur_if->prefix); return; } - if (apsta_params->vsdb) { - if (chan_5g) { - cur_if->channel = chan_5g; - auto_band = WLC_BAND_5G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); - } else { - cur_if->channel = chan_2g; - auto_band = WLC_BAND_2G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); + if (chan_5g) + wl_ext_set_chan_info(cur_if, WLC_BAND_5G, chan_5g); + else + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, chan_2g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, cur_if, TRUE); + if (!auto_chan) { + auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, + cur_chan_info->band); } - if (!other_chan) { - other_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, - auto_band); - } - if (other_chan) - cur_if->channel = other_chan; - } else if (apsta_params->rsdb) { + if (auto_chan) + cur_chan_info->chan = auto_chan; + } + else if (apsta_params->rsdb) { if (chan_5g) { - cur_if->channel = chan_5g; - auto_band = WLC_BAND_5G; - other_chan = wl_ext_same_band(apsta_params, cur_if, FALSE); - if (wl_ext_dfs_chan(other_chan) && chan_2g) { - cur_if->channel = chan_2g; - auto_band = WLC_BAND_2G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); + wl_ext_set_chan_info(cur_if, WLC_BAND_5G, chan_5g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, cur_if, FALSE); + if (auto_chan) { + if (wl_ext_dfs_chan(cur_chan_info) && chan_2g) { + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, chan_2g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, cur_if, TRUE); + } } } else { - cur_if->channel = chan_2g; - auto_band = WLC_BAND_2G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, chan_2g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, cur_if, TRUE); } - if (!other_chan) { - other_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, - auto_band); + if (!auto_chan) { + auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, + cur_chan_info->band); } - if (other_chan) - cur_if->channel = other_chan; - } else { - cur_if->channel = chan_5g; - other_chan = wl_ext_same_band(apsta_params, cur_if, FALSE); - if (other_chan) { - cur_if->channel = other_chan; - } else { - auto_band = WLC_BAND_5G; - other_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, - auto_band); - if (other_chan) - cur_if->channel = other_chan; + if (auto_chan) { + cur_chan_info->chan = auto_chan; } } - WL_MSG(cur_if->ifname, "[%c] move channel %d => %d\n", - cur_if->prefix, cur_chan, cur_if->channel); + else { + wl_ext_set_chan_info(cur_if, WLC_BAND_5G, chan_5g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, cur_if, FALSE); + if (auto_chan) { + cur_chan_info->chan = auto_chan; + } else { + auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, + cur_chan_info->band); + if (auto_chan) { + cur_chan_info->chan = auto_chan; + } + } + } + WL_MSG(cur_if->ifname, "[%c] move channel %s-%d => %s-%d\n", + cur_if->prefix, WLCBAND2STR(cur_band), cur_chan, + WLCBAND2STR(cur_chan_info->band), cur_chan_info->chan); } } static void wl_ext_move_other_dfs_channel(struct wl_apsta_params *apsta_params, - struct wl_if_info *cur_if) + struct wl_if_info *tgt_if) { - uint16 other_chan = 0, cur_chan = cur_if->channel; + struct wl_chan_info *tgt_chan_info = &tgt_if->chan_info; + uint cur_band = tgt_chan_info->band; + uint16 cur_chan = tgt_chan_info->chan, auto_chan = 0; uint16 chan_2g = 0, chan_5g = 0; - uint32 auto_band = WLC_BAND_2G; - if (wl_ext_master_if(cur_if) && wl_ext_dfs_chan(cur_if->channel) && - !apsta_params->radar) { - - wl_ext_get_default_chan(cur_if->dev, &chan_2g, &chan_5g, TRUE); + if (!apsta_params->radar && wl_ext_master_if(tgt_if) && + wl_ext_dfs_chan(tgt_chan_info)) { + wl_ext_get_default_chan(tgt_if->dev, &chan_2g, &chan_5g, TRUE); if (!chan_2g && !chan_5g) { - cur_if->channel = 0; - WL_MSG(cur_if->ifname, "[%c] no valid channel\n", cur_if->prefix); + tgt_chan_info->chan = 0; + WL_MSG(tgt_if->ifname, "[%c] no valid channel\n", tgt_if->prefix); return; } if (apsta_params->vsdb) { - if (chan_5g) { - cur_if->channel = chan_5g; - auto_band = WLC_BAND_5G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); - } else { - cur_if->channel = chan_2g; - auto_band = WLC_BAND_2G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); + if (chan_5g) + wl_ext_set_chan_info(tgt_if, WLC_BAND_5G, chan_5g); + else + wl_ext_set_chan_info(tgt_if, WLC_BAND_2G, chan_2g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, tgt_if, TRUE); + if (!auto_chan) { + auto_chan = wl_ext_autochannel(tgt_if->dev, ACS_FW_BIT|ACS_DRV_BIT, + tgt_chan_info->band); } - if (!other_chan) { - other_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, - auto_band); + if (auto_chan) { + tgt_chan_info->chan = auto_chan; } - if (other_chan) - cur_if->channel = other_chan; - } else if (apsta_params->rsdb) { + } + else if (apsta_params->rsdb) { if (chan_2g) { - cur_if->channel = chan_2g; - auto_band = WLC_BAND_2G; - other_chan = wl_ext_same_band(apsta_params, cur_if, TRUE); - if (!other_chan) { - other_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT, - auto_band); + wl_ext_set_chan_info(tgt_if, WLC_BAND_2G, chan_2g); + auto_chan = wl_ext_get_same_band_chan(apsta_params, tgt_if, TRUE); + if (!auto_chan) { + auto_chan = wl_ext_autochannel(tgt_if->dev, ACS_FW_BIT|ACS_DRV_BIT, + tgt_chan_info->band); } } else { - cur_if->channel = 0; + tgt_chan_info->chan = 0; + } + if (auto_chan) { + tgt_chan_info->chan = auto_chan; } - if (other_chan) - cur_if->channel = other_chan; } else { - cur_if->channel = 0; + tgt_chan_info->chan = 0; } - WL_MSG(cur_if->ifname, "[%c] move channel %d => %d\n", - cur_if->prefix, cur_chan, cur_if->channel); + WL_MSG(tgt_if->ifname, "[%c] move channel %s-%d => %s-%d\n", + tgt_if->prefix, WLCBAND2STR(cur_band), cur_chan, + WLCBAND2STR(tgt_chan_info->band), tgt_chan_info->chan); } } @@ -1820,12 +1912,12 @@ wl_ext_move_cur_channel(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { struct wl_if_info *tmp_if, *target_if = NULL; - uint16 tmp_chan, target_chan = 0; + struct wl_chan_info cur_chan_info, tgt_chan_info; + uint16 tmp_chan; wl_prio_t max_prio; int i; if (apsta_params->vsdb) { - target_chan = cur_if->channel; goto exit; } @@ -1838,34 +1930,38 @@ wl_ext_move_cur_channel(struct wl_apsta_params *apsta_params, tmp_chan = wl_ext_get_vsdb_chan(apsta_params, cur_if, tmp_if); if (tmp_chan) { target_if = tmp_if; - target_chan = tmp_chan; max_prio = tmp_if->prio; } } } - if (target_chan) { - tmp_chan = wl_ext_get_chan(apsta_params, cur_if->dev); - if (apsta_params->rsdb && tmp_chan && - wl_ext_diff_band(tmp_chan, target_chan)) { - WL_MSG(cur_if->ifname, "[%c] keep on current channel %d\n", - cur_if->prefix, tmp_chan); - cur_if->channel = 0; + if (target_if) { + memset(&cur_chan_info, 0, sizeof(struct wl_chan_info)); + memset(&tgt_chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &cur_chan_info); + wl_ext_get_chan(apsta_params, target_if->dev, &tgt_chan_info); + if (apsta_params->rsdb && cur_chan_info.chan && + wl_ext_rsdb_band(cur_chan_info.band, tgt_chan_info.band)) { + WL_MSG(cur_if->ifname, "[%c] keep on current channel %s-%d\n", + cur_if->prefix, WLCBAND2STR(cur_chan_info.band), cur_chan_info.chan); + cur_if->chan_info.chan = 0; } else { - WL_MSG(cur_if->ifname, "[%c] channel=%d => %s[%c] channel=%d\n", - cur_if->prefix, cur_if->channel, - target_if->ifname, target_if->prefix, target_chan); - cur_if->channel = target_chan; + WL_MSG(cur_if->ifname, "[%c] channel=%s-%d => %s[%c] channel=%s-%d\n", + cur_if->prefix, + WLCBAND2STR(cur_if->chan_info.band), cur_if->chan_info.chan, + target_if->ifname, target_if->prefix, + WLCBAND2STR(tgt_chan_info.band), tgt_chan_info.chan); + wl_ext_set_chan_info(cur_if, tgt_chan_info.band, tgt_chan_info.chan); } } exit: wl_ext_move_cur_dfs_channel(apsta_params, cur_if); - return cur_if->channel; + return cur_if->chan_info.chan; } -static void +static struct wl_if_info * wl_ext_move_other_channel(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { @@ -1874,8 +1970,8 @@ wl_ext_move_other_channel(struct wl_apsta_params *apsta_params, wl_prio_t max_prio = 0, cur_prio; int i; - if (apsta_params->vsdb || !cur_if->channel) { - return; + if (apsta_params->vsdb || !cur_if->chan_info.chan) { + return NULL; } // find the max prio, but lower than cur_if @@ -1894,9 +1990,10 @@ wl_ext_move_other_channel(struct wl_apsta_params *apsta_params, } if (target_if) { - WL_MSG(target_if->ifname, "channel=%d => %s channel=%d\n", - target_chan, cur_if->ifname, cur_if->channel); - target_if->channel = cur_if->channel; + WL_MSG(target_if->ifname, "channel=%s-%d => %s channel=%s-%d\n", + WLCBAND2STR(target_if->chan_info.band), target_chan, + cur_if->ifname, WLCBAND2STR(cur_if->chan_info.band), cur_if->chan_info.chan); + wl_ext_set_chan_info(target_if, cur_if->chan_info.band, cur_if->chan_info.chan); wl_ext_move_other_dfs_channel(apsta_params, target_if); if (apsta_params->csa == 0) { wl_ext_if_down(apsta_params, target_if); @@ -1911,6 +2008,7 @@ wl_ext_move_other_channel(struct wl_apsta_params *apsta_params, } } + return target_if; } static bool @@ -1970,7 +2068,7 @@ wl_ext_iapsta_other_if_enabled(struct net_device *net) for (i=0; iif_info[i]; if (tmp_if && wl_get_isam_status(tmp_if, IF_READY)) { - if (wl_ext_get_chan(apsta_params, tmp_if->dev)) { + if (wl_ext_associated(tmp_if->dev)) { enabled = TRUE; break; } @@ -2034,8 +2132,8 @@ wl_ext_update_wlfc_maxcount(struct dhd_pub *dhd) { struct wl_apsta_params *apsta_params = dhd->iapsta_params; struct wl_if_info *tmp_if; + struct wl_chan_info chan_info; bool band_5g = FALSE; - uint16 chan = 0; int i, ret; if (!apsta_params->rsdb) @@ -2044,8 +2142,9 @@ wl_ext_update_wlfc_maxcount(struct dhd_pub *dhd) for (i=0; iif_info[i]; if (tmp_if->dev) { - chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (chan > CH_MAX_2G_CHANNEL) { + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info); + if (chan_info.band == WLC_BAND_5G || chan_info.band == WLC_BAND_6G) { tmp_if->transit_maxcount = dhd->conf->proptx_maxcnt_5g; ret = dhd_wlfc_update_maxcount(dhd, tmp_if->ifidx, tmp_if->transit_maxcount); @@ -2060,9 +2159,9 @@ wl_ext_update_wlfc_maxcount(struct dhd_pub *dhd) for (i=0; iif_info[i]; if (tmp_if->dev) { - chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if ((chan == 0) || (chan <= CH_MAX_2G_CHANNEL && chan >= CH_MIN_2G_CHANNEL)) { - if (chan == 0) { + wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info); + if ((chan_info.chan == 0) || (chan_info.band == WLC_BAND_2G)) { + if (chan_info.chan == 0) { tmp_if->transit_maxcount = WL_TXSTATUS_FREERUNCTR_MASK; } else if (band_5g) { tmp_if->transit_maxcount = dhd->conf->proptx_maxcnt_2g; @@ -2085,15 +2184,16 @@ static struct wl_if_info * wl_ext_get_dfs_master_if(struct wl_apsta_params *apsta_params) { struct wl_if_info *cur_if = NULL; - uint16 chan = 0; + struct wl_chan_info chan_info; int i; for (i=0; iif_info[i]; if (!cur_if->dev || !wl_ext_master_if(cur_if)) continue; - chan = wl_ext_get_chan(apsta_params, cur_if->dev); - if (wl_ext_dfs_chan(chan)) { + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info); + if (chan_info.chan && wl_ext_dfs_chan(&chan_info)) { return cur_if; } } @@ -2105,7 +2205,7 @@ wl_ext_save_master_channel(struct wl_apsta_params *apsta_params, uint16 post_channel) { struct wl_if_info *cur_if = NULL; - uint16 chan = 0; + struct wl_chan_info chan_info; int i; if (apsta_params->vsdb) @@ -2115,56 +2215,142 @@ wl_ext_save_master_channel(struct wl_apsta_params *apsta_params, cur_if = &apsta_params->if_info[i]; if (!cur_if->dev || !wl_ext_master_if(cur_if)) continue; - chan = wl_ext_get_chan(apsta_params, cur_if->dev); - if (chan) { - cur_if->prev_channel = chan; + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info); + if (chan_info.chan) { + cur_if->prev_channel = chan_info.chan; cur_if->post_channel = post_channel; } } } +void +wl_ext_iapsta_enable_master_if(struct net_device *dev, bool post) +{ + dhd_pub_t *dhd = dhd_get_pub(dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + struct wl_if_info *cur_if = NULL; + int i; + + for (i=0; iif_info[i]; + if (cur_if && cur_if->post_channel) { + if (post) + cur_if->chan_info.chan = cur_if->post_channel; + else + cur_if->chan_info.chan = cur_if->prev_channel; + wl_ext_if_up(apsta_params, cur_if, TRUE, 0); + cur_if->prev_channel = 0; + cur_if->post_channel = 0; + } + } +} + +void +wl_ext_iapsta_restart_master(struct net_device *dev) +{ + dhd_pub_t *dhd = dhd_get_pub(dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + struct wl_if_info *ap_if = NULL; + + if (apsta_params->radar) + return; + + ap_if = wl_ext_get_dfs_master_if(apsta_params); + if (ap_if) { + uint16 chan_2g, chan_5g; + wl_ext_if_down(apsta_params, ap_if); + wl_ext_iapsta_restart_master(dev); + wl_ext_get_default_chan(ap_if->dev, &chan_2g, &chan_5g, TRUE); + if (chan_5g) + wl_ext_set_chan_info(ap_if, WLC_BAND_5G, chan_5g); + else if (chan_2g) + wl_ext_set_chan_info(ap_if, WLC_BAND_2G, chan_2g); + else + ap_if->chan_info.chan = 0; + if (ap_if->chan_info.chan) { + wl_ext_move_cur_channel(apsta_params, ap_if); + wl_ext_if_up(apsta_params, ap_if, FALSE, 0); + } + } +} + +static void +wl_ext_if_reenabled(struct wl_apsta_params *apsta_params, ifmode_t ifmode, u32 channel) +{ + struct wl_if_info *tmp_if; + int i; + + for (i=0; iif_info[i]; + if (tmp_if && tmp_if->ifmode == ifmode && + wl_get_isam_status(tmp_if, IF_READY)) { + if (wl_ext_get_chan(apsta_params, tmp_if->dev, &tmp_if->chan_info) == channel) { + WL_MSG(tmp_if->ifname, "re-enable channel %d\n", channel); + if (ifmode == IAP_MODE) { + wl_ext_if_down(apsta_params, tmp_if); + wl_ext_if_up(apsta_params, tmp_if, FALSE, 0); + } + break; + } + } + } + +} + u32 -wl_ext_iapsta_update_channel(struct net_device *dev, u32 channel) +wl_ext_iapsta_update_channel(struct net_device *dev, u32 chanspec) { struct dhd_pub *dhd = dhd_get_pub(dev); struct wl_apsta_params *apsta_params = dhd->iapsta_params; - struct wl_if_info *cur_if = NULL; + struct wl_if_info *cur_if = NULL, *target_if = NULL; struct dhd_conf *conf = dhd->conf; cur_if = wl_get_cur_if(dev); if (cur_if) { + struct wl_chan_info *chan_info = &cur_if->chan_info; mutex_lock(&apsta_params->usr_sync); wl_ext_isam_status(cur_if->dev, NULL, 0); - cur_if->channel = channel; + wl_ext_set_chan_info(cur_if, CHSPEC2WLC_BAND(chanspec), + wf_chspec_ctlchan(chanspec)); if (wl_ext_master_if(cur_if) && apsta_params->acs) { - uint auto_band = WL_GET_BAND(channel); - cur_if->channel = wl_ext_autochannel(cur_if->dev, apsta_params->acs, - auto_band); + chan_info->chan = wl_ext_autochannel(cur_if->dev, apsta_params->acs, + chan_info->band); } - channel = wl_ext_move_cur_channel(apsta_params, cur_if); - if (channel) { - if (cur_if->ifmode == ISTA_MODE && wl_ext_dfs_chan(channel)) - wl_ext_save_master_channel(apsta_params, channel); - wl_ext_move_other_channel(apsta_params, cur_if); + chan_info->chan = wl_ext_move_cur_channel(apsta_params, cur_if); + if (chan_info->chan) { + if (cur_if->ifmode == ISTA_MODE && wl_ext_dfs_chan(chan_info)) + wl_ext_save_master_channel(apsta_params, chan_info->chan); + target_if = wl_ext_move_other_channel(apsta_params, cur_if); + if (dhd->conf->chip == BCM4359_CHIP_ID && + cur_if->ifmode == ISTA_MODE && !target_if) { + /* this is a WAR to fix 4359 fw trap issue as below procedure: + * step1: enable wlan1 on channel 1 + * step2: enable wlan2 on channel 36 + * step3: enable wlan0 to connect channel 1 AP, then it will fw trap + */ + wl_ext_if_reenabled(apsta_params, IAP_MODE, chan_info->chan); + } } if (cur_if->ifmode == ISTA_MODE) { if (conf->war & SET_CHAN_INCONN) { chanspec_t fw_chspec; - IAPSTA_INFO(dev->name, "set channel %d\n", channel); - wl_ext_set_chanspec(cur_if->dev, apsta_params->ioctl_ver, channel, - &fw_chspec); + IAPSTA_INFO(dev->name, "set channel %d\n", chan_info->chan); + wl_ext_set_chanspec(cur_if->dev, chan_info, &fw_chspec); } wl_set_isam_status(cur_if, STA_CONNECTING); } + chanspec = wf_create_chspec_from_primary(chan_info->chan, + CHSPEC_BW(chanspec), wl_ext_wlcband_to_chanspec_band(chan_info->band)); mutex_unlock(&apsta_params->usr_sync); } - return channel; + return chanspec; } static int wl_ext_iftype_to_ifmode(struct net_device *net, int wl_iftype, ifmode_t *ifmode) -{ +{ switch (wl_iftype) { case WL_IF_TYPE_STA: *ifmode = ISTA_MODE; @@ -2186,11 +2372,12 @@ wl_ext_iftype_to_ifmode(struct net_device *net, int wl_iftype, ifmode_t *ifmode) } void -wl_ext_iapsta_update_iftype(struct net_device *net, int ifidx, int wl_iftype) +wl_ext_iapsta_update_iftype(struct net_device *net, int wl_iftype) { struct dhd_pub *dhd = dhd_get_pub(net); struct wl_apsta_params *apsta_params = dhd->iapsta_params; struct wl_if_info *cur_if = NULL; + int ifidx = dhd_net2idx(dhd->info, net); IAPSTA_TRACE(net->name, "ifidx=%d, wl_iftype=%d\n", ifidx, wl_iftype); @@ -2219,6 +2406,11 @@ wl_ext_iapsta_update_iftype(struct net_device *net, int ifidx, int wl_iftype) cur_if->prio = PRIO_P2P; cur_if->vsdb = TRUE; cur_if->prefix = 'P'; + } else if (wl_iftype == WL_IF_TYPE_IBSS) { + cur_if->ifmode = IAP_MODE; + cur_if->prio = PRIO_AP; + cur_if->vsdb = FALSE; + cur_if->prefix = 'H'; wl_ext_iovar_setint(cur_if->dev, "assoc_retry_max", 3); } } @@ -2254,57 +2446,6 @@ wl_ext_iapsta_iftype_enabled(struct net_device *net, int wl_iftype) return FALSE; } -void -wl_ext_iapsta_enable_master_if(struct net_device *dev, bool post) -{ - dhd_pub_t *dhd = dhd_get_pub(dev); - struct wl_apsta_params *apsta_params = dhd->iapsta_params; - struct wl_if_info *cur_if = NULL; - int i; - - for (i=0; iif_info[i]; - if (cur_if && cur_if->post_channel) { - if (post) - cur_if->channel = cur_if->post_channel; - else - cur_if->channel = cur_if->prev_channel; - wl_ext_if_up(apsta_params, cur_if, TRUE, 0); - cur_if->prev_channel = 0; - cur_if->post_channel = 0; - } - } -} - -void -wl_ext_iapsta_restart_master(struct net_device *dev) -{ - dhd_pub_t *dhd = dhd_get_pub(dev); - struct wl_apsta_params *apsta_params = dhd->iapsta_params; - struct wl_if_info *ap_if = NULL; - - if (apsta_params->radar) - return; - - ap_if = wl_ext_get_dfs_master_if(apsta_params); - if (ap_if) { - uint16 chan_2g, chan_5g; - wl_ext_if_down(apsta_params, ap_if); - wl_ext_iapsta_restart_master(dev); - wl_ext_get_default_chan(ap_if->dev, &chan_2g, &chan_5g, TRUE); - if (chan_5g) - ap_if->channel = chan_5g; - else if (chan_2g) - ap_if->channel = chan_2g; - else - ap_if->channel = 0; - if (ap_if->channel) { - wl_ext_move_cur_channel(apsta_params, ap_if); - wl_ext_if_up(apsta_params, ap_if, FALSE, 0); - } - } -} - bool wl_ext_iapsta_mesh_creating(struct net_device *net) { @@ -2347,14 +2488,14 @@ wl_ext_fw_reinit_incsa(struct net_device *dev) static void wl_ext_reconnect_timeout(unsigned long data) { - struct wl_if_info *cur_if = (struct wl_if_info *)data; + struct net_device *dev = (struct net_device *)data; - if (!cur_if) { - IAPSTA_ERROR("wlan", "cur_if is not ready\n"); + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); return; } - IAPSTA_ERROR(cur_if->dev->name, "timer expired\n"); - wl_ext_send_event_msg(cur_if->dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS); + IAPSTA_ERROR(dev->name, "timer expired\n"); + wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS); } static int @@ -2373,6 +2514,8 @@ wl_ext_connect_retry(struct net_device *dev, wl_event_msg_t *e) if (!cur_if) return ret; + mutex_unlock(&apsta_params->in4way_sync); + mutex_lock(&cfg->connect_sync); connecting = wl_ext_sta_connecting(dev); osl_do_gettimeofday(&cur_ts); @@ -2390,7 +2533,7 @@ wl_ext_connect_retry(struct net_device *dev, wl_event_msg_t *e) wl_handle_reassoc(cfg, dev, &cur_if->assoc_info); max_wait_time = STA_RECONNECT_RETRY_TIMEOUT; } else { - if (!wl_ext_get_chan(apsta_params, dev)) { + if (!wl_ext_associated(dev)) { WL_MSG(dev->name, "retry join\n"); wl_cfg80211_disassoc(dev, WLAN_REASON_DEAUTH_LEAVING); wl_handle_join(cfg, dev, &cur_if->assoc_info); @@ -2401,6 +2544,8 @@ wl_ext_connect_retry(struct net_device *dev, wl_event_msg_t *e) } ret = -EAGAIN; } + mutex_unlock(&cfg->connect_sync); + mutex_lock(&apsta_params->in4way_sync); return ret; } @@ -2432,6 +2577,73 @@ wl_ext_set_connect_retry(struct net_device *dev, void *context) } } #endif /* WL_EXT_RECONNECT */ + +#ifdef STA_MGMT +static void +wl_ext_flush_sta_list(struct net_device *net, int ifidx) +{ + struct dhd_pub *dhd = dhd_get_pub(net); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + wl_sta_info_t *node, *next; + + list_for_each_entry_safe(node, next, &apsta_params->sta_list, list) { + if (node->ifidx == ifidx || ifidx == 0xFF) { + IAPSTA_INFO(net->name, "Del BSSID %pM\n", &node->bssid); + list_del(&node->list); + kfree(node); + } + } +} + +bool +wl_ext_del_sta_info(struct net_device *net, u8 *bssid) +{ + struct dhd_pub *dhd = dhd_get_pub(net); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + int ifidx = dhd_net2idx(dhd->info, net); + wl_sta_info_t *node, *next; + bool in_list = FALSE; + + list_for_each_entry_safe(node, next, &apsta_params->sta_list, list) { + if (node->ifidx == ifidx && !memcmp(&node->bssid, bssid, ETHER_ADDR_LEN)) { + IAPSTA_INFO(net->name, "Del BSSID %pM\n", &node->bssid); + in_list = TRUE; + list_del(&node->list); + kfree(node); + } + } + return in_list; +} + +bool +wl_ext_add_sta_info(struct net_device *net, u8 *bssid) +{ + struct dhd_pub *dhd = dhd_get_pub(net); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + int ifidx = dhd_net2idx(dhd->info, net); + wl_sta_info_t *node, *next, *leaf; + + list_for_each_entry_safe(node, next, &apsta_params->sta_list, list) { + if (node->ifidx == ifidx && !memcmp(&node->bssid, bssid, ETHER_ADDR_LEN)) { + IAPSTA_INFO(net->name, "BSSID %pM already in list\n", bssid); + return FALSE; + } + } + + leaf = kmalloc(sizeof(wl_sta_info_t), GFP_KERNEL); + if (!leaf) { + IAPSTA_ERROR(net->name, "Memory alloc failure %d\n", + (int)sizeof(wl_sta_info_t)); + return FALSE; + } + IAPSTA_INFO(net->name, "Add BSSID %pM in the leaf\n", bssid); + leaf->ifidx = ifidx; + memcpy(&leaf->bssid, bssid, ETHER_ADDR_LEN); + list_add_tail(&leaf->list, &apsta_params->sta_list); + + return TRUE; +} +#endif /* STA_MGMT */ #endif /* WL_CFG80211 */ #ifndef WL_STATIC_IF @@ -2680,11 +2892,11 @@ wl_ext_update_conn_state(dhd_pub_t *dhd, int ifidx, uint conn_state) spin_lock_irqsave(&apsta_params->eapol_lock, flags); #endif /* EAPOL_RESEND */ if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) { - if (wl_ext_sta_connecting(cur_if->dev) || - conn_state >= CONN_STATE_CONNECTED || - conn_state <= CONN_STATE_CONNECTING) + if (wl_ext_sta_connecting(cur_if->dev) || + conn_state >= CONN_STATE_CONNECTED || + conn_state <= CONN_STATE_CONNECTING) apsta_params->if_info[ifidx].conn_state = conn_state; - else + else IAPSTA_INFO(cur_if->dev->name, "skip update %d\n", conn_state); } else { apsta_params->if_info[ifidx].conn_state = conn_state; @@ -2847,23 +3059,21 @@ wl_resend_eapol_handler(struct wl_if_info *cur_if, static void wl_eapol_timer(unsigned long data) { - struct wl_if_info *cur_if = (struct wl_if_info *)data; + struct net_device *dev = (struct net_device *)data; struct dhd_pub *dhd; - struct wl_apsta_params *apsta_params; wl_event_msg_t msg; - if (!cur_if) { - IAPSTA_ERROR("wlan", "cur_if is not ready\n"); + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); return; } - dhd = dhd_get_pub(cur_if->dev); - apsta_params = dhd->iapsta_params; + dhd = dhd_get_pub(dev); bzero(&msg, sizeof(wl_event_msg_t)); - IAPSTA_TRACE(cur_if->dev->name, "timer expired\n"); + IAPSTA_TRACE(dev->name, "timer expired\n"); - msg.ifidx = cur_if->ifidx; + msg.ifidx = dhd_net2idx(dhd->info, dev); msg.event_type = hton32(WLC_E_RESERVED); msg.reason = hton32(ISAM_RC_EAPOL_RESEND); wl_ext_event_send(dhd->event_params, &msg, NULL); @@ -2909,43 +3119,45 @@ wl_ext_light_scan_prep(struct net_device *dev, void *scan_params, bool scan_v2) } static uint16 -wl_ext_max_tput_chan(struct wl_apsta_params *apsta_params) +wl_ext_max_tput_chan(struct wl_apsta_params *apsta_params, + struct wl_chan_info *chan_info) { struct wl_if_info *tmp_if, *max_tput_if = NULL; - uint16 chan = 0, max_tput_chan = 0; int32 tput_sum = 0; int i; for (i=0; iif_info[i]; - if (tmp_if->dev && (tmp_if->tput_tx + tmp_if->tput_rx) > tput_sum) { - chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (chan) { + if (tmp_if->dev && (tmp_if->tput_info.tput_tx + tmp_if->tput_info.tput_rx) > tput_sum) { + memset(chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, tmp_if->dev, chan_info); + if (chan_info->chan) { max_tput_if = tmp_if; - tput_sum = tmp_if->tput_tx + tmp_if->tput_rx; - max_tput_chan = chan; + tput_sum = tmp_if->tput_info.tput_tx + tmp_if->tput_info.tput_rx; break; } } } - if (max_tput_chan) - IAPSTA_INFO(max_tput_if->dev->name, "chan=%d\n", max_tput_chan); + if (max_tput_if) + IAPSTA_INFO(max_tput_if->dev->name, "chan=%s-%d\n", + WLCBAND2STR(chan_info->band), chan_info->chan); - return max_tput_chan; + return chan_info->chan; } uint16 -wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2) +wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2, + struct wl_chan_info *chan_info) { struct dhd_pub *dhd = dhd_get_pub(dev); struct wl_apsta_params *apsta_params = dhd->iapsta_params; struct dhd_conf *conf = dhd->conf; - uint16 chan = 0; if (!(conf->scan_intput & (SCAN_CURCHAN_INTPUT|SCAN_LIGHT_INTPUT))) return 0; + memset(chan_info, 0, sizeof(struct wl_chan_info)); if (apsta_params->tput_sum >= conf->scan_tput_thresh) { IAPSTA_INFO(dev->name, "tput %dMbps >= %dMbps (busy cnt/thresh %d/%d)\n", apsta_params->tput_sum, conf->scan_tput_thresh, @@ -2953,9 +3165,9 @@ wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2) if (apsta_params->scan_busy_cnt >= conf->scan_busy_thresh) { apsta_params->scan_busy_cnt = 0; } else if (conf->scan_intput & SCAN_CURCHAN_INTPUT) { - chan = wl_ext_max_tput_chan(apsta_params); + wl_ext_max_tput_chan(apsta_params, chan_info); } - if ((conf->scan_intput & SCAN_LIGHT_INTPUT) && !chan) + if ((conf->scan_intput & SCAN_LIGHT_INTPUT) && !chan_info->chan) wl_ext_light_scan_prep(dev, scan_params, scan_v2); apsta_params->scan_busy_cnt++; } @@ -2963,7 +3175,7 @@ wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2) apsta_params->scan_busy_cnt = 0; } - return chan; + return chan_info->chan; } static int @@ -3115,13 +3327,14 @@ wl_iapsta_suspend_resume_ap(dhd_pub_t *dhd, struct wl_if_info *cur_if, if (suspend) { if (insuspend & AP_DOWN_IN_SUSPEND) { - cur_if->channel = wl_ext_get_chan(apsta_params, cur_if->dev); - if (cur_if->channel) + cur_if->chan_info.chan = wl_ext_get_chan(apsta_params, cur_if->dev, + &cur_if->chan_info); + if (cur_if->chan_info.chan) wl_ext_if_down(apsta_params, cur_if); } } else { if (insuspend & AP_DOWN_IN_SUSPEND) { - if (cur_if->channel) + if (cur_if->chan_info.chan) wl_ext_if_up(apsta_params, cur_if, FALSE, 0); } } @@ -3257,16 +3470,16 @@ wl_ext_in4way_sync_sta(dhd_pub_t *dhd, struct wl_if_info *cur_if, break; case WL_EXT_STATUS_SCAN_COMPLETE: if ((conf->war & FW_REINIT_EMPTY_SCAN) && cfg->bss_list->count == 0) { - uint16 channel; + bool assoc; osl_do_gettimeofday(&cur_ts); diff_ms = osl_do_gettimediff(&cur_ts, sta_disc_ts)/1000; - channel = wl_ext_get_chan(apsta_params, dev); + assoc = wl_ext_associated(dev); cur_if->empty_scan++; - if ((channel && cur_if->empty_scan >= STA_EMPTY_SCAN_MAX) || + if ((assoc && cur_if->empty_scan >= STA_EMPTY_SCAN_MAX) || (diff_ms < STA_LINKDOWN_TIMEOUT && apsta_params->linkdown_reason == WLC_E_LINK_BCN_LOSS)) { if (conf->chip == BCM43569_CHIP_ID) { - if (channel) { + if (assoc) { IAPSTA_INFO(dev->name, "wl disassoc for empty scan\n"); wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1); } @@ -3281,7 +3494,7 @@ wl_ext_in4way_sync_sta(dhd_pub_t *dhd, struct wl_if_info *cur_if, } break; #endif /* WL_CFG80211 */ - case WL_EXT_STATUS_DISCONNECTING: + case WL_EXT_STATUS_DISCONNECTING: #ifdef EAPOL_RESEND wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE); #endif /* EAPOL_RESEND */ @@ -3421,12 +3634,25 @@ wl_ext_in4way_sync_ap(dhd_pub_t *dhd, struct wl_if_info *cur_if, break; } break; + case WL_EXT_STATUS_AP_ENABLING: +#ifdef RESTART_AP_WAR + wl_ext_mod_timer(&cur_if->restart_ap_timer, AP_RESTART_TIMEOUT, 0); +#endif /* RESTART_AP_WAR */ + break; case WL_EXT_STATUS_AP_ENABLED: +#ifdef RESTART_AP_WAR + wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0); +#endif /* RESTART_AP_WAR */ if (cur_if->ifmode == IAP_MODE) dhd_conf_set_wme(dhd, cur_if->ifidx, 1); else if (cur_if->ifmode == IGO_MODE) dhd_conf_set_mchan_bw(dhd, WL_P2P_IF_GO, -1); break; + case WL_EXT_STATUS_AP_DISABLING: +#ifdef RESTART_AP_WAR + wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0); +#endif /* RESTART_AP_WAR */ + break; case WL_EXT_STATUS_DELETE_STA: if (action & AP_WAIT_STA_RECONNECT) { osl_do_gettimeofday(&cur_ts); @@ -3621,6 +3847,29 @@ wl_ext_in4way_sync_wext(struct net_device *dev, uint action, #endif /* WL_WIRELESS_EXT */ #ifdef TPUT_MONITOR +static void +wl_tput_monitor_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct dhd_pub *dhd; + wl_event_msg_t msg; + + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); + return; + } + + dhd = dhd_get_pub(dev); + + bzero(&msg, sizeof(wl_event_msg_t)); + IAPSTA_TRACE(dev->name, "timer expired\n"); + + msg.ifidx = 0; + msg.event_type = hton32(WLC_E_RESERVED); + msg.reason = hton32(ISAM_RC_TPUT_MONITOR); + wl_ext_event_send(dhd->event_params, &msg, NULL); +} + static int wl_ext_assoclist_num(struct net_device *dev) { @@ -3639,103 +3888,84 @@ wl_ext_assoclist_num(struct net_device *dev) } static void -wl_tput_monitor_timer(unsigned long data) +wl_phy_rssi_ant(struct net_device *dev, struct ether_addr *mac, + char *rssi_buf, int len) { - struct wl_apsta_params *apsta_params = (struct wl_apsta_params *)data; - wl_event_msg_t msg; - - if (!apsta_params) { - IAPSTA_ERROR("wlan", "apsta_params is not ready\n"); - return; - } - - bzero(&msg, sizeof(wl_event_msg_t)); - IAPSTA_TRACE("wlan", "timer expired\n"); - - msg.ifidx = 0; - msg.event_type = hton32(WLC_E_RESERVED); - msg.reason = hton32(ISAM_RC_TPUT_MONITOR); - wl_ext_event_send(apsta_params->dhd->event_params, &msg, NULL); -} - -static void -wl_tput_dump(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) -{ - struct dhd_pub *dhd = apsta_params->dhd; - void *buf = NULL; - sta_info_v4_t *sta = NULL; - struct ether_addr bssid; + struct wl_if_info *cur_if = NULL; + char buf[WLC_IOCTL_SMLEN]; wl_rssi_ant_t *rssi_ant_p; - char rssi_buf[16]; - scb_val_t scb_val; int ret, bytes_written = 0, i; - s32 rate = 0; - dhd_if_t *ifp = NULL; + scb_val_t scb_val; - if (!(android_msg_level & ANDROID_TPUT_LEVEL)) + cur_if = wl_get_cur_if(dev); + if (!cur_if) return; - ifp = dhd_get_ifp(dhd, cur_if->ifidx); - - buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); - if (buf == NULL) { - IAPSTA_ERROR(cur_if->dev->name, "MALLOC failed\n"); - goto exit; - } - - wldev_ioctl_get(cur_if->dev, WLC_GET_RATE, &rate, sizeof(rate)); - rate = dtoh32(rate); - memset(rssi_buf, 0, sizeof(rssi_buf)); - if (cur_if->ifmode == ISTA_MODE) { - ret = wldev_iovar_getbuf(cur_if->dev, "phy_rssi_ant", NULL, 0, - buf, WLC_IOCTL_MEDLEN, NULL); - rssi_ant_p = (wl_rssi_ant_t *)buf; - rssi_ant_p->version = dtoh32(rssi_ant_p->version); - rssi_ant_p->count = dtoh32(rssi_ant_p->count); - if (ret < 0 || rssi_ant_p->count == 0) { - wldev_ioctl(cur_if->dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0); + memset(buf, 0, sizeof(buf)); + ret = wldev_iovar_getbuf(dev, "phy_rssi_ant", + mac, mac ? ETHER_ADDR_LEN : 0, buf, sizeof(buf), NULL); + rssi_ant_p = (wl_rssi_ant_t *)buf; + rssi_ant_p->version = dtoh32(rssi_ant_p->version); + rssi_ant_p->count = dtoh32(rssi_ant_p->count); + if (ret < 0 || rssi_ant_p->count == 0) { + if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) { + wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0); rssi_ant_p->count = 1; rssi_ant_p->rssi_ant[0] = dtoh32(scb_val.val); } - for (i=0; icount && rssi_ant_p->rssi_ant[i]; i++) { - bytes_written += snprintf(rssi_buf+bytes_written, sizeof(rssi_buf), - "[%2d]", rssi_ant_p->rssi_ant[i]); - } - wldev_ioctl(cur_if->dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); - ret = wldev_iovar_getbuf(cur_if->dev, "sta_info", (const void*)&bssid, - ETHER_ADDR_LEN, buf, WLC_IOCTL_MEDLEN, NULL); - if (ret == 0) { - sta = (sta_info_v4_t *)buf; - } } - else { - bytes_written += snprintf(rssi_buf+bytes_written, sizeof(rssi_buf), - "[ ][ ]"); + for (i=0; icount && rssi_ant_p->rssi_ant[i]; i++) { + bytes_written += snprintf(rssi_buf+bytes_written, len, + "[%2d]", rssi_ant_p->rssi_ant[i]); } +} +static void +wl_tput_dump(struct wl_apsta_params *apsta_params, + struct net_device *dev, wl_tput_info_t *tput_info) +{ + WL_MSG(dev->name, + "tx=%3d.%d%d%d Mbps, rx=%3d.%d%d%d Mbps, tput_sum=%3d.%d%d%d Mbps\n", + tput_info->tput_tx, (tput_info->tput_tx_kb/100)%10, + (tput_info->tput_tx_kb/10)%10, (tput_info->tput_tx_kb)%10, + tput_info->tput_rx, (tput_info->tput_rx_kb/100)%10, + (tput_info->tput_rx_kb/10)%10, (tput_info->tput_rx_kb)%10, + apsta_params->tput_sum, (apsta_params->tput_sum_kb/100)%10, + (apsta_params->tput_sum_kb/10)%10, (apsta_params->tput_sum_kb)%10); +} + +static void +wl_sta_info_dump(struct net_device *dev, struct ether_addr *mac) +{ + void *buf = NULL; + sta_info_v4_t *sta = NULL; + char rssi_buf[16]; + int ret; + s32 rate = 0; + + buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); + if (buf == NULL) { + IAPSTA_ERROR(dev->name, "MALLOC failed\n"); + goto exit; + } + memset(rssi_buf, 0, sizeof(rssi_buf)); + wl_phy_rssi_ant(dev, mac, rssi_buf, sizeof(rssi_buf)); + ret = wldev_iovar_getbuf(dev, "sta_info", (const void*)mac, + ETHER_ADDR_LEN, buf, WLC_IOCTL_MEDLEN, NULL); + if (ret == 0) { + sta = (sta_info_v4_t *)buf; + } if (sta == NULL || (sta->ver != WL_STA_VER_4 && sta->ver != WL_STA_VER_5)) { - WL_MSG(cur_if->dev->name, - "rssi=%s, tx=%3d.%d%d%d Mbps(rate:%4d%2s), rx=%3d.%d%d%d Mbps(rate: ), "\ - "tput_sum=%3d.%d%d%d Mbps\n", - rssi_buf, cur_if->tput_tx, (cur_if->tput_tx_kb/100)%10, - (cur_if->tput_tx_kb/10)%10, (cur_if->tput_tx_kb)%10, - rate/2, (rate & 1) ? ".5" : "", - cur_if->tput_rx, (cur_if->tput_rx_kb/100)%10, - (cur_if->tput_rx_kb/10)%10, (cur_if->tput_rx_kb)%10, - apsta_params->tput_sum, (apsta_params->tput_sum_kb/100)%10, - (apsta_params->tput_sum_kb/10)%10, (apsta_params->tput_sum_kb)%10); + wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate)); + rate = dtoh32(rate); + WL_MSG(dev->name, + "mac=%pM, rssi=%s, tx_rate:%4d%2s\n", + mac, rssi_buf, rate/2, (rate & 1) ? ".5" : ""); } else { - WL_MSG(cur_if->dev->name, - "rssi=%s, tx=%3d.%d%d%d Mbps(rate:%4d%2s), rx=%3d.%d%d%d Mbps(rate:%4d.%d), "\ - "tput_sum=%3d.%d%d%d Mbps\n", - rssi_buf, cur_if->tput_tx, (cur_if->tput_tx_kb/100)%10, - (cur_if->tput_tx_kb/10)%10, (cur_if->tput_tx_kb)%10, - rate/2, (rate & 1) ? ".5" : "", - cur_if->tput_rx, (cur_if->tput_rx_kb/100)%10, - (cur_if->tput_rx_kb/10)%10, (cur_if->tput_rx_kb)%10, - dtoh32(sta->rx_rate)/1000, ((dtoh32(sta->rx_rate)/100)%10), - apsta_params->tput_sum, (apsta_params->tput_sum_kb/100)%10, - (apsta_params->tput_sum_kb/10)%10, (apsta_params->tput_sum_kb)%10); + WL_MSG(dev->name, + "mac=%pM, rssi=%s, tx_rate:%4d.%d, rx_rate:%4d.%d\n", mac, rssi_buf, + dtoh32(sta->tx_rate)/1000, ((dtoh32(sta->tx_rate)/100)%10), + dtoh32(sta->rx_rate)/1000, ((dtoh32(sta->rx_rate)/100)%10)); } exit: @@ -3745,40 +3975,90 @@ exit: } static void -wl_tput_monitor(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) +wl_cur_if_tput_dump(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) +{ +#ifdef WLDWDS + struct wl_dwds_info *dwds_if; + int i; +#endif /* WLDWDS */ + struct ether_addr bssid; + int ret = 0; + + if (!(android_msg_level & ANDROID_TPUT_LEVEL)) + return; + + wl_tput_dump(apsta_params, cur_if->dev, &cur_if->tput_info); + + if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) { + wldev_ioctl(cur_if->dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); + if (ret != BCME_NOTASSOCIATED && memcmp(ðer_null, &bssid, ETHER_ADDR_LEN)) { + wl_sta_info_dump(cur_if->dev, &bssid); + } + } + else if (cur_if->ifmode == IAP_MODE || cur_if->ifmode == IGO_MODE) { + int i, maxassoc = 0; + char mac_buf[MAX_NUM_OF_ASSOCLIST * + sizeof(struct ether_addr) + sizeof(uint)] = {0}; + struct maclist *assoc_maclist = (struct maclist *)mac_buf; + + assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST); + ret = wl_ext_ioctl(cur_if->dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), 0); + if (ret) + goto exit; + maxassoc = dtoh32(assoc_maclist->count); + for (i=0; idev, &assoc_maclist->ea[i]); + } +#ifdef WLDWDS + for (i=0; idwds_info[i]; + if (dwds_if->dev && cur_if->bssidx == dwds_if->bssidx) { + wl_tput_dump(apsta_params, dwds_if->dev, &dwds_if->tput_info); + } + } +#endif /* WLDWDS */ + } + +exit: + return; +} + +static void +wl_tput_monitor(struct dhd_pub *dhd, int ifidx, struct wl_tput_info *tput_info) { - struct dhd_pub *dhd = apsta_params->dhd; dhd_if_t *ifp = NULL; - ifp = dhd_get_ifp(dhd, cur_if->ifidx); + ifp = dhd_get_ifp(dhd, ifidx); + if (!ifp) + return; - if (cur_if->tput_ts.tv_sec == 0 && cur_if->tput_ts.tv_nsec == 0) { - osl_do_gettimeofday(&cur_if->tput_ts); - cur_if->last_tx = ifp->stats.tx_bytes; - cur_if->last_rx = ifp->stats.rx_bytes; + if (tput_info->tput_ts.tv_sec == 0 && tput_info->tput_ts.tv_nsec == 0) { + osl_do_gettimeofday(&tput_info->tput_ts); + tput_info->last_tx = ifp->stats.tx_bytes; + tput_info->last_rx = ifp->stats.rx_bytes; } else { struct osl_timespec cur_ts; uint32 diff_ms; osl_do_gettimeofday(&cur_ts); - diff_ms = osl_do_gettimediff(&cur_ts, &cur_if->tput_ts)/1000; - memcpy(&cur_if->tput_ts, &cur_ts, sizeof(struct osl_timespec)); - cur_if->tput_tx = (int32)(((ifp->stats.tx_bytes-cur_if->last_tx)/1024/1024)*8)*1000/diff_ms; - if (cur_if->tput_tx == 0) { - cur_if->tput_tx = (int32)((ifp->stats.tx_bytes-cur_if->last_tx)*8*1000/1024/1024)/diff_ms; - cur_if->tput_tx_kb = (int32)((ifp->stats.tx_bytes-cur_if->last_tx)*8*1000/1024)/diff_ms; - cur_if->tput_tx_kb = cur_if->tput_tx_kb % 1000; + diff_ms = osl_do_gettimediff(&cur_ts, &tput_info->tput_ts)/1000; + memcpy(&tput_info->tput_ts, &cur_ts, sizeof(struct osl_timespec)); + tput_info->tput_tx = (int32)(((ifp->stats.tx_bytes-tput_info->last_tx)/1024/1024)*8)*1000/diff_ms; + if (tput_info->tput_tx == 0) { + tput_info->tput_tx = (int32)((ifp->stats.tx_bytes-tput_info->last_tx)*8*1000/1024/1024)/diff_ms; + tput_info->tput_tx_kb = (int32)((ifp->stats.tx_bytes-tput_info->last_tx)*8*1000/1024)/diff_ms; + tput_info->tput_tx_kb = tput_info->tput_tx_kb % 1000; } else - cur_if->tput_tx_kb = 0; - cur_if->tput_rx = (int32)(((ifp->stats.rx_bytes-cur_if->last_rx)/1024/1024)*8)*1000/diff_ms; - if (cur_if->tput_rx == 0) { - cur_if->tput_rx = (int32)((ifp->stats.rx_bytes-cur_if->last_rx)*8*1000/1024/1024)/diff_ms; - cur_if->tput_rx_kb = (int32)((ifp->stats.rx_bytes-cur_if->last_rx)*8*1000/1024)/diff_ms; - cur_if->tput_rx_kb = cur_if->tput_rx_kb % 1000; + tput_info->tput_tx_kb = 0; + tput_info->tput_rx = (int32)(((ifp->stats.rx_bytes-tput_info->last_rx)/1024/1024)*8)*1000/diff_ms; + if (tput_info->tput_rx == 0) { + tput_info->tput_rx = (int32)((ifp->stats.rx_bytes-tput_info->last_rx)*8*1000/1024/1024)/diff_ms; + tput_info->tput_rx_kb = (int32)((ifp->stats.rx_bytes-tput_info->last_rx)*8*1000/1024)/diff_ms; + tput_info->tput_rx_kb = tput_info->tput_rx_kb % 1000; } else - cur_if->tput_rx_kb = 0; - cur_if->last_tx = ifp->stats.tx_bytes; - cur_if->last_rx = ifp->stats.rx_bytes; + tput_info->tput_rx_kb = 0; + tput_info->last_tx = ifp->stats.tx_bytes; + tput_info->last_rx = ifp->stats.rx_bytes; } } @@ -3787,42 +4067,64 @@ wl_tput_monitor_handler(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if, const wl_event_msg_t *e, void *data) { struct dhd_pub *dhd = apsta_params->dhd; + wl_tput_info_t *tput_info; struct wl_if_info *tmp_if; +#ifdef WLDWDS + struct wl_dwds_info *dwds_if; +#endif /* WLDWDS */ uint32 etype = ntoh32(e->event_type); uint32 status = ntoh32(e->status); uint32 reason = ntoh32(e->reason); uint16 flags = ntoh16(e->flags); uint timeout = dhd->conf->tput_monitor_ms; int32 tput_sum = 0, tput_sum_kb = 0; - bool monitor_if[MAX_IF_NUM] = {FALSE}; + bool monitor_if[MAX_IF_NUM] = {FALSE}, monitor = FALSE; int i; if (etype == WLC_E_RESERVED && reason == ISAM_RC_TPUT_MONITOR) { tput_sum = 0; for (i=0; iif_info[i]; - if (tmp_if->dev && tmp_if->ifmode == ISTA_MODE && - wl_ext_get_chan(apsta_params, tmp_if->dev)) { - wl_tput_monitor(apsta_params, tmp_if); + if (tmp_if->dev && + (tmp_if->ifmode == ISTA_MODE || tmp_if->ifmode == IGC_MODE) && + wl_ext_associated(tmp_if->dev)) { + wl_tput_monitor(dhd, tmp_if->ifidx, &tmp_if->tput_info); monitor_if[i] = TRUE; } - else if (tmp_if->dev && tmp_if->ifmode == IAP_MODE && + else if (tmp_if->dev && + (tmp_if->ifmode == IAP_MODE || tmp_if->ifmode == IGO_MODE) && wl_ext_assoclist_num(tmp_if->dev)) { - wl_tput_monitor(apsta_params, tmp_if); + wl_tput_monitor(dhd, tmp_if->ifidx, &tmp_if->tput_info); monitor_if[i] = TRUE; } - tput_sum += (tmp_if->tput_tx + tmp_if->tput_rx); - tput_sum_kb += (tmp_if->tput_tx_kb + tmp_if->tput_rx_kb); + if (monitor_if[i] == TRUE) { + tput_info = &tmp_if->tput_info; + tput_sum += (tput_info->tput_tx + tput_info->tput_rx); + tput_sum_kb += (tput_info->tput_tx_kb + tput_info->tput_rx_kb); + } } +#ifdef WLDWDS + for (i=0; idwds_info[i]; + if (dwds_if->dev) { + wl_tput_monitor(dhd, dwds_if->ifidx, &dwds_if->tput_info); + tput_info = &dwds_if->tput_info; + tput_sum += (tput_info->tput_tx + tput_info->tput_rx); + tput_sum_kb += (tput_info->tput_tx_kb + tput_info->tput_rx_kb); + } + } +#endif /* WLDWDS */ apsta_params->tput_sum = tput_sum + (tput_sum_kb/1000); apsta_params->tput_sum_kb = tput_sum_kb % 1000; for (i=0; iif_info[i]; - wl_tput_dump(apsta_params, tmp_if); - wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout); + wl_cur_if_tput_dump(apsta_params, tmp_if); + monitor = TRUE; } } + if (monitor) + wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout); #ifdef BCMSDIO if (apsta_params->tput_sum >= dhd->conf->doflow_tput_thresh && dhd_doflow) { dhd_doflow = FALSE; @@ -3835,7 +4137,7 @@ wl_tput_monitor_handler(struct wl_apsta_params *apsta_params, } #endif } - else if (cur_if->ifmode == ISTA_MODE) { + else if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) { if (etype == WLC_E_LINK) { if (flags & WLC_EVENT_MSG_LINK) { wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout); @@ -3844,7 +4146,7 @@ wl_tput_monitor_handler(struct wl_apsta_params *apsta_params, } } } - else if (cur_if->ifmode == IAP_MODE) { + else if (cur_if->ifmode == IAP_MODE || cur_if->ifmode == IGO_MODE) { if ((etype == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) || (etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS && reason == WLC_E_REASON_INITIAL_ASSOC)) { @@ -3881,11 +4183,9 @@ wl_ext_max_prio_if(struct wl_apsta_params *apsta_params, { struct wl_if_info *tmp_if; wl_prio_t max_prio; - uint16 target_chan; int i; if (apsta_params->vsdb) { - target_chan = cur_if->channel; goto exit; } @@ -3895,8 +4195,7 @@ wl_ext_max_prio_if(struct wl_apsta_params *apsta_params, tmp_if = &apsta_params->if_info[i]; if (cur_if != tmp_if && wl_get_isam_status(tmp_if, IF_READY) && tmp_if->prio > max_prio) { - target_chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (target_chan) { + if (wl_ext_associated(tmp_if->dev)) { return TRUE; } } @@ -3909,7 +4208,7 @@ static void wl_ext_acs_scan(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { if (apsta_params->acs & ACS_DRV_BIT) { - if (wl_ext_get_chan(apsta_params, cur_if->dev)) { + if (wl_ext_associated(cur_if->dev)) { int ret, cur_scan_time; cur_if->escan->autochannel = 1; cur_scan_time = wl_ext_set_scan_time(cur_if->dev, 80, @@ -3927,22 +4226,22 @@ wl_ext_acs_scan(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) static void wl_ext_acs(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) { - uint cur_band; - uint16 cur_chan, acs_chan; + struct wl_chan_info chan_info; if (apsta_params->acs & ACS_DRV_BIT) { mutex_lock(&apsta_params->usr_sync); - cur_chan = wl_ext_get_chan(apsta_params, cur_if->dev); - if (cur_chan) { - cur_band = WL_GET_BAND(cur_chan); - if (cur_band == WLC_BAND_5G) - cur_if->channel = cur_if->escan->best_5g_ch; + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info); + if (chan_info.chan) { + if (chan_info.band == WLC_BAND_5G) + cur_if->chan_info.chan = cur_if->escan->best_5g_ch; else - cur_if->channel = cur_if->escan->best_2g_ch; - acs_chan = wl_ext_move_cur_channel(apsta_params, cur_if); - if (acs_chan != cur_chan) { - WL_MSG(cur_if->dev->name, "move channel %d => %d\n", - cur_chan, acs_chan); + cur_if->chan_info.chan = cur_if->escan->best_2g_ch; + wl_ext_move_cur_channel(apsta_params, cur_if); + if (!wl_ext_same_chan(&cur_if->chan_info, &chan_info)) { + WL_MSG(cur_if->dev->name, "move channel %s-%d => %s-%d\n", + WLCBAND2STR(chan_info->band), chan_info.chan, + WLCBAND2STR(cur_if->chan_info.band), cur_if->chan_info.chan); wl_ext_if_down(apsta_params, cur_if); wl_ext_move_other_channel(apsta_params, cur_if); wl_ext_if_up(apsta_params, cur_if, FALSE, 500); @@ -3955,23 +4254,21 @@ wl_ext_acs(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if) static void wl_acs_timer(unsigned long data) { - struct wl_if_info *cur_if = (struct wl_if_info *)data; + struct net_device *dev = (struct net_device *)data; struct dhd_pub *dhd; - struct wl_apsta_params *apsta_params; wl_event_msg_t msg; - if (!cur_if) { - IAPSTA_ERROR("wlan", "cur_if is not ready\n"); + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); return; } - dhd = dhd_get_pub(cur_if->dev); - apsta_params = dhd->iapsta_params; + dhd = dhd_get_pub(dev); bzero(&msg, sizeof(wl_event_msg_t)); - IAPSTA_TRACE(cur_if->dev->name, "timer expired\n"); + IAPSTA_TRACE(dev->name, "timer expired\n"); - msg.ifidx = cur_if->ifidx; + msg.ifidx = dhd_net2idx(dhd->info, dev); msg.event_type = hton32(WLC_E_RESERVED); msg.reason = hton32(ISAM_RC_AP_ACS); wl_ext_event_send(dhd->event_params, &msg, NULL); @@ -4054,10 +4351,349 @@ wl_acs_attach(dhd_pub_t *dhd, struct wl_if_info *cur_if) { IAPSTA_TRACE(cur_if->dev->name, "Enter\n"); cur_if->escan = dhd->escan; - init_timer_compat(&cur_if->acs_timer, wl_acs_timer, cur_if); + init_timer_compat(&cur_if->acs_timer, wl_acs_timer, cur_if->dev); } #endif /* ACS_MONITOR */ +#ifdef RESTART_AP_WAR +static void +wl_ext_restart_ap_timeout(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct dhd_pub *dhd; + wl_event_msg_t msg; + + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); + return; + } + + dhd = dhd_get_pub(dev); + + bzero(&msg, sizeof(wl_event_msg_t)); + IAPSTA_TRACE(dev->name, "timer expired\n"); + + msg.ifidx = dhd_net2idx(dhd->info, dev); + msg.event_type = hton32(WLC_E_RESERVED); + msg.reason = hton32(ISAM_RC_AP_RESTART); + wl_ext_event_send(dhd->event_params, &msg, NULL); +} + +static void +wl_ext_restart_ap_handler(struct wl_if_info *cur_if, + const wl_event_msg_t *e, void *data) +{ + struct dhd_pub *dhd = dhd_get_pub(cur_if->dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + uint32 etype = ntoh32(e->event_type); + uint32 reason = ntoh32(e->reason); + + if (etype == WLC_E_RESERVED && reason == ISAM_RC_AP_RESTART) { + if (!wl_get_isam_status(cur_if, AP_CREATED)) { + if (!wl_ext_associated(cur_if->dev)) { + WL_MSG(cur_if->ifname, "restart AP\n"); + wl_ext_if_down(apsta_params, cur_if); + wl_ext_if_up(apsta_params, cur_if, FALSE, 1); + wl_ext_mod_timer(&cur_if->restart_ap_timer, AP_RESTART_TIMEOUT, 0); + } else { + WL_MSG(cur_if->ifname, "skip restart AP\n"); + } + } + } + return; +} +#endif /* RESTART_AP_WAR */ + +#if defined(RESET_AP_WAR) || defined(RXF0OVFL_REINIT_WAR) +static int +wl_ext_counters_cbfn(void *ctx, const uint8 *data, uint16 type, uint16 len) +{ + struct wl_if_info *cur_if = ctx; + struct dhd_pub *dhd = dhd_get_pub(cur_if->dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + int res = BCME_OK; + + switch (type) { + case WL_CNT_XTLV_CNTV_LE10_UCODE: { + wl_cnt_v_le10_mcst_t *cnt = (wl_cnt_v_le10_mcst_t *)data; + if (len != sizeof(wl_cnt_v_le10_mcst_t)) { + printf("type %d: cnt struct length mismatch! %d != %d\n", + type, len, (int)sizeof(wl_cnt_v_le10_mcst_t)); + } +#ifdef RESET_AP_WAR + if (apsta_params->war_reason == ISAM_RC_AP_RESET) + cur_if->txbcnfrm = dtoh32(cnt->txbcnfrm); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + if (apsta_params->war_reason == ISAM_RC_RXF0OVFL_REINIT) { + apsta_params->rxbeaconmbss = dtoh32(cnt->rxbeaconmbss); + apsta_params->rxf0ovfl = dtoh32(cnt->rxf0ovfl); + } +#endif /* RXF0OVFL_REINIT_WAR */ + break; + } + case WL_CNT_XTLV_GE40_UCODE_V1: + { + wl_cnt_ge40mcst_v1_t *cnt = (wl_cnt_ge40mcst_v1_t *)data; + if (len != sizeof(wl_cnt_ge40mcst_v1_t)) { + IAPSTA_ERROR(cur_if->ifname, + "type 0x%x, cnt struct length mismatch! %d != %d\n", + type, len, (int)sizeof(wl_cnt_ge40mcst_v1_t)); + } +#ifdef RESET_AP_WAR + if (apsta_params->war_reason == ISAM_RC_AP_RESET) + cur_if->txbcnfrm = dtoh32(cnt->txbcnfrm); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + if (apsta_params->war_reason == ISAM_RC_RXF0OVFL_REINIT) { + apsta_params->rxbeaconmbss = dtoh32(cnt->rxbeaconmbss); + apsta_params->rxf0ovfl = dtoh32(cnt->rxf0ovfl); + } +#endif /* RXF0OVFL_REINIT_WAR */ + break; + } + case WL_CNT_XTLV_GE80_UCODE_V1: + { + wl_cnt_ge80mcst_v1_t *cnt = (wl_cnt_ge80mcst_v1_t *)data; + if (len != sizeof(wl_cnt_ge80mcst_v1_t)) { + IAPSTA_ERROR(cur_if->ifname, + "type 0x%x, cnt struct length mismatch! %d != %d\n", + type, len, (int)sizeof(wl_cnt_ge80mcst_v1_t)); + } +#ifdef RESET_AP_WAR + if (apsta_params->war_reason == ISAM_RC_AP_RESET) + cur_if->txbcnfrm = dtoh32(cnt->txbcnfrm); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + if (apsta_params->war_reason == ISAM_RC_RXF0OVFL_REINIT) { + apsta_params->rxbeaconmbss = dtoh32(cnt->rxbeaconmbss); + apsta_params->rxf0ovfl = dtoh32(cnt->rxf0ovfl); + } +#endif /* RXF0OVFL_REINIT_WAR */ + break; + } + default: + break; + } + return res; +} + +static int +wl_ext_counters_update(struct wl_if_info *cur_if, int war_reason) +{ + struct dhd_pub *dhd = dhd_get_pub(cur_if->dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + char *iovar_buf = NULL; + uint32 corerev = 0; + wl_cnt_info_t *cntinfo; + uint16 ver; + int ret = 0; + + iovar_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); + if (!iovar_buf) { + IAPSTA_ERROR(cur_if->ifname, "no memory\n"); + ret = BCME_NOMEM; + goto exit; + } + + memset(iovar_buf, 0, WLC_IOCTL_MEDLEN); + ret = wldev_iovar_getbuf(cur_if->dev, "counters", NULL, 0, + iovar_buf, WLC_IOCTL_MEDLEN, NULL); + if (unlikely(ret)) { + IAPSTA_ERROR(cur_if->ifname, + "counters error (%d) - size = %zu\n", ret, sizeof(wl_cnt_wlc_t)); + goto exit; + } + cntinfo = (wl_cnt_info_t *)iovar_buf; + cntinfo->version = dtoh16(cntinfo->version); + cntinfo->datalen = dtoh16(cntinfo->datalen); + ver = cntinfo->version; + CHK_CNTBUF_DATALEN(iovar_buf, WLC_IOCTL_MEDLEN); + if (ver > WL_CNT_T_VERSION) { + IAPSTA_ERROR(cur_if->ifname, + "Incorrect version of counters struct: expected %d; got %d\n", + WL_CNT_T_VERSION, ver); + goto exit; + } + + if (ver == WL_CNT_VERSION_11) { + wlc_rev_info_t revinfo; + memset(&revinfo, 0, sizeof(revinfo)); + ret = wl_ext_ioctl(cur_if->dev, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), 0); + if (ret) { + IAPSTA_ERROR(cur_if->ifname, "WLC_GET_REVINFO failed %d\n", ret); + goto exit; + } + corerev = dtoh32(revinfo.corerev); + } + ret = wl_cntbuf_to_xtlv_format(NULL, cntinfo, WLC_IOCTL_MEDLEN, corerev); + if (ret) { + IAPSTA_ERROR(cur_if->ifname, "wl_cntbuf_to_xtlv_format failed %d\n", ret); + goto exit; + } + + apsta_params->war_reason = war_reason; + if ((ret = bcm_unpack_xtlv_buf(cur_if, cntinfo->data, cntinfo->datalen, + BCM_XTLV_OPTION_ALIGN32, wl_ext_counters_cbfn))) { + IAPSTA_ERROR(cur_if->ifname, "bcm_unpack_xtlv_buf failed %d\n", ret); + goto exit; + } + +exit: + if (iovar_buf) + kfree(iovar_buf); + + return ret; +} +#endif /* RESET_AP_WAR | RXF0OVFL_REINIT_WAR */ + +#ifdef RESET_AP_WAR +static void +wl_ext_reset_ap_timeout(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct dhd_pub *dhd; + wl_event_msg_t msg; + + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); + return; + } + + dhd = dhd_get_pub(dev); + + bzero(&msg, sizeof(wl_event_msg_t)); + IAPSTA_TRACE(dev->name, "timer expired\n"); + + msg.ifidx = dhd_net2idx(dhd->info, dev); + msg.event_type = hton32(WLC_E_RESERVED); + msg.reason = hton32(ISAM_RC_AP_RESET); + wl_ext_event_send(dhd->event_params, &msg, NULL); +} + +static void +wl_ext_reset_ap_handler(struct wl_if_info *cur_if, + const wl_event_msg_t *e, void *data) +{ + struct dhd_pub *dhd = dhd_get_pub(cur_if->dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + uint32 etype = ntoh32(e->event_type); + uint32 status = ntoh32(e->status); + uint32 reason = ntoh32(e->reason); + uint32 txbcnfrm; + int ret = 0; + + if (wl_get_isam_status(cur_if, AP_CREATED)) { + if ((etype == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) || + (etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS && + reason == WLC_E_REASON_INITIAL_ASSOC)) { + // Link up + wl_ext_counters_update(cur_if, ISAM_RC_AP_RESET); + wl_ext_mod_timer(&cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT, 0); + } + else if (etype == WLC_E_RESERVED && reason == ISAM_RC_AP_RESET) { + txbcnfrm = cur_if->txbcnfrm; + ret = wl_ext_counters_update(cur_if, ISAM_RC_AP_RESET); + if (ret) + goto done; + if ((cur_if->txbcnfrm != 0) && (txbcnfrm == cur_if->txbcnfrm)) { + WL_MSG(cur_if->ifname, "reset AP mode\n"); + wl_ext_if_down(apsta_params, cur_if); + wl_ext_if_up(apsta_params, cur_if, FALSE, 500); + } +done: + wl_ext_mod_timer(&cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT, 0); + } + } + return; +} +#endif /* RESET_AP_WAR */ + +#ifdef RXF0OVFL_REINIT_WAR +static void +wl_ext_rxf0ovfl_reinit_timeout(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct dhd_pub *dhd; + wl_event_msg_t msg; + + if (!dev) { + IAPSTA_ERROR("wlan", "dev is not ready\n"); + return; + } + + dhd = dhd_get_pub(dev); + + bzero(&msg, sizeof(wl_event_msg_t)); + IAPSTA_TRACE(dev->name, "timer expired\n"); + + msg.ifidx = dhd_net2idx(dhd->info, dev); + msg.event_type = hton32(WLC_E_RESERVED); + msg.reason = hton32(ISAM_RC_RXF0OVFL_REINIT); + wl_ext_event_send(dhd->event_params, &msg, NULL); +} + +static void +wl_ext_rxf0ovfl_reinit_handler(struct wl_if_info *cur_if, const wl_event_msg_t *e, void *data) +{ + struct dhd_pub *dhd = dhd_get_pub(cur_if->dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + uint32 etype = ntoh32(e->event_type); + uint32 reason = ntoh32(e->reason); + uint32 status = ntoh32(e->status); + uint16 flags = ntoh16(e->flags); + uint32 rxbeaconmbss, rxbeaconmbss_diff = 0, rxf0ovfl, rxf0ovfl_diff = 0; + int ret = 0; + bool reinit = FALSE; + + if ((cur_if->ifmode == ISTA_MODE) && + (etype == WLC_E_LINK) && (flags & WLC_EVENT_MSG_LINK)) { + // Link up + wl_ext_counters_update(cur_if, ISAM_RC_RXF0OVFL_REINIT); + wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0); + } + else if ((cur_if->ifmode == IAP_MODE) && + ((etype == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) || + (etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS && + reason == WLC_E_REASON_INITIAL_ASSOC))) { + // Link up + wl_ext_counters_update(cur_if, ISAM_RC_RXF0OVFL_REINIT); + wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0); + } + else if ((etype == WLC_E_RESERVED) && (reason == ISAM_RC_RXF0OVFL_REINIT) && + (wl_ext_iapsta_other_if_enabled(cur_if->dev))) { + rxbeaconmbss = apsta_params->rxbeaconmbss; + rxf0ovfl = apsta_params->rxf0ovfl; + wl_ext_counters_update(cur_if, ISAM_RC_RXF0OVFL_REINIT); + if (ret) + goto done; + rxf0ovfl_diff = apsta_params->rxf0ovfl - rxf0ovfl; + rxbeaconmbss_diff = apsta_params->rxbeaconmbss - rxbeaconmbss; + if (rxf0ovfl_diff > 0) { + IAPSTA_INFO(cur_if->ifname, + "rxf0ovfl diff = %d, rxbeaconmbss diff = %d\n", + rxf0ovfl_diff, rxbeaconmbss_diff); + } + if (wl_ext_if_enabled(apsta_params, ISTA_MODE)) { + if (rxbeaconmbss_diff < 5 && rxf0ovfl_diff > RXF0OVFL_THRESHOLD) + reinit = TRUE; + } + else if (wl_ext_if_enabled(apsta_params, IAP_MODE)) { + if (rxf0ovfl_diff > RXF0OVFL_THRESHOLD) + reinit = TRUE; + } + if (reinit) { + WL_MSG(cur_if->ifname, "wl reinit\n"); + wl_ext_ioctl(cur_if->dev, WLC_INIT, NULL, 0, 1); + } +done: + wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0); + } + + return; +} +#endif /* RXF0OVFL_REINIT_WAR */ + void wl_ext_iapsta_event(struct net_device *dev, void *argu, const wl_event_msg_t *e, void *data) @@ -4219,6 +4855,15 @@ wl_ext_iapsta_event(struct net_device *dev, void *argu, #ifdef EAPOL_RESEND wl_resend_eapol_handler(cur_if, e, data); #endif /* EAPOL_RESEND */ +#ifdef RESTART_AP_WAR + wl_ext_restart_ap_handler(cur_if, e, data); +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + wl_ext_reset_ap_handler(cur_if, e, data); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + wl_ext_rxf0ovfl_reinit_handler(cur_if, e, data); +#endif /* RXF0OVFL_REINIT_WAR */ return; } @@ -4244,6 +4889,7 @@ wl_ext_parse_config(struct wl_if_info *cur_if, char *command, char **pick_next) {" bgnmode ", NULL, NULL}, {" hidden ", NULL, NULL}, {" maxassoc ", NULL, NULL}, + {" band ", NULL, NULL}, {" chan ", NULL, NULL}, {" amode ", NULL, NULL}, {" emode ", NULL, NULL}, @@ -4358,8 +5004,23 @@ wl_ext_parse_config(struct wl_if_info *cur_if, char *command, char **pick_next) } } else if (!strcmp(row->name, " maxassoc ")) { cur_if->maxassoc = (int)simple_strtol(pick_tmp, NULL, 10); + } else if (!strcmp(row->name, " band ")) { + if (!strcmp(pick_tmp, "2g")) + cur_if->amode = WLC_BAND_2G; + else if (!strcmp(pick_tmp, "5g")) + cur_if->amode = WLC_BAND_5G; +#ifdef WL_6G_BAND + else if (!strcmp(pick_tmp, "6g")) + cur_if->amode = WLC_BAND_6G; +#endif /* WL_6G_BAND */ + else { + IAPSTA_ERROR(cur_if->dev->name, "band [2g|5g|6g]\n"); + return -1; + } } else if (!strcmp(row->name, " chan ")) { - cur_if->channel = (int)simple_strtol(pick_tmp, NULL, 10); + cur_if->chan_info.chan = (int)simple_strtol(pick_tmp, NULL, 10); + if (!cur_if->chan_info.band) + cur_if->chan_info.band = WL_GET_BAND(cur_if->chan_info.chan); } else if (!strcmp(row->name, " amode ")) { if (!strcmp(pick_tmp, "open")) cur_if->amode = AUTH_OPEN; @@ -4424,14 +5085,14 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para if (i >= 1 && !strlen(cur_if->ifname)) snprintf(cur_if->ifname, IFNAMSIZ, "wlan%d", i); if (cur_if->ifmode == ISTA_MODE) { - cur_if->channel = 0; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 0); cur_if->maxassoc = -1; cur_if->prio = PRIO_STA; cur_if->vsdb = TRUE; cur_if->prefix = 'S'; snprintf(cur_if->ssid, DOT11_MAX_SSID_LEN, "ttt_sta"); } else if (cur_if->ifmode == IAP_MODE) { - cur_if->channel = 1; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 1); cur_if->maxassoc = -1; cur_if->prio = PRIO_AP; cur_if->vsdb = FALSE; @@ -4439,7 +5100,7 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para snprintf(cur_if->ssid, DOT11_MAX_SSID_LEN, "ttt_ap"); #ifdef WLMESH } else if (cur_if->ifmode == IMESH_MODE) { - cur_if->channel = 1; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 1); cur_if->maxassoc = -1; cur_if->prio = PRIO_MESH; cur_if->vsdb = FALSE; @@ -4677,7 +5338,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname, int wait_up, bool lock struct wl_apsta_params *apsta_params = dhd->iapsta_params; apstamode_t apstamode = apsta_params->apstamode; struct wl_if_info *cur_if = NULL, *tmp_if = NULL; - uint16 cur_chan; + struct wl_chan_info chan_info; struct wl_conn_info conn_info; u32 timeout; @@ -4709,13 +5370,11 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname, int wait_up, bool lock if (wl_ext_master_if(cur_if) && apsta_params->acs) { uint16 chan_2g, chan_5g; - uint auto_band; - auto_band = WL_GET_BAND(cur_if->channel); wl_ext_get_default_chan(cur_if->dev, &chan_2g, &chan_5g, TRUE); - if ((chan_2g && auto_band == WLC_BAND_2G) || - (chan_5g && auto_band == WLC_BAND_5G)) { - cur_if->channel = wl_ext_autochannel(cur_if->dev, apsta_params->acs, - auto_band); + if ((chan_2g && cur_if->chan_info.band == WLC_BAND_2G) || + (chan_5g && cur_if->chan_info.band == WLC_BAND_5G)) { + cur_if->chan_info.chan = wl_ext_autochannel(cur_if->dev, apsta_params->acs, + cur_if->chan_info.band); } else { IAPSTA_ERROR(ifname, "invalid channel\n"); ret = -1; @@ -4725,16 +5384,17 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname, int wait_up, bool lock wl_ext_move_cur_channel(apsta_params, cur_if); - if (wl_ext_master_if(cur_if) && !cur_if->channel) { + if (wl_ext_master_if(cur_if) && !cur_if->chan_info.chan) { IAPSTA_ERROR(ifname, "skip channel 0\n"); ret = -1; goto exit; } - cur_chan = wl_ext_get_chan(apsta_params, cur_if->dev); - if (cur_chan) { + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info); + if (chan_info.chan) { IAPSTA_INFO(cur_if->ifname, "Associated\n"); - if (cur_chan != cur_if->channel) { + if (!wl_ext_same_chan(&cur_if->chan_info, &chan_info)) { wl_ext_trigger_csa(apsta_params, cur_if); } goto exit; @@ -4767,11 +5427,10 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname, int wait_up, bool lock if (wl_ext_master_if(cur_if)) { wl_ext_set_bgnmode(cur_if); - if (!cur_if->channel) { - cur_if->channel = 1; + if (!cur_if->chan_info.chan) { + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 1); } - ret = wl_ext_set_chanspec(cur_if->dev, apsta_params->ioctl_ver, - cur_if->channel, &fw_chspec); + ret = wl_ext_set_chanspec(cur_if->dev, &cur_if->chan_info, &fw_chspec); if (ret) goto exit; } @@ -4781,7 +5440,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname, int wait_up, bool lock if (cur_if->ifmode == ISTA_MODE) { conn_info.bssidx = cur_if->bssidx; - conn_info.channel = cur_if->channel; + conn_info.channel = cur_if->chan_info.chan; memcpy(conn_info.ssid.SSID, cur_if->ssid, strlen(cur_if->ssid)); conn_info.ssid.SSID_len = strlen(cur_if->ssid); memcpy(&conn_info.bssid, &cur_if->bssid, ETHER_ADDR_LEN); @@ -4904,22 +5563,70 @@ exit: return ret; } +int +wl_ext_isam_dev_status(struct net_device *dev, ifmode_t ifmode, char prefix, + char *dump_buf, int dump_len) +{ + struct dhd_pub *dhd = dhd_get_pub(dev); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + struct wl_chan_info chan_info; + wlc_ssid_t ssid = { 0, {0} }; + struct ether_addr bssid; + scb_val_t scb_val; + char sec[64]; + u32 chanspec = 0; + int dump_written = 0; + + if (dev) { + memset(&ssid, 0, sizeof(ssid)); + memset(&bssid, 0, sizeof(bssid)); + memset(&scb_val, 0, sizeof(scb_val)); + memset(&chan_info, 0, sizeof(struct wl_chan_info)); + if (wl_ext_associated(dev)) { + wl_ext_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid), 0); + wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); + wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, + sizeof(scb_val_t), 0); + chanspec = wl_ext_get_chanspec(apsta_params, dev, &chan_info); + wl_ext_get_sec(dev, ifmode, sec, sizeof(sec), FALSE); + dump_written += snprintf(dump_buf+dump_written, dump_len, + "\n" DHD_LOG_PREFIXS "[%s-%c]: bssid=%pM, chan=%s-%-3d(0x%x %sMHz), " + "rssi=%3d, sec=%-20s, SSID=\"%s\"", + dev->name, prefix, &bssid, + WLCBAND2STR(chan_info.band), chan_info.chan, chanspec, + CHSPEC_IS20(chanspec)?"20": + CHSPEC_IS40(chanspec)?"40": + CHSPEC_IS80(chanspec)?"80":"160", + dtoh32(scb_val.val), sec, ssid.SSID); + if (ifmode == IAP_MODE) { + dump_written += wl_ext_assoclist(dev, NULL, + dump_buf+dump_written, dump_len-dump_written); + } +#ifdef WLMESH + else if (ifmode == IMESH_MODE) { + dump_written += snprintf(dump_buf+dump_written, dump_len, "\n"); + dump_written += wl_ext_mesh_peer_status(dev, NULL, + dump_buf+dump_written, dump_len-dump_written); + } +#endif /* WLMESH */ + } else { + dump_written += snprintf(dump_buf+dump_written, dump_len, + "\n" DHD_LOG_PREFIXS "[%s-%c]:", dev->name, prefix); + } + } + + return dump_written; +} + int wl_ext_isam_status(struct net_device *dev, char *command, int total_len) { struct dhd_pub *dhd = dhd_get_pub(dev); struct wl_apsta_params *apsta_params = dhd->iapsta_params; - int i; - struct wl_if_info *tmp_if; - uint16 chan = 0; - wlc_ssid_t ssid = { 0, {0} }; - struct ether_addr bssid; - scb_val_t scb_val; - char sec[32]; - u32 chanspec = 0; + struct wl_if_info *cur_if = NULL; char *dump_buf = NULL; - int dump_len = WLC_IOCTL_MEDLEN; - int dump_written = 0; + int dump_len = WLC_IOCTL_MEDLEN, dump_written = 0; + int i; if (command || android_msg_level & ANDROID_INFO_LEVEL) { if (command) { @@ -4929,51 +5636,31 @@ wl_ext_isam_status(struct net_device *dev, char *command, int total_len) dump_buf = kmalloc(dump_len, GFP_KERNEL); if (dump_buf == NULL) { IAPSTA_ERROR(dev->name, "Failed to allocate buffer of %d bytes\n", - dump_len); + dump_len); return -1; } + memset(dump_buf, 0, dump_len); } dump_written += snprintf(dump_buf+dump_written, dump_len, "apstamode=%d", apsta_params->apstamode); for (i=0; iif_info[i]; - if (tmp_if->dev) { - chan = wl_ext_get_chan(apsta_params, tmp_if->dev); - if (chan) { - wl_ext_ioctl(tmp_if->dev, WLC_GET_SSID, &ssid, sizeof(ssid), 0); - wldev_ioctl(tmp_if->dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0); - wldev_ioctl(tmp_if->dev, WLC_GET_RSSI, &scb_val, - sizeof(scb_val_t), 0); - chanspec = wl_ext_get_chanspec(apsta_params, tmp_if->dev); - wl_ext_get_sec(tmp_if->dev, tmp_if->ifmode, sec, sizeof(sec), FALSE); - dump_written += snprintf(dump_buf+dump_written, dump_len, - "\n" DHD_LOG_PREFIX "[%s-%c]: bssid=%pM, chan=%3d(0x%x %sMHz), " - "rssi=%3d, sec=%-15s, SSID=\"%s\"", - tmp_if->ifname, tmp_if->prefix, &bssid, chan, chanspec, - CHSPEC_IS20(chanspec)?"20": - CHSPEC_IS40(chanspec)?"40": - CHSPEC_IS80(chanspec)?"80":"160", - dtoh32(scb_val.val), sec, ssid.SSID); - if (tmp_if->ifmode == IAP_MODE) { - dump_written += snprintf(dump_buf+dump_written, dump_len, "\n"); - dump_written += wl_ext_assoclist(tmp_if->dev, NULL, + cur_if = &apsta_params->if_info[i]; + if (cur_if->dev) { + dump_written += wl_ext_isam_dev_status(cur_if->dev, + cur_if->ifmode, cur_if->prefix, + dump_buf+dump_written, dump_len-dump_written); + } +#ifdef WLDWDS + if (cur_if->ifmode == IAP_MODE) { + for (i=0; idwds_info[i].dev) { + dump_written += wl_ext_isam_dev_status(apsta_params->dwds_info[i].dev, + IAP_MODE, 'W', dump_buf+dump_written, dump_len-dump_written); } -#ifdef WLMESH - else if (tmp_if->ifmode == IMESH_MODE) { - dump_written += snprintf(dump_buf+dump_written, dump_len, "\n"); - dump_written += wl_ext_mesh_peer_status(tmp_if->dev, NULL, - dump_buf+dump_written, dump_len-dump_written); - } -#endif /* WLMESH */ - } else { - dump_written += snprintf(dump_buf+dump_written, dump_len, - "\n" DHD_LOG_PREFIX "[%s-%c]:", tmp_if->ifname, tmp_if->prefix); } } +#endif /* WLDWDS */ } IAPSTA_INFO(dev->name, "%s\n", dump_buf); } @@ -5348,7 +6035,7 @@ wl_ext_iapsta_alive_postinit(struct net_device *dev) if (i == 2 && !strlen(cur_if->ifname)) strcpy(cur_if->ifname, "wlan2"); if (cur_if->ifmode == ISTA_MODE) { - cur_if->channel = 0; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 0); cur_if->maxassoc = -1; wl_set_isam_status(cur_if, IF_READY); cur_if->prio = PRIO_STA; @@ -5357,7 +6044,7 @@ wl_ext_iapsta_alive_postinit(struct net_device *dev) snprintf(cur_if->ssid, DOT11_MAX_SSID_LEN, "ttt_sta"); } else if (cur_if->ifmode == IAP_MODE) { - cur_if->channel = 1; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 1); cur_if->maxassoc = -1; wl_set_isam_status(cur_if, IF_READY); cur_if->prio = PRIO_AP; @@ -5367,7 +6054,7 @@ wl_ext_iapsta_alive_postinit(struct net_device *dev) } #ifdef WLMESH else if (cur_if->ifmode == IMESH_MODE) { - cur_if->channel = 1; + wl_ext_set_chan_info(cur_if, WLC_BAND_2G, 1); cur_if->maxassoc = -1; wl_set_isam_status(cur_if, IF_READY); cur_if->prio = PRIO_MESH; @@ -5396,10 +6083,7 @@ wl_ext_iapsta_get_rsdb(struct net_device *net, struct dhd_pub *dhd) rsdb = 1; } else { rsdb_p = (wl_config_t *) iovar_buf; - if (dhd->conf->chip == BCM4375_CHIP_ID) - rsdb = rsdb_p->status; - else - rsdb = rsdb_p->config; + rsdb = rsdb_p->status; IAPSTA_INFO(net->name, "config=%d, status=%d\n", rsdb_p->config, rsdb_p->status); } @@ -5516,9 +6200,11 @@ wl_ext_iapsta_update_net_device(struct net_device *net, int ifidx) if (apsta_params->apstamode != IUNKNOWN_MODE && apsta_params->apstamode != ISTAAPAP_MODE && apsta_params->apstamode != ISTASTA_MODE) { - memcpy(net->dev_addr, primary_if->dev->dev_addr, ETHER_ADDR_LEN); - net->dev_addr[0] |= 0x02; - wl_ext_iapsta_get_vif_macaddr(dhd, ifidx, net->dev_addr); + u8 mac_addr[ETH_ALEN]; + memcpy(mac_addr, primary_if->dev->dev_addr, ETHER_ADDR_LEN); + mac_addr[0] |= 0x02; + wl_ext_iapsta_get_vif_macaddr(dhd, ifidx, mac_addr); + dev_addr_set(net, mac_addr); } #endif /* WL_STATIC_IF */ } @@ -5526,12 +6212,71 @@ wl_ext_iapsta_update_net_device(struct net_device *net, int ifidx) return 0; } +#ifdef WLDWDS +int +wl_ext_iapsta_attach_dwds_netdev(struct net_device *net, int ifidx, uint8 bssidx) +{ + struct dhd_pub *dhd = dhd_get_pub(net); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + struct wl_if_info *cur_if = NULL; + int i; + + for (i=0; iif_info[ifidx]; + if (cur_if->bssidx == bssidx) { + break; + } + } + + if (cur_if) { + IAPSTA_TRACE(net->name, "ifidx=%d, bssidx=%d\n", ifidx, bssidx); + for (i=0; idwds_info[i].dev == NULL) { + apsta_params->dwds_info[i].dev = net; + apsta_params->dwds_info[i].ifidx = ifidx; + apsta_params->dwds_info[i].bssidx = bssidx; + break; + } + } + } + + return 0; +} + +int +wl_ext_iapsta_dettach_dwds_netdev(struct net_device *net, int ifidx, uint8 bssidx) +{ + struct dhd_pub *dhd = dhd_get_pub(net); + struct wl_apsta_params *apsta_params = dhd->iapsta_params; + struct wl_if_info *cur_if = NULL; + int i; + + for (i=0; iif_info[ifidx]; + if (cur_if->bssidx == bssidx) { + break; + } + } + + if (cur_if) { + IAPSTA_TRACE(net->name, "ifidx=%d, bssidx=%d\n", ifidx, bssidx); + for (i=0; idwds_info[i].dev == net) { + memset(&apsta_params->dwds_info[i], 0, sizeof(struct wl_dwds_info)); + } + } + } + + return 0; +} +#endif /* WLDWDS */ + int wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx) { struct dhd_pub *dhd = dhd_get_pub(net); struct wl_apsta_params *apsta_params = dhd->iapsta_params; - struct wl_if_info *cur_if = NULL, *primary_if; + struct wl_if_info *cur_if = NULL; if (ifidx < MAX_IF_NUM) { IAPSTA_TRACE(net->name, "ifidx=%d, bssidx=%d\n", ifidx, bssidx); @@ -5555,8 +6300,11 @@ wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx) mutex_init(&apsta_params->usr_sync); mutex_init(&apsta_params->in4way_sync); mutex_init(&cur_if->pm_sync); +#ifdef STA_MGMT + INIT_LIST_HEAD(&apsta_params->sta_list); +#endif /* STA_MGMT */ #ifdef TPUT_MONITOR - init_timer_compat(&apsta_params->monitor_timer, wl_tput_monitor_timer, apsta_params); + init_timer_compat(&apsta_params->monitor_timer, wl_tput_monitor_timer, net); #endif /* TPUT_MONITOR */ #ifdef ACS_MONITOR wl_acs_attach(dhd, cur_if); @@ -5565,16 +6313,25 @@ wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx) #ifdef SET_CARRIER wl_ext_net_setcarrier(cur_if, FALSE, TRUE); #endif /* SET_CARRIER */ - init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, cur_if); + init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, net); #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) - init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, cur_if); + init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, net); #endif /* WL_EXT_RECONNECT && WL_CFG80211 */ +#ifdef RESTART_AP_WAR + init_timer_compat(&cur_if->restart_ap_timer, wl_ext_restart_ap_timeout, net); +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + init_timer_compat(&cur_if->reset_ap_timer, wl_ext_reset_ap_timeout, net); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + init_timer_compat(&apsta_params->rxf0ovfl_timer, wl_ext_rxf0ovfl_reinit_timeout, net); +#endif /* RXF0OVFL_REINIT_WAR */ #ifdef EAPOL_RESEND spin_lock_init(&apsta_params->eapol_lock); - init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, cur_if); + init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, net); #endif /* EAPOL_RESEND */ - } else if (cur_if && wl_get_isam_status(cur_if, IF_ADDING)) { - primary_if = &apsta_params->if_info[IF_PIF]; + } + else if (cur_if && wl_get_isam_status(cur_if, IF_ADDING)) { cur_if->dev = net; cur_if->ifidx = ifidx; cur_if->bssidx = bssidx; @@ -5593,12 +6350,18 @@ wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx) #ifdef SET_CARRIER wl_ext_net_setcarrier(cur_if, FALSE, TRUE); #endif /* SET_CARRIER */ - init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, cur_if); + init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, net); +#ifdef RESTART_AP_WAR + init_timer_compat(&cur_if->restart_ap_timer, wl_ext_restart_ap_timeout, net); +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + init_timer_compat(&cur_if->reset_ap_timer, wl_ext_reset_ap_timeout, net); +#endif /* RESET_AP_WAR */ #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) - init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, cur_if); + init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, net); #endif /* WL_EXT_RECONNECT && WL_CFG80211 */ #ifdef EAPOL_RESEND - init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, cur_if); + init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, net); #endif /* EAPOL_RESEND */ } @@ -5628,6 +6391,15 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx) #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0); #endif /* WL_EXT_RECONNECT && WL_CFG80211 */ +#ifdef RESTART_AP_WAR + wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0); +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + wl_ext_mod_timer(&cur_if->reset_ap_timer, 0, 0); +#endif /* RESET_AP_WAR */ +#ifdef RXF0OVFL_REINIT_WAR + wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, 0, 0); +#endif /* RXF0OVFL_REINIT_WAR */ #ifdef SET_CARRIER wl_ext_net_setcarrier(cur_if, FALSE, FALSE); #endif /* SET_CARRIER */ @@ -5644,6 +6416,9 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx) } #endif /* WLMESH && WL_ESCAN */ wl_ext_event_deregister(net, dhd, WLC_E_LAST, wl_ext_iapsta_event); +#ifdef STA_MGMT + wl_ext_flush_sta_list(net, ifidx); +#endif /* STA_MGMT */ memset(apsta_params, 0, sizeof(struct wl_apsta_params)); } else if (cur_if && (wl_get_isam_status(cur_if, IF_READY) || @@ -5655,6 +6430,12 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx) #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211) wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0); #endif /* WL_EXT_RECONNECT && WL_CFG80211 */ +#ifdef RESTART_AP_WAR + wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0); +#endif /* RESTART_AP_WAR */ +#ifdef RESET_AP_WAR + wl_ext_mod_timer(&cur_if->reset_ap_timer, 0, 0); +#endif /* RESET_AP_WAR */ #ifdef SET_CARRIER wl_ext_net_setcarrier(cur_if, FALSE, FALSE); #endif /* SET_CARRIER */ @@ -5668,6 +6449,9 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx) } #endif /* WLMESH && WL_ESCAN */ wl_ext_event_deregister(net, dhd, WLC_E_LAST, wl_ext_iapsta_event); +#ifdef STA_MGMT + wl_ext_flush_sta_list(net, ifidx); +#endif /* STA_MGMT */ memset(cur_if, 0, sizeof(struct wl_if_info)); } @@ -5705,4 +6489,3 @@ wl_ext_iapsta_dettach(struct net_device *net) } } #endif /* WL_EXT_IAPSTA */ - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.h index 176b77cc7262..75f016138cdb 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.h @@ -19,10 +19,12 @@ enum wl_ext_status { WL_EXT_STATUS_RECONNECT, WL_EXT_STATUS_CONNECTED, WL_EXT_STATUS_ADD_KEY, + WL_EXT_STATUS_AP_ENABLING, WL_EXT_STATUS_AP_ENABLED, WL_EXT_STATUS_DELETE_STA, WL_EXT_STATUS_STA_DISCONNECTED, WL_EXT_STATUS_STA_CONNECTED, + WL_EXT_STATUS_AP_DISABLING, WL_EXT_STATUS_AP_DISABLED }; @@ -33,6 +35,10 @@ void wl_ext_backup_eapol_txpkt(dhd_pub_t *dhd, int ifidx, void *pkt); void wl_ext_release_eapol_txpkt(dhd_pub_t *dhd, int ifidx, bool rx); #endif /* EAPOL_RESEND */ void wl_ext_iapsta_get_vif_macaddr(struct dhd_pub *dhd, int ifidx, u8 *mac_addr); +#ifdef WLDWDS +int wl_ext_iapsta_attach_dwds_netdev(struct net_device *net, int ifidx, uint8 bssidx); +int wl_ext_iapsta_dettach_dwds_netdev(struct net_device *net, int ifidx, uint8 bssidx); +#endif /* WLDWDS */ int wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx); int wl_ext_iapsta_attach_name(struct net_device *net, int ifidx); int wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx); @@ -67,15 +73,20 @@ int wl_ext_in4way_sync(struct net_device *dev, uint action, void wl_ext_update_extsae_4way(struct net_device *dev, const struct ieee80211_mgmt *mgmt, bool tx); u32 wl_ext_iapsta_update_channel(struct net_device *dev, u32 channel); -void wl_ext_iapsta_update_iftype(struct net_device *net, int ifidx, int wl_iftype); +void wl_ext_iapsta_update_iftype(struct net_device *net, int wl_iftype); bool wl_ext_iapsta_iftype_enabled(struct net_device *net, int wl_iftype); void wl_ext_iapsta_enable_master_if(struct net_device *dev, bool post); void wl_ext_iapsta_restart_master(struct net_device *dev); void wl_ext_iapsta_ifadding(struct net_device *net, int ifidx); bool wl_ext_iapsta_mesh_creating(struct net_device *net); void wl_ext_fw_reinit_incsa(struct net_device *dev); +#ifdef STA_MGMT +bool wl_ext_del_sta_info(struct net_device *net, u8 *bssid); +bool wl_ext_add_sta_info(struct net_device *net, u8 *bssid); +#endif /* STA_MGMT */ #ifdef SCAN_SUPPRESS -uint16 wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2); +uint16 wl_ext_scan_suppress(struct net_device *dev, void *scan_params, bool scan_v2, + struct wl_chan_info *chan_info); void wl_ext_reset_scan_busy(dhd_pub_t *dhd); #endif /* SCAN_SUPPRESS */ #endif @@ -83,4 +94,3 @@ void wl_ext_reset_scan_busy(dhd_pub_t *dhd); int wl_ext_get_wlfc_maxcount(struct dhd_pub *dhd, int ifidx); #endif /* PROPTX_MAXCOUNT */ #endif - diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c index fd116352b82b..ddec5e572394 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c @@ -2,13 +2,13 @@ * Linux Wireless Extensions support * * Copyright (C) 1999-2017, 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 @@ -16,7 +16,7 @@ * 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. @@ -56,32 +56,32 @@ uint iw_msg_level = WL_ERROR_LEVEL; #define WL_ERROR_MSG(x, args...) \ do { \ if (iw_msg_level & WL_ERROR_LEVEL) { \ - printk(KERN_ERR DHD_LOG_PREFIXS "WEXT-ERROR) %s : " x, __func__, ## args); \ + printf("WEXT-ERROR) %s : " x, __func__, ## args); \ } \ } while (0) #define WL_TRACE_MSG(x, args...) \ do { \ if (iw_msg_level & WL_TRACE_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "WEXT-TRACE) %s : " x, __func__, ## args); \ + printf("WEXT-TRACE) %s : " x, __func__, ## args); \ } \ } while (0) #define WL_SCAN_MSG(x, args...) \ do { \ if (iw_msg_level & WL_SCAN_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "WEXT-SCAN) %s : " x, __func__, ## args); \ + printf("WEXT-SCAN) %s : " x, __func__, ## args); \ } \ } while (0) #define WL_WSEC_MSG(x, args...) \ do { \ if (iw_msg_level & WL_WSEC_LEVEL) { \ - printk(KERN_INFO DHD_LOG_PREFIXS "WEXT-WSEC) %s : " x, __func__, ## args); \ + printf("WEXT-WSEC) %s : " x, __func__, ## args); \ } \ } while (0) #define WL_ERROR(x) WL_ERROR_MSG x #define WL_TRACE(x) WL_TRACE_MSG x #define WL_SCAN(x) WL_SCAN_MSG x #define WL_WSEC(x) WL_WSEC_MSG x - + #ifdef BCMWAPI_WPI /* these items should evetually go into wireless.h of the linux system headfile dir */ #ifndef IW_ENCODE_ALG_SM4 @@ -607,7 +607,7 @@ done: } #define DHD_CHECK(dhd, dev) \ - if (!dhd) { \ + if (!dhd) { \ WL_ERROR (("[%s] dhd is NULL\n", dev->name)); \ return -ENODEV; \ } \ @@ -1056,7 +1056,7 @@ wl_iw_set_wap( WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); DHD_CHECK(dhd, dev); - wext_info = dhd->wext_info; + wext_info = dhd->wext_info; if (awrq->sa_family != ARPHRD_ETHER) { WL_ERROR(("Invalid Header...sa_family\n")); return -EINVAL; @@ -1265,7 +1265,7 @@ wl_iw_iscan_get_aplist( WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); DHD_CHECK(dhd, dev); - wext_info = dhd->wext_info; + wext_info = dhd->wext_info; iscan = &wext_info->iscan; if (!extra) @@ -1594,7 +1594,7 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end, break; } } - + #ifdef BCMWAPI_WPI ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); ptr_len = bi->ie_length; @@ -2808,7 +2808,7 @@ wl_iw_set_pmksa( WL_TRACE(("%s: SIOCSIWPMKSA\n", dev->name)); DHD_CHECK(dhd, dev); wext_info = dhd->wext_info; - pmk_list = &wext_info->pmk_list; + pmk_list = &wext_info->pmk_list; if (pmk_list) pmkid_array = pmk_list->pmkids.pmkid; iwpmksa = (struct iw_pmksa *)extra; @@ -2935,7 +2935,7 @@ wl_iw_set_wpaauth( case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: { - int fbt_cap = 0; +// int fbt_cap = 0; if (paramid == IW_AUTH_CIPHER_PAIRWISE) { iw->pwsec = paramval; @@ -2984,6 +2984,7 @@ wl_iw_set_wpaauth( return error; } +#if 0 /* Ensure in-dongle supplicant is turned on when FBT wants to do the 4-way * handshake. */ @@ -3004,6 +3005,7 @@ wl_iw_set_wpaauth( } } } +#endif break; } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.h index eff0c6e227e8..e161006a2bd6 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.h @@ -2,13 +2,13 @@ * Linux Wireless Extensions support * * Copyright (C) 1999-2017, 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 @@ -16,7 +16,7 @@ * 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. @@ -129,10 +129,6 @@ extern const struct iw_handler_def wl_iw_handler_def; extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); int wl_iw_send_priv_event(struct net_device *dev, char *flag); -#ifdef WL_ESCAN -int wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi); -#endif int wl_iw_attach(struct net_device *dev); void wl_iw_detach(struct net_device *dev); s32 wl_iw_autochannel(struct net_device *dev, char* command, int total_len); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_linux_mon.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_linux_mon.c index 5568c9b20f34..d8b69aaba857 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_linux_mon.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_linux_mon.c @@ -64,7 +64,7 @@ int dhd_monitor_uninit(void); #ifndef DHD_MAX_IFS #define DHD_MAX_IFS 16 #endif -#define MON_PRINT(format, ...) printk("DHD-MON: %s " format, __func__, ##__VA_ARGS__) +#define MON_PRINT(format, ...) printf("DHD-MON: %s " format, __func__, ##__VA_ARGS__) #define MON_TRACE MON_PRINT typedef struct monitor_interface { diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wldev_common.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wldev_common.c index ebdc8ffe42bd..9cf13d2f0f62 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wldev_common.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wldev_common.c @@ -56,21 +56,19 @@ #define WLDEV_ERROR_TEXT USER_PREFIX_WLDEV #define WLDEV_INFO_TEXT USER_PREFIX_WLDEV #else -#define WLDEV_ERROR_TEXT DHD_LOG_PREFIXS "WLDEV-ERROR) " -#define WLDEV_INFO_TEXT DHD_LOG_PREFIXS "WLDEV-INFO) " +#define WLDEV_ERROR_TEXT "WLDEV-ERROR) " +#define WLDEV_INFO_TEXT "WLDEV-INFO) " #endif /* defined(CUSTOMER_DBG_PREFIX_ENABLE) */ #define WLDEV_ERROR_MSG(x, args...) \ do { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(WLDEV_ERROR_TEXT x, ## args); \ + printf(WLDEV_ERROR_TEXT x, ## args); \ } while (0) #define WLDEV_ERROR(x) WLDEV_ERROR_MSG x #define WLDEV_INFO_MSG(x, args...) \ do { \ - WL_DBG_PRINT_SYSTEM_TIME; \ - pr_cont(WLDEV_INFO_TEXT x, ## args); \ + printf(WLDEV_INFO_TEXT x, ## args); \ } while (0) #define WLDEV_INFO(x) WLDEV_INFO_MSG x