[Feature][API-904][wifi] Ignition-ES100 update bcmdhd ver to 100_10_96
Change-Id: I88670495c1ab5a32387c0c8aaabf4d9b126bd7ea
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
index 29835c5..3b046c4 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
@@ -7,7 +7,7 @@
config BCMDHD
tristate "Broadcom FullMAC wireless cards support"
- ---help---
+ help
This module adds support for wireless adapters based on
Broadcom FullMAC chipset.
@@ -60,20 +60,20 @@
depends on BCMDHD
string "Firmware path"
default "/system/vendor/firmware/fw_bcmdhd.bin"
- ---help---
+ help
Path to the firmware file.
config BCMDHD_NVRAM_PATH
depends on BCMDHD
string "NVRAM path"
default "/system/etc/wifi/bcmdhd.cal"
- ---help---
+ help
Path to the calibration file.
config BROADCOM_WIFI_RESERVED_MEM
bool "BROADCOM Reserved memory for wifi device"
depends on BCMDHD
- ---help---
+ help
This is a configuration for Broadcom WLAN driver.
config BCMDHD_WEXT
@@ -88,28 +88,28 @@
bool "Enable memory preallocation"
depends on BCMDHD
default n
- ---help---
+ help
Use memory preallocated in platform
config DHD_USE_SCHED_SCAN
bool "Use CFG80211 sched scan"
depends on BCMDHD && CFG80211
default n
- ---help---
+ help
Use CFG80211 sched scan
config DHD_SET_RANDOM_MAC_VAL
hex "Vendor OUI"
depends on BCMDHD
default 0x001A11
- ---help---
+ help
Set vendor OUI for SoftAP
config WLAN_REGION_CODE
int "---Region codes for Broadcom WiFi Driver"
depends on BCMDHD
default 100
- ---help---
+ help
This is a region code for Broadcom Wi-Fi featured functions.
- 100 : EUR OPEN
- 101 : EUR ORG
@@ -123,58 +123,58 @@
bool "Advanced IBSS mode"
depends on (BCM4335 || BCM4339 || BCM4354 || BCM4358 || BCM4359 || BCM4361)
default y
- ---help---
+ help
This is a configuration for Oxygen Network.
config WL_RELMCAST
bool "Reliable Multicast Support"
depends on (BCM4335 || BCM4339 || BCM4354 || BCM4358 || BCM4359 || BCM4361)
default y
- ---help---
+ help
This is a configuration for RMC.
config WL_NAN
bool "NAN Feature"
depends on BCMDHD
default n
- ---help---
+ help
This is a configuration for NAN Feature.
config WL_AP_IF
bool "Create additional AP interface during intialization"
default n
- ---help---
+ help
Create additional AP interface during initialization.
config BCMDHD_PREALLOC_PKTIDMAP
bool "BROADCOM PCIE specific memory reserved for PKTIDMAP"
depends on BROADCOM_WIFI_RESERVED_MEM && BCMDHD_PCIE
- ---help---
+ help
Preallocated memory support for PCIE interface in Broadcom
WLAN driver.
config BCMDHD_PREALLOC_MEMDUMP
bool "BROADCOM PCIE specific memory reserved for MEMDUMP"
depends on BROADCOM_WIFI_RESERVED_MEM
- ---help---
+ help
Preallocated memory support for dongle memory dump
config BCMDHD_OOB_HOST_WAKE
bool "Use the external WLAN_HOST_WAKE pin"
depends on BCMDHD
- ---help---
+ help
Use the external GPIO pin to wake up host
config BCMDHD_GET_OOB_STATE
bool "Support WLAN_HOST_WAKE pin level information"
depends on BCMDHD_OOB_HOST_WAKE
default y
- ---help---
+ help
Support WLAN_HOST_WAKE pin level information
config BCMDHD_WPA3
bool "Support WPA3 feature"
depends on BCMDHD
default n
- ---help---
+ help
This will enable WPA3 support
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
index 6507e16..00b81ea 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
@@ -1,8 +1,8 @@
# bcmdhd
#
-# Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+# Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
#
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2016, Broadcom Corporation
#
# Unless you and Broadcom execute a separate written software license
# agreement governing use of this software, this software is licensed to you
@@ -45,6 +45,10 @@
ifeq "$(GCCVERSIONGTEQ9)" "1"
DHDCFLAGS += -Wno-error=date-time
endif
+GCCVERSIONGTEQ7 := $(shell expr `$(CROSS_COMPILE)gcc -dumpversion | cut -f1 -d.` \>= 7)
+ifeq "$(GCCVERSIONGTEQ7)" "1"
+ DHDCFLAGS += -Wimplicit-fallthrough=3
+endif
DHDCFLAGS += $(call cc-disable-warning, date-time)
DHDCFLAGS += $(call cc-disable-warning, stringop-overflow)
@@ -115,6 +119,12 @@
# keepalive
DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
+#OCE enable/disable in dhd
+DHDCFLAGS += -DOCE_SUPPORT
+
+#OWE enable in dhd
+DHDCFLAGS += -DWL_OWE
+
DHDCFLAGS += -DVSDB
# For p2p connection issue
@@ -146,10 +156,10 @@
DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
# Hog flags
-#DHDCFLAGS += -DENABLE_HOGSQS
-#ifeq ($(ENABLE_HOGSQS), y)
-#DHDCFLAGS += -DM_HOGSQS_CFG=0x1910
-#endif // endif
+ifeq ($(CONFIG_ENABLE_HOGSQS), y)
+DHDCFLAGS += -DENABLE_HOGSQS
+DHDCFLAGS += -DM_HOGSQS_CFG=0x1910
+endif
# For special PNO Event keep wake lock for 10sec
DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -218,14 +228,23 @@
DHDCFLAGS += -DKEEP_WIFION_OPTION
DHDCFLAGS += -Wno-date-time
-# To support android12 Wifi-HAL
-ifeq ($(CONFIG_ANDROID12),y)
- DHDCFLAGS += -DANDROID12_SUPPORT
-endif
+#Android features
+ifeq ($(shell expr $(CONFIG_ANDROID_VERSION) \>= 12), 1)
+ DHDCFLAGS += -DCONFIG_ANDROID_VERSION=$(CONFIG_ANDROID_VERSION)
+ DHDCFLAGS += -DP2P_RAND
+ DHDCFLAGS += -DSOFTAP_RAND
+#To support Android12 CDD [C-1-7] [C-1-8] [C-1-9] [C-1-10]
+ DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+#To support recovery
+ DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT
+
+ DHDCFLAGS += -DWL_SELF_MANAGED_REGDOM
# To support ACS on hostapd
# DHDCFLAGS += -DWL_SUPPORT_ACS_OFFLOAD
endif
+endif
# SoftAP
DHDCFLAGS += -DSET_RANDOM_MAC_SOFTAP
@@ -255,11 +274,18 @@
DHDCFLAGS += -DDHD_4WAYM4_FAIL_DISCONNECT
endif
-#6Ghz
-ifneq ($(CONFIG_BCMDHD_6E),)
+#802.11ax and 6Ghz Support
+ifeq ($(CONFIG_BCMDHD_WIFI6_6E),y)
+# DHDCFLAGS += -DWL11AX
DHDCFLAGS += -DWL_6E
endif
+#IFX cfg80211 support
+ifeq ($(CONFIG_BCMDHD_IFX_CFG80211),y)
+ #For 5.4.21 kernel
+ DHDCFLAGS += -DIFX_CFG80211_5_4_21
+endif
+
# Uncomment the below line for AP to receive disconnect management frame.
# DHDCFLAGS += -DWL_CFG80211_AP_RX_MGMT_DISCONNECT
@@ -375,7 +401,9 @@
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
DHDCFLAGS += -DDHD_USE_STATIC_IOCTLBUF
endif
-
+ifeq ($(CONFIG_BCMDHD_COHERENT_MEM_RING),y)
+DHDCFLAGS += -DDHD_USE_COHERENT_MEM_FOR_RING
+endif
# Enable health check event handling
DHDCFLAGS += -DDNGL_EVENT_SUPPORT
DHDCFLAGS += -DHCHK_COMMON_SW_EVENT
@@ -497,7 +525,7 @@
endif
#EXTRA_LDFLAGS += --strip-debug
-#tianyan
+#qs.xiong
DHDCFLAGS += -Wno-array-bounds -Wno-sizeof-pointer-memaccess -Wno-unused-function
@@ -516,7 +544,7 @@
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
+ dhd_linux_exportfs.o wl_twt.o
ifneq ($(CONFIG_DHD_MONITOR_INTERFACE),)
DHDCFLAGS += -DDHD_MONITOR_INTERFACE
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
old mode 100644
new mode 100755
index 94e0e3c..e06b1ce
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
@@ -1,9 +1,9 @@
/*
* Bloom filter support
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -31,9 +31,6 @@
#include <typedefs.h>
#include <bcmdefs.h>
-
-#include <stdarg.h>
-
#ifdef BCMDRIVER
#include <osl.h>
#include <bcmutils.h>
@@ -44,6 +41,7 @@
#define ASSERT(exp)
#endif // endif
#endif /* !BCMDRIVER */
+#include <stdarg.h>
#include <bcmutils.h>
#include <bcmbloom.h>
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
old mode 100644
new mode 100755
index 7173f1b..635041f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -1,9 +1,9 @@
/*
* SDIO access interface for drivers - linux specific (pci only)
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -311,6 +311,12 @@
bcmsdh_unregister_client_driver();
}
+void *bcmsdh_get_dev(bcmsdh_info_t *sdh)
+{
+ bcmsdh_os_info_t *bcmsdh_osinfo = sdh->os_cxt;
+ return bcmsdh_osinfo->dev;
+}
+
void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh)
{
#if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
old mode 100644
new mode 100755
index 149f2da..b0e401d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -1,9 +1,9 @@
/*
* BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -191,6 +191,10 @@
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N2G_ID) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N5G_ID) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4373_CHIP_ID) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43430_CHIP_ID) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43439_CHIP_ID) },
+ { SDIO_DEVICE(CY_DNGL_VID, BCM43439_CHIP_ID) },
+ { SDIO_DEVICE(CY_DNGL_VID, BCM_DNGL_BL_PID_43439) },
/* { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) }, */
/* end: all zeroes */
{ 0, 0, 0, 0},
@@ -272,7 +276,8 @@
if (id) {
sd_err(("%s: class=0x%x; vendor=0x%x; device=0x%x\n", __FUNCTION__,
id->class, id->vendor, id->device));
- if (id->vendor != SDIO_VENDOR_ID_BROADCOM)
+ if ((id->vendor != SDIO_VENDOR_ID_BROADCOM) &&
+ (id->vendor != CY_DNGL_VID))
return -ENODEV;
}
if (func && (func->num != 2)) {
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
old mode 100644
new mode 100755
index eef1190..b13ed80
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
@@ -1,9 +1,9 @@
/*
* Broadcom SPI Host Controller Driver - Linux Per-port
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -43,7 +43,11 @@
#include <pcicfg.h>
#include <sdio.h> /* SDIO Device and Protocol Specs */
#include <linux/sched.h> /* request_irq(), free_irq() */
+#ifndef GSPIBCM
#include <bcmsdspi.h>
+#else
+#include <bcmgspi.h>
+#endif /* GSPIBCM */
#include <bcmdevs.h>
#include <bcmspi.h>
#endif /* BCMSPI_ANDROID */
@@ -147,7 +151,6 @@
{
osl_t *osh = NULL;
sdioh_info_t *sdioh = NULL;
- void *bcmsdh;
int rc;
@@ -231,13 +234,8 @@
goto err;
}
-#ifdef GSPIBCM
- bcmsdh = bcmsdh_probe(osh, &pdev->dev, sdioh, NULL, PCI_BUS, -1, -1);
- if (bcmsdh == NULL) {
-#else
sdioh->bcmsdh = bcmsdh_probe(osh, &pdev->dev, sdioh, NULL, PCI_BUS, -1, -1);
if (sdioh->bcmsdh == NULL) {
-#endif /* GSPIBCM */
sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
goto err;
}
@@ -272,6 +270,7 @@
}
osh = sdioh->osh;
+
bcmsdh_remove(sdioh->bcmsdh);
sdioh_detach(osh, sdioh);
osl_detach(osh);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
old mode 100644
new mode 100755
index 9021aea..f026432
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
@@ -1,9 +1,9 @@
/*
* Driver O/S-independent utility routines
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -32,7 +32,6 @@
#include <bcm_cfg.h>
#include <typedefs.h>
#include <bcmdefs.h>
-#include <stdarg.h>
#ifdef BCMDRIVER
#include <osl.h>
#include <bcmutils.h>
@@ -53,7 +52,7 @@
#endif // endif
#endif /* !BCMDRIVER */
-
+#include <stdarg.h>
#ifdef WL_UNITTEST
#ifdef ASSERT
#undef ASSERT
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
old mode 100644
new mode 100755
index 18747aa..d242b6c
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
@@ -3,9 +3,9 @@
* Contents are wifi-specific, used by any kernel or app-level
* software that might want wifi things as it grows.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -835,6 +835,11 @@
}
}
}
+#ifdef WL_6E
+ else if (CHSPEC_IS6G(chanspec)) {
+ return TRUE;
+ }
+#endif /* WL_6E */
return FALSE;
}
@@ -1012,6 +1017,61 @@
return chspec;
}
+#ifdef WL_6E
+/* return chanspec for 6E given primary 20MHz channel and bandwidth
+ * return 0 on error. Below separate func added for 6E as 6ghz channels
+ * overlap with legacy bands and there was no way in older func to
+ * differentiate this through just channel number and bw.
+ */
+uint16
+wf_channel2chspec6E(uint pri_ch, uint bw)
+{
+ uint16 chspec = 0;
+ const uint8 *center_ch = NULL;
+ int num_ch = 0;
+ int sb = -1;
+ int i = 0;
+
+ chspec = WL_CHANSPEC_BAND_6G;
+ chspec |= bw;
+
+ if (bw == WL_CHANSPEC_BW_40) {
+ center_ch = wf_6g_40m_chans;
+ num_ch = WF_NUM_6G_40M_CHANS;
+ bw = 40;
+ } else if (bw == WL_CHANSPEC_BW_80) {
+ center_ch = wf_6g_80m_chans;
+ num_ch = WF_NUM_6G_80M_CHANS;
+ bw = 80;
+ } else if (bw == WL_CHANSPEC_BW_160) {
+ center_ch = wf_6g_160m_chans;
+ num_ch = WF_NUM_6G_160M_CHANS;
+ bw = 160;
+ } else if (bw == WL_CHANSPEC_BW_20) {
+ chspec |= pri_ch;
+ return chspec;
+ } else {
+ return 0;
+ }
+
+ for (i = 0; i < num_ch; i ++) {
+ sb = channel_to_sb(center_ch[i], pri_ch, bw);
+ if (sb >= 0) {
+ chspec |= center_ch[i];
+ chspec |= (sb << WL_CHANSPEC_CTL_SB_SHIFT);
+ break;
+ }
+ }
+
+ /* check for no matching sb/center */
+ if (sb < 0) {
+ return 0;
+ }
+
+ return chspec;
+}
+#endif /* WL_6E */
+
/*
* This function returns the chanspec for the primary 40MHz of an 80MHz or wider channel.
* The primary 20MHz channel of the returned 40MHz chanspec is the same as the primary 20MHz
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
index e78878b..f1004f0 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
@@ -3,9 +3,9 @@
* This header file housing the define and function prototype use by
* both the wl driver, tools & Apps.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -734,6 +734,9 @@
*
*/
extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
+#ifdef WL_6E
+extern uint16 wf_channel2chspec6E(uint pri_ch, uint bw);
+#endif /* WL_6E */
extern uint wf_channel2freq(uint channel);
extern uint wf_freq2channel(uint freq);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
old mode 100644
new mode 100755
index 76ac971..96cf6f4
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
@@ -1,9 +1,9 @@
/*
* Common OS-independent driver header for rate management.
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -52,6 +52,9 @@
#define WL_RSPEC_BW_MASK 0x00070000 /**< Band width */
#define WL_RSPEC_BW_SHIFT 16
#define WL_RSPEC_DCM 0x00080000 /**< Dual Carrier Modulation */
+#define WL_RSPEC_DCM_SHIFT 19
+#define WL_RSPEC_ER_MASK 0x0000C000 /**< Range extension mask */
+#define WL_RSPEC_ER_SHIFT 14
#define WL_RSPEC_STBC 0x00100000 /**< STBC expansion, Nsts = 2 * Nss */
#define WL_RSPEC_TXBF 0x00200000
#define WL_RSPEC_LDPC 0x00400000
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
old mode 100644
new mode 100755
index 509fb2f..6802520
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
@@ -1,9 +1,9 @@
/*
* Driver O/S-independent utility routines
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -33,9 +33,6 @@
#include <typedefs.h>
#include <bcmdefs.h>
-
-#include <stdarg.h>
-
#ifdef BCMDRIVER
#include <osl.h>
#else /* !BCMDRIVER */
@@ -46,7 +43,7 @@
#define ASSERT(exp)
#endif // endif
#endif /* !BCMDRIVER */
-
+#include <stdarg.h>
#include <bcmtlv.h>
#include <bcmendian.h>
#include <bcmutils.h>
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
index f426c42..3d14f18 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
@@ -4,9 +4,9 @@
* Provides type definitions and function prototypes used to link the
* DHD OS, bus, and protocol modules.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -830,8 +830,8 @@
#define DHD_COMMON_DUMP_PATH "/data/misc/wifi/"
#elif defined(OEM_ANDROID) && (defined(BOARD_PANDA) || defined(__ARM_ARCH_7A__))
#define DHD_COMMON_DUMP_PATH "/data/vendor/wifi/"
-#elif defined(OEM_ANDROID) /* For Brix Live Image */
-#define DHD_COMMON_DUMP_PATH "/installmedia/"
+#elif defined(OEM_ANDROID) /* For other Android platforms such as Brix Live Image */
+#define DHD_COMMON_DUMP_PATH "/data/vendor/wifi/wifi_dumps/"
#else /* Default */
#define DHD_COMMON_DUMP_PATH "/root/"
#endif // endif
@@ -1427,6 +1427,9 @@
#ifdef REVERSE_AIFSN
bool aifsn_reverse;
#endif /* REVERSE_AIFSN */
+#ifdef WL11AX
+ void *twt_ctx;
+#endif /* WL11AX */
} dhd_pub_t;
typedef struct {
@@ -2203,7 +2206,8 @@
#ifdef KEEP_ALIVE
extern int dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pkt,
- uint16 ip_pkt_len, uint8* src_mac_addr, uint8* dst_mac_addr, uint32 period_msec);
+ uint16 ip_pkt_len, uint8* src_mac_addr, uint8* dst_mac_addr, uint32 period_msec,
+ uint16 ether_type);
extern int dhd_dev_stop_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id);
#endif /* KEEP_ALIVE */
@@ -3488,6 +3492,13 @@
extern uint8 control_he_enab;
#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+extern int dhd_control_mbo_enab(dhd_pub_t * dhd, uint8 mbo_enab);
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+extern int dhd_control_oce_enab(dhd_pub_t * dhd, uint8 oce_enab);
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
+
#if defined(BCMSDIO)
void dhd_set_role(dhd_pub_t *dhdp, int role, int bssidx);
#endif /* BCMSDIO */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
old mode 100644
new mode 100755
index fda0c7e..2f12fdc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -1,9 +1,9 @@
/*
* DHD Protocol Module for CDC and BDC.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -153,21 +153,13 @@
#ifdef BCMSPI
/* 11bit gSPI bus allows 2048bytes of max-data. We restrict 'len'
- * value which is 8Kbytes for various 'get' commands to 2000. 48 bytes are
+ * value which is 8Kbytes for various 'get' commands to 1990. 58 bytes are
* left for sw headers and misc.
*/
-
- if (len > 2000) {
- DHD_ERROR(("dhdcdc_query_ioctl: len is truncated to 2000 bytes\n"));
- len = 2000;
+ if (len > 1990) {
+ DHD_ERROR(("dhdcdc_query_ioctl: len is truncated from %d to 1990 bytes\n", len));
+ len = 1990;
}
-#ifdef BCMQT
- /* WAR: packet length limited for SPI host issue in FIFO mode on Zebu */
- if (len > 460) {
- DHD_ERROR(("len is truncated to 460 bytes on Zebu\n"));
- len = 460;
- }
-#endif /* BCMQT */
#endif /* BCMSPI */
msg->cmd = htol32(cmd);
msg->len = htol32(len);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
index 680bc6d..d56ea16 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -1,9 +1,9 @@
/*
* Broadcom Dongle Host Driver (DHD), common DHD core.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -116,8 +116,7 @@
#ifdef DHD_LOG_PRINT_RATE_LIMIT
int log_print_threshold = 0;
#endif /* DHD_LOG_PRINT_RATE_LIMIT */
-int dhd_msg_level = DHD_ERROR_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL
-//int dhd_msg_level = DHD_ERROR_VAL | DHD_EVENT_VAL
+uint dhd_msg_level = DHD_ERROR_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL
/* For CUSTOMER_HW4 do not enable DHD_IOVAR_MEM_VAL by default */
#if !defined(BOARD_HIKEY)
| DHD_IOVAR_MEM_VAL
@@ -143,6 +142,12 @@
#include <linux/pm_runtime.h>
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+
+#include <bcmiov.h>
+
#ifdef SOFTAP
char fw_path2[MOD_PARAM_PATHLEN];
extern bool softap_enabled;
@@ -3666,6 +3671,15 @@
}
break;
#endif /* BCMSDIO */
+#ifdef WL11AX
+ case WLC_E_TWT_SETUP:
+ case WLC_E_TWT_TEARDOWN:
+ DHD_EVENT(("%s: %u event received\n", __FUNCTION__, type));
+ if (wl_twt_event(dhd_pub, event, event_data)) {
+ DHD_ERROR(("%s: TWT event handling failure\n", __FUNCTION__));
+ }
+ break;
+#endif /* WL11AX */
case WLC_E_LINK:
#ifdef PCIE_FULL_DONGLE
if (dhd_update_interface_link_status(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info,
@@ -5835,8 +5849,14 @@
int32 i = 0;
uint8 *pfw_id = NULL;
uint32 fwid = 0;
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ const struct firmware *fw = NULL;
+ int err = 0;
+ uint fwid_size = 0;
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
void *file = NULL;
int file_len = 0;
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
char fwid_str[FWID_STR_LEN];
uint32 hdr_logstrs_size = 0;
@@ -5868,7 +5888,20 @@
/* For ver. 2 of the header, need to match fwid of
* both logstrs.bin and fw bin
*/
-
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ if (dhd_os_open_reqfw(&fw, st_str_file_path)) {
+ goto error;
+ }
+ memset(fwid_str, 0, sizeof(fwid_str));
+ fwid_size = sizeof(fwid_str) - 1;
+ err = memcpy_s(fwid_str, fwid_size, &(fw->data[fw->size - fwid_size]),
+ fwid_size);
+ if (err) {
+ DHD_ERROR(("%s: failed to copy data, err=%d\n",
+ __FUNCTION__, err));
+ goto error;
+ }
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
/* read the FWID from fw bin */
file = dhd_os_open_image1(NULL, st_str_file_path);
if (!file) {
@@ -5891,6 +5924,7 @@
DHD_ERROR(("%s: read fw file failed !\n", __FUNCTION__));
goto error;
}
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
pfw_id = (uint8 *)bcmstrnstr(fwid_str, sizeof(fwid_str) - 1,
FWID_STR_1, strlen(FWID_STR_1));
if (!pfw_id) {
@@ -5928,9 +5962,14 @@
hdr_logstrs_size = hdr->logstrs_size;
error:
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ if (fw)
+ release_firmware(fw);
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
if (file) {
dhd_os_close_image1(NULL, file);
}
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
if (match_fail) {
return BCME_DECERR;
}
@@ -5999,6 +6038,11 @@
char * cptr = NULL;
char c;
uint8 count = 0;
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ const struct firmware *fw = file;
+ uint32 offset = 0;
+ uint32 size = (uint32)fw->size;
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
*ramstart = 0;
*rodata_start = 0;
@@ -6014,12 +6058,25 @@
/* read ram start, rodata_start and rodata_end values from map file */
while (count != ALL_MAP_VAL)
{
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ if ((offset + read_size) > size) {
+ read_size = size - offset;
+ }
+
+ error = memcpy_s(raw_fmts, read_size, ((char *)(fw->data) + offset), read_size);
+
+ if (error) {
+ DHD_ERROR(("%s: Failed to copy data, err=%d\n", __FUNCTION__, error));
+ goto fail;
+ }
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
error = dhd_os_read_file(file, raw_fmts, read_size);
if (error < 0) {
DHD_ERROR(("%s: map file read failed err:%d \n", __FUNCTION__,
error));
goto fail;
}
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
/* End raw_fmts with NULL as strstr expects NULL terminated strings */
raw_fmts[read_size] = '\0';
@@ -6054,6 +6111,13 @@
count |= RDEND_BIT;
}
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+ if ((offset + read_size) >= size) {
+ break;
+ }
+ memset(raw_fmts, 0, read_size);
+ offset += (read_size - GO_BACK_FILE_POS_NUM_BYTES);
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
if (error < (int)read_size) {
/*
* since we reset file pos back to earlier pos by
@@ -6070,6 +6134,7 @@
* the string and addr even if it comes as splited in next read.
*/
dhd_os_seek_file(file, -GO_BACK_FILE_POS_NUM_BYTES);
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
}
fail:
@@ -7844,3 +7909,87 @@
return ret;
}
#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+int
+dhd_control_mbo_enab(dhd_pub_t * dhd, uint8 enable)
+{
+ int ret = BCME_OK;
+ uint8 *pxtlv_data = NULL;
+ bcm_iov_buf_t *iov_buf = NULL;
+ uint8 buf_xtlv[WLC_IOCTL_SMLEN] = {0x0};
+ uint16 buflen = 0, buflen_start = 0;
+
+ iov_buf = (bcm_iov_buf_t *)buf_xtlv;
+ iov_buf->version = WL_MBO_IOV_VERSION;
+ iov_buf->id = WL_MBO_CMD_ENABLE;
+
+ pxtlv_data = (uint8 *)&iov_buf->data[0];
+ buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+ ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_MBO_XTLV_ENABLE,
+ sizeof(enable), &enable, BCM_XTLV_OPTION_ALIGN32);
+
+ if (ret != BCME_OK) {
+ ret = -EINVAL;
+ DHD_ERROR(("%s failed to pack mbo enab, err: %s\n",
+ __FUNCTION__, bcmerrorstr(ret)));
+ return ret;
+ }
+
+ iov_buf->len = buflen_start - buflen;
+
+ ret = dhd_iovar(dhd, 0, "mbo", (char *)&buf_xtlv, sizeof(buf_xtlv), NULL, 0, TRUE);
+
+ if (ret < 0) {
+ DHD_ERROR(("%s mbo_enab (%d) set failed, err: %s\n",
+ __FUNCTION__, enable, bcmerrorstr(ret)));
+ } else {
+ DHD_ERROR(("%s mbo_enab (%d) set successed\n", __FUNCTION__, enable));
+ }
+
+ return ret;
+}
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
+
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+int
+dhd_control_oce_enab(dhd_pub_t * dhd, uint8 enable)
+{
+ int ret = BCME_OK;
+ uint8 *pxtlv_data = NULL;
+ bcm_iov_buf_t *iov_buf = NULL;
+ uint8 buf_xtlv[WLC_IOCTL_SMLEN] = {0x0};
+ uint16 buflen = 0, buflen_start = 0;
+
+ iov_buf = (bcm_iov_buf_t *)buf_xtlv;
+ iov_buf->version = WL_OCE_IOV_VERSION;
+ iov_buf->id = WL_OCE_CMD_ENABLE;
+
+ pxtlv_data = (uint8 *)&iov_buf->data[0];
+ buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+ ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+ sizeof(enable), &enable, BCM_XTLV_OPTION_ALIGN32);
+
+ if (ret != BCME_OK) {
+ ret = -EINVAL;
+ DHD_ERROR(("%s failed to pack oce enab, err: %s\n",
+ __FUNCTION__, bcmerrorstr(ret)));
+ return ret;
+ }
+
+ iov_buf->len = buflen_start - buflen;
+
+ ret = dhd_iovar(dhd, 0, "oce", (char *)&buf_xtlv, sizeof(buf_xtlv), NULL, 0, TRUE);
+
+ if (ret < 0) {
+ DHD_ERROR(("%s oce_enab (%d) set failed, err: %s\n",
+ __FUNCTION__, enable, bcmerrorstr(ret)));
+ } else {
+ DHD_ERROR(("%s oce_enab (%d) set successed\n", __FUNCTION__, enable));
+ }
+
+ return ret;
+}
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
old mode 100644
new mode 100755
index f6dba15..8a203dc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -1,9 +1,9 @@
/*
* Debug/trace/assert driver definitions for Dongle Host Driver.
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -366,7 +366,7 @@
#define DHD_BLOG(cp, size)
#define DHD_NONE(args)
-extern int dhd_msg_level;
+extern uint dhd_msg_level;
#ifdef DHD_LOG_PRINT_RATE_LIMIT
extern int log_print_threshold;
#endif /* DHD_LOG_PRINT_RATE_LIMIT */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
index 57317ce..9de2b7d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
@@ -3,9 +3,9 @@
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -1601,8 +1601,12 @@
alloc_len = sizeof(*tx_report);
MFREE(dhdp->osh, tx_report, alloc_len);
}
- dhdp->dbg->pkt_mon.tx_report = NULL;
- dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+ if (dhdp->dbg->pkt_mon.tx_report) {
+ if (dhdp->dbg->pkt_mon.tx_report->tx_pkts) {
+ dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+ }
+ dhdp->dbg->pkt_mon.tx_report = NULL;
+ }
dhdp->dbg->pkt_mon.tx_pkt_mon = NULL;
dhdp->dbg->pkt_mon.tx_status_mon = NULL;
dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_DETACHED;
@@ -1617,8 +1621,12 @@
alloc_len = sizeof(*rx_report);
MFREE(dhdp->osh, rx_report, alloc_len);
}
- dhdp->dbg->pkt_mon.rx_report = NULL;
- dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+ if (dhdp->dbg->pkt_mon.rx_report) {
+ if (dhdp->dbg->pkt_mon.rx_report->rx_pkts) {
+ dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+ }
+ dhdp->dbg->pkt_mon.rx_report = NULL;
+ }
dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_DETACHED;
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
index cb9bf49..66c829d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -2,9 +2,9 @@
* Broadcom Dongle Host Driver (DHD), Linux-specific network interface
* Basically selected code segments from usb-cdc.c and usb-rndis.c
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -172,6 +172,10 @@
#include <dhd_linux_nfct.h>
#endif /* WL_NATOE */
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL_11AX */
+
#if defined(OEM_ANDROID) && defined(SOFTAP)
extern bool ap_cfg_running;
extern bool ap_fw_loaded;
@@ -387,6 +391,13 @@
#endif /* BCMPCIE */
#endif /* OEM_ANDROID */
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+struct dhd_firmware_req {
+ const struct firmware *fw;
+ unsigned long offset;
+};
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
+
dhd_pub_t *g_dhd_pub = NULL;
#if defined(BT_OVER_SDIO)
@@ -503,7 +514,7 @@
#endif /* DHD_WET || DHD_MCAST_REGEN || DHD_L2_FILTER */
/* Error bits */
-module_param(dhd_msg_level, int, 0);
+module_param(dhd_msg_level, uint, 0);
#ifdef ARP_OFFLOAD_SUPPORT
/* ARP offload enable */
@@ -633,6 +644,12 @@
uint32 hw_module_variant = 0;
module_param(hw_module_variant, uint, 0644);
+/* Specify pcie device bus name param as shown below
+ * pcie_dev_bus_name='"PCI Bus 0001:01"'
+ */
+char pcie_dev_bus_name[MOD_PARAM_INFOLEN];
+module_param_string(pcie_dev_bus_name, pcie_dev_bus_name, MOD_PARAM_INFOLEN, 0444);
+
#if defined(DHD_LB_RXP)
static int dhd_napi_weight = 32;
module_param(dhd_napi_weight, int, 0644);
@@ -666,7 +683,13 @@
#endif /* FORCE_TPOWERON */
#ifdef SHOW_LOGTRACE
-#if defined(CUSTOMER_HW4_DEBUG)
+#if defined(DHD_SUPPORT_REQFW_FOR_EVTLOG)
+static char *logstrs_path = "logstrs.bin";
+char *st_str_file_path = "rtecdc.bin";
+static char *map_file_path = "rtecdc.map";
+static char *rom_st_str_file_path = "roml.bin";
+static char *rom_map_file_path = "roml.map";
+#elif defined(CUSTOMER_HW4_DEBUG)
static char *logstrs_path = PLATFORM_PATH"logstrs.bin";
char *st_str_file_path = PLATFORM_PATH"rtecdc.bin";
static char *map_file_path = PLATFORM_PATH"rtecdc.map";
@@ -2454,13 +2477,17 @@
dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
{
int i = 0;
-
+#ifdef WL_STATIC_IF
+ int max_ifs = DHD_MAX_IFS + DHD_MAX_STATIC_IFS;
+#else
+ int max_ifs = DHD_MAX_IFS;
+#endif // endif
if (!dhd) {
DHD_ERROR(("%s : DHD_BAD_IF return\n", __FUNCTION__));
return DHD_BAD_IF;
}
- while (i < DHD_MAX_IFS) {
+ while (i < max_ifs) {
if (dhd->iflist[i] && dhd->iflist[i]->net && (dhd->iflist[i]->net == net))
return i;
i++;
@@ -2717,6 +2744,11 @@
_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr)
{
int ret;
+#ifdef P2P_RAND
+ struct bcm_cfg80211 *cfg = NULL;
+ s16 bssidx = 0;
+ s32 cfg_type = BCME_ERROR;
+#endif /* P2P_RAND */
ret = dhd_iovar(&dhd->pub, ifidx, "cur_etheraddr", (char *)addr,
ETHER_ADDR_LEN, NULL, 0, TRUE);
@@ -2726,6 +2758,25 @@
memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN);
if (ifidx == 0)
memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN);
+#ifdef P2P_RAND
+ //Update p2p mac in cfg bss
+ cfg = wl_get_cfg(dhd->iflist[ifidx]->net);
+ if (!cfg) {
+ DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+ return ret;
+ }
+ bssidx = wl_get_bssidx_by_wdev(cfg, ndev_to_wdev(dhd->iflist[ifidx]->net));
+ if (bssidx > 0) {
+ if (wl_cfgp2p_find_type(cfg, bssidx, &cfg_type) == BCME_OK) {
+ ret = memcpy_s(wl_to_p2p_bss_macaddr(cfg, cfg_type),
+ ETHER_ADDR_LEN, addr, ETHER_ADDR_LEN);
+ if (ret) {
+ DHD_ERROR(("%s: P2P CFG MAC copy fail\n", __FUNCTION__));
+ return ret;
+ }
+ }
+ }
+#endif /* P2P_RAND */
}
return ret;
@@ -3098,10 +3149,19 @@
int ret = 0;
dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#if defined(WL_STATIC_IF) && defined(SOFTAP_RAND)
+ struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif /* WL_STATIC_IF && SOFTAP_RAND */
struct sockaddr *sa = (struct sockaddr *)addr;
int ifidx;
dhd_if_t *dhdif;
-
+#if defined(SOFTAP_RAND)
+ if (!ETHER_IS_LOCALADDR(sa->sa_data)) {
+ DHD_ERROR(("%s: locally administered not set" MACDBG "\n", __FUNCTION__,
+ MAC2STRDBG(sa->sa_data)));
+ return -1;
+ }
+#endif /* SOFTAP_RAND */
ifidx = dhd_net2idx(dhd, dev);
if (ifidx == DHD_BAD_IF)
return -1;
@@ -3112,6 +3172,16 @@
memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
dhdif->set_macaddress = TRUE;
dhd_net_if_unlock_local(dhd);
+
+#if defined(WL_STATIC_IF) && defined(SOFTAP_RAND)
+ if (dhd_is_static_ndev(&dhd->pub, dev) &&
+ static_if_ndev_get_state(cfg, dev) == NDEV_STATE_OS_IF_CREATED) {
+ /* In case of SoftAP, save random MAC as FW interface is not created in ndev.
+ */
+ (void)memcpy_s(dev->dev_addr, ETH_ALEN, dhdif->mac_addr, ETH_ALEN);
+ return ret;
+ }
+#endif /* WL_STATIC_IF && SOFTAP_RAND */
#ifdef DHD_DIRECT_SET_MAC
/* It needs to update new mac address on this context */
ret = _dhd_set_mac_address(dhd, ifidx, dhdif->mac_addr);
@@ -5651,7 +5721,7 @@
/* Copy out any request driver name */
if (copy_from_user(&info, uaddr, sizeof(info)))
return -EFAULT;
- strncpy(drvname, info.driver, sizeof(info.driver));
+ strncpy(drvname, info.driver, sizeof(drvname));
drvname[sizeof(info.driver)-1] = '\0';
/* clear struct for return */
@@ -6381,6 +6451,14 @@
return OSL_ERROR(bcmerror);
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static int
+dhd_ioctl_private(struct net_device *net, struct ifreq *ifr,
+ void __user *data, int cmd) {
+ return dhd_ioctl_entry(net, ifr, cmd);
+}
+#endif // endif
+
#if defined(WL_CFG80211) && defined(SUPPORT_DEEP_SLEEP)
/* Flags to indicate if we distingish power off policy when
* user set the memu "Keep Wi-Fi on during sleep" to "Never"
@@ -6582,6 +6660,11 @@
dhd_rtt_deinit(&dhd->pub);
}
#endif /* RTT_SUPPORT */
+#ifdef WL11AX
+ if (dhd->pub.twt_ctx) {
+ dhd_twt_deinit(&dhd->pub);
+ }
+#endif /* WL11AX */
ret = dhd_bus_devreset(dhdp, TRUE);
if (!ret) {
dhd_bus_suspend(dhdp);
@@ -6699,6 +6782,7 @@
unsigned long flags = 0;
#ifdef WL_STATIC_IF
struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+ int i = 0;
#endif /* WL_STATIC_IF */
#endif /* WL_CFG80211 */
dhd_info_t *dhd = DHD_DEV_INFO(net);
@@ -6739,12 +6823,15 @@
#if defined(WL_STATIC_IF) && defined(WL_CFG80211)
/* If static if is operational, don't reset the chip */
- if (static_if_ndev_get_state(cfg, net) == NDEV_STATE_FW_IF_CREATED) {
- DHD_ERROR(("static if operational. skip chip reset.\n"));
- skip_reset = true;
- wl_cfg80211_sta_ifdown(net);
- goto exit;
+ for (i = 0; i < DHD_NUM_STATIC_IFACES; i++) {
+ if ((cfg && (cfg->static_ndev_state[i] == NDEV_STATE_FW_IF_CREATED))) {
+ DHD_ERROR(("static if operational. skip chip reset.\n"));
+ skip_reset = true;
+ wl_cfg80211_sta_ifdown(net);
+ goto exit;
+ }
}
+
#endif /* WL_STATIC_IF && WL_CFG80211 */
#if defined(WL_VIF_SUPPORT)
@@ -7349,11 +7436,17 @@
struct bcm_cfg80211 *cfg;
struct net_device *primary_netdev = NULL;
+#if defined(SOFTAP_RAND)
+ dhd_info_t *dhd = DHD_DEV_INFO(net);
+ dhd_if_t *ifp;
+#endif /* SOFTAP_RAND */
cfg = wl_get_cfg(net);
primary_netdev = bcmcfg_to_prmry_ndev(cfg);
if (!is_static_iface(cfg, net)) {
DHD_TRACE(("non-static interface (%s)..do nothing \n", net->name));
+ /* Allow transmit calls for non-static iface */
+ netif_start_queue(net);
ret = BCME_OK;
goto done;
}
@@ -7367,8 +7460,17 @@
DHD_ERROR(("Failed to open primary dev ret %d\n", ret));
goto done;
}
-
- ret = wl_cfg80211_static_if_open(net);
+#if defined(SOFTAP_RAND)
+ ifp = dhd_get_ifp_by_ndev(&dhd->pub, net);
+ if (ifp && ifp->set_macaddress) {
+ ret = wl_cfg80211_static_if_open(net, net->dev_addr);
+ ifp->set_macaddress = FALSE;
+ } else {
+ ret = wl_cfg80211_static_if_open(net, NULL);
+ }
+#else
+ ret = wl_cfg80211_static_if_open(net, NULL);
+#endif /* SOFTAP_RAND */
if (!ret) {
/* Allow transmit calls */
netif_start_queue(net);
@@ -8047,6 +8149,10 @@
#else
.ndo_set_multicast_list = dhd_set_multicast_list,
#endif // endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+ .ndo_siocdevprivate = dhd_ioctl_private,
+#endif // endif
+
};
static struct net_device_ops dhd_ops_virt = {
@@ -8068,6 +8174,9 @@
#else
.ndo_set_multicast_list = dhd_set_multicast_list,
#endif // endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+ .ndo_siocdevprivate = dhd_ioctl_private,
+#endif // endif
};
int
@@ -8111,6 +8220,177 @@
return 0;
}
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+static int
+dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
+{
+ const struct firmware *fw = NULL;
+ int ret = BCME_ERROR;
+ char *raw_fmts = NULL;
+ int logstrs_size = 0;
+
+ ret = dhd_os_open_reqfw(&fw, logstrs_path);
+ if (ret) {
+ goto exit;
+ }
+
+ logstrs_size = (int)fw->size;
+
+ if (logstrs_size == 0) {
+ DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+ goto exit;
+ }
+
+ raw_fmts = MALLOC(osh, logstrs_size);
+ if (raw_fmts == NULL) {
+ DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__));
+ ret = BCME_NOMEM;
+ goto exit;
+ }
+
+ ret = memcpy_s(raw_fmts, logstrs_size, (char *)(fw->data), logstrs_size);
+ if (ret) {
+ DHD_ERROR(("%s: Failed to copy fw data, err=%d\n", __FUNCTION__, ret));
+ ret = BCME_ERROR;
+ goto exit;
+ }
+
+ ret = dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp);
+
+exit:
+ if (fw)
+ release_firmware(fw);
+
+ if (ret != BCME_OK) {
+ if (raw_fmts) {
+ MFREE(osh, raw_fmts, logstrs_size);
+ raw_fmts = NULL;
+ }
+
+ temp->fmts = NULL;
+ }
+
+ return ret;
+}
+
+static int
+dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
+ uint32 *rodata_end)
+{
+ const struct firmware *fw = NULL;
+ int ret = BCME_ERROR;
+
+ if (fname == NULL) {
+ DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__));
+ goto fail;
+ }
+
+ ret = dhd_os_open_reqfw(&fw, fname);
+ if (ret) {
+ goto fail;
+ }
+
+ if ((ret = dhd_parse_map_file(osh, (struct firmware *)fw, ramstart,
+ rodata_start, rodata_end)) < 0)
+ goto fail;
+
+fail:
+ if (fw) {
+ release_firmware(fw);
+ }
+
+ return ret;
+}
+
+static int
+dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file)
+{
+ const struct firmware *fw = NULL;
+ char *raw_fmts = NULL;
+ uint32 logstrs_size = 0;
+ int ret = BCME_OK;
+ uint32 ramstart = 0;
+ uint32 rodata_start = 0;
+ uint32 rodata_end = 0;
+ uint32 logfilebase = 0;
+
+ ret = dhd_read_map(osh, map_file, &ramstart, &rodata_start, &rodata_end);
+ if (ret != BCME_OK) {
+ DHD_ERROR(("readmap Error!! \n"));
+ /* don't do event log parsing in actual case */
+ if (strstr(str_file, ram_file_str) != NULL) {
+ temp->raw_sstr = NULL;
+ } else if (strstr(str_file, rom_file_str) != NULL) {
+ temp->rom_raw_sstr = NULL;
+ }
+ goto exit;
+ }
+ DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n",
+ ramstart, rodata_start, rodata_end));
+
+ ret = dhd_os_open_reqfw(&fw, str_file);
+ if (ret) {
+ goto exit;
+ }
+
+ /* Full file size is huge. Just read required part */
+ logstrs_size = rodata_end - rodata_start;
+ logfilebase = rodata_start - ramstart;
+
+ if (logstrs_size == 0) {
+ DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+ ret = BCME_ERROR;
+ goto exit;
+ }
+
+ raw_fmts = MALLOC(osh, logstrs_size);
+ if (raw_fmts == NULL) {
+ DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+ ret = BCME_NOMEM;
+ goto exit;
+ }
+
+ ret = memcpy_s(raw_fmts, logstrs_size, (char *)((fw->data) + logfilebase),
+ logstrs_size);
+
+ if (ret) {
+ DHD_ERROR(("%s: Failed to copy data, err=%d\n", __FUNCTION__, ret));
+ ret = BCME_ERROR;
+ goto exit;
+ }
+
+ if (strstr(str_file, ram_file_str) != NULL) {
+ temp->raw_sstr = raw_fmts;
+ temp->raw_sstr_size = logstrs_size;
+ temp->rodata_start = rodata_start;
+ temp->rodata_end = rodata_end;
+ } else if (strstr(str_file, rom_file_str) != NULL) {
+ temp->rom_raw_sstr = raw_fmts;
+ temp->rom_raw_sstr_size = logstrs_size;
+ temp->rom_rodata_start = rodata_start;
+ temp->rom_rodata_end = rodata_end;
+ }
+
+exit:
+ if (fw)
+ release_firmware(fw);
+
+ if (ret != BCME_OK) {
+ if (raw_fmts) {
+ MFREE(osh, raw_fmts, logstrs_size);
+ raw_fmts = NULL;
+ }
+
+ if (strstr(str_file, ram_file_str) != NULL) {
+ temp->raw_sstr = NULL;
+ } else if (strstr(str_file, rom_file_str) != NULL) {
+ temp->rom_raw_sstr = NULL;
+ }
+ }
+
+ return ret;
+}
+#else /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
static int
dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
{
@@ -8343,7 +8623,7 @@
return error;
} /* dhd_init_static_strs_array */
-
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
#endif /* SHOW_LOGTRACE */
#ifdef DHD_ERPOM
@@ -8423,7 +8703,7 @@
#ifdef DHD_DISABLE_FWLOG_IN_CHIPBOOT
dhd_msg_level = (dhd_msg_level & (~DHD_FWLOG_VAL));
- DHD_ERROR(("%s , dhd_msg_level: 0x%x\n",__FUNCTION__,dhd_msg_level));
+ DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
#endif
#ifdef PCIE_FULL_DONGLE
ASSERT(sizeof(dhd_pkttag_fd_t) <= OSL_PKTTAG_SZ);
@@ -9254,6 +9534,8 @@
config_chipid = BCM4335_CHIP_ID;
#elif defined(BCM43430_CHIP)
config_chipid = BCM43430_CHIP_ID;
+#elif defined(BCM43439_CHIP)
+ config_chipid = BCM43439_CHIP_ID;
#elif defined(BCM43018_CHIP)
config_chipid = BCM43018_CHIP_ID;
#elif defined(BCM43455_CHIP)
@@ -10091,6 +10373,10 @@
uint32 okc = 1;
#endif // endif
+#ifdef OCE_SUPPORT
+ uint8 oce_enable = 0;
+#endif //endif
+
#ifdef DISABLE_11N
uint32 nmode = 0;
#endif /* DISABLE_11N */
@@ -10542,6 +10828,44 @@
DHD_ERROR(("%s set const_awake_thresh failed %d\n", __FUNCTION__, ret));
}
#endif /* CUSTOM_EVENT_PM_WAKE */
+
+#ifdef OCE_SUPPORT
+ {
+ uint8 ioctl_buf[WLC_IOCTL_SMLEN] = {0};
+ uint8 oce_xtlv[WLC_IOCTL_SMLEN] = {0};
+ bcm_iov_buf_t *iov_buf = NULL;
+ uint8 *pxtlv_data = NULL;
+ uint16 buflen = 0, buflen_start = 0, iovlen = 0;
+ s32 iovar_len = 0;
+ struct wl_ioctl ioc;
+
+ memset(&ioc, 0, sizeof(ioc));
+ iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+ iov_buf->version = WL_OCE_IOV_VERSION;
+ iov_buf->id = WL_OCE_CMD_ENABLE;
+ pxtlv_data = (uint8 *)&iov_buf->data[0];
+ buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+ ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+ sizeof(oce_enable), &oce_enable, BCM_XTLV_OPTION_ALIGN32);
+ if (ret != BCME_OK) {
+ DHD_ERROR(("Failed to enable oce: %d\n", ret));
+ } else {
+ iov_buf->len = buflen_start - buflen;
+ iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len;
+ iovar_len = wldev_mkiovar_bsscfg("oce", (void *)iov_buf, iovlen, ioctl_buf, WLC_IOCTL_SMLEN, 0);
+ if (iovar_len > 0) {
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = (void *)ioctl_buf;
+ ioc.len = iovar_len;
+ ioc.set = 1;
+ ret = dhd_wl_ioctl(dhd, 0, (wl_ioctl_t *)&ioc, ioc.buf, ioc.len);
+ if (ret < 0)
+ DHD_ERROR(("%s set oce failed %d\n", __FUNCTION__, ret));
+ }
+ }
+ }
+#endif
+
#ifdef OKC_SUPPORT
ret = dhd_iovar(dhd, 0, "okc_enable", (char *)&okc, sizeof(okc), NULL, 0, TRUE);
#endif // endif
@@ -10892,7 +11216,14 @@
control_he_enab = 0;
#endif /* DISABLE_HE_ENAB */
dhd_control_he_enab(dhd, control_he_enab);
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+ if (!control_he_enab)
+ dhd_control_mbo_enab(dhd, FALSE);
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+ dhd_control_oce_enab(dhd, FALSE);
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
#ifdef CUSTOM_PSPRETEND_THR
/* Turn off MPC in AP mode */
@@ -11064,6 +11395,12 @@
setbit(eventmask_msg->mask, WLC_E_ROAM_EXP_EVENT);
#endif /* GSCAN_SUPPORT */
setbit(eventmask_msg->mask, WLC_E_RSSI_LQM);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ setbit(eventmask_msg->mask, WLC_E_RSSI);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+ setbit(eventmask_msg->mask, WLC_E_BCNLOST_MSG);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
#ifdef BT_WIFI_HANDOVER
setbit(eventmask_msg->mask, WLC_E_BT_WIFI_HANDOVER_REQ);
#endif /* BT_WIFI_HANDOVER */
@@ -11105,6 +11442,17 @@
setbit(eventmask_msg->mask, WLC_E_LDF_HOGGER);
#endif /* ENABLE_HOGSQS */
+#ifdef WL11AX
+ /* TWT Setup Complete Event */
+ setbit(eventmask_msg->mask, WLC_E_TWT_SETUP);
+
+ /* TWT Teardown Complete Event */
+ setbit(eventmask_msg->mask, WLC_E_TWT_TEARDOWN);
+#endif /* WL11AX */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ setbit(eventmask_msg->mask, WLC_E_EXT_ASSOC_FRAME_RX);
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+
/* over temp event */
setbit(eventmask_msg->mask, WLC_E_OVERTEMP);
@@ -11414,6 +11762,14 @@
}
}
#endif // endif
+#ifdef WL11AX
+ if (!dhd->twt_ctx) {
+ ret = wl_twt_init(dhd);
+ if (ret < 0) {
+ DHD_ERROR(("%s failed to initialize TWT\n", __FUNCTION__));
+ }
+ }
+#endif /* WL11AX */
#ifdef FILTER_IE
/* Failure to configure filter IE is not a fatal error, ignore it. */
if (!(dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE)))
@@ -12050,15 +12406,16 @@
net->netdev_ops = &dhd_ops_virt;
/* Ok, link into the network layer... */
- DHD_ERROR(("%s , ifidx: %d\n", __FUNCTION__, ifidx));
if (ifidx == 0) {
/*
* device functions for the primary interface only
*/
#ifdef DHD_DISABLE_FWLOG_IN_CHIPBOOT
- dhd_msg_level = (dhd_msg_level | (DHD_FWLOG_VAL));
- DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
+ dhd_msg_level = (dhd_msg_level | (DHD_FWLOG_VAL));
+ DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
#endif
+
+
net->netdev_ops = &dhd_ops_pri;
if (!ETHER_ISNULLADDR(dhd->pub.mac.octet))
memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
@@ -12587,6 +12944,11 @@
dhd_rtt_deinit(dhdp);
}
#endif // endif
+#ifdef WL11AX
+ if (dhdp->twt_ctx) {
+ wl_twt_deinit(dhdp);
+ }
+#endif /* WL11AX */
#if defined(CONFIG_PM_SLEEP)
if (dhd_pm_notifier_registered) {
unregister_pm_notifier(&dhd->pm_notifier);
@@ -12641,7 +13003,9 @@
}
#endif /* DHD_ERPOM */
+#if defined(OEM_ANDROID)
cancel_work_sync(&dhd->dhd_hang_process_work);
+#endif /* OEM_ANDROID */
/* Prefer adding de-init code above this comment unless necessary.
* The idea is to cancel work queue, sysfs and flags at the end.
@@ -13268,9 +13632,44 @@
#endif /* DHD_PCIE_RUNTIMEPM */
+#if defined(DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING) || \
+ defined(DHD_SUPPORT_REQFW_FOR_EVTLOG)
+int
+dhd_os_open_reqfw(const struct firmware **fw, char *filename)
+{
+ int ret = BCME_OK;
+
+ ret = request_firmware(fw, filename, dhd_bus_to_dev(g_dhd_pub->bus));
+
+ if (ret) {
+ DHD_ERROR(("%s] request_firmware error : %d\n", __FUNCTION__, ret));
+ ret = BCME_ERROR;
+ }
+
+ return ret;
+}
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING || DHD_SUPPORT_REQFW_FOR_EVTLOG */
void *
dhd_os_open_image1(dhd_pub_t *pub, char *filename)
{
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+ int ret = BCME_OK;
+ struct dhd_firmware_req *fw;
+
+ fw = kmalloc(sizeof(struct dhd_firmware_req), GFP_ATOMIC);
+ if (fw) {
+ ret = dhd_os_open_reqfw(&fw->fw, filename);
+ if (!ret) {
+ fw->offset = 0;
+ }
+ else {
+ kfree(fw);
+ fw = NULL;
+ }
+ }
+
+ return (void *)fw;
+#else
struct file *fp;
int size;
@@ -13303,11 +13702,35 @@
err:
return fp;
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
}
int
dhd_os_get_image_block(char *buf, int len, void *image)
{
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+ struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+ const struct firmware *fw;
+ unsigned long length;
+
+ if (!dhd_fw)
+ return 0;
+
+ fw = dhd_fw->fw;
+ if (!fw)
+ return 0;
+
+ if (dhd_fw->offset + len < fw->size) {
+ length = len;
+ }
+ else {
+ length = fw->size - dhd_fw->offset;
+ }
+ memcpy(buf, &fw->data[dhd_fw->offset], length);
+ dhd_fw->offset += length;
+
+ return length;
+#else
struct file *fp = (struct file *)image;
int rdlen;
int size;
@@ -13328,6 +13751,7 @@
}
return rdlen;
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
}
#if defined(BT_OVER_SDIO)
@@ -13361,6 +13785,19 @@
int
dhd_os_get_image_size(void *image)
{
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+ struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+ const struct firmware *fw;
+
+ if (!dhd_fw)
+ return 0;
+
+ fw = dhd_fw->fw;
+ if (!fw)
+ return 0;
+
+ return fw->size;
+#else
struct file *fp = (struct file *)image;
int size;
if (!image) {
@@ -13370,14 +13807,26 @@
size = i_size_read(file_inode(fp));
return size;
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
}
void
dhd_os_close_image1(dhd_pub_t *pub, void *image)
{
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+ struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+
+ if (dhd_fw) {
+ if (dhd_fw->fw) {
+ release_firmware(dhd_fw->fw);
+ }
+ kfree(dhd_fw);
+ }
+#else
if (image) {
filp_close((struct file *)image, NULL);
}
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
}
void
@@ -14828,7 +15277,7 @@
int
dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pkt,
- uint16 ip_pkt_len, uint8* src_mac, uint8* dst_mac, uint32 period_msec)
+ uint16 ip_pkt_len, uint8* src_mac, uint8* dst_mac, uint32 period_msec, uint16 ether_type)
{
const int ETHERTYPE_LEN = 2;
char *pbuf = NULL;
@@ -14933,9 +15382,10 @@
memcpy(pmac_frame, src_mac, ETHER_ADDR_LEN);
pmac_frame += ETHER_ADDR_LEN;
- /* Mapping Ethernet type (ETHERTYPE_IP: 0x0800) */
- *(pmac_frame++) = 0x08;
- *(pmac_frame++) = 0x00;
+ /* Mapping Ethernet type */
+ ether_type = hton16(ether_type);
+ memcpy(pmac_frame, ðer_type, ETHERTYPE_LEN);
+ pmac_frame += ETHERTYPE_LEN;
/* Mapping IP pkt */
memcpy(pmac_frame, ip_pkt, ip_pkt_len);
@@ -22327,8 +22777,11 @@
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b)
-#else
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b, c)
+#else
+#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(mnt_user_ns(file_path.mnt), \
+ DHD_VFS_INODE(dir), b, c)
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
int
dhd_file_delete(char *path)
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
index f3ff91d..68b6199 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
@@ -2,9 +2,9 @@
* Broadcom Dongle Host Driver (DHD), Linux-specific network interface
* Basically selected code segments from usb-cdc.c and usb-rndis.c
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -828,13 +828,21 @@
container_of(work, struct dhd_info, tx_compl_dispatcher_work);
int cpu;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
get_online_cpus();
+#else
+ cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
cpu = atomic_read(&dhd->tx_compl_cpu);
if (!cpu_online(cpu))
dhd_tasklet_schedule(&dhd->tx_compl_tasklet);
else
dhd_tasklet_schedule_on(&dhd->tx_compl_tasklet, cpu);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
put_online_cpus();
+#else
+ cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
}
#endif /* DHD_LB_TXC */
@@ -880,14 +888,22 @@
container_of(work, struct dhd_info, rx_compl_dispatcher_work);
int cpu;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
get_online_cpus();
+#else
+ cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
cpu = atomic_read(&dhd->rx_compl_cpu);
if (!cpu_online(cpu))
dhd_tasklet_schedule(&dhd->rx_compl_tasklet);
else {
dhd_tasklet_schedule_on(&dhd->rx_compl_tasklet, cpu);
}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
put_online_cpus();
+#else
+ cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
}
#endif /* DHD_LB_RXC */
@@ -1124,7 +1140,11 @@
#endif // endif
int cpu;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
get_online_cpus();
+#else
+ cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
cpu = atomic_read(&dhd->rx_napi_cpu);
if (!cpu_online(cpu))
@@ -1132,7 +1152,11 @@
else
dhd_napi_schedule_on(dhd, cpu);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
put_online_cpus();
+#else
+ cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
}
/**
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
index 7c0e53e..ca80439 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
@@ -1,9 +1,9 @@
/*
* DHD Linux header file - contains private structure definition of the Linux specific layer
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -52,6 +52,15 @@
#include <dhd_flowring.h>
#endif /* PCIE_FULL_DONGLE */
+#if defined(DHD_SUPPORT_REQFW_FOR_EVTLOG) || \
+ defined(DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING)
+#include <linux/firmware.h>
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG || DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
+
+#if defined(CONFIG_PM_WAKELOCKS)
+#undef CONFIG_PM_WAKELOCKS
+#endif
+
/*
* Do not include this header except for the dhd_linux.c dhd_linux_sysfs.c
* Local private structure (extension of pub)
@@ -427,4 +436,7 @@
void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask);
#endif /* DHD_LB_IRQSET || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+int dhd_os_open_reqfw(const struct firmware **fw, char *filename);
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
#endif /* __DHD_LINUX_PRIV_H__ */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
index 3cf7267..b4e14ce 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
@@ -1,9 +1,9 @@
/*
* DHD Bus Module for PCIE
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -682,8 +682,7 @@
si_chipid(bus->sih) == BCM4375_CHIP_ID ||
si_chipid(bus->sih) == BCM4362_CHIP_ID ||
si_chipid(bus->sih) == BCM43751_CHIP_ID ||
- si_chipid(bus->sih) == BCM4361_CHIP_ID ||
- si_chipid(bus->sih) == CYW55560_CHIP_ID) {
+ si_chipid(bus->sih) == BCM4361_CHIP_ID) {
return FALSE;
} else {
return TRUE;
@@ -3459,7 +3458,6 @@
uint readlen = 0;
uint i = 0;
- DHD_ERROR(("dhdpcie_bus_readconsole\n"));
if (!DHD_FWLOG_ON())
return 0;
@@ -3512,7 +3510,6 @@
* important to handle wrap-around.
*/
addr = ltoh32(c->log.buf);
- DHD_ERROR(("addr 0x%x\n", addr));
/* wrap around case - write ptr < read ptr */
if (idx < c->last) {
@@ -3543,7 +3540,6 @@
/* update read ptr */
c->last = idx;
- DHD_ERROR(("last 0x%x\n", idx));
/* now output the read data from the local buffer to the host console */
while (i < readlen) {
for (n = 0; n < CONSOLE_LINE_MAX - 2 && i < readlen; n++) {
@@ -3562,7 +3558,6 @@
}
}
- DHD_ERROR(("read console finish\n"));
return BCME_OK;
} /* dhdpcie_bus_readconsole */
@@ -7329,7 +7324,6 @@
bool do_flr;
hs_addrs_t bl_hs_addrs = {NULL, NULL};
- DHD_ERROR(("dhdpcie_bus_download_state\n"));
if (bus->sih->chip == CYW55560_CHIP_ID) {
/* Host bootloader handshake TCM/REGS addresses init */
bcmerror = dhdpcie_dongle_host_get_handshake_address(bus->sih, bus->osh,
@@ -7359,7 +7353,6 @@
#ifndef BCMQT /* for performance reasons, skip the FLR for QT */
#endif /* !BCMQT */
- DHD_ERROR(("dhdpcie_bus_download_state enter\n"));
/* Make sure BAR1 maps to backplane address 0 */
dhdpcie_setbar1win(bus, 0x00000000);
bus->alp_only = TRUE;
@@ -7437,7 +7430,6 @@
__FUNCTION__));
}
- DHD_ERROR(("dhdpcie_bus_download_state 1\n"));
/* Console buffer read - First pass */
if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
DHD_ERROR(("%s: First pass console buffer read failed\n",
@@ -7461,10 +7453,8 @@
}
}
} else {
- DHD_ERROR(("dhdpcie_bus_download_state not enter\n"));
if (si_setcore(bus->sih, ARMCA7_CORE_ID, 0)) {
/* write vars */
- DHD_ERROR(("dhdpcie_bus_download_state ca7\n"));
if ((bcmerror = dhdpcie_bus_write_vars(bus))) {
DHD_ERROR(("%s: could not write vars to RAM\n", __FUNCTION__));
goto fail;
@@ -7488,7 +7478,6 @@
(uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
/* now remove reset and halt and continue to run CA7 */
} else if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
- DHD_ERROR(("dhdpcie_bus_download_state cr4\n"));
if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__));
bcmerror = BCME_ERROR;
@@ -7518,7 +7507,6 @@
goto fail;
}
} else {
- DHD_ERROR(("dhdpcie_bus_download_state oth\n"));
if (BCM43602_CHIP(bus->sih->chip)) {
/* Firmware crashes on SOCSRAM access when core is in reset */
if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
@@ -7533,7 +7521,6 @@
if (bus->sih->chip == CYW55560_CHIP_ID) {
/* Console buffer read - Second pass */
- DHD_ERROR(("dhdpcie_bus_download_state 2\n"));
if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
DHD_ERROR(("%s: Second pass console buffer read failed\n",
__FUNCTION__));
@@ -7612,7 +7599,6 @@
/* now remove reset and halt and continue to run CR4 */
}
- DHD_ERROR(("dhdpcie_bus_download_state 55560\n"));
if (bus->sih->chip == CYW55560_CHIP_ID) {
/* Console buffer read - Final pass */
if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
@@ -7647,7 +7633,6 @@
__FUNCTION__));
} else {
/* Console buffer read */
- DHD_ERROR(("dhdpcie_bus_download_state 4\n"));
if (dhdpcie_bus_readconsole(bus) < 0) {
DHD_ERROR(("%s: Failure case console buffer read failed\n",
__FUNCTION__));
@@ -7663,7 +7648,6 @@
dhd_bus_pcie_pwr_req_clear(bus);
}
- DHD_ERROR(("dhdpcie_bus_download_state exit\n"));
return bcmerror;
} /* dhdpcie_bus_download_state */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
old mode 100644
new mode 100755
index 426afe7..32be7b1
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
@@ -1,9 +1,9 @@
/*
* Linux DHD Bus Module for PCIE
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -267,6 +267,7 @@
#endif /* DHD_PCIE_RUNTIMEPM || DHD_PCIE_NATIVE_RUNTIMEPM */
};
+extern char pcie_dev_bus_name[MOD_PARAM_INFOLEN];
int dhdpcie_init_succeeded = FALSE;
#ifdef USE_SMMU_ARCH_MSM
@@ -1042,10 +1043,23 @@
{
int err = 0;
dhdpcie_info_t *pch = pci_get_drvdata(dev);
+
+ DHD_ERROR(("%s: Enter\n", __FUNCTION__));
+
+ err = pci_set_power_state(dev, PCI_D0);
+ if (err) {
+ printf("%s:pci_set_power_state error %d \n", __FUNCTION__, err);
+ goto out;
+ }
+ err = pci_enable_device(dev);
+ if (err) {
+ printf("%s:pci_enable_device error %d \n", __FUNCTION__, err);
+ goto out;
+ }
+ pci_set_master(dev);
#if defined(OEM_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
pci_load_and_free_saved_state(dev, &pch->state);
#endif /* OEM_ANDROID && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
- DHD_ERROR(("%s: Enter\n", __FUNCTION__));
#ifdef OEM_ANDROID
dev->state_saved = TRUE;
#endif /* OEM_ANDROID */
@@ -1055,17 +1069,6 @@
dhd_bus_set_tpoweron(pch->bus, tpoweron_scale);
}
#endif /* FORCE_TPOWERON */
- err = pci_enable_device(dev);
- if (err) {
- printf("%s:pci_enable_device error %d \n", __FUNCTION__, err);
- goto out;
- }
- pci_set_master(dev);
- err = pci_set_power_state(dev, PCI_D0);
- if (err) {
- printf("%s:pci_set_power_state error %d \n", __FUNCTION__, err);
- goto out;
- }
BCM_REFERENCE(pch);
dhdpcie_suspend_dump_cfgregs(pch->bus, "AFTER_EP_RESUME");
out:
@@ -1510,9 +1513,21 @@
return -ENODEV;
}
- printf("PCI_PROBE: bus %X, slot %X,vendor %X, device %X"
- "(good PCI location)\n", pdev->bus->number,
- PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device);
+ DHD_ERROR(("%s: PCI_PROBE: bus %X, slot %X,vendor %X, device %X"
+ "(good PCI location), name %s\n", dhdpcie_driver.name, pdev->bus->number,
+ PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device, pdev->bus->name));
+
+ if (strlen(pcie_dev_bus_name)) {
+ if (!strncmp(pdev->bus->name,
+ pcie_dev_bus_name, strlen(pcie_dev_bus_name))) {
+ DHD_ERROR(("%s: PCI_PROBE: bus name (%s) matched (%s)\n",
+ dhdpcie_driver.name, pcie_dev_bus_name, pdev->bus->name));
+ } else {
+ DHD_ERROR(("%s: PCI_PROBE: bus name (%s) did not match (%s)\n",
+ dhdpcie_driver.name, pcie_dev_bus_name, pdev->bus->name));
+ return -ENODEV;
+ }
+ }
if (dhdpcie_init_succeeded == TRUE) {
DHD_ERROR(("%s(): === Driver Already attached to a BRCM device === \r\n",
@@ -1797,10 +1812,11 @@
goto err;
}
- dhdpcie_info->regs = (volatile char *) REG_MAP(bar0_addr, DONGLE_REG_MAP_SIZE);
+ dhdpcie_info->regs = (volatile char *) REG_MAP_XBIT(bar0_addr, DONGLE_REG_MAP_SIZE);
dhdpcie_info->bar1_size =
(bar1_size > DONGLE_TCM_MAP_SIZE) ? bar1_size : DONGLE_TCM_MAP_SIZE;
- dhdpcie_info->tcm = (volatile char *) REG_MAP(bar1_addr, dhdpcie_info->bar1_size);
+ dhdpcie_info->tcm = (volatile char *) REG_MAP_XBIT(bar1_addr,
+ dhdpcie_info->bar1_size);
if (!dhdpcie_info->regs || !dhdpcie_info->tcm) {
DHD_ERROR(("%s:ioremap() failed\n", __FUNCTION__));
@@ -2528,7 +2544,7 @@
break;
}
- dhdpcie_info->regs = (volatile char *) REG_MAP(bar0_addr, DONGLE_REG_MAP_SIZE);
+ dhdpcie_info->regs = (volatile char *) REG_MAP_XBIT(bar0_addr, DONGLE_REG_MAP_SIZE);
if (!dhdpcie_info->regs) {
DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__));
break;
@@ -2537,7 +2553,8 @@
bus->regs = dhdpcie_info->regs;
dhdpcie_info->bar1_size =
(bar1_size > DONGLE_TCM_MAP_SIZE) ? bar1_size : DONGLE_TCM_MAP_SIZE;
- dhdpcie_info->tcm = (volatile char *) REG_MAP(bar1_addr, dhdpcie_info->bar1_size);
+ dhdpcie_info->tcm = (volatile char *) REG_MAP_XBIT(bar1_addr,
+ dhdpcie_info->bar1_size);
if (!dhdpcie_info->tcm) {
DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__));
REG_UNMAP(dhdpcie_info->regs);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
index c8a0d5a..a9555ef 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -1,9 +1,9 @@
/*
* DHD Bus Module for SDIO
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -163,6 +163,11 @@
#define DHD_WAIT_HTAVAIL 10000
#endif /* BCMQT */
+/* Maximum read shared console retry */
+#ifdef BCMSPI
+#define MAX_READSHARED_RETRY 1000
+#endif /* BCMSPI */
+
/* Bump up limit on waiting for HT to account for first startup;
* if the image is doing a CRC calculation before programming the PMU
* for HT availability, it could take a couple hundred ms more, so
@@ -941,6 +946,7 @@
}
if (bus->sih->chip == BCM43430_CHIP_ID ||
+ bus->sih->chip == BCM43439_CHIP_ID ||
bus->sih->chip == BCM43018_CHIP_ID) {
/* check if fw initialized sr engine */
addr = SI_ENUM_BASE(bus->sih) + OFFSETOF(chipcregs_t, sr_control1);
@@ -1037,6 +1043,7 @@
#endif /* USE_CMD14 */
if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+ CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43018_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM4339_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43012_CHIP_ID ||
@@ -3457,6 +3464,7 @@
}
}
if ((CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+ CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43018_CHIP_ID) && !dhdsdio_sr_cap(bus))
bus->srmemsize = 0;
@@ -3522,7 +3530,9 @@
uint32 shaddr = 0;
sdpcm_shared_t sh_info;
sdpcm_shared_t *sh = &sh_info;
+#ifndef BCMSPI
int retry = 10;
+#endif /* BCMSPI */
shaddr = bus->dongle_ram_base + bus->ramsize - 4;
i = 0;
@@ -3550,10 +3560,19 @@
}
} else
break;
+#ifndef BCMSPI
} while (i < retry);
+#else
+ } while (++i < MAX_READSHARED_RETRY);
+#endif /* BCMSPI */
+#ifndef BCMSPI
if (i == retry)
return BCME_ERROR;
+#else
+ if (i == MAX_READSHARED_RETRY)
+ return BCME_ERROR;
+#endif /* BCMSPI */
/* Read hndrte_shared structure */
if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0)
@@ -3630,7 +3649,6 @@
/* Read the console buffer */
addr = ltoh32(c->log.buf);
- DHD_ERROR(("read addr finish\n"));
if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0)
return rv;
@@ -4842,6 +4860,7 @@
dhdsdio_devram_remap(bus, FALSE);
if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+ CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43018_CHIP_ID) {
/* Disabling Remap for SRAM_3 */
si_socram_set_bankpda(bus->sih, 0x3, 0x0);
@@ -5610,6 +5629,17 @@
#endif /* DHD_DEBUG */
}
+#if defined(PLATFORM_IMX)
+ /* dhdsdio_readshared_console is failed sometimes in i.MX platform
+ * unless wait the time with specific chips so it treat as fine.
+ */
+ if ((ret < 0) &&
+ ((CHIPID(bus->sih->chip) == BCM43430_CHIP_ID) ||
+ (CHIPID(bus->sih->chip) == BCM43439_CHIP_ID))) {
+ ret = BCME_OK;
+ }
+#endif /* defined(PLATFORM_IMX) */
+
if (enforce_mutex)
dhd_os_sdlock(bus->dhd);
@@ -7079,7 +7109,8 @@
#endif /* SDTEST */
#if defined(BCMSPI)
- if ((chan == SDPCM_EVENT_CHANNEL) && (bus->sdpcmrev >= 17 && bus->sdpcmrev <= 22)) {
+ if (((chan == SDPCM_EVENT_CHANNEL) && (bus->sdpcmrev >= 17 && bus->sdpcmrev <= 22))||
+ PKTLEN(osh, pkt) == 0) {
#else
if (PKTLEN(osh, pkt) == 0) {
#endif /* BCMSPI */
@@ -7522,8 +7553,10 @@
#endif /* DHD_ULP */
}
/* Resched the DPC if ctrl cmd is pending on bus credit */
- if (bus->ctrl_frame_stat)
+ if (bus->ctrl_frame_stat) {
resched = TRUE;
+ bus->ipend = TRUE;
+ }
/* Resched if events or tx frames are pending, else await next interrupt */
/* On failed register access, all bets are off: no resched or interrupts */
@@ -7988,6 +8021,11 @@
#endif // endif
}
+struct device * dhd_bus_to_dev(struct dhd_bus *bus)
+{
+ return (struct device *)bcmsdh_get_dev(bus->sdh);
+}
+
void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub)
{
bcmsdh_dev_pm_stay_awake(dhdpub->bus->sdh);
@@ -8287,6 +8325,8 @@
return TRUE;
if (chipid == BCM43430_CHIP_ID)
return TRUE;
+ if (chipid == BCM43439_CHIP_ID)
+ return TRUE;
if (chipid == BCM43018_CHIP_ID)
return TRUE;
if (BCM4349_CHIP(chipid))
@@ -9092,7 +9132,7 @@
#if defined(BCMSPI) && defined(GSPI_DWORD_MODE)
/* Enable the dwordmode in gSPI before first F2 transaction */
if (((bus->sih->chip == BCM4329_CHIP_ID) && (bus->sih->chiprev > 1)) ||
- (bus->sih->chip == BCM43430_CHIP_ID)) {
+ (bus->sih->chip == BCM43430_CHIP_ID || bus->sih->chip == BCM43439_CHIP_ID)) {
bcmsdh_dwordmode(bus->sdh, TRUE);
bus->dwordmode = TRUE;
DHD_INFO(("DHD:SPI DWORD mode enabled\n"));
@@ -9253,6 +9293,10 @@
* well as WLAN reset (instead of using PMU/CC Watchdog register)
*/
uint8 cardctl;
+#ifdef BCMSPI
+ int bcmspierr;
+ uint32 regdata;
+#endif /* BCMSPI */
cardctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
SDIOD_CCCR_BRCM_CARDCTL, &bcmerror);
cardctl |= SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT;
@@ -9266,6 +9310,26 @@
DHD_ERROR(("%s: Set WLANRST in cardctl error %d\n",
__FUNCTION__, bcmerror));
}
+
+#ifdef BCMSPI
+
+ regdata = bcmsdh_cfg_read_word(bus->sdh,
+ SDIO_FUNC_0, SPID_RESET_BP, &bcmspierr);
+
+ regdata |= (RESET_ON_WLAN_BP_RESET | RESET_SPI);
+
+ if (!bcmspierr) {
+ bcmsdh_cfg_write_word(bus->sdh, SDIO_FUNC_0,
+ SPID_RESET_BP, regdata, &bcmspierr);
+ }
+
+ if (bcmspierr) {
+ DHD_ERROR(("%s : SPI RESET Returns Error 0x%x\n",
+ __FUNCTION__, bcmspierr));
+ }
+
+#endif /* BCMSPI */
+
} else {
si_watchdog(bus->sih, 4);
}
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
index 6cbdb45..8c1a745 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
@@ -1,9 +1,9 @@
/*
* Fundamental types and constants relating to 802.11
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -5305,6 +5305,9 @@
DOT11_5GHZ_40MHZ_CLASS_30 = 127, /* Ch 153-161, upper */
DOT11_2GHZ_40MHZ_CLASS_32 = 83, /* Ch 1-7, lower */
DOT11_2GHZ_40MHZ_CLASS_33 = 84, /* Ch 5-11, upper */
+ DOT11_6GHZ_20MHZ_CLASS_131 = 131, /* Ch 1-233 */
+ DOT11_6GHZ_40MHZ_CLASS_132 = 132, /* Ch 3-227 */
+ DOT11_6GHZ_80MHZ_CLASS_133 = 133, /* Ch 7-215 */
} dot11_op_class_t;
/* QoS map */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h
new file mode 100755
index 0000000..35455bd
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h
@@ -0,0 +1,283 @@
+/*
+ * Basic types and constants relating to 802.11ah standard.
+ * This is a portion of 802.11ah definition. The rest are in 802.11.h.
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2016, 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.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _802_11ah_h_
+#define _802_11ah_h_
+
+#include <typedefs.h>
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+/**
+ * TWT IE (sec 8.4.2.196)
+ */
+
+/* TWT element - top */
+BWL_PRE_PACKED_STRUCT struct twt_ie_top {
+ uint8 id;
+ uint8 len;
+ uint8 ctrl; /* Control */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_top twt_ie_top_t;
+
+/* S1G Action IDs */
+#define S1G_ACTION_TWT_SETUP 6u
+#define S1G_ACTION_TWT_TEARDOWN 7u
+#define S1G_ACTION_TWT_INFO 11u
+
+/* S1G Action frame offsets */
+#define S1G_AF_CAT_OFF 0u
+#define S1G_AF_ACT_OFF 1u
+
+/* TWT Setup */
+#define S1G_AF_TWT_SETUP_TOKEN_OFF 2u
+#define S1G_AF_TWT_SETUP_TWT_IE_OFF 3u
+
+/* TWT Teardown */
+#define S1G_AF_TWT_TEARDOWN_FLOW_OFF 2u
+
+/* TWT Information */
+#define S1G_AF_TWT_INFO_OFF 2u
+
+#define TWT_BCAST_WAKE_TIME_OFFSET 10u
+#define TWT_BCAST_WAKE_TIME_SHIFT 10u
+#define TWT_BCAST_WAKE_TIME_MASK 0x03FFFC00u
+#define TWT_BCAST_WAKE_TIME_ZERO_BIT_SZ 10u
+
+/* Control field (Figure 9-589aw) */
+#define TWT_CTRL_NDP_PAGING_IND 0x01u /* NDP Paging Indication */
+#define TWT_CTRL_RESP_PM_MODE 0x02u /* Respondor PM Mode */
+#define TWT_CTRL_NEGO_TYPE_IDX 2u
+#define TWT_CTRL_NEGO_TYPE_MASK 0x0Cu /* TWT Negotiation Type */
+#define TWT_CTRL_NEGO_TYPE_SHIFT 2u
+
+/* TWT Negotiation Type (Table 9-262j1) */
+typedef enum twt_ctrl_nego_type {
+ TWT_CTRL_NEGO_TYPE_0 = 0, /* Individual TWT Setup */
+ TWT_CTRL_NEGO_TYPE_1 = 1, /* Wake TBTT Negotiation */
+ TWT_CTRL_NEGO_TYPE_2 = 2, /* Broadcast TWT IE in Beacon */
+ TWT_CTRL_NEGO_TYPE_3 = 3, /* Broadcast TWT memberships */
+} twt_ctrl_nego_type_t;
+
+/* Request Type field (Figure 9-589ay) */
+#define TWT_REQ_TYPE_REQUEST 0x0001u /* Request */
+#define TWT_REQ_TYPE_SETUP_CMD_MASK 0x000eu /* Setup Command */
+#define TWT_REQ_TYPE_SETUP_CMD_SHIFT 1u
+#define TWT_REQ_TYPE_TRIGGER 0x0010u /* Trigger */
+#define TWT_REQ_TYPE_IMPLICIT 0x0020u /* Implicit */
+#define TWT_REQ_TYPE_LAST_BCAST_PARAM 0x0020u /* Last Broadcast Parameter Set */
+#define TWT_REQ_TYPE_FLOW_TYPE 0x0040u /* Flow Type */
+#define TWT_REQ_TYPE_FLOW_ID_MASK 0x0380u /* Flow Identifier */
+#define TWT_REQ_TYPE_FLOW_ID_SHIFT 7u
+#define TWT_REQ_TYPE_BTWT_RECOMM_MASK 0x0380u /* Broadcast TWT Recommendation */
+#define TWT_REQ_TYPE_BTWT_RECOMM_SHIFT 7u
+#define TWT_REQ_TYPE_WAKE_EXP_MASK 0x7c00u /* Wake Interval Exponent */
+#define TWT_REQ_TYPE_WAKE_EXP_SHIFT 10u
+#define TWT_REQ_TYPE_PROTECTION 0x8000u /* Protection */
+
+/* Setup Command field (Table 9-262k) */
+#define TWT_SETUP_CMD_REQUEST_TWT 0u /* Request TWT */
+#define TWT_SETUP_CMD_SUGGEST_TWT 1u /* Suggest TWT */
+#define TWT_SETUP_CMD_DEMAND_TWT 2u /* Demand TWT */
+#define TWT_SETUP_CMD_GROUPING_TWT 3u /* Grouping TWT */
+#define TWT_SETUP_CMD_ACCEPT_TWT 4u /* Accept TWT */
+#define TWT_SETUP_CMD_ALTERNATE_TWT 5u /* Alternate TWT */
+#define TWT_SETUP_CMD_DICTATE_TWT 6u /* Dictate TWT */
+#define TWT_SETUP_CMD_REJECT_TWT 7u /* Reject TWT */
+
+/* Broadcast TWT Recommendation field (Table 9-262k1) */
+#define TWT_BCAST_FRAME_RECOMM_0 0u /* No constrains on frames in Broadcast TWT SP */
+#define TWT_BCAST_FRAME_RECOMM_1 1u /* Do not contain RUs for random access */
+#define TWT_BCAST_FRAME_RECOMM_2 2u /* Can contain RUs for random access */
+#define TWT_BCAST_FRAME_RECOMM_3 3u
+
+/* Request Type subfield - 2 octets */
+typedef uint16 twt_request_type_t; /* 16 bit request type */
+
+/* Target Wake Time - 8 octets or 0 octet */
+typedef uint64 twt_target_wake_time_t; /* 64 bit TSF time of TWT Responding STA */
+typedef uint16 twt_bcast_wake_time_t; /* 16 bit Wake Time of Bcast scheduling STA */
+typedef uint16 twt_bcast_twt_info_t; /* 16 bit Broadcast TWT Info subfield */
+
+/* TWT Group Assignment Info - 9 octets (long format) or 3 octets (short format) or 0 octet */
+/* Group Assignment Info field - short format - Zero Offset Preset field is 0 */
+BWL_PRE_PACKED_STRUCT struct twt_grp_short {
+ uint8 grpid_n_0off; /* Group ID and Zero Offset Present */
+ uint16 unit_n_off; /* TWT Unit and TWT Offset */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_grp_short twt_grp_short_t;
+
+/* Group Assignment Info field - long format - Zero Offset Preset field is 1 */
+#define TWT_ZERO_OFF_GRP_LEN 6u
+BWL_PRE_PACKED_STRUCT struct twt_grp_long {
+ uint8 grpid_n_0off; /* Group ID and Zero Offset Present */
+ uint8 grp_0off[TWT_ZERO_OFF_GRP_LEN]; /* Zero Offset of Group */
+ uint16 unit_n_off; /* Unit and Offset */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_grp_long twt_grp_long_t;
+
+/* TWT Unit and TWT Offset field */
+#define TWT_UNIT_MASK 0x000fu /* TWT Unit */
+#define TWT_OFFSET_MASK 0xfff0u /* TWT Offset */
+#define TWT_OFFSET_SHIFT 4u
+
+/* TWT Unit field (table 8-248m) */
+#define TWT_UNIT_32us 0u
+#define TWT_UNIT_256us 1u
+#define TWT_UNIT_1024us 2u
+#define TWT_UNIT_8ms192us 3u
+#define TWT_UNIT_32ms768us 4u
+#define TWT_UNIT_262ms144us 5u
+#define TWT_UNIT_1s048576us 6u
+#define TWT_UNIT_8s388608us 7u
+#define TWT_UNIT_33s554432us 8u
+#define TWT_UNIT_268s435456us 9u
+#define TWT_UNIT_1073s741824us 10u
+#define TWT_UNIT_8589s934592us 11u
+
+/* TWT element - bottom */
+BWL_PRE_PACKED_STRUCT struct twt_ie_itwt_bottom {
+ uint8 nom_wake_dur; /* Nominal Minimum Wake Duration */
+ uint16 wake_int_mant; /* TWT Wake Interval Mantissa */
+ uint8 channel; /* TWT Channel */
+ /* NDP Paging field */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_itwt_bottom twt_ie_itwt_bottom_t;
+
+/* TWT element - bottom */
+BWL_PRE_PACKED_STRUCT struct twt_ie_btwt_bottom {
+ uint8 nom_wake_dur; /* Nominal Minimum Wake Duration */
+ uint16 wake_int_mant; /* TWT Wake Interval Mantissa */
+ twt_bcast_twt_info_t btwt_info; /* Broadcast TWT Info */
+ /* NDP Paging field */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_btwt_bottom twt_ie_btwt_bottom_t;
+
+/* TWT IE structure for broadcast TWT */
+typedef struct twt_last_bcast_ie {
+ twt_ie_top_t top; /* Element id, len, control fields */
+ twt_request_type_t req_type; /* request type field */
+ twt_bcast_wake_time_t twt; /* twt field */
+ twt_ie_btwt_bottom_t btwt_bottom; /* wake dur, int, BID Info */
+} twt_last_bcast_ie_t;
+
+/* Nominal Minimum Wake Duration */
+#define TWT_NOM_WAKE_DUR_UNIT 256u /* Nominal Minimum Wake Duration is in 256us units */
+
+/* TWT IE field lengths */
+#define TWT_IE_NOM_MIN_TWT_WK_DUR_SZ 1u /* 1 byte */
+#define TWT_IE_TWT_WAKE_INT_MANT_SZ 2u /* 2 bytes */
+#define TWT_IE_BCAST_TWT_INFO_SZ 2u /* 2 byte */
+#define TWT_IE_TWT_CHANNEL_SZ 1u /* 1 byte */
+
+/* Broadcast TWT info subfield format (figure 9-589ay1) */
+#define TWT_BTWT_PERSIST_EXPO_MASK 0x0007u /* Broadcast TWT Persistence Exponent */
+#define TWT_BCAST_TWT_ID_MASK 0x00F8u /* Broadcast TWT ID */
+#define TWT_BCAST_TWT_ID_SHIFT 3u
+#define TWT_BTWT_PERSIST_MANT_MASK 0xFF00u /* Broadcast TWT Persistence Mantissa */
+#define TWT_BTWT_PERSIST_MANT_SHIFT 8u
+
+#define TWT_BTWT_PERSIST_INDEFINITE 0xFFu
+
+/* NDP Paging field - 4 octets or 0 octet */
+typedef uint32 twt_ndp_paging_t;
+
+#define TWT_NDP_PAGING_PID 0x000001ffu /* P-ID */
+#define TWT_NDP_PAGING_MAX_PERIOD 0x0001fe00u /* Max NDP Paging Period */
+#define TWT_NDP_PAGING_PART_TSF_OFF 0x001e0000u /* Partial TSF Offset */
+#define TWT_NDP_PAGING_ACTION 0x00e00000u /* Action */
+#define TWT_NDP_PAGING_MIN_SLEEP 0x3f000000u /* Min Sleep Duration */
+
+/* Action field (table 8-248n) */
+#define TWT_ACTION_SEND_PSP_TRIG 0u /* Send a PS-Poll or uplink trigger frame */
+#define TWT_ACTION_WAKE_MIN_SLEEP 1u /* Wake up at the time indicated by
+ * Min Sleep Duration
+ */
+#define TWT_ACTION_WAKE_RCV_BCN 2u /* Wake up to receive the Beacon */
+#define TWT_ACTION_WAKE_RCV_DTIM 3u /* Wake up to receive the DTIM Beacon */
+#define TWT_ACTION_WAKE_IND_TIME 4u /* Wakeup at the time indicated by the sum of
+ * the Min Sleep Duration field and the ASD subfield
+ * in the APDI field of the NDP Paging frame
+ */
+
+/* TWT Teardown for Negotiation type 0 or 1 */
+#define TWT_TEARDOWN_FLOW_ID_MASK 0x07u
+/* TWT Teardown for Negotiation type 3 */
+#define TWT_TEARDOWN_BTWT_ID_MASK 0x1Fu
+
+#define TWT_TEARDOWN_NEGO_TYPE_MASK 0x60u
+#define TWT_TEARDOWN_NEGO_TYPE_SHIFT 5u
+/* Teardown All TWT indication */
+#define TWT_TEARDOWN_ALL_TWT 0x80u
+
+/* TWT Information field byte 0 */
+#define TWT_INFO_FLOW_ID_MASK 0x07u
+#define TWT_INFO_RESP_REQ 0x08u
+#define TWT_INFO_NEXT_TWT_REQ 0x10u
+#define TWT_INFO_NEXT_TWT_SIZE_MASK 0x60u
+#define TWT_INFO_NEXT_TWT_SIZE_SHIFT 0x5u
+#define TWT_INFO_ALL_TWT 0x80u
+
+/* Next TWT Subfield Size field encoding */
+#define TWT_INFO_NEXT_TWT_SIZE_0_IDX 0u /* 0 byte */
+#define TWT_INFO_NEXT_TWT_SIZE_32_IDX 1u /* 4 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_48_IDX 2u /* 6 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_64_IDX 3u /* 8 bytes */
+
+/* Next TWT Subfield Size field */
+#define TWT_INFO_NEXT_TWT_SIZE_0 0u /* 0 byte */
+#define TWT_INFO_NEXT_TWT_SIZE_32 4u /* 4 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_48 6u /* 6 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_64 8u /* 8 bytes */
+
+/* Old macro definitions - To be removed - Start here */
+#define TWT_BCAST_MAX_VALID_FLOW_ID 3u
+#define TWT_CTRL_BCAST 0x04u /* Broadcast */
+#define TWT_CTRL_WAKE_TBTT_NEGO 0x08u /* Wake TBTT Negotiation */
+#define TWT_SETUP_CMD_GRPING_TWT 3u /* Grouping TWT */
+#define TWT_SETUP_CMD_ALTER_TWT 5u /* Alternate TWT */
+#define TWT_IE_BCAST_TWT_ID_SZ 1u /* 1 byte */
+#define TWT_INFO_BROADCAST_RESCHED 0x80u
+
+typedef struct twt_ie_itwt_bottom twt_ie_bottom_t;
+/* Old macro definitions - To be removed - End here */
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _802_11ah_h_ */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
index b7acf2b..7358b4b 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
@@ -1,9 +1,9 @@
/*
* Broadcom device-specific manifest constants.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -73,6 +73,7 @@
#define BCM_DNGL_BL_PID_4354 0xbd26
#define BCM_DNGL_BL_PID_43569 0xbd27
#define BCM_DNGL_BL_PID_4373 0xbd29
+#define BCM_DNGL_BL_PID_43439 0xbd3d
#define BCM_DNGL_BDC_PID 0x0bdc
#define BCM_DNGL_JTAG_PID 0x4a44
@@ -536,6 +537,7 @@
case BCM43458_CHIP_ID
#define BCM43430_CHIP_ID 43430 /* 43430 chipcommon chipid */
+#define BCM43439_CHIP_ID 43439 /* 43439 chipcommon chipid */
#define BCM43018_CHIP_ID 43018 /* 43018 chipcommon chipid */
#define BCM4349_CHIP_ID 0x4349 /* 4349 chipcommon chipid */
#define BCM4355_CHIP_ID 0x4355 /* 4355 chipcommon chipid */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
old mode 100644
new mode 100755
index c40af1d..51f0157
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
@@ -3,9 +3,9 @@
*
* Dependencies: bcmeth.h
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -312,9 +312,11 @@
#define WLC_E_LDF_HOGGER 192 /* Detection Hogger Squasher -Cambium */
#define WLC_E_DLTRO 193 /* DHCP lease time renew offload */
#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."
+#define WLC_E_TWT_TEARDOWN 195 /* TWT Teardown Complete Event */
+#define WLC_E_EXT_ASSOC_FRAME_RX 196 /* association requeste received */
+#define WLC_E_LAST 197 /* highest val + 1 for range checking */
+#if (WLC_E_LAST > 197)
+#error "WLC_E_LAST: Invalid value for last event; must be <= 197."
#endif /* WLC_E_LAST */
/* define an API for getting the string name of an event */
@@ -994,6 +996,16 @@
/* wl_twt_sdesc_t desc; - defined in wlioctl.h */
} wl_twt_setup_cplt_t;
+#define WL_TWT_TEARDOWN_CPLT_VER 0
+
+/* TWT Teardown Completion event data */
+typedef struct wl_twt_teardown_cplt {
+ uint16 version;
+ uint16 length; /* the byte count of fields from 'status' onwards */
+ int32 status;
+ /* wl_twt_teardesc_t desc; - defined in wlioctl.h */
+} wl_twt_teardown_cplt_t;
+
#define WL_INVALID_IE_EVENT_VERSION 0
/* Invalid IE Event data */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
index efc8258..1e0609f 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
@@ -3,9 +3,9 @@
* export functions to client drivers
* abstract OS and BUS specific details of SDIO
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -238,6 +238,7 @@
extern void bcmsdh_oob_intr_unregister(bcmsdh_info_t *sdh);
extern void bcmsdh_oob_intr_set(bcmsdh_info_t *sdh, bool enable);
#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
+extern void *bcmsdh_get_dev(bcmsdh_info_t *sdh);
extern void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *sdh);
extern void bcmsdh_dev_relax(bcmsdh_info_t *sdh);
extern bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *sdh);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
old mode 100644
new mode 100755
index 84eacf9..1e28a2f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
@@ -1,9 +1,9 @@
/*
* Definitions for nl80211 vendor command/event access to host driver
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -47,6 +47,7 @@
BRCM_VENDOR_SCMD_MPC = 7,
BRCM_VENDOR_SCMD_BAND = 8,
BRCM_VENDOR_SCMD_ACS = 9,
+ BRCM_VENDOR_SCMD_SET_MAC = 10,
BRCM_VENDOR_SCMD_MAX
};
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h
new file mode 100755
index 0000000..272c3e6
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h
@@ -0,0 +1,294 @@
+/*
+ * Infineon Technologies OUI and vendor specific assignments
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein. IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE. INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef IFX_VENDOR_H
+#define IFX_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Infineon
+ * OUI 00:03:19 for purposes other than MAC address assignment. New identifiers
+ * can be assigned through normal review process for changes to the upstream
+ * hostap.git repository.
+ */
+#define OUI_IFX 0x000319
+
+/*
+ * enum ifx_nl80211_vendor_subcmds - IFX nl80211 vendor command identifiers
+ *
+ * @IFX_VENDOR_SCMD_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_SCMD_FRAMEBURST: Vendor command to enable/disable Frameburst
+ *
+ * @IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE: Vendor command to enable/disable HE MU-EDCA opt
+ *
+ * @IFX_VENDOR_SCMD_LDPC_CAP: Vendor command enable/disable LDPC Capability
+ *
+ * @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues
+ *
+ * @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT
+ * Uses attributes defined in enum ifx_vendor_attr_twt.
+ *
+ * @IFX_VENDOR_SCMD_OCE_ENABLE: Vendor command to enable/disable OCE Capability
+ *
+ * @IFX_VENDOR_SCMD_RANDMAC: Vendor command to enable/disable RANDMAC Capability
+ *
+ * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ * Make sure it located at the end of the list.
+ */
+enum ifx_nl80211_vendor_subcmds {
+ /*
+ * TODO: IFX Vendor subcmd enum IDs between 1-10 are reserved
+ * to be be filled later with BRCM Vendor subcmds that are
+ * already used by IFX.
+ */
+ IFX_VENDOR_SCMD_UNSPEC = 0,
+ /* Reserved 1-5 */
+ IFX_VENDOR_SCMD_FRAMEBURST = 6,
+ /* Reserved 7-9 */
+#ifdef P2P_RAND
+ IFX_VENDOR_SCMD_SET_P2P_RAND_MAC = 10,
+#endif /* P2P_RAND */
+ IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE = 11,
+ IFX_VENDOR_SCMD_LDPC_CAP = 12,
+ IFX_VENDOR_SCMD_AMSDU = 13,
+ IFX_VENDOR_SCMD_TWT = 14,
+ IFX_VENDOR_SCMD_OCE_ENABLE = 15,
+ /* Reserved 16 */
+ IFX_VENDOR_SCMD_RANDMAC = 17,
+ IFX_VENDOR_SCMD_MAX
+};
+
+/*
+ * enum ifx_vendor_attr - IFX nl80211 vendor attributes
+ *
+ * @IFX_VENDOR_ATTR_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_MAX: This acts as a the tail of attrs list.
+ * Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr {
+ /*
+ * TODO: IFX Vendor attr enum IDs between 0-10 are reserved
+ * to be filled later with BRCM Vendor attrs that are
+ * already used by IFX.
+ */
+ IFX_VENDOR_ATTR_UNSPEC = 0,
+ IFX_VENDOR_ATTR_PAD = 1,
+ IFX_VENDOR_ATTR_MAC_ADDR = 2,
+ /* Reserved 1-10 */
+ IFX_VENDOR_ATTR_MAX = 11
+};
+
+/*
+ * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command
+ *
+ * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_OPER: To specify the type of TWT operation
+ * to be performed. Uses attributes defined in enum ifx_twt_oper.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAMS: Nester attributes representing the
+ * parameters configured for TWT. These parameters are defined in
+ * the enum ifx_vendor_attr_twt_param.
+ *
+ * @IFX_VENDOR_ATTR_TWT_MAX: This acts as a the tail of cmds list.
+ * Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt {
+ IFX_VENDOR_ATTR_TWT_UNSPEC,
+ IFX_VENDOR_ATTR_TWT_OPER,
+ IFX_VENDOR_ATTR_TWT_PARAMS,
+ IFX_VENDOR_ATTR_TWT_MAX
+};
+
+/*
+ * enum ifx_twt_oper - TWT operation to be specified using the vendor
+ * attribute IFX_VENDOR_ATTR_TWT_OPER
+ *
+ * @IFX_TWT_OPER_UNSPEC: Reserved value 0
+ *
+ * @IFX_TWT_OPER_SETUP: Setup a TWT session. Required parameters are
+ * obtained through the nested attrs under IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_TEARDOWN: Teardown the already negotiated TWT session.
+ * Required parameters are obtained through the nested attrs under
+ * IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_MAX: This acts as a the tail of the list.
+ * Make sure it located at the end of the list.
+ */
+enum ifx_twt_oper {
+ IFX_TWT_OPER_UNSPEC,
+ IFX_TWT_OPER_SETUP,
+ IFX_TWT_OPER_TEARDOWN,
+ IFX_TWT_OPER_MAX
+};
+
+/*
+ * enum ifx_vendor_attr_twt_param - TWT parameters
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: Specifies the type of Negotiation to be
+ * done during Setup. The four possible types are
+ * 0 - Individual TWT Negotiation
+ * 1 - Wake TBTT Negotiation
+ * 2 - Broadcast TWT in Beacon
+ * 3 - Broadcast TWT Membership Negotiation
+ *
+ * The possible values are defined in the enum ifx_twt_param_nego_type
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: Specifies the type of TWT Setup frame
+ * when sent by the TWT Requesting STA
+ * 0 - Request
+ * 1 - Suggest
+ * 2 - Demand
+ *
+ * when sent by the TWT Responding STA.
+ * 3 - Grouping
+ * 4 - Accept
+ * 5 - Alternate
+ * 6 - Dictate
+ * 7 - Reject
+ *
+ * The possible values are defined in the enum ifx_twt_oper_setup_cmd_type.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: Dialog Token used by the TWT Requesting STA to
+ * identify the TWT Setup request/response transaction.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: Target Wake Time.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: Target Wake Time Offset.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: Nominal Minimum TWT Wake Duration.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: TWT Wake Interval Exponent.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: TWT Wake Interval Mantissa.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: Specify this is a TWT Requesting / Responding STA.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: Specify Trigger based / Non-Trigger based TWT Session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: Specify Implicit / Explicit TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: Specify Un-Announced / Announced TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: Flow ID of an iTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: Brocast TWT ID of a bTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: Specifies whether Tx within SP is protected.
+ * Set to 1 to indicate that TXOPs within the TWT SPs shall be initiated
+ * with a NAV protection mechanism, such as (MU) RTS/CTS or CTS-to-self frame;
+ * otherwise, it shall set it to 0.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless
+ * the HE STA sets up a subchannel selective transmission operation.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing
+ * disabled / enabled.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: Nominal Minimum TWT Wake Duration
+ * Unit. 0 represents unit in "256 usecs" and 1 represents unit in "TUs".
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: Teardown all negotiated TWT sessions.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MAX: This acts as a the tail of the list.
+ * Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt_param {
+ IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC,
+ IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
+ IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
+ IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET,
+ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
+ IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
+ IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
+ IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
+ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
+ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
+ IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
+ IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
+ IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
+ IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
+ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
+ IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT,
+ IFX_VENDOR_ATTR_TWT_PARAM_MAX
+};
+
+enum ifx_twt_param_nego_type {
+ IFX_TWT_PARAM_NEGO_TYPE_INVALID = -1,
+ IFX_TWT_PARAM_NEGO_TYPE_ITWT = 0,
+ IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT = 1,
+ IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN = 2,
+ IFX_TWT_PARAM_NEGO_TYPE_BTWT = 3,
+ IFX_TWT_PARAM_NEGO_TYPE_MAX = 4
+};
+
+enum ifx_twt_oper_setup_cmd_type {
+ IFX_TWT_OPER_SETUP_CMD_TYPE_INVALID = -1,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST = 0,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST = 1,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND = 2,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING = 3,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT = 4,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE = 5,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE = 6,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT = 7,
+ IFX_TWT_OPER_SETUP_CMD_TYPE_MAX = 8
+};
+
+#endif /* IFX_VENDOR_H */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
index de6785e..98b6179 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
@@ -1,9 +1,9 @@
/*
* Linux OS Independent Layer
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -446,13 +446,20 @@
/* map/unmap physical to virtual I/O */
#if !defined(CONFIG_MMC_MSM7X00A)
+/* REG_MAP: Arguments type casted to 'unsigned long' for 32 bit variables.
+ * REG_MAP_XBIT: Arguments not type casted, because variables of type like
+ * phys_addr_t can be 32 or 64 bit depending on platform architecture.
+*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0))
#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#define REG_MAP_XBIT(pa, size) ioremap_nocache((pa), (size))
#else
#define REG_MAP(pa, size) ioremap((unsigned long)(pa), (unsigned long)(size))
+#define REG_MAP_XBIT(pa, size) ioremap((pa), (size))
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) */
#else
#define REG_MAP(pa, size) (void *)(0)
+#define REG_MAP_XBIT(pa, size) (void *)(0)
#endif /* !defined(CONFIG_MMC_MSM7X00A */
#define REG_UNMAP(va) iounmap((va))
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
index e6aa882..a523ac0 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
@@ -2,9 +2,9 @@
* Linux-specific abstractions to gain some independence from linux kernel versions.
* Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -880,6 +880,53 @@
}
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) */
+/* Android GKI kernel does not allow direct file access by driver. */
+#ifdef DHD_DENY_DIRECT_FS_ACCESS
+static inline
+ssize_t __kernel_does_not_allow_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *pos) {
+ return -EPERM;
+}
+static inline
+ssize_t __kernel_does_not_allow_read(struct file *file,
+ char __user *buf,
+ size_t count, loff_t *pos) {
+ return -EPERM;
+}
+static inline
+int __kernel_does_not_allow_unlink(struct user_namespace *mnt_userns,
+ struct inode *dir,
+ struct dentry *dentry,
+ struct inode **delegated_inode) {
+ return -EPERM;
+}
+static inline
+int __kernel_does_not_allow_kern_path(const char *name,
+ unsigned flag, struct path *path) {
+ return -EPERM;
+}
+static inline
+struct file *__kernel_does_not_allow_filp_open(const char *filename,
+ int flags, umode_t mode) {
+ return ERR_PTR(-EPERM);
+}
+
+#define vfs_read(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+#define vfs_write(fp, buf, len, pos) __kernel_does_not_allow_write(fp, buf, len, pos)
+#define kernel_read(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+#define kernel_write(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
+#define vfs_unlink(a, b) __kernel_does_not_allow_unlink(a, b, 0, NULL)
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
+#define vfs_unlink(a, b, c) __kernel_does_not_allow_unlink(NULL, a, b, c)
+#else
+#define vfs_unlink(a, b, c, d) __kernel_does_not_allow_unlink(a, b, c, d)
+#endif // endif
+#define kern_path(a, b, c) __kernel_does_not_allow_kern_path(a, b, c)
+#define filp_open(a, b, c) __kernel_does_not_allow_filp_open(a, b, c)
+#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
#define vfs_write(fp, buf, len, pos) kernel_write(fp, buf, len, pos)
#define vfs_read(fp, buf, len, pos) kernel_read(fp, buf, len, pos)
@@ -887,6 +934,7 @@
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) */
#define kernel_read_compat(file, offset, addr, count) kernel_read(file, offset, addr, count)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) */
+#endif /* DHD_SUPPORT_ANDROID_GKI_KERNEL */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
#define timespec64 timespec
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
old mode 100644
new mode 100755
index 052430c..d404373
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
@@ -2,9 +2,9 @@
* Generic Broadcom Home Networking Division (HND) DMA engine HW interface
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -230,6 +230,9 @@
uint32 addrhigh; /**< descriptor ring base address bits 63:32 (8K aligned) */
uint32 status0; /**< current descriptor, xmt state */
uint32 status1; /**< active descriptor, xmt error */
+#if defined(BCMQT) && defined(BCMSPI)
+ uint32 PAD[2];
+#endif /* defined(BCMQT) && defined(BCMSPI) */
} dma64regs_t;
typedef volatile struct {
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
old mode 100644
new mode 100755
index 2edda4a..80910e8
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
@@ -2,9 +2,9 @@
* Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific
* device core support
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -140,7 +140,7 @@
sdiodma64_t sdiod64;
} dma;
- uint32 PAD[12]; /* 0x300-0x32c */
+ uint32 PAD[4]; /* 0x320-0x32c */
uint32 chipid; /* SDIO ChipID Register, 0x330, rev31 */
uint32 eromptr; /* SDIO EromPtrOffset Register, 0x334, rev31 */
uint32 PAD[50];
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
old mode 100644
new mode 100755
index 2d5120b..1de4dd3
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
@@ -1,7 +1,7 @@
/*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -325,6 +325,9 @@
/* Suppress unused parameter warning */
#define UNUSED_PARAMETER(x) (void)(x)
+/* Suppress unused function warning */
+#define UNUSED_FUNCTION(x) (void)(x)
+
/* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */
#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr))
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
old mode 100644
new mode 100755
index b1cfe0e..0e87ace
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -6,9 +6,9 @@
*
* Definitions subject to change without notice.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -15778,6 +15778,8 @@
/* -------------- dynamic BTCOEX --------------- */
#define DCTL_TROWS 2 /**< currently practical number of rows */
#define DCTL_TROWS_MAX 4 /**< 2 extra rows RFU */
+/* Default Agg mode is Firmware Driven */
+#define DCTL_AGG_MODE_DFLT 0
/* DYNCTL profile flags */
#define DCTL_FLAGS_DISABLED 0 /**< default value: all features disabled */
#define DCTL_FLAGS_DYNCTL (1 << 0) /**< 1 - enabled, 0 - legacy only */
@@ -15835,6 +15837,7 @@
btc_thr_data_t msw_data[DCTL_TROWS_MAX];
/** dynctl desense switching data table */
btc_thr_data_t dsns_data[DCTL_TROWS_MAX];
+ uint16 custom_agg_mode;
} BWL_POST_PACKED_STRUCT dctl_prof_t;
#include <packed_section_end.h>
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
index dc862a0..9e2f0b1 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
@@ -4,9 +4,9 @@
*
* Definitions subject to change without notice.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -570,7 +570,7 @@
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)
-
+#define NON_WPA3_AUTH_ENABLED(wpa_auth) ((wpa_auth) & ~WPA3_AUTH_MASK)
/* pmkid */
#define MAXPMKID 16
@@ -2367,4 +2367,9 @@
/* The macro for data field in empty vendor specific action frame */
#define VS_EMPTY_ACTION 0xac
+#define H2_OCL_RSSI_DELTA 10 /* hysteresis rssi delta */
+#define H2_OCL_RSSI_THRESHOLD -70 /**< Low value, e.g. for forcing roam */
+#define H2_OCL_RSSI_INVALID 0 /* invalid RSSI value */
+#define H2_OCL_DISABLED_RSSI 0x02 /* Disabled because of ocl_rssi_threshold */
+
#endif /* wlioctl_defs_h */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
index f2746a3..d9530f7 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
@@ -2,9 +2,9 @@
* Misc utility routines for accessing chip-specific features
* of the SiliconBackplane-based Broadcom chips.
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -699,9 +699,12 @@
#endif // endif
uint32 erombase;
#ifdef BCMSDIO
- uint8 cardcap;
sdpcmd_regs_t *sdioc;
-#endif // endif
+ uint8 cardcap;
+#ifdef BCMSPI
+ uint32 spidreg;
+#endif /* BCMSPI */
+#endif /* BCMSDIO */
ASSERT(GOODREGS(regs));
@@ -748,20 +751,35 @@
erombase = R_REG(osh, &cc->eromptr);
#ifdef BCMSDIO
} else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
+ if (bustype == SDIO_BUS) {
+ cardcap = bcmsdh_cfg_read(sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
+ if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT)
+ sih->chipidpresent = TRUE;
+ if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE)
+ sih->secureboot = TRUE;
+ }
+#ifdef BCMSPI
+ else {
+ spidreg = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_RESET_BP, NULL);
+ if (spidreg & SPID_SECURE_MODE) {
+ printf("Security related features are present\n");
+ sih->secureboot = TRUE;
+ }
+ if (spidreg & SPID_CHIPID_PRESENT) {
+ printf("Chip ID is present in SPI core\n");
+ sih->chipidpresent = true;
+ }
+ }
+#endif /* BCMSPI */
cc = (chipcregs_t *)sii->curmap;
- cardcap = bcmsdh_cfg_read(sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
- if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) {
- sih->chipidpresent = TRUE;
+ if (sih->chipidpresent) {
sdioc = si_get_sdio_addrbase(sdh);
w = R_REG(osh, &sdioc->chipid);
erombase = R_REG(osh, &sdioc->eromptr);
} else {
erombase = R_REG(osh, &cc->eromptr);
}
- if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE) {
- sih->secureboot = TRUE;
- }
-#endif // endif
+#endif /* BCMSDIO */
} else {
cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
erombase = R_REG(osh, &cc->eromptr);
@@ -2026,6 +2044,7 @@
switch (CHIPID(sih->chip)) {
case BCM43018_CHIP_ID:
case BCM43430_CHIP_ID:
+ case BCM43439_CHIP_ID:
hosti = CHIP_HOSTIF_SDIOMODE;
break;
case BCM43012_CHIP_ID:
@@ -3096,6 +3115,7 @@
uint memsize = 0;
if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
+ CHIPID(sih->chip) == BCM43439_CHIP_ID ||
CHIPID(sih->chip) == BCM43018_CHIP_ID) {
return (64 * 1024);
}
@@ -3347,6 +3367,7 @@
switch (CHIPID(sih->chip)) {
case BCM43018_CHIP_ID:
case BCM43430_CHIP_ID:
+ case BCM43439_CHIP_ID:
return FALSE;
case BCM4335_CHIP_ID:
CASE_BCM4345_CHIP:
@@ -3650,6 +3671,7 @@
#ifdef SAVERESTORE
case BCM43018_CHIP_ID:
case BCM43430_CHIP_ID:
+ case BCM43439_CHIP_ID:
if (SR_ENAB() && sr_isenab(sih)) {
/* read back the pll openloop state */
data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
index 15e0aeb..1c72d15 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 driver - Android related functions
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -147,6 +147,9 @@
#endif /* AUTOMOTIVE_FEATURE */
#define CMD_SET_CSA "SETCSA"
#define CMD_RSDB_MODE "RSDB_MODE"
+#ifdef WL11AX
+#define CMD_GETBSSCOLOR "BSSCOLOR"
+#endif /* WL11AX */
#ifdef WL_SUPPORT_AUTO_CHANNEL
#define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
#endif /* WL_SUPPORT_AUTO_CHANNEL */
@@ -985,6 +988,9 @@
#define M_HOGSQS_DUR_THR (M_HOGSQS_CFG + 0x4)
#define M_HOGSQS_STAT (M_HOGSQS_CFG + 0x6)
#define M_HOGSQS_TXCFE_DET_CNT (M_HOGSQS_CFG + 0xe)
+
+/* hidden node recovery command */
+#define HOGSQS_CMD_HNRECOVER 0x9001
static int
wl_android_hogsqs(struct net_device *dev, char *command, int total_len)
{
@@ -1013,6 +1019,9 @@
} else if (!strncmp(pos, "count", strlen("count"))) {
reg = M_HOGSQS_TXCFE_DET_CNT;
pos2 = pos + strlen("count");
+ } else if (!strncmp(pos, "hnrecovery", strlen("hnrecovery"))) {
+ reg = HOGSQS_CMD_HNRECOVER;
+ pos2 = pos + strlen("hnrecovery");
} else {
DHD_ERROR(("%s: Error wrong argument is on %s \n", __FUNCTION__,
CMD_AP_HOGSQS));
@@ -1501,6 +1510,35 @@
return bytes_written;
}
+/* returns bsscolor using wpa_cli driver command "driver bsscolor" */
+#ifdef WL11AX
+int wl_android_get_bsscolor(struct net_device *dev, char *command, int total_len)
+{
+ bcm_xtlv_t read_he_xtlv_subcmd;
+ int err = 0;
+ int bytes_written = 0;
+ u8 color = 0;
+ u8 ioctl_buf[WLC_IOCTL_SMLEN]= {0};
+ read_he_xtlv_subcmd.id = WL_HE_CMD_BSSCOLOR;
+ read_he_xtlv_subcmd.len = 0;
+
+ /* To get fw iovars of the form wl he bsscolor call the
+ parent iovar with the subcmd filled and passed along */
+ err = wldev_iovar_getbuf(dev, "he", &read_he_xtlv_subcmd, sizeof(read_he_xtlv_subcmd),
+ ioctl_buf, sizeof(ioctl_buf), NULL);
+
+ if (unlikely(err)) {
+ WL_ERR(("he bsscolor failed. Error (%d)\n", err));
+ return err;
+ } else {
+ color = *(u8 *)ioctl_buf;
+ }
+
+ bytes_written = snprintf(command, total_len, "%d", color);
+ return bytes_written;
+}
+#endif /* WL11AX */
+
/* returns current datarate datarate returned from firmware are in 500kbps */
#ifdef AUTOMOTIVE_FEATURE
int wl_android_get_datarate(struct net_device *dev, char *command, int total_len)
@@ -10128,6 +10166,11 @@
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);
}
+#ifdef WL11AX
+ else if (strnicmp(command, CMD_GETBSSCOLOR, strlen(CMD_GETBSSCOLOR)) == 0) {
+ bytes_written = wl_android_get_bsscolor(net, command, priv_cmd.total_len);
+ }
+#endif /* WL11AX */
else {
DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL");
@@ -10553,7 +10596,7 @@
}
s32
-wl_cfg80211_static_if_open(struct net_device *net)
+wl_cfg80211_static_if_open(struct net_device *net, u8 *mac_addr)
{
struct wireless_dev *wdev = NULL;
struct bcm_cfg80211 *cfg = wl_get_cfg(net);
@@ -10568,7 +10611,7 @@
return BCME_ERROR;
}
if (static_if_ndev_get_state(cfg, net) != NDEV_STATE_FW_IF_CREATED) {
- wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, NULL);
+ wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, mac_addr);
if (!wdev) {
WL_ERR(("[STATIC_IF] wdev is NULL, can't proceed"));
return BCME_ERROR;
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 9e3f9f4..19021bf 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 driver
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -36,6 +36,7 @@
#include <bcmutils.h>
#include <bcmstdlib_s.h>
#include <bcmwifi_channels.h>
+#include <bcmwifi_rspec.h>
#include <bcmendian.h>
#include <ethernet.h>
#ifdef WL_WPS_SYNC
@@ -58,6 +59,9 @@
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
+#include <linux/bitfield.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) */
#include <linux/wait.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
@@ -123,6 +127,10 @@
#include <dhd_bandsteer.h>
#endif /* DHD_BANDSTEER */
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+
#ifdef BCMWAPI_WPI
/* these items should evetually go into wireless.h of the linux system headfile dir */
#ifndef IW_ENCODE_ALG_SM4
@@ -182,6 +190,7 @@
#define IBSS_IF_NAME "ibss%d"
#endif /* WLAIBSS_MCHAN */
+#define DHD_IOVAR_BUF_SIZE 128
#ifdef VSDB
/* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */
#define DEFAULT_SLEEP_TIME_VSDB 120
@@ -506,6 +515,45 @@
NULL
};
+#if defined(WL11AX) || defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
+bool
+wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len)
+{
+ he_xtlv_v32 *v32 = ctx;
+
+ *id = v32->id;
+ *len = v32->len;
+
+ return FALSE;
+}
+
+void
+wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf)
+{
+ he_xtlv_v32 *v32 = ctx;
+
+ BCM_REFERENCE(id);
+ BCM_REFERENCE(len);
+
+ v32->val = htod32(v32->val);
+
+ switch (v32->len) {
+ case sizeof(uint8):
+ *buf = (uint8)v32->val;
+ break;
+ case sizeof(uint16):
+ store16_ua(buf, (uint16)v32->val);
+ break;
+ case sizeof(uint32):
+ store32_ua(buf, v32->val);
+ break;
+ default:
+ /* ASSERT(0); */
+ break;
+ }
+}
+#endif /* WL11AX || WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
+
typedef struct wl_vndr_oui_entry {
uchar oui[DOT11_OUI_LEN];
struct list_head list;
@@ -566,12 +614,25 @@
struct net_device *dev, u8 *mac,
struct station_info *sinfo);
#endif // endif
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+static int wl_cfg80211_set_bitrate(struct wiphy *wiphy,
+ struct net_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ unsigned int link_id,
+#endif // endif
+ const u8 *addr,
+ const struct cfg80211_bitrate_mask *mask);
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
+
static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
+#if defined(WL_FILS) || defined(WL_OWE)
#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 /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
+#endif /* defined(WL_FILS) || defined(WL_OWE) */
static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code);
#if defined(WL_CFG80211_P2P_DEV_IF)
@@ -680,7 +741,11 @@
s32 wl_cfg80211_add_del_bss(struct bcm_cfg80211 *cfg,
struct net_device *ndev, s32 bsscfg_idx,
wl_iftype_t brcm_iftype, s32 del, u8 *addr);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+static s32 wl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || \
+ defined(WL_COMPAT_WIRELESS)
static s32 wl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
#ifdef GTK_OFFLOAD_SUPPORT
@@ -710,6 +775,16 @@
struct cfg80211_external_auth_params *params);
#endif /* WL_SAE */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static int wl_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
+ s32 rssi_thold, u32 rssi_hyst);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+static int wl_cfg80211_update_owe_info(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_update_owe_info *owe_info);
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+
/*
* event & event Q handlers for cfg80211 interfaces
*/
@@ -750,6 +825,14 @@
static s32 wl_handle_rssi_monitor_event(struct bcm_cfg80211 *wl, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data);
#endif /* RSSI_MONITOR_SUPPORT */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static s32 wl_notify_rssi_change_ind(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+ const wl_event_msg_t *e, void *data);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+static s32 wl_notify_beacon_loss(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+ const wl_event_msg_t *e, void *data);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_net_info,
enum wl_status state, bool set);
#ifdef CUSTOM_EVENT_PM_WAKE
@@ -1246,6 +1329,10 @@
&he_cap->he_cap_elem;
struct ieee80211_he_mcs_nss_supp *he_mcs =
&he_cap->he_mcs_nss_supp;
+#ifdef WL_6E
+ struct ieee80211_he_6ghz_capa *he_6ghz_capa = &data->he_6ghz_capa;
+ u16 sixghz_capa = 0;
+#endif /* WL_6E */
if(data == NULL) {
WL_ERR(("failed to allco mem\n"));
@@ -1254,47 +1341,95 @@
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 MAC Capabilities Information */
+ he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE |
+ IEEE80211_HE_MAC_CAP0_TWT_REQ |
+ IEEE80211_HE_MAC_CAP0_TWT_RES;
+
+ he_cap_elem->mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US |
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
+
+ he_cap_elem->mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_BSR |
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT;
+
+ he_cap_elem->mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 |
+#else
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 |
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+ IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+ he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
+#else
+ he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+
+ /* HE PHY Capabilities Information */
+ he_cap_elem->phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_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 |
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
+
+ he_cap_elem->phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2 |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM;
+
+ he_cap_elem->phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8;
+
+ he_cap_elem->phy_cap_info[5] = IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
+ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
+
+ he_cap_elem->phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
+#else
+ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+ IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
+
+ he_cap_elem->phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
+ IEEE80211_HE_PHY_CAP7_MAX_NC_1;
+
+ he_cap_elem->phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G;
+
+ he_cap_elem->phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
+
+ /* HE Supported MCS and NSS Set */
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));
+
+#ifdef WL_6E
+ if (band == NL80211_BAND_6GHZ) {
+ sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
+ IEEE80211_HT_MPDU_DENSITY_8);
+ sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
+ IEEE80211_VHT_MAX_AMPDU_1024K);
+ sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
+ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454);
+ sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
+ WLAN_HT_CAP_SM_PS_DISABLED);
+ sixghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
+ sixghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
+ he_6ghz_capa->capa = cpu_to_le16(sixghz_capa);
+ }
+#endif /* WL_6E */
+
return idx;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21) */
@@ -6610,6 +6745,7 @@
}
#endif /* WL_FILS */
+#if defined(WL_FILS) || defined(WL_OWE)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
#define UPDATE_ASSOC_IES BIT(0)
#ifndef UPDATE_FILS_ERP_INFO
@@ -6663,6 +6799,7 @@
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
+#endif /* defined(WL_FILS) || defined(WL_OWE) */
#ifdef WL_SAE
static int
@@ -6789,6 +6926,72 @@
}
#endif /* WL_SAE */
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+static int wl_cfg80211_set_bitrate(struct wiphy *wiphy,
+ struct net_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ unsigned int link_id,
+#endif // endif
+ const u8 *addr,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ int he = 0;
+ uint32 rspec = 0;
+ uint8 hegi;
+ char iovbuf[WLC_IOCTL_SMLEN];
+ int ret = BCME_OK, band = 0;
+
+ ret = wldev_iovar_getint(dev, "he", &he);
+ if (unlikely(ret)) {
+ WL_ERR(("error reading he (%d)\n", ret));
+ return -ENOTSUPP;
+ }
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ if (band != NL80211_BAND_2GHZ && band != NL80211_BAND_5GHZ &&
+ band != NL80211_BAND_6GHZ) {
+ continue;
+ }
+
+ /* Skip setting HE rates if legacy rate set is called from userspace */
+ if (!mask->control[band].he_mcs[0]) {
+ continue;
+ }
+
+ if (he) {
+ rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */
+ rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | mask->control[band].he_mcs[0];
+ /* set the other rspec fields */
+ hegi = mask->control[band].he_gi;
+ rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0);
+
+ if (band == NL80211_BAND_2GHZ) {
+ ret = wldev_iovar_setbuf(dev, "2g_rate", (char *)&rspec, 4,
+ iovbuf, WLC_IOCTL_SMLEN, NULL);
+ }
+ if (band == NL80211_BAND_5GHZ) {
+ ret = wldev_iovar_setbuf(dev, "5g_rate", (char *)&rspec, 4,
+ iovbuf, WLC_IOCTL_SMLEN, NULL);
+ }
+ if (band == NL80211_BAND_6GHZ) {
+ ret = wldev_iovar_setbuf(dev, "6g_rate", (char *)&rspec, 4,
+ iovbuf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+ if (unlikely(ret)) {
+ WL_ERR(("%s: set rate failed, retcode = %d\n",
+ __FUNCTION__, ret));
+ }
+ }
+ else {
+ WL_ERR(("Only HE supported\n"));
+ return -ENOTSUPP;
+ }
+ }
+ return ret;
+}
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
+
#define MAX_SCAN_ABORT_WAIT_CNT 20
#define WAIT_SCAN_ABORT_OSL_SLEEP_TIME 10
@@ -7356,7 +7559,12 @@
wdev = dev->ieee80211_ptr;
wait_cnt = WAIT_FOR_DISCONNECT_STATE_SYNC;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ while ((wdev->connected) && wait_cnt) {
+#else
while ((wdev->current_bss) && wait_cnt) {
+#endif // endif
WL_DBG(("Waiting for disconnect sync, wait_cnt: %d\n", wait_cnt));
wait_cnt--;
OSL_SLEEP(50);
@@ -7364,7 +7572,12 @@
if (wait_cnt == 0) {
/* state didn't get cleared within given timeout */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ WL_INFORM_MEM(("cfg80211 state. wdev->connected is true\n"));
+#else
WL_INFORM_MEM(("cfg80211 state. wdev->current_bss non null\n"));
+#endif // endif
} else {
WL_MEM(("cfg80211 disconnect state sync done\n"));
}
@@ -10420,7 +10633,7 @@
}
timeout = wait_for_completion_timeout(&netinfo->mgmt_tx_cpl,
- MGMT_AUTH_FRAME_WAIT_TIME);
+ msecs_to_jiffies(MGMT_AUTH_FRAME_WAIT_TIME));
if ((timeout > 0) || test_bit(MGMT_TX_ACK, &netinfo->mgmt_txstatus)) {
WL_DBG(("TX auth frame operation is success\n"));
ack = true;
@@ -10688,7 +10901,13 @@
}
set_channel:
+#ifdef WL_6E
+ if (chan->band == IEEE80211_BAND_6GHZ)
+ chspec = wf_channel2chspec6E(_chan, bw);
+ else
+#endif /* WL_6E */
chspec = wf_channel2chspec(_chan, bw);
+
if (wf_chspec_valid(chspec)) {
fw_chspec = wl_chspec_host_to_driver(chspec);
if (fw_chspec != INVCHANSPEC) {
@@ -11040,6 +11259,16 @@
wpa_auth |= WPA3_AUTH_1X_SUITE_B_SHA384;
break;
#endif /* WL_SAE */
+#ifdef WL_OWE
+ case RSN_AKM_OWE:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ wpa_auth |= WPA3_AUTH_OWE;
+#else
+ WL_ERR(("Kernel version 5.2 or higher supports for OWE AP\n"));
+ return BCME_ERROR;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+ break;
+#endif /* WL_OWE */
#endif /* MFP */
default:
WL_ERR(("No Key Mgmt Info\n"));
@@ -12640,6 +12869,16 @@
s32 bssidx = 0;
u32 dev_role = 0;
dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+#ifdef WL11AX
+#if (defined IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && \
+ LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)))
+ uint8 se_he_xtlv[32];
+ int se_he_xtlv_len= sizeof(se_he_xtlv);
+ he_xtlv_v32 v32;
+#endif /* IFX_CFG80211_5_4_21 ||
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) &&
+ LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)) */
+#endif /* WL11AX */
#ifdef WL11U
bcm_tlv_t *interworking_ie;
u32 iw_ie_len = 0;
@@ -12709,7 +12948,12 @@
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && !defined(WL_COMPAT_WIRELESS))
if ((err = wl_cfg80211_set_channel(wiphy, dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ dev->ieee80211_ptr->u.ap.preset_chandef.chan,
+#else
dev->ieee80211_ptr->preset_chandef.chan,
+#endif // endif
NL80211_CHAN_HT20) < 0)) {
WL_ERR(("Set channel failed \n"));
goto fail;
@@ -12768,6 +13012,34 @@
wl_set_drv_status(cfg, CONNECTED, dev);
WL_DBG(("** AP/GO Created **\n"));
+#ifdef WL11AX
+#if (defined IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && \
+ LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)))
+ /* Set he_bss_color in hostapd */
+ if (info->he_bss_color.enabled)
+ {
+ v32.id = WL_HE_CMD_BSSCOLOR;
+ v32.len = sizeof(s32);
+ v32.val = info->he_bss_color.color;
+ /* To set fw iovars of the form wl he bsscolor where
+ he is parent iovar followed by subcmd */
+ err = bcm_pack_xtlv_buf((void *)&v32, se_he_xtlv, sizeof(se_he_xtlv),
+ BCM_XTLV_OPTION_ALIGN32, wl_he_get_uint_cb, wl_he_pack_uint_cb,
+ &se_he_xtlv_len);
+ if (err != BCME_OK) {
+ WL_ERR(("failed to pack he bsscolor_xtlv=%d\n", err));
+ }
+ else {
+ err = wldev_iovar_setbuf_bsscfg(dev, "he", &se_he_xtlv, sizeof(se_he_xtlv),
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+ if (unlikely(err)) {
+ WL_ERR(("failed to set he bsscolor, error=%d\n", err));
+ }
+ }
+ }
+#endif /* IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19) */
+#endif /* WL11AX */
+
#ifdef WL_CFG80211_ACL
/* Enfoce Admission Control. */
if ((err = wl_cfg80211_set_mac_acl(wiphy, dev, info->acl)) < 0) {
@@ -12815,7 +13087,7 @@
/* Configure hidden SSID */
if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) {
if ((err = wldev_iovar_setint(dev, "closednet", 1)) < 0)
- WL_ERR(("failed to set hidden 1: %d\n", err));
+ WL_ERR(("failed to set hidden : %d\n", err));
WL_DBG(("hidden_ssid_enum_val: %d \n", info->hidden_ssid));
//add by qs.xiong 20221102 to fix ap unhidden fail
}else{
@@ -12835,7 +13107,12 @@
#endif /* SUPPORT_AP_RADIO_PWRSAVE */
#ifdef ENABLE_HOGSQS
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ chan_h = dev->ieee80211_ptr->u.ap.preset_chandef.chan;
+#else
chan_h = dev->ieee80211_ptr->preset_chandef.chan;
+#endif // endif
if (chan_h->band == IEEE80211_BAND_5GHZ) {
s32 value = 0x0;
@@ -12856,7 +13133,12 @@
if (err) {
WL_ERR(("ADD/SET beacon failed\n"));
wl_flush_fw_log_buffer(dev, FW_LOGSET_MASK_ALL);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ wl_cfg80211_stop_ap(wiphy, dev, 0);
+#else
wl_cfg80211_stop_ap(wiphy, dev);
+#endif // endif
if (dev_role == NL80211_IFTYPE_AP) {
dhd->op_mode &= ~DHD_FLAG_HOSTAP_MODE;
#ifdef PKT_FILTER_SUPPORT
@@ -12889,10 +13171,19 @@
return err;
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+static s32
+wl_cfg80211_stop_ap(
+ struct wiphy *wiphy,
+ struct net_device *dev,
+ unsigned int link_id)
+#else
static s32
wl_cfg80211_stop_ap(
struct wiphy *wiphy,
struct net_device *dev)
+#endif // endif
{
int err = 0;
u32 dev_role = 0;
@@ -13639,6 +13930,9 @@
.sched_scan_start = wl_cfg80211_sched_scan_start,
.sched_scan_stop = wl_cfg80211_sched_scan_stop,
#endif /* WL_SCHED_SCAN */
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+ .set_bitrate_mask = wl_cfg80211_set_bitrate,
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
2, 0))
.del_station = wl_cfg80211_del_station,
@@ -13676,6 +13970,12 @@
#ifdef WL_SAE
.external_auth = wl_cfg80211_external_auth,
#endif /* WL_SAE */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ .set_cqm_rssi_config = wl_cfg80211_set_cqm_rssi_config,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ .update_owe_info = wl_cfg80211_update_owe_info,
+#endif /* WL_OWE && LINUX_VERSION_CODE > KERNEL_VERSION(5, 2, 0) */
};
s32 wl_mode_to_nl80211_iftype(s32 mode)
@@ -13701,9 +14001,11 @@
bool notify, bool user_enforced, int revinfo)
{
s32 ret = BCME_OK;
-#ifdef WL_NAN
+#if defined(WL_NAN) || (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
struct wireless_dev *wdev = ndev_to_wdev(net);
struct wiphy *wiphy = wdev->wiphy;
+#endif // endif
+#ifdef WL_NAN
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
if (cfg->nan_enable) {
mutex_lock(&cfg->if_sync);
@@ -13720,6 +14022,13 @@
if (ret < 0) {
WL_ERR(("set country Failed :%d\n", ret));
}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+ else {
+ /* Notification new country hints */
+ if (notify && !(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED))
+ regulatory_hint(wiphy, country_code);
+ }
+#endif // endif
return ret;
}
@@ -13749,6 +14058,162 @@
return BCME_OK;
}
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+enum regdom_freq_bands wl_get_regdom_freq_bands(int channel) {
+ enum regdom_freq_bands area = WL_REGRULE_2G;
+ if (channel > 0 && channel <=13)
+ area = WL_REGRULE_2G;
+ else if (channel == 14)
+ area = WL_REGRULE_2G_14;
+ else if (channel >= 36 && channel <= 48)
+ area = WL_REGRULE_5G_UNII1;
+ else if (channel >= 52 && channel <= 64)
+ area = WL_REGRULE_5G_UNII2A;
+ else if (channel >= 100 && channel <=144)
+ area = WL_REGRULE_5G_UNII2C;
+ else if (channel >= 149 && channel <=165)
+ area = WL_REGRULE_5G_UNII3;
+ return area;
+}
+
+int
+wl_construct_regrule(struct wiphy *wiphy, struct ieee80211_reg_rule *rules, int *nrules)
+{
+ int i,j;
+ int index = 0;
+ struct ieee80211_supported_band *band;
+ struct ieee80211_channel *channels;
+ struct ieee80211_reg_rule *rule;
+
+ if (rules == NULL)
+ return BCME_BADARG;
+
+ *nrules = 0;
+ for( i = IEEE80211_BAND_2GHZ; i <= IEEE80211_BAND_5GHZ; ++i){
+ int maxbw = 20;
+ band = wiphy->bands[i];
+ if (!band)
+ continue;
+ channels = &band->channels[0];
+
+ /* get max bw from channel.flags */
+ for( j = 0; j < band->n_channels; ++j) {
+ if (channels[j].flags == IEEE80211_CHAN_NO_HT40)
+ maxbw = MAX(maxbw, 20);
+ else if ( (channels[j].flags == IEEE80211_CHAN_NO_HT40PLUS) ||
+ (channels[j].flags == IEEE80211_CHAN_NO_HT40MINUS))
+ maxbw = MAX(maxbw, 40);
+ }
+ if ( band->vht_cap.vht_supported )
+ maxbw = MAX(maxbw, 80);
+
+ /* filling tables for reg_rule per channels */
+ for( j = 0; j < band->n_channels; ++j) {
+ index = wl_get_regdom_freq_bands(channels[j].hw_value);
+ rule = &rules[index];
+ if (channels[j].flags & IEEE80211_CHAN_DISABLED)
+ continue;
+ if (rule->freq_range.start_freq_khz == 0) {
+ (*nrules)++;
+ /* adding default information */
+ rule->freq_range.start_freq_khz =
+ MHZ_TO_KHZ(channels[j].center_freq - 10);
+ rule->freq_range.end_freq_khz =
+ MHZ_TO_KHZ(channels[j].center_freq + 10);
+ rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(maxbw);
+ rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
+ rule->power_rule.max_eirp = DBM_TO_MBM(20);
+ /* adding regulatory flags */
+ if ( i == IEEE80211_BAND_5GHZ)
+ rule->flags |= NL80211_RRF_AUTO_BW;
+ if (channels[j].flags & IEEE80211_CHAN_RADAR)
+ rule->flags |= NL80211_RRF_DFS | NL80211_RRF_NO_IR;
+ if (channels[j].flags & IEEE80211_CHAN_NO_IR)
+ rule->flags |= NL80211_RRF_NO_IR;
+
+ rule->dfs_cac_ms = 0;
+ }
+ else {
+ rule->freq_range.end_freq_khz =
+ MHZ_TO_KHZ(channels[j].center_freq + 10);
+ }
+ }
+ }
+ for(i=0;i<WL_REGRULE_MAX;++i) {
+ if (rules[i].freq_range.start_freq_khz) {
+ WL_DBG(("new regdom[%d] - (%d - %d @ %d), (%d, %d), %x\n", i,
+ rules[i].freq_range.start_freq_khz,
+ rules[i].freq_range.end_freq_khz,
+ rules[i].freq_range.max_bandwidth_khz,
+ rules[i].power_rule.max_antenna_gain,
+ rules[i].power_rule.max_eirp, rules[i].flags));
+ }
+ }
+ return BCME_OK;
+}
+
+static struct ieee80211_regdomain *wl_get_regdom(struct wiphy *wiphy)
+{
+ int err = BCME_OK;
+ struct ieee80211_regdomain *regd = NULL;
+ struct ieee80211_reg_rule *rules = NULL;
+ int nrules = 0;
+ struct bcm_cfg80211 *cfg;
+ struct net_device *dev;
+ dhd_pub_t *dhdp;
+ wl_country_t cspec;
+ int len, i;
+ gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+
+ cfg = wiphy_priv(wiphy);
+ dhdp = (struct dhd_pub *)(cfg->pub);
+ if (!cfg || !cfg->wdev || !dhdp) {
+ goto done;
+ }
+ dev = bcmcfg_to_prmry_ndev(cfg);
+ if (!dev) {
+ goto done;
+ }
+
+ rules = kzalloc(sizeof(struct ieee80211_reg_rule) * WL_REGRULE_MAX, flags);
+
+ if (wl_construct_regrule(wiphy, rules, &nrules) == BCME_OK) {
+ len = sizeof(struct ieee80211_regdomain) +
+ sizeof(struct ieee80211_reg_rule) * nrules;
+ regd = kzalloc(len, flags);
+ regd->alpha2[0] = '9';
+ regd->alpha2[1] = '9';
+ for( i = 0; i < WL_REGRULE_MAX; ++i) {
+ if (rules[i].freq_range.start_freq_khz) {
+ memcpy(®d->reg_rules[regd->n_reg_rules++],
+ &rules[i], sizeof(struct ieee80211_reg_rule));
+ }
+ }
+ }
+ else {
+ /* if failed to get reg_rules, use brcm_regdom */
+ len = sizeof(brcm_regdom);
+ regd = kmemdup(&brcm_regdom, len, flags);
+ }
+ kfree(rules);
+
+ /* get current country code, if nothing, get from firmware. */
+ if (dhdp->dhd_cspec.ccode[0] && dhdp->dhd_cspec.ccode[1])
+ memcpy(&cspec, &dhdp->dhd_cspec, sizeof(wl_country_t));
+ else
+ err = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
+done:
+ if (regd && err == BCME_OK) {
+ /* mapping current country code */
+ regd->alpha2[0] = cspec.ccode[0];
+ regd->alpha2[1] = cspec.ccode[1];
+ }
+
+ return regd;
+}
+
+#endif /* WL_SELF_MANAGED_REGDOM */
+
#ifdef WL_SAE
static s32 wl_wiphy_update_sae(struct wiphy *wiphy, dhd_pub_t *dhd)
{
@@ -13760,6 +14225,11 @@
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SAE_OFFLOAD);
WL_DBG(("%s intsae enabled\n", __FUNCTION__));
}
+
+ if (FW_SUPPORTED(dhd, ap_pmksa)) {
+ WL_ERR(("Firmware support AP PMKSA\n"));
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+ }
return BCME_OK;
}
#endif /* WL_SAE */
@@ -13892,7 +14362,8 @@
#endif /* WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS)
- wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+ if (FW_SUPPORTED(dhd, tdls))
+ wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
#endif // endif
#if defined(CONFIG_PM) && defined(WL_CFG80211_P2P_DEV_IF)
@@ -13909,18 +14380,12 @@
* Note: wiphy->wowlan_config is freed by cfg80211 layer.
* so use malloc instead of MALLOC(osh) to avoid false alarm.
*/
- brcm_wowlan_config = kmalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL);
+ brcm_wowlan_config = kzalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL);
if (brcm_wowlan_config) {
brcm_wowlan_config->disconnect = true;
brcm_wowlan_config->gtk_rekey_failure = true;
brcm_wowlan_config->eap_identity_req = true;
brcm_wowlan_config->four_way_handshake = true;
- brcm_wowlan_config->patterns = NULL;
- brcm_wowlan_config->n_patterns = 0;
- brcm_wowlan_config->tcp = NULL;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
- brcm_wowlan_config->nd_config = NULL;
-#endif // endif
} else {
WL_ERR(("Can not allocate memory for brcm_wowlan_config,"
" So wiphy->wowlan_config is set to NULL\n"));
@@ -13938,12 +14403,17 @@
#endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */
WL_DBG(("Registering custom regulatory)\n"));
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+ wdev->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
+ wdev->wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
+#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
wdev->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
#else
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0) */
wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
+#endif /* WL_SELF_MANAGED_REGDOM */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
WL_INFORM_MEM(("Registering Vendor80211\n"));
@@ -13975,6 +14445,9 @@
#ifdef WL_SAE
wdev->wiphy->features |= NL80211_FEATURE_SAE;
+ if (FW_SUPPORTED(dhd, ap_pmksa)) {
+ wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+ }
#endif /* WL_SAE */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)) && defined(BCMSUP_4WAY_HANDSHAKE)
if (FW_SUPPORTED(dhd, idsup)) {
@@ -16026,8 +16499,14 @@
ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
if (ndev) {
wdev = ndev->ieee80211_ptr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ wdev->u.client.ssid_len = min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN);
+ memcpy(wdev->u.client.ssid, ssid->SSID, wdev->u.client.ssid_len);
+#else
wdev->ssid_len = min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN);
memcpy(wdev->ssid, ssid->SSID, wdev->ssid_len);
+#endif // endif
WL_ERR(("SSID is %s\n", ssid->SSID));
wl_update_prof(cfg, ndev, NULL, ssid, WL_PROF_SSID);
} else {
@@ -16072,6 +16551,71 @@
}
#endif /* RSSI_MONITOR_SUPPORT */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static s32
+wl_notify_rssi_change_ind(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+ const wl_event_msg_t *e, void *data)
+{
+ wl_event_data_rssi_t *value = (struct wl_event_data_rssi *)data;
+ u32 event = ntoh32(e->event_type);
+ u32 status = ntoh32(e->status);
+ u32 reason = ntoh32(e->reason);
+ s32 rssi = 0;
+
+ WL_DBG(("Enter: event %d (%d), status=%d\n",
+ event, reason, status));
+
+ if (!cfg->cqm_info.enable)
+ return 0;
+
+ rssi = ntohl(value->rssi);
+ cfg80211_cqm_rssi_notify(wdev->netdev,
+ (rssi > cfg->cqm_info.rssi_threshold ?
+ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH :
+ NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW),
+ rssi, GFP_KERNEL);
+
+ return 0;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+static s32
+wl_notify_beacon_loss(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+ const wl_event_msg_t *e, void *data)
+{
+ struct cfg80211_bss *bss;
+ struct wiphy *wiphy = bcmcfg_to_wiphy(cfg);
+ struct wl_profile *profile = wl_get_profile_by_netdev(cfg, wdev->netdev);
+
+ if (!profile)
+ return WL_INVALID;
+
+ if (!us_ap_select)
+ return 0;
+
+ WL_DBG(("Enter: event %d (%d), status=%d\n",
+ ntoh32(e->event_type), ntoh32(e->status), ntoh32(e->reason)));
+
+ /* On beacon loss event, supplicant will trigger new scan request
+ * with NL80211_SCAN_FLAG_FLUSH Flag set, but the flushed AP bss entry
+ * still remains as it is still held by cfg in associated state. Unlinking this
+ * current BSS from cfg cached bss list on beacon loss event here
+ * would allow supplicant to receive new scanned entries
+ * without current bss and select new bss to trigger roam.
+ */
+ bss = CFG80211_GET_BSS(wiphy, NULL, profile->bssid, 0, 0);
+ if (bss) {
+ cfg80211_unlink_bss(wiphy, bss);
+ cfg80211_put_bss(wiphy, bss);
+ }
+
+ cfg80211_cqm_beacon_loss_notify(wdev->netdev, GFP_KERNEL);
+
+ return 0;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
+
static s32
wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data)
@@ -16796,8 +17340,14 @@
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) || defined(WL_FILS_ROAM_OFFLD) || \
defined(CFG80211_ROAM_API_GE_4_12)
memset(&roam_info, 0, sizeof(struct cfg80211_roam_info));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ roam_info.links[0].channel = notify_channel;
+ roam_info.links[0].bssid = curbssid;
+#else
roam_info.channel = notify_channel;
roam_info.bssid = curbssid;
+#endif // endif
roam_info.req_ie = conn_info->req_ie;
roam_info.req_ie_len = conn_info->req_ie_len;
roam_info.resp_ie = conn_info->resp_ie;
@@ -17752,6 +18302,47 @@
}
isfree = true;
#endif /* WL_SAE */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ } else if (event == WLC_E_EXT_ASSOC_FRAME_RX) {
+ struct cfg80211_update_owe_info owe_info;
+ bcm_tlv_t *owe_info_ie = NULL;
+ u8 *ies = NULL;
+ u32 ies_len;
+
+ WL_DBG(("EVENT: WLC_E_EXT_ASSOC_FRAME_RX received\n"));
+
+ if (ndev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
+ WL_ERR(("OWE ASSOC REQ: not AP I/F\n"));
+ return -EINVAL;
+ }
+
+ ies = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1) + DOT11_MGMT_HDR_LEN;
+ ies_len = mgmt_frame_len - DOT11_MGMT_HDR_LEN;
+
+ ies += DOT11_ASSOC_REQ_FIXED_LEN;
+ if (ies_len <= DOT11_ASSOC_REQ_FIXED_LEN) {
+ WL_ERR(("OWE ASSOC REQ: event data too small. Ignoring event\n"));
+ return -EINVAL;
+ }
+ ies_len -= DOT11_ASSOC_REQ_FIXED_LEN;
+
+ memset(&owe_info, 0, sizeof(struct cfg80211_update_owe_info));
+ memcpy(owe_info.peer, e->addr.octet, ETH_ALEN);
+ owe_info.ie = ies;
+ owe_info.ie_len = ies_len;
+
+ owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info.ie, owe_info.ie_len, DOT11_MNG_RSN_ID);
+ if (owe_info_ie)
+ WL_INFORM(("OWE ASSOC REQ: found RSNIE"));
+
+ owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info.ie, owe_info.ie_len, DOT11_MNG_ID_EXT_ID);
+ if (owe_info_ie && DOT11_OWE_DH_PARAM_IE(owe_info_ie))
+ WL_INFORM(("OWE ASSOC REQ: found OWE DH PARAM"));
+
+ cfg80211_update_owe_info_event(ndev, &owe_info, GFP_KERNEL);
+
+ return 0;
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
} else {
mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
@@ -17945,6 +18536,15 @@
cfg->evt_handler[WLC_E_LDF_HOGGER] = wl_cfg80211_hogsqs_notify;
#endif /* ENABLE_HOGSQS */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ cfg->evt_handler[WLC_E_RSSI] = wl_notify_rssi_change_ind;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+ cfg->evt_handler[WLC_E_BCNLOST_MSG] = wl_notify_beacon_loss;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ cfg->evt_handler[WLC_E_EXT_ASSOC_FRAME_RX] = wl_notify_rx_mgmt_frame;
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
}
#if defined(STATIC_WL_PRIV_STRUCT)
@@ -18549,6 +19149,7 @@
u32 chan = 0;
struct net_device *primary_dev = bcmcfg_to_prmry_ndev(cfg);
dhd_pub_t *dhd = cfg->pub;
+ s32 ifidx = DHD_BAD_IF;
#ifdef RTT_SUPPORT
rtt_status_info_t *rtt_status;
#endif /* RTT_SUPPORT */
@@ -18556,6 +19157,12 @@
WL_ERR(("busstate is DHD_BUS_DOWN!\n"));
return 0;
}
+
+ ifidx = dhd_net2idx(dhd->info, _net_info->ndev);
+ if (ifidx == DHD_BAD_IF) {
+ WL_ERR(("ifidx is invalid\n"));
+ return BCME_ERROR;
+ }
WL_DBG(("Enter state %d set %d _net_info->pm_restore %d iface %s\n",
state, set, _net_info->pm_restore, _net_info->ndev->name));
@@ -18646,6 +19253,9 @@
wl_cfg80211_set_frameburst(cfg, FALSE);
}
#endif /* DISABLE_WL_FRAMEBURST_SOFTAP */
+#ifdef WL11AX
+ wl_twt_cleanup_session_records(dhd, (u8)ifidx);
+#endif /* WL11AX */
}
return err;
}
@@ -20150,8 +20760,23 @@
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
}
- if (notify)
- wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+ if (notify) {
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+ if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
+ struct ieee80211_regdomain *regd = wl_get_regdom(wiphy);
+ regulatory_set_wiphy_regd(wiphy, regd);
+ kfree(regd);
+ }
+ else
+#endif // endif
+ {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+#endif // endif
+ wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+ }
+
+ }
#ifdef WL_SAE
(void)wl_wiphy_update_sae(wiphy, dhd);
#endif /* WL_SAE */
@@ -20446,8 +21071,14 @@
u8 *latest_bssid = wl_read_prof(cfg, ndev, WL_PROF_LATEST_BSSID);
struct wiphy *wiphy = bcmcfg_to_wiphy(cfg);
struct wireless_dev *wdev = ndev->ieee80211_ptr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ struct cfg80211_bss *bss = CFG80211_GET_BSS(wiphy, NULL, latest_bssid,
+ wdev->u.client.ssid, wdev->u.client.ssid_len);
+#else
struct cfg80211_bss *bss = CFG80211_GET_BSS(wiphy, NULL, latest_bssid,
wdev->ssid, wdev->ssid_len);
+#endif // endif
BCM_REFERENCE(bss);
@@ -22344,13 +22975,20 @@
}
/*
- * 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.
+ * skip parsing the HE capab, oper & 6GHz Band capab 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.
+ * Skip guarding with WL11AX flag because these IEs being
+ * supplied from hostapd, using 11ax enabled hostapd and
+ * 11ax disabled DHD (in case of legacy chips), guarding
+ * under WL11AX flag would cause this code to be skipped
+ * causing double IE addition issue (one from fw and one
+ * dhd).
*/
if ((ie->data[0] == EXT_MNG_HE_CAP_ID) ||
- (ie->data[0] == EXT_MNG_HE_OP_ID)) {
+ (ie->data[0] == EXT_MNG_HE_OP_ID) ||
+ (ie->data[0] == EXT_MNG_HE_6GBAND_CAP_ID)) {
goto end;
}
} else {
@@ -22986,6 +23624,13 @@
}
+#ifdef WL_6E
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION (5, 4, 0))
+ if (CHSPEC_IS6G(chanspec))
+ freq = ieee80211_channel_to_frequency(channel, NL80211_BAND_6GHZ);
+ else
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION (5, 4, 0) */
+#endif /* WL_6E */
if (CHSPEC_IS5G(chanspec))
freq = ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
else
@@ -23059,7 +23704,11 @@
WL_ERR(("chspec_chandef failed\n"));
return;
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 8, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+ defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+ freq = chandef.chan ? chandef.chan->center_freq : chandef.center_freq1;
+ cfg80211_ch_switch_notify(dev, &chandef, 0);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 8, 0))
freq = chandef.chan ? chandef.chan->center_freq : chandef.center_freq1;
cfg80211_ch_switch_notify(dev, &chandef);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 5, 0) && (LINUX_VERSION_CODE <= (3, 7, \
@@ -25515,50 +26164,8 @@
MFREE(cfg->osh, ver_ptr, alloc_len);
}
+
#if defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
-typedef struct {
- uint16 id;
- uint16 len;
- uint32 val;
-} he_xtlv_v32;
-
- static bool
-wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len)
-{
- he_xtlv_v32 *v32 = ctx;
-
- *id = v32->id;
- *len = v32->len;
-
- return FALSE;
-}
-
- static void
-wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf)
-{
- he_xtlv_v32 *v32 = ctx;
-
- BCM_REFERENCE(id);
- BCM_REFERENCE(len);
-
- v32->val = htod32(v32->val);
-
- switch (v32->len) {
- case sizeof(uint8):
- *buf = (uint8)v32->val;
- break;
- case sizeof(uint16):
- store16_ua(buf, (uint16)v32->val);
- break;
- case sizeof(uint32):
- store32_ua(buf, v32->val);
- break;
- default:
- /* ASSERT(0); */
- break;
- }
-}
-
int wl_cfg80211_set_he_mode(struct net_device *dev, struct bcm_cfg80211 *cfg,
s32 bssidx, u32 interface_type, bool set)
{
@@ -25921,6 +26528,41 @@
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static int wl_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev, s32 rssi_thold, u32 rssi_hyst)
+{
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ wl_rssi_event_t rssi = {};
+ int err = 0;
+
+ if (rssi_thold == 0) {
+ cfg->cqm_info.enable = 0;
+ cfg->cqm_info.rssi_threshold = 0;
+ } else {
+ cfg->cqm_info.enable = 1;
+ cfg->cqm_info.rssi_threshold = rssi_thold;
+
+ rssi.rate_limit_msec = 0;
+ rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MIN;
+ rssi.rssi_levels[rssi.num_rssi_levels++] =
+ cfg->cqm_info.rssi_threshold;
+ rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MAX;
+ }
+
+ err = wldev_iovar_setbuf(dev, "rssi_event", &rssi, sizeof(rssi),
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
+
+ if (err < 0)
+ WL_ERR(("set rssi_event iovar failed (%d)\n", err));
+
+ WL_DBG(("enable = %d, rssi_threshold = %d\n",
+ cfg->cqm_info.enable, cfg->cqm_info.rssi_threshold));
+
+ return err;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
#ifdef WL_WIPSEVT
int
wl_cfg80211_wips_event(uint16 misdeauth, char* bssid)
@@ -26013,3 +26655,41 @@
cfg80211_vendor_event(skb, kflags);
}
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1) */
+
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+static int wl_cfg80211_update_owe_info(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_update_owe_info *owe_info)
+{
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ bcm_tlv_t *owe_info_ie = NULL;
+ s32 bssidx = -1;
+ int ret = BCME_OK;
+
+ if (owe_info->status != DOT11_SC_SUCCESS) {
+ /* may need to pass down unsuccessful status to the firmware */
+ WL_DBG(("Update OWE info failure status %d\n", owe_info->status));
+ } else {
+ owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info->ie, owe_info->ie_len, DOT11_MNG_RSN_ID);
+ if (owe_info_ie)
+ WL_INFORM(("Update OWE info found RSNIE"));
+
+ owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info->ie, owe_info->ie_len, DOT11_MNG_ID_EXT_ID);
+ if (owe_info_ie && DOT11_OWE_DH_PARAM_IE(owe_info_ie))
+ WL_INFORM(("Update OWE info found OWE DH PARAM"));
+
+ bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr);
+ if (bssidx == WL_INVALID) {
+ WL_DBG(("I/F not available. Do nothing.\n"));
+ return -EINVAL;
+ }
+
+ ret = wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx,
+ VNDR_IE_ASSOCRSP_FLAG, owe_info->ie, owe_info->ie_len);
+ if (ret) {
+ WL_ERR(("error(%d) updating vndr ies\n", ret));
+ }
+ }
+
+ return ret;
+}
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index a8557ed..d1e400b 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 driver
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -607,6 +607,18 @@
TDLS_STATE_NMI_CREATE
};
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+enum regdom_freq_bands {
+ WL_REGRULE_2G = 0, /* 1 - 13 */
+ WL_REGRULE_2G_14, /* 14 */
+ WL_REGRULE_5G_UNII1, /* 36 - 48 */
+ WL_REGRULE_5G_UNII2A, /* 52 - 64 */
+ WL_REGRULE_5G_UNII2C, /* 100 - 144 */
+ WL_REGRULE_5G_UNII3, /* 149 - 165 */
+ WL_REGRULE_MAX
+};
+#endif /* WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
+
/* beacon / probe_response */
struct beacon_proberesp {
__le64 timestamp;
@@ -1231,6 +1243,13 @@
const void *data_buf[1]; /* array of user space buffer pointers. */
} buf_data_t;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+struct cqm_rssi_info {
+ bool enable;
+ s32 rssi_threshold;
+};
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
/* private data of cfg80211 interface */
struct bcm_cfg80211 {
struct wireless_dev *wdev; /* representing cfg cfg80211 device */
@@ -1255,6 +1274,9 @@
struct wl_scan_results *bss_list;
struct wl_scan_results *scan_results;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ struct cqm_rssi_info cqm_info; /* trigger cqm event for rssi based bgscan */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
/* scan request object for internal purpose */
struct wl_scan_req *scan_req_int;
/* information element object for internal purpose */
@@ -1538,6 +1560,17 @@
CONCURRENCY_RSDB_MODE
} wl_concurrency_mode_t;
+#if defined(WL11AX) || defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
+typedef struct {
+ uint16 id;
+ uint16 len;
+ uint32 val;
+} he_xtlv_v32;
+
+bool wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len);
+void wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf);
+#endif /* WL11AX || WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
+
s32 wl_iftype_to_mode(wl_iftype_t iftype);
#define BCM_LIST_FOR_EACH_ENTRY_SAFE(pos, next, head, member) \
@@ -2606,7 +2639,7 @@
extern struct net_device *wl_cfg80211_register_static_if(struct bcm_cfg80211 *cfg,
u16 iftype, char *ifname, int ifidx);
extern void wl_cfg80211_unregister_static_if(struct bcm_cfg80211 * cfg);
-extern s32 wl_cfg80211_static_if_open(struct net_device *net);
+extern s32 wl_cfg80211_static_if_open(struct net_device *net, u8 *mac_addr);
extern s32 wl_cfg80211_static_if_close(struct net_device *net);
extern struct net_device * wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211 *cfg,
wl_if_event_info *event, u8 *addr, s32 iface_type, const char *iface_name);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
old mode 100644
new mode 100755
index fa567bc..463e748
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -1,9 +1,9 @@
/*
* Linux cfgp2p driver
*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -384,7 +384,11 @@
wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
{
struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
+#ifdef P2P_RAND
+ struct ether_addr *p2p_dev_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE);
+#else
struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } };
+#endif /* P2P_RAND */
s32 ret = BCME_OK;
s32 val = 0;
/* Do we have to check whether APSTA is enabled or not ? */
@@ -419,8 +423,14 @@
* After Initializing firmware, we have to set current mac address to
* firmware for P2P device address
*/
- ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
- sizeof(null_eth_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#ifdef P2P_RAND
+ //Override default firmware mac setting for p2p dev interface
+ ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", p2p_dev_addr,
+ sizeof(*p2p_dev_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#else
+ ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
+ sizeof(null_eth_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#endif /* P2P_RAND */
if (ret && ret != BCME_UNSUPPORTED) {
CFGP2P_ERR(("failed to update device address ret %d\n", ret));
}
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
index ba5cc7e..866e843 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 driver scan related code
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -717,7 +717,7 @@
WL_INFORM_MEM(("ESCAN ABORTED\n"));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
- if (p2p_scan(cfg) && cfg->scan_request &&
+ if (p2p_is_on(cfg) && p2p_scan(cfg) && cfg->scan_request &&
(cfg->scan_request->flags & NL80211_SCAN_FLAG_FLUSH)) {
WL_ERR(("scan list is changed"));
cfg->bss_list = wl_escan_get_buf(cfg, FALSE);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
index 3dd8083..c905a3d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 Vendor Extension Code
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -91,7 +91,12 @@
#ifdef PROP_TXSTATUS
#include <dhd_wlfc.h>
#endif // endif
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+#include <bcmiov.h>
#include <brcm_nl80211.h>
+#include <ifx_nl80211.h>
char*
wl_get_kernel_timestamp(void)
@@ -453,7 +458,11 @@
wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* GSCAN_SUPPORT */
@@ -1321,7 +1330,11 @@
static int wl_cfgvendor_set_rssi_monitor(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* RSSI_MONITOR_SUPPORT */
@@ -1466,7 +1479,11 @@
wl_cfgvendor_get_wake_reason_stats(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* DHD_WAKE_STATUS */
@@ -1536,19 +1553,19 @@
return err;
}
-#ifndef CONFIG_SOC_S5E5515
static int
wl_cfgvendor_set_random_mac(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
- int err = BCME_OK;
WL_ERR(("ANDR_WIFI_ATTRIBUTE_RANDOM_MAC is not available\n"));
- err = BCME_UNSUPPORTED;
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
+ return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
- return err;
}
-#endif /* CONFIG_SOC_S5E5515 */
static int
wl_cfgvendor_set_tx_power_scenario(struct wiphy *wiphy,
@@ -1648,14 +1665,22 @@
wl_cfgvendor_chavoid_set_config(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int
wl_cfgvendor_usable_channel(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#ifdef RTT_SUPPORT
void
@@ -6403,7 +6428,11 @@
static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* LINKSTAT_SUPPORT */
@@ -6885,38 +6914,62 @@
wl_cfgvendor_dbg_trigger_mem_dump(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int
wl_cfgvendor_dbg_get_mem_dump(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_start_logging(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_reset_logging(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_get_ring_status(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_get_ring_data(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* DEBUGABILITY */
@@ -7417,6 +7470,127 @@
return ret;
}
+#ifdef WL11AX
+static int wl_cfgvendor_priv_muedca_opt_enable(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ int ret = BCME_OK;
+ uint val = *(uint *)data;
+ struct net_device *dev;
+ uint8 se_he_xtlv[32];
+ bcm_xtlv_t read_he_xtlv_subcmd;
+ int se_he_xtlv_len = sizeof(se_he_xtlv);
+ s32 bssidx = 0;
+ int err = 0;
+ int ioctl_buf[WLC_IOCTL_SMLEN/2] = {0};
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ read_he_xtlv_subcmd.id = WL_HE_CMD_MUEDCA_OPT;
+ read_he_xtlv_subcmd.len = 0;
+ dev = wdev_to_ndev(wdev);
+
+ if (val == 0xa) {
+ /* To get fw iovars of the form "wl he muedca_opt_enable" using iw,call the
+ parent iovar "he" with the subcmd filled and passed along
+ ./iw dev wlan0 vendor recv 0x000319 0xb 0xa */
+ ret = wldev_iovar_getbuf(dev, "he", &read_he_xtlv_subcmd, sizeof(read_he_xtlv_subcmd),
+ ioctl_buf, sizeof(ioctl_buf), NULL);
+ if (ret) {
+ WL_ERR(("Failed : %d\n", ret));
+ } else {
+ WL_DBG(("Get muedca_opt_enable : %d\n", *(int *)ioctl_buf));
+ err = wl_cfgvendor_send_cmd_reply(wiphy,ioctl_buf, sizeof(int));
+ if (unlikely(err)) {
+ WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+ }
+ }
+ } else {
+ read_he_xtlv_subcmd.len = sizeof(s32);
+ read_he_xtlv_subcmd.data[0] = val;
+ WL_DBG(("Enable muedca"));
+ err = bcm_pack_xtlv_buf((void *)&read_he_xtlv_subcmd, se_he_xtlv, sizeof(se_he_xtlv),
+ BCM_XTLV_OPTION_ALIGN32, wl_he_get_uint_cb, wl_he_pack_uint_cb,
+ &se_he_xtlv_len);
+ if (err) {
+ WL_ERR(("failed to pack he muedca_opt=%d\n", err));
+ } else {
+ /* To set fw iovars of the form "wl he muedca_opt_enable" using iw where
+ "he" is the parent iovar followed by subcmd
+ ./iw dev wlan0 vendor send 0x000319 0xb 0x1 */
+ err = wldev_iovar_setbuf_bsscfg(dev, "he", &se_he_xtlv, sizeof(se_he_xtlv),
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+ if (unlikely(err)) {
+ WL_ERR(("failed to set he muedca_opt_enable, error=%d\n", err));
+ }
+ }
+ }
+ return ret;
+}
+#endif /* WL11AX */
+
+static int wl_cfgvendor_priv_ldpc_cap(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ int ret = BCME_OK;
+ int val = *(int *)data;
+ int get_ldpc_cap = 0;
+ int err = 0;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+ if (val == 0xa) {
+ ret = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "ldpc_cap", &get_ldpc_cap);
+ if (ret) {
+ WL_ERR(("Failed : %d\n", ret));
+ } else {
+ WL_DBG(("Get ldpc_cap : %d\n", get_ldpc_cap));
+ err = wl_cfgvendor_send_cmd_reply(wiphy, &get_ldpc_cap, sizeof(int));
+ if (unlikely(err)) {
+ WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+ }
+ }
+ } else {
+ WL_DBG(("Set ldpc_cap %d\n", val));
+ ret = wldev_iovar_setint(bcmcfg_to_prmry_ndev(cfg), "ldpc_cap", val);
+ if (ret < 0) {
+ WL_ERR(("Failed to set ldpc_cap, ret=%d\n", ret));
+ } else {
+ WL_DBG(("ldpc_cap is %s\n", val ? "enabled" : "disabled"));
+ }
+ }
+ return ret;
+}
+
+static int wl_cfgvendor_priv_amsdu(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ int ret = BCME_OK;
+ int val = *(int *)data;
+ int get_amsdu = 0;
+ int err = 0;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+ if (val == 0xa) {
+ ret = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "amsdu", &get_amsdu);
+ if (ret) {
+ WL_ERR(("Failed : %d\n", ret));
+ } else {
+ WL_DBG(("Get amsdu : %d\n", get_amsdu));
+ err = wl_cfgvendor_send_cmd_reply(wiphy, &get_amsdu, sizeof(int));
+ if (unlikely(err)) {
+ WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+ }
+ }
+ } else {
+ WL_DBG(("Set amsdu %d\n", val));
+ ret = wldev_iovar_setint(bcmcfg_to_prmry_ndev(cfg), "amsdu", val);
+ if (ret < 0) {
+ WL_ERR(("Failed to set amsdu, ret=%d\n", ret));
+ } else {
+ WL_DBG(("amsdu is %s\n", val ? "enabled" : "disabled"));
+ }
+ }
+ return ret;
+}
+
static int wl_cfgvendor_dbg_get_version(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
@@ -7578,19 +7752,31 @@
static int wl_cfgvendor_dbg_start_pkt_fate_monitoring(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_get_tx_pkt_fates(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int wl_cfgvendor_dbg_get_rx_pkt_fates(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* DBG_PKT_MON */
@@ -7608,6 +7794,7 @@
uint8 src_mac[ETHER_ADDR_LEN];
uint8 dst_mac[ETHER_ADDR_LEN];
uint32 period_msec = 0;
+ uint16 ether_type = ETHERTYPE_IP;
const struct nlattr *iter;
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
dhd_pub_t *dhd_pub = cfg->pub;
@@ -7653,6 +7840,15 @@
case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC:
period_msec = nla_get_u32(iter);
break;
+ case MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE:
+ ether_type = nla_get_u16(iter);
+ if (!((ether_type == ETHERTYPE_IP) ||
+ (ether_type == ETHERTYPE_IPV6))) {
+ WL_ERR(("Invalid ether type, %2x\n", ether_type));
+ ret = BCME_BADARG;
+ goto exit;
+ }
+ break;
default:
WL_ERR(("Unknown type: %d\n", type));
ret = BCME_BADARG;
@@ -7667,7 +7863,7 @@
}
ret = dhd_dev_start_mkeep_alive(dhd_pub, mkeep_alive_id, ip_pkt, ip_pkt_len, src_mac,
- dst_mac, period_msec);
+ dst_mac, period_msec, ether_type);
if (ret < 0) {
WL_ERR(("start_mkeep_alive is failed ret: %d\n", ret));
}
@@ -7861,7 +8057,11 @@
dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
if (dhdp && !FW_SUPPORTED(dhdp, ndoe)) {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ ret = -EOPNOTSUPP;
+#else
ret = WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
goto exit;
}
@@ -7890,7 +8090,11 @@
static int wl_cfgvendor_configure_nd_offload(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#endif /* NDO_CONFIG_SUPPORT */
@@ -7983,18 +8187,83 @@
return ret;
}
+#ifdef P2P_RAND
+static int
+wl_cfgvendor_set_p2p_rand_mac(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ int type, err = 0;
+
+ if (!data) {
+ WL_ERR(("%s data is not available\n",__FUNCTION__));
+ return -EINVAL;
+ }
+ if (len <= 0) {
+ WL_ERR(("%s invalid len %d\n",__FUNCTION__, len));
+ return -EINVAL;
+ }
+ if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) {
+ WL_ERR(("%s wrong interface type , wdev->iftype=%d\n",__FUNCTION__,wdev->iftype));
+ return -EINVAL;
+ }
+
+ BCM_REFERENCE(cfg);
+ type = nla_type(data);
+ if (type == BRCM_ATTR_DRIVER_MAC_ADDR || type == IFX_VENDOR_ATTR_MAC_ADDR) {
+ if (nla_len(data) != ETHER_ADDR_LEN) {
+ WL_ERR(("%s nla_len is not ethernet address \n",__FUNCTION__));
+ err = -EINVAL;
+ goto exit;
+ }
+ //setting p2p device address
+ (void)memcpy_s(wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE), ETHER_ADDR_LEN,
+ nla_data(data), ETHER_ADDR_LEN);
+ (void)memcpy_s(wdev->address, ETHER_ADDR_LEN, nla_data(data), ETHER_ADDR_LEN);
+ err = wl_cfgp2p_disable_discovery(cfg);
+ if (unlikely(err < 0)) {
+ WL_ERR(("%s P2P disable discovery failed, ret=%d\n",__FUNCTION__, err));
+ goto exit;
+ }
+ err = wl_cfgp2p_set_firm_p2p(cfg);
+ if (unlikely(err < 0)) {
+ WL_ERR(("%s Set P2P_da_override failed ret=%d\n",__FUNCTION__, err));
+ goto exit;
+ }
+ err = wl_cfgp2p_enable_discovery(cfg, bcmcfg_to_prmry_ndev(cfg), NULL, 0);
+ if (unlikely(err < 0)) {
+ WL_ERR(("%s P2P enable discovery failed, ret=%d\n",__FUNCTION__, err));
+ goto exit;
+ }
+ } else {
+ WL_ERR(("%s unexpected attrib type:%d\n", __FUNCTION__,type));
+ return -EINVAL;
+ }
+exit:
+ return err;
+}
+#endif /* P2P_RAND */
+
static int
wl_cfgvendor_set_multista_primary_connection(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
static int
wl_cfgvendor_set_multista_use_case(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int len)
{
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ return -EOPNOTSUPP;
+#else
return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
}
#ifdef WL_SUPPORT_ACS_OFFLOAD
@@ -8442,7 +8711,268 @@
return ret;
}
-#endif // endif
+#endif /* WL_SUPPORT_ACS_OFFLOAD */
+
+#ifdef WL11AX
+static void
+wl_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, wl_twt_param_t *twt_param)
+{
+ int tmp, twt_param_attr;
+ const struct nlattr *twt_param_iter;
+
+ nla_for_each_nested(twt_param_iter, attr_iter, tmp) {
+ twt_param_attr = nla_type(twt_param_iter);
+ switch (twt_param_attr) {
+ case IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE:
+ twt_param->negotiation_type = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE:
+ twt_param->setup_cmd = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN:
+ twt_param->dialog_token = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME:
+ twt_param->twt = nla_get_u64(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET:
+ twt_param->twt_offset = nla_get_u64(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION:
+ twt_param->min_twt = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT:
+ twt_param->exponent = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA:
+ twt_param->mantissa = nla_get_u16(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR:
+ twt_param->requestor = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER:
+ twt_param->trigger = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT:
+ twt_param->implicit = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE:
+ twt_param->flow_type = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID:
+ twt_param->flow_id = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID:
+ twt_param->bcast_twt_id = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION:
+ twt_param->protection = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL:
+ twt_param->twt_channel = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED:
+ twt_param->twt_info_frame_disabled =
+ nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT:
+ twt_param->min_twt_unit = nla_get_u8(twt_param_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT:
+ twt_param->teardown_all_twt =
+ nla_get_u8(twt_param_iter);
+ break;
+ default:
+ WL_INFORM(("Unknown TWT param, skipping"));
+ break;
+ }
+ }
+}
+
+int wl_cfgvendor_twt(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int len)
+{
+ int tmp, attr_type;
+ const struct nlattr *attr_iter;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ struct net_device *pri_ndev = bcmcfg_to_prmry_ndev(cfg);
+
+ wl_twt_param_t twt_param = {
+ .twt_oper = 0,
+ .negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT,
+ .setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST,
+ .dialog_token = 1,
+ .twt = 0,
+ .twt_offset = 0,
+ .requestor = 1,
+ .trigger = 0,
+ .implicit = 1,
+ .flow_type = 0,
+ .flow_id = 0,
+ .bcast_twt_id = 0,
+ .protection = 0,
+ .twt_channel = 0,
+ .twt_info_frame_disabled = 0,
+ .min_twt_unit = 0,
+ .teardown_all_twt = 0
+ };
+
+ nla_for_each_attr(attr_iter, data, len, tmp) {
+ attr_type = nla_type(attr_iter);
+
+ switch (attr_type) {
+ case IFX_VENDOR_ATTR_TWT_OPER:
+ twt_param.twt_oper = nla_get_u8(attr_iter);
+ break;
+ case IFX_VENDOR_ATTR_TWT_PARAMS:
+ wl_cfgvendor_twt_parse_params(attr_iter, &twt_param);
+ break;
+ default:
+ WL_INFORM(("Unknown TWT attribute %d, skipping",
+ attr_type));
+ break;
+ }
+ }
+
+ return wl_twt_oper(pri_ndev, wdev, twt_param);
+}
+
+#endif /* WL11AX */
+
+static int wl_cfgvendor_oce_enable(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ int ret = BCME_OK;
+ uint8 val = *(uint8 *)data;
+ struct net_device *dev;
+ s32 bssidx = 0;
+ int err = 0;
+ uint8 oce_xtlv[WLC_IOCTL_SMLEN] = {0};
+ bcm_iov_buf_t iov_buf_data, *iov_buf = NULL;
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ dev = wdev_to_ndev(wdev);
+
+ if (val == 0xa) {
+ bcm_xtlv_t *pxtlv_recv = NULL;
+ iov_buf_data.version = WL_OCE_IOV_VERSION;
+ iov_buf_data.id = WL_OCE_CMD_ENABLE;
+
+ /* To get fw iovars of the form "wl oce enable" using iw,call the
+ * parent iovar "oce" with the subcmd filled and passed along
+ * ./iw dev wlan0 vendor recv 0x000319 0xf 0xa */
+ ret = wldev_iovar_getbuf(dev, "oce", &iov_buf_data, sizeof(iov_buf_data),
+ oce_xtlv, sizeof(oce_xtlv), NULL);
+
+ if (ret) {
+ WL_ERR(("Failed to get oce enable: %d\n", ret));
+ } else {
+ iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+ pxtlv_recv = (bcm_xtlv_t *)((uint8 *)iov_buf->data);
+ WL_DBG(("Get oce_enable : %d\n", pxtlv_recv->data[0]));
+ err = wl_cfgvendor_send_cmd_reply(wiphy, &pxtlv_recv->data[0], sizeof(int));
+ if (unlikely(err)) {
+ WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+ return err;
+ }
+ }
+ } else {
+ uint8 *pxtlv_data = NULL;
+ uint16 buflen = 0, buflen_start = 0, iovlen = 0;
+ iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+ iov_buf->version = WL_OCE_IOV_VERSION;
+ iov_buf->id = WL_OCE_CMD_ENABLE;
+ pxtlv_data = (uint8 *)&iov_buf->data[0];
+ buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+ ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+ sizeof(val), &val, BCM_XTLV_OPTION_ALIGN32);
+ if (ret != BCME_OK) {
+ WL_ERR(("Failed to enable oce: %d\n", ret));
+ } else {
+ iov_buf->len = buflen_start - buflen;
+ iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len;
+
+ /* To set fw iovars of the form "wl oce enable 1" using iw,call the
+ * parent iovar "oce" with the subcmd filled and passed along
+ * ./iw dev wlan0 vendor recv 0x000319 0xf 0x1 */
+ err = wldev_iovar_setbuf_bsscfg(dev, "oce", (void *)iov_buf, iovlen,
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+ if (unlikely(err)) {
+ WL_ERR(("Failed to set oce enable, error=:%d\n", err));
+ return err;
+ }
+ }
+ }
+ return ret;
+}
+
+static int wl_cfgvendor_randmac(struct wiphy *wiphy,
+ struct wireless_dev *wdev, const void *data, int len)
+{
+ int ret = BCME_OK;
+ wl_randmac_t *iov_buf = NULL;
+ uint8 val = *(uint8 *)data;
+ struct net_device *dev;
+ s32 bssidx = 0;
+ int err = 0;
+ uint8 randmac_xtlv[WLC_IOCTL_SMLEN] = {0};
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+ dev = wdev_to_ndev(wdev);
+
+ iov_buf = (wl_randmac_t *)randmac_xtlv;
+ iov_buf->version = WL_RANDMAC_API_VERSION;
+ iov_buf->subcmd_id = WL_RANDMAC_SUBCMD_ENABLE;
+ iov_buf->len = WL_RANDMAC_IOV_HDR_SIZE;
+
+ if (val == 0x1) {
+ /* To set fw iovars of the form "wl randmac enable" using iw,call the
+ * parent iovar "randmac" with the subcmd filled and passed along
+ * ./iw dev wlan0 vendor send 0x000319 0x11 0x1 */
+ ret = wldev_iovar_setbuf_bsscfg(dev, "randmac", (void *)iov_buf, iov_buf->len,
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+ if (ret) {
+ WL_ERR(("Failed to set randmac enable: %d\n", ret));
+ return ret;
+ }
+ } else if (val == 0x0) {
+ iov_buf->subcmd_id = WL_RANDMAC_SUBCMD_DISABLE;
+
+ /* To set fw iovars of the form "wl randmac disable" using iw,call the
+ * parent iovar "randmac" with the subcmd filled and passed along
+ * ./iw dev wlan0 vendor send 0x000319 0x11 0x0 */
+ ret = wldev_iovar_setbuf_bsscfg(dev, "randmac", (void *)iov_buf, iov_buf->len,
+ cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+ if (ret) {
+ WL_ERR(("Failed to set randmac disable: %d\n", ret));
+ return ret;
+ }
+ } else if (val == 0xa) {
+ int result_data = 0;
+ wl_randmac_t *iov_resp = NULL;
+ uint8 resp_xtlv[WLC_IOCTL_SMLEN] = {0};
+
+ /* To get fw iovars of the form "wl randmac" using iw,call the
+ * parent iovar "randmac" with the subcmd filled and passed along
+ * ./iw dev wlan0 vendor recv 0x000319 0x11 0xa */
+ ret = wldev_iovar_getbuf(dev, "randmac", (void *)iov_buf, iov_buf->len,
+ resp_xtlv, sizeof(resp_xtlv), NULL);
+ if (ret) {
+ WL_ERR(("Failed to get randmac enable or disable: %d\n", ret));
+ return ret;
+ } else {
+ iov_resp = (wl_randmac_t *)resp_xtlv;
+ if(iov_resp->subcmd_id == WL_RANDMAC_SUBCMD_ENABLE) {
+ result_data = 1;
+ }
+ err = wl_cfgvendor_send_cmd_reply(wiphy, &result_data, sizeof(int));
+ if (unlikely(err)) {
+ WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+ return err;
+ }
+ }
+ }
+ return ret;
+}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
#define WL_VENDOR_POLICY_RAW_DATA .policy = VENDOR_CMD_RAW_DATA
@@ -8450,6 +8980,7 @@
const struct nla_policy brcm_drv_attr_policy[BRCM_ATTR_DRIVER_MAX] = {
[BRCM_ATTR_DRIVER_CMD] = {.type = NLA_NUL_STRING},
[BRCM_ATTR_DRIVER_KEY_PMK] = {.type = NLA_BINARY},
+ [BRCM_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN },
};
const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = {
@@ -8535,6 +9066,52 @@
[DEBUG_ATTRIBUTE_HANG_REASON] = {.type = NLA_BINARY},
};
+#ifdef DHD_LOG_DUMP
+const struct nla_policy google_file_dump_event_policy[DUMP_EVENT_ATTR_MAX] = {
+ [DUMP_LEN_ATTR_MEMDUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C0_D11_BEFORE] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C0_D11_AFTER] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C1_D11_BEFORE] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C1_D11_AFTER] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C2_D11_BEFORE] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_C2_D11_AFTER] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_DIG_BEFORE] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SSSR_DIG_AFTER] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_TIMESTAMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_GENERAL_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_ECNTRS] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SPECIAL_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_DHD_DUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_EXT_TRAP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_HEALTH_CHK] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_PRESERVE_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_COOKIE] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_FLOWRING_DUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_PKTLOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_PKTLOG_DEBUG] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_DEBUG_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_MEM_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_PKTLOG_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_STATUS_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_AXI_ERROR] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_AXI_ERROR_DUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_RTT_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_SDTC_ETB_DUMP] = {.type = NLA_BINARY},
+ [DUMP_FILENAME_ATTR_SDTC_ETB_DUMP] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_PKTID_MAP_LOG] = {.type = NLA_BINARY},
+ [DUMP_LEN_ATTR_PKTID_UNMAP_LOG] = {.type = NLA_BINARY}
+};
+#endif /* DHD_LOG_DUMP */
+
const struct nla_policy hal_start_attr_policy[SET_HAL_START_ATTRIBUTE_MAX] = {
[SET_HAL_START_ATTRIBUTE_DEINIT] = {.type = NLA_UNSPEC},
[SET_HAL_START_ATTRIBUTE_PRE_INIT] = {.type = NLA_NUL_STRING},
@@ -8601,6 +9178,48 @@
#define WL_VENDOR_POLICY_RAW_DATA
#endif /* LINUX_VER >= 5.3 */
+#ifdef WL11AX
+const struct nla_policy
+ifx_vendor_attr_twt_param_policy[IFX_VENDOR_ATTR_TWT_PARAM_MAX + 1] = {
+ [IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME] = {.type = NLA_U64},
+ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET] = {.type = NLA_U64},
+ [IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA] = {.type = NLA_U16},
+ [IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAM_MAX] = {.type = NLA_U8},
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+const struct nla_policy ifx_vendor_attr_twt_policy[IFX_VENDOR_ATTR_TWT_MAX + 1] = {
+ [IFX_VENDOR_ATTR_TWT_UNSPEC] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_OPER] = {.type = NLA_U8},
+ [IFX_VENDOR_ATTR_TWT_PARAMS] =
+ NLA_POLICY_NESTED(ifx_vendor_attr_twt_param_policy),
+ [IFX_VENDOR_ATTR_TWT_MAX] = {.type = NLA_U8},
+};
+#endif
+
+#endif /* WL11AX */
+
+const struct nla_policy ifx_vendor_attr_policy[IFX_VENDOR_ATTR_MAX + 1] = {
+ [IFX_VENDOR_ATTR_MAC_ADDR] = {.type = NLA_BINARY, .len = ETHER_ADDR_LEN},
+};
+
static const struct wiphy_vendor_command wl_vendor_cmds [] = {
{
{
@@ -8669,6 +9288,33 @@
#endif // endif
},
#endif /* WL_SAE */
+#ifdef P2P_RAND
+ {
+ {
+ .vendor_id = OUI_BRCM,
+ .subcmd = BRCM_VENDOR_SCMD_SET_MAC
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
+ .doit = wl_cfgvendor_set_p2p_rand_mac,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = brcm_drv_attr_policy,
+ .maxattr = BRCM_ATTR_DRIVER_MAX
+#endif /* LINUX_VERSION >= 5.3 */
+ },
+
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_SET_P2P_RAND_MAC
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
+ .doit = wl_cfgvendor_set_p2p_rand_mac,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = ifx_vendor_attr_policy,
+ .maxattr = IFX_VENDOR_ATTR_MAX
+#endif /* LINUX_VERSION >= 5.3 */
+ },
+#endif /* P2P_RAND */
{
{
.vendor_id = OUI_GOOGLE,
@@ -8988,7 +9634,12 @@
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = wl_cfgvendor_dbg_file_dump,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = google_file_dump_event_policy,
+ .maxattr = DUMP_EVENT_ATTR_MAX
+#else
WL_VENDOR_POLICY_RAW_DATA
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
},
#endif /* DHD_LOG_DUMP */
{
@@ -9108,7 +9759,12 @@
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = wl_cfgvendor_start_mkeep_alive,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = mkeep_alive_attr_policy,
+ .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
+#else
WL_VENDOR_POLICY_RAW_DATA
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
},
{
{
@@ -9117,7 +9773,12 @@
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = wl_cfgvendor_stop_mkeep_alive,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = mkeep_alive_attr_policy,
+ .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
+#else
WL_VENDOR_POLICY_RAW_DATA
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
},
#endif /* KEEP_ALIVE */
#ifdef WL_NAN
@@ -9490,8 +10151,77 @@
.maxattr = BRCM_VENDOR_ATTR_ACS_LAST
#endif /* LINUX_VERSION >= 5.3 */
},
+#endif /* WL_SUPPORT_ACS_OFFLOAD */
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_FRAMEBURST
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_priv_frameburst,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
+#ifdef WL11AX
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_priv_muedca_opt_enable,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
+#endif /* WL11AX */
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_LDPC_CAP
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_priv_ldpc_cap,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_AMSDU
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_priv_amsdu,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
+#ifdef WL11AX
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_TWT
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_twt,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+ .policy = ifx_vendor_attr_twt_policy,
+ .maxattr = IFX_VENDOR_ATTR_TWT_MAX
#endif // endif
-
+ },
+#endif /* WL11AX */
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_OCE_ENABLE
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_oce_enable,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
+ {
+ {
+ .vendor_id = OUI_IFX,
+ .subcmd = IFX_VENDOR_SCMD_RANDMAC
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wl_cfgvendor_randmac,
+ WL_VENDOR_POLICY_RAW_DATA
+ },
};
static const struct nl80211_vendor_cmd_info wl_vendor_events [] = {
@@ -9539,13 +10269,14 @@
{ OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO},
{ OUI_BRCM, BRCM_VENDOR_EVENT_ACS},
{ OUI_BRCM, BRCM_VENDOR_EVENT_OVERTEMP},
+ { OUI_IFX, IFX_VENDOR_SCMD_TWT},
};
int wl_cfgvendor_attach(struct wiphy *wiphy, dhd_pub_t *dhd)
{
- WL_INFORM_MEM(("Vendor: Register BRCM cfg80211 vendor cmd(0x%x) interface \n",
- NL80211_CMD_VENDOR));
+ WL_INFORM_MEM(("Vendor: Register BRCM,GOOGLE,IFX cfg80211 vendor cmd(0x%x) interface \n",
+ NL80211_CMD_VENDOR));
wiphy->vendor_commands = wl_vendor_cmds;
wiphy->n_vendor_commands = ARRAY_SIZE(wl_vendor_cmds);
@@ -9560,6 +10291,8 @@
dhd_os_dbg_register_urgent_notifier(dhd, wl_cfgvendor_dbg_send_file_dump_evt);
#endif /* DHD_LOG_DUMP */
+ BCM_REFERENCE(wl_cfgvendor_set_random_mac);
+
return 0;
}
@@ -9568,7 +10301,7 @@
#ifdef WL_SUPPORT_ACS_OFFLOAD
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
#endif // endif
- WL_INFORM_MEM(("Vendor: Unregister BRCM cfg80211 vendor interface \n"));
+ WL_INFORM_MEM(("Vendor: Unregister BRCM,GOOGLE,IFX cfg80211 vendor interface \n"));
wiphy->vendor_commands = NULL;
wiphy->vendor_events = NULL;
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
index c275efa..1dafa23 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 Vendor Extension Code
*
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -39,12 +39,15 @@
#define VENDOR_ID_OVERHEAD ATTRIBUTE_U32_LEN
#define VENDOR_SUBCMD_OVERHEAD ATTRIBUTE_U32_LEN
#define VENDOR_DATA_OVERHEAD (NLA_HDRLEN)
+#define ETHERTYPE_IP 0x0800 /* IP */
+#define ETHERTYPE_IPV6 0x86dd /* IP protocol version 6 */
enum brcm_vendor_attr {
BRCM_ATTR_DRIVER_CMD = 0,
BRCM_ATTR_DRIVER_KEY_PMK = 1,
BRCM_ATTR_DRIVER_FEATURE_FLAGS = 2,
- BRCM_ATTR_DRIVER_MAX = 3
+ BRCM_ATTR_DRIVER_MAC_ADDR = 3,
+ BRCM_ATTR_DRIVER_MAX = 4
};
enum brcm_wlan_vendor_features {
@@ -235,7 +238,10 @@
DEBUG_SET_HAL_START,
DEBUG_SET_HAL_STOP,
DEBUG_SET_HAL_PID,
-
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+ DEBUG_SET_TPUT_DEBUG_DUMP_CMD,
+ DEBUG_GET_BUF_RING_MAP,
+#endif // endif
WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
@@ -422,6 +428,9 @@
};
enum rtt_attributes {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
+ RTT_ATTRIBUTE_TARGET_INVALID,
+#endif // endif
RTT_ATTRIBUTE_TARGET_CNT,
RTT_ATTRIBUTE_TARGET_INFO,
RTT_ATTRIBUTE_TARGET_MAC,
@@ -446,7 +455,7 @@
};
enum wifi_rssi_monitor_attr {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
RSSI_MONITOR_ATTRIBUTE_INVALID,
#endif // endif
RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
@@ -462,7 +471,7 @@
};
enum debug_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
DEBUG_ATTRIBUTE_INVALID,
#endif // endif
DEBUG_ATTRIBUTE_GET_DRIVER,
@@ -495,6 +504,8 @@
DUMP_LEN_ATTR_SSSR_C0_D11_AFTER,
DUMP_LEN_ATTR_SSSR_C1_D11_BEFORE,
DUMP_LEN_ATTR_SSSR_C1_D11_AFTER,
+ DUMP_LEN_ATTR_SSSR_C2_D11_BEFORE,
+ DUMP_LEN_ATTR_SSSR_C2_D11_AFTER,
DUMP_LEN_ATTR_SSSR_DIG_BEFORE,
DUMP_LEN_ATTR_SSSR_DIG_AFTER,
DUMP_LEN_ATTR_TIMESTAMP,
@@ -508,19 +519,29 @@
DUMP_LEN_ATTR_COOKIE,
DUMP_LEN_ATTR_FLOWRING_DUMP,
DUMP_LEN_ATTR_PKTLOG,
+ DUMP_LEN_ATTR_PKTLOG_DEBUG,
DUMP_FILENAME_ATTR_DEBUG_DUMP,
DUMP_FILENAME_ATTR_MEM_DUMP,
DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP,
DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP,
DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP,
DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP,
+ DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP,
+ DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP,
DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP,
DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP,
DUMP_FILENAME_ATTR_PKTLOG_DUMP,
+ DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP,
DUMP_LEN_ATTR_STATUS_LOG,
DUMP_LEN_ATTR_AXI_ERROR,
DUMP_FILENAME_ATTR_AXI_ERROR_DUMP,
- DUMP_LEN_ATTR_RTT_LOG
+ DUMP_LEN_ATTR_RTT_LOG,
+ DUMP_LEN_ATTR_SDTC_ETB_DUMP,
+ DUMP_FILENAME_ATTR_SDTC_ETB_DUMP,
+ DUMP_LEN_ATTR_PKTID_MAP_LOG,
+ DUMP_LEN_ATTR_PKTID_UNMAP_LOG,
+ /* Please add new attributes from here to sync up old DHD */
+ DUMP_EVENT_ATTR_MAX
} EWP_DUMP_EVENT_ATTRIBUTE;
/* Attributes associated with DEBUG_GET_DUMP_BUF */
@@ -531,6 +552,8 @@
DUMP_BUF_ATTR_SSSR_C0_D11_AFTER,
DUMP_BUF_ATTR_SSSR_C1_D11_BEFORE,
DUMP_BUF_ATTR_SSSR_C1_D11_AFTER,
+ DUMP_BUF_ATTR_SSSR_C2_D11_BEFORE,
+ DUMP_BUF_ATTR_SSSR_C2_D11_AFTER,
DUMP_BUF_ATTR_SSSR_DIG_BEFORE,
DUMP_BUF_ATTR_SSSR_DIG_AFTER,
DUMP_BUF_ATTR_TIMESTAMP,
@@ -544,13 +567,19 @@
DUMP_BUF_ATTR_COOKIE,
DUMP_BUF_ATTR_FLOWRING_DUMP,
DUMP_BUF_ATTR_PKTLOG,
+ DUMP_BUF_ATTR_PKTLOG_DEBUG,
DUMP_BUF_ATTR_STATUS_LOG,
DUMP_BUF_ATTR_AXI_ERROR,
- DUMP_BUF_ATTR_RTT_LOG
+ DUMP_BUF_ATTR_RTT_LOG,
+ DUMP_BUF_ATTR_SDTC_ETB_DUMP,
+ DUMP_BUF_ATTR_PKTID_MAP_LOG,
+ DUMP_BUF_ATTR_PKTID_UNMAP_LOG,
+ /* Please add new attributes from here to sync up old DHD */
+ DUMP_BUF_ATTR_MAX
} EWP_DUMP_CMD_ATTRIBUTE;
enum mkeep_alive_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
MKEEP_ALIVE_ATTRIBUTE_INVALID,
#endif // endif
MKEEP_ALIVE_ATTRIBUTE_ID,
@@ -618,7 +647,7 @@
} wl_vendor_event_t;
enum andr_wifi_attr {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
ANDR_WIFI_ATTRIBUTE_INVALID,
#endif // endif
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
@@ -676,7 +705,7 @@
#ifdef DHD_WAKE_STATUS
enum wake_stat_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
WAKE_STAT_ATTRIBUTE_INVALID,
#endif // endif
WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c
new file mode 100755
index 0000000..e0438d3
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c
@@ -0,0 +1,754 @@
+/*
+ * Target Wake Time Module which is responsible for acting as an
+ * interface between the userspace and firmware.
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein. IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE. INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifdef WL11AX
+
+#include "wl_twt.h"
+
+static DEFINE_SPINLOCK(twt_session_list_lock);
+
+/*
+ * Nominal Minimum Wake Duration derivation from Wake Duration
+ */
+static inline void
+wl_twt_wake_dur_to_min_twt(uint32 wake_dur, uint8 *min_twt, uint8 *min_twt_unit)
+{
+ *min_twt = wake_dur / 102400;
+}
+
+/*
+ * Wake Duration derivation from Nominal Minimum Wake Duration
+ */
+static inline uint32
+wl_twt_min_twt_to_wake_dur(uint8 min_twt, uint8 min_twt_unit)
+{
+ uint32 wake_dur;
+
+ if (min_twt_unit == 1) {
+ /*
+ * If min_twt_unit is 1, then min_twt is
+ * in units of TUs (i.e) 102400 usecs.
+ */
+ wake_dur = (uint32)min_twt * 102400;
+ } else if (min_twt_unit == 0) {
+ /*
+ * If min_twt_unit is 0, then min_twt is
+ * in units of 256 usecs.
+ */
+ wake_dur = (uint32)min_twt * 256;
+ } else {
+ /* Invalid min_twt */
+ wake_dur = 0;
+ }
+
+ return wake_dur;
+}
+
+/*
+ * Wake Interval Mantissa & Exponent derivation from Wake Interval
+ */
+static inline void
+wl_twt_uint32_to_float(uint32 val, uint8 *exp, uint16 *mant)
+{
+ uint8 lzs = (uint8)CLZ(val); /* leading 0's */
+ uint8 shift = lzs < 16 ? 16 - lzs : 0;
+
+ *mant = (uint16)(val >> shift);
+ *exp = shift;
+}
+
+/*
+ * Wake Interval derivation from Wake Interval Mantissa & Exponent
+ */
+static inline uint32
+wl_twt_float_to_uint32(uint8 exponent, uint16 mantissa)
+{
+ return (uint32)mantissa << exponent;
+}
+
+wl_twt_session_t* wl_twt_lookup_session_by_flow_id(struct list_head *twt_session_list,
+ uint8 flow_id)
+{
+ wl_twt_session_t *iter = NULL;
+
+ list_for_each_entry(iter, twt_session_list, list) {
+ if (iter->twt_param.negotiation_type != IFX_TWT_PARAM_NEGO_TYPE_ITWT)
+ continue;
+
+ if (iter->twt_param.flow_id == flow_id)
+ return iter;
+ }
+
+ return NULL;
+}
+
+int wl_twt_add_session_to_list(struct list_head *twt_session_list, dhd_pub_t *dhd,
+ uint8 ifidx, wl_twt_param_t twt_param)
+{
+ int ret = BCME_OK;
+ wl_twt_session_t *new_twt_session;
+
+ new_twt_session = (wl_twt_session_t *)MALLOCZ(dhd->osh,
+ sizeof(wl_twt_session_t));
+ if (!new_twt_session) {
+ WL_ERR(("TWT: Failed to alloc memory for new session"));
+ ret = BCME_NOMEM;
+ goto exit;
+ }
+
+ new_twt_session->ifidx = ifidx;
+ new_twt_session->twt_param = twt_param;
+ new_twt_session->state = TWT_SESSION_SETUP_COMPLETE;
+
+ spin_lock_bh(&twt_session_list_lock);
+ WL_INFORM(("TWT: Adding TWT session with flow ID: %d", twt_param.flow_id));
+ list_add_tail(&new_twt_session->list, twt_session_list);
+exit:
+ spin_unlock_bh(&twt_session_list_lock);
+ return ret;
+}
+
+int wl_twt_del_session_by_flow_id(struct list_head *twt_session_list, uint8 flow_id)
+{
+ int ret = BCME_OK;
+ wl_twt_session_t *twt_session = NULL;
+
+ spin_lock_bh(&twt_session_list_lock);
+ twt_session = wl_twt_lookup_session_by_flow_id(twt_session_list, flow_id);
+ if (twt_session) {
+ WL_INFORM(("TWT: Deleting TWT session with flow ID: %d", flow_id));
+ list_del(&twt_session->list);
+ kfree(twt_session);
+ } else {
+ WL_INFORM(("TWT: TWT session with flow ID: %d is not found to be deleted",
+ flow_id));
+ ret = -1;
+ goto exit;
+ }
+exit:
+ spin_unlock_bh(&twt_session_list_lock);
+ return ret;
+}
+
+int wl_twt_count_session(struct list_head *twt_session_list)
+{
+ wl_twt_session_t *twt_session = NULL;
+ int ct = 0;
+
+ list_for_each_entry(twt_session, twt_session_list, list) {
+ if (twt_session->twt_param.negotiation_type ==
+ IFX_TWT_PARAM_NEGO_TYPE_ITWT)
+ ct++;
+ }
+
+ return ct;
+}
+
+void wl_twt_flush_session_list(struct list_head *twt_session_list, u8 ifidx)
+{
+ wl_twt_session_t *entry = NULL, *next = NULL;
+
+ spin_lock_bh(&twt_session_list_lock);
+ list_for_each_entry_safe(entry, next, twt_session_list, list) {
+ if ((ifidx != 0xFF) &&
+ (ifidx != entry->ifidx))
+ continue;
+
+ WL_INFORM(("TWT: Deleting TWT session with flow ID: %d",
+ entry->twt_param.flow_id));
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ spin_unlock_bh(&twt_session_list_lock);
+}
+
+int wl_twt_cleanup_session_records(dhd_pub_t *dhd, u8 ifidx)
+{
+ wl_twt_ctx_t *twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+ int ret = BCME_OK;
+
+ NULL_CHECK(twt_ctx,
+ "TWT: Failed to cleanup session records, Module not initialized",
+ ret);
+
+ wl_twt_flush_session_list(&twt_ctx->twt_session_list, ifidx);
+
+ return ret;
+}
+
+int wl_twt_setup(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+ wl_twt_param_t twt_param)
+{
+ wl_twt_setup_t val;
+ s32 bw = BCME_OK;
+ u8 mybuf[WLC_IOCTL_SMLEN] = {0};
+ u8 resp_buf[WLC_IOCTL_SMLEN] = {0};
+ uint8 *rem = mybuf;
+ uint16 rem_len = sizeof(mybuf);
+ wl_twt_session_t *twt_session = NULL;
+
+ bzero(&val, sizeof(val));
+ val.version = WL_TWT_SETUP_VER;
+ val.length = sizeof(val.version) + sizeof(val.length);
+
+ /* Default values, Override Below */
+ val.desc.flow_flags = 0x0;
+ val.desc.wake_dur = 0xFFFFFFFF;
+ val.desc.wake_int = 0xFFFFFFFF;
+ val.desc.wake_int_max = 0xFFFFFFFF;
+
+ /* TWT Negotiation_type */
+ val.desc.negotiation_type = (uint8)twt_param.negotiation_type;
+
+ switch (val.desc.negotiation_type) {
+ case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+ /* Flow ID */
+ val.desc.flow_id = twt_param.flow_id;
+
+ if (val.desc.flow_id == 0xFF) {
+ /* Let the FW choose the Flow ID */
+ break;
+ }
+
+ /* Lookup the active session list for the requested flow ID */
+ twt_session =
+ wl_twt_lookup_session_by_flow_id(&twt_ctx->twt_session_list,
+ twt_param.flow_id);
+ if (twt_session) {
+ WL_ERR(("TWT: Setup REQ: flow ID: %d is already active",
+ twt_param.flow_id));
+ bw = BCME_ERROR;
+ goto exit;
+ }
+ break;
+ case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+ /* Broadcast TWT ID */
+ val.desc.bid = twt_param.bcast_twt_id;
+
+ /* TODO: Handle the Broadcast TWT Setup REQ */
+
+ /* FALLTHRU */
+ default:
+ WL_ERR(("TWT: Setup REQ: Negotiation Type %d not handled",
+ twt_param.negotiation_type));
+ bw = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ /* Setup command */
+ val.desc.setup_cmd = twt_param.setup_cmd;
+
+ /* Flow flags */
+ val.desc.flow_flags |= ((twt_param.negotiation_type & 0x02) >> 1 ?
+ WL_TWT_FLOW_FLAG_BROADCAST : 0);
+ val.desc.flow_flags |= (twt_param.implicit ? WL_TWT_FLOW_FLAG_IMPLICIT : 0);
+ val.desc.flow_flags |= (twt_param.flow_type ? WL_TWT_FLOW_FLAG_UNANNOUNCED : 0);
+ val.desc.flow_flags |= (twt_param.trigger ? WL_TWT_FLOW_FLAG_TRIGGER : 0);
+ val.desc.flow_flags |= ((twt_param.negotiation_type & 0x01) ?
+ WL_TWT_FLOW_FLAG_WAKE_TBTT_NEGO : 0);
+ val.desc.flow_flags |= (twt_param.requestor ? WL_TWT_FLOW_FLAG_REQUEST : 0);
+ val.desc.flow_flags |= (twt_param.protection ? WL_TWT_FLOW_FLAG_PROTECT : 0);
+
+ if (twt_param.twt) {
+ /* Target Wake Time parameter */
+ val.desc.wake_time_h = htod32((uint32)(twt_param.twt >> 32));
+ val.desc.wake_time_l = htod32((uint32)(twt_param.twt));
+ val.desc.wake_type = WL_TWT_TIME_TYPE_BSS;
+ } else if (twt_param.twt_offset) {
+ /* Target Wake Time offset parameter */
+ val.desc.wake_time_h = htod32((uint32)(twt_param.twt_offset >> 32));
+ val.desc.wake_time_l = htod32((uint32)(twt_param.twt_offset));
+ val.desc.wake_type = WL_TWT_TIME_TYPE_OFFSET;
+ } else {
+ /* Let the FW choose the Target Wake Time */
+ val.desc.wake_time_h = 0x0;
+ val.desc.wake_time_l = 0x0;
+ val.desc.wake_type = WL_TWT_TIME_TYPE_AUTO;
+ }
+
+ /* Wake Duration or Service Period */
+ val.desc.wake_dur = htod32(wl_twt_min_twt_to_wake_dur(twt_param.min_twt,
+ twt_param.min_twt_unit));
+
+ /* Wake Interval or Service Interval */
+ val.desc.wake_int = htod32(wl_twt_float_to_uint32(twt_param.exponent,
+ twt_param.mantissa));
+
+ bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_SETUP, sizeof(val),
+ (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32);
+ if (bw != BCME_OK) {
+ WL_ERR(("TWT: Setup REQ: Failed to pack IOVAR, ret: %d", bw));
+ goto exit;
+ }
+
+ bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", mybuf,
+ sizeof(mybuf) - rem_len, resp_buf,
+ WLC_IOCTL_SMLEN, NULL);
+ if (bw != BCME_OK) {
+ WL_ERR(("TWT: Setup REQ: Failed, ret: %d", bw));
+ goto exit;
+ }
+
+ WL_INFORM(("TWT: Setup REQ: Initiated\n"
+ "Setup command : %u\n"
+ "Flow flags : 0x %02x\n"
+ "Flow ID : %u\n"
+ "Broadcast TWT ID : %u\n"
+ "Wake Time H,L : 0x %08x %08x\n"
+ "Wake Type : %u\n"
+ "Wake Dururation : %u usecs\n"
+ "Wake Interval : %u usecs\n"
+ "Negotiation type : %u\n",
+ val.desc.setup_cmd,
+ val.desc.flow_flags,
+ val.desc.flow_id,
+ val.desc.bid,
+ val.desc.wake_time_h,
+ val.desc.wake_time_l,
+ val.desc.wake_type,
+ val.desc.wake_dur,
+ val.desc.wake_int,
+ val.desc.negotiation_type));
+exit:
+ return bw;
+}
+
+int wl_twt_teardown(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+ wl_twt_param_t twt_param)
+{
+ wl_twt_teardown_t val;
+ s32 bw = BCME_OK;
+ u8 mybuf[WLC_IOCTL_SMLEN] = {0};
+ u8 resp_buf[WLC_IOCTL_SMLEN] = {0};
+ uint8 *rem = mybuf;
+ uint16 rem_len = sizeof(mybuf);
+ wl_twt_session_t *twt_session = NULL;
+
+ bzero(&val, sizeof(val));
+ val.version = WL_TWT_TEARDOWN_VER;
+ val.length = sizeof(val.version) + sizeof(val.length);
+
+ /* TWT Negotiation_type */
+ val.teardesc.negotiation_type = (uint8)twt_param.negotiation_type;
+
+ switch (val.teardesc.negotiation_type) {
+ case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+ /* Teardown all Negotiated TWT */
+ val.teardesc.alltwt = twt_param.teardown_all_twt;
+
+ if (val.teardesc.alltwt) {
+ int sess_ct =
+ wl_twt_count_session(&twt_ctx->twt_session_list);
+ if (!sess_ct) {
+ WL_ERR(("TWT: Teardown REQ: No active sessions"));
+ bw = BCME_ERROR;
+ goto exit;
+ }
+ break;
+ }
+
+ /* Flow ID */
+ if (twt_param.flow_id >= 0 && twt_param.flow_id <= 0x7) {
+ val.teardesc.flow_id = twt_param.flow_id;
+ } else {
+ WL_ERR(("TWT: Teardown REQ: flow ID: %d is invalid",
+ twt_param.flow_id));
+ bw = BCME_ERROR;
+ goto exit;
+ }
+
+ /* Lookup the active session list for the same flow ID */
+ twt_session =
+ wl_twt_lookup_session_by_flow_id(&twt_ctx->twt_session_list,
+ twt_param.flow_id);
+ if (!twt_session) {
+ WL_ERR(("TWT: Teardown REQ: flow ID: %d is not active",
+ twt_param.flow_id));
+ bw = BCME_ERROR;
+ goto exit;
+ }
+ break;
+ case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+ /* Broadcast TWT ID */
+ val.teardesc.bid = twt_param.bcast_twt_id;
+
+ /* TODO: Handle the Broadcast TWT Teardown REQ */
+
+ /* FALLTHRU */
+ default:
+ WL_ERR(("TWT: Teardown REQ: Negotiation Type %d not handled",
+ twt_param.negotiation_type));
+ bw = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_TEARDOWN, sizeof(val),
+ (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32);
+ if (bw != BCME_OK) {
+ WL_ERR(("TWT: Teardown REQ: Failed to pack IOVAR, ret: %d", bw));
+ goto exit;
+ }
+
+ bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", mybuf,
+ sizeof(mybuf) - rem_len, resp_buf,
+ WLC_IOCTL_SMLEN, NULL);
+ if (bw != BCME_OK) {
+ WL_ERR(("TWT: Teardown REQ: Failed, ret: %d", bw));
+ goto exit;
+ }
+
+ WL_INFORM(("TWT: Teardown REQ: Initiated\n"
+ "Flow ID : %u\n"
+ "Broadcast TWT ID : %u\n"
+ "Negotiation type : %u\n"
+ "Teardown all TWT : %u\n",
+ val.teardesc.flow_id,
+ val.teardesc.bid,
+ val.teardesc.negotiation_type,
+ val.teardesc.alltwt));
+exit:
+ return bw;
+}
+
+int wl_twt_oper(struct net_device *pri_ndev,
+ struct wireless_dev *wdev, wl_twt_param_t twt_param)
+{
+ int ret = -1;
+ dhd_info_t *dhd_inf = *(dhd_info_t **)netdev_priv(pri_ndev);
+ dhd_pub_t *dhd = &dhd_inf->pub;
+ wl_twt_ctx_t *twt_ctx = NULL;
+
+ NULL_CHECK(dhd, "dhd is NULL", ret);
+
+ twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+ NULL_CHECK(twt_ctx, "TWT: REQ: Failed, Module not initialized", ret);
+
+ switch (twt_param.twt_oper) {
+ case IFX_TWT_OPER_SETUP:
+ ret = wl_twt_setup(twt_ctx, wdev, twt_param);
+ break;
+ case IFX_TWT_OPER_TEARDOWN:
+ ret = wl_twt_teardown(twt_ctx, wdev, twt_param);
+ break;
+ default:
+ WL_ERR(("TWT: REQ: Requested operation %d not supported",
+ twt_param.twt_oper));
+ ret = BCME_UNSUPPORTED;
+ goto exit;
+ }
+exit:
+ return ret;
+}
+
+int wl_twt_setup_event(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+ wl_event_msg_t *event, void *event_data)
+{
+ wl_twt_setup_cplt_t *setup_complete;
+ wl_twt_sdesc_t *setup_desc;
+ wl_twt_param_t twt_param;
+ int ret = BCME_OK;
+
+ setup_complete = (wl_twt_setup_cplt_t *)event_data;
+ setup_desc = (wl_twt_sdesc_t *)(event_data + sizeof(wl_twt_setup_cplt_t));
+
+ /* TWT Negotiation_type */
+ twt_param.negotiation_type = setup_desc->negotiation_type;
+
+ switch (twt_param.negotiation_type) {
+ case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+ /* Flow ID */
+ twt_param.flow_id = setup_desc->flow_id;
+ break;
+ case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+ /* Broadcast TWT ID */
+ twt_param.bcast_twt_id = setup_desc->bid;
+
+ /* TODO: Handle the Broadcast TWT Setup Event */
+
+ /* FALLTHRU */
+ default:
+ WL_ERR(("TWT: Setup EVT: Negotiation Type %d not handled",
+ twt_param.negotiation_type));
+ ret = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ /* Setup command */
+ if (setup_desc->setup_cmd != TWT_SETUP_CMD_ACCEPT_TWT) {
+ WL_ERR(("TWT: Setup EVT: Request not accepted by the AP"));
+ ret = BCME_ERROR;
+ goto exit;
+ }
+ twt_param.setup_cmd = setup_desc->setup_cmd;
+
+ /* Flow flags */
+ twt_param.implicit = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_IMPLICIT) ? 1 : 0;
+ twt_param.flow_type = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_UNANNOUNCED) ? 1 : 0;
+ twt_param.trigger = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_TRIGGER) ? 1 : 0;
+ twt_param.requestor = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_REQUEST) ? 1 : 0;
+ twt_param.protection = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_PROTECT) ? 1 : 0;
+
+ /* Target Wake Time */
+ twt_param.twt = dtoh64((uint64)setup_desc->wake_time_h << 32) |
+ dtoh64((uint64)setup_desc->wake_time_l);
+
+ /* Wake Duration or Service Period */
+ wl_twt_wake_dur_to_min_twt(htod32(setup_desc->wake_dur),
+ &twt_param.min_twt,
+ &twt_param.min_twt_unit);
+
+ /* Wake Interval or Service Interval */
+ wl_twt_uint32_to_float(dtoh32(setup_desc->wake_int),
+ &twt_param.exponent,
+ &twt_param.mantissa);
+
+ ret = wl_twt_add_session_to_list(&twt_ctx->twt_session_list,
+ twt_ctx->dhd, event->ifidx, twt_param);
+ if (ret) {
+ WL_ERR(("TWT: Setup EVT: Failed to add new session to list"));
+ goto exit;
+ }
+
+ WL_INFORM(("TWT: Setup EVT: Succeeded\n"
+ "Setup command : %u\n"
+ "Flow flags : 0x %02x\n"
+ "Flow ID : %u\n"
+ "Broadcast TWT ID : %u\n"
+ "Wake Time H,L : 0x %08x %08x\n"
+ "Wake Type : %u\n"
+ "Wake Dururation : %u usecs\n"
+ "Wake Interval : %u usecs\n"
+ "Negotiation type : %u\n",
+ setup_desc->setup_cmd,
+ setup_desc->flow_flags,
+ setup_desc->flow_id,
+ setup_desc->bid,
+ setup_desc->wake_time_h,
+ setup_desc->wake_time_l,
+ setup_desc->wake_type,
+ setup_desc->wake_dur,
+ setup_desc->wake_int,
+ setup_desc->negotiation_type));
+exit:
+ return ret;
+}
+
+int wl_twt_teardown_event(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+ wl_event_msg_t *event, void *event_data)
+{
+ dhd_pub_t *dhd = twt_ctx->dhd;
+ wl_twt_teardown_cplt_t *teardown_complete;
+ wl_twt_teardesc_t *teardown_desc;
+ wl_twt_param_t twt_param;
+ int ret = BCME_OK;
+ s32 ifidx = DHD_BAD_IF;
+
+ ifidx = dhd_net2idx(dhd->info, wdev_to_ndev(wdev));
+ if (ifidx == DHD_BAD_IF) {
+ ret = BCME_ERROR;
+ goto exit;
+ }
+
+ teardown_complete = (wl_twt_teardown_cplt_t *)event_data;
+ teardown_desc = (wl_twt_teardesc_t *)(event_data + sizeof(teardown_complete));
+
+ /* TWT Negotiation_type */
+ twt_param.negotiation_type = teardown_desc->negotiation_type;
+
+ /* Teardown all Negotiated TWT */
+ twt_param.teardown_all_twt = teardown_desc->alltwt;
+ if (twt_param.teardown_all_twt) {
+ wl_twt_flush_session_list(&twt_ctx->twt_session_list,
+ (u8)ifidx);
+ } else {
+ switch (twt_param.negotiation_type) {
+ case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+ /* Flow ID */
+ twt_param.flow_id = teardown_desc->flow_id;
+ ret = wl_twt_del_session_by_flow_id(&twt_ctx->twt_session_list,
+ twt_param.flow_id);
+ if (ret) {
+ WL_ERR(("TWT: Failed to del session from list"));
+ goto exit;
+ }
+ break;
+ case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+ /* Broadcast TWT ID */
+ twt_param.bcast_twt_id = teardown_desc->bid;
+ /* TODO */
+ /* FALLTHRU */
+ default:
+ WL_ERR(("TWT: Negotiation Type not handled\n"));
+ ret = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ }
+
+ WL_INFORM(("TWT: Teardown EVT: Succeeded\n"
+ "Flow ID : %u\n"
+ "Broadcast TWT ID : %u\n"
+ "Negotiation type : %u\n"
+ "Teardown all TWT : %u\n",
+ teardown_desc->flow_id,
+ teardown_desc->bid,
+ teardown_desc->negotiation_type,
+ teardown_desc->alltwt));
+
+exit:
+ return ret;
+}
+
+int wl_twt_event(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
+{
+ int ret = BCME_OK;
+ wl_twt_ctx_t *twt_ctx = NULL;
+ uint32 event_type;
+ dhd_if_t *ifp = NULL;
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+
+ NULL_CHECK(dhd, "TWT: EVT: Failed, dhd is NULL", ret);
+
+ twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+ NULL_CHECK(twt_ctx, "TWT: EVT: Failed, Module not initialized", ret);
+
+ ifp = dhd_get_ifp(dhd, event->ifidx);
+ NULL_CHECK(ifp, "TWT: EVT: Failed, ifp is NULL", ret);
+
+ ndev = ifp->net;
+ NULL_CHECK(ndev, "TWT: EVT: Failed, ndev is NULL", ret);
+
+ wdev = ndev_to_wdev(ndev);
+ NULL_CHECK(wdev, "TWT: EVT: Failed, wdev is NULL", ret);
+
+ NULL_CHECK(event_data, "TWT: EVT: Failed, event_data is NULL", ret);
+
+ event_type = ntoh32_ua((void *)&event->event_type);
+ switch(event_type) {
+ case WLC_E_TWT_SETUP:
+ ret = wl_twt_setup_event(twt_ctx, wdev, event, event_data);
+ if (ret) {
+ WL_ERR(("TWT: EVT: Failed to handle TWT Setup event"));
+ goto exit;
+ }
+ break;
+ case WLC_E_TWT_TEARDOWN:
+ ret = wl_twt_teardown_event(twt_ctx, wdev, event, event_data);
+ if (ret) {
+ WL_ERR(("TWT: EVT: Failed to handle TWT Teardown event"));
+ goto exit;
+ }
+ break;
+ default:
+ WL_ERR(("TWT: EVT: Received event %d not handeled",
+ event_type));
+ ret = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+int wl_twt_init(dhd_pub_t *dhd)
+{
+ int ret = BCME_OK;
+ wl_twt_ctx_t *twt_ctx;
+
+ NULL_CHECK(dhd, "TWT: INIT: Failed, dhd is NULL", ret);
+
+ if (dhd->twt_ctx) {
+ WL_ERR(("TWT: INIT: Failed, Module already initialized"));
+ ret = BCME_ERROR;
+ goto exit;
+ }
+
+ dhd->twt_ctx = (wl_twt_ctx_t *)MALLOCZ(dhd->osh, sizeof(wl_twt_ctx_t));
+ if (dhd->twt_ctx == NULL) {
+ ret = BCME_NOMEM;
+ WL_ERR(("TWT: INIT: Failed to create TWT context"));
+ goto exit;
+ }
+ bzero(dhd->twt_ctx, sizeof(wl_twt_ctx_t));
+
+ twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+ twt_ctx->dhd = dhd;
+
+ INIT_LIST_HEAD(&twt_ctx->twt_session_list);
+
+ WL_INFORM(("TWT: INIT: Module Initialized"));
+exit:
+ return ret;
+}
+
+int wl_twt_deinit(dhd_pub_t *dhd)
+{
+ int ret = BCME_OK;
+ wl_twt_ctx_t *twt_ctx;
+
+ NULL_CHECK(dhd, "TWT: DEINIT: Failed, dhd is NULL", ret);
+
+ twt_ctx = dhd->twt_ctx;
+ NULL_CHECK(twt_ctx,
+ "TWT: DEINIT: Failed, Module not Initialized to De-initialize", ret);
+
+ wl_twt_flush_session_list(&twt_ctx->twt_session_list, 0xFF);
+
+ kfree(twt_ctx);
+ dhd->twt_ctx = NULL;
+
+ WL_INFORM(("TWT: DEINIT: Module De-initialized"));
+
+ return ret;
+}
+
+#endif /* WL11AX */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h
new file mode 100755
index 0000000..53fc3aa
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h
@@ -0,0 +1,115 @@
+/*
+ * Target Wake Time header
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein. IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE. INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#ifndef _wl_twt_h_
+#define _wl_twt_h_
+
+#include <typedefs.h>
+#include <bcmendian.h>
+#include <net/cfg80211.h>
+#include <dhd_dbg.h>
+#include <dhd_linux.h>
+#include <802.11ah.h>
+#include "dhd_linux_priv.h"
+#include "wlioctl.h"
+#include "wldev_common.h"
+#include "wl_cfg80211.h"
+#include "wl_cfgvendor.h"
+#include "bcmutils.h"
+#include "ifx_nl80211.h"
+
+enum wl_twt_session_state {
+ TWT_SESSION_SETUP_COMPLETE,
+ TWT_SESSION_TEARDOWN_COMPLETE
+};
+
+typedef struct wl_twt_param {
+ uint8 twt_oper;
+ enum ifx_twt_param_nego_type negotiation_type;
+ enum ifx_twt_oper_setup_cmd_type setup_cmd;
+ uint8 dialog_token;
+ uint64 twt;
+ uint64 twt_offset;
+ uint8 min_twt;
+ uint8 exponent;
+ uint16 mantissa;
+ uint8 requestor;
+ uint8 trigger;
+ uint8 implicit;
+ uint8 flow_type;
+ uint8 flow_id;
+ uint8 bcast_twt_id;
+ uint8 protection;
+ uint8 twt_channel;
+ uint8 twt_info_frame_disabled;
+ uint8 min_twt_unit;
+ uint8 teardown_all_twt;
+} wl_twt_param_t;
+
+typedef struct wl_twt_session {
+ uint8 ifidx;
+ uint8 state;
+ wl_twt_param_t twt_param;
+ struct list_head list;
+} wl_twt_session_t;
+
+typedef struct wl_twt_ctx {
+ dhd_pub_t *dhd;
+ struct list_head twt_session_list;
+} wl_twt_ctx_t;
+
+int wl_twt_cleanup_session_records(dhd_pub_t *dhd, u8 ifidx);
+int wl_twt_oper(struct net_device *pri_ndev,
+ struct wireless_dev *wdev, wl_twt_param_t twt_param);
+int wl_twt_event(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
+int wl_twt_init(dhd_pub_t *dhd);
+int wl_twt_deinit(dhd_pub_t *dhd);
+
+#endif /* _wl_twt_h_ */