diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/Makefile b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/Makefile index 4902f3df03c1..be6dc59adafe 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/Makefile +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/Makefile @@ -26,14 +26,9 @@ # <> # -CONFIG_BCMDHD := m - -#CONFIG_BCMDHD_SDIO := y -#CONFIG_BCMDHD_PCIE := y -#CONFIG_BCMDHD_USB := y -CONFIG_BCMDHD_OOB_HOST_WAKE := y - CONFIG_ANDROID := y +CONFIG_ANDROID12 := y +CONFIG_BCMDHD_OOB_HOST_WAKE := y ##################### # SDIO Basic feature @@ -48,7 +43,7 @@ DHDCFLAGS += -Wall -Wstrict-prototypes -Dlinux -DLINUX -DBCMDRIVER \ -DGET_CUSTOM_MAC_ENABLE \ -DSEC_ENHANCEMENT -DDHD_FW_COREDUMP -DCHIPS_CUSTOMER_HW6 \ -DDHD_RND_DEBUG -DDHD_DUMP_FILE_WRITE_FROM_KERNEL \ - -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT + -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DWL11AX GCCVERSIONGTEQ9 := $(shell expr `$(CROSS_COMPILE)gcc -dumpversion | cut -f1 -d.` \>= 9) ifeq "$(GCCVERSIONGTEQ9)" "1" @@ -56,8 +51,8 @@ ifeq "$(GCCVERSIONGTEQ9)" "1" endif DHDCFLAGS += $(call cc-disable-warning, date-time) DHDCFLAGS += $(call cc-disable-warning, stringop-overflow) - DHDCFLAGS += -Wno-implicit-function-declaration -Wno-incompatible-pointer-types +DHDCFLAGS += -Wno-unused-const-variable -Wno-unused-function ################# # Common feature @@ -156,6 +151,12 @@ DHDCFLAGS += -DBCMCCX DHDCFLAGS += -DWBTEXT DHDCFLAGS += -DDHD_LOSSLESS_ROAMING +# Hog flags +#DHDCFLAGS += -DENABLE_HOGSQS +#ifeq ($(ENABLE_HOGSQS), y) +#DHDCFLAGS += -DM_HOGSQS_CFG=0x1910 +#endif // endif + # For special PNO Event keep wake lock for 10sec DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10 DHDCFLAGS += -DMIRACAST_AMPDU_SIZE=8 @@ -224,7 +225,9 @@ ifeq ($(CONFIG_ANDROID),y) DHDCFLAGS += -Wno-date-time # To support android12 Wifi-HAL -# DHDCFLAGS += -DANDROID12_SUPPORT +ifeq ($(CONFIG_ANDROID12),y) + DHDCFLAGS += -DANDROID12_SUPPORT +endif # To support ACS on hostapd # DHDCFLAGS += -DWL_SUPPORT_ACS_OFFLOAD @@ -258,6 +261,11 @@ ifneq ($(CONFIG_BCMDHD_PCIE),) DHDCFLAGS += -DDHD_4WAYM4_FAIL_DISCONNECT endif +#6Ghz +ifneq ($(CONFIG_BCMDHD_6E),) + DHDCFLAGS += -DWL_6E +endif + # Uncomment the below line for AP to receive disconnect management frame. # DHDCFLAGS += -DWL_CFG80211_AP_RX_MGMT_DISCONNECT @@ -306,7 +314,12 @@ endif ifeq ($(CONFIG_BCMDHD_SDMMC),y) DHDCFLAGS += -DBCMLXSDMMC -DCUSTOM_TXGLOM=1 ifneq ($(CONFIG_HAVE_IMX8_SOC),) - DHDCFLAGS += -DCONFIG_DTS -DPLATFORM_IMX + DHDCFLAGS += \ + -DCONFIG_DTS \ + -DOEM_EMBEDDED_LINUX \ + -DPLATFORM_IMX \ + -DSDIO_ISR_THREAD \ + -DWL_VIF_SUPPORT endif endif @@ -342,6 +355,11 @@ endif DHDCFLAGS += -DWLFC_STATE_PREALLOC DHDCFLAGS += -DREVERSE_AIFSN + +# btsharedsdio +ifneq ($(CONFIG_BT_OVER_SDIO),) + DHDCFLAGS += -DBT_OVER_SDIO +endif endif # Expand TCP tx queue to 10 times of default size @@ -496,12 +514,17 @@ DHDOFILES += dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o \ dhd_linux.o dhd_linux_sched.o dhd_cfg80211.o dhd_linux_wq.o aiutils.o \ bcmevent.o bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o linux_pkt.o \ sbutils.o siutils.o wl_android.o wl_roam.o wl_cfg80211.o wl_cfgscan.o wl_cfgp2p.o \ - wl_cfg_btcoex.o wldev_common.o wl_linux_mon.o dhd_linux_platdev.o \ + wl_cfg_btcoex.o wldev_common.o dhd_linux_platdev.o \ dhd_pno.o dhd_linux_pktdump.o wl_cfg_btcoex.o hnd_pktq.o \ hnd_pktpool.o wl_cfgvendor.o bcmxtlv.o bcm_app_utils.o dhd_debug.o \ dhd_debug_linux.o dhd_mschdbg.o bcmbloom.o dhd_dbg_ring.o bcmstdlib_s.o \ dhd_linux_exportfs.o +ifneq ($(CONFIG_DHD_MONITOR_INTERFACE),) + DHDCFLAGS += -DDHD_MONITOR_INTERFACE + DHDOFILES += wl_linux_mon.o +endif + ifneq ($(CONFIG_DHD_OF_SUPPORT),) DHDCFLAGS += -DDHD_OF_SUPPORT DHDOFILES += dhd_custom_msm.o diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmevent.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmevent.c index 8e29abf818d3..1e5a250a6183 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmevent.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmevent.c @@ -205,6 +205,7 @@ static const bcmevent_name_str_t bcmevent_names[] = { BCMEVENT_NAME(WLC_E_RPSNOA), BCMEVENT_NAME(WLC_E_PHY_CAL), BCMEVENT_NAME(WLC_E_WA_LQM), + BCMEVENT_NAME(WLC_E_OVERTEMP), }; const char *bcmevent_get_name(uint event_type) diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmsdh.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmsdh.c index 2e289c85b3bf..2fbbcf5c0745 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmsdh.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmsdh.c @@ -147,7 +147,11 @@ void bcmsdh_btsdio_interface_init(struct sdio_func *func, BCMSDH_INFO(("%s: func %p \n", __FUNCTION__, func)); func_f3 = func; processf3intr = f3intr_fun; +#if defined(BCMLXSDMMC) sdioh_sdmmc_card_enable_func_f3(bcmsdh->sdioh, func); +#else + BCMSDH_ERROR(("bcmsdh_btsdio_interface_init: not support f3 enable on non-sdmmc build\n")); +#endif /* defined(BCMLXSDMMC) */ process_dhd_hang_notification = hang_notification; } EXPORT_SYMBOL(bcmsdh_btsdio_interface_init); @@ -614,7 +618,7 @@ bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) + if (fn != SDIO_FUNC_3 && width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, @@ -652,7 +656,7 @@ bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - if (width == 4) + if (fn != SDIO_FUNC_3 && width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.c index 3ab1eb666ddd..18747aae268b 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.c @@ -160,6 +160,35 @@ static const uint8 wf_5g_160m_chans[] = #define WF_NUM_5G_160M_CHANS \ (sizeof(wf_5g_160m_chans)/sizeof(uint8)) +/* Based on IEEE 802.11ax D6.1 */ +/* 40MHz channels in 6GHz band */ +static const uint8 wf_6g_40m_chans[] = +{3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, +107, 115, 123, 131, 139, 147, 155, 163, 171, 179, +187, 195, 203, 211, 219, 227}; +#define WF_NUM_6G_40M_CHANS \ + (sizeof(wf_6g_40m_chans)/sizeof(uint8)) + +/* 80MHz channels in 6GHz band */ +static const uint8 wf_6g_80m_chans[] = +{7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 167, 183, +199, 215}; +#define WF_NUM_6G_80M_CHANS \ + (sizeof(wf_6g_80m_chans)/sizeof(uint8)) + +/* 160MHz channels in 6GHz band */ +static const uint8 wf_6g_160m_chans[] = +{15, 47, 79, 111, 143, 175, 207}; +#define WF_NUM_6G_160M_CHANS \ + (sizeof(wf_6g_160m_chans)/sizeof(uint8)) + +/* 6GHz PSC channels */ +uint8 wf_6g_psc_chans[] = +{5, 21, 37, 53, 69, 85, 101, 117, 133, 149, 165, 181, +197, 213, 229}; +#define WF_NUM_6G_PSC_CHANS \ + (sizeof(wf_6g_psc_chans)/sizeof(uint8)) + /* opclass and channel information for US. Table E-1 */ static const uint16 opclass_data[] = { (WL_CHANSPEC_BAND_5G |((WL_CHANSPEC_BW_20)&WL_CHANSPEC_BW_MASK)), @@ -645,10 +674,9 @@ wf_chspec_malformed(chanspec_t chanspec) uint chspec_bw = CHSPEC_BW(chanspec); uint chspec_ch = CHSPEC_CHANNEL(chanspec); - /* must be 2G or 5G band */ if (CHSPEC_IS2G(chanspec)) { - /* must be valid bandwidth */ - if (!BW_LE40(chspec_bw)) { + /* must be valid bandwidth and channel */ + if (!BW_LE40(chspec_bw) || (chspec_ch > CH_MAX_2G_CHANNEL)) { return TRUE; } } else if (CHSPEC_IS5G(chanspec)) { @@ -661,6 +689,26 @@ wf_chspec_malformed(chanspec_t chanspec) if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS) return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 || + chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) { + + if (chspec_ch > MAXCHANNEL) { + return TRUE; + } + } else { + /* invalid bandwidth */ + return TRUE; + } + } else if (CHSPEC_IS6G(chanspec)) { + if (chspec_bw == WL_CHANSPEC_BW_8080) { + uint ch1_id, ch2_id; + + /* channel IDs in 80+80 must be in range */ + ch1_id = CHSPEC_CHAN1(chanspec); + ch2_id = CHSPEC_CHAN2(chanspec); + if (ch1_id >= WF_NUM_6G_80M_CHANS || ch2_id >= WF_NUM_6G_80M_CHANS) + return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 || chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) { @@ -672,7 +720,8 @@ wf_chspec_malformed(chanspec_t chanspec) return TRUE; } } else { - /* must be 2G or 5G band */ + + /* must be 2G, 5G or 6G band */ return TRUE; } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.h index 296f1507a220..e78878bcf984 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/bcmwifi_channels.h @@ -52,12 +52,15 @@ typedef uint16 chanspec_subband_t; #define CH_MIN_2G_40M_CHANNEL 3u /* Min 40MHz center channel in 2G band */ #define CH_MAX_2G_40M_CHANNEL 11u /* Max 40MHz center channel in 2G band */ +#define CH_MIN_6G_CHANNEL 1u /* Min channel in 6G band */ +#define CH_MAX_6G_CHANNEL 233u /* Max channel in 6G band */ + /* maximum # channels the s/w supports */ -#define MAXCHANNEL 224 /* max # supported channels. The max channel no is above, - * this is that + 1 rounded up to a multiple of NBBY (8). +#define MAXCHANNEL 240 /* max # supported channels. The max channel no is 233, + * this is that + 7 rounded up to a multiple of NBBY (8). * DO NOT MAKE it > 255: channels are uint8's all over */ -#define MAXCHANNEL_NUM (MAXCHANNEL - 1) /* max channel number */ +#define MAXCHANNEL_NUM (MAXCHANNEL - 7) /* max channel number */ #define INVCHANNEL 255 /* error value for a bad channel */ @@ -502,6 +505,12 @@ extern bool wf_chspec_coexist(chanspec_t chspec1, chanspec_t chspec2); #define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ +/** + * Starting frequence of 6 GHz channels. + * Wi-Fi 6E operates in the 6 GHz band from 5.925 to 7.125 GHz. + */ +#define FREQ_START_6G_CHANNEL 5925 /* 6G band starting frequence */ + /** * No of sub-band vlaue of the specified Mhz chanspec */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_bt_interface.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_bt_interface.h new file mode 100644 index 000000000000..fda4426dd0fb --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_bt_interface.h @@ -0,0 +1,76 @@ +/* + * + * + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation + * + * 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 + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * + * <> + * + * $Id: $ + * + */ + +#ifndef _dhd_bt_interface_h_ +#define _dhd_bt_interface_h_ +#include + +typedef enum { + WLAN_MODULE = 0, + BT_MODULE +} bus_owner_t; + +typedef void * wlan_bt_handle_t; +typedef void (*f3intr_handler)(struct sdio_func *func); +typedef void (*dhd_hang_notification)(struct sdio_func *func, bool wifi_state); + +extern void bcmsdh_btsdio_interface_init(struct sdio_func *func, + f3intr_handler f3intr_fun, dhd_hang_notification hang_notification); +void bcmsdh_btsdio_process_f3_intr(void); +void bcmsdh_btsdio_process_dhd_hang_notification(bool wifi_recovery_completed); + +extern int dhd_bus_recv_buf(void *h, uint32 addr, uint fn, uint8 *buf, uint nbytes); +extern int dhd_bus_send_buf(void *h, uint32 addr, uint fn, uint8 *buf, uint nbytes); +extern int dhd_bus_set_blocksize(void *h, unsigned int fun_num, unsigned int block_size); + +/* Shared Layer Init function */ +extern wlan_bt_handle_t dhd_bt_get_pub_hndl(void); +extern int dhd_download_btfw(wlan_bt_handle_t handle, char* btfw_path); +extern int dhd_bus_get(wlan_bt_handle_t handle, bus_owner_t owner); +extern int dhd_bus_put(wlan_bt_handle_t handle, bus_owner_t owner); + +extern unsigned char dhd_bus_cfg_read(void *h, unsigned int fun_num, unsigned int addr, int *err); +extern void dhd_bus_cfg_write(void *h, unsigned int fun_num, unsigned int addr, + unsigned char val, int *err); + +/* + * Functions to be called from other layers to enable/disable Bus clock + * can_wait - Callers pass TRUE, if they want & can wait until the + * clock configuration takes effect (there is a register poll until the + * PLLs are locked). If the caller cannot wait they can simply pass + * FALSE. + */ +extern int dhd_bus_clk_enable(wlan_bt_handle_t handle, bus_owner_t owner); +extern int dhd_bus_clk_disable(wlan_bt_handle_t handle, bus_owner_t owner); +extern void dhd_bus_reset_bt_use_count(wlan_bt_handle_t handle); +extern void dhd_bus_retry_hang_recovery(wlan_bt_handle_t handle); +#endif /* _dhd_bt_interface_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_common.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_common.c index fb97358e3a57..0ffadceb79f6 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_common.c @@ -89,6 +89,7 @@ #include #endif // endif +#include #if defined(DHD_POST_EAPOL_M1_AFTER_ROAM_EVT) #include #endif // endif @@ -3102,6 +3103,11 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data, elqm_basic->tx_rate, elqm_basic->rx_rate)); break; } + case WLC_E_OVERTEMP: + { + DHD_EVENT(("MACEVENT: %s\n", event_name)); + break; + } default: DHD_INFO(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", event_name, event_type, eabuf, (int)status, (int)reason, @@ -3563,6 +3569,13 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); break; } +#ifdef WL_CFG80211 + case WLC_E_OVERTEMP: + { + wl_cfg80211_overtemp_event(dhd_idx2net(dhd_pub, event->ifidx)); + break; + } +#endif /* WL_CFG80211 */ case WLC_E_NDIS_LINK: break; @@ -3645,6 +3658,13 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen } break; #endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */ +#ifdef BCMSDIO + case WLC_E_AP_STARTED: + if (FW_SUPPORTED(dhd_pub, idsup)) { + dhd_pub->info->iflist[*ifidx]->role = WLC_E_IF_ROLE_AP; + } + break; +#endif /* BCMSDIO */ case WLC_E_LINK: #ifdef PCIE_FULL_DONGLE if (dhd_update_interface_link_status(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info, @@ -5695,13 +5715,12 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) DHD_ERROR(("clm path exceeds max len\n")); return BCME_ERROR; } - clm_blob_path = clm_path; + clm_blob_path = "/vendor/etc/firmware/4359_cypress_auto.clm_blob";//clm_path; DHD_TRACE(("clm path from module param:%s\n", clm_path)); } else { - clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; + clm_blob_path = "/vendor/etc/firmware/4359_cypress_auto.clm_blob";//VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; } - clm_blob_path = "/vendor/etc/firmware/4359_cypress_auto.clm_blob"; /* If CLM blob file is found on the filesystem, download the file. * After CLM file download or If the blob file is not present, * validate the country code before proceeding with the initialization. diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_custom_msm.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_custom_msm.c index 7b438418a61c..453b371094c4 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_custom_msm.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_custom_msm.c @@ -36,7 +36,12 @@ #include #include #include +#if defined(CONFIG_WIFI_CONTROL_FUNC) #include +#else +#include +#include +#endif /* CONFIG_WIFI_CONTROL_FUNC */ #include #include #include @@ -55,7 +60,9 @@ extern int dhd_init_wlan_mem(void); extern void *dhd_wlan_mem_prealloc(int section, unsigned long size); #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */ -#define WIFI_TURNON_DELAY 200 +#ifndef WIFI_TURNON_DELAY +#define WIFI_TURNON_DELAY 200 +#endif /* WIFI_TURNON_DELAY */ static int wlan_reg_on = -1; #ifdef CUSTOM_DT_COMPAT_ENTRY #define DHD_DT_COMPAT_ENTRY CUSTOM_DT_COMPAT_ENTRY diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_debug.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_debug.c index 501f120e6438..e4b50cb430f2 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_debug.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_debug.c @@ -1380,13 +1380,9 @@ __dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid) uint32 __dhd_dbg_driver_ts_usec(void) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) struct timespec64 ts; -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) - struct timespec ts; -#endif /* LINUX_VER >= 2.6.39 */ - get_monotonic_boottime(&ts); + ts = ktime_to_timespec64(ktime_get_boottime()); return ((uint32)(__TIMESPEC_TO_US(ts))); } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.c index fbd3543899e2..119c02f33e81 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.c @@ -875,9 +875,11 @@ static void dhd_net_if_unlock_local(dhd_info_t *dhd); static void dhd_suspend_lock(dhd_pub_t *dhdp); static void dhd_suspend_unlock(dhd_pub_t *dhdp); +#ifdef DHD_MONITOR_INTERFACE /* Monitor interface */ int dhd_monitor_init(void *dhd_pub); int dhd_monitor_uninit(void); +#endif /* DHD_MONITOR_INTERFACE */ #ifdef DHD_PM_CONTROL_FROM_FILE bool g_pm_control; @@ -3097,9 +3099,6 @@ dhd_set_mac_address(struct net_device *dev, void *addr) int ret = 0; dhd_info_t *dhd = DHD_DEV_INFO(dev); -#if defined(SUPPORT_RANDOM_MAC_SCAN) - struct bcm_cfg80211 *cfg = wl_get_cfg(dev); -#endif // endif struct sockaddr *sa = (struct sockaddr *)addr; int ifidx; dhd_if_t *dhdif; @@ -3110,15 +3109,6 @@ dhd_set_mac_address(struct net_device *dev, void *addr) dhdif = dhd->iflist[ifidx]; - if ((dhdif != NULL) && -#if defined(SUPPORT_RANDOM_MAC_SCAN) - (!(cfg->random_mac_enabled)) && -#endif // endif - (dhdif->idx > 0)) { - DHD_ERROR(("%s: Intf[%s] Blocking MAC Overwrite \n", __FUNCTION__, dhdif->name)); - return 0; - } - dhd_net_if_lock_local(dhd); memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN); dhdif->set_macaddress = TRUE; @@ -3498,6 +3488,9 @@ exit: return ret; } +#ifndef DHD_MONITOR_INTERFACE +static +#endif /* DHD_MONITOR_INTERFACE */ #ifdef CFI_CHECK netdev_tx_t BCMFASTPATH #else /* CFI_CHECK */ @@ -5917,230 +5910,6 @@ dhd_monitor_start(struct sk_buff *skb, struct net_device *dev) #endif /* CFI_CHECK */ } -#if defined(BT_OVER_SDIO) - -void -dhdsdio_bus_usr_cnt_inc(dhd_pub_t *dhdp) -{ - dhdp->info->bus_user_count++; -} - -void -dhdsdio_bus_usr_cnt_dec(dhd_pub_t *dhdp) -{ - dhdp->info->bus_user_count--; -} - -/* Return values: - * Success: Returns 0 - * Failure: Returns -1 or errono code - */ -int -dhd_bus_get(wlan_bt_handle_t handle, bus_owner_t owner) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - int ret = 0; - - mutex_lock(&dhd->bus_user_lock); - ++dhd->bus_user_count; - if (dhd->bus_user_count < 0) { - DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__)); - ret = -1; - goto exit; - } - - if (dhd->bus_user_count == 1) { - - dhd->pub.hang_was_sent = 0; - - /* First user, turn on WL_REG, start the bus */ - DHD_ERROR(("%s(): First user Turn On WL_REG & start the bus", __FUNCTION__)); - - if (!wifi_platform_set_power(dhd->adapter, TRUE, WIFI_TURNON_DELAY)) { - /* Enable F1 */ - ret = dhd_bus_resume(dhdp, 0); - if (ret) { - DHD_ERROR(("%s(): Failed to enable F1, err=%d\n", - __FUNCTION__, ret)); - goto exit; - } - } - - dhd_update_fw_nv_path(dhd); - /* update firmware and nvram path to sdio bus */ - dhd_bus_update_fw_nv_path(dhd->pub.bus, - dhd->fw_path, dhd->nv_path); - /* download the firmware, Enable F2 */ - /* TODO: Should be done only in case of FW switch */ - ret = dhd_bus_devreset(dhdp, FALSE); - dhd_bus_resume(dhdp, 1); - if (!ret) { - if (dhd_sync_with_dongle(&dhd->pub) < 0) { - DHD_ERROR(("%s(): Sync with dongle failed!!\n", __FUNCTION__)); - ret = -EFAULT; - } - } else { - DHD_ERROR(("%s(): Failed to download, err=%d\n", __FUNCTION__, ret)); - } - } else { - DHD_ERROR(("%s(): BUS is already acquired, just increase the count %d \r\n", - __FUNCTION__, dhd->bus_user_count)); - } -exit: - mutex_unlock(&dhd->bus_user_lock); - return ret; -} -EXPORT_SYMBOL(dhd_bus_get); - -/* Return values: - * Success: Returns 0 - * Failure: Returns -1 or errono code - */ -int -dhd_bus_put(wlan_bt_handle_t handle, bus_owner_t owner) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - int ret = 0; - BCM_REFERENCE(owner); - - mutex_lock(&dhd->bus_user_lock); - --dhd->bus_user_count; - if (dhd->bus_user_count < 0) { - DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__)); - dhd->bus_user_count = 0; - ret = -1; - goto exit; - } - - if (dhd->bus_user_count == 0) { - /* Last user, stop the bus and turn Off WL_REG */ - DHD_ERROR(("%s(): There are no owners left Trunf Off WL_REG & stop the bus \r\n", - __FUNCTION__)); -#ifdef PROP_TXSTATUS - if (dhd->pub.wlfc_enabled) { - dhd_wlfc_deinit(&dhd->pub); - } -#endif /* PROP_TXSTATUS */ -#ifdef PNO_SUPPORT - if (dhd->pub.pno_state) { - dhd_pno_deinit(&dhd->pub); - } -#endif /* PNO_SUPPORT */ -#ifdef RTT_SUPPORT - if (dhd->pub.rtt_state) { - dhd_rtt_deinit(&dhd->pub); - } -#endif /* RTT_SUPPORT */ - ret = dhd_bus_devreset(dhdp, TRUE); - if (!ret) { - dhd_bus_suspend(dhdp); - wifi_platform_set_power(dhd->adapter, FALSE, WIFI_TURNOFF_DELAY); - } - } else { - DHD_ERROR(("%s(): Other owners using bus, decrease the count %d \r\n", - __FUNCTION__, dhd->bus_user_count)); - } -exit: - mutex_unlock(&dhd->bus_user_lock); - return ret; -} -EXPORT_SYMBOL(dhd_bus_put); - -int -dhd_net_bus_get(struct net_device *dev) -{ - dhd_info_t *dhd = DHD_DEV_INFO(dev); - return dhd_bus_get(&dhd->pub, WLAN_MODULE); -} - -int -dhd_net_bus_put(struct net_device *dev) -{ - dhd_info_t *dhd = DHD_DEV_INFO(dev); - return dhd_bus_put(&dhd->pub, WLAN_MODULE); -} - -/* - * Function to enable the Bus Clock - * Returns BCME_OK on success and BCME_xxx on failure - * - * This function is not callable from non-sleepable context - */ -int dhd_bus_clk_enable(wlan_bt_handle_t handle, bus_owner_t owner) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - - int ret; - - dhd_os_sdlock(dhdp); - /* - * The second argument is TRUE, that means, we expect - * the function to "wait" until the clocks are really - * available - */ - ret = __dhdsdio_clk_enable(dhdp->bus, owner, TRUE); - dhd_os_sdunlock(dhdp); - - return ret; -} -EXPORT_SYMBOL(dhd_bus_clk_enable); - -/* - * Function to disable the Bus Clock - * Returns BCME_OK on success and BCME_xxx on failure - * - * This function is not callable from non-sleepable context - */ -int dhd_bus_clk_disable(wlan_bt_handle_t handle, bus_owner_t owner) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - - int ret; - - dhd_os_sdlock(dhdp); - /* - * The second argument is TRUE, that means, we expect - * the function to "wait" until the clocks are really - * disabled - */ - ret = __dhdsdio_clk_disable(dhdp->bus, owner, TRUE); - dhd_os_sdunlock(dhdp); - - return ret; -} -EXPORT_SYMBOL(dhd_bus_clk_disable); - -/* - * Function to reset bt_use_count counter to zero. - * - * This function is not callable from non-sleepable context - */ -void dhd_bus_reset_bt_use_count(wlan_bt_handle_t handle) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - - /* take the lock and reset bt use count */ - dhd_os_sdlock(dhdp); - dhdsdio_reset_bt_use_count(dhdp->bus); - dhd_os_sdunlock(dhdp); -} -EXPORT_SYMBOL(dhd_bus_reset_bt_use_count); - -void dhd_bus_retry_hang_recovery(wlan_bt_handle_t handle) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)handle; - dhd_info_t *dhd = (dhd_info_t*)dhdp->info; - - dhdp->hang_was_sent = 0; - - dhd_os_send_hang_message(&dhd->pub); -} -EXPORT_SYMBOL(dhd_bus_retry_hang_recovery); - -#endif /* BT_OVER_SDIO */ - static int dhd_monitor_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -6698,6 +6467,230 @@ dhd_ioctl_entry_wrapper(struct net_device *net, struct ifreq *ifr, int cmd) } #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */ +#if defined(BT_OVER_SDIO) + +void +dhdsdio_bus_usr_cnt_inc(dhd_pub_t *dhdp) +{ + dhdp->info->bus_user_count++; +} + +void +dhdsdio_bus_usr_cnt_dec(dhd_pub_t *dhdp) +{ + dhdp->info->bus_user_count--; +} + +/* Return values: + * Success: Returns 0 + * Failure: Returns -1 or errono code + */ +int +dhd_bus_get(wlan_bt_handle_t handle, bus_owner_t owner) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + dhd_info_t *dhd = (dhd_info_t *)dhdp->info; + int ret = 0; + + mutex_lock(&dhd->bus_user_lock); + ++dhd->bus_user_count; + if (dhd->bus_user_count < 0) { + DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__)); + ret = -1; + goto exit; + } + + if (dhd->bus_user_count == 1) { + + dhd->pub.hang_was_sent = 0; + + /* First user, turn on WL_REG, start the bus */ + DHD_ERROR(("%s(): First user Turn On WL_REG & start the bus", __FUNCTION__)); + + if (!wifi_platform_set_power(dhd->adapter, TRUE, WIFI_TURNON_DELAY)) { + /* Enable F1 */ + ret = dhd_bus_resume(dhdp, 0); + if (ret) { + DHD_ERROR(("%s(): Failed to enable F1, err=%d\n", + __FUNCTION__, ret)); + goto exit; + } + } + + dhd_update_fw_nv_path(dhd); + /* update firmware and nvram path to sdio bus */ + dhd_bus_update_fw_nv_path(dhd->pub.bus, + dhd->fw_path, dhd->nv_path); + /* download the firmware, Enable F2 */ + /* TODO: Should be done only in case of FW switch */ + ret = dhd_bus_devreset(dhdp, FALSE); + dhd_bus_resume(dhdp, 1); + if (!ret) { + if (dhd_sync_with_dongle(&dhd->pub) < 0) { + DHD_ERROR(("%s(): Sync with dongle failed!!\n", __FUNCTION__)); + ret = -EFAULT; + } + } else { + DHD_ERROR(("%s(): Failed to download, err=%d\n", __FUNCTION__, ret)); + } + } else { + DHD_ERROR(("%s(): BUS is already acquired, just increase the count %d \r\n", + __FUNCTION__, dhd->bus_user_count)); + } +exit: + mutex_unlock(&dhd->bus_user_lock); + return ret; +} +EXPORT_SYMBOL(dhd_bus_get); + +/* Return values: + * Success: Returns 0 + * Failure: Returns -1 or errono code + */ +int +dhd_bus_put(wlan_bt_handle_t handle, bus_owner_t owner) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + dhd_info_t *dhd = (dhd_info_t *)dhdp->info; + int ret = 0; + BCM_REFERENCE(owner); + + mutex_lock(&dhd->bus_user_lock); + --dhd->bus_user_count; + if (dhd->bus_user_count < 0) { + DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__)); + dhd->bus_user_count = 0; + ret = -1; + goto exit; + } + + if (dhd->bus_user_count == 0) { + /* Last user, stop the bus and turn Off WL_REG */ + DHD_ERROR(("%s(): There are no owners left Trunf Off WL_REG & stop the bus \r\n", + __FUNCTION__)); +#ifdef PROP_TXSTATUS + if (dhd->pub.wlfc_enabled) { + dhd_wlfc_deinit(&dhd->pub); + } +#endif /* PROP_TXSTATUS */ +#ifdef PNO_SUPPORT + if (dhd->pub.pno_state) { + dhd_pno_deinit(&dhd->pub); + } +#endif /* PNO_SUPPORT */ +#ifdef RTT_SUPPORT + if (dhd->pub.rtt_state) { + dhd_rtt_deinit(&dhd->pub); + } +#endif /* RTT_SUPPORT */ + ret = dhd_bus_devreset(dhdp, TRUE); + if (!ret) { + dhd_bus_suspend(dhdp); + wifi_platform_set_power(dhd->adapter, FALSE, WIFI_TURNOFF_DELAY); + } + } else { + DHD_ERROR(("%s(): Other owners using bus, decrease the count %d \r\n", + __FUNCTION__, dhd->bus_user_count)); + } +exit: + mutex_unlock(&dhd->bus_user_lock); + return ret; +} +EXPORT_SYMBOL(dhd_bus_put); + +int +dhd_net_bus_get(struct net_device *dev) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + return dhd_bus_get(&dhd->pub, WLAN_MODULE); +} + +int +dhd_net_bus_put(struct net_device *dev) +{ + dhd_info_t *dhd = DHD_DEV_INFO(dev); + return dhd_bus_put(&dhd->pub, WLAN_MODULE); +} + +/* + * Function to enable the Bus Clock + * Returns BCME_OK on success and BCME_xxx on failure + * + * This function is not callable from non-sleepable context + */ +int dhd_bus_clk_enable(wlan_bt_handle_t handle, bus_owner_t owner) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + + int ret; + + dhd_os_sdlock(dhdp); + /* + * The second argument is TRUE, that means, we expect + * the function to "wait" until the clocks are really + * available + */ + ret = __dhdsdio_clk_enable(dhdp->bus, owner, TRUE); + dhd_os_sdunlock(dhdp); + + return ret; +} +EXPORT_SYMBOL(dhd_bus_clk_enable); + +/* + * Function to disable the Bus Clock + * Returns BCME_OK on success and BCME_xxx on failure + * + * This function is not callable from non-sleepable context + */ +int dhd_bus_clk_disable(wlan_bt_handle_t handle, bus_owner_t owner) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + + int ret; + + dhd_os_sdlock(dhdp); + /* + * The second argument is TRUE, that means, we expect + * the function to "wait" until the clocks are really + * disabled + */ + ret = __dhdsdio_clk_disable(dhdp->bus, owner, TRUE); + dhd_os_sdunlock(dhdp); + + return ret; +} +EXPORT_SYMBOL(dhd_bus_clk_disable); + +/* + * Function to reset bt_use_count counter to zero. + * + * This function is not callable from non-sleepable context + */ +void dhd_bus_reset_bt_use_count(wlan_bt_handle_t handle) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + + /* take the lock and reset bt use count */ + dhd_os_sdlock(dhdp); + dhdsdio_reset_bt_use_count(dhdp->bus); + dhd_os_sdunlock(dhdp); +} +EXPORT_SYMBOL(dhd_bus_reset_bt_use_count); + +void dhd_bus_retry_hang_recovery(wlan_bt_handle_t handle) +{ + dhd_pub_t *dhdp = (dhd_pub_t *)handle; + dhd_info_t *dhd = (dhd_info_t*)dhdp->info; + + dhdp->hang_was_sent = 0; + + dhd_os_send_hang_message(&dhd->pub); +} +EXPORT_SYMBOL(dhd_bus_retry_hang_recovery); + +#endif /* BT_OVER_SDIO */ + static int dhd_stop(struct net_device *net) { @@ -8125,34 +8118,35 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) struct file *filep = NULL; #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) struct kstat stat; - mm_segment_t fs; int error = 0; -#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) */ +#if defined(KERNEL_DS) && defined(USER_DS) + mm_segment_t fs; +#endif /* KERNEL_DS && USER_DS */ char *raw_fmts = NULL; int logstrs_size = 0; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ + filep = filp_open(logstrs_path, O_RDONLY, 0); if (IS_ERR(filep)) { 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)) - logstrs_size = i_size_read(file_inode(filep)); -#else +#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; -#endif - +#else + logstrs_size = i_size_read(file_inode(filep)); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) */ if (logstrs_size == 0) { DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__)); goto fail1; @@ -8172,9 +8166,9 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp) == BCME_OK) { filp_close(filep, NULL); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); -#endif +#endif /* KERNEL_DS && USER_DS */ return BCME_OK; } @@ -8187,9 +8181,11 @@ fail: fail1: if (!IS_ERR(filep)) filp_close(filep, NULL); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) + +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); -#endif +#endif /* KERNEL_DS && USER_DS */ + temp->fmts = NULL; return BCME_ERROR; } @@ -8199,9 +8195,10 @@ 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)) +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t fs; -#endif +#endif /* KERNEL_DS && USER_DS */ + int err = BCME_ERROR; if (fname == NULL) { @@ -8209,10 +8206,10 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start, return BCME_ERROR; } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ filep = filp_open(fname, O_RDONLY, 0); if (IS_ERR(filep)) { @@ -8228,9 +8225,9 @@ fail: if (!IS_ERR(filep)) filp_close(filep, NULL); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); -#endif +#endif /* KERNEL_DS && USER_DS */ return err; } @@ -8239,9 +8236,9 @@ static int dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file) { struct file *filep = NULL; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t fs; -#endif +#endif /* KERNEL_DS && USER_DS */ char *raw_fmts = NULL; uint32 logstrs_size = 0; int error = 0; @@ -8264,10 +8261,10 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n", ramstart, rodata_start, rodata_end)); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ filep = filp_open(str_file, O_RDONLY, 0); if (IS_ERR(filep)) { @@ -8319,9 +8316,9 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch } filp_close(filep, NULL); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); -#endif +#endif /* KERNEL_DS && USER_DS */ return BCME_OK; @@ -8335,9 +8332,9 @@ fail1: if (!IS_ERR(filep)) filp_close(filep, NULL); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); -#endif +#endif /* KERNEL_DS && USER_DS */ if (strstr(str_file, ram_file_str) != NULL) { temp->raw_sstr = NULL; @@ -8448,6 +8445,15 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) memset(dhd, 0, sizeof(dhd_info_t)); dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC; +#ifdef SHOW_LOGTRACE + /* Create ring proc entries */ + dhd_dbg_ring_proc_create(&dhd->pub); + + if (dhd_init_logtrace_process(dhd) != BCME_OK) { + goto fail; + } +#endif /* SHOW_LOGTRACE */ + dhd->unit = dhd_found + instance_base; /* do not increment dhd_found, yet */ dhd->pub.osh = osh; @@ -8616,9 +8622,11 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) goto fail; } +#ifdef DHD_MONITOR_INTERFACE dhd_monitor_init(&dhd->pub); +#endif /* DHD_MONITOR_INTERFACE */ dhd_state |= DHD_ATTACH_STATE_CFG80211; -#endif // endif +#endif /* WL_CFG80211 */ #if defined(WL_WIRELESS_EXT) /* Attach and link in the iw */ @@ -8733,9 +8741,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) #ifdef SHOW_LOGTRACE skb_queue_head_init(&dhd->evt_trace_queue); - - /* Create ring proc entries */ - dhd_dbg_ring_proc_create(&dhd->pub); #endif /* SHOW_LOGTRACE */ /* Set up the bottom half handler */ @@ -8910,12 +8915,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) #endif /* DNGL_AXI_ERROR_LOGGING */ #endif /* BCMPCIE && ETD */ -#ifdef SHOW_LOGTRACE - if (dhd_init_logtrace_process(dhd) != BCME_OK) { - goto fail; - } -#endif /* SHOW_LOGTRACE */ - DHD_SSSR_MEMPOOL_INIT(&dhd->pub); #ifdef EWP_EDL @@ -9057,7 +9056,6 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) #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 */ @@ -9067,27 +9065,23 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo) /* check if we need to initialize the path */ if (dhdinfo->fw_path[0] == '\0') { - if (adapter && adapter->fw_path && adapter->fw_path[0] != '\0') { + if (adapter && adapter->fw_path && adapter->fw_path[0] != '\0') fw = adapter->fw_path; - } } if (dhdinfo->nv_path[0] == '\0') { - if (adapter && adapter->nv_path && adapter->nv_path[0] != '\0') { + if (adapter && adapter->nv_path && adapter->nv_path[0] != '\0') nv = adapter->nv_path; - } } /* Use module parameter if it is valid, EVEN IF the path has not been initialized * * TODO: need a solution for multi-chip, can't use the same firmware for all chips */ - if (firmware_path[0] != '\0') { + if (firmware_path[0] != '\0') fw = firmware_path; - } - if (nvram_path[0] != '\0') { + if (nvram_path[0] != '\0') nv = nvram_path; - } fw = "/vendor/etc/firmware/fw_bcm88459_pcie.bin"; nv = "/vendor/etc/firmware/nvram_cyw88459.txt"; @@ -11112,6 +11106,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) setbit(eventmask_msg->mask, WLC_E_LDF_HOGGER); #endif /* ENABLE_HOGSQS */ + /* over temp event */ + setbit(eventmask_msg->mask, WLC_E_OVERTEMP); + /* Write updated Event mask */ eventmask_msg->ver = EVENTMSGS_VER; eventmask_msg->command = EVENTMSGS_SET_MASK; @@ -12247,7 +12244,7 @@ void dhd_detach(dhd_pub_t *dhdp) dhd_info_t *dhd; unsigned long flags; int timer_valid = FALSE; - struct net_device *dev; + struct net_device *dev = NULL; #ifdef WL_CFG80211 struct bcm_cfg80211 *cfg = NULL; #endif // endif @@ -12258,7 +12255,8 @@ void dhd_detach(dhd_pub_t *dhdp) if (!dhd) return; - dev = dhd->iflist[0]->net; + if (dhd->iflist[0]) + dev = dhd->iflist[0]->net; if (dev) { rtnl_lock(); @@ -12504,10 +12502,12 @@ void dhd_detach(dhd_pub_t *dhdp) ASSERT(0); } else { wl_cfg80211_detach(cfg); +#ifdef DHD_MONITOR_INTERFACE dhd_monitor_uninit(); +#endif /* DHD_MONITOR_INTERFACE */ } } -#endif // endif +#endif /* WL_CFG80211 */ #ifdef DHD_PCIE_NATIVE_RUNTIMEPM destroy_workqueue(dhd->tx_wq); @@ -15824,16 +15824,13 @@ int write_file(const char * file_name, uint32 flags, uint8 *buf, int size) { int ret = 0; struct file *fp = NULL; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) - mm_segment_t old_fs; -#endif loff_t pos = 0; /* change to KERNEL_DS address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) + mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); -#endif - +#endif /* KERNEL_DS && USER_DS */ /* open file to write */ fp = filp_open(file_name, flags, 0664); if (IS_ERR(fp)) { @@ -15862,10 +15859,9 @@ exit: filp_close(fp, current->files); /* restore previous address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif - +#endif /* KERNEL_DS && USER_DS */ return ret; } #endif // endif @@ -17301,9 +17297,9 @@ dhd_get_rnd_info(dhd_pub_t *dhd) int ret = BCME_ERROR; char *filepath = RND_IN; uint32 file_mode = O_RDONLY; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t old_fs; -#endif +#endif /* KERNEL_DS && USER_DS */ loff_t pos = 0; /* Read memdump info from the file */ @@ -17328,10 +17324,10 @@ dhd_get_rnd_info(dhd_pub_t *dhd) #endif /* CONFIG_X86 && OEM_ANDROID */ } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) old_fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ /* Handle success case */ ret = vfs_read(fp, (char *)&dhd->rnd_len, sizeof(dhd->rnd_len), &pos); @@ -17352,9 +17348,9 @@ dhd_get_rnd_info(dhd_pub_t *dhd) goto err3; } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ filp_close(fp, NULL); DHD_ERROR(("%s: RND read from %s\n", __FUNCTION__, filepath)); @@ -17364,9 +17360,9 @@ err3: MFREE(dhd->osh, dhd->rnd_buf, dhd->rnd_len); dhd->rnd_buf = NULL; err2: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ filp_close(fp, NULL); err1: return BCME_ERROR; @@ -17379,9 +17375,9 @@ dhd_dump_rnd_info(dhd_pub_t *dhd, uint8 *rnd_buf, uint32 rnd_len) int ret = BCME_OK; char *filepath = RND_OUT; uint32 file_mode = O_CREAT | O_WRONLY | O_SYNC; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t old_fs; -#endif +#endif /* KERNEL_DS && USER_DS */ loff_t pos = 0; /* Read memdump info from the file */ @@ -17406,10 +17402,11 @@ dhd_dump_rnd_info(dhd_pub_t *dhd, uint8 *rnd_buf, uint32 rnd_len) #endif /* CONFIG_X86 && OEM_ANDROID */ } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) old_fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ + /* Handle success case */ ret = vfs_write(fp, (char *)&rnd_len, sizeof(rnd_len), &pos); if (ret < 0) { @@ -17423,17 +17420,17 @@ dhd_dump_rnd_info(dhd_pub_t *dhd, uint8 *rnd_buf, uint32 rnd_len) goto err2; } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ filp_close(fp, NULL); DHD_ERROR(("%s: RND written to %s\n", __FUNCTION__, filepath)); return BCME_OK; err2: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ filp_close(fp, NULL); err1: return BCME_ERROR; @@ -18936,18 +18933,20 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) { int ret = 0, i = 0; struct file *fp = NULL; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) - struct kstat stat; +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t old_fs; -#else - int isize = 0; -#endif +#endif /* KERNEL_DS && USER_DS */ loff_t pos = 0; char dump_path[128]; uint32 file_mode; unsigned long flags = 0; size_t log_size = 0; size_t fspace_remain = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) + int isize = 0; +#else + struct kstat stat; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) */ char time_str[128]; unsigned int len = 0; log_dump_section_hdr_t sec_hdr; @@ -18967,11 +18966,10 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) goto exit1; } /* change to KERNEL_DS address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) old_fs = get_fs(); set_fs(KERNEL_DS); -#endif - +#endif /* KERNEL_DS && USER_DS */ dhd_get_debug_dump_file_name(NULL, dhdp, dump_path, sizeof(dump_path)); DHD_ERROR(("debug_dump_path = %s\n", dump_path)); @@ -19036,8 +19034,7 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) stat.size < dhdp->last_file_posn) { dhdp->last_file_posn = 0; } -#endif - +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) */ if (dhdp->logdump_periodic_flush) { log_size = strlen(time_str) + strlen(DHD_DUMP_LOG_HDR) + sizeof(sec_hdr); /* calculate the amount of space required to dump all logs */ @@ -19172,9 +19169,9 @@ exit2: DHD_ERROR(("%s: Finished writing log dump to file - '%s' \n", __FUNCTION__, dump_path)); } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ exit1: if (type) { MFREE(dhdp->osh, type, sizeof(*type)); @@ -20554,7 +20551,7 @@ void dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path) { struct file *fp; - char *filepath = "/vendor/etc/firmware/4359_cypress_auto.clm_blob";//VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; + char *filepath = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; fp = filp_open(filepath, O_RDONLY, 0); if (IS_ERR(fp)) { DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__, @@ -20664,16 +20661,14 @@ int dhd_write_file(const char *filepath, char *buf, int buf_len) { struct file *fp = NULL; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) - mm_segment_t old_fs; -#endif int ret = 0; - /* change to KERNEL_DS address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) + mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ + /* File is always created. */ fp = filp_open(filepath, O_RDWR | O_CREAT, 0664); if (IS_ERR(fp)) { @@ -20695,9 +20690,9 @@ dhd_write_file(const char *filepath, char *buf, int buf_len) } /* restore previous address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ return ret; } @@ -20706,21 +20701,18 @@ int dhd_read_file(const char *filepath, char *buf, int buf_len) { struct file *fp = NULL; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) - mm_segment_t old_fs; -#endif int ret; - /* change to KERNEL_DS address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) + mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); -#endif +#endif /* KERNEL_DS && USER_DS */ fp = filp_open(filepath, O_RDONLY, 0); if (IS_ERR(fp)) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ DHD_ERROR(("%s: File %s doesn't exist\n", __FUNCTION__, filepath)); return BCME_ERROR; } @@ -20729,9 +20721,9 @@ dhd_read_file(const char *filepath, char *buf, int buf_len) filp_close(fp, NULL); /* restore previous address limit */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(old_fs); -#endif +#endif /* KERNEL_DS && USER_DS */ /* Return the number of bytes read */ if (ret > 0) { @@ -21303,31 +21295,20 @@ void dhd_schedule_gather_ap_stadata(void *bcm_cfg, void *ndev, const wl_event_ms void get_debug_dump_time(char *str) { - struct timeval curtime; - unsigned long local_time; + struct timespec64 curtime; + unsigned long long local_time; + struct rtc_time tm; if (!strlen(str)) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - do_gettimeofday(&curtime); -#else - curtime = do_gettimeofday(); -#endif - local_time = (u32)(curtime.tv_sec - + ktime_get_real_ts64(&curtime); + local_time = (u64)(curtime.tv_sec - (sys_tz.tz_minuteswest * DHD_LOG_DUMP_TS_MULTIPLIER_VALUE)); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) rtc_time_to_tm(local_time, &tm); snprintf(str, DEBUG_DUMP_TIME_BUF_LEN, DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSSMSMS, tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, - tm.tm_sec, (int)(curtime.tv_usec/NSEC_PER_USEC)); -#else - tm = rtc_ktime_to_tm(local_time); - - snprintf(str, DEBUG_DUMP_TIME_BUF_LEN, DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSSMSMS, - tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, - tm.tm_sec, (int)(curtime.tv_usec)); -#endif + tm.tm_sec, (int)(curtime.tv_nsec/NSEC_PER_MSEC)); } } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.h index ae9295b575bd..53a727af2672 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux.h @@ -41,10 +41,6 @@ #include #include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1)) -#include -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1)) */ - #include #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1)) diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_exportfs.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_exportfs.c index dc361e670130..9e96728b74b2 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_exportfs.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_exportfs.c @@ -70,7 +70,8 @@ static const struct file_operations dhd_ring_proc_fops = { .read = dhd_ring_proc_read, .release = single_release, }; -#endif +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) */ + static int dhd_ring_proc_open(struct inode *inode, struct file *file) { @@ -756,11 +757,6 @@ get_assert_val_from_file(void) filp_close(fp, NULL); } -#ifdef CUSTOMER_HW4_DEBUG - mem_val = (mem_val >= 0) ? mem_val : 1; -#else - mem_val = (mem_val >= 0) ? mem_val : 0; -#endif /* CUSTOMER_HW4_DEBUG */ return mem_val; } @@ -770,8 +766,8 @@ void dhd_get_assert_info(dhd_pub_t *dhd) int mem_val = -1; mem_val = get_assert_val_from_file(); - - g_assert_type = mem_val; + if (mem_val != -1) + g_assert_type = mem_val; #endif /* !DHD_EXPORT_CNTL_FILE */ } @@ -1517,6 +1513,8 @@ void dhd_sysfs_exit(dhd_info_t *dhd) } /* Releae the kobject */ - kobject_put(&dhd->dhd_kobj); - kobject_put(&dhd->dhd_conf_file_kobj); + if (dhd->dhd_kobj.state_initialized) + kobject_put(&dhd->dhd_kobj); + if (dhd->dhd_conf_file_kobj.state_initialized) + kobject_put(&dhd->dhd_conf_file_kobj); } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_lb.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_lb.c index 4358d0ad9c79..f3ff91dbf696 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_lb.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_lb.c @@ -300,14 +300,17 @@ dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) int dhd_register_cpuhp_callback(dhd_info_t *dhd) { - int cpuhp_ret = 0; + dhd->cpuhp_setup_state = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - cpuhp_ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dhd", + dhd->cpuhp_setup_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dhd", dhd_cpu_startup_callback, dhd_cpu_teardown_callback); - if (cpuhp_ret < 0) { + if (dhd->cpuhp_setup_state < 0) { DHD_ERROR(("%s(): cpuhp_setup_state failed %d RX LB won't happen \r\n", - __FUNCTION__, cpuhp_ret)); + __FUNCTION__, dhd->cpuhp_setup_state)); + } else { + DHD_INFO(("%s(): cpuhp_setup_state returned %d\n", + __FUNCTION__, dhd->cpuhp_setup_state)); } #else /* @@ -318,15 +321,20 @@ int dhd_register_cpuhp_callback(dhd_info_t *dhd) dhd->cpu_notifier.notifier_call = dhd_cpu_callback; register_hotcpu_notifier(&dhd->cpu_notifier); /* Register a callback */ #endif /* LINUX_VERSION_CODE < 4.10.0 */ - return cpuhp_ret; + return dhd->cpuhp_setup_state; } int dhd_unregister_cpuhp_callback(dhd_info_t *dhd) { int ret = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - /* Don't want to call tear down while unregistering */ - cpuhp_remove_state_nocalls(CPUHP_AP_ONLINE_DYN); + DHD_INFO(("%s(): cpuhp_setup_state %d\n", + __FUNCTION__, dhd->cpuhp_setup_state)); + + if (dhd->cpuhp_setup_state >= 0) { + /* Don't want to call tear down while unregistering */ + cpuhp_remove_state_nocalls(dhd->cpuhp_setup_state); + } #else if (dhd->cpu_notifier.notifier_call != NULL) { unregister_cpu_notifier(&dhd->cpu_notifier); diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_priv.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_priv.h index 2e2a4526e93a..7c0e53e806aa 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_priv.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_priv.h @@ -321,6 +321,9 @@ typedef struct dhd_info { uint32 *napi_rx_hist[HIST_BIN_SIZE]; uint32 *txc_hist[HIST_BIN_SIZE]; uint32 *rxc_hist[HIST_BIN_SIZE]; + + /* State returned by kernel function cpuhp_setup_state(). */ + int cpuhp_setup_state; #endif /* DHD_LB */ #if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR) struct work_struct axi_error_dispatcher_work; diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_sched.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_sched.c index 7c74e97a91f2..6cc377d94323 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_sched.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_linux_sched.c @@ -31,34 +31,40 @@ #include #include #include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) #include -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ +#else +#include +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */ #include #include int setScheduler(struct task_struct *p, int policy, struct sched_param *param) { int rc = 0; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) - rc = sched_setscheduler(p, policy, param); -#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) switch (policy) { case SCHED_FIFO: - if (param->sched_priority > 1) - /* If the priority is 2 or higher, it is considered - * as high priority. priority is set basically MAX_RT_PRIO/2 + if (param->sched_priority >= MAX_RT_PRIO/2) + /* If the priority is MAX_RT_PRIO/2 or higher, + * it is considered as high priority. + * sched_priority of FIFO task dosen't + * exceed MAX_RT_PRIO/2. */ sched_set_fifo(p); else + /* For when you don't much care about FIFO, + * but want to be above SCHED_NORMAL. + */ sched_set_fifo_low(p); break; case SCHED_NORMAL: sched_set_normal(p, PRIO_TO_NICE(p->static_prio)); break; } -#endif +#else + rc = sched_setscheduler(p, policy, param); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) */ return rc; } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_msgbuf.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_msgbuf.c index 0e573c8f73f6..26638d450e1f 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_msgbuf.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_msgbuf.c @@ -7696,7 +7696,6 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf) timeleft = dhd_os_ioctl_resp_wait(dhd, (uint *)&prot->ioctl_received); -#ifdef DHD_RECOVER_TIMEOUT if (prot->ioctl_received == 0) { uint32 intstatus = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, dhd->bus->pcie_mailbox_int, 0, 0); @@ -7714,7 +7713,6 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf) dhdpcie_bus_clear_intstatus(dhd->bus); } } -#endif /* DHD_RECOVER_TIMEOUT */ if (timeleft == 0 && (!dhd_query_bus_erros(dhd))) { /* check if resumed on time out related to scheduling issue */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie.c index 06c132ae4f95..ee87d2d5edf7 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie.c @@ -783,6 +783,7 @@ enumerate_module: /* software resources */ if (!(bus->dhd = dhd_attach(osh, bus, PCMSGBUF_HDRLEN))) { DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__)); + ret = BCME_ERROR; break; } @@ -10286,7 +10287,7 @@ dhdpcie_chipmatch(uint16 vendor, uint16 device) #endif /* CHIPS_CUSTOMER_HW6 */ /* CYW55560 */ - if (device == CYW55560_WLAN_ID) { + if ((device == CYW55560_WLAN_ID) || (device == CYW89570_WLAN_ID)) { return 0; } DHD_ERROR(("%s: Unsupported vendor %x device %x\n", __FUNCTION__, vendor, device)); diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie_linux.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie_linux.c index 1d633d35305a..426afe78c78b 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie_linux.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pcie_linux.c @@ -87,6 +87,15 @@ #ifdef FORCE_TPOWERON extern uint32 tpoweron_scale; #endif /* FORCE_TPOWERON */ + +#if defined(CONFIG_ARCH_MSM) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#ifndef MSM_PCIE_CONFIG_NO_CFG_RESTORE +#define MSM_PCIE_CONFIG_NO_CFG_RESTORE 0 +#endif /* MSM_PCIE_CONFIG_NO_CFG_RESTORE */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) */ +#endif /* CONFIG_ARCH_MSM */ + /* user defined data structures */ typedef bool (*dhdpcie_cb_fn_t)(void *); @@ -1756,8 +1765,10 @@ int dhdpcie_get_resource(dhdpcie_info_t *dhdpcie_info) goto err; } DHD_ERROR(("PCIe:%s:enabled link\n", __FUNCTION__)); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) /* recover the config space of both RC and Endpoint */ msm_pcie_recover_config(pdev); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) */ #endif /* CONFIG_ARCH_MSM && !ENABLE_INSMOD_NO_FW_LOAD */ #ifdef EXYNOS_PCIE_MODULE_PATCH #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -2329,7 +2340,9 @@ dhdpcie_start_host_pcieclock(dhd_bus_t *bus) ret = msm_pcie_pm_control(MSM_PCIE_RESUME, bus->dev->bus->number, bus->dev, NULL, options); if (bus->no_cfg_restore && !ret) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) msm_pcie_recover_config(bus->dev); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) */ bus->no_cfg_restore = 0; } #else diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pno.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pno.c index a3cab80a07a3..e01c7ff9f9e1 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pno.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_pno.c @@ -2610,11 +2610,7 @@ _dhd_pno_get_gscan_batch_from_fw(dhd_pub_t *dhd) goto exit_mutex_unlock; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&tm_spec); -#else get_monotonic_boottime(&tm_spec); -#endif if (plbestnet_v1->version == PFN_LBEST_SCAN_RESULT_VERSION_V1) { fwstatus = plbestnet_v1->status; fwcount = plbestnet_v1->count; @@ -3452,11 +3448,11 @@ exit: } mutex_unlock(&_pno_state->pno_mutex); exit_no_unlock: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - if (waitqueue_active(&_pno_state->get_batch_done.wait)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) + if (swait_active(&_pno_state->get_batch_done.wait)) #else - if (!try_wait_for_completion(&_pno_state->get_batch_done)) -#endif + if (waitqueue_active(&_pno_state->get_batch_done.wait)) +#endif/* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ complete(&_pno_state->get_batch_done); return err; } @@ -4015,11 +4011,7 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, uint32 len, int result->fixed.rssi = (int32) bi->RSSI; result->fixed.rtt = 0; result->fixed.rtt_sd = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&ts); -#else get_monotonic_boottime(&ts); -#endif result->fixed.ts = (uint64) TIMESPEC_TO_US(ts); result->fixed.beacon_period = dtoh16(bi->beacon_period); result->fixed.capability = dtoh16(bi->capability); @@ -4157,9 +4149,9 @@ dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, gscan_results_cache_t *gscan_hotlist_cache; u32 malloc_size = 0, i, total = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - struct timespec64 tm_spec; + struct timespec64 tm_spec; #else - struct timespec tm_spec; + struct timespec tm_spec; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) */ uint16 fwstatus; uint16 fwcount; @@ -4183,11 +4175,8 @@ dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, *send_evt_bytes = 0; return ptr; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&tm_spec); -#else + get_monotonic_boottime(&tm_spec); -#endif malloc_size = sizeof(gscan_results_cache_t) + ((fwcount - 1) * sizeof(wifi_gscan_result_t)); gscan_hotlist_cache = (gscan_results_cache_t *)MALLOC(dhd->osh, malloc_size); @@ -4250,11 +4239,8 @@ dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, *send_evt_bytes = 0; return ptr; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&tm_spec); -#else + get_monotonic_boottime(&tm_spec); -#endif malloc_size = sizeof(gscan_results_cache_t) + ((fwcount - 1) * sizeof(wifi_gscan_result_t)); gscan_hotlist_cache = @@ -4352,11 +4338,11 @@ dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) { struct dhd_pno_batch_params *params_batch; params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - if (!waitqueue_active(&_pno_state->get_batch_done.wait)) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) + if (!swait_active(&_pno_state->get_batch_done.wait)) #else - if (!try_wait_for_completion(&_pno_state->get_batch_done)) { -#endif + if (!waitqueue_active(&_pno_state->get_batch_done.wait)) { +#endif/* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__)); params_batch->get_batch.buf = NULL; params_batch->get_batch.bufsize = 0; diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_rtt.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_rtt.c index 26f10f371b27..ccb53b35bd42 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_rtt.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_rtt.c @@ -2712,11 +2712,7 @@ dhd_rtt_convert_results_to_host_v1(rtt_result_t *rtt_result, const uint8 *p_data /* time stamp */ /* get the time elapsed from boot time */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&ts); -#else get_monotonic_boottime(&ts); -#endif rtt_report->ts = (uint64)TIMESPEC_TO_US(ts); #endif /* LINUX_VER >= 2.6.39 */ @@ -2972,11 +2968,7 @@ dhd_rtt_convert_results_to_host_v2(rtt_result_t *rtt_result, const uint8 *p_data /* time stamp */ /* get the time elapsed from boot time */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&ts); -#else get_monotonic_boottime(&ts); -#endif rtt_report->ts = (uint64)TIMESPEC_TO_US(ts); #endif /* LINUX_VER >= 2.6.39 */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_sdio.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_sdio.c index 320b404c17f1..53c1bd4b6f71 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/dhd_sdio.c @@ -243,6 +243,7 @@ typedef struct dhd_console { #endif /* DHD_UCODE_DOWNLOAD */ #if defined(BT_OVER_SDIO) +#define BTMEM_OFFSET_MASK 0xFF000000 #define BTMEM_OFFSET 0x19000000 /* BIT0 => WLAN Power UP and BIT1=> WLAN Wake */ #define BT2WLAN_PWRUP_WAKE 0x03 @@ -589,7 +590,11 @@ static const uint max_roundup = 512; /* Try doing readahead */ static bool dhd_readahead; -#define TXCTL_CREDITS 2 +#ifdef AUTOMOTIVE_FEATURE +#define TXCTL_CREDITS 1 +#else +#define TXCTL_CREDITS 2 +#endif /* AUTOMOTIVE_FEATURE */ /* To check if there's window offered */ #define DATAOK(bus) \ @@ -3054,6 +3059,9 @@ enum { IOV_WATERMARK, IOV_MESBUSYCTRL, #endif /* USE_SDIOFIFO_IOVAR */ +#if defined(BT_OVER_SDIO) + IOV_SDF3, +#endif /* defined (BT_OVER_SDIO) */ #ifdef SDTEST IOV_PKTGEN, IOV_EXTLOOP, @@ -3127,6 +3135,9 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"watermark", IOV_WATERMARK, 0, 0, IOVT_UINT32, 0 }, {"mesbusyctrl", IOV_MESBUSYCTRL, 0, 0, IOVT_UINT32, 0 }, #endif /* USE_SDIOFIFO_IOVAR */ +#if defined(BT_OVER_SDIO) + {"sdf3", IOV_SDF3, 0, 0, IOVT_UINT32, 0 }, +#endif /* defined (BT_OVER_SDIO) */ {"devcap", IOV_DEVCAP, 0, 0, IOVT_UINT32, 0 }, {"dngl_isolation", IOV_DONGLEISOLATION, 0, 0, IOVT_UINT32, 0 }, {"kso", IOV_KSO, 0, 0, IOVT_UINT32, 0 }, @@ -4185,7 +4196,13 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, (set ? "write" : "read"), size, address)); - +#if defined(BT_OVER_SDIO) + /* Check if address is within BT range */ + if ((address & BTMEM_OFFSET_MASK) == BTMEM_OFFSET) { + DHD_INFO(("%s: Access BTMEM, bypass check\n", __FUNCTION__)); + } + else +#endif // endif /* check if CR4 */ if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { /* @@ -4506,6 +4523,33 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch break; #endif // endif +#if defined(BT_OVER_SDIO) + case IOV_GVAL(IOV_SDF3): + case IOV_SVAL(IOV_SDF3): + { + uint8 *buf; + int ret = BCME_OK; + uint size; + bool set = (actionid == IOV_SVAL(IOV_SDF3)); + ASSERT(plen >= sizeof(int)); + + size = (uint)int_val; + /* Generate the actual data pointer */ + buf = set ? (uint8*)params + sizeof(int): (uint8*)arg; + + if (actionid == IOV_SVAL(IOV_SDF3)) { + ret = dhd_bcmsdh_send_buf(bus, 0, SDIO_FUNC_3, + F2SYNC, buf, size, NULL, NULL, NULL, 1); + } else { + ret = dhd_bcmsdh_recv_buf(bus, 0, SDIO_FUNC_3, + F2SYNC, buf, size, NULL, NULL, NULL); + } + if (ret != BCME_OK) { + bcmerror = BCME_SDIO_ERROR; + } + break; + } +#endif /* defined (BT_OVER_SDIO) */ case IOV_GVAL(IOV_DONGLEISOLATION): int_val = bus->dhd->dongle_isolation; bcopy(&int_val, arg, val_size); @@ -10431,6 +10475,60 @@ void dhd_bus_cfg_write(void *h, uint fun_num, uint32 addr, uint8 val, int *err) } EXPORT_SYMBOL(dhd_bus_cfg_write); +int dhd_bus_recv_buf(void *h, uint32 addr, uint fn, uint8 *buf, uint nbytes) +{ + int ret; + dhd_pub_t *dhdp = (dhd_pub_t *)h; + dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; + dhd_os_sdlock(bus->dhd); + + ret = dhd_bcmsdh_recv_buf(bus, 0, fn, + F2SYNC, buf, nbytes, NULL, NULL, NULL); + + dhd_os_sdunlock(bus->dhd); + DHD_ERROR(("\nEntering %s function is %d and no of bytes received %d\n", + __func__, fn, nbytes)); + + return ret; +} EXPORT_SYMBOL(dhd_bus_recv_buf); + +int dhd_bus_send_buf(void *h, uint32 addr, uint fn, uint8 *buf, uint nbytes) +{ + int ret; + dhd_pub_t *dhdp = (dhd_pub_t *)h; + dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; + DHD_ERROR(("\nEntering %s function is %d and no of bytes sent is %d\n", + __func__, fn, nbytes)); + + dhd_os_sdlock(bus->dhd); + + ret = dhd_bcmsdh_send_buf(bus, 0, fn, + F2SYNC, buf, nbytes, NULL, NULL, NULL, 1); + + dhd_os_sdunlock(bus->dhd); + + return ret; +} EXPORT_SYMBOL(dhd_bus_send_buf); + +int dhd_bus_set_blocksize(void *h, unsigned int fun_num, unsigned int block_size) +{ + int bcmerr; + int func_blk_size = fun_num; + dhd_pub_t *dhd = (dhd_pub_t *)h; + dhd_bus_t *bus = (dhd_bus_t *)dhd->bus; + +#ifdef USE_DYNAMIC_F2_BLKSIZE + func_blk_size = fun_num << 16 | block_size; + bcmerr = bcmsdh_iovar_op(bus->sdh, "sd_blocksize", NULL, 0, &func_blk_size, + sizeof(func_blk_size), TRUE); + if (bcmerr != BCME_OK) { + DHD_ERROR(("%s: Set F%d Block size error\n", __FUNCTION__, fun_num)); + return BCME_ERROR; + } +#endif // endif + return bcmerr; +} EXPORT_SYMBOL(dhd_bus_set_blocksize); + static int extract_hex_field(char * line, uint16 start_pos, uint16 num_chars, uint16 * value) { diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11.h index 62861395acec..6cbdb454c936 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11.h @@ -509,17 +509,23 @@ typedef struct dot11_wide_bw_channel dot11_wide_bw_chan_ie_t; #define DOT11_WIDE_BW_IE_LEN 3 /* length of IE data, not including 2 byte header */ /** VHT Transmit Power Envelope IE data structure */ BWL_PRE_PACKED_STRUCT struct dot11_vht_transmit_power_envelope { - uint8 id; /* id DOT11_MNG_WIDE_BW_CHANNEL_SWITCH_ID */ + uint8 id; /* id DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID */ uint8 len; /* length of IE */ uint8 transmit_power_info; uint8 local_max_transmit_power_20; } BWL_POST_PACKED_STRUCT; typedef struct dot11_vht_transmit_power_envelope dot11_vht_transmit_power_envelope_ie_t; -/* vht transmit power envelope IE length depends on channel width */ -#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ 1 -#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ 2 -#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ 3 +/* Transmit power envelope IE length depends on channel width */ +#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_20MHZ 0 +#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ 1 +#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ 2 +#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ 3 + +/* vht transmit power envelope IE length. (Keeping these for backward compatibility) */ +#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ +#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ +#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { uint8 id; @@ -1366,9 +1372,11 @@ typedef struct ccx_qfl_ie ccx_qfl_ie_t; #define DOT11_SC_DECLINED 37 /* request declined */ #define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */ +#define DOT11_SC_INVALID_GROUP_CIPHER 41 /* invalid group cipher */ #define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */ #define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */ #define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */ +#define DOT11_SC_CIPHER_OUT_OF_POLICY 46 /* Association denied due to cipher out of policy */ #define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */ #define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */ #define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */ @@ -1513,7 +1521,8 @@ typedef struct ccx_qfl_ie ccx_qfl_ie_t; #define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */ #define DOT11_MNG_EXT_BSSLOAD_ID 193 /* d11 mgmt VHT extended bss load id */ #define DOT11_MNG_WIDE_BW_CHANNEL_SWITCH_ID 194 /* Wide BW Channel Switch IE */ -#define DOT11_MNG_VHT_TRANSMIT_POWER_ENVELOPE_ID 195 /* VHT transmit Power Envelope IE */ +#define DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID 195 /* VHT transmit Power Envelope IE */ +#define DOT11_MNG_VHT_TRANSMIT_POWER_ENVELOPE_ID (DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID) #define DOT11_MNG_CHANNEL_SWITCH_WRAPPER_ID 196 /* Channel Switch Wrapper IE */ #define DOT11_MNG_AID_ID 197 /* Association ID IE */ #define DOT11_MNG_OPER_MODE_NOTIF_ID 199 /* d11 mgmt VHT oper mode notif */ @@ -1936,7 +1945,35 @@ typedef struct dot11_oper_mode_notif_ie dot11_oper_mode_notif_ie_t; #define DOT11_UWNM_ACTION_TIM 0 #define DOT11_UWNM_ACTION_TIMING_MEASUREMENT 1 -#define DOT11_MNG_COUNTRY_ID_LEN 3 +/* + * Fixed length of country information element + * + * 1Byte: Tag + * 1Byte: Length + * 2Byte: Country string as per ISO 3166-1 + * 1Byte: Environment regulation feild + */ +#define DOT11_MNG_COUNTRY_ID_LEN 3 +#define DOT11_MNG_COUNTRY_IE_FIXED_LEN (TLV_HDR_LEN + DOT11_MNG_COUNTRY_ID_LEN) + +/* + * Length of one operating triplet field in country IE + * + * 1Byte: Operating Extension Identifier + * 1Byte: Operating class + * 1Byte: Coverage class + */ +#define DOT11_MNG_COUNTRY_IE_OPER_TRIP_LEN 3 +#define DOT11_MNG_COUNTRY_OPER_EXT_ID 255 +#define DOT11_MNG_COUNTRY_COVERAGE_CLASS 0 +/* + * Length of one subband triplet field in country IE + * + * 1Byte: First channel number + * 1Byte: Number of channels + * 1Byte: Maximum transmit power for this group of channels + */ +#define DOT11_MNG_COUNTRY_IE_SUBBAND_TRIP_LEN 3 /* VHT category action types - 802.11ac D3.0 - 8.5.23.1 */ #define DOT11_VHT_ACTION_CBF 0 /* Compressed Beamforming */ @@ -4436,6 +4473,9 @@ typedef struct vht_features_ie_hdr vht_features_ie_hdr_t; #define WFA_OUI_TYPE_MBO 0x16 #define WFA_OUI_TYPE_MBO_OCE 0x16 +/* DPP authenticated key managment suite */ +#define WFA_AKM_DPP 2 + /* RSN authenticated key managment suite */ #define RSN_AKM_NONE 0 /* None (IBSS) */ #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11ax.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11ax.h index 34dca6eae286..24fe183869d6 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11ax.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/802.11ax.h @@ -355,6 +355,7 @@ typedef uint8 he_phy_cap_t[HE_PHY_CAP_INFO_SIZE]; /* b1-b7: Channel Width Support field */ #define HE_PHY_CH_WIDTH_2G_40 0x01 #define HE_PHY_CH_WIDTH_5G_80 0x02 +#define HE_PHY_CH_WIDTH_6G_40_80 HE_PHY_CH_WIDTH_5G_80 #define HE_PHY_CH_WIDTH_5G_160 0x04 #define HE_PHY_CH_WIDTH_5G_80P80 0x08 #define HE_PHY_CH_WIDTH_2G_40_RU 0x10 @@ -847,9 +848,6 @@ BWL_PRE_PACKED_STRUCT struct he_6gband_cap_ie { typedef struct he_6gband_cap_ie he_6gband_cap_ie_t; -/* This marks the end of a packed structure section. */ -#include - /* HE Action Frame */ #define HE_AF_CAT_OFF 0 #define HE_AF_ACT_OFF 1 @@ -1012,4 +1010,54 @@ typedef uint8 he_cba_bar_info_set_t[HE_BAR_INFO_SZ]; #define HE_N_TAIL 6 /* tail field bits for BCC */ #define HE_N_SERVICE 16 /* bits in service field */ #define HE_T_MAX_PE 16 /* max Packet extension duration */ + +/* HE Transmit Power Envelope(TPE) IE related */ + +/** + * ref: (802.11ax D8.0 Figure 9-617 Page 176) + * + * Transmit Power Information field format + */ +#define HE_TPE_TX_PWR_INFO_COUNT_MASK 0x7 +#define HE_TPE_TX_PWR_INFO_COUNT_SHIFT 0 +#define HE_TPE_TX_PWR_INFO_INTERPRET_MASK 0x38 +#define HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT 3 +#define HE_TPE_TX_PWR_INFO_CATEGORY_MASK 0xC0 +#define HE_TPE_TX_PWR_INFO_CATEGORY_SHIFT 6 + +/** + * ref: (802.11ax D8.0 Table 9-275a Page 177) + * + * Maximum Transmit Power Interpretation subfield encoding + */ +#define HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP 0 +#define HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP_PSD 1 +#define HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP 2 +#define HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP_PSD 3 + +/** Set Maximum Transmit Power Interpretation on TX PWR INFO field */ +#define HE_TX_PWR_INFO_LOC_EIRP ((HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP << \ + HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK) +#define HE_TX_PWR_INFO_LOC_EIRP_PSD ((HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP_PSD << \ + HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK) +#define HE_TX_PWR_INFO_REG_EIRP ((HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP << \ + HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK) +#define HE_TX_PWR_INFO_REG_EIRP_PSD ((HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP_PSD << \ + HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK) + +/** HE Transmit Power Envelope IE data structure */ +BWL_PRE_PACKED_STRUCT struct he_transmit_power_envelope { + uint8 id; /* id DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID */ + uint8 len; /* length of IE */ + uint8 transmit_power_info; + union { + uint8 max_transmit_power_20; + uint8 max_transmit_psd_1; + }; +} BWL_POST_PACKED_STRUCT; +typedef struct he_transmit_power_envelope he_transmit_power_envelope_ie_t; + +/* This marks the end of a packed structure section. */ +#include + #endif /* _802_11ax_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmdevs.h index 0d8421d79dec..b7acf2b1456c 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmdevs.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmdevs.h @@ -358,6 +358,7 @@ #define BCM4373_D11AC5G_ID 0x441a /* 4373 802.11ac 5G device */ #define CYW55560_WLAN_ID 0xBD31 /* CYW55560 802.11ax WLAN device ID */ +#define CYW89570_WLAN_ID 0xBD3f /* CYW89570 802.11ax WLAN device ID */ #define CYW55560_BT_ID 0xBD37 /* CYW55560 802.11ax BT device ID */ #define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmevent.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmevent.h index e84f9e3900a2..c40af1da9eeb 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmevent.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmevent.h @@ -311,9 +311,10 @@ typedef union bcm_event_msg_u { #define WLC_E_IND_DOS_STATUS 191 #define WLC_E_LDF_HOGGER 192 /* Detection Hogger Squasher -Cambium */ #define WLC_E_DLTRO 193 /* DHCP lease time renew offload */ -#define WLC_E_LAST 194 /* highest val + 1 for range checking */ -#if (WLC_E_LAST > 194) -#error "WLC_E_LAST: Invalid value for last event; must be <= 193." +#define WLC_E_OVERTEMP 194 /* Overtemp notification */ +#define WLC_E_LAST 195 /* highest val + 1 for range checking */ +#if (WLC_E_LAST > 195) +#error "WLC_E_LAST: Invalid value for last event; must be <= 195." #endif /* WLC_E_LAST */ /* define an API for getting the string name of an event */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmsdbus.h index 0e42ccd762c8..bded9f7b4de5 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmsdbus.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/bcmsdbus.h @@ -83,7 +83,7 @@ typedef struct sdioh_info sdioh_info_t; /* callback function, taking one arg */ typedef void (*sdioh_cb_fn_t)(void *); -#if defined(BT_OVER_SDIO) +#if defined(BT_OVER_SDIO) && defined(BCMLXSDMMC) extern void sdioh_sdmmc_card_enable_func_f3(sdioh_info_t *sd, struct sdio_func *func); #endif /* defined (BT_OVER_SDIO) */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/epivers.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/epivers.h index 7455f17d5bda..46c98b94c3d9 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/epivers.h @@ -15,26 +15,26 @@ #define EPI_MINOR_VERSION 10 -#define EPI_RC_NUMBER 66 +#define EPI_RC_NUMBER 80 #define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 100, 10, 66, 0 +#define EPI_VERSION 100, 10, 80, 0 -#define EPI_VERSION_NUM 0x640a4200 +#define EPI_VERSION_NUM 0x640a5000 -#define EPI_VERSION_DEV 100.10.66 +#define EPI_VERSION_DEV 100.10.80 /* Driver Version String, ASCII, 32 chars max */ #ifdef BCMINTERNAL -#define EPI_VERSION_STR "100.10.66 (ccc742e BCMINT)" +#define EPI_VERSION_STR "100.10.80 (b285849 BCMINT)" #else #ifdef WLTEST -#define EPI_VERSION_STR "100.10.66 (ccc742e WLTEST)" +#define EPI_VERSION_STR "100.10.80 (b285849 WLTEST)" #else -#define EPI_VERSION_STR "100.10.66 (ccc742e)" +#define EPI_VERSION_STR "100.10.80 (b285849)" #endif #endif /* BCMINTERNAL */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linux_osl.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linux_osl.h index b62986bd7094..6c87ae5a40a8 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linux_osl.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linux_osl.h @@ -34,18 +34,6 @@ #include #define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x))) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1)) -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) -void do_gettimeofday(struct timeval *tv); -#else -struct timeval { - time64_t tv_sec; - long tv_usec; -}; -struct timeval do_gettimeofday(void); -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) */ -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1) */ /* Linux Kernel: File Operations: start */ extern void * osl_os_open_image(char * filename); extern int osl_os_get_image_block(char * buf, int len, void * image); @@ -458,11 +446,11 @@ extern uint64 osl_systztime_us(void); /* map/unmap physical to virtual I/O */ #if !defined(CONFIG_MMC_MSM7X00A) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) #else #define REG_MAP(pa, size) ioremap((unsigned long)(pa), (unsigned long)(size)) -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) */ #else #define REG_MAP(pa, size) (void *)(0) #endif /* !defined(CONFIG_MMC_MSM7X00A */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linuxver.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linuxver.h index a647fdaf3cdc..268d126f04b8 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/linuxver.h @@ -641,16 +641,10 @@ static inline bool binary_sema_up(tsk_ctl_t *tsk) return sem_up; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) -#ifndef __alpha__ -#define SMP_RD_BARRIER_DEPENDS(x) do {} while(0) -#else -#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) -#endif -#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) +#define SMP_RD_BARRIER_DEPENDS(x) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) -#endif #else #define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) #endif // endif @@ -894,4 +888,14 @@ int kernel_read_compat(struct file *file, loff_t offset, char *addr, unsigned lo #define kernel_read_compat(file, offset, addr, count) kernel_read(file, offset, addr, count) #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) +#define timespec64 timespec +#define ktime_get_real_ts64(timespec) ktime_get_real_ts(timespec) +#define ktime_to_timespec64(timespec) ktime_to_timespec(timespec) +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) +#define rtc_time_to_tm(time, tm) rtc_time64_to_tm(time, tm) +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) */ + #endif /* _linuxver_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/mbo.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/mbo.h index 59e99e899ffe..a52198bb2bb6 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/mbo.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/mbo.h @@ -177,10 +177,10 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_mbo_cell_data_conn_pref_attr_s { uint8 cell_pref; } BWL_POST_PACKED_STRUCT wifi_mbo_cell_data_conn_pref_attr_t; -/* Cellular Data Conn Pref attr: Cellular Pref field values */ +/* Cellular Data Conn Pref attr: Cellular Pref field values. Per MBO Spec. v1.1 */ enum { - MBO_CELLULAR_DATA_CONN_EXCLUDED = 1, - MBO_CELLULAR_DATA_CONN_NOT_PREFERRED = 2, + MBO_CELLULAR_DATA_CONN_EXCLUDED = 0, + MBO_CELLULAR_DATA_CONN_NOT_PREFERRED = 1, MBO_CELLULAR_DATA_CONN_PREFERRED = 255 }; @@ -262,6 +262,9 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_mbo_anqp_elem_s { /* oui:3 bytes + oui type:1 byte + sub type:1 byte */ #define MBO_ANQP_ELEM_NO_PAYLOAD_LEN 5 +#define MBO_ANQP_VS_ELEM_SIZE (sizeof(wifi_mbo_anqp_elem_t)) +#define MBO_ANQP_VS_ELEM_LENGTH (MBO_ANQP_VS_ELEM_SIZE - 4) + /* MBO ANQP Subtype Values */ enum { MBO_ANQP_ELEM_MBO_QUERY_LIST = 1, diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/sdio.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/sdio.h index 1e9658b3b5fa..a0d95d56cab7 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/sdio.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/sdio.h @@ -269,6 +269,7 @@ typedef volatile struct { #define SDIO_FUNC_0 0 #define SDIO_FUNC_1 1 #define SDIO_FUNC_2 2 +#define SDIO_FUNC_3 3 #define SDIO_FUNC_4 4 #define SDIO_FUNC_5 5 #define SDIO_FUNC_6 6 diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl.h index a06009f1b9f3..b1cfe0e8f9af 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl.h @@ -17396,6 +17396,7 @@ enum wl_mbo_cmd_ids { WL_MBO_CMD_DBG_EVENT_CHECK = 13, WL_MBO_CMD_EVENT_MASK = 14, WL_MBO_CMD_ASSOC_DISALLOWED = 15, + WL_MBO_CMD_CELLULAR_DATA_PREF = 16, /* Add before this !! */ WL_MBO_CMD_LAST }; @@ -17413,7 +17414,8 @@ enum wl_mbo_xtlv_id { WL_MBO_XTLV_BTQ_TRIG_RSSI_DELTA = 0xa, WL_MBO_XTLV_ANQP_CELL_SUPP = 0xb, WL_MBO_XTLV_BIT_MASK = 0xc, - WL_MBO_XTLV_ASSOC_DISALLOWED = 0xd + WL_MBO_XTLV_ASSOC_DISALLOWED = 0xd, + WL_MBO_XTLV_CELLULAR_DATA_PREF = 0xe }; /* event bit mask flags for MBO */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl_defs.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl_defs.h index c9a4fe0d5b32..dc862a04f3ea 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl_defs.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wlioctl_defs.h @@ -555,12 +555,22 @@ #define WPA3_AUTH_PSK_SHA384 0x800000 /* PSK with SHA384 key derivation */ #define WPA3_AUTH_1X_SHA384 0x2000000 /* 1x with SHA384 key derivation */ +/* WFA_AUTH_DPP */ +#define WPA2_WFA_AUTH_DPP 0x200000 +#define WFA_AUTH_DPP 0x100 + /* WPA2_AUTH_SHA256 not used anymore. Just kept here to avoid build issue in DINGO */ #define WPA2_AUTH_SHA256 0x8000 #define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ #define WPA3_AUTH_SAE 0x10000 /* SAE authentication with SHA-256 */ +#define WPA3_AUTH_MASK (WPA3_AUTH_SAE_PSK | WPA3_AUTH_SAE_FBT |\ + WPA3_AUTH_OWE | WPA3_AUTH_1X_SUITE_B_SHA256 |\ + WPA3_AUTH_1X_SUITE_B_SHA384 | WPA3_AUTH_PSK_SHA384 |\ + WPA3_AUTH_1X_SHA384 | WPA3_AUTH_SAE) +#define WPA3_AUTH_ENABLED(wpa_auth) ((wpa_auth) & WPA3_AUTH_MASK) + /* pmkid */ #define MAXPMKID 16 @@ -1043,6 +1053,7 @@ #define WL_CHAN_FREQ_RANGE_6G_BAND1 6 #define WL_CHAN_FREQ_RANGE_6G_BAND2 7 #define WL_CHAN_FREQ_RANGE_6G_BAND3 8 +#define WL_CHAN_FREQ_RANGE_6G_4BAND 18 /* SROM12 */ #define WL_CHAN_FREQ_RANGE_5G_BAND4 5 diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wpa.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wpa.h index 864826bb8ce6..c6f4619bdd75 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wpa.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/include/wpa.h @@ -74,6 +74,7 @@ typedef BWL_PRE_PACKED_STRUCT struct #define WPA_IE_TAG_FIXED_LEN 6 #define BIP_OUI_TYPE WPA2_OUI "\x06" +#define BIP_GMAC_256_OUI_TYPE WPA2_OUI "\x0c" typedef BWL_PRE_PACKED_STRUCT struct { uint8 tag; /* TAG */ @@ -189,6 +190,13 @@ typedef BWL_PRE_PACKED_STRUCT struct (cipher) == WPA_CIPHER_BIP_GMAC_128 || \ (cipher) == WPA_CIPHER_BIP_GMAC_256 || \ (cipher) == WPA_CIPHER_BIP_CMAC_256) + +/* Unicast deprecated/invalid ciphers */ +#define IS_UNICAST_DEPRECATED_CIPHER(cipher) \ + ((cipher) == WPA_CIPHER_WEP_40 || \ + (cipher) == WPA_CIPHER_WEP_104 || \ + (cipher) == WPA_CIPHER_TKIP) + /* WPA TKIP countermeasures parameters */ #define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ #define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/linux_osl.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/linux_osl.c index 9f526cc62c58..d7d0c7986517 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/linux_osl.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/linux_osl.c @@ -1155,27 +1155,6 @@ osl_assert(const char *exp, const char *file, int line) } } #endif // endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1)) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) -void do_gettimeofday(struct timeval *tv) -{ - struct timespec64 ts; - ktime_get_real_ts64(&ts); - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec; -} -#else -struct timeval do_gettimeofday(void) -{ - struct timespec64 ts; - struct timeval tv; - ktime_get_real_ts64(&ts); - tv.tv_sec = ts.tv_sec; - tv.tv_usec = ts.tv_nsec; - return tv; -} -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) */ -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1) */ void osl_delay(uint usec) { @@ -1200,16 +1179,12 @@ osl_sleep(uint ms) uint64 osl_sysuptime_us(void) { - struct timeval tv; + struct timespec64 ts; uint64 usec; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - do_gettimeofday(&tv); -#else - tv = do_gettimeofday(); -#endif + ktime_get_real_ts64(&ts); /* tv_usec content is fraction of a second */ - usec = (uint64)tv.tv_sec * 1000000ul + tv.tv_usec; + usec = (uint64)ts.tv_sec * 1000000ul + (ts.tv_nsec / NSEC_PER_USEC); return usec; } @@ -1238,18 +1213,14 @@ osl_get_localtime(uint64 *sec, uint64 *usec) uint64 osl_systztime_us(void) { - struct timeval tv; + struct timespec64 ts; uint64 tzusec; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - do_gettimeofday(&tv); -#else - tv = do_gettimeofday(); -#endif + ktime_get_real_ts64(&ts); /* apply timezone */ - tzusec = (uint64)((tv.tv_sec - (sys_tz.tz_minuteswest * 60)) * + tzusec = (uint64)((ts.tv_sec - (sys_tz.tz_minuteswest * 60)) * USEC_PER_SEC); - tzusec += tv.tv_usec; + tzusec += ts.tv_nsec / NSEC_PER_USEC; return tzusec; } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/siutils.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/siutils.c index e4a0776b0adf..f2746a3fc84d 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/siutils.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/siutils.c @@ -224,6 +224,7 @@ si_pcie_enum_base(uint devid) { switch (devid) { case CYW55560_WLAN_ID: + case CYW89570_WLAN_ID: return SI_ENUM_PCIE2_BASE; } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_android.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_android.c index b16ced1e9b87..15e0aeb575de 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_android.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_android.c @@ -450,6 +450,8 @@ typedef union { #define CMD_CHANNEL_WIDTH "CHANNEL_WIDTH" #define CMD_TRANSITION_DISABLE "TRANSITION_DISABLE" +#define CMD_SAE_PWE "SAE_PWE" +#define CMD_MAXASSOC "MAXASSOC" #ifdef ENABLE_HOGSQS #define CMD_AP_HOGSQS "HOGSQS" @@ -475,6 +477,8 @@ struct connection_stats { }; #endif /* CONNECTION_STATISTICS */ +#define CMD_SCAN_PROTECT_BSS "SCAN_PROTECT_BSS" + #ifdef SUPPORT_LQCM #define CMD_SET_LQCM_ENABLE "SET_LQCM_ENABLE" #define CMD_GET_LQCM_REPORT "GET_LQCM_REPORT" @@ -1051,6 +1055,33 @@ wl_android_hogsqs(struct net_device *dev, char *command, int total_len) } #endif /* ENABLE_HOGSQS */ +/* The wl_android_scan_protect_bss function does both SET/GET based on parameters passed */ +static int wl_android_scan_protect_bss(struct net_device * dev, char * command, int total_len) +{ + int ret = 0, result = 0, bytes_written = 0; + + if (*(command + strlen(CMD_SCAN_PROTECT_BSS)) == '\0') { + ret = wldev_iovar_getint(dev, "scan_protect_bss", &result); + if (ret) { + DHD_ERROR(("%s: Failed to get scan_protect_bss\n", __FUNCTION__)); + return ret; + } + bytes_written = snprintf(command, total_len, "%s %d", CMD_SCAN_PROTECT_BSS, result); + return bytes_written; + } + command = (command + strlen(CMD_SCAN_PROTECT_BSS)); + command++; + result = bcm_atoi(command); + + DHD_INFO(("%s : scan_protect_bss = %d\n", __FUNCTION__, result)); + ret = wldev_iovar_setint(dev, "scan_protect_bss", result); + if (ret) { + DHD_ERROR(("%s: Failed to set result to %d\n", __FUNCTION__, result)); + return ret; + } + return 0; +} + #ifdef DHD_BANDSTEER static int wl_android_set_bandsteer(struct net_device *dev, char *command, int total_len) @@ -1153,6 +1184,33 @@ wl_android_set_bandsteer(struct net_device *dev, char *command, int total_len) } #endif /* DHD_BANDSTEER */ +static int +wl_android_set_maxassoc_limit(struct net_device *dev, char *command, int total_len) +{ + int ret = 0, max_assoc = 0, bytes_written = 0; + + if (*(command + strlen(CMD_MAXASSOC)) == '\0') { + ret = wldev_iovar_getint(dev, "maxassoc", &max_assoc); + if (ret) { + DHD_ERROR(("%s: Failed to get maxassoc limit\n", __FUNCTION__)); + return ret; + } + bytes_written = snprintf(command, total_len, "%s %d", CMD_MAXASSOC, max_assoc); + return bytes_written; + } + command = (command + strlen(CMD_MAXASSOC)); + command++; + max_assoc = bcm_atoi(command); + + DHD_INFO(("%s : maxassoc limit = %d\n", __FUNCTION__, max_assoc)); + ret = wldev_iovar_setint(dev, "maxassoc", max_assoc); + if (ret) { + DHD_ERROR(("%s: Failed to set maxassoc limit to %d\n", __FUNCTION__, max_assoc)); + return ret; + } + return 0; +} + #ifdef WLWFDS static int wl_android_set_wfds_hash( struct net_device *dev, char *command, bool enable) @@ -10060,6 +10118,16 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) int transition_disabled = *(command + strlen(CMD_TRANSITION_DISABLE) + 1) - '0'; bytes_written = wl_cfg80211_set_transition_mode(net, transition_disabled); } + else if (strnicmp(command, CMD_SAE_PWE, strlen(CMD_SAE_PWE)) == 0) { + u8 sae_pwe = *(command + strlen(CMD_SAE_PWE) + 1) - '0'; + bytes_written = wl_cfg80211_set_sae_pwe(net, sae_pwe); + } + else if (strnicmp(command, CMD_MAXASSOC, strlen(CMD_MAXASSOC)) == 0) { + bytes_written = wl_android_set_maxassoc_limit(net, command, priv_cmd.total_len); + } + else if (strnicmp(command, CMD_SCAN_PROTECT_BSS, strlen(CMD_SCAN_PROTECT_BSS)) == 0) { + bytes_written = wl_android_scan_protect_bss(net, command, priv_cmd.total_len); + } else { DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL"); diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.c index 8e2e73f81e44..5efa69e93136 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.c @@ -168,6 +168,9 @@ uint fw_ap_select = true; uint fw_ap_select = false; #endif /* WL_FW_OCE_AP_SELECT && (ROAM_ENABLE || BCMFW_ROAM_ENABLE) */ module_param(fw_ap_select, uint, 0660); +/* this flag enable triggerrs bgscan method from supplicant */ +uint us_ap_select = false; +module_param(us_ap_select, uint, 0660); static struct device *cfg80211_parent_dev = NULL; static struct bcm_cfg80211 *g_bcmcfg = NULL; @@ -274,7 +277,11 @@ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") #endif // endif static const struct ieee80211_regdomain brcm_regdom = { +#ifdef WL_6E + .n_reg_rules = 5, +#else .n_reg_rules = 4, +#endif /* WL_6E */ .alpha2 = "99", .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ @@ -287,7 +294,12 @@ static const struct ieee80211_regdomain brcm_regdom = { /* IEEE 802.11a, channel 36..64 */ REG_RULE(5150-10, 5350+10, 80, 6, 20, 0), /* IEEE 802.11a, channel 100..165 */ - REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), +#ifdef WL_6E + /* IEEE 802.11ax, 6E */ + REG_RULE(5935-10, 7115+10, 80, 6, 20, 0), +#endif /* WL_6E */ + } }; #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \ 4 && __GNUC_MINOR__ >= 6)) @@ -556,10 +568,10 @@ static s32 wl_cfg80211_get_station(struct wiphy *wiphy, #endif // endif static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); -#if defined(WL_FILS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) static int wl_cfg80211_update_connect_params(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme, u32 changed); -#endif /* WL_FILS */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */ static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); #if defined(WL_CFG80211_P2P_DEV_IF) @@ -827,7 +839,7 @@ static s32 wl_set_wsec_info_algos(struct net_device *dev, uint32 algos, uint32 m static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev); static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, - struct wl_join_params *join_params, size_t *join_params_size); + struct wl_join_params *join_params, size_t *join_params_size, struct ieee80211_channel *chan); void wl_cfg80211_clear_security(struct bcm_cfg80211 *cfg); /* @@ -921,6 +933,7 @@ static int wl_cfg80211_set_mac_acl(struct wiphy *wiphy, struct net_device *cfgde /* * Some external functions, TODO: move them to dhd_linux.h */ +#ifdef DHD_MONITOR_INTERFACE int dhd_add_monitor(const char *name, struct net_device **new_ndev); int dhd_del_monitor(struct net_device *ndev); int dhd_monitor_init(void *dhd_pub); @@ -931,12 +944,13 @@ netdev_tx_t int #endif /* CFI_CHECK */ dhd_start_xmit(struct sk_buff *skb, struct net_device *net); +#endif /* DHD_MONITOR_INTERFACE */ #ifdef ESCAN_CHANNEL_CACHE void reset_roam_cache(struct bcm_cfg80211 *cfg); void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi); int get_roam_channel_list(int target_chan, chanspec_t *channels, - int n_channels, const wlc_ssid_t *ssid, int ioctl_ver); + int n_channels, const wlc_ssid_t *ssid, int ioctl_ver, struct ieee80211_channel *chan); void set_roam_band(int band); #endif /* ESCAN_CHANNEL_CACHE */ @@ -1126,6 +1140,17 @@ struct chan_info { .max_power = 30, \ } +#ifdef WL_6E +#define CHAN6G(_channel, _flags) { \ + .band = IEEE80211_BAND_6GHZ, \ + .center_freq = 5950 + (5 * (_channel)), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} +#endif /* WL_6E */ + #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) #define RATETAB_ENT(_rateid, _flags) \ { \ @@ -1189,12 +1214,98 @@ static struct ieee80211_channel __wl_5ghz_a_channels[] = { CHAN5G(165, 0) }; +#ifdef WL_6E +static struct ieee80211_channel __wl_6ghz_a_channels[] = { + CHAN6G(1, 0), CHAN6G(5, 0), CHAN6G(9, 0), CHAN6G(13, 0), + CHAN6G(17, 0), CHAN6G(21, 0), CHAN6G(25, 0), CHAN6G(29, 0), + CHAN6G(33, 0), CHAN6G(37, 0), CHAN6G(41, 0), CHAN6G(45, 0), + CHAN6G(49, 0), CHAN6G(53, 0), CHAN6G(57, 0), CHAN6G(61, 0), + CHAN6G(65, 0), CHAN6G(69, 0), CHAN6G(73, 0), CHAN6G(77, 0), + CHAN6G(81, 0), CHAN6G(85, 0), CHAN6G(89, 0), CHAN6G(93, 0), + CHAN6G(97, 0), CHAN6G(101, 0), CHAN6G(105, 0), CHAN6G(109, 0), + CHAN6G(113, 0), CHAN6G(117, 0), CHAN6G(121, 0), CHAN6G(125, 0), + CHAN6G(129, 0), CHAN6G(133, 0), CHAN6G(137, 0), CHAN6G(141, 0), + CHAN6G(145, 0), CHAN6G(149, 0), CHAN6G(153, 0), CHAN6G(157, 0), + CHAN6G(161, 0), CHAN6G(165, 0), CHAN6G(169, 0), CHAN6G(173, 0), + CHAN6G(177, 0), CHAN6G(181, 0), CHAN6G(185, 0), CHAN6G(189, 0), + CHAN6G(193, 0), CHAN6G(197, 0), CHAN6G(201, 0), CHAN6G(205, 0), + CHAN6G(209, 0), CHAN6G(213, 0), CHAN6G(217, 0), CHAN6G(221, 0), + CHAN6G(225, 0), CHAN6G(229, 0), CHAN6G(233, 0) +}; +#endif /* WL_6E */ + +#ifdef WL11AX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21)) +static u32 he = 0; +struct ieee80211_sband_iftype_data sdata[IEEE80211_NUM_BANDS]; +static int wl_update_he_cap(struct bcm_cfg80211 *cfg, struct ieee80211_sband_iftype_data *data, int band) +{ + int idx = 1; + struct ieee80211_sta_he_cap *he_cap = &data->he_cap; + struct ieee80211_he_cap_elem *he_cap_elem = + &he_cap->he_cap_elem; + struct ieee80211_he_mcs_nss_supp *he_mcs = + &he_cap->he_mcs_nss_supp; + + if(data == NULL) { + WL_ERR(("failed to allco mem\n")); + return 0; + } + + data->types_mask= BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); + he_cap->has_he = true; + he_cap_elem->mac_cap_info[0] = + IEEE80211_HE_MAC_CAP0_HTC_HE | IEEE80211_HE_MAC_CAP0_TWT_REQ; + + he_cap_elem->mac_cap_info[2] = + IEEE80211_HE_MAC_CAP2_BSR; + if ((band == NL80211_BAND_5GHZ) || (band == NL80211_BAND_6GHZ)) + he_cap_elem->phy_cap_info[0] = + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; + he_cap_elem->phy_cap_info[1] = + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; + he_cap_elem->phy_cap_info[2] = + IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US; + he_cap_elem->phy_cap_info[3] = + IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; + he_cap_elem->phy_cap_info[4] = + IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; + he_cap_elem->phy_cap_info[5] = + IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2; + he_cap_elem->phy_cap_info[6] = + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | + IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | + IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | + IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | + IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; + he_cap_elem->phy_cap_info[7] = + IEEE80211_HE_PHY_CAP7_MAX_NC_1; + he_cap_elem->phy_cap_info[8] = + IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | + IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; + he_cap_elem->phy_cap_info[9] = + IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | + IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU; + he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa); + he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa); + he_mcs->rx_mcs_160 = cpu_to_le16((0xfffa)); + he_mcs->tx_mcs_160 = cpu_to_le16((0xfffa)); + return idx; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21) */ +#endif /* WL11AX */ + static struct ieee80211_supported_band __wl_band_2ghz = { .band = IEEE80211_BAND_2GHZ, .channels = __wl_2ghz_channels, .n_channels = ARRAY_SIZE(__wl_2ghz_channels), .bitrates = wl_g_rates, - .n_bitrates = wl_g_rates_size + .n_bitrates = wl_g_rates_size, }; static struct ieee80211_supported_band __wl_band_5ghz_a = { @@ -1202,9 +1313,19 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = { .channels = __wl_5ghz_a_channels, .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), .bitrates = wl_a_rates, - .n_bitrates = wl_a_rates_size + .n_bitrates = wl_a_rates_size, }; +#ifdef WL_6E +static struct ieee80211_supported_band __wl_band_6ghz = { + .band = IEEE80211_BAND_6GHZ, + .channels = __wl_6ghz_a_channels, + .n_channels = ARRAY_SIZE(__wl_6ghz_a_channels), + .bitrates = wl_a_rates, + .n_bitrates = wl_a_rates_size, +}; +#endif /* WL_6E */ + static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, @@ -1332,7 +1453,7 @@ static const rsn_akm_wpa_auth_entry_t rsn_akm_wpa_auth_lookup_tbl[] = { {WLAN_AKM_SUITE_SAE, WPA3_AUTH_SAE_PSK}, #endif /* WL_SAE */ {WLAN_AKM_SUITE_FT_8021X_SHA384, WPA3_AUTH_1X_SHA384 | WPA2_AUTH_FT}, - {WLAN_AKM_SUITE_DPP, WFA_AUTH_DPP} + {WLAN_AKM_SUITE_DPP, WPA2_WFA_AUTH_DPP} }; #define BUFSZ 8 @@ -1882,6 +2003,13 @@ static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy) else { bss = (wl_bss_info_t *) (buf + 4); chspec = bss->chanspec; +#ifdef WL_6E + /* Avoid p2p bring up in 6G based on bssinfo */ + if (CHSPEC_IS6G(chspec)) { + channel = WL_P2P_TEMP_CHAN_5G; + chspec = wl_ch_host_to_driver(channel); + } +#endif /* WL_6E */ WL_DBG(("Valid BSS Found. chanspec:%d \n", chspec)); } @@ -1922,7 +2050,6 @@ wl_wlfc_enable(struct bcm_cfg80211 *cfg, bool enable) dhd_wlfc_get_enable(dhd, &wlfc_enabled); if (wlfc_enabled && cfg->wlfc_on && dhd->op_mode != DHD_FLAG_HOSTAP_MODE && dhd->op_mode != DHD_FLAG_IBSS_MODE) { - dhd_wlfc_deinit(dhd); cfg->wlfc_on = false; } } @@ -2794,6 +2921,7 @@ wl_cfg80211_handle_if_role_conflict(struct bcm_cfg80211 *cfg, } #endif /* WL_IFACE_MGMT */ +#ifdef DHD_MONITOR_INTERFACE static struct wireless_dev * wl_cfg80211_add_monitor_if(struct wiphy *wiphy, const char *name) { @@ -2821,6 +2949,7 @@ wl_cfg80211_add_monitor_if(struct wiphy *wiphy, const char *name) return ndev->ieee80211_ptr; #endif /* WL_ENABLE_P2P_IF || WL_CFG80211_P2P_DEV_IF */ } +#endif /* DHD_MONITOR_INTERFACE */ static struct wireless_dev * wl_cfg80211_add_ibss(struct wiphy *wiphy, u16 wl_iftype, char const *name) @@ -3150,9 +3279,11 @@ wl_cfg80211_add_if(struct bcm_cfg80211 *cfg, case WL_IF_TYPE_IBSS: wdev = wl_cfg80211_add_ibss(wiphy, wl_iftype, name); break; +#ifdef DHD_MONITOR_INTERFACE case WL_IF_TYPE_MONITOR: wdev = wl_cfg80211_add_monitor_if(wiphy, name); break; +#endif /* DHD_MONITOR_INTERFACE */ case WL_IF_TYPE_STA: case WL_IF_TYPE_AP: case WL_IF_TYPE_NAN: @@ -6479,7 +6610,8 @@ wl_fils_add_hlp_container(struct bcm_cfg80211 *cfg, struct net_device *dev, } #endif /* WL_FILS */ -#if defined(WL_FILS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) +#define UPDATE_ASSOC_IES BIT(0) #ifndef UPDATE_FILS_ERP_INFO #define UPDATE_FILS_ERP_INFO BIT(1) #define UPDATE_AUTH_TYPE BIT(2) @@ -6489,7 +6621,24 @@ static int wl_cfg80211_update_connect_params(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme, u32 changed) { + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); + s32 bssidx = -1; s32 err = BCME_OK; + + if (changed & UPDATE_ASSOC_IES) { + WL_DBG(("update assoc ies\n")); + bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr); + + err = wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx, + VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len); + + if (err) { + WL_ERR(("error updating vndr ies\n")); + goto exit; + } + } + +#if defined(WL_FILS) if (changed & UPDATE_FILS_ERP_INFO) { err = wl_set_fils_params(dev, sme); @@ -6508,11 +6657,12 @@ wl_cfg80211_update_connect_params(struct wiphy *wiphy, struct net_device *dev, if ((changed & UPDATE_FILS_ERP_INFO) && !(changed & UPDATE_AUTH_TYPE)) { WL_DBG(("Warning: FILS ERP params are set, but authentication type - not\n")); } +#endif // endif exit: return err; } -#endif /* WL_FILS */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */ #ifdef WL_SAE static int @@ -6704,6 +6854,9 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (skip_hints) { /* Let fw choose the best AP */ WL_INFORM(("skipping bssid & channel hint\n")); + /* sme->channel can point to an invalid address + * which gets assigned to chan instead of NULL */ + chan = NULL; } else { if (sme->channel_hint) { chan = sme->channel_hint; @@ -6933,7 +7086,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(ssid.SSID, sme->ssid, sme->ssid_len); ssid.SSID_len = (uint32)sme->ssid_len; chan_cnt = get_roam_channel_list(cfg->channel, chanspec_list, - MAX_ROAM_CHANNEL, &ssid, ioctl_version); + MAX_ROAM_CHANNEL, &ssid, ioctl_version, chan); WL_DBG(("RCC channel count:%d \n", chan_cnt)); } #endif /* ESCAN_CHANNEL_CACHE */ @@ -7012,8 +7165,24 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, /* increate dwell time to receive probe response or detect Beacon * from target AP at a noisy air only during connect command */ +#ifdef WL_6E + /* If chan is NULL in case of fw_ap_select=1 + * avoiding dereferencing chan->center_freq */ + if (chan && chan->center_freq > FREQ_START_6G_CHANNEL) { + ext_join_params->scan.active_time = chan_cnt ? + WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E : -1; + ext_join_params->scan.passive_time = chan_cnt ? + WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E : -1; + } else { + ext_join_params->scan.active_time = chan_cnt ? + WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1; + ext_join_params->scan.passive_time = chan_cnt ? + WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1; + } +#else ext_join_params->scan.active_time = chan_cnt ? WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1; ext_join_params->scan.passive_time = chan_cnt ? WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1; +#endif /* WL_6E */ /* Set up join scan parameters */ ext_join_params->scan.scan_type = -1; ext_join_params->scan.nprobes = chan_cnt ? @@ -7144,7 +7313,8 @@ set_ssid: else memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); - if (wl_ch_to_chanspec(dev, cfg->channel, &join_params, &join_params_size) < 0) { + if (wl_ch_to_chanspec(dev, cfg->channel, &join_params, &join_params_size, + chan) < 0) { WL_ERR(("Invalid chanspec\n")); return -EINVAL; } @@ -8782,13 +8952,17 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].pmkid[j])); } } - if (cfg->wlc_ver.wlc_ver_major >= MIN_PMKID_LIST_V3_FW_MAJOR) { + if (cfg->wlc_ver.wlc_ver_major > MIN_PMKID_LIST_V3_FW_MAJOR) { pmk_list->pmkids.version = PMKID_LIST_VER_3; err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list, sizeof(*pmk_list), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync); } - else if (cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V2_FW_MAJOR) { + /* For wlc_ver_major 13 sending pmkid version as 2 + * as firmware has not implemented the pmkid list ver 3 + */ + else if (cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V2_FW_MAJOR || + cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V3_FW_MAJOR) { u32 v2_list_size = (u32)(sizeof(pmkid_list_v2_t) + npmkids*sizeof(pmkid_v2_t)); pmkid_list_v2_t *pmkid_v2_list = (pmkid_list_v2_t *)MALLOCZ(cfg->osh, v2_list_size); @@ -10312,7 +10486,17 @@ exit: return err; } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) +static void +wl_cfg80211_update_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, + struct mgmt_frame_regs *upd) +{ + WL_DBG(("mgmt_frame_regs: %x %x %x %x\n", upd->global_stypes,upd->interface_stypes, + upd->global_mcast_stypes,upd->interface_mcast_stypes)); + + return; +} +#else static void wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, u16 frame, bool reg) @@ -10325,7 +10509,7 @@ wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, return; } -#endif +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) */ static s32 wl_cfg80211_change_bss(struct wiphy *wiphy, @@ -10398,8 +10582,16 @@ wl_get_bandwidth_cap(struct net_device *ndev, uint32 band, uint32 *bandwidth) struct wiphy *wiphy = wdev->wiphy; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); +#ifdef WL_6E + if (band == IEEE80211_BAND_5GHZ || band == IEEE80211_BAND_6GHZ) { + if (band == IEEE80211_BAND_5GHZ) + param.band = WLC_BAND_5G; + else if (band == IEEE80211_BAND_6GHZ) + param.band = WLC_BAND_6G; +#else if (band == IEEE80211_BAND_5GHZ) { param.band = WLC_BAND_5G; +#endif /* WL_6E AP */ channel_width = wl_get_chanwidth_by_netdev(cfg, ndev); switch (channel_width) { case WL_CHANSPEC_BW_80: @@ -10853,7 +11045,7 @@ wl_validate_wpa2ie(struct net_device *dev, const bcm_tlv_t *wpa2ie, s32 bssidx) WL_ERR(("No Key Mgmt Info\n")); } } else if (!bcmp(mgmt->list[cnt].oui, WFA_OUI, WFA_OUI_LEN)) - wpa_auth |= WFA_AUTH_DPP; + wpa_auth |= WPA2_WFA_AUTH_DPP; } if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) { @@ -13420,9 +13612,11 @@ static struct cfg80211_ops wl_cfg80211_ops = { .remain_on_channel = wl_cfg80211_remain_on_channel, .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel, .mgmt_tx = wl_cfg80211_mgmt_tx, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) + .update_mgmt_frame_registrations = wl_cfg80211_update_mgmt_frame_register, +#else .mgmt_frame_register = wl_cfg80211_mgmt_frame_register, -#endif +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) */ .change_bss = wl_cfg80211_change_bss, #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) || defined(WL_COMPAT_WIRELESS) .set_channel = wl_cfg80211_set_channel, @@ -13461,10 +13655,12 @@ static struct cfg80211_ops wl_cfg80211_ops = { .set_rekey_data = wl_cfg80211_set_rekey_data, #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) */ #endif /* GTK_OFFLOAD_SUPPORT */ -#if defined(WL_FILS) +#if defined(WL_FILS) || defined(WL_OWE) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) /* This should be enabled from kernel version which supports this */ .update_connect_params = wl_cfg80211_update_connect_params, -#endif /* WL_FILS */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */ +#endif /* WL_FILS || defined(WL_OWE) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)) .set_pmk = wl_cfg80211_set_pmk, .del_pmk = wl_cfg80211_del_pmk, @@ -13653,7 +13849,11 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev * fw_ap_select variable determines whether FW selects the AP or the * user space selects the target AP within the given ESS. */ - wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + + if (!us_ap_select) + wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + else + WL_MEM(("upper layer roam is selected %s\n", __FUNCTION__)); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || defined(WL_COMPAT_WIRELESS) wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | @@ -13737,7 +13937,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; #else wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; -#endif // endif +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0) */ wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WL_VENDOR_EXT_SUPPORT) @@ -13881,6 +14081,9 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, boo struct wl_scan_req *sr = wl_to_sr(cfg); struct beacon_proberesp *beacon_proberesp; struct cfg80211_bss *cbss = NULL; +#if defined(WL_SUPPORT_BSS_BOOTTIME) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + struct cfg80211_inform_bss bss_data = {0x00, }; +#endif /* WL_SUPPORT_BSS_BOOTTIME */ dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub); log_conn_event_t *event_data = NULL; tlv_log *tlv_data = NULL; @@ -13914,6 +14117,11 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, boo notif_bss_info->channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec)); +#ifdef WL_6E + if (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))) { + band = wiphy->bands[IEEE80211_BAND_6GHZ]; + } else +#endif /* WL_6E */ if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else @@ -13965,33 +14173,40 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, boo } memcpy(tmp_buf, bi->SSID, bi->SSID_len); tmp_buf[bi->SSID_len] = '\0'; - WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM" + WL_DBG(("SSID : \"%s\", rssi %d, channel %d, freq %d, capability : 0x04%x, bssid %pM" "mgmt_type %d frame_len %d\n", tmp_buf, - notif_bss_info->rssi, notif_bss_info->channel, + notif_bss_info->rssi, notif_bss_info->channel, freq, mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type, notif_bss_info->frame_len)); signal = notif_bss_info->rssi * 100; +#if defined(WL_SUPPORT_BSS_BOOTTIME) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + bss_data.chan = channel; + bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; + bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); + bss_data.signal = signal; +#endif /* WL_SUPPORT_BSS_BOOTTIME */ if (!mgmt->u.probe_resp.timestamp) { +#if defined(WL_SUPPORT_BSS_BOOTTIME) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + mgmt->u.probe_resp.timestamp = bss_data.boottime_ns / 1000; +#else #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)) struct timespec ts; +#else + struct timespec64 ts; +#endif // endif get_monotonic_boottime(&ts); mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000; -#else - struct timeval tv; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) - do_gettimeofday(&tv); -#else - tv = do_gettimeofday(); -#endif - mgmt->u.probe_resp.timestamp = ((u64)tv.tv_sec*1000000) - + tv.tv_usec; -#endif // endif +#endif /* WL_SUPPORT_BSS_BOOTTIME */ } - +#if defined(WL_SUPPORT_BSS_BOOTTIME) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + cbss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, mgmt, + le16_to_cpu(notif_bss_info->frame_len), aflags); +#else cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, le16_to_cpu(notif_bss_info->frame_len), signal, aflags); +#endif /* WL_SUPPORT_BSS_BOOTTIME */ if (unlikely(!cbss)) { WL_ERR(("cfg80211_inform_bss_frame error bssid " MACDBG " channel %d \n", MAC2STRDBG((u8*)(&bi->BSSID)), notif_bss_info->channel)); @@ -14824,12 +15039,17 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, struct eth #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(channel); #else +#ifdef WL_6E + if (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))) { + freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_6GHZ); + } else +#endif /* WL_6E */ if (channel > 14) { freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); } else { freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); } -#endif // endif +#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !(WL_COMPAT_WIRELESS) */ rate = 0; err = wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate)); if (err) { @@ -16274,7 +16494,7 @@ static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev) } static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, struct wl_join_params *join_params, - size_t *join_params_size) + size_t *join_params_size, struct ieee80211_channel *chan) { chanspec_t chanspec = 0, chspec; struct bcm_cfg80211 *cfg = @@ -16284,6 +16504,11 @@ static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, struct wl_join_para join_params->params.chanspec_num = 1; join_params->params.chanspec_list[0] = ch; +#ifdef WL_6E + if (chan->center_freq > FREQ_START_6G_CHANNEL) { + chanspec |= WL_CHANSPEC_BAND_6G; + } else +#endif /* WL_6E */ if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL) chanspec |= WL_CHANSPEC_BAND_2G; else @@ -16316,7 +16541,7 @@ static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, struct wl_join_para */ int n_channels; n_channels = get_roam_channel_list(ch, join_params->params.chanspec_list, - MAX_ROAM_CHANNEL, &join_params->ssid, ioctl_version); + MAX_ROAM_CHANNEL, &join_params->ssid, ioctl_version, chan); join_params->params.chanspec_num = htod32(n_channels); *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + join_params->params.chanspec_num * sizeof(chanspec_t); @@ -16387,10 +16612,15 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(channel); +#else +#ifdef WL_6E + band = CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))? IEEE80211_BAND_6GHZ : + (channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; #else band = (channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; +#endif /* WL_6E */ freq = ieee80211_channel_to_frequency(channel, band); -#endif // endif +#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !(WL_COMPAT_WIRELESS) */ bss->channel = ieee80211_get_channel(wiphy, freq); #if defined(WL_CFG80211_P2P_DEV_IF) ie = (const u8 *)bss->ies->data; @@ -17242,6 +17472,11 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } } +#ifdef WL_6E + if (CHSPEC_IS6G(ntoh16(rxframe->channel))) { + band = wiphy->bands[IEEE80211_BAND_6GHZ]; + } else +#endif /* WL_6E */ if (channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else @@ -19316,16 +19551,28 @@ static void wl_get_bwcap(struct bcm_cfg80211 *cfg, u32 bw_cap[]) err = wldev_iovar_getint(dev, "bw_cap", &band); if (likely(!err)) { bw_cap[NL80211_BAND_2GHZ] = band; + band = WLC_BAND_5G; err = wldev_iovar_getint(dev, "bw_cap", &band); if (likely(!err)) { bw_cap[NL80211_BAND_5GHZ] = band; + +#ifdef WL_6E + band = WLC_BAND_6G; + err = wldev_iovar_getint(dev, "bw_cap", &band); + if (likely(!err)) { + bw_cap[NL80211_BAND_6GHZ] = band; + return; + } + WARN_ON(1); +#else return; +#endif /* WL_6E */ } - bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; WARN_ON(1); return; } + WARN_ON(1); WL_ERR(("fallback to mimo_bw_cap info\n")); mimo_bwcap = 0; @@ -19574,12 +19821,12 @@ s32 wl_add_remove_eventextmsg(struct net_device *ndev, u16 event, bool add) return err; } -static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap[]) +static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, u32 bw_cap[]) { struct net_device *dev = bcmcfg_to_prmry_ndev(cfg); struct ieee80211_channel *band_chan_arr = NULL; wl_uint32_list_t *list; - u32 i, j, index, n_2g, n_5g, band, channel, array_size; + u32 i, j, index, n_2g, n_5g, n_6g, band, channel, array_size; u32 *n_cnt = NULL; chanspec_t c = 0; s32 err = BCME_OK; @@ -19604,7 +19851,7 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap[]) } list = (wl_uint32_list_t *)(void *)pbuf; - band = array_size = n_2g = n_5g = 0; + band = array_size = n_2g = n_5g = n_6g = 0; for (i = 0; i < dtoh32(list->count); i++) { index = 0; update = false; @@ -19630,8 +19877,17 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap[]) n_cnt = &n_5g; band = IEEE80211_BAND_5GHZ; ht40_allowed = (bw_cap[band] == WLC_N_BW_20ALL)? false : true; +#ifdef WL_6E + } else if (CHSPEC_IS6G(c) && channel >= CH_MIN_6G_CHANNEL && + (channel <= CH_MAX_6G_CHANNEL)) { + band_chan_arr = __wl_6ghz_a_channels; + array_size = ARRAYSIZE(__wl_6ghz_a_channels); + n_cnt = &n_6g; + band = IEEE80211_BAND_6GHZ; + ht40_allowed = (bw_cap[band] == WLC_N_BW_20ALL)? false : true; +#endif /* WL_6E */ } else { - WL_ERR(("Invalid channel Sepc. 0x%x.\n", c)); + WL_ERR(("Invalid channel Spec. 0x%x.\n", c)); continue; } if (!ht40_allowed && CHSPEC_IS40(c)) @@ -19681,8 +19937,13 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap[]) if (!dfs_radar_disabled) { if (band == IEEE80211_BAND_2GHZ) channel |= WL_CHANSPEC_BAND_2G; - else + else if (band == IEEE80211_BAND_5GHZ) channel |= WL_CHANSPEC_BAND_5G; +#ifdef WL_6E + else if (band == IEEE80211_BAND_6GHZ) + channel |= WL_CHANSPEC_BAND_6G; +#endif /* WL_6E */ + channel |= WL_CHANSPEC_BW_20; channel = wl_chspec_host_to_driver(channel); err = wldev_iovar_getint(dev, "per_chan_info", &channel); @@ -19719,6 +19980,9 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap[]) } __wl_band_2ghz.n_channels = n_2g; __wl_band_5ghz_a.n_channels = n_5g; +#ifdef WL_6E + __wl_band_6ghz.n_channels = n_6g; +#endif /* WL_6E */ MFREE(cfg->osh, pbuf, LOCAL_BUF_LEN); #undef LOCAL_BUF_LEN @@ -19729,7 +19993,11 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) { struct wiphy *wiphy; struct net_device *dev = bcmcfg_to_prmry_ndev(cfg); +#ifdef WL_6E + u32 bandlist[4]; +#else u32 bandlist[3]; +#endif /* WL_6E */ u32 nband = 0; u32 i = 0; s32 err = 0; @@ -19743,7 +20011,10 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) #ifdef WL_SAE dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); #endif /* WL_SAE */ - u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; + u32 bw_cap[4] = { WLC_BW_20MHZ_BIT, /* 2GHz */ + WLC_BW_20MHZ_BIT, /* 5GHz */ + 0, /* 60GHz */ + WLC_BW_20MHZ_BIT }; /* 6GHz */ s32 cur_band = -1; struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS] = {NULL, }; @@ -19798,6 +20069,14 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) if (err != BCME_UNSUPPORTED) return err; } +#ifdef WL11AX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21)) + err = wldev_iovar_getint(dev, "he", &he); + if (unlikely(err)) { + WL_ERR(("error reading he (%d)\n", err)); + } +#endif // endif +#endif // endif wiphy = bcmcfg_to_wiphy(cfg); nband = bandlist[0]; @@ -19811,12 +20090,42 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) if (vhtmode) { wl_update_vht_cap(cfg, bands[index], bw_cap[index]); } +#endif // endif +#ifdef WL11AX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21)) + if(he) { + bands[index]->n_iftype_data = wl_update_he_cap(cfg, &sdata[index], NL80211_BAND_5GHZ); + bands[index]->iftype_data = &sdata[index]; + } +#endif // endif #endif // endif } else if (bandlist[i] == WLC_BAND_2G && __wl_band_2ghz.n_channels > 0) { index = IEEE80211_BAND_2GHZ; bands[index] = &__wl_band_2ghz; +#ifdef WL11AX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21)) + if(he) { + bands[index]->n_iftype_data = wl_update_he_cap(cfg, &sdata[index], NL80211_BAND_2GHZ); + bands[index]->iftype_data = &sdata[index]; + } +#endif // endif +#endif // endif } +#ifdef WL_6E + else if (bandlist[i] == WLC_BAND_6G && __wl_band_6ghz.n_channels > 0) { + index = IEEE80211_BAND_6GHZ; + bands[index] = &__wl_band_6ghz; +#ifdef WL11AX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21)) + if(he) { + bands[index]->n_iftype_data = wl_update_he_cap(cfg, &sdata[index], NL80211_BAND_6GHZ); + bands[index]->iftype_data = &sdata[index]; + } +#endif // endif +#endif // endif + } +#endif /* WL_6E */ if ((index >= 0) && nmode) { wl_update_ht_cap(bands[index], bw_cap[index], nchain); @@ -19825,6 +20134,9 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify) wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ]; wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ]; +#ifdef WL_6E + wiphy->bands[IEEE80211_BAND_6GHZ] = bands[IEEE80211_BAND_6GHZ]; +#endif /* WL_6E */ /* check if any bands populated otherwise makes 2Ghz as default */ if (wiphy->bands[IEEE80211_BAND_2GHZ] == NULL && @@ -19953,7 +20265,9 @@ static s32 __wl_cfg80211_up(struct bcm_cfg80211 *cfg) } #endif /* DHD_LOSSLESS_ROAMING */ +#ifdef DHD_MONITOR_INTERFACE err = dhd_monitor_init(cfg->pub); +#endif /* DHD_MONITOR_INTERFACE */ #ifdef WL_HOST_BAND_MGMT /* By default the curr_band is initialized to BAND_AUTO */ @@ -20184,7 +20498,10 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) DHD_OS_SCAN_WAKE_UNLOCK((dhd_pub_t *)(cfg->pub)); #endif // endif +#ifdef DHD_MONITOR_INTERFACE dhd_monitor_uninit(); +#endif /* DHD_MONITOR_INTERFACE */ + #ifdef WLAIBSS_MCHAN bcm_cfg80211_del_ibss_if(cfg->wdev->wiphy, cfg->ibss_cfgdev); #endif /* WLAIBSS_MCHAN */ @@ -20387,7 +20704,7 @@ int wl_cfg80211_hang(struct net_device *dev, u16 reason) dhd->hang_reason)); dhd->hang_reason = HANG_REASON_UNKNOWN; } -#ifdef DHD_USE_EXTENDED_HANG_REASON +#if defined(DHD_USE_EXTENDED_HANG_REASON) || defined(WL_CFGVENDOR_SEND_HANG_EVENT) if (dhd->hang_reason != 0) { reason = dhd->hang_reason; } @@ -20403,8 +20720,7 @@ int wl_cfg80211_hang(struct net_device *dev, u16 reason) { if (dhd->up == TRUE) { #ifdef WL_CFGVENDOR_SEND_HANG_EVENT - wl_cfgvendor_send_hang_event(dev, reason, - dhd->hang_info, dhd->hang_info_cnt); + wl_cfgvendor_send_hang_event(dev, reason); #else CFG80211_DISCONNECTED(dev, reason, NULL, 0, false, GFP_KERNEL); #endif /* WL_CFGVENDOR_SEND_HANG_EVENT */ @@ -22021,6 +22337,17 @@ wl_cfg80211_parse_vndr_ies(const u8 *parse, u32 len, __FUNCTION__, vndrie->len)); goto end; } + + /* + * skip parsing the HE capab & oper IE from upper layer + * to avoid sending it to the FW, as these IEs will be + * added by the FW based on the MAC & PHY capab if HE + * is enabled. + */ + if ((ie->data[0] == EXT_MNG_HE_CAP_ID) || + (ie->data[0] == EXT_MNG_HE_OP_ID)) { + goto end; + } } else { /* len should be bigger than OUI length + * one data length at least @@ -24081,6 +24408,25 @@ wl_cfg80211_set_transition_mode(struct net_device *ndev, u32 transition_disabled return ret; } +s32 +wl_cfg80211_set_sae_pwe(struct net_device *ndev, u8 sae_pwe) +{ + int ret = BCME_UNSUPPORTED; + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); + dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub); + + /* sae_pwe 0: HnP, 1: H2E, 2: Both HnP and H2E */ + WL_DBG(("Set SAE PWE derivation machanisme %d\n", sae_pwe)); + + if (FW_SUPPORTED(dhd, sae_ext)) + ret = wldev_iovar_setint(ndev, "extsae_pwe", sae_pwe); + + if (ret < 0) + WL_ERR(("Failed set SAE PWE, ret=%d\n", ret)); + + return ret; +} + s32 wl_cfg80211_set_dbg_verbose(struct net_device *ndev, u32 level) { @@ -25622,3 +25968,43 @@ fail: return err; } #endif /* WL_WIPSEVT */ + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1)) +void +wl_cfg80211_overtemp_event(struct net_device *ndev) +{ + return; +} +#else +void +wl_cfg80211_overtemp_event(struct net_device *ndev) +{ + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); + struct wiphy *wiphy; + struct sk_buff *skb; + gfp_t kflags; + + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + + if (!cfg || !cfg->wdev) { + WL_ERR(("cfg=%p wdev=%p\n", cfg, (cfg ? cfg->wdev : NULL))); + return; + } + + wiphy = cfg->wdev->wiphy; + if (!wiphy) { + WL_ERR(("wiphy is NULL\n")); + return; + } + +#if (defined(CONFIG_ARCH_MSM) && defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC)) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) + skb = cfg80211_vendor_event_alloc(wiphy, ndev_to_wdev(ndev), 0, + BRCM_VENDOR_EVENT_OVERTEMP, kflags); +#else + skb = cfg80211_vendor_event_alloc(wiphy, 0, BRCM_VENDOR_EVENT_OVERTEMP, + kflags); +#endif // endif + cfg80211_vendor_event(skb, kflags); +} +#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1) */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.h index f703cfd9904a..a8557ede84fb 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfg80211.h @@ -125,6 +125,7 @@ struct wl_ibss; /* Newer kernels use defines from nl80211.h */ #define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ #define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ +#define IEEE80211_BAND_6GHZ NL80211_BAND_6GHZ #define IEEE80211_BAND_60GHZ NL80211_BAND_60GHZ #define IEEE80211_NUM_BANDS NUM_NL80211_BANDS #endif /* LINUX_VER >= 4.7 */ @@ -340,11 +341,16 @@ do { \ #define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320 #define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 #define WL_AF_TX_MAX_RETRY 5 +#ifdef WL_6E +#define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E 80 +#define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E 130 +#endif /* WL_6E */ #define WL_AF_SEARCH_TIME_MAX 450 #define WL_AF_TX_EXTRA_TIME_MAX 200 -#define WL_SCAN_TIMER_INTERVAL_MS 10000 /* Scan timeout */ +/* Increase SCAN_TIMER_INTERVAL to 15secs from 10secs to accomodate 6Ghz Channels */ +#define WL_SCAN_TIMER_INTERVAL_MS 15000 /* Scan timeout */ #ifdef WL_NAN #define WL_SCAN_TIMER_INTERVAL_MS_NAN 15000 /* Scan timeout */ #endif /* WL_NAN */ @@ -405,14 +411,16 @@ do { \ /* TODO: even in upstream linux(v5.0), FT-1X-SHA384 isn't defined and supported yet. * need to revisit here to sync correct name later. */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) +#ifndef WLAN_AKM_SUITE_FT_8021X_SHA384 #define WLAN_AKM_SUITE_FT_8021X_SHA384 0x000FAC0D -#endif +#endif /* WLAN_AKM_SUITE_FT_8021X_SHA384 */ #define WL_AKM_SUITE_SHA256_1X 0x000FAC05 #define WL_AKM_SUITE_SHA256_PSK 0x000FAC06 #define WLAN_AKM_SUITE_DPP 0x506F9A02 -#define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */ +#ifndef WPA2_WFA_AUTH_DPP +#define WPA2_WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */ +#endif /* WPA2_WFA_AUTH_DPP */ #ifndef WLAN_AKM_SUITE_FILS_SHA256 #define WLAN_AKM_SUITE_FILS_SHA256 0x000FAC0E @@ -2612,6 +2620,7 @@ extern s32 wl_release_vif_macaddr(struct bcm_cfg80211 *cfg, u8 *mac_addr, u16 wl extern int wl_cfg80211_ifstats_counters(struct net_device *dev, wl_if_stats_t *if_stats); extern s32 wl_cfg80211_set_dbg_verbose(struct net_device *ndev, u32 level); extern s32 wl_cfg80211_set_transition_mode(struct net_device *ndev, u32 transition_disabled); +extern s32 wl_cfg80211_set_sae_pwe(struct net_device *ndev, u8 sae_pwe); extern int wl_cfg80211_deinit_p2p_discovery(struct bcm_cfg80211 * cfg); extern int wl_cfg80211_set_frameburst(struct bcm_cfg80211 *cfg, bool enable); extern int wl_cfg80211_determine_p2p_rsdb_mode(struct bcm_cfg80211 *cfg); @@ -2642,6 +2651,8 @@ int wl_cfg80211_set_he_mode(struct net_device *dev, struct bcm_cfg80211 *cfg, #define WL_HE_FEATURES_HE_P2P 0x20 #endif /* WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */ extern s32 wl_cfg80211_config_suspend_events(struct net_device *ndev, bool enable); +void wl_cfg80211_overtemp_event(struct net_device *ndev); + #ifdef WL11U extern bcm_tlv_t * wl_cfg80211_find_interworking_ie(const u8 *parse, u32 len); diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgscan.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgscan.c index 281e9c8679cb..ba5cc7e1013f 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgscan.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgscan.c @@ -247,7 +247,12 @@ wl_bcnrecv_result_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, s32 err = BCME_OK; struct wiphy *wiphy = NULL; wl_bcnrecv_result_t *bcn_recv = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) + struct timespec64 ts; +#else struct timespec ts; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) */ + if (!bi) { WL_ERR(("%s: bi is NULL\n", __func__)); err = BCME_NORESOURCE; @@ -280,11 +285,7 @@ wl_bcnrecv_result_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, bcn_recv->beacon_interval = bi->beacon_period; /* kernal timestamp */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) - ktime_get_boottime_ts64(&ts); -#else get_monotonic_boottime(&ts); -#endif bcn_recv->system_time = ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000; bcn_recv->timestamp[0] = bi->timestamp[0]; @@ -976,6 +977,11 @@ wl_cfgscan_populate_scan_channels(struct bcm_cfg80211 *cfg, u16 *channel_list, } #endif /* LINUX_VER >= 3.6 */ +#ifdef WL_6E + if (request->channels[i]->band == IEEE80211_BAND_6GHZ) { + chanspec |= WL_CHANSPEC_BAND_6G; + } else +#endif /* WL_6E */ if (request->channels[i]->band == IEEE80211_BAND_2GHZ) { #ifdef WL_HOST_BAND_MGMT if (cfg->curr_band == WLC_BAND_5G) { @@ -1059,7 +1065,7 @@ wl_scan_prep(struct bcm_cfg80211 *cfg, void *scan_params, u32 len, { wl_scan_params_t *params = NULL; wl_scan_params_v2_t *params_v2 = NULL; - u32 scan_type = 0; + u32 scan_type = htod32(scan_type); u32 scan_param_size = 0; u32 n_channels = 0; u32 n_ssids = 0; @@ -1222,6 +1228,7 @@ wl_update_ap_chandef(struct net_device *ndev) return err; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) + wl_cfg80211_ch_switch_notify(net, chanspec, bcmcfg_to_wiphy(cfg)); if (!cfg80211_chandef_valid(&wdev->chandef)) { wl_cfg80211_ch_switch_notify(net, 0x1001, bcmcfg_to_wiphy(cfg)); @@ -1229,8 +1236,6 @@ wl_update_ap_chandef(struct net_device *ndev) "it MUST be stopped or" " moved to a valid channel immediately\n", CHSPEC_CHANNEL(chanspec))); - }else { - wl_cfg80211_ch_switch_notify(net, chanspec, bcmcfg_to_wiphy(cfg)); } #endif /* LINUX_VERSION_CODE >= (3, 5, 0) */ } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.c index ae0ec047403f..3dd80833ed3d 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.c @@ -9538,6 +9538,7 @@ static const struct nl80211_vendor_cmd_info wl_vendor_events [] = { { OUI_BRCM, NAN_ASYNC_RESPONSE_DISABLED}, { OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO}, { OUI_BRCM, BRCM_VENDOR_EVENT_ACS}, + { OUI_BRCM, BRCM_VENDOR_EVENT_OVERTEMP}, }; int wl_cfgvendor_attach(struct wiphy *wiphy, dhd_pub_t *dhd) @@ -9583,108 +9584,62 @@ int wl_cfgvendor_detach(struct wiphy *wiphy) #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */ #ifdef WL_CFGVENDOR_SEND_HANG_EVENT +#define WL_VENDOR_STR_MAX_LEN 128 void -wl_cfgvendor_send_hang_event(struct net_device *dev, u16 reason, char *string, int hang_info_cnt) +wl_cfgvendor_send_hang_event(struct net_device *dev, u16 reason) { - struct bcm_cfg80211 *cfg = wl_get_cfg(dev); + struct bcm_cfg80211 *cfg; struct wiphy *wiphy; - char *hang_info; + struct sk_buff *skb; + dhd_pub_t *dhdp; + gfp_t kflags; int len = 0; - int bytes_written; - uint32 dummy_data = 0; - int reason_hang_info = 0; - int cnt = 0; - dhd_pub_t *dhd; - int hang_reason_mismatch = FALSE; + char reason_str[WL_VENDOR_STR_MAX_LEN] = {0x00, }; + cfg = wl_cfg80211_get_bcmcfg(); if (!cfg || !cfg->wdev) { WL_ERR(("cfg=%p wdev=%p\n", cfg, (cfg ? cfg->wdev : NULL))); return; } wiphy = cfg->wdev->wiphy; - if (!wiphy) { WL_ERR(("wiphy is NULL\n")); return; } - hang_info = MALLOCZ(cfg->osh, VENDOR_SEND_HANG_EXT_INFO_LEN); - if (hang_info == NULL) { - WL_ERR(("alloc hang_info failed\n")); + dhdp = (dhd_pub_t *)(cfg->pub); + if (!dhdp) { + WL_ERR(("dhdp is NULL\n")); return; } - dhd = (dhd_pub_t *)(cfg->pub); + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; -#ifdef WL_BCNRECV - /* check fakeapscan in progress then stop scan */ - if (cfg->bcnrecv_info.bcnrecv_state == BEACON_RECV_STARTED) { - wl_android_bcnrecv_stop(dev, WL_BCNRECV_HANG); - } -#endif /* WL_BCNRECV */ - sscanf(string, "%d", &reason_hang_info); - bytes_written = 0; - len = VENDOR_SEND_HANG_EXT_INFO_LEN - bytes_written; - if (strlen(string) == 0 || (reason_hang_info != reason)) { - WL_ERR(("hang reason mismatch: string len %d reason_hang_info %d\n", - (int)strlen(string), reason_hang_info)); - hang_reason_mismatch = TRUE; - if (dhd) { - get_debug_dump_time(dhd->debug_dump_time_hang_str); - copy_debug_dump_time(dhd->debug_dump_time_str, - dhd->debug_dump_time_hang_str); - } - bytes_written += scnprintf(&hang_info[bytes_written], len, - "%d %d %s %08x %08x %08x %08x %08x %08x %08x", - reason, VENDOR_SEND_HANG_EXT_INFO_VER, - dhd->debug_dump_time_hang_str, - 0, 0, 0, 0, 0, 0, 0); - if (dhd) { - clear_debug_dump_time(dhd->debug_dump_time_hang_str); - } - } else { - bytes_written += scnprintf(&hang_info[bytes_written], len, "%s", string); - } - - WL_ERR(("hang reason: %d info cnt: %d\n", reason, hang_info_cnt)); - - if (hang_reason_mismatch == FALSE) { - cnt = hang_info_cnt; - } else { - cnt = HANG_FIELD_MISMATCH_CNT; - } - - while (cnt < HANG_FIELD_CNT_MAX) { - len = VENDOR_SEND_HANG_EXT_INFO_LEN - bytes_written; - if (len <= 0) { - break; - } - bytes_written += scnprintf(&hang_info[bytes_written], len, - "%c%08x", HANG_RAW_DEL, dummy_data); - cnt++; - } - - WL_ERR(("hang info cnt: %d len: %d\n", cnt, (int)strlen(hang_info))); - WL_ERR(("hang info data: %s\n", hang_info)); - - wl_cfgvendor_send_async_event(wiphy, - bcmcfg_to_prmry_ndev(cfg), BRCM_VENDOR_EVENT_HANGED, - hang_info, (int)strlen(hang_info)); - - memset(string, 0, VENDOR_SEND_HANG_EXT_INFO_LEN); - - if (hang_info) { - MFREE(cfg->osh, hang_info, VENDOR_SEND_HANG_EXT_INFO_LEN); - } - -#ifdef DHD_LOG_DUMP - dhd_logdump_cookie_save(dhd, dhd->debug_dump_time_hang_str, "HANG"); -#endif /* DHD_LOG_DUMP */ - - if (dhd) { - clear_debug_dump_time(dhd->debug_dump_time_str); +#ifdef DHD_FW_COREDUMP + len = snprintf(reason_str, WL_VENDOR_STR_MAX_LEN, + "memdump_type = 0x%x, ", dhdp->memdump_type); +#endif // endif + len = snprintf(reason_str + len, WL_VENDOR_STR_MAX_LEN, + "HANG reason = 0x%x", reason); + + /* Alloc the SKB for vendor_event */ +#if (defined(CONFIG_ARCH_MSM) && defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC)) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) + skb = cfg80211_vendor_event_alloc(wiphy, ndev_to_wdev(dev), WL_VENDOR_STR_MAX_LEN, + BRCM_VENDOR_EVENT_HANGED, kflags); +#else + skb = cfg80211_vendor_event_alloc(wiphy, len, BRCM_VENDOR_EVENT_HANGED, kflags); +#endif /* (defined(CONFIG_ARCH_MSM) && defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC)) || */ + /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) */ + + if (!skb) { + WL_ERR(("skb allocation is failed\n")); + return; } + WL_INFORM_MEM(("%s\n", reason_str)); + nla_put(skb, DEBUG_ATTRIBUTE_HANG_REASON, strlen(reason_str), reason_str); + cfg80211_vendor_event(skb, kflags); } void diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.h b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.h index debe3515bfd7..c275efa1b908 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.h +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_cfgvendor.h @@ -613,6 +613,7 @@ typedef enum wl_vendor_event { NAN_ASYNC_RESPONSE_DISABLED = 40, BRCM_VENDOR_EVENT_RCC_INFO = 41, BRCM_VENDOR_EVENT_ACS = 42, + BRCM_VENDOR_EVENT_OVERTEMP = 43, BRCM_VENDOR_EVENT_LAST } wl_vendor_event_t; @@ -893,8 +894,7 @@ int wl_cfgvendor_notify_supp_event_str(const char *evt_name, const char *fmt, .. /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) */ #ifdef WL_CFGVENDOR_SEND_HANG_EVENT -void wl_cfgvendor_send_hang_event(struct net_device *dev, u16 reason, - char *string, int hang_info_cnt); +void wl_cfgvendor_send_hang_event(struct net_device *dev, u16 reason); void wl_copy_hang_info_if_falure(struct net_device *dev, u16 reason, s32 ret); #endif /* WL_CFGVENDOR_SEND_HANG_EVENT */ #endif /* _wl_cfgvendor_h_ */ diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_iw.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_iw.c index 13cc9c45afed..78fd08e48328 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_iw.c @@ -240,7 +240,9 @@ dev_wlc_ioctl( { struct ifreq ifr; wl_ioctl_t ioc; +#if defined(KERNEL_DS) && defined(USER_DS) mm_segment_t fs; +#endif /* KERNEL_DS && USER_DS */ int ret; memset(&ioc, 0, sizeof(ioc)); @@ -252,16 +254,20 @@ dev_wlc_ioctl( ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; ifr.ifr_data = (caddr_t) &ioc; +#if defined(KERNEL_DS) && defined(USER_DS) fs = get_fs(); #if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 21) set_fs(get_ds()); #endif // endif +#endif /* KERNEL_DS && USER_DS */ #if defined(WL_USE_NETDEV_OPS) ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); #else ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); #endif // endif +#if defined(KERNEL_DS) && defined(USER_DS) set_fs(fs); +#endif /* KERNEL_DS && USER_DS */ return ret; } diff --git a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_roam.c b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_roam.c index c93f2c617880..e3be4aa3b3a6 100644 --- a/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_roam.c +++ b/drivers/net/wireless/rockchip_wlan/infineon/bcmdhd/wl_roam.c @@ -56,7 +56,7 @@ typedef struct { static int n_roam_cache = 0; static int roam_band = WLC_BAND_AUTO; static roam_channel_cache roam_cache[MAX_ROAM_CACHE]; -static uint band2G, band5G, band_bw; +static uint band2G, band5G, band6G, band_bw; #ifdef WES_SUPPORT static int roamscan_mode = ROAMSCAN_MODE_NORMAL; @@ -86,11 +86,13 @@ int init_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver) } else { band2G = WL_CHANSPEC_BAND_2G; band5G = WL_CHANSPEC_BAND_5G; + band6G = WL_CHANSPEC_BAND_6G; band_bw = WL_CHANSPEC_BW_20; } #else band2G = WL_CHANSPEC_BAND_2G; band5G = WL_CHANSPEC_BAND_5G; + band6G = WL_CHANSPEC_BAND_6G; band_bw = WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; #endif /* D11AC_IOTYPES */ @@ -248,7 +250,8 @@ void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi) channel = wf_chspec_ctlchan(bi->chanspec); WL_DBG(("CHSPEC = %s, CTL %d\n", wf_chspec_ntoa_ex(bi->chanspec, chanbuf), channel)); roam_cache[n_roam_cache].chanspec = - (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw | channel; + (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))? + band6G : (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw | channel; (void)memcpy_s(roam_cache[n_roam_cache].ssid, bi->SSID_len, bi->SSID, bi->SSID_len); n_roam_cache++; @@ -267,7 +270,8 @@ static bool is_duplicated_channel(const chanspec_t *channels, int n_channels, ch } int get_roam_channel_list(int target_chan, - chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver) + chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver, + struct ieee80211_channel *chan) { int i, n = 1; char chanbuf[CHANSPEC_STR_LEN]; @@ -275,7 +279,8 @@ int get_roam_channel_list(int target_chan, /* first index is filled with the given target channel */ if (target_chan) { channels[0] = (target_chan & WL_CHANSPEC_CHAN_MASK) | - (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw; + (chan->center_freq > FREQ_START_6G_CHANNEL ? + band6G : (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw; } else { /* If target channel is not provided, set the index to 0 */ n = 0; @@ -289,11 +294,15 @@ int get_roam_channel_list(int target_chan, chanspec_t ch = roam_cache[i].chanspec; bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch); + bool is_6G = CHSPEC_IS6G(ch); bool band_match = ((roam_band == WLC_BAND_AUTO) || ((roam_band == WLC_BAND_2G) && is_2G) || - ((roam_band == WLC_BAND_5G) && is_5G)); + ((roam_band == WLC_BAND_5G) && is_5G) || + ((roam_band == WLC_BAND_6G) && is_6G)); ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw; + ch = CHSPEC_CHANNEL(ch) | + (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw; if (band_match && !is_duplicated_channel(channels, n, ch)) { WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__, wf_chspec_ntoa_ex(ch, chanbuf))); @@ -313,11 +322,13 @@ int get_roam_channel_list(int target_chan, chanspec_t ch = roam_cache[i].chanspec; bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch); + bool is_6G = CHSPEC_IS6G(ch); bool band_match = ((roam_band == WLC_BAND_AUTO) || ((roam_band == WLC_BAND_2G) && is_2G) || - ((roam_band == WLC_BAND_5G) && is_5G)); + ((roam_band == WLC_BAND_5G) && is_5G) || + ((roam_band == WLC_BAND_6G) && is_6G)); - ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw; + ch = CHSPEC_CHANNEL(ch) | (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw; if ((roam_cache[i].ssid_len == ssid->SSID_len) && band_match && !is_duplicated_channel(channels, n, ch) && (memcmp(roam_cache[i].ssid, ssid->SSID, ssid->SSID_len) == 0)) { @@ -418,14 +429,17 @@ void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver) chanspec_t ch = roam_cache[i].chanspec; bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch); + bool is_6G = CHSPEC_IS6G(ch); bool band_match = ((roam_band == WLC_BAND_AUTO) || ((roam_band == WLC_BAND_2G) && is_2G) || - ((roam_band == WLC_BAND_5G) && is_5G)); + ((roam_band == WLC_BAND_5G) && is_5G) || + ((roam_band == WLC_BAND_6G) && is_6G)); if ((roam_cache[i].ssid_len == ssid.SSID_len) && band_match && (memcmp(roam_cache[i].ssid, ssid.SSID, ssid.SSID_len) == 0)) { /* match found, add it */ - ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw; + ch = CHSPEC_CHANNEL(ch) | + (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw; add_roamcache_channel(&channel_list, ch); } } @@ -464,8 +478,9 @@ void wl_update_roamscan_cache_by_band(struct net_device *dev, int band) for (n = 0; n < n_roam_cache; n++) { chanspec_t ch = roam_cache[n].chanspec; bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch); + bool is_6G = CHSPEC_IS6G(ch); chanlist_before.channels[n] = CHSPEC_CHANNEL(ch) | - (is_2G ? band2G : band5G) | band_bw; + (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw; } } else { if (band == WLC_BAND_AUTO) { @@ -484,9 +499,11 @@ void wl_update_roamscan_cache_by_band(struct net_device *dev, int band) chanspec_t chspec = chanlist_before.channels[i]; bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(chspec) : CHSPEC_IS2G(chspec); bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(chspec) : CHSPEC_IS5G(chspec); + bool is_6G = CHSPEC_IS6G(chspec); bool band_match = ((band == WLC_BAND_AUTO) || ((band == WLC_BAND_2G) && is_2G) || - ((band == WLC_BAND_5G) && is_5G)); + ((band == WLC_BAND_5G) && is_5G) || + ((band == WLC_BAND_6G) && is_6G)); if (band_match) { chanlist_after.channels[chanlist_after.n++] = chspec; }