3746 lines
130 KiB
Diff
3746 lines
130 KiB
Diff
From 7ca1e08f7b6f75ee55dd3826028ffb868c5f7354 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Jirman <megi@xff.cz>
|
|
Date: Sun, 30 Jul 2023 12:06:41 +0200
|
|
Subject: [PATCH 404/464] bes2600: Update the wifi driver from bestechnic
|
|
(0.3.5_2023.0209)
|
|
|
|
Import from https://gitlab.com/TuxThePenguin0/bes2600
|
|
|
|
New driver intended to work with Linux 6.3 provided by bestechnic.
|
|
Despite the lower version number this does appear to be a newer version.
|
|
|
|
Signed-off-by: Ondrej Jirman <megi@xff.cz>
|
|
---
|
|
drivers/staging/bes2600/Kconfig | 42 +---
|
|
drivers/staging/bes2600/Makefile | 36 +--
|
|
drivers/staging/bes2600/ap.c | 68 +++---
|
|
drivers/staging/bes2600/ap.h | 2 +-
|
|
drivers/staging/bes2600/bes2600.h | 51 +++--
|
|
drivers/staging/bes2600/bes2600_factory.c | 80 ++++++-
|
|
drivers/staging/bes2600/bes2600_factory.h | 20 +-
|
|
drivers/staging/bes2600/bes2600_sdio.c | 91 +++++++-
|
|
drivers/staging/bes2600/bes_chardev.c | 87 ++++++--
|
|
drivers/staging/bes2600/bes_chardev.h | 35 ++-
|
|
drivers/staging/bes2600/bes_fw.c | 8 +-
|
|
.../bes2600/bes_nl80211_testmode_msg.h | 10 +
|
|
drivers/staging/bes2600/bes_pwr.c | 66 ++++--
|
|
drivers/staging/bes2600/bes_pwr.h | 2 +
|
|
drivers/staging/bes2600/bh.c | 20 +-
|
|
drivers/staging/bes2600/debug.c | 6 +-
|
|
drivers/staging/bes2600/epta_request.c | 24 +-
|
|
drivers/staging/bes2600/main.c | 58 +++--
|
|
drivers/staging/bes2600/pm.c | 165 ++++++++++++--
|
|
drivers/staging/bes2600/pm.h | 7 +
|
|
drivers/staging/bes2600/queue.c | 210 +++++++++++++++---
|
|
drivers/staging/bes2600/queue.h | 5 +-
|
|
drivers/staging/bes2600/scan.c | 10 +-
|
|
drivers/staging/bes2600/sta.c | 156 +++++++++----
|
|
drivers/staging/bes2600/sta.h | 2 +-
|
|
drivers/staging/bes2600/tx_loop.c | 5 +
|
|
drivers/staging/bes2600/tx_loop.h | 2 +
|
|
drivers/staging/bes2600/txrx.c | 88 ++++++--
|
|
drivers/staging/bes2600/txrx_opt.c | 170 +++++++++++---
|
|
drivers/staging/bes2600/txrx_opt.h | 11 +-
|
|
drivers/staging/bes2600/wifi_testmode_cmd.c | 1 +
|
|
drivers/staging/bes2600/wsm.c | 68 ++++--
|
|
drivers/staging/bes2600/wsm.h | 65 ++++--
|
|
33 files changed, 1280 insertions(+), 391 deletions(-)
|
|
|
|
diff --git a/drivers/staging/bes2600/Kconfig b/drivers/staging/bes2600/Kconfig
|
|
index 374c15db823f..9c8de42ea6e0 100644
|
|
--- a/drivers/staging/bes2600/Kconfig
|
|
+++ b/drivers/staging/bes2600/Kconfig
|
|
@@ -4,10 +4,6 @@ config BES2600
|
|
select CFG80211
|
|
select NL80211_TESTMODE
|
|
default m
|
|
- ---help---
|
|
- This is an experimental driver for the bes2600 chip-set.
|
|
- Enabling this option enables the generic driver without
|
|
- any platform support.
|
|
|
|
if BES2600
|
|
|
|
@@ -15,68 +11,48 @@ config BES2600_WLAN_SDIO
|
|
bool "SDIO bus interface support"
|
|
depends on MMC
|
|
default y
|
|
- ---help---
|
|
- This option enables the SDIO bus interface support for Bes2600
|
|
- WLAN driver. Say Y if you want to use SDIO.
|
|
+
|
|
|
|
config BES2600_WLAN_USB
|
|
bool "USB bus interface support"
|
|
depends on USB
|
|
default n
|
|
- ---help---
|
|
- This option enables the USB bus interface support for Bes2600
|
|
- WLAN driver. Say Y if you want to use USB.
|
|
+
|
|
|
|
config BES2600_WLAN_SPI
|
|
bool "SPI bus interface support"
|
|
depends on SPI
|
|
default n
|
|
- ---help---
|
|
- This option enables the SPI bus interface support for Bes2600
|
|
- WLAN driver. Say Y if you want to use USB.
|
|
+
|
|
|
|
config BES2600_USE_GPIO_IRQ
|
|
bool "Use GPIO interrupt"
|
|
default n
|
|
- ---help---
|
|
- Say Y here if you want to include GPIO IRQ support instead of SDIO IRQ.
|
|
- If unsure, say N.
|
|
+
|
|
|
|
config BES2600_5GHZ_SUPPORT
|
|
bool "5GHz band support"
|
|
default y
|
|
- ---help---
|
|
- Say Y if your device supports 5GHz band.
|
|
- If unsure, say N.
|
|
+
|
|
|
|
config BES2600_WAPI_SUPPORT
|
|
bool "WAPI support"
|
|
default y
|
|
- ---help---
|
|
- Say Y if your compat-wireless support WAPI.
|
|
- If unsure, say N.
|
|
+
|
|
|
|
config BES2600_USE_STE_EXTENSIONS
|
|
bool "STE extensions"
|
|
default n
|
|
- ---help---
|
|
- Say Y if you want to include STE extensions.
|
|
- If unsure, say N.
|
|
+
|
|
|
|
config BES2600_DISABLE_BEACON_HINTS
|
|
bool "Disable 11d beacon hints"
|
|
default n
|
|
- ---help---
|
|
- Say Y if you want to disable 11d beacon hints.
|
|
- If unsure, say N.
|
|
|
|
config BES2600_TESTMODE
|
|
bool "bes2600 testmode support"
|
|
select NL80211_TESTMODE
|
|
default n
|
|
- ---help---
|
|
- Say Y if you want to enable bes2600 testmode.
|
|
- If unsure, say N.
|
|
|
|
menu "Driver debug features"
|
|
|
|
@@ -110,9 +86,7 @@ config BES2600_DUMP_ON_ERROR
|
|
|
|
config BES2600_ITP
|
|
bool "Enable ITP DebugFS"
|
|
- ---help---
|
|
- Say Y if you want to include ITP code.
|
|
- If unsure, say N.
|
|
+
|
|
|
|
endmenu
|
|
|
|
diff --git a/drivers/staging/bes2600/Makefile b/drivers/staging/bes2600/Makefile
|
|
index 103519907e4f..6b41436f6d4e 100644
|
|
--- a/drivers/staging/bes2600/Makefile
|
|
+++ b/drivers/staging/bes2600/Makefile
|
|
@@ -6,11 +6,9 @@ CONFIG_BES2600_WLAN_SPI ?= n
|
|
CONFIG_BES2600_WLAN_USB ?= n
|
|
|
|
CONFIG_BES2600_VENDOR_CMD ?= y
|
|
-ifneq ($(CONFIG_BES2600_WLAN_USB),y)
|
|
-CONFIG_BES2600_TESTMODE ?= y
|
|
-endif
|
|
+CONFIG_BES2600_TESTMODE ?= n
|
|
|
|
-CONFIG_BES2600_WAPI_SUPPORT ?= y
|
|
+CONFIG_BES2600_WAPI_SUPPORT ?= n
|
|
CONFIG_BES2600_5GHZ_SUPPORT ?= y
|
|
CONFIG_BES2600_STA_DEBUG ?= y
|
|
CONFIG_BES2600_STATIC_SDD ?= y
|
|
@@ -31,17 +29,19 @@ CONFIG_BES2600_ITP ?= n
|
|
CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES ?= n
|
|
CONFIG_BES2600_CALIB_FROM_LINUX ?= y
|
|
|
|
-CONFIG_BES2600_WIFI_BOOT_ON ?= n
|
|
+CONFIG_BES2600_WIFI_BOOT_ON ?= y
|
|
CONFIG_BES2600_BT_BOOT_ON ?= n
|
|
|
|
PLAT_ALLWINNER_T507 ?= n
|
|
PLAT_ALLWINNER_R329 ?= n
|
|
-PLAT_ROCKCHIP ?= y
|
|
+PLAT_ROCKCHIP ?= n
|
|
PLAT_UBUNTU_VUB300 ?= n
|
|
PLAT_QCOM_QM215 ?= n
|
|
+PLAT_CVITEK_182X ?= n
|
|
|
|
-BES2600_GPIO_WAKEUP_AP ?= y
|
|
+BES2600_GPIO_WAKEUP_AP ?= n
|
|
BES2600_WRITE_DPD_TO_FILE ?= n
|
|
+BES2600_TX_MORE_RETRY ?= n
|
|
|
|
# bes evb
|
|
BES2600_INDEPENDENT_EVB ?= n
|
|
@@ -54,13 +54,13 @@ BES2600_INTEGRATED_MODULE_V3 ?= n
|
|
|
|
# 0: use dynamic_ps_timeout value
|
|
# other: override dynamic_ps_timeout value
|
|
-BES2600_FASTPS_IDLE_TIME ?= 0
|
|
+BES2600_FASTPS_IDLE_TIME ?= 8
|
|
|
|
#1.rock api(fixed macaddr)
|
|
#2.read from file(macaddr of customers)
|
|
#3.read from file(macaddr template)
|
|
#4.random macaddr
|
|
-GET_MAC_ADDR_METHOD ?= 4
|
|
+GET_MAC_ADDR_METHOD ?= 0
|
|
|
|
ifeq ($(CONFIG_BES2600_DEBUGFS),y)
|
|
BES2600_DUMP_FW_DPD_LOG ?= n
|
|
@@ -73,7 +73,7 @@ ccflags-y += -DVENDOR_XM_KEEPALIVE
|
|
endif
|
|
endif
|
|
|
|
-BES2600_DRV_VERSION := bes2600_0.3.10_2022.1125
|
|
+BES2600_DRV_VERSION := bes2600_0.3.5_2023.0209
|
|
|
|
ifeq ($(GET_MAC_ADDR_METHOD)_$(PLAT_ROCKCHIP),1_n)
|
|
$(error Parameter setting error, GET_MAC_ADDR_METHOD can only be set to 1 on rockchip platform)
|
|
@@ -89,7 +89,8 @@ endif
|
|
|
|
ifeq ($(CONFIG_BES2600_CALIB_FROM_LINUX),y)
|
|
FACTORY_CRC_CHECK ?= n
|
|
-FACTORY_SAVE_MULTI_PATH ?= n
|
|
+FACTORY_SAVE_MULTI_PATH ?= y
|
|
+STANDARD_FACTORY_EFUSE_FLAG ?= y
|
|
ifeq ($(FACTORY_SAVE_MULTI_PATH),y)
|
|
FACTORY_PATH ?= /data/cfg/bes2600_factory.txt
|
|
FACTORY_DEFAULT_PATH ?= /lib/firmware/bes2600_factory.txt
|
|
@@ -100,7 +101,7 @@ FACTORY_PATH ?= /vendor/firmware/bes2600_factory.txt
|
|
endif
|
|
endif
|
|
|
|
-FACTORY_PATH ?= /vendor/lib/firmware/bes2600_factory.txt
|
|
+FACTORY_PATH ?= /lib/firmware/bes2600_factory.txt
|
|
|
|
# basic function
|
|
define boolen_flag
|
|
@@ -144,7 +145,7 @@ ccflags-y += -DBES_UNIFIED_PM
|
|
endif # CONFIG_BES2600_WLAN_SPI
|
|
|
|
ifeq ($(CONFIG_BES2600_WLAN_USB),y)
|
|
-FW_DOWNLOAD_BY_USB ?= n
|
|
+FW_DOWNLOAD_BY_USB ?= y
|
|
ccflags-y += -DCONFIG_BES2600_WLAN_BES
|
|
endif # CONFIG_BES2600_WLAN_USB
|
|
|
|
@@ -179,6 +180,7 @@ ccflags-y += $(call boolen_flag,PLAT_ALLWINNER_T507,y)
|
|
ccflags-y += $(call boolen_flag,PLAT_UBUNTU_VUB300,y)
|
|
ccflags-y += $(call boolen_flag,PLAT_ROCKCHIP,y)
|
|
ccflags-y += $(call boolen_flag,PLAT_QCOM_QM215,y)
|
|
+ccflags-y += $(call boolen_flag,PLAT_CVITEK_182X,y)
|
|
|
|
ccflags-y += $(call boolen_flag,CONFIG_BES2600_VENDOR_CMD,y)
|
|
|
|
@@ -192,6 +194,7 @@ ccflags-y += $(call boolen_flag,WIFI_BT_COEXIST_EPTA_ENABLE,y)
|
|
ccflags-y += $(call boolen_flag,WIFI_BT_COEXIST_EPTA_FDD,y)
|
|
ccflags-y += $(call boolen_flag,CONFIG_BES2600_DISABLE_BEACON_HINTS,y)
|
|
ccflags-y += $(call boolen_flag,CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES,y)
|
|
+ccflags-y += $(call boolen_flag,BES2600_TX_MORE_RETRY,y)
|
|
|
|
ccflags-y += $(call boolen_flag,CONFIG_BES2600_ITP,y)
|
|
ccflags-y += $(call boolen_flag,CONFIG_BES2600_DEBUGFS,y)
|
|
@@ -244,6 +247,7 @@ ccflags-y += $(call boolen_flag,BES2600_WRITE_DPD_TO_FILE,y)
|
|
ccflags-y += $(call boolen_flag,BES2600_DUMP_FW_DPD_LOG,y)
|
|
ccflags-y += $(call string_flag,BES2600_DPD_LOG_PATH)
|
|
|
|
+ccflags-y += $(call boolen_flag,STANDARD_FACTORY_EFUSE_FLAG,y)
|
|
|
|
# internal feature options
|
|
ccflags-y += -DAP_HT_CAP_UPDATE
|
|
@@ -259,6 +263,10 @@ ccflags-y += -DCHIP_WIFI_ROM_VER=1
|
|
ccflags-y += -DWIFI_OUT_FEM=0
|
|
ccflags-y += -DRF_TX_CONTROL_IO=16
|
|
|
|
+# stbc rx option
|
|
+ccflags-y += -DSTBC_RX_24G=0
|
|
+ccflags-y += -DSTBC_RX_5G=0
|
|
+
|
|
#ccflags-y += -DP2P_STA_COEX
|
|
#ccflags-y += -DCUSTOM_FEATURE
|
|
#ccflags-y += -DMCAST_FWDING
|
|
@@ -267,7 +275,7 @@ ccflags-y += -DRF_TX_CONTROL_IO=16
|
|
# For offloading probe response to FW, the extra IE must be included
|
|
# in the probe response template
|
|
#ccflags-y += -DPROBE_RESP_EXTRA_IE
|
|
-#ccflags-y += -DIPV6_FILTERING
|
|
+ccflags-y += -DIPV6_FILTERING
|
|
|
|
# basic files for building module
|
|
bes2600-y := \
|
|
diff --git a/drivers/staging/bes2600/ap.c b/drivers/staging/bes2600/ap.c
|
|
index 2126e7b516da..c6a4b8c29106 100644
|
|
--- a/drivers/staging/bes2600/ap.c
|
|
+++ b/drivers/staging/bes2600/ap.c
|
|
@@ -30,7 +30,7 @@
|
|
|
|
#define BES2600_ENABLE_ARP_FILTER_OFFLOAD 3
|
|
|
|
-#define BES2600_KEEP_ALIVE_PERIOD (20)
|
|
+#define BES2600_KEEP_ALIVE_PERIOD (15)
|
|
|
|
#ifndef ERP_INFO_BYTE_OFFSET
|
|
#define ERP_INFO_BYTE_OFFSET 2
|
|
@@ -249,8 +249,11 @@ static int bes2600_set_tim_impl(struct bes2600_vif *priv, bool aid0_bit_set)
|
|
bes2600_dbg(BES2600_DBG_AP, "[AP] %s mcast: %s.\n",
|
|
__func__, aid0_bit_set ? "ena" : "dis");
|
|
|
|
- skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
|
|
- &tim_offset, &tim_length);
|
|
+ // skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
|
|
+ // &tim_offset, &tim_length);
|
|
+ skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
|
|
+ &tim_offset, &tim_length, 0);
|
|
+
|
|
if (!skb) {
|
|
if (!__bes2600_flush(hw_priv, true, priv->if_id))
|
|
wsm_unlock_tx(hw_priv);
|
|
@@ -393,18 +396,19 @@ static int bes2600_set_btcoexinfo(struct bes2600_vif *priv)
|
|
void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
struct ieee80211_vif *vif,
|
|
struct ieee80211_bss_conf *info,
|
|
- u32 changed)
|
|
+ u64 changed)
|
|
{
|
|
struct bes2600_common *hw_priv = dev->priv;
|
|
struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
|
|
struct ieee80211_conf *conf = &dev->conf;
|
|
const u8 override_fpsm_timeout = BES2600_FASTPS_IDLE_TIME;
|
|
+ struct ieee80211_vif_cfg cfg;
|
|
|
|
#ifdef P2P_MULTIVIF
|
|
if (priv->if_id == CW12XX_GENERIC_IF_ID)
|
|
return;
|
|
#endif
|
|
- bes2600_info(BES2600_DBG_AP, "BSS CHANGED: %08x\n", changed);
|
|
+ bes2600_info(BES2600_DBG_AP, "BSS CHANGED: %08llx\n", changed);
|
|
down(&hw_priv->conf_lock);
|
|
if (changed & BSS_CHANGED_BSSID) {
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
@@ -430,19 +434,19 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
struct wsm_arp_ipv4_filter filter = {0};
|
|
int i;
|
|
bes2600_dbg(BES2600_DBG_AP, "[STA] BSS_CHANGED_ARP_FILTER cnt: %d",
|
|
- info->arp_addr_cnt);
|
|
+ vif->cfg.arp_addr_cnt);
|
|
|
|
#ifdef WIFI_BT_COEXIST_EPTA_ENABLE
|
|
- if (info->arp_addr_cnt > 0) {
|
|
+ if (vif->cfg.arp_addr_cnt > 0) {
|
|
bwifi_change_current_status(hw_priv, BWIFI_STATUS_GOT_IP);
|
|
}
|
|
#endif
|
|
/* Currently only one IP address is supported by firmware.
|
|
* In case of more IPs arp filtering will be disabled. */
|
|
- if (info->arp_addr_cnt > 0 &&
|
|
- info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
|
|
- for (i = 0; i < info->arp_addr_cnt; i++) {
|
|
- filter.ipv4Address[i] = info->arp_addr_list[i];
|
|
+ if (vif->cfg.arp_addr_cnt > 0 &&
|
|
+ vif->cfg.arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
|
|
+ for (i = 0; i < vif->cfg.arp_addr_cnt; i++) {
|
|
+ filter.ipv4Address[i] = vif->cfg.arp_addr_list[i];
|
|
bes2600_dbg(BES2600_DBG_AP, "[STA] addr[%d]: 0x%X\n",
|
|
i, filter.ipv4Address[i]);
|
|
}
|
|
@@ -490,7 +494,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
priv->power_set_true = 0;
|
|
priv->user_power_set_true = 0;
|
|
|
|
- if(!info->ps) {
|
|
+ if(!cfg.ps) {
|
|
bes2600_pwr_set_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_PS_ACTIVE);
|
|
}
|
|
}
|
|
@@ -498,7 +502,8 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_GET_IP);
|
|
}
|
|
|
|
-#ifdef IPV6_FILTERING
|
|
+// #if (defined(IPV6_FILTERING) && LINUX_VERSION_CODE > KERNEL_VERSION(4,19,0))
|
|
+#if 0
|
|
if (changed & BSS_CHANGED_NDP_FILTER) {
|
|
struct wsm_ndp_ipv6_filter filter = {0};
|
|
int i;
|
|
@@ -606,7 +611,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
priv->wep_default_key_id = -1;
|
|
wsm_unlock_tx(hw_priv);
|
|
|
|
- if (!info->assoc /* && !info->ibss_joined */) {
|
|
+ if (!cfg.assoc /* && !info->ibss_joined */) {
|
|
#ifdef P2P_STA_COEX
|
|
priv->cqm_link_loss_count = 400;
|
|
priv->cqm_beacon_loss_count = 200;
|
|
@@ -628,8 +633,8 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
int is_combo = 0;
|
|
int i;
|
|
struct bes2600_vif *tmp_priv;
|
|
- bes2600_info(BES2600_DBG_AP, "BSS_CHANGED_ASSOC assoc: %d.\n", info->assoc);
|
|
- if (info->assoc) { /* TODO: ibss_joined */
|
|
+ bes2600_info(BES2600_DBG_AP, "BSS_CHANGED_ASSOC assoc: %d.\n", vif->cfg.assoc );
|
|
+ if (cfg.assoc) { /* TODO: ibss_joined */
|
|
struct ieee80211_sta *sta = NULL;
|
|
if (info->dtim_period)
|
|
priv->join_dtim_period = info->dtim_period;
|
|
@@ -640,7 +645,9 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
cancel_delayed_work_sync(&priv->join_timeout);
|
|
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_JOIN);
|
|
bes2600_pwr_set_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_GET_IP);
|
|
- txrx_opt_timer_init(priv->hw_priv);
|
|
+#ifdef BES2600_TX_RX_OPT
|
|
+ txrx_opt_timer_init(priv);
|
|
+#endif
|
|
}
|
|
|
|
rcu_read_lock();
|
|
@@ -651,11 +658,11 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
* mac80211 changes are available */
|
|
enum nl80211_channel_type ch_type;
|
|
BUG_ON(!hw_priv->channel);
|
|
- hw_priv->ht_info.ht_cap = sta->ht_cap;
|
|
+ hw_priv->ht_info.ht_cap = sta->deflink.ht_cap;
|
|
priv->bss_params.operationalRateSet =
|
|
__cpu_to_le32(
|
|
bes2600_rate_mask_to_wsm(hw_priv,
|
|
- sta->supp_rates[
|
|
+ sta->deflink.supp_rates[
|
|
hw_priv->channel->band]));
|
|
rcu_read_unlock();
|
|
ch_type = cfg80211_get_chandef_type(&info->chandef);
|
|
@@ -769,7 +776,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
priv->cqm_beacon_loss_count :
|
|
priv->cqm_link_loss_count;
|
|
|
|
- priv->bss_params.aid = info->aid;
|
|
+ priv->bss_params.aid = cfg.aid;
|
|
|
|
if (priv->join_dtim_period < 1)
|
|
priv->join_dtim_period = 1;
|
|
@@ -975,7 +982,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
if (changed & BSS_CHANGED_BANDWIDTH) {
|
|
enum nl80211_channel_type ch_type = cfg80211_get_chandef_type(&info->chandef);
|
|
|
|
- if (info->assoc &&
|
|
+ if (cfg.assoc &&
|
|
hw_priv->ht_info.channel_type != ch_type &&
|
|
priv->join_status == BES2600_JOIN_STATUS_STA) {
|
|
struct wsm_switch_channel channel;
|
|
@@ -990,7 +997,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
}
|
|
|
|
if (changed & BSS_CHANGED_PS) {
|
|
- if (info->ps == false)
|
|
+ if (cfg.ps == false)
|
|
priv->powersave_mode.pmMode = WSM_PSM_ACTIVE;
|
|
else if (conf->dynamic_ps_timeout <= 0)
|
|
priv->powersave_mode.pmMode = WSM_PSM_PS;
|
|
@@ -999,7 +1006,7 @@ void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
|
|
/* set/clear ps active power busy event */
|
|
if(priv->join_status == BES2600_JOIN_STATUS_STA) {
|
|
- if(!info->ps) {
|
|
+ if(!cfg.ps) {
|
|
bes2600_pwr_set_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_PS_ACTIVE);
|
|
} else {
|
|
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_PS_ACTIVE);
|
|
@@ -1292,7 +1299,8 @@ static int bes2600_upload_beacon(struct bes2600_vif *priv)
|
|
#endif
|
|
frame.rate = WSM_TRANSMIT_RATE_6;
|
|
|
|
- frame.skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ // frame.skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ frame.skb = ieee80211_beacon_get(priv->hw, priv->vif, 0);
|
|
if (WARN_ON(!frame.skb))
|
|
return -ENOMEM;
|
|
|
|
@@ -1461,7 +1469,8 @@ static int bes2600_upload_null(struct bes2600_vif *priv)
|
|
};
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))
|
|
- frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ // frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, true);
|
|
#else
|
|
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
|
#endif
|
|
@@ -1486,7 +1495,8 @@ static int bes2600_upload_qosnull(struct bes2600_vif *priv)
|
|
};
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))
|
|
- frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, true);
|
|
+ // frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, true);
|
|
+ frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, true);
|
|
#else
|
|
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
|
#endif
|
|
@@ -1609,7 +1619,8 @@ static int bes2600_start_ap(struct bes2600_vif *priv)
|
|
|
|
#ifndef HIDDEN_SSID
|
|
/* Get SSID */
|
|
- skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ // skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ skb = ieee80211_beacon_get(priv->hw, priv->vif, 0);
|
|
if (WARN_ON(!skb))
|
|
return -ENOMEM;
|
|
|
|
@@ -1960,7 +1971,8 @@ void bes2600_ht_info_update_work(struct work_struct *work)
|
|
.count = 1,
|
|
};
|
|
|
|
- skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ // skb = ieee80211_beacon_get(priv->hw, priv->vif);
|
|
+ skb = ieee80211_beacon_get(priv->hw, priv->vif, 0);
|
|
if (WARN_ON(!skb))
|
|
return;
|
|
|
|
diff --git a/drivers/staging/bes2600/ap.h b/drivers/staging/bes2600/ap.h
|
|
index f9d85d847397..63874ccf33e2 100644
|
|
--- a/drivers/staging/bes2600/ap.h
|
|
+++ b/drivers/staging/bes2600/ap.h
|
|
@@ -26,7 +26,7 @@ void bes2600_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
|
void bes2600_bss_info_changed(struct ieee80211_hw *dev,
|
|
struct ieee80211_vif *vif,
|
|
struct ieee80211_bss_conf *info,
|
|
- u32 changed);
|
|
+ u64 changed);
|
|
|
|
int bes2600_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
diff --git a/drivers/staging/bes2600/bes2600.h b/drivers/staging/bes2600/bes2600.h
|
|
index ecfe154a0283..d31dd8cf683e 100644
|
|
--- a/drivers/staging/bes2600/bes2600.h
|
|
+++ b/drivers/staging/bes2600/bes2600.h
|
|
@@ -33,8 +33,8 @@
|
|
#define CW12XX_GENERIC_IF_ID (2)
|
|
#define CW12XX_HOST_VIF0_11N_THROTTLE (63)
|
|
#define CW12XX_HOST_VIF1_11N_THROTTLE (63)
|
|
-#define CW12XX_HOST_VIF0_11BG_THROTTLE (15)
|
|
-#define CW12XX_HOST_VIF1_11BG_THROTTLE (15)
|
|
+#define CW12XX_HOST_VIF0_11BG_THROTTLE (20)
|
|
+#define CW12XX_HOST_VIF1_11BG_THROTTLE (20)
|
|
#if 0
|
|
#define CW12XX_FW_VIF0_THROTTLE (15)
|
|
#define CW12XX_FW_VIF1_THROTTLE (15)
|
|
@@ -374,6 +374,13 @@ struct bes2600_common {
|
|
atomic_t bh_term;
|
|
atomic_t bh_suspend;
|
|
|
|
+#ifdef CONFIG_PM
|
|
+ /*Suspend*/
|
|
+ u8 unjoin_if_id_slots;
|
|
+ bool suspend_in_progress;
|
|
+ struct notifier_block pm_notify;
|
|
+#endif
|
|
+
|
|
struct workqueue_struct *bh_workqueue;
|
|
struct work_struct bh_work;
|
|
|
|
@@ -642,24 +649,28 @@ struct bes2600_vif {
|
|
#endif
|
|
bool pmf;
|
|
|
|
- u32 hw_value;
|
|
- /* dot11CountersTable */
|
|
- u32 dot11TransmittedFragmentCount;
|
|
- u32 dot11MulticastTransmittedFrameCount;
|
|
- u32 dot11FailedCount;
|
|
- u32 dot11RetryCount;
|
|
- u32 dot11MultipleRetryCount;
|
|
- u32 dot11FrameDuplicateCount;
|
|
- u32 dot11ReceivedFragmentCount;
|
|
- u32 dot11RxReorderLeakCount;
|
|
- u32 dot11ReceivedBytes;
|
|
- u32 dot11ReceivedDataBytes;
|
|
- u32 dot11MulticastReceivedFrameCount;
|
|
- u32 dot11TransmittedFrameCount;
|
|
- u32 dot11TransmittedBytes;
|
|
- u32 dot11TransmittedDataBytes;
|
|
- u32 dot11Txbps;
|
|
- u32 dot11Rxbps;
|
|
+ u32 hw_value;
|
|
+ /* dot11CountersTable */
|
|
+ u32 dot11TransmittedFragmentCount;
|
|
+ u32 dot11MulticastTransmittedFrameCount;
|
|
+ u32 dot11FailedCount;
|
|
+ u32 dot11RetryCount;
|
|
+ u32 dot11MultipleRetryCount;
|
|
+ u32 dot11FrameDuplicateCount;
|
|
+ u32 dot11ReceivedFragmentCount;
|
|
+ u32 dot11RxReorderLeakCount;
|
|
+ u32 dot11ReceivedBytes;
|
|
+ u32 dot11ReceivedDataBytes;
|
|
+ u32 dot11MulticastReceivedFrameCount;
|
|
+ u32 dot11TransmittedFrameCount;
|
|
+ u32 dot11TransmittedBytes;
|
|
+ u32 dot11TransmittedDataBytes;
|
|
+ u32 dot11Txbps;
|
|
+ u32 dot11Rxbps;
|
|
+
|
|
+ /* used to calculate signal strength */
|
|
+ s32 signal;
|
|
+ s32 signal_mul;
|
|
};
|
|
struct bes2600_sta_priv {
|
|
int link_id;
|
|
diff --git a/drivers/staging/bes2600/bes2600_factory.c b/drivers/staging/bes2600/bes2600_factory.c
|
|
index c525311c2a30..f1a7a84027c2 100644
|
|
--- a/drivers/staging/bes2600/bes2600_factory.c
|
|
+++ b/drivers/staging/bes2600/bes2600_factory.c
|
|
@@ -100,13 +100,17 @@ static int bes2600_factory_crc_check(struct factory_t *factory_data)
|
|
{
|
|
#ifdef FACTORY_CRC_CHECK
|
|
u32 cal_crc = 0;
|
|
+ u32 crc_len = sizeof(factory_data_t);
|
|
+#ifndef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ crc_len = (crc_len - sizeof(u16) + 3) & (~0x3);
|
|
+#endif
|
|
|
|
if (!factory_data) {
|
|
bes2600_err(BES2600_DBG_FACTORY, "%s NULL pointer err \n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
- cal_crc = factory_crc32((uint8_t *)(&(factory_data->data)), sizeof(factory_data_t));
|
|
+ cal_crc = factory_crc32((uint8_t *)(&(factory_data->data)), crc_len);
|
|
if (factory_data->head.crc != cal_crc) {
|
|
bes2600_err(BES2600_DBG_CHARDEV,
|
|
"bes2600 factory check failed, calc_crc:0x%08x factory_crc: 0x%08x\n",
|
|
@@ -243,9 +247,19 @@ static inline int factory_parse(uint8_t *source_buf, struct factory_t *factory)
|
|
&factory->data.bt_tx_power[0],\
|
|
&factory->data.bt_tx_power[1],\
|
|
&factory->data.bt_tx_power[2],\
|
|
- &factory->data.bt_tx_power[3]);
|
|
+ &factory->data.bt_tx_power[3]
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ ,&factory->data.select_efuse);
|
|
+#else
|
|
+ );
|
|
+#endif
|
|
|
|
- if (ret != 30) {
|
|
+#ifndef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ factory->data.select_efuse = 0;
|
|
+#endif
|
|
+
|
|
+ if (ret != FACTORY_MEMBER_NUM)
|
|
+ {
|
|
bes2600_err(BES2600_DBG_FACTORY, "bes2600_factory.txt parse fail\n");
|
|
return -1;
|
|
}
|
|
@@ -401,6 +415,7 @@ void factory_little_endian_cvrt(u8 *data)
|
|
|
|
TRANS_LE16(trans_data->data.tx_power_flags_5G);
|
|
TRANS_LE16(trans_data->data.temperature_5G);
|
|
+ TRANS_LE16(trans_data->data.select_efuse);
|
|
|
|
}
|
|
|
|
@@ -520,6 +535,9 @@ static int bes2600_factory_cali_file_hdr_fill(struct factory_t **factory_head)
|
|
(*factory_head)->data.bt_tx_power[1] = 0x10;
|
|
(*factory_head)->data.bt_tx_power[2] = 0x05;
|
|
(*factory_head)->data.bt_tx_power[3] = 0x15;
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ (*factory_head)->data.select_efuse = 0;
|
|
+#endif
|
|
|
|
return 0;
|
|
}
|
|
@@ -741,6 +759,49 @@ int16_t bes2600_wifi_cali_freq_write(struct wifi_freq_cali_t *data_cali)
|
|
return ret;
|
|
}
|
|
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+int16_t bes2600_select_efuse_flag_write(uint16_t select_efuse_flag)
|
|
+{
|
|
+ struct factory_t *factory_flag_p = NULL;
|
|
+ u8 *file_buffer = NULL;
|
|
+ int16_t ret = 0;
|
|
+
|
|
+ if (!(file_buffer = bes2600_factory_get_file_buffer()))
|
|
+ return -FACTORY_GET_INPUT_NULL_POINTER;
|
|
+
|
|
+ bes2600_factory_lock();
|
|
+
|
|
+ /**
|
|
+ * When it returns true, it means that the factory file has been read.
|
|
+ * When it returns false, it means that the factory file does not exist,
|
|
+ * or the operation of reading the text file fails. At this time, a new factory file will be created.
|
|
+ */
|
|
+ if (bes2600_factory_file_status_read(file_buffer)) {
|
|
+ factory_flag_p = factory_p;
|
|
+ } else {
|
|
+ if (bes2600_factory_cali_file_hdr_fill(&factory_flag_p)) {
|
|
+ bes2600_warn(BES2600_DBG_FACTORY, "%s, create bes2600_factory.txt fail.", __func__);
|
|
+ ret = -FACTORY_FACTORY_TXT_CREATE_FAIL;
|
|
+ goto err;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ factory_flag_p->data.select_efuse = select_efuse_flag;
|
|
+ bes2600_dbg(BES2600_DBG_FACTORY, "%s: select_efuse = %x\n", __func__, select_efuse_flag);
|
|
+
|
|
+ /* save to file */
|
|
+ if (bes2600_wifi_cali_table_save(file_buffer, factory_flag_p)) {
|
|
+ ret = -FACTORY_SAVE_WRITE_ERR;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+err:
|
|
+ bes2600_factory_free_file_buffer(file_buffer);
|
|
+ bes2600_factory_unlock();
|
|
+ return ret;
|
|
+}
|
|
+#endif
|
|
+
|
|
int16_t vendor_set_power_cali_flag(struct wifi_power_cali_flag_t *cali_flag)
|
|
{
|
|
struct factory_t *factory_power_flag_p = NULL;
|
|
@@ -823,13 +884,22 @@ static inline int factory_build(uint8_t *dest_buf, struct factory_t *factory)
|
|
factory->data.bt_tx_power[0],\
|
|
factory->data.bt_tx_power[1],\
|
|
factory->data.bt_tx_power[2],\
|
|
- factory->data.bt_tx_power[3]);
|
|
+ factory->data.bt_tx_power[3]
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ ,factory->data.select_efuse);
|
|
+#else
|
|
+ );
|
|
+#endif
|
|
}
|
|
|
|
static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *factory_save_p)
|
|
{
|
|
int ret = 0;
|
|
int w_size;
|
|
+ u32 crc_len = sizeof(factory_data_t);
|
|
+#ifndef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ crc_len = (crc_len - sizeof(u16) + 3) & (~0x3);
|
|
+#endif
|
|
|
|
bes2600_info(BES2600_DBG_FACTORY, "enter %s\n", __func__);
|
|
|
|
@@ -846,7 +916,7 @@ static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *facto
|
|
file_buffer[FACTORY_MAX_SIZE - 1] = '\n';
|
|
|
|
factory_save_p->head.crc =
|
|
- factory_crc32((uint8_t *)(&(factory_save_p->data)), sizeof(factory_data_t));
|
|
+ factory_crc32((uint8_t *)(&(factory_save_p->data)), crc_len);
|
|
|
|
w_size = factory_build(file_buffer, factory_save_p);
|
|
|
|
diff --git a/drivers/staging/bes2600/bes2600_factory.h b/drivers/staging/bes2600/bes2600_factory.h
|
|
index 473840282a82..3835b0d9c96c 100644
|
|
--- a/drivers/staging/bes2600/bes2600_factory.h
|
|
+++ b/drivers/staging/bes2600/bes2600_factory.h
|
|
@@ -19,7 +19,7 @@
|
|
#define NVREC_CURRENT_VERSION 2
|
|
|
|
#define FACTORY_MAX_SIZE 600
|
|
-#define STANDARD_FACTORY "##head\n\
|
|
+#define __STANDARD_FACTORY "##head\n\
|
|
magic:0x%hx\n\
|
|
version:0x%hx\n\
|
|
crc:0x%x\n\
|
|
@@ -53,8 +53,17 @@ temperature_5G:0x%hx\n\
|
|
bdr_div:0x%x\n\
|
|
bdr_power:0x%x\n\
|
|
edr_div:0x%x\n\
|
|
-edr_power:0x%x\n\
|
|
-%%%%\n"
|
|
+edr_power:0x%x\n"
|
|
+
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+#define STANDARD_FACTORY_EFUSE "##select_efuse_flag\nselect_efuse:%hx\n"
|
|
+#define FACTORY_MEMBER_NUM 31
|
|
+#else
|
|
+#define STANDARD_FACTORY_EFUSE
|
|
+#define FACTORY_MEMBER_NUM 30
|
|
+#endif
|
|
+
|
|
+#define STANDARD_FACTORY __STANDARD_FACTORY STANDARD_FACTORY_EFUSE "%%%%\n"
|
|
|
|
typedef struct {
|
|
uint16_t magic;
|
|
@@ -103,6 +112,7 @@ typedef struct {
|
|
uint32_t bt_tx_power[4];
|
|
/* The temperature after 5G clibrating. */
|
|
uint16_t temperature_5G;
|
|
+ uint16_t select_efuse;
|
|
} factory_data_t;
|
|
|
|
struct factory_t {
|
|
@@ -204,5 +214,7 @@ int16_t bes2600_wifi_cali_freq_write(struct wifi_freq_cali_t *data_cali);
|
|
int16_t vendor_get_freq_cali(struct wifi_freq_cali_t *vendor_freq);
|
|
int16_t vendor_get_power_cali(struct wifi_get_power_cali_t *power_cali);
|
|
int16_t vendor_set_power_cali_flag(struct wifi_power_cali_flag_t *cali_flag);
|
|
-
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+int16_t bes2600_select_efuse_flag_write(uint16_t select_efuse_flag);
|
|
+#endif
|
|
#endif
|
|
diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/drivers/staging/bes2600/bes2600_sdio.c
|
|
index 5252951cc3bb..d9b60c72fd45 100644
|
|
--- a/drivers/staging/bes2600/bes2600_sdio.c
|
|
+++ b/drivers/staging/bes2600/bes2600_sdio.c
|
|
@@ -47,6 +47,15 @@ extern void sw_mci_rescan_card(unsigned id, unsigned insert);
|
|
extern void sunxi_wlan_set_power(bool on_off);
|
|
#endif
|
|
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+#include <linux/regulator/consumer.h>
|
|
+
|
|
+extern int cvi_sdio_rescan(void);
|
|
+extern int cvi_get_wifi_pwr_on_gpio(void);
|
|
+extern int cvi_get_wifi_reset_gpio(void);
|
|
+extern int cvi_get_wifi_wakeup_gpio(void);
|
|
+#endif
|
|
+
|
|
#if defined(BES2600_BOOT_UART_TO_SDIO)
|
|
static struct sbus_ops bes2600_sdio_sbus_ops;
|
|
extern int bes2600_boot_uart_to_sdio(struct sbus_ops *ops);
|
|
@@ -434,15 +443,23 @@ static int bes2600_sdio_reg_write(struct sbus_priv *self, u32 reg,
|
|
#ifndef CONFIG_BES2600_USE_GPIO_IRQ
|
|
static void bes2600_sdio_irq_handler(struct sdio_func *func)
|
|
{
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ int ret =0;
|
|
+#endif
|
|
struct sbus_priv *self = sdio_get_drvdata(func);
|
|
unsigned long flags;
|
|
- bes2600_dbg(BES2600_DBG_SDIO, "\n %s called, fw_started:%d \n",
|
|
- __func__, self->fw_started);
|
|
|
|
if (WARN_ON(!self)) {
|
|
return;
|
|
}
|
|
|
|
+ bes2600_dbg(BES2600_DBG_SDIO, "\n %s called, fw_started:%d \n",
|
|
+ __func__, self->fw_started);
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ sdio_claim_host(func);
|
|
+ sdio_readb(func, 1, &ret);
|
|
+ sdio_release_host(func);
|
|
+#endif
|
|
if (likely(self->fw_started && self->core)) {
|
|
queue_work(self->sdio_wq, &self->rx_work);
|
|
self->last_irq_timestamp = jiffies;
|
|
@@ -598,6 +615,16 @@ static int bes2600_sdio_off(const struct bes2600_platform_data_sdio *pdata)
|
|
rockchip_wifi_power(0);
|
|
#endif
|
|
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ if (gpio_is_valid(pdata->powerup)) {
|
|
+ gpio_direction_output(pdata->powerup, 0);
|
|
+ }
|
|
+
|
|
+ if (gpio_is_valid(pdata->reset)) {
|
|
+ gpio_direction_output(pdata->reset, 0);
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (pdata == NULL)
|
|
return 0;
|
|
|
|
@@ -626,6 +653,18 @@ static int bes2600_sdio_on(const struct bes2600_platform_data_sdio *pdata)
|
|
rockchip_wifi_set_carddetect(1);
|
|
#endif
|
|
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ if (gpio_is_valid(pdata->powerup)) {
|
|
+ gpio_direction_output(pdata->powerup, 1);
|
|
+ }
|
|
+
|
|
+ msleep(10);
|
|
+ if (gpio_is_valid(pdata->reset)) {
|
|
+ gpio_direction_output(pdata->reset, 0);
|
|
+ }
|
|
+ cvi_sdio_rescan();
|
|
+#endif
|
|
+
|
|
if (pdata != NULL) {
|
|
#ifdef BES2600_INDEPENDENT_EVB
|
|
if (gpio_is_valid(pdata->powerup)) {
|
|
@@ -1019,6 +1058,10 @@ static void sdio_scan_work(struct work_struct *work)
|
|
#ifdef PLAT_ROCKCHIP
|
|
rockchip_wifi_set_carddetect(1);
|
|
#endif
|
|
+
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ cvi_sdio_rescan();
|
|
+#endif
|
|
bes2600_info(BES2600_DBG_SDIO, "%s: power down, rescan card\n", __FUNCTION__);
|
|
}
|
|
|
|
@@ -1362,7 +1405,7 @@ static int bes2600_sdio_misc_init(struct sbus_priv *self, struct bes2600_common
|
|
return 0;
|
|
}
|
|
|
|
-#if defined(PLAT_ALLWINNER)|| defined (PLAT_ROCKCHIP)
|
|
+#if defined(PLAT_ALLWINNER)|| defined (PLAT_ROCKCHIP) || defined(PLAT_CVITEK_182X)
|
|
static struct bes2600_platform_data_sdio bes_sdio_plat_data = {
|
|
#if defined(BES2600_INDEPENDENT_EVB)
|
|
.reset = GPIOA(9),
|
|
@@ -1380,27 +1423,34 @@ static struct bes2600_platform_data_sdio bes_sdio_plat_data = {
|
|
.reset = -1,
|
|
.powerup = -1,
|
|
.wakeup = -1,
|
|
+#elif defined(PLAT_CVITEK_182X)
|
|
+ .reset = -1,
|
|
+ .powerup = -1,
|
|
+ .wakeup = -1,
|
|
+ .host_wakeup = -1,
|
|
#endif
|
|
};
|
|
#endif
|
|
|
|
struct bes2600_platform_data_sdio *bes2600_get_platform_data(void)
|
|
{
|
|
-#if defined(PLAT_ALLWINNER)|| defined (PLAT_ROCKCHIP)
|
|
+#if defined(PLAT_ALLWINNER)|| defined (PLAT_ROCKCHIP) || defined(PLAT_CVITEK_182X)
|
|
return &bes_sdio_plat_data;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
-static void bes2600_get_gpio_from_dts(int *gpio_num, const char *gpio_name)
|
|
+
|
|
+static void __attribute__((unused)) bes2600_get_gpio_from_dts(int *gpio_num, const char *gpio_name)
|
|
{
|
|
int wakeup_gpio;
|
|
- enum of_gpio_flags flags;
|
|
+ // enum of_gpio_flags flags;
|
|
struct device_node *wireless_node;
|
|
wireless_node = of_find_node_with_property(NULL, gpio_name);
|
|
if(wireless_node != NULL){
|
|
- wakeup_gpio = of_get_named_gpio_flags(wireless_node, gpio_name, 0, &flags);
|
|
+ // wakeup_gpio = of_get_named_gpio_flags(wireless_node, gpio_name, 0, &flags);
|
|
+ wakeup_gpio = of_get_named_gpio(wireless_node, gpio_name, 0);
|
|
if (gpio_is_valid(wakeup_gpio))
|
|
*gpio_num = wakeup_gpio;
|
|
}else{
|
|
@@ -1408,6 +1458,7 @@ static void bes2600_get_gpio_from_dts(int *gpio_num, const char *gpio_name)
|
|
}
|
|
}
|
|
|
|
+
|
|
static int bes2600_platform_data_init(void)
|
|
{
|
|
int ret = 0;
|
|
@@ -1416,6 +1467,9 @@ static int bes2600_platform_data_init(void)
|
|
return 0;
|
|
|
|
/* Ensure I/Os are pulled low */
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ pdata->reset=cvi_get_wifi_reset_gpio();
|
|
+#endif
|
|
if (gpio_is_valid(pdata->reset)) {
|
|
ret = gpio_request(pdata->reset, "bes2600_wlan_reset");
|
|
if (ret) {
|
|
@@ -1427,7 +1481,9 @@ static int bes2600_platform_data_init(void)
|
|
} else {
|
|
bes2600_err(BES2600_DBG_SDIO, "reset is invalid\n");
|
|
}
|
|
-
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ pdata->powerup=cvi_get_wifi_pwr_on_gpio();
|
|
+#endif
|
|
if (gpio_is_valid(pdata->powerup)) {
|
|
ret = gpio_request(pdata->powerup, "bes2600_wlan_powerup");
|
|
if (ret) {
|
|
@@ -1439,8 +1495,11 @@ static int bes2600_platform_data_init(void)
|
|
} else {
|
|
bes2600_err(BES2600_DBG_SDIO, "powerup is invalid\n");
|
|
}
|
|
-
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ pdata->wakeup=cvi_get_wifi_wakeup_gpio();
|
|
+#else
|
|
bes2600_get_gpio_from_dts(&pdata->wakeup, "WIFI,host_wakeup_wifi");
|
|
+#endif
|
|
if (gpio_is_valid(pdata->wakeup)) {
|
|
ret = gpio_request(pdata->wakeup, "bes2600_wakeup");
|
|
if (ret) {
|
|
@@ -1452,8 +1511,9 @@ static int bes2600_platform_data_init(void)
|
|
} else {
|
|
bes2600_err(BES2600_DBG_SDIO, "wakeup is invalid\n");
|
|
}
|
|
-
|
|
+#ifndef PLAT_CVITEK_182X
|
|
bes2600_get_gpio_from_dts(&pdata->host_wakeup, "WIFI,host_wake_irq");
|
|
+#endif
|
|
if (gpio_is_valid(pdata->host_wakeup)) {
|
|
ret = gpio_request(pdata->host_wakeup, "bes2600_host_irq");
|
|
if (ret) {
|
|
@@ -1957,6 +2017,14 @@ static void bes2600_sdio_power_down(struct sbus_priv *self)
|
|
#if defined(PLAT_ALLWINNER)
|
|
sunxi_wlan_set_power(false);
|
|
#endif
|
|
+
|
|
+#ifdef PLAT_CVITEK_182X
|
|
+ struct bes2600_platform_data_sdio *pdata = bes2600_get_platform_data();
|
|
+
|
|
+ if (gpio_is_valid(pdata->powerup)) {
|
|
+ gpio_direction_output(pdata->powerup, 0);
|
|
+ }
|
|
+#endif
|
|
#endif
|
|
|
|
msleep(10);
|
|
@@ -2232,6 +2300,7 @@ static irqreturn_t bes2600_wlan_bt_hostwake_thread(int irq, void *dev_id)
|
|
bes2600_info(BES2600_DBG_SDIO, "bes2600_wlan_hostwake:%d\n", dev_id == (void *)pdata);
|
|
|
|
if (dev_id == (void *)pdata) {
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_SETTING);
|
|
pdata->wakeup_source = true;
|
|
disable_irq_nosync(irq);
|
|
return IRQ_HANDLED;
|
|
@@ -2277,9 +2346,9 @@ static int bes2600_wlan_bt_hostwake_register(void)
|
|
|
|
static void bes2600_wlan_bt_hostwake_unregister(void)
|
|
{
|
|
+ int ret = 0;
|
|
struct bes2600_platform_data_sdio *pdata = bes2600_get_platform_data();
|
|
|
|
- int ret = 0;
|
|
#if defined(PLAT_ALLWINNER)
|
|
int irq = sunxi_wlan_get_oob_irq();
|
|
#elif defined(PLAT_ROCKCHIP)
|
|
diff --git a/drivers/staging/bes2600/bes_chardev.c b/drivers/staging/bes2600/bes_chardev.c
|
|
index 77573e59952e..e4c81cf0c922 100644
|
|
--- a/drivers/staging/bes2600/bes_chardev.c
|
|
+++ b/drivers/staging/bes2600/bes_chardev.c
|
|
@@ -73,7 +73,10 @@ struct bes_cdev
|
|
int no_dpd;
|
|
#endif
|
|
enum pend_read_op read_flag;
|
|
- u32 wakeup_state; /* for userspace check wakeup reason */
|
|
+ enum wakeup_event wakeup_by_event; /* used to filter unwanted event wakeup reason report */
|
|
+ u16 wakeup_state; /* for userspace check wakeup reason */
|
|
+ wait_queue_head_t wakeup_reason_wq;
|
|
+ u16 src_port;
|
|
#ifdef BES2600_DUMP_FW_DPD_LOG
|
|
u8 *dpd_log;
|
|
u16 dpd_log_len;
|
|
@@ -608,10 +611,17 @@ static ssize_t bes2600_chrdev_read(struct file *file, char __user *user_buf,
|
|
{
|
|
char buf[64] = {0};
|
|
unsigned int len;
|
|
+ long status = 0;
|
|
|
|
switch (bes2600_cdev.read_flag) {
|
|
case BES_CDEV_READ_WAKEUP_STATE:
|
|
- len = sprintf(buf, "wakeup_state:%u\n", bes2600_cdev.wakeup_state);
|
|
+ if (bes2600_chrdev_wakeup_by_event_get() > WAKEUP_EVENT_NONE) {
|
|
+ status = wait_event_timeout(bes2600_cdev.wakeup_reason_wq,
|
|
+ bes2600_chrdev_wakeup_by_event_get() == WAKEUP_EVENT_NONE, HZ * 2);
|
|
+ WARN_ON(status <= 0);
|
|
+ }
|
|
+ len = sprintf(buf, "wakeup_reason: %u, src_port: %u\n",
|
|
+ bes2600_cdev.wakeup_state, bes2600_cdev.src_port);
|
|
break;
|
|
default:
|
|
len = sprintf(buf, "dpd_calied:%d wifi_opened:%d bt_opened:%d fw_type:%d\n",
|
|
@@ -729,13 +739,35 @@ static int bes2600_chrdev_write_dpd_data_to_file(const char *path, void *buffer,
|
|
return ret;
|
|
}
|
|
|
|
+static bool bes2600_chrdev_dpd_is_vaild(u8 *dpd_data)
|
|
+{
|
|
+ u32 cal_crc = 0;
|
|
+ u32 dpd_crc = le32_to_cpup((__le32 *)(dpd_data));
|
|
+ u32 dpd_ver = le32_to_cpup((__le32 *)(dpd_data + DPD_VERSION_OFFSET));
|
|
+
|
|
+ /* check version */
|
|
+ if (dpd_ver < DPD_CUR_VERSION)
|
|
+ return false;
|
|
+
|
|
+ cal_crc ^= 0xffffffffL;
|
|
+ cal_crc = crc32_le(cal_crc, dpd_data + 4, DPD_BIN_SIZE - 4);
|
|
+ cal_crc ^= 0xffffffffL;
|
|
+
|
|
+ /* check if the dpd data is valid */
|
|
+ if (cal_crc != dpd_crc) {
|
|
+ bes2600_err(BES2600_DBG_CHARDEV,
|
|
+ "bes2600 dpd data from file check failed, calc_crc:0x%08x dpd_crc: 0x%08x\n",
|
|
+ cal_crc, dpd_crc);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static int bes2600_chrdev_read_and_check_dpd_data(const char *file, u8 **data, u32 *len)
|
|
{
|
|
int ret = 0;
|
|
- u32 read_len = 0;
|
|
u8* read_data = NULL;
|
|
- u32 cal_crc = 0;
|
|
- u32 dpd_crc = 0;
|
|
struct file *fp;
|
|
|
|
/* open file */
|
|
@@ -773,27 +805,16 @@ static int bes2600_chrdev_read_and_check_dpd_data(const char *file, u8 **data, u
|
|
goto err2;
|
|
}
|
|
|
|
- /* calculate crc value */
|
|
- read_len = DPD_BIN_SIZE;
|
|
- dpd_crc = *((u32 *)read_data);
|
|
- cal_crc ^= 0xffffffffL;
|
|
- cal_crc = crc32_le(cal_crc, read_data + 4, read_len - 4);
|
|
- cal_crc ^= 0xffffffffL;
|
|
-
|
|
- /* check if the dpd data is valid */
|
|
- if(cal_crc != dpd_crc) {
|
|
- bes2600_err(BES2600_DBG_CHARDEV,
|
|
- "bes2600 dpd data from file check failed, calc_crc:0x%08x dpd_crc: 0x%08x\n",
|
|
- cal_crc, dpd_crc);
|
|
+ /* check dpd version and crc */
|
|
+ if (!bes2600_chrdev_dpd_is_vaild(read_data))
|
|
goto err2;
|
|
- }
|
|
|
|
/* close file */
|
|
filp_close(fp, NULL);
|
|
|
|
/* copy data to external */
|
|
*data = read_data;
|
|
- *len = read_len;
|
|
+ *len = DPD_BIN_SIZE;;
|
|
|
|
/* output debug information */
|
|
bes2600_info(BES2600_DBG_CHARDEV, "read dpd data from %s\n", file);
|
|
@@ -862,7 +883,7 @@ void bes2600_chrdev_free_dpd_data(void)
|
|
int bes2600_chrdev_update_dpd_data(void)
|
|
{
|
|
u32 cal_crc = 0;
|
|
- u32 dpd_crc = *((u32 *)bes2600_cdev.dpd_data);
|
|
+ u32 dpd_crc = le32_to_cpup((__le32 *)(bes2600_cdev.dpd_data));
|
|
|
|
/* check if the dpd data is valid */
|
|
cal_crc ^= 0xffffffffL;
|
|
@@ -1165,7 +1186,7 @@ void bes2600_chrdev_start_bus_probe(void)
|
|
spin_unlock(&bes2600_cdev.status_lock);
|
|
|
|
cancel_delayed_work_sync(&bes2600_cdev.probe_timeout_work);
|
|
- schedule_delayed_work(&bes2600_cdev.probe_timeout_work, (HZ * 8) / 10);
|
|
+ schedule_delayed_work(&bes2600_cdev.probe_timeout_work, 3 * HZ);
|
|
}
|
|
|
|
void bes2600_chrdev_bus_probe_notify(void)
|
|
@@ -1178,13 +1199,30 @@ void bes2600_chrdev_bus_probe_notify(void)
|
|
wake_up(&bes2600_cdev.probe_done_wq);
|
|
}
|
|
|
|
-void bes2600_chrdev_wifi_update_wakeup_reason(u32 val)
|
|
+#if defined(CONFIG_BES2600_WLAN_SDIO) || defined(CONFIG_BES2600_WLAN_SPI)
|
|
+void bes2600_chrdev_wifi_update_wakeup_reason(u16 reason, u16 port)
|
|
{
|
|
spin_lock(&bes2600_cdev.status_lock);
|
|
- bes2600_cdev.wakeup_state = val;
|
|
+ bes2600_cdev.wakeup_state = reason;
|
|
+ bes2600_cdev.src_port = port;
|
|
spin_unlock(&bes2600_cdev.status_lock);
|
|
}
|
|
|
|
+void bes2600_chrdev_wakeup_by_event_set(enum wakeup_event wakeup_event)
|
|
+{
|
|
+ spin_lock(&bes2600_cdev.status_lock);
|
|
+ bes2600_cdev.wakeup_by_event = wakeup_event;
|
|
+ spin_unlock(&bes2600_cdev.status_lock);
|
|
+ if (wakeup_event == WAKEUP_EVENT_NONE)
|
|
+ wake_up(&bes2600_cdev.wakeup_reason_wq);
|
|
+}
|
|
+
|
|
+int bes2600_chrdev_wakeup_by_event_get(void)
|
|
+{
|
|
+ return bes2600_cdev.wakeup_by_event;
|
|
+}
|
|
+#endif
|
|
+
|
|
int bes2600_chrdev_init(struct sbus_ops *ops)
|
|
{
|
|
int ret = 0;
|
|
@@ -1234,6 +1272,8 @@ int bes2600_chrdev_init(struct sbus_ops *ops)
|
|
init_waitqueue_head(&bes2600_cdev.probe_done_wq);
|
|
INIT_WORK(&bes2600_cdev.wifi_force_close_work, bes2600_chrdev_wifi_force_close_work);
|
|
INIT_DELAYED_WORK(&bes2600_cdev.probe_timeout_work, bes2600_probe_timeout_work);
|
|
+ init_waitqueue_head(&bes2600_cdev.wakeup_reason_wq);
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
#ifdef CONFIG_BES2600_WIFI_BOOT_ON
|
|
bes2600_cdev.wifi_opened = true;
|
|
#else
|
|
@@ -1252,6 +1292,7 @@ int bes2600_chrdev_init(struct sbus_ops *ops)
|
|
bes2600_cdev.bus_error = false;
|
|
bes2600_cdev.halt_dev = false;
|
|
bes2600_cdev.read_flag = BES_CDEV_READ_NUM_MAX;
|
|
+ bes2600_cdev.wakeup_by_event = false;
|
|
bes2600_info(BES2600_DBG_CHARDEV, "%s done\n", __func__);
|
|
|
|
return 0;
|
|
diff --git a/drivers/staging/bes2600/bes_chardev.h b/drivers/staging/bes2600/bes_chardev.h
|
|
index 8c7257c087a4..5c2519879135 100644
|
|
--- a/drivers/staging/bes2600/bes_chardev.h
|
|
+++ b/drivers/staging/bes2600/bes_chardev.h
|
|
@@ -16,8 +16,10 @@
|
|
#define BES2600_FW_TYPE_BT 2
|
|
#define BES2600_FW_TYPE_MAX_NUM 3
|
|
|
|
-#define DPD_BIN_SIZE 0x3AF8
|
|
+#define DPD_VERSION_OFFSET 0x3AF4
|
|
+#define DPD_BIN_SIZE 0x3B14
|
|
#define DPD_BIN_FILE_SIZE 0x4000
|
|
+#define DPD_CUR_VERSION 7
|
|
|
|
enum pend_read_op {
|
|
BES_CDEV_READ_WAKEUP_STATE = 0,
|
|
@@ -26,6 +28,25 @@ enum pend_read_op {
|
|
BES_CDEV_READ_NUM_MAX,
|
|
};
|
|
|
|
+enum wifi_wakeup_reason_code {
|
|
+ WAKEUP_REASON_WIFI_DEAUTH_DISASSOC = 0x1000,
|
|
+ WAKEUP_REASON_WIFI_BSSLOST,
|
|
+ /* add new here */
|
|
+};
|
|
+
|
|
+enum bt_wakeup_reason_code {
|
|
+ WAKEUP_REASON_BT_PLAY = 0x0100,
|
|
+ /* add new here */
|
|
+};
|
|
+
|
|
+enum wakeup_event {
|
|
+ WAKEUP_EVENT_NONE = 0,
|
|
+ WAKEUP_EVENT_SETTING,
|
|
+ WAKEUP_EVENT_WSME,
|
|
+ WAKEUP_EVENT_PEER_DETACH,
|
|
+ /* add new here */
|
|
+};
|
|
+
|
|
/* dpd management */
|
|
u8* bes2600_chrdev_get_dpd_buffer(u32 size);
|
|
int bes2600_chrdev_update_dpd_data(void);
|
|
@@ -54,9 +75,17 @@ bool bes2600_chrdev_is_bus_error(void);
|
|
void bes2600_chrdev_start_bus_probe(void);
|
|
void bes2600_chrdev_bus_probe_notify(void);
|
|
|
|
+#if defined(CONFIG_BES2600_WLAN_SDIO) || defined(CONFIG_BES2600_WLAN_SPI)
|
|
/* set wifi wakeup state */
|
|
-void bes2600_chrdev_wifi_update_wakeup_reason(u32 val);
|
|
-
|
|
+void bes2600_chrdev_wifi_update_wakeup_reason(u16 reason, u16 port);
|
|
+void bes2600_chrdev_wakeup_by_event_set(enum wakeup_event wakeup_event);
|
|
+int bes2600_chrdev_wakeup_by_event_get(void);
|
|
+#else
|
|
+/* set wifi wakeup state */
|
|
+static inline void bes2600_chrdev_wifi_update_wakeup_reason(u16 reason, u16 port) { }
|
|
+static inline void bes2600_chrdev_wakeup_by_event_set(enum wakeup_event wakeup_event) { }
|
|
+static inline int bes2600_chrdev_wakeup_by_event_get(void) { return 0; }
|
|
+#endif
|
|
/* init and deinit module */
|
|
int bes2600_chrdev_init(struct sbus_ops *ops);
|
|
void bes2600_chrdev_free(void);
|
|
diff --git a/drivers/staging/bes2600/bes_fw.c b/drivers/staging/bes2600/bes_fw.c
|
|
index 67f361c0431f..b32d514c0ec9 100644
|
|
--- a/drivers/staging/bes2600/bes_fw.c
|
|
+++ b/drivers/staging/bes2600/bes_fw.c
|
|
@@ -1341,7 +1341,13 @@ static int bes_read_dpd_data(struct sbus_ops *ops, struct sbus_priv *priv)
|
|
goto exit;
|
|
}
|
|
|
|
- dpd_data = bes2600_chrdev_get_dpd_buffer(dpd_data_len);
|
|
+ /* dpd size check */
|
|
+ if (dpd_data_len != DPD_BIN_SIZE) {
|
|
+ bes2600_err(BES2600_DBG_DOWNLOAD, "get dpd data size err:%u\n", dpd_data_len);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ dpd_data = bes2600_chrdev_get_dpd_buffer(DPD_BIN_FILE_SIZE);
|
|
if (!dpd_data) {
|
|
ret = -ENOMEM;
|
|
goto exit;
|
|
diff --git a/drivers/staging/bes2600/bes_nl80211_testmode_msg.h b/drivers/staging/bes2600/bes_nl80211_testmode_msg.h
|
|
index a05f9f862704..b70a0dddc6c3 100644
|
|
--- a/drivers/staging/bes2600/bes_nl80211_testmode_msg.h
|
|
+++ b/drivers/staging/bes2600/bes_nl80211_testmode_msg.h
|
|
@@ -27,6 +27,13 @@ struct bes_event_test_t {
|
|
int dummy;
|
|
};
|
|
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+/*example command structure for set select efuse*/
|
|
+struct bes_select_calib_t {
|
|
+ uint16_t select_efuse_flag;
|
|
+};
|
|
+#endif
|
|
+
|
|
/* vendor to mcu cmd msg reply structure */
|
|
struct vendor_rf_cmd_msg_reply {
|
|
u32 id;
|
|
@@ -65,6 +72,8 @@ enum bes_msg_id {
|
|
BES_MSG_EPTA_PARM_CONFIG,
|
|
BES_MSG_GET_KEEP_ALIVE_STREAM,
|
|
BES_MSG_MCU_CPUUSAGE,
|
|
+ BES_MSG_SAVE_CALI_TXT_TO_EFUSE,
|
|
+ BES_MSG_SET_SELECT_EFUSE_FLAG,
|
|
/* Add new IDs here */
|
|
|
|
BES_MSG_ID_MAX,
|
|
@@ -78,6 +87,7 @@ enum vendor_rf_cmd_type {
|
|
VENDOR_RF_SAVE_FREQOFFSET_CMD,
|
|
VENDOR_RF_SAVE_POWERLEVEL_CMD,
|
|
VENDOR_RF_POWER_CALIB_FINISH,
|
|
+ VENDOR_RF_GET_CALI_FROM_EFUSE,
|
|
/* add new here */
|
|
|
|
VENDOR_RF_CMD_MAX,
|
|
diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c
|
|
index 19d7ed26fde8..4da84cf519bc 100644
|
|
--- a/drivers/staging/bes2600/bes_pwr.c
|
|
+++ b/drivers/staging/bes2600/bes_pwr.c
|
|
@@ -436,8 +436,8 @@ static void bes2600_pwr_delete_all_cb(struct bes2600_common *hw_priv)
|
|
|
|
/* delete all cb in exit_cb_list */
|
|
list_for_each_entry_safe(item1, temp1, &hw_priv->bes_power.exit_cb_list, link) {
|
|
- list_del(&item->link);
|
|
- kfree(item);
|
|
+ list_del(&item1->link);
|
|
+ kfree(item1);
|
|
}
|
|
|
|
mutex_unlock(&hw_priv->bes_power.pwr_cb_mutex);
|
|
@@ -487,13 +487,14 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
|
|
|
|
if (priv->join_status == BES2600_JOIN_STATUS_STA &&
|
|
priv->bss_params.aid &&
|
|
- priv->setbssparams_done &&
|
|
- priv->filter4.enable) {
|
|
+ priv->setbssparams_done) {
|
|
/* enable arp filter */
|
|
- bes2600_dbg(BES2600_DBG_PWR, "%s, arp filter, enable:%d addr:%s\n",
|
|
- __func__, priv->filter4.enable, bes2600_get_mac_str(ip_str, priv->filter4.ipv4Address[0]));
|
|
- ret = wsm_set_arp_ipv4_filter(hw_priv, &priv->filter4, priv->if_id);
|
|
- bes2600_err_with_cond(ret, BES2600_DBG_PWR, "%s, set arp filter failed\n", __func__);
|
|
+ if (priv->filter4.enable) {
|
|
+ bes2600_dbg(BES2600_DBG_PWR, "%s, arp filter, enable:%d addr:%s\n",
|
|
+ __func__, priv->filter4.enable, bes2600_get_mac_str(ip_str, priv->filter4.ipv4Address[0]));
|
|
+ ret = wsm_set_arp_ipv4_filter(hw_priv, &priv->filter4, priv->if_id);
|
|
+ bes2600_err_with_cond(ret, BES2600_DBG_PWR, "%s, set arp filter failed\n", __func__);
|
|
+ }
|
|
|
|
/* skip beacon receive if applications don't have muticast service */
|
|
if(priv->join_dtim_period && !priv->has_multicast_subscription) {
|
|
@@ -501,14 +502,15 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
|
|
if(priv->join_dtim_period >= CONFIG_BES2600_LISTEN_INTERVAL) {
|
|
listen_interval = priv->join_dtim_period;
|
|
} else {
|
|
- listen_interval = CONFIG_BES2600_LISTEN_INTERVAL / priv->join_dtim_period;
|
|
+ listen_interval = CONFIG_BES2600_LISTEN_INTERVAL / priv->join_dtim_period * priv->join_dtim_period;
|
|
}
|
|
ret = wsm_set_beacon_wakeup_period(hw_priv, 1, listen_interval, priv->if_id);
|
|
bes2600_err_with_cond(ret, BES2600_DBG_PWR, "%s, set wakeup period failed\n", __func__);
|
|
}
|
|
|
|
/* Set Enable Broadcast Address Filter */
|
|
- priv->broadcast_filter.action_mode = WSM_FILTER_ACTION_FILTER_OUT;
|
|
+ priv->broadcast_filter.action_mode = priv->filter4.enable ?
|
|
+ WSM_FILTER_ACTION_FILTER_OUT : WSM_FILTER_ACTION_IGNORE;
|
|
if (priv->join_status == BES2600_JOIN_STATUS_AP)
|
|
priv->broadcast_filter.address_mode = WSM_FILTER_ADDR_MODE_A3;
|
|
ret = bes2600_set_macaddrfilter(hw_priv, priv, (u8 *)&priv->broadcast_filter);
|
|
@@ -587,15 +589,16 @@ static int bes2600_pwr_exit_lp_mode(struct bes2600_common *hw_priv)
|
|
|
|
if (priv->join_status == BES2600_JOIN_STATUS_STA &&
|
|
priv->bss_params.aid &&
|
|
- priv->setbssparams_done &&
|
|
- priv->filter4.enable) {
|
|
- /* enable arp filter */
|
|
- filter = priv->filter4;
|
|
- filter.enable = false;
|
|
- bes2600_dbg(BES2600_DBG_PWR, "%s, arp filter, enable:%d addr:%s\n",
|
|
- __func__, filter.enable, bes2600_get_mac_str(ip_str, filter.ipv4Address[0]));
|
|
- ret = wsm_set_arp_ipv4_filter(hw_priv, &filter, priv->if_id);
|
|
- bes2600_err_with_cond(ret, BES2600_DBG_PWR, "%s, set arp filter failed\n", __func__);
|
|
+ priv->setbssparams_done) {
|
|
+ /* disable arp filter */
|
|
+ if (priv->filter4.enable) {
|
|
+ filter = priv->filter4;
|
|
+ filter.enable = false;
|
|
+ bes2600_dbg(BES2600_DBG_PWR, "%s, arp filter, enable:%d addr:%s\n",
|
|
+ __func__, filter.enable, bes2600_get_mac_str(ip_str, filter.ipv4Address[0]));
|
|
+ ret = wsm_set_arp_ipv4_filter(hw_priv, &filter, priv->if_id);
|
|
+ bes2600_err_with_cond(ret, BES2600_DBG_PWR, "%s, set arp filter failed\n", __func__);
|
|
+ }
|
|
|
|
/* set wakeup perioid */
|
|
wsm_set_beacon_wakeup_period(hw_priv, priv->join_dtim_period, 0, priv->if_id);
|
|
@@ -1404,3 +1407,28 @@ int bes2600_pwr_busy_event_dump(struct bes2600_common *hw_priv, char *buffer, u3
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+int bes2600_pwr_busy_event_record(struct bes2600_common *hw_priv, char *buffer, u32 buf_len)
|
|
+{
|
|
+ unsigned long max_timeout = 0;
|
|
+ struct bes2600_pwr_event_t *item = NULL;
|
|
+ unsigned long flags;
|
|
+
|
|
+ if(!buffer) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ spin_lock_irqsave(&hw_priv->bes_power.pwr_lock, flags);
|
|
+ bes2600_update_power_delay_events(&hw_priv->bes_power, &max_timeout);
|
|
+ if(!list_empty(&hw_priv->bes_power.pending_event_list)) {
|
|
+ list_for_each_entry(item, &hw_priv->bes_power.pending_event_list, link) {
|
|
+ snprintf(buffer, buf_len, "Event: %9s. Flag: %s. timeout(ticks): %lu.\n",
|
|
+ bes2600_get_pwr_busy_event_name(item),
|
|
+ BES_PWR_IS_CONSTANT_EVENT(item->event) ? "C" : "D",
|
|
+ bes2600_get_pwr_busy_event_timeout(item));
|
|
+ }
|
|
+ }
|
|
+ spin_unlock_irqrestore(&hw_priv->bes_power.pwr_lock, flags);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/drivers/staging/bes2600/bes_pwr.h b/drivers/staging/bes2600/bes_pwr.h
|
|
index 2c27f4293a55..1ba866c25c42 100644
|
|
--- a/drivers/staging/bes2600/bes_pwr.h
|
|
+++ b/drivers/staging/bes2600/bes_pwr.h
|
|
@@ -135,6 +135,7 @@ void bes2600_pwr_mcu_sleep_directly(struct bes2600_common *hw_priv);
|
|
void bes2600_pwr_mark_ap_lp_bad(struct bes2600_common *hw_priv);
|
|
void bes2600_pwr_clear_ap_lp_bad_mark(struct bes2600_common *hw_priv);
|
|
int bes2600_pwr_busy_event_dump(struct bes2600_common *hw_priv, char *buffer, u32 buf_len);
|
|
+int bes2600_pwr_busy_event_record(struct bes2600_common *hw_priv, char *buffer, u32 buf_len);
|
|
#else
|
|
static inline void bes2600_pwr_init(struct bes2600_common *hw_priv) { }
|
|
static inline void bes2600_pwr_exit(struct bes2600_common *hw_priv) { }
|
|
@@ -162,6 +163,7 @@ static inline void bes2600_pwr_mcu_sleep_directly(struct bes2600_common *hw_priv
|
|
static inline void bes2600_pwr_mark_ap_lp_bad(struct bes2600_common *hw_priv) { }
|
|
static inline void bes2600_pwr_clear_ap_lp_bad_mark(struct bes2600_common *hw_priv) { }
|
|
static inline int bes2600_pwr_busy_event_dump(struct bes2600_common *hw_priv, char *buffer, u32 buf_len) { return 0; }
|
|
+static inline int bes2600_pwr_busy_event_record(struct bes2600_common *hw_priv, char *buffer, u32 buf_len) { return 0; }
|
|
#endif
|
|
|
|
#endif
|
|
\ No newline at end of file
|
|
diff --git a/drivers/staging/bes2600/bh.c b/drivers/staging/bes2600/bh.c
|
|
index fed5101d42c6..082eaa8e200f 100644
|
|
--- a/drivers/staging/bes2600/bh.c
|
|
+++ b/drivers/staging/bes2600/bh.c
|
|
@@ -955,6 +955,7 @@ static void bes2600_bh_parse_wakeup_event(struct bes2600_common *hw_priv, struct
|
|
{
|
|
struct wsm_hdr *wsm = (struct wsm_hdr *)skb->data;
|
|
u16 wsm_id = __le16_to_cpu(wsm->id) & 0xFFF;
|
|
+ bool set_wakeup_reason_later = false;
|
|
|
|
if (hw_priv->sbus_ops->wakeup_source &&
|
|
hw_priv->sbus_ops->wakeup_source(hw_priv->sbus_priv)) {
|
|
@@ -966,15 +967,29 @@ static void bes2600_bh_parse_wakeup_event(struct bes2600_common *hw_priv, struct
|
|
if (ieee80211_is_mgmt(fctl)) {
|
|
u16 type = (fctl & cpu_to_le16(IEEE80211_FCTL_FTYPE)) >> 2;
|
|
u16 stype = (fctl & cpu_to_le16(IEEE80211_FCTL_STYPE)) >> 4;
|
|
+ if (ieee80211_is_deauth(fctl) || ieee80211_is_disassoc(fctl)) {
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_PEER_DETACH);
|
|
+ set_wakeup_reason_later = true;
|
|
+ bes2600_info(BES2600_DBG_BH, "Host was waked by mgmt(deauth or disassoc)\n");
|
|
+ }
|
|
bes2600_info(BES2600_DBG_BH, "Host was waked by mgmt, type:%d(%d)\n", type, stype);
|
|
- } else if(ieee80211_is_data(fctl)){
|
|
+ } else if (ieee80211_is_data(fctl)){
|
|
bes2600_bh_parse_data_pkt(hw_priv, skb);
|
|
} else {
|
|
bes2600_info(BES2600_DBG_BH, "Host was waked by unexpected frame, fctl:0x%04x\n", fctl);
|
|
}
|
|
+ } else if (wsm_id == 0x0C31) {
|
|
+ bes2600_info(BES2600_DBG_BH, "Host was waked by BT:0x%04x.\n", wsm_id);
|
|
+ bes2600_chrdev_wifi_update_wakeup_reason(WAKEUP_REASON_BT_PLAY, 0);
|
|
} else {
|
|
+ if (wsm_id == 0x0805) {
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_WSME);
|
|
+ set_wakeup_reason_later = true;
|
|
+ }
|
|
bes2600_info(BES2600_DBG_BH, "Host was waked by event:0x%04x.\n", wsm_id);
|
|
}
|
|
+ if (!set_wakeup_reason_later)
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
}
|
|
}
|
|
|
|
@@ -1451,7 +1466,8 @@ static int bes2600_bh(void *arg)
|
|
|
|
if (!hw_priv->hw_bufs_used &&
|
|
!bes2600_pwr_device_is_idle(hw_priv) &&
|
|
- !atomic_read(&hw_priv->recent_scan)) {
|
|
+ !atomic_read(&hw_priv->recent_scan) &&
|
|
+ bes2600_chrdev_is_signal_mode()) {
|
|
status = 5 * HZ;
|
|
} else if (hw_priv->hw_bufs_used) {
|
|
/* Interrupt loss detection */
|
|
diff --git a/drivers/staging/bes2600/debug.c b/drivers/staging/bes2600/debug.c
|
|
index c5bba0789a3c..0e51f53f3af2 100644
|
|
--- a/drivers/staging/bes2600/debug.c
|
|
+++ b/drivers/staging/bes2600/debug.c
|
|
@@ -82,7 +82,11 @@ static void bes2600_queue_status_show(struct seq_file *seq,
|
|
seq_printf(seq, " pending: %ld\n", (long)q->num_pending);
|
|
seq_printf(seq, " sent: %ld\n", (long)q->num_sent);
|
|
seq_printf(seq, " locked: %s\n", q->tx_locked_cnt ? "yes" : "no");
|
|
- seq_printf(seq, " overfull: %s\n", q->overfull ? "yes" : "no");
|
|
+ seq_printf(seq, " vif_overfull[0]: %s\n", q->vif_overfull[0] ? "yes" : "no");
|
|
+ seq_printf(seq, " vif_overfull[1]: %s\n", q->vif_overfull[1] ? "yes" : "no");
|
|
+#ifdef P2P_MULTIVIF
|
|
+ seq_printf(seq, " vif_overfull[2]: %s\n", q->vif_overfull[2] ? "yes" : "no");
|
|
+#endif
|
|
seq_puts(seq, " link map: 0-> ");
|
|
for (if_id = 0; if_id < CW12XX_MAX_VIFS; if_id++) {
|
|
for (i = 0; i < q->stats->map_capacity; ++i)
|
|
diff --git a/drivers/staging/bes2600/epta_request.c b/drivers/staging/bes2600/epta_request.c
|
|
index 44676dcbc6d7..abbd4abc31ae 100644
|
|
--- a/drivers/staging/bes2600/epta_request.c
|
|
+++ b/drivers/staging/bes2600/epta_request.c
|
|
@@ -105,8 +105,8 @@ typedef enum {
|
|
BWIFI_BT_STATUS_SHUTDOWN = 0,
|
|
BWIFI_BT_STATUS_DISCONNECTED = 1,
|
|
BWIFI_BT_STATUS_CONNECTING = 2,
|
|
- BWIFI_BT_STATUS_CONNECTED_SNIFF = 3,//
|
|
- BWIFI_BT_STATUS_CONNECTED = 4,//
|
|
+ BWIFI_BT_STATUS_CONNECTED_SNIFF = 3,
|
|
+ BWIFI_BT_STATUS_CONNECTED = 4,
|
|
} BWIFI_BT_STATUS_T;
|
|
|
|
typedef enum {
|
|
@@ -123,23 +123,23 @@ typedef enum {
|
|
} BWIFI_BT_AUDIO_T;
|
|
|
|
typedef enum {
|
|
- BWIFI_BT_INQ_STOP = 0,//
|
|
- BWIFI_BT_INQ_START = 1,//
|
|
+ BWIFI_BT_INQ_STOP = 0,
|
|
+ BWIFI_BT_INQ_START = 1,
|
|
} BWIFI_BT_INQ_T;
|
|
|
|
typedef enum {
|
|
- BWIFI_LE_SCAN_STOP = 0,//
|
|
- BWIFI_LE_SCAN_START = 1,//
|
|
+ BWIFI_LE_SCAN_STOP = 0,
|
|
+ BWIFI_LE_SCAN_START = 1,
|
|
} BWIFI_BT_LE_SCAN_T;
|
|
|
|
typedef enum {
|
|
- BWIFI_LE_ADV_STOP = 0,//
|
|
- BWIFI_LE_ADV_START = 1,//
|
|
+ BWIFI_LE_ADV_STOP = 0,
|
|
+ BWIFI_LE_ADV_START = 1,
|
|
} BWIFI_BT_LE_ADV_T;
|
|
|
|
typedef enum {
|
|
- BWIFI_LE_DISCONNECTED = 0,//
|
|
- BWIFI_LE_CONNECTED = 1,//
|
|
+ BWIFI_LE_DISCONNECTED = 0,
|
|
+ BWIFI_LE_CONNECTED = 1,
|
|
} BWIFI_BT_LE_STATUS_T;
|
|
|
|
enum COEX_BT_OPER_T {
|
|
@@ -206,8 +206,8 @@ void coex_calc_wifi_scan_time(uint32_t *min_chan, uint32_t *max_chan)
|
|
uint32_t time = coex_calc_bt_time();
|
|
|
|
if (time == 0) {
|
|
- *min_chan = 90;
|
|
- *max_chan = 90;
|
|
+ *min_chan = 100;
|
|
+ *max_chan = 100;
|
|
} else if (time < 40000) {
|
|
*min_chan = 50;
|
|
*max_chan = 110;
|
|
diff --git a/drivers/staging/bes2600/main.c b/drivers/staging/bes2600/main.c
|
|
index 675839d7177a..cc33b16a3b5a 100644
|
|
--- a/drivers/staging/bes2600/main.c
|
|
+++ b/drivers/staging/bes2600/main.c
|
|
@@ -46,6 +46,9 @@ MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>");
|
|
MODULE_DESCRIPTION("Softmac BES2600 common code");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_ALIAS("bes2600");
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
|
+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
|
|
+#endif
|
|
|
|
static u8 bes2600_mac_template[ETH_ALEN] = {
|
|
#if (GET_MAC_ADDR_METHOD == 2)||(GET_MAC_ADDR_METHOD == 3)
|
|
@@ -199,7 +202,7 @@ static struct ieee80211_supported_band bes2600_band_2ghz = {
|
|
.n_bitrates = bes2600_g_rates_size,
|
|
.ht_cap = {
|
|
.cap = IEEE80211_HT_CAP_GRN_FLD |
|
|
- (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
|
|
+ (STBC_RX_24G << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
|
|
IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
|
|
IEEE80211_HT_CAP_SGI_20 |
|
|
IEEE80211_HT_CAP_SGI_40 |
|
|
@@ -223,7 +226,7 @@ static struct ieee80211_supported_band bes2600_band_5ghz = {
|
|
.n_bitrates = bes2600_a_rates_size,
|
|
.ht_cap = {
|
|
.cap = IEEE80211_HT_CAP_GRN_FLD |
|
|
- (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
|
|
+ (STBC_RX_5G << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
|
|
IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
|
|
IEEE80211_HT_CAP_SGI_20 |
|
|
IEEE80211_HT_CAP_SGI_40 |
|
|
@@ -320,23 +323,23 @@ static const struct wiphy_wowlan_support bes2600_wowlan_support = {
|
|
#endif
|
|
|
|
#ifdef CONFIG_BES2600_WAPI_SUPPORT
|
|
-static void bes2600_init_wapi_cipher(struct ieee80211_hw *hw)
|
|
-{
|
|
- static struct ieee80211_cipher_scheme wapi_cs = {
|
|
- .cipher = WLAN_CIPHER_SUITE_SMS4,
|
|
- .iftype = BIT(NL80211_IFTYPE_STATION),
|
|
- .hdr_len = 18,
|
|
- .pn_len = 16,
|
|
- .pn_off = 2,
|
|
- .key_idx_off = 0,
|
|
- .key_idx_mask = 0x01,
|
|
- .key_idx_shift = 0,
|
|
- .mic_len = 16
|
|
- };
|
|
-
|
|
- hw->cipher_schemes = &wapi_cs;
|
|
- hw->n_cipher_schemes = 1;
|
|
-}
|
|
+// static void bes2600_init_wapi_cipher(struct ieee80211_hw *hw)
|
|
+// {
|
|
+// static struct ieee80211_cipher_scheme wapi_cs = {
|
|
+// .cipher = WLAN_CIPHER_SUITE_SMS4,
|
|
+// .iftype = BIT(NL80211_IFTYPE_STATION),
|
|
+// .hdr_len = 18,
|
|
+// .pn_len = 16,
|
|
+// .pn_off = 2,
|
|
+// .key_idx_off = 0,
|
|
+// .key_idx_mask = 0x01,
|
|
+// .key_idx_shift = 0,
|
|
+// .mic_len = 16
|
|
+// };
|
|
+
|
|
+// hw->cipher_schemes = &wapi_cs;
|
|
+// hw->n_cipher_schemes = 1;
|
|
+// }
|
|
#endif
|
|
|
|
static void bes2600_get_base_mac(struct bes2600_common *hw_priv)
|
|
@@ -532,7 +535,7 @@ struct ieee80211_hw *bes2600_init_common(size_t hw_priv_data_len)
|
|
#ifdef CONFIG_BES2600_WAPI_SUPPORT
|
|
hw_priv->last_ins_wapi_usk_id = -1;
|
|
hw_priv->last_del_wapi_usk_id = -1;
|
|
- bes2600_init_wapi_cipher(hw);
|
|
+ // bes2600_init_wapi_cipher(hw);
|
|
#endif
|
|
|
|
SET_IEEE80211_PERM_ADDR(hw, hw_priv->addresses[0].addr);
|
|
@@ -609,6 +612,11 @@ struct ieee80211_hw *bes2600_init_common(size_t hw_priv_data_len)
|
|
|
|
bes2600_tx_loop_init(hw_priv);
|
|
|
|
+#ifdef CONFIG_PM
|
|
+ bes2600_suspend_status_set(hw_priv, false);
|
|
+ bes2600_pending_unjoin_reset(hw_priv);
|
|
+#endif
|
|
+
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
hw_priv->test_frame.data = NULL;
|
|
hw_priv->test_frame.len = 0;
|
|
@@ -659,7 +667,9 @@ int bes2600_register_common(struct ieee80211_hw *dev)
|
|
#endif /* CONFIG_BES2600_LEDS */
|
|
|
|
bes2600_debug_init_common(hw_priv);
|
|
-
|
|
+#ifdef CONFIG_PM
|
|
+ bes2600_register_pm_notifier(hw_priv);
|
|
+#endif /* CONFIG_PM */
|
|
bes2600_info(BES2600_DBG_INIT, "is registered as '%s'\n",
|
|
wiphy_name(dev->wiphy));
|
|
return 0;
|
|
@@ -697,7 +707,9 @@ void bes2600_unregister_common(struct ieee80211_hw *dev)
|
|
bes2600_unregister_bh(hw_priv);
|
|
|
|
bes2600_debug_release_common(hw_priv);
|
|
-
|
|
+#ifdef CONFIG_PM
|
|
+ bes2600_unregister_pm_notifier(hw_priv);
|
|
+#endif /* CONFIG_PM */
|
|
#ifdef CONFIG_BES2600_LEDS
|
|
bes2600_unregister_leds(hw_priv);
|
|
#endif /* CONFIG_BES2600_LEDS */
|
|
@@ -1014,7 +1026,7 @@ int access_file(char *path, char *buffer, int size, int isRead)
|
|
#ifdef CONFIG_BES2600_WLAN_BES
|
|
int bes2600_wifi_start(struct bes2600_common *hw_priv)
|
|
{
|
|
- int ret, if_id;
|
|
+ int ret = 0, if_id;
|
|
#ifndef CONFIG_BES2600_WLAN_USB
|
|
if(hw_priv->sbus_ops->gpio_wake) {
|
|
hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, GPIO_WAKE_FLAG_WIFI_ON);
|
|
diff --git a/drivers/staging/bes2600/pm.c b/drivers/staging/bes2600/pm.c
|
|
index fbd6a8867332..d3213339e11c 100644
|
|
--- a/drivers/staging/bes2600/pm.c
|
|
+++ b/drivers/staging/bes2600/pm.c
|
|
@@ -11,6 +11,7 @@
|
|
|
|
#include <linux/platform_device.h>
|
|
#include <linux/if_ether.h>
|
|
+#include <linux/suspend.h>
|
|
#include "bes2600.h"
|
|
#include "pm.h"
|
|
#include "sta.h"
|
|
@@ -30,9 +31,9 @@ struct bes2600_udp_port_filter {
|
|
|
|
struct bes2600_ether_type_filter {
|
|
struct wsm_ether_type_filter_hdr hdr;
|
|
- struct wsm_ether_type_filter ip;
|
|
struct wsm_ether_type_filter pae;
|
|
struct wsm_ether_type_filter wapi;
|
|
+ struct wsm_ether_type_filter append;
|
|
} __packed;
|
|
|
|
static struct bes2600_udp_port_filter bes2600_udp_port_filter_on = {
|
|
@@ -65,12 +66,10 @@ static struct wsm_udp_port_filter_hdr bes2600_udp_port_filter_off = {
|
|
#define ETH_P_WAPI 0x88B4
|
|
#endif
|
|
|
|
+#define ETH_P_UNKNOWN 0xFFFF
|
|
static struct bes2600_ether_type_filter bes2600_ether_type_filter_on = {
|
|
.hdr.nrFilters = 3,
|
|
- .ip = {
|
|
- .filterAction = WSM_FILTER_ACTION_FILTER_OUT,
|
|
- .etherType = __cpu_to_le16(ETH_P_IPV6),
|
|
- },
|
|
+ .hdr.extFlags = WSM_ETH_FILTER_EXT_DISABLE_IPV6_MATCH, // patch for disable lmac SUSPEND_MODE_IPV6_FIX
|
|
.pae = {
|
|
.filterAction = WSM_FILTER_ACTION_FILTER_IN,
|
|
.etherType = __cpu_to_le16(ETH_P_PAE),
|
|
@@ -79,6 +78,11 @@ static struct bes2600_ether_type_filter bes2600_ether_type_filter_on = {
|
|
.filterAction = WSM_FILTER_ACTION_FILTER_IN,
|
|
.etherType = __cpu_to_le16(ETH_P_WAPI),
|
|
},
|
|
+ // add for lmac ether filter strategy: If every filtermode is FilterIN, discard all the frame which is mismatched
|
|
+ .append = {
|
|
+ .filterAction = WSM_FILTER_ACTION_FILTER_OUT,
|
|
+ .etherType = __cpu_to_le16(ETH_P_UNKNOWN),
|
|
+ },
|
|
/* Please add other known ether types to be filtered out here and
|
|
* update nrFilters field in the header.
|
|
* Up to 4 filters are allowed. */
|
|
@@ -88,6 +92,25 @@ static struct wsm_ether_type_filter_hdr bes2600_ether_type_filter_off = {
|
|
.nrFilters = 0,
|
|
};
|
|
|
|
+#ifdef IPV6_FILTERING
|
|
+static struct wsm_ipv6_filter bes2600_ipv6_filter_on = {
|
|
+ .hdr.numfilter = 1,
|
|
+ .hdr.action_mode = WSM_FILTER_ACTION_FILTER_IN,
|
|
+ .ipv6filter[0] = {
|
|
+ .filter_mode = WSM_FILTER_ACTION_FILTER_IN,
|
|
+ .address_mode = WSM_IP_DATA_FRAME_ADDRMODE_DEST,
|
|
+ /* a random ipvd addr, in order to filter all ipv6 packet */
|
|
+ .ipv6 = {0x01, 0x28, 0x35, 0xde, 0xbf, 0x34, 0x9d, 0x8a,
|
|
+ 0x47, 0x62, 0x85, 0x69, 0x7e, 0x8c, 0x29, 0x38},
|
|
+ }
|
|
+};
|
|
+
|
|
+static struct wsm_ipv6_filter bes2600_ipv6_filter_off = {
|
|
+ .hdr.numfilter = 0,
|
|
+ .hdr.action_mode = WSM_FILTER_ACTION_IGNORE,
|
|
+};
|
|
+#endif
|
|
+
|
|
static int __bes2600_wow_suspend(struct bes2600_vif *priv,
|
|
struct cfg80211_wowlan *wowlan);
|
|
static int __bes2600_wow_resume(struct bes2600_vif *priv);
|
|
@@ -102,6 +125,88 @@ struct bes2600_suspend_state {
|
|
unsigned long link_id_gc;
|
|
};
|
|
|
|
+void bes2600_suspend_status_set(struct bes2600_common *hw_priv, bool status)
|
|
+{
|
|
+ hw_priv->suspend_in_progress = status;
|
|
+}
|
|
+
|
|
+bool bes2600_suspend_status_get(struct bes2600_common *hw_priv)
|
|
+{
|
|
+ return hw_priv->suspend_in_progress;
|
|
+}
|
|
+
|
|
+void bes2600_pending_unjoin_reset(struct bes2600_common *hw_priv)
|
|
+{
|
|
+ hw_priv->unjoin_if_id_slots = 0x00;
|
|
+}
|
|
+
|
|
+void bes2600_pending_unjoin_set(struct bes2600_common *hw_priv, int if_id)
|
|
+{
|
|
+ if(if_id > 1)
|
|
+ bes2600_err(BES2600_DBG_PM, "unexpected if_id: %d\n", if_id);
|
|
+ else
|
|
+ hw_priv->unjoin_if_id_slots |= (1 << if_id);
|
|
+}
|
|
+
|
|
+bool bes2600_pending_unjoin_get(struct bes2600_common *hw_priv, int if_id)
|
|
+{
|
|
+ if(if_id > 1) {
|
|
+ bes2600_err(BES2600_DBG_PM, "unexpected if_id: %d\n", if_id);
|
|
+ return false;
|
|
+ } else
|
|
+ return hw_priv->unjoin_if_id_slots & (1 << if_id);
|
|
+}
|
|
+
|
|
+static int bes2600_pm_notifier(struct notifier_block *notifier,
|
|
+ unsigned long pm_event,
|
|
+ void *unused)
|
|
+{
|
|
+ int if_id;
|
|
+ struct bes2600_vif *priv;
|
|
+ struct bes2600_common *hw_priv = container_of(notifier,
|
|
+ struct bes2600_common,
|
|
+ pm_notify);
|
|
+
|
|
+ switch (pm_event) {
|
|
+ case PM_HIBERNATION_PREPARE:
|
|
+ case PM_SUSPEND_PREPARE:
|
|
+ bes2600_suspend_status_set(hw_priv, true);
|
|
+ break;
|
|
+
|
|
+ case PM_POST_RESTORE:
|
|
+ case PM_POST_HIBERNATION:
|
|
+ case PM_POST_SUSPEND:
|
|
+ bes2600_suspend_status_set(hw_priv, false);
|
|
+ if(hw_priv->unjoin_if_id_slots) {
|
|
+ for(if_id = 0; if_id < 2; if_id++) {
|
|
+ if(bes2600_pending_unjoin_get(hw_priv, if_id)) {
|
|
+ priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, if_id);
|
|
+ ieee80211_connection_loss(priv->vif);
|
|
+ }
|
|
+ }
|
|
+ bes2600_pending_unjoin_reset(hw_priv);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case PM_RESTORE_PREPARE:
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+void bes2600_register_pm_notifier(struct bes2600_common *hw_priv)
|
|
+{
|
|
+ hw_priv->pm_notify.notifier_call = bes2600_pm_notifier;
|
|
+ register_pm_notifier(&hw_priv->pm_notify);
|
|
+}
|
|
+
|
|
+void bes2600_unregister_pm_notifier(struct bes2600_common *hw_priv)
|
|
+{
|
|
+ unregister_pm_notifier(&hw_priv->pm_notify);
|
|
+}
|
|
+
|
|
static long bes2600_suspend_work(struct delayed_work *work)
|
|
{
|
|
int ret = cancel_delayed_work(work);
|
|
@@ -143,13 +248,14 @@ int bes2600_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|
struct bes2600_vif *priv;
|
|
int i, ret = 0;
|
|
unsigned long begin, end, diff;
|
|
+ char *busy_event_buffer = NULL;
|
|
|
|
bes2600_info(BES2600_DBG_PM, "bes2600_wow_suspend enter\n");
|
|
|
|
WARN_ON(!atomic_read(&hw_priv->num_vifs));
|
|
|
|
/* reset wakeup reason to default */
|
|
- bes2600_chrdev_wifi_update_wakeup_reason(0);
|
|
+ bes2600_chrdev_wifi_update_wakeup_reason(0, 0);
|
|
|
|
#ifdef ROAM_OFFLOAD
|
|
bes2600_for_each_vif(hw_priv, priv, i) {
|
|
@@ -198,6 +304,18 @@ int bes2600_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|
if (wait_event_timeout(hw_priv->bes_power.dev_lp_wq,
|
|
bes2600_pwr_device_is_idle(hw_priv), HZ * 5) <= 0) {
|
|
bes2600_err(BES2600_DBG_PM, "wait device idle timeout\n");
|
|
+ busy_event_buffer = kmalloc(4096, GFP_KERNEL);
|
|
+
|
|
+ if(!busy_event_buffer)
|
|
+ goto revert2;
|
|
+
|
|
+ if(bes2600_pwr_busy_event_record(hw_priv, busy_event_buffer, 4096) == 0) {
|
|
+ bes2600_info(BES2600_DBG_PM, "%s\n", busy_event_buffer);
|
|
+ } else {
|
|
+ bes2600_err(BES2600_DBG_PM, "busy event show failed\n");
|
|
+ }
|
|
+
|
|
+ kfree(busy_event_buffer);
|
|
goto revert2;
|
|
}
|
|
}
|
|
@@ -287,10 +405,10 @@ static int __bes2600_wow_suspend(struct bes2600_vif *priv,
|
|
int ret;
|
|
|
|
#ifdef MCAST_FWDING
|
|
- struct wsm_forwarding_offload fwdoffload = {
|
|
- .fwenable = 0x1,
|
|
- .flags = 0x1,
|
|
- };
|
|
+ struct wsm_forwarding_offload fwdoffload = {
|
|
+ .fwenable = 0x1,
|
|
+ .flags = 0x1,
|
|
+ };
|
|
#endif
|
|
|
|
/* Do not suspend when join work is scheduled */
|
|
@@ -300,6 +418,11 @@ static int __bes2600_wow_suspend(struct bes2600_vif *priv,
|
|
bes2600_set_ehter_and_udp_filter(hw_priv, &bes2600_ether_type_filter_on.hdr,
|
|
&bes2600_udp_port_filter_on.hdr, priv->if_id);
|
|
|
|
+ /* Set ipv6 filer */
|
|
+#ifdef IPV6_FILTERING
|
|
+ wsm_set_ipv6_filter(hw_priv, &bes2600_ipv6_filter_on.hdr, priv->if_id);
|
|
+#endif
|
|
+
|
|
if (priv->join_status == BES2600_JOIN_STATUS_AP)
|
|
WARN_ON(wsm_set_keepalive_filter(priv, true));
|
|
|
|
@@ -307,7 +430,7 @@ static int __bes2600_wow_suspend(struct bes2600_vif *priv,
|
|
if (priv->multicast_filter.numOfAddresses) {
|
|
priv->multicast_filter.enable = __cpu_to_le32(2);
|
|
wsm_set_multicast_filter(hw_priv, &priv->multicast_filter, priv->if_id);
|
|
- }
|
|
+ }
|
|
|
|
#ifdef MCAST_FWDING
|
|
if (priv->join_status == BES2600_JOIN_STATUS_AP)
|
|
@@ -362,7 +485,7 @@ static int __bes2600_wow_suspend(struct bes2600_vif *priv,
|
|
if (priv->multicast_filter.numOfAddresses) {
|
|
priv->multicast_filter.enable = __cpu_to_le32(1);
|
|
wsm_set_multicast_filter(hw_priv, &priv->multicast_filter, priv->if_id);
|
|
- }
|
|
+ }
|
|
|
|
|
|
#ifdef MCAST_FWDING
|
|
@@ -422,10 +545,10 @@ static int __bes2600_wow_resume(struct bes2600_vif *priv)
|
|
struct bes2600_suspend_state *state;
|
|
|
|
#ifdef MCAST_FWDING
|
|
- struct wsm_forwarding_offload fwdoffload = {
|
|
- .fwenable = 0x1,
|
|
- .flags = 0x0,
|
|
- };
|
|
+ struct wsm_forwarding_offload fwdoffload = {
|
|
+ .fwenable = 0x1,
|
|
+ .flags = 0x0,
|
|
+ };
|
|
#endif
|
|
state = pm_state_vif->suspend_state;
|
|
pm_state_vif->suspend_state = NULL;
|
|
@@ -443,7 +566,7 @@ static int __bes2600_wow_resume(struct bes2600_vif *priv)
|
|
if (priv->multicast_filter.numOfAddresses) {
|
|
priv->multicast_filter.enable = __cpu_to_le32(1);
|
|
wsm_set_multicast_filter(hw_priv, &priv->multicast_filter, priv->if_id);
|
|
- }
|
|
+ }
|
|
|
|
#ifdef MCAST_FWDING
|
|
if (priv->join_status == BES2600_JOIN_STATUS_AP)
|
|
@@ -467,8 +590,14 @@ static int __bes2600_wow_resume(struct bes2600_vif *priv)
|
|
/* Remove ethernet frame type filter */
|
|
wsm_set_ether_type_filter(hw_priv, &bes2600_ether_type_filter_off,
|
|
priv->if_id);
|
|
+
|
|
+ /* Remove ipv6 filer */
|
|
+#ifdef IPV6_FILTERING
|
|
+ wsm_set_ipv6_filter(hw_priv, &bes2600_ipv6_filter_off.hdr, priv->if_id);
|
|
+#endif
|
|
+
|
|
/* Free memory */
|
|
kfree(state);
|
|
|
|
return 0;
|
|
-}
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/drivers/staging/bes2600/pm.h b/drivers/staging/bes2600/pm.h
|
|
index dbf887367877..0f6943ecd870 100644
|
|
--- a/drivers/staging/bes2600/pm.h
|
|
+++ b/drivers/staging/bes2600/pm.h
|
|
@@ -21,6 +21,13 @@ struct bes2600_pm_state_vif {
|
|
struct bes2600_suspend_state *suspend_state;
|
|
};
|
|
|
|
+void bes2600_suspend_status_set(struct bes2600_common *hw_priv, bool status);
|
|
+bool bes2600_suspend_status_get(struct bes2600_common *hw_priv);
|
|
+void bes2600_pending_unjoin_reset(struct bes2600_common *hw_priv);
|
|
+void bes2600_pending_unjoin_set(struct bes2600_common *hw_priv, int if_id);
|
|
+bool bes2600_pending_unjoin_get(struct bes2600_common *hw_priv, int if_id);
|
|
+void bes2600_register_pm_notifier(struct bes2600_common *hw_priv);
|
|
+void bes2600_unregister_pm_notifier(struct bes2600_common *hw_priv);
|
|
int bes2600_can_suspend(struct bes2600_common *priv);
|
|
int bes2600_wow_suspend(struct ieee80211_hw *hw,
|
|
struct cfg80211_wowlan *wowlan);
|
|
diff --git a/drivers/staging/bes2600/queue.c b/drivers/staging/bes2600/queue.c
|
|
index de8edb2a3433..868ad23e95a3 100644
|
|
--- a/drivers/staging/bes2600/queue.c
|
|
+++ b/drivers/staging/bes2600/queue.c
|
|
@@ -129,6 +129,34 @@ static void bes2600_queue_register_post_gc(struct list_head *gc_list,
|
|
list_add_tail(&gc_item->head, gc_list);
|
|
}
|
|
|
|
+static void bes2600_queue_pending_record(struct list_head *pending_record_list,
|
|
+ struct bes2600_queue_item *pending_item)
|
|
+{
|
|
+ struct bes2600_queue_item *record_item;
|
|
+
|
|
+ record_item = kmalloc(sizeof(struct bes2600_queue_item),GFP_ATOMIC);
|
|
+ BUG_ON(!record_item);
|
|
+ memcpy(record_item, pending_item, sizeof(struct bes2600_queue_item));
|
|
+ record_item->skb = skb_clone(pending_item->skb, GFP_ATOMIC);
|
|
+ list_add_tail(&record_item->head, pending_record_list);
|
|
+}
|
|
+
|
|
+static void bes2600_queue_vif_wake_subqueue(struct bes2600_queue_stats *stats,
|
|
+ struct bes2600_queue *queue, int vif)
|
|
+{
|
|
+ struct bes2600_vif *priv;
|
|
+ struct wireless_dev *wdev;
|
|
+
|
|
+ priv = __cw12xx_hwpriv_to_vifpriv(stats->hw_priv, vif);
|
|
+ if (priv && unlikely(queue->vif_overfull[vif])) {
|
|
+ wdev = ieee80211_vif_to_wdev(priv->vif);
|
|
+ if (wdev->netdev && !ieee80211_queue_stopped(stats->hw_priv->hw, queue->queue_id)) {
|
|
+ queue->vif_overfull[vif] = false;
|
|
+ netif_wake_subqueue(wdev->netdev, queue->queue_id);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
static void __bes2600_queue_gc(struct bes2600_queue *queue,
|
|
struct list_head *head,
|
|
bool unlock)
|
|
@@ -136,6 +164,9 @@ static void __bes2600_queue_gc(struct bes2600_queue *queue,
|
|
struct bes2600_queue_stats *stats = queue->stats;
|
|
struct bes2600_queue_item *item = NULL;
|
|
struct bes2600_vif *priv;
|
|
+ struct wireless_dev *wdev;
|
|
+ int throttle;
|
|
+ int vif_i;
|
|
int if_id;
|
|
bool wakeup_stats = false;
|
|
|
|
@@ -169,17 +200,28 @@ static void __bes2600_queue_gc(struct bes2600_queue *queue,
|
|
if (wakeup_stats)
|
|
wake_up(&stats->wait_link_id_empty);
|
|
|
|
- if (queue->overfull) {
|
|
- if (queue->num_queued <= ((stats->hw_priv->vif0_throttle +
|
|
- stats->hw_priv->vif1_throttle + 2)/2)) {
|
|
- queue->overfull = false;
|
|
- if (unlock)
|
|
- __bes2600_queue_unlock(queue);
|
|
- } else if (item) {
|
|
- unsigned long tmo = item->queue_timestamp + queue->ttl;
|
|
- mod_timer(&queue->gc, tmo);
|
|
- bes2600_pwr_set_busy_event_with_timeout_async(stats->hw_priv,
|
|
- BES_PWR_LOCK_ON_QUEUE_GC, jiffies_to_msecs(tmo - jiffies));
|
|
+ for (vif_i = 0; vif_i < CW12XX_MAX_VIFS; vif_i++) {
|
|
+ if (vif_i == 0)
|
|
+ throttle = stats->hw_priv->vif0_throttle - (num_present_cpus() - 1);
|
|
+ else if (vif_i == 1)
|
|
+ throttle = stats->hw_priv->vif1_throttle - (num_present_cpus() - 1);
|
|
+ else
|
|
+ throttle = 2;
|
|
+
|
|
+ priv = __cw12xx_hwpriv_to_vifpriv(stats->hw_priv, vif_i);
|
|
+
|
|
+ if (priv && queue->vif_overfull[vif_i]) {
|
|
+ wdev = ieee80211_vif_to_wdev(priv->vif);
|
|
+ if (wdev->netdev && queue->num_queued_vif[vif_i] < (throttle + 1)/2 && unlock &&
|
|
+ !ieee80211_queue_stopped(stats->hw_priv->hw, queue->queue_id)) {
|
|
+ queue->vif_overfull[vif_i] = false;
|
|
+ netif_wake_subqueue(wdev->netdev, queue->queue_id);
|
|
+ } else if (item) {
|
|
+ unsigned long tmo = item->queue_timestamp + queue->ttl;
|
|
+ mod_timer(&queue->gc, tmo);
|
|
+ bes2600_pwr_set_busy_event_with_timeout_async(stats->hw_priv,
|
|
+ BES_PWR_LOCK_ON_QUEUE_GC, jiffies_to_msecs(tmo - jiffies));
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -282,14 +324,24 @@ int bes2600_queue_init(struct bes2600_queue *queue,
|
|
/* TODO:COMBO: Flush only a particular interface specific parts */
|
|
int bes2600_queue_clear(struct bes2600_queue *queue, int if_id)
|
|
{
|
|
- int i, cnt, iter;
|
|
+ int i, cnt, iter, vif_i;
|
|
struct bes2600_queue_stats *stats = queue->stats;
|
|
LIST_HEAD(gc_list);
|
|
+ struct bes2600_queue_item *pending_item = NULL, *temp_pending_item = NULL;
|
|
|
|
cnt = 0;
|
|
spin_lock_bh(&queue->lock);
|
|
queue->generation++;
|
|
queue->generation &= 0xf;
|
|
+
|
|
+ spin_lock(&stats->hw_priv->tx_loop.pending_record_lock);
|
|
+ if (!list_empty(&queue->pending)) {
|
|
+ list_for_each_entry_safe(pending_item, temp_pending_item, &queue->pending, head) {
|
|
+ bes2600_queue_pending_record(&stats->hw_priv->tx_loop.pending_record_list, pending_item);
|
|
+ }
|
|
+ }
|
|
+ spin_unlock(&stats->hw_priv->tx_loop.pending_record_lock);
|
|
+
|
|
list_splice_tail_init(&queue->queue, &queue->pending);
|
|
while (!list_empty(&queue->pending)) {
|
|
struct bes2600_queue_item *item = list_first_entry(
|
|
@@ -334,9 +386,12 @@ int bes2600_queue_clear(struct bes2600_queue *queue, int if_id)
|
|
}
|
|
}
|
|
spin_unlock_bh(&stats->lock);
|
|
- if (unlikely(queue->overfull)) {
|
|
- queue->overfull = false;
|
|
- __bes2600_queue_unlock(queue);
|
|
+ if (CW12XX_ALL_IFS == if_id) {
|
|
+ for (vif_i = 0; vif_i < CW12XX_MAX_VIFS; vif_i++) {
|
|
+ bes2600_queue_vif_wake_subqueue(stats, queue, vif_i);
|
|
+ }
|
|
+ } else {
|
|
+ bes2600_queue_vif_wake_subqueue(stats, queue, if_id);
|
|
}
|
|
spin_unlock_bh(&queue->lock);
|
|
wake_up(&stats->wait_link_id_empty);
|
|
@@ -403,8 +458,15 @@ int bes2600_queue_put(struct bes2600_queue *queue,
|
|
{
|
|
int ret = 0;
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec64 tmval;
|
|
+#else
|
|
struct timeval tmval;
|
|
+#endif
|
|
#endif /*CONFIG_BES2600_TESTMODE*/
|
|
+ struct bes2600_vif *priv;
|
|
+ struct wireless_dev *wdev;
|
|
+ int throttle = 0;
|
|
|
|
LIST_HEAD(gc_list);
|
|
struct bes2600_queue_stats *stats = queue->stats;
|
|
@@ -436,8 +498,13 @@ int bes2600_queue_put(struct bes2600_queue *queue,
|
|
}
|
|
#endif
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ ktime_get_real_ts64(&tmval);
|
|
+ item->qdelay_timestamp = tmval.tv_nsec / 1000;
|
|
+#else
|
|
do_gettimeofday(&tmval);
|
|
item->qdelay_timestamp = tmval.tv_usec;
|
|
+#endif
|
|
#endif /*CONFIG_BES2600_TESTMODE*/
|
|
|
|
++queue->num_queued;
|
|
@@ -453,14 +520,24 @@ int bes2600_queue_put(struct bes2600_queue *queue,
|
|
* TX may happen in parallel sometimes.
|
|
* Leave extra queue slots so we don't overflow.
|
|
*/
|
|
- if (queue->overfull == false &&
|
|
- queue->num_queued >=
|
|
- ((stats->hw_priv->vif0_throttle +
|
|
- stats->hw_priv->vif1_throttle + 2)
|
|
- - (num_present_cpus() - 1))) {
|
|
- queue->overfull = true;
|
|
- __bes2600_queue_lock(queue);
|
|
- mod_timer(&queue->gc, jiffies);
|
|
+ if (txpriv->if_id == 0)
|
|
+ throttle = stats->hw_priv->vif0_throttle - (num_present_cpus() - 1);
|
|
+ else if (txpriv->if_id == 1)
|
|
+ throttle = stats->hw_priv->vif1_throttle - (num_present_cpus() - 1);
|
|
+ else if (txpriv->if_id == 2)
|
|
+ throttle = 2;
|
|
+ else
|
|
+ bes2600_warn(BES2600_DBG_TXRX, "%s: unexpected if_id = %d\n", __func__, txpriv->if_id);
|
|
+
|
|
+ priv = __cw12xx_hwpriv_to_vifpriv(stats->hw_priv, txpriv->if_id);
|
|
+
|
|
+ if (priv && queue->num_queued_vif[txpriv->if_id] >= throttle) {
|
|
+ wdev = ieee80211_vif_to_wdev(priv->vif);
|
|
+ if (wdev->netdev) {
|
|
+ queue->vif_overfull[txpriv->if_id] = true;
|
|
+ netif_stop_subqueue(wdev->netdev, queue->queue_id);
|
|
+ mod_timer(&queue->gc, jiffies);
|
|
+ }
|
|
}
|
|
} else {
|
|
ret = -ENOENT;
|
|
@@ -489,7 +566,11 @@ int bes2600_queue_get(struct bes2600_queue *queue,
|
|
struct bes2600_queue_stats *stats = queue->stats;
|
|
bool wakeup_stats = false;
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec64 tmval;
|
|
+#else
|
|
struct timeval tmval;
|
|
+#endif
|
|
#endif /*CONFIG_BES2600_TESTMODE*/
|
|
|
|
spin_lock_bh(&queue->lock);
|
|
@@ -513,8 +594,13 @@ int bes2600_queue_get(struct bes2600_queue *queue,
|
|
[item->txpriv.link_id];
|
|
item->xmit_timestamp = jiffies;
|
|
#ifdef CONFIG_BES2600_TESTMODE
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ ktime_get_real_ts64(&tmval);
|
|
+ item->mdelay_timestamp = tmval.tv_nsec / 1000;
|
|
+#else
|
|
do_gettimeofday(&tmval);
|
|
item->mdelay_timestamp = tmval.tv_usec;
|
|
+#endif
|
|
#endif /*CONFIG_BES2600_TESTMODE*/
|
|
|
|
spin_lock_bh(&stats->lock);
|
|
@@ -726,6 +812,9 @@ int bes2600_queue_remove(struct bes2600_queue *queue, u32 packetID)
|
|
struct bes2600_queue_stats *stats = queue->stats;
|
|
struct sk_buff *gc_skb = NULL;
|
|
struct bes2600_txpriv gc_txpriv;
|
|
+ struct bes2600_vif *priv;
|
|
+ struct wireless_dev *wdev;
|
|
+ int throttle = 0;
|
|
|
|
bes2600_queue_parse_id(packetID, &queue_generation, &queue_id,
|
|
&item_generation, &item_id, &if_id, &link_id);
|
|
@@ -758,9 +847,30 @@ int bes2600_queue_remove(struct bes2600_queue *queue, u32 packetID)
|
|
spin_lock_bh(&hw_priv->tsm_lock);
|
|
if (hw_priv->start_stop_tsm.start) {
|
|
if (queue_id == hw_priv->tsm_info.ac) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec64 tmval;
|
|
+#else
|
|
struct timeval tmval;
|
|
+#endif
|
|
unsigned long queue_delay;
|
|
unsigned long media_delay;
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ ktime_get_real_ts64(&tmval);
|
|
+
|
|
+ if (tmval.tv_nsec / 1000 > item->qdelay_timestamp)
|
|
+ queue_delay = tmval.tv_nsec / 1000 -
|
|
+ item->qdelay_timestamp;
|
|
+ else
|
|
+ queue_delay = tmval.tv_nsec / 1000 +
|
|
+ 1000000 - item->qdelay_timestamp;
|
|
+
|
|
+ if (tmval.tv_nsec / 1000 > item->mdelay_timestamp)
|
|
+ media_delay = tmval.tv_nsec / 1000 -
|
|
+ item->mdelay_timestamp;
|
|
+ else
|
|
+ media_delay = tmval.tv_nsec / 1000 +
|
|
+ 1000000 - item->mdelay_timestamp;
|
|
+#else
|
|
do_gettimeofday(&tmval);
|
|
|
|
if (tmval.tv_usec > item->qdelay_timestamp)
|
|
@@ -776,6 +886,7 @@ int bes2600_queue_remove(struct bes2600_queue *queue, u32 packetID)
|
|
else
|
|
media_delay = tmval.tv_usec +
|
|
1000000 - item->mdelay_timestamp;
|
|
+#endif
|
|
hw_priv->tsm_info.sum_media_delay +=
|
|
media_delay;
|
|
hw_priv->tsm_info.sum_pkt_q_delay += queue_delay;
|
|
@@ -796,10 +907,24 @@ int bes2600_queue_remove(struct bes2600_queue *queue, u32 packetID)
|
|
*/
|
|
list_move(&item->head, &queue->free_pool);
|
|
|
|
- if (unlikely(queue->overfull) &&
|
|
- (queue->num_queued <= ((stats->hw_priv->vif0_throttle + stats->hw_priv->vif1_throttle + 2) / 2))) {
|
|
- queue->overfull = false;
|
|
- __bes2600_queue_unlock(queue);
|
|
+ if (if_id == 0)
|
|
+ throttle = stats->hw_priv->vif0_throttle - (num_present_cpus() - 1);
|
|
+ else if (if_id == 1)
|
|
+ throttle = stats->hw_priv->vif1_throttle - (num_present_cpus() - 1);
|
|
+ else if (if_id == 2)
|
|
+ throttle = 2;
|
|
+ else
|
|
+ bes2600_warn(BES2600_DBG_TXRX, "%s: unexpected if_id = %d\n", __func__, if_id);
|
|
+
|
|
+ priv = __cw12xx_hwpriv_to_vifpriv(stats->hw_priv, if_id);
|
|
+
|
|
+ if (priv && unlikely(queue->vif_overfull[if_id]) &&
|
|
+ queue->num_queued_vif[if_id] < (throttle + 1)/2) {
|
|
+ wdev = ieee80211_vif_to_wdev(priv->vif);
|
|
+ if (wdev->netdev && !ieee80211_queue_stopped(stats->hw_priv->hw, queue->queue_id)) {
|
|
+ queue->vif_overfull[if_id] = false;
|
|
+ netif_wake_subqueue(wdev->netdev, queue->queue_id);
|
|
+ }
|
|
}
|
|
}
|
|
spin_unlock_bh(&queue->lock);
|
|
@@ -824,10 +949,25 @@ int bes2600_queue_get_skb(struct bes2600_queue *queue, u32 packetID,
|
|
int ret = 0;
|
|
u8 queue_generation, queue_id, item_generation, item_id, if_id, link_id;
|
|
struct bes2600_queue_item *item;
|
|
+ struct bes2600_queue_item *record_item = NULL, *temp_record_item = NULL;
|
|
|
|
bes2600_queue_parse_id(packetID, &queue_generation, &queue_id,
|
|
&item_generation, &item_id, &if_id, &link_id);
|
|
|
|
+ spin_lock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
|
|
+ if (!list_empty(&queue->stats->hw_priv->tx_loop.pending_record_list)) {
|
|
+ list_for_each_entry_safe(record_item, temp_record_item, &queue->stats->hw_priv->tx_loop.pending_record_list, head) {
|
|
+ if (record_item->packetID == packetID) {
|
|
+ list_del(&record_item->head);
|
|
+ dev_kfree_skb(record_item->skb);
|
|
+ kfree(record_item);
|
|
+ spin_unlock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ spin_unlock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
|
|
+
|
|
item = &queue->pool[item_id];
|
|
|
|
spin_lock_bh(&queue->lock);
|
|
@@ -835,6 +975,7 @@ int bes2600_queue_get_skb(struct bes2600_queue *queue, u32 packetID,
|
|
/* TODO:COMBO: Add check for interface ID here */
|
|
if (unlikely(queue_generation != queue->generation)) {
|
|
bes2600_info(BES2600_DBG_TXRX, "%s, Queue Generation is not equal\n", __func__);
|
|
+ WARN_ON(1);
|
|
ret = -EINVAL;
|
|
} else if (unlikely(item_id >= (unsigned) queue->capacity)) {
|
|
WARN_ON(1);
|
|
@@ -922,10 +1063,23 @@ void bes2600_queue_iterate_pending_packet(struct bes2600_queue *queue,
|
|
{
|
|
struct bes2600_queue_item *item = NULL;
|
|
|
|
- if(list_empty(&queue->pending))
|
|
+ if (list_empty(&queue->pending))
|
|
return;
|
|
|
|
list_for_each_entry(item, &queue->pending, head) {
|
|
iterate_cb(queue->stats->hw_priv, item->skb);
|
|
}
|
|
+}
|
|
+
|
|
+void bes2600_queue_iterate_record_pending_packet(struct bes2600_common *hw_priv,
|
|
+ void (*iterate_cb)(struct bes2600_common *hw_priv, struct sk_buff *skb))
|
|
+{
|
|
+ struct bes2600_queue_item *item = NULL;
|
|
+ if (list_empty(&hw_priv->tx_loop.pending_record_list)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ list_for_each_entry(item, &hw_priv->tx_loop.pending_record_list, head) {
|
|
+ iterate_cb(hw_priv, item->skb);
|
|
+ }
|
|
}
|
|
\ No newline at end of file
|
|
diff --git a/drivers/staging/bes2600/queue.h b/drivers/staging/bes2600/queue.h
|
|
index 803ceacff178..f0a40a404c47 100644
|
|
--- a/drivers/staging/bes2600/queue.h
|
|
+++ b/drivers/staging/bes2600/queue.h
|
|
@@ -41,7 +41,7 @@ struct bes2600_queue {
|
|
struct list_head pending;
|
|
int tx_locked_cnt;
|
|
int *link_map_cache[CW12XX_MAX_VIFS];
|
|
- bool overfull;
|
|
+ bool vif_overfull[CW12XX_MAX_VIFS];
|
|
spinlock_t lock;
|
|
u8 queue_id;
|
|
u8 generation;
|
|
@@ -169,5 +169,6 @@ int bes2600_sw_retry_requeue(struct bes2600_common *hw_priv,
|
|
struct bes2600_queue *queue, u32 packetID, bool check);
|
|
void bes2600_queue_iterate_pending_packet(struct bes2600_queue *queue,
|
|
void (*iterate_cb)(struct bes2600_common *hw_priv, struct sk_buff *skb));
|
|
-
|
|
+void bes2600_queue_iterate_record_pending_packet(struct bes2600_common *hw_priv,
|
|
+ void (*iterate_cb)(struct bes2600_common *hw_priv, struct sk_buff *skb));
|
|
#endif /* BES2600_QUEUE_H_INCLUDED */
|
|
diff --git a/drivers/staging/bes2600/scan.c b/drivers/staging/bes2600/scan.c
|
|
index e0e13b3e5a0f..84a5373dc147 100644
|
|
--- a/drivers/staging/bes2600/scan.c
|
|
+++ b/drivers/staging/bes2600/scan.c
|
|
@@ -87,8 +87,8 @@ static int bes2600_disable_filtering(struct bes2600_vif *priv)
|
|
priv->if_id);
|
|
|
|
/* Beacon Filter Disable */
|
|
- bf_control.enabled = 0;
|
|
- bf_control.bcn_count = 1;
|
|
+ bf_control.enabled = __cpu_to_le32(0);
|
|
+ bf_control.bcn_count = __cpu_to_le32(1);
|
|
if (!ret)
|
|
ret = wsm_beacon_filter_control(hw_priv, &bf_control,
|
|
priv->if_id);
|
|
@@ -651,8 +651,8 @@ void bes2600_scan_work(struct work_struct *work)
|
|
if (scan.band == NL80211_BAND_2GHZ) {
|
|
coex_calc_wifi_scan_time(&minChannelTime, &maxChannelTime);
|
|
} else {
|
|
- minChannelTime = 90;
|
|
- maxChannelTime = 90;
|
|
+ minChannelTime = 100;
|
|
+ maxChannelTime = 100;
|
|
}
|
|
#endif
|
|
|
|
@@ -1078,7 +1078,7 @@ void bes2600_probe_work(struct work_struct *work)
|
|
return;
|
|
}
|
|
|
|
- if (bes2600_queue_get_skb(queue, hw_priv->pending_frame_id,
|
|
+ if (bes2600_queue_get_skb(queue, hw_priv->pending_frame_id,
|
|
&frame.skb, &txpriv)) {
|
|
up(&hw_priv->scan.lock);
|
|
up(&hw_priv->conf_lock);
|
|
diff --git a/drivers/staging/bes2600/sta.c b/drivers/staging/bes2600/sta.c
|
|
index eed1c85fc67c..4fa7e4ad9999 100644
|
|
--- a/drivers/staging/bes2600/sta.c
|
|
+++ b/drivers/staging/bes2600/sta.c
|
|
@@ -38,7 +38,7 @@
|
|
#include "epta_request.h"
|
|
#include "epta_coex.h"
|
|
|
|
-#ifdef PLAT_ALLWINNER_R329
|
|
+#if defined(PLAT_ALLWINNER_R329) || defined(STANDARD_FACTORY_EFUSE_FLAG)
|
|
#include "bes2600_factory.h"
|
|
#endif
|
|
|
|
@@ -132,7 +132,7 @@ static inline void __bes2600_bf_configure(struct bes2600_vif *priv)
|
|
WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
|
|
WSM_BEACON_FILTER_IE_HAS_APPEARED;
|
|
|
|
- priv->bf_control.enabled = WSM_BEACON_FILTER_ENABLE;
|
|
+ priv->bf_control.enabled = __cpu_to_le32(WSM_BEACON_FILTER_ENABLE);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
@@ -236,8 +236,20 @@ void bes2600_stop(struct ieee80211_hw *dev)
|
|
spin_unlock(&hw_priv->event_queue_lock);
|
|
__bes2600_free_event_queue(&list);
|
|
|
|
- for (i = 0; i < 4; i++)
|
|
- bes2600_queue_clear(&hw_priv->tx_queue[i], CW12XX_ALL_IFS);
|
|
+ spin_lock(&hw_priv->vif_list_lock);
|
|
+ bes2600_for_each_vif(hw_priv, priv, i) {
|
|
+ if (!priv)
|
|
+ continue;
|
|
+ if (!(hw_priv->if_id_slot & BIT(priv->if_id)))
|
|
+ return;
|
|
+ /* protect tx confirm flow */
|
|
+ spin_lock(&priv->vif_lock);
|
|
+ for (i = 0; i < 4; i++)
|
|
+ bes2600_queue_clear(&hw_priv->tx_queue[i], i);
|
|
+ spin_unlock(&priv->vif_lock);
|
|
+ }
|
|
+ spin_unlock(&hw_priv->vif_list_lock);
|
|
+
|
|
|
|
/* HACK! */
|
|
if (atomic_xchg(&hw_priv->tx_lock, 1) != 1)
|
|
@@ -424,6 +436,9 @@ void bes2600_remove_interface(struct ieee80211_hw *dev,
|
|
bes2600_info(BES2600_DBG_STA, "AP REMOVE 11BG %d\n",hw_priv->vif0_throttle);
|
|
}
|
|
bes2600_pwr_clear_busy_event(hw_priv, BES2600_JOIN_STATUS_AP);
|
|
+#ifdef BES2600_TX_RX_OPT
|
|
+ bes2600_txrx_opt_timer_restore();
|
|
+#endif
|
|
break;
|
|
case BES2600_JOIN_STATUS_MONITOR:
|
|
bes2600_disable_listening(priv);
|
|
@@ -600,12 +615,12 @@ void bes2600_update_filtering(struct bes2600_vif *priv)
|
|
struct bes2600_common *hw_priv = cw12xx_vifpriv_to_hwpriv(priv);
|
|
bool bssid_filtering = !priv->rx_filter.bssid;
|
|
static struct wsm_beacon_filter_control bf_disabled = {
|
|
- .enabled = 0,
|
|
- .bcn_count = 1,
|
|
+ .enabled = __cpu_to_le32(0),
|
|
+ .bcn_count = __cpu_to_le32(1),
|
|
};
|
|
bool ap_mode = 0;
|
|
static struct wsm_beacon_filter_table bf_table_auto = {
|
|
- .numOfIEs = __cpu_to_le32(2),
|
|
+ .numOfIEs = __cpu_to_le32(1),
|
|
.entry[0].ieId = WLAN_EID_VENDOR_SPECIFIC,
|
|
.entry[0].actionFlags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
|
|
WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
|
|
@@ -613,18 +628,14 @@ void bes2600_update_filtering(struct bes2600_vif *priv)
|
|
.entry[0].oui[0] = 0x50,
|
|
.entry[0].oui[1] = 0x6F,
|
|
.entry[0].oui[2] = 0x9A,
|
|
-
|
|
- .entry[1].ieId = WLAN_EID_HT_OPERATION,
|
|
- .entry[1].actionFlags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
|
|
- WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
|
|
- WSM_BEACON_FILTER_IE_HAS_APPEARED,
|
|
};
|
|
static struct wsm_beacon_filter_control bf_auto = {
|
|
- .enabled = WSM_BEACON_FILTER_ENABLE |
|
|
- WSM_BEACON_FILTER_AUTO_ERP,
|
|
- .bcn_count = 1,
|
|
+ .enabled = __cpu_to_le32(WSM_BEACON_FILTER_ENABLE |
|
|
+ WSM_BEACON_FILTER_AUTO_ERP | WSM_BEACON_FILTER_AUTO_HT),
|
|
+ // .bcn_count = __cpu_to_le32(priv->bf_control.bcn_count);
|
|
};
|
|
- bf_auto.bcn_count = priv->bf_control.bcn_count;
|
|
+ // bf_table_auto.numOfIEs = 0; /* No filtering to do - so discarding */
|
|
+ bf_auto.bcn_count = __cpu_to_le32(priv->bf_control.bcn_count);
|
|
|
|
if (priv->join_status == BES2600_JOIN_STATUS_PASSIVE)
|
|
return;
|
|
@@ -783,8 +794,8 @@ void bes2600_configure_filter(struct ieee80211_hw *hw,
|
|
priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
|
|
FIF_PROBE_REQ)) ? 1 : 0;
|
|
priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
|
|
- priv->bf_control.bcn_count = (*total_flags &
|
|
- (FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ)) ? 1 : 0;
|
|
+ priv->bf_control.bcn_count = __cpu_to_le32((*total_flags &
|
|
+ (FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ)) ? 1 : 0);
|
|
#if 0
|
|
if (priv->listening ^ listening) {
|
|
priv->listening = listening;
|
|
@@ -800,7 +811,7 @@ void bes2600_configure_filter(struct ieee80211_hw *hw,
|
|
}
|
|
|
|
int bes2600_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
|
- u16 queue, const struct ieee80211_tx_queue_params *params)
|
|
+ unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params)
|
|
{
|
|
struct bes2600_common *hw_priv = dev->priv;
|
|
struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
|
|
@@ -829,9 +840,9 @@ int bes2600_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
|
goto out;
|
|
}
|
|
|
|
- WSM_EDCA_SET(&priv->edca, queue, params->aifs,
|
|
- params->cw_min, params->cw_max, params->txop, 0xc8,
|
|
- params->uapsd);
|
|
+ WSM_EDCA_SET(&priv->edca, queue, params->aifs,
|
|
+ params->cw_min, params->cw_max, params->txop, 0xc8,
|
|
+ params->uapsd);
|
|
ret = wsm_set_edca_params(hw_priv, &priv->edca, priv->if_id);
|
|
if (ret) {
|
|
ret = -EINVAL;
|
|
@@ -1183,9 +1194,12 @@ int __bes2600_flush(struct bes2600_common *hw_priv, bool drop, int if_id)
|
|
* Temporary workaround: 2s
|
|
*/
|
|
if (drop) {
|
|
+ /* protect tx confirm flow */
|
|
+ spin_lock(&priv->vif_lock);
|
|
for (i = 0; i < 4; ++i)
|
|
bes2600_queue_clear(&hw_priv->tx_queue[i],
|
|
if_id);
|
|
+ spin_unlock(&priv->vif_lock);
|
|
} else {
|
|
ret = wait_event_timeout(
|
|
hw_priv->tx_queue_stats.wait_link_id_empty,
|
|
@@ -1224,6 +1238,7 @@ void bes2600_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
struct bes2600_vif *priv = NULL;
|
|
struct bes2600_common *hw_priv = hw->priv;
|
|
unsigned int ret = 0;
|
|
+ int hw_bufs_used = 0;
|
|
int i;
|
|
|
|
/* get queue status */
|
|
@@ -1231,6 +1246,7 @@ void bes2600_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
priv = cw12xx_get_vif_from_ieee80211(vif);
|
|
ret |= !bes2600_queue_stats_is_empty(
|
|
&hw_priv->tx_queue_stats, -1, priv->if_id);
|
|
+ hw_bufs_used = hw_priv->hw_bufs_used_vif[priv->if_id];
|
|
} else {
|
|
bes2600_for_each_vif(hw_priv, priv, i) {
|
|
if (!priv)
|
|
@@ -1239,11 +1255,12 @@ void bes2600_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
return;
|
|
ret |= !bes2600_queue_stats_is_empty(
|
|
&hw_priv->tx_queue_stats, -1, priv->if_id);
|
|
+ hw_bufs_used = hw_priv->hw_bufs_used;
|
|
}
|
|
}
|
|
|
|
/* no need to do the next work if queue was already clear */
|
|
- if(ret == 0) {
|
|
+ if((ret == 0) && (hw_bufs_used == 0)) {
|
|
bes2600_info(BES2600_DBG_STA, "no need to flush\n");
|
|
return;
|
|
}
|
|
@@ -1385,6 +1402,10 @@ void bes2600_event_handler(struct work_struct *work)
|
|
break;
|
|
case WSM_EVENT_BSS_LOST:
|
|
{
|
|
+ if (bes2600_chrdev_wakeup_by_event_get() == WAKEUP_EVENT_WSME) {
|
|
+ bes2600_chrdev_wifi_update_wakeup_reason(WAKEUP_REASON_WIFI_BSSLOST, 0);
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
+ }
|
|
spin_lock(&priv->bss_loss_lock);
|
|
if (priv->bss_loss_status > BES2600_BSS_LOSS_NONE) {
|
|
spin_unlock(&priv->bss_loss_lock);
|
|
@@ -1498,11 +1519,22 @@ void bes2600_event_handler(struct work_struct *work)
|
|
break;
|
|
}
|
|
case WSM_EVENT_WAKEUP_EVENT:
|
|
- bes2600_info(BES2600_DBG_STA, "wifi wakeup, Reason:%u\n", event->evt.eventData);
|
|
- bes2600_chrdev_wifi_update_wakeup_reason(event->evt.eventData);
|
|
+ {
|
|
+ if (bes2600_chrdev_wakeup_by_event_get() == WAKEUP_EVENT_WSME) {
|
|
+ u16 src_port, reason;
|
|
+ reason = event->evt.eventData & 0xFFFF;
|
|
+ src_port = event->evt.eventData >> 16;
|
|
+ src_port = __be16_to_cpu(src_port);
|
|
+ bes2600_info(BES2600_DBG_STA, "wifi wakeup, reason: %u, src_port: %u\n", reason, src_port);
|
|
+ bes2600_chrdev_wifi_update_wakeup_reason(reason, src_port);
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
+ }
|
|
+ }
|
|
+
|
|
break;
|
|
}
|
|
}
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
up(&hw_priv->conf_lock);
|
|
__bes2600_free_event_queue(&list);
|
|
}
|
|
@@ -1529,7 +1561,7 @@ void bes2600_bss_loss_work(struct work_struct *work)
|
|
|
|
spin_lock(&priv->bss_loss_lock);
|
|
#ifdef BSS_LOSS_CHECK
|
|
- if (!priv->vif->bss_conf.assoc) {
|
|
+ if (!priv->vif->cfg.assoc) {
|
|
priv->bss_loss_status = BES2600_BSS_LOSS_NONE;
|
|
spin_unlock(&priv->bss_loss_lock);
|
|
bl_ck_cnt = 0;
|
|
@@ -1545,7 +1577,8 @@ void bes2600_bss_loss_work(struct work_struct *work)
|
|
bl_ck_cnt = 0;
|
|
bl_cfm_cnt = 0;
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))
|
|
- skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ // skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, false);
|
|
#else
|
|
skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
|
#endif
|
|
@@ -1575,7 +1608,8 @@ void bes2600_bss_loss_work(struct work_struct *work)
|
|
spin_unlock(&priv->bss_loss_lock);
|
|
priv->bss_loss_status = BES2600_BSS_LOSS_CHECKING;
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))
|
|
- skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ // skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, false);
|
|
#else
|
|
skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
|
#endif
|
|
@@ -1611,7 +1645,8 @@ void bes2600_bss_loss_work(struct work_struct *work)
|
|
spin_unlock(&priv->bss_loss_lock);
|
|
priv->bss_loss_status = BES2600_BSS_LOSS_CHECKING;
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))
|
|
- skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ // skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
|
+ skb = ieee80211_nullfunc_get(priv->hw, priv->vif, -1, false);
|
|
#else
|
|
skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
|
#endif
|
|
@@ -1661,9 +1696,14 @@ void bes2600_connection_loss_work(struct work_struct *work)
|
|
struct bes2600_vif *priv =
|
|
container_of(work, struct bes2600_vif,
|
|
connection_loss_work.work);
|
|
+ struct bes2600_common *hw_priv = cw12xx_vifpriv_to_hwpriv(priv);
|
|
+
|
|
bes2600_info(BES2600_DBG_STA, "[CQM] Reporting connection loss.\n");
|
|
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_BSS_LOST);
|
|
- ieee80211_connection_loss(priv->vif);
|
|
+ if(bes2600_suspend_status_get(hw_priv)) {
|
|
+ bes2600_pending_unjoin_set(hw_priv, priv->if_id);
|
|
+ } else
|
|
+ ieee80211_connection_loss(priv->vif);
|
|
#ifdef WIFI_BT_COEXIST_EPTA_ENABLE
|
|
// set disconnected in BSS_CHANGED_ASSOC
|
|
// bwifi_change_current_status(hw_priv, BWIFI_STATUS_DISCONNECTED);
|
|
@@ -2295,6 +2335,7 @@ void bes2600_join_work(struct work_struct *work)
|
|
#else
|
|
wsm_set_template_frame(hw_priv, &probe_tmp, priv->if_id);
|
|
#endif
|
|
+ dev_kfree_skb(probe_tmp.skb);
|
|
}
|
|
|
|
if (wsm_join(hw_priv, &join, priv->if_id)) {
|
|
@@ -2390,7 +2431,7 @@ void bes2600_unjoin_work(struct work_struct *work)
|
|
cancel_work_sync(&priv->set_beacon_wakeup_period_work);
|
|
memset(&priv->join_bssid[0], 0, sizeof(priv->join_bssid));
|
|
#ifdef BES2600_TX_RX_OPT
|
|
- txrx_opt_timer_exit(hw_priv);
|
|
+ txrx_opt_timer_exit(priv);
|
|
#endif
|
|
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_PS_ACTIVE);
|
|
bes2600_pwr_clear_ap_lp_bad_mark(hw_priv);
|
|
@@ -2838,11 +2879,15 @@ void bes2600_rem_chan_timeout(struct work_struct *work)
|
|
|
|
void bes2600_dynamic_opt_txrx_work(struct work_struct *work)
|
|
{
|
|
+ bool multivif_connected = false;
|
|
struct bes2600_common *hw_priv =
|
|
container_of(work, struct bes2600_common, dynamic_opt_txrx_work);
|
|
- struct bes2600_vif *priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, 0);
|
|
- bes2600_dynamic_opt_rxtx(hw_priv,priv, 0);
|
|
- bes2600_dbg(BES2600_DBG_STA, "bes2600_dynamic_opt_txrx_work called\n");
|
|
+ struct bes2600_vif *priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, 1);
|
|
+
|
|
+ if (priv != NULL && priv->join_status > BES2600_JOIN_STATUS_MONITOR) {
|
|
+ multivif_connected = true;
|
|
+ }
|
|
+ bes2600_txrx_opt_multivif_connected_handler(hw_priv, multivif_connected);
|
|
}
|
|
|
|
|
|
@@ -2980,7 +3025,7 @@ static int bes2600_set_ipv6addrfilter(struct ieee80211_hw *hw,
|
|
ipv6_info = (struct ipv6_addr_info *)&data[2];
|
|
|
|
/* Computing sizeof Mac addr filter */
|
|
- ipaddrfiltersize = sizeof(*ipv6_filter) + \
|
|
+ ipaddrfiltersize = sizeof(struct wsm_ipv6_filter_header) + \
|
|
(no_of_ip_addr * sizeof(struct wsm_ip6_addr_info));
|
|
|
|
|
|
@@ -2989,8 +3034,8 @@ static int bes2600_set_ipv6addrfilter(struct ieee80211_hw *hw,
|
|
ret = -ENOMEM;
|
|
goto exit_p;
|
|
}
|
|
- ipv6_filter->action_mode = action_mode;
|
|
- ipv6_filter->numfilter = no_of_ip_addr;
|
|
+ ipv6_filter->hdr.action_mode = action_mode;
|
|
+ ipv6_filter->hdr.numfilter = no_of_ip_addr;
|
|
|
|
for (i = 0; i < no_of_ip_addr; i++) {
|
|
ipv6_filter->ipv6filter[i].address_mode = \
|
|
@@ -3025,8 +3070,10 @@ void bes2600_set_data_filter(struct ieee80211_hw *hw,
|
|
void *data, int len)
|
|
{
|
|
int ret = 0;
|
|
- //struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
|
|
int filter_id;
|
|
+#ifdef IPV6_FILTERING
|
|
+ struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
|
|
+#endif /*IPV6_FILTERING*/
|
|
|
|
if (!data) {
|
|
ret = -EINVAL;
|
|
@@ -4344,8 +4391,8 @@ static int net_device_en_ip_offload(struct ieee80211_hw *hw, struct ieee80211_vi
|
|
}
|
|
#endif /* CONFIG_BES2600_KEEP_ALIVE */
|
|
|
|
-#ifdef PLAT_ALLWINNER_R329
|
|
-static int bes2600_factory_cali_to_flash(struct ieee80211_hw *hw)
|
|
+#if defined(PLAT_ALLWINNER_R329) || defined(STANDARD_FACTORY_EFUSE_FLAG)
|
|
+static int bes2600_factory_cali_to_mcu(struct ieee80211_hw *hw, enum bes2600_rf_cmd_type cmd_type)
|
|
{
|
|
struct bes2600_common *hw_priv = hw->priv;
|
|
u8 *factory_data = NULL;
|
|
@@ -4367,8 +4414,8 @@ static int bes2600_factory_cali_to_flash(struct ieee80211_hw *hw)
|
|
} else {
|
|
bes2600_factory_data_check(factory_data);
|
|
factory_little_endian_cvrt(factory_data);
|
|
- ret = wsm_save_factory_txt_to_flash(hw_priv, factory_data, 0);
|
|
- bes2600_err_with_cond(ret, BES2600_DBG_DOWNLOAD, "save factory data to flash failed.\n");
|
|
+ ret = wsm_save_factory_txt_to_mcu(hw_priv, factory_data, 0, cmd_type);
|
|
+ bes2600_err_with_cond(ret, BES2600_DBG_DOWNLOAD, "save factory data to mcu failed.\n");
|
|
}
|
|
bes2600_factory_free_file_buffer(file_buffer);
|
|
bes2600_factory_unlock();
|
|
@@ -4377,7 +4424,16 @@ static int bes2600_factory_cali_to_flash(struct ieee80211_hw *hw)
|
|
return bes2600_testmode_reply(hw->wiphy, &ret, sizeof(int));
|
|
|
|
return ret;
|
|
+}
|
|
+#endif
|
|
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+static int bes2600_set_select_efuse_flag_to_txt(struct ieee80211_hw *hw,
|
|
+ void *data, int len)
|
|
+{
|
|
+ struct bes_select_calib_t *test_p = (struct bes_select_calib_t *)data;
|
|
+ int ret = bes2600_select_efuse_flag_write(test_p->select_efuse_flag);
|
|
+ return bes2600_testmode_reply(hw->wiphy, &ret, sizeof(int));
|
|
}
|
|
#endif
|
|
|
|
@@ -4490,9 +4546,23 @@ int bes2600_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, voi
|
|
break;
|
|
case BES_MSG_SAVE_CALI_TXT_TO_FLASH:
|
|
#ifdef PLAT_ALLWINNER_R329
|
|
- ret = bes2600_factory_cali_to_flash(hw);
|
|
+ ret = bes2600_factory_cali_to_mcu(hw, BES2600_RF_CMD_CALI_TXT_TO_FLASH);
|
|
+#else
|
|
+ ret = -EPERM;
|
|
+#endif
|
|
+ break;
|
|
+ case BES_MSG_SAVE_CALI_TXT_TO_EFUSE:
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ ret = bes2600_factory_cali_to_mcu(hw, BES2600_RF_CMD_CALI_TXT_TO_EFUSE);
|
|
#else
|
|
ret = -EPERM;
|
|
+#endif
|
|
+ break;
|
|
+ case BES_MSG_SET_SELECT_EFUSE_FLAG:
|
|
+#ifdef STANDARD_FACTORY_EFUSE_FLAG
|
|
+ ret = bes2600_set_select_efuse_flag_to_txt(hw, nla_data(data_p), nla_len(data_p));
|
|
+#else
|
|
+ ret = EPERM;
|
|
#endif
|
|
break;
|
|
case BES_MSG_VENDOR_RF_CMD:
|
|
diff --git a/drivers/staging/bes2600/sta.h b/drivers/staging/bes2600/sta.h
|
|
index f97e8fc1bb21..229d1305f38f 100644
|
|
--- a/drivers/staging/bes2600/sta.h
|
|
+++ b/drivers/staging/bes2600/sta.h
|
|
@@ -36,7 +36,7 @@ void bes2600_configure_filter(struct ieee80211_hw *dev,
|
|
unsigned int *total_flags,
|
|
u64 multicast);
|
|
int bes2600_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
|
|
- u16 queue, const struct ieee80211_tx_queue_params *params);
|
|
+ unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params);
|
|
int bes2600_get_stats(struct ieee80211_hw *dev,
|
|
struct ieee80211_low_level_stats *stats);
|
|
/* Not more a part of interface?
|
|
diff --git a/drivers/staging/bes2600/tx_loop.c b/drivers/staging/bes2600/tx_loop.c
|
|
index dbd5c37c6b9d..69eef9f4c14f 100644
|
|
--- a/drivers/staging/bes2600/tx_loop.c
|
|
+++ b/drivers/staging/bes2600/tx_loop.c
|
|
@@ -27,6 +27,8 @@ void bes2600_tx_loop_init(struct bes2600_common *hw_priv)
|
|
hw_priv->tx_loop.enabled = false;
|
|
hw_priv->tx_loop.start_lmac_seq = 0;
|
|
hw_priv->tx_loop.start_mcu_seq = 0;
|
|
+ INIT_LIST_HEAD(&hw_priv->tx_loop.pending_record_list);
|
|
+ spin_lock_init(&hw_priv->tx_loop.pending_record_lock);
|
|
spin_lock_init(&hw_priv->tx_loop.tx_loop_lock);
|
|
skb_queue_head_init(&hw_priv->tx_loop.rx_queue);
|
|
}
|
|
@@ -108,6 +110,9 @@ void bes2600_tx_loop_set_enable(struct bes2600_common *hw_priv)
|
|
bes2600_queue_iterate_pending_packet(&hw_priv->tx_queue[i],
|
|
bes2600_tx_loop_item_pending_item);
|
|
}
|
|
+ spin_lock(&hw_priv->tx_loop.pending_record_lock);
|
|
+ bes2600_queue_iterate_record_pending_packet(hw_priv, bes2600_tx_loop_item_pending_item);
|
|
+ spin_unlock(&hw_priv->tx_loop.pending_record_lock);
|
|
|
|
if (atomic_read(&hw_priv->bh_rx) > 0)
|
|
wake_up(&hw_priv->bh_wq);
|
|
diff --git a/drivers/staging/bes2600/tx_loop.h b/drivers/staging/bes2600/tx_loop.h
|
|
index 7294025d8eca..f7325c9fae0f 100644
|
|
--- a/drivers/staging/bes2600/tx_loop.h
|
|
+++ b/drivers/staging/bes2600/tx_loop.h
|
|
@@ -21,6 +21,8 @@ struct bes2600_tx_loop
|
|
u8 start_mcu_seq;
|
|
struct sk_buff_head rx_queue;
|
|
u8 *wsm_cmd_ptr;
|
|
+ struct list_head pending_record_list;
|
|
+ spinlock_t pending_record_lock;
|
|
};
|
|
|
|
void bes2600_tx_loop_init(struct bes2600_common *hw_priv);
|
|
diff --git a/drivers/staging/bes2600/txrx.c b/drivers/staging/bes2600/txrx.c
|
|
index d9202bce7116..ce700bdcaf72 100644
|
|
--- a/drivers/staging/bes2600/txrx.c
|
|
+++ b/drivers/staging/bes2600/txrx.c
|
|
@@ -10,6 +10,7 @@
|
|
*/
|
|
|
|
#include <net/mac80211.h>
|
|
+#include <net/sock.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/skbuff.h>
|
|
|
|
@@ -90,28 +91,23 @@ static void tx_policy_build(const struct bes2600_common *hw_priv,
|
|
BUG_ON(rates[0].idx < 0);
|
|
memset(policy, 0, sizeof(*policy));
|
|
|
|
- /* minstrel is buggy a little bit, so distille
|
|
- * incoming rates first. */
|
|
- /* Sort rates in descending order. */
|
|
+ /*
|
|
+ * Calculate the count of rate list.
|
|
+ * Don't change the order of rate list, it will cause tp debounce at medium attenuation
|
|
+ * For some test, you may want to rate stable, you can use fix rate.
|
|
+ * The way of setting fix rate is writting /sys/kernel/debug/ieee80211/phy0/rc/fixed_rate_idx
|
|
+ * Note: if you want to use the function of fix rate, you need to make sure CONFIG_MAC80211_DEBUGFS is y
|
|
+ */
|
|
+
|
|
for (i = 0; i < count; i++) {
|
|
if (rates[i].idx < 0) {
|
|
count = i;
|
|
break;
|
|
}
|
|
- for (j= 0; j < count; j++) {
|
|
- if (rates[j].idx < 0) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (rates[j].idx < rates[j + 1].idx) {
|
|
- struct ieee80211_tx_rate tmp = rates[j];
|
|
- rates[j] = rates[j + 1];
|
|
- rates[j + 1] = tmp;
|
|
- }
|
|
- }
|
|
}
|
|
+
|
|
/* enhance throughput, more tx retry rate */
|
|
-#ifdef BES2600_TX_RX_OPT
|
|
+#if defined(BES2600_TX_RX_OPT) && defined(BES2600_TX_MORE_RETRY)
|
|
if (rates[0].flags & IEEE80211_TX_RC_MCS) {
|
|
static int min_rate_index = 1; //min rate index is mcs1
|
|
static u8 last_rate_tx_cnt = 7;
|
|
@@ -1073,7 +1069,7 @@ void bes2600_tx(struct ieee80211_hw *dev,
|
|
int ret;
|
|
struct bes2600_vif *priv;
|
|
struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
|
|
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
|
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
|
|
|
if (!skb->data)
|
|
BUG_ON(1);
|
|
@@ -1320,13 +1316,23 @@ void bes2600_tx_confirm_cb(struct bes2600_common *hw_priv,
|
|
} else if ((hw_priv->start_stop_tsm.start) &&
|
|
(arg->status == WSM_STATUS_SUCCESS)) {
|
|
if (queue_id == hw_priv->tsm_info.ac) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec64 tmval;
|
|
+ ktime_get_real_ts64(&tmval);
|
|
+#else
|
|
struct timeval tmval;
|
|
do_gettimeofday(&tmval);
|
|
+#endif
|
|
pkt_delay = hw_priv->start_stop_tsm.packetization_delay;
|
|
if (hw_priv->tsm_info.sta_roamed &&
|
|
!hw_priv->tsm_info.use_rx_roaming) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ hw_priv->tsm_info.roam_delay = tmval.tv_nsec / 1000 -
|
|
+ hw_priv->tsm_info.txconf_timestamp_vo;
|
|
+#else
|
|
hw_priv->tsm_info.roam_delay = tmval.tv_usec -
|
|
hw_priv->tsm_info.txconf_timestamp_vo;
|
|
+#endif
|
|
if (hw_priv->tsm_info.roam_delay > pkt_delay)
|
|
hw_priv->tsm_info.roam_delay -= pkt_delay;
|
|
bes2600_info(BES2600_DBG_TEST_MODE, "[TX] txConf"
|
|
@@ -1334,7 +1340,11 @@ void bes2600_tx_confirm_cb(struct bes2600_common *hw_priv,
|
|
hw_priv->tsm_info.roam_delay);
|
|
hw_priv->tsm_info.sta_roamed = 0;
|
|
}
|
|
- hw_priv->tsm_info.txconf_timestamp_vo = tmval.tv_usec;
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ hw_priv->tsm_info.rx_timestamp_vo = tmval.tv_nsec / 1000;
|
|
+#else
|
|
+ hw_priv->tsm_info.rx_timestamp_vo = tmval.tv_usec;
|
|
+#endif
|
|
}
|
|
}
|
|
spin_unlock_bh(&hw_priv->tsm_lock);
|
|
@@ -1422,7 +1432,6 @@ void bes2600_tx_confirm_cb(struct bes2600_common *hw_priv,
|
|
if (tx_count)
|
|
++tx_count;
|
|
}
|
|
- spin_unlock(&priv->vif_lock);
|
|
|
|
for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
|
|
if (tx->status.rates[i].count >= tx_count) {
|
|
@@ -1440,6 +1449,7 @@ void bes2600_tx_confirm_cb(struct bes2600_common *hw_priv,
|
|
}
|
|
#ifdef KEY_FRAME_SW_RETRY
|
|
if (bes2600_bh_sw_process(hw_priv, arg) == 0) {
|
|
+ spin_unlock(&priv->vif_lock);
|
|
return;
|
|
}
|
|
#endif
|
|
@@ -1449,6 +1459,7 @@ void bes2600_tx_confirm_cb(struct bes2600_common *hw_priv,
|
|
#else
|
|
bes2600_queue_remove(queue, arg->packetID);
|
|
#endif /*CONFIG_BES2600_TESTMODE*/
|
|
+ spin_unlock(&priv->vif_lock);
|
|
}else {
|
|
spin_unlock(&priv->vif_lock);
|
|
return;
|
|
@@ -1499,8 +1510,11 @@ void bes2600_skb_dtor(struct bes2600_common *hw_priv,
|
|
tx_policy_put(hw_priv, txpriv->rate_id);
|
|
}
|
|
if (likely(!bes2600_is_itp(hw_priv))) {
|
|
+ if (priv) {
|
|
+ /* The interface may be already removed */
|
|
+ bes2600_tx_status(priv, skb);
|
|
+ }
|
|
ieee80211_tx_status(hw_priv->hw, skb);
|
|
- bes2600_tx_status(priv, skb);
|
|
}
|
|
|
|
}
|
|
@@ -1600,18 +1614,30 @@ void bes2600_rx_cb(struct bes2600_vif *priv,
|
|
struct bes2600_link_entry *entry = NULL;
|
|
bool early_data = false;
|
|
size_t hdrlen = 0;
|
|
+ u64 tsf;
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
|
+ do {
|
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec ts;
|
|
+ ts = ktime_to_timespec(ktime_get_boottime());
|
|
+ tsf = (u64)ts.tv_sec * 1000000000 + ts.tv_nsec;
|
|
+#else
|
|
+ struct timespec64 ts;
|
|
+ ts = ktime_to_timespec64(ktime_get_boottime());
|
|
+ tsf = (u64)ts.tv_sec * 1000000000 + ts.tv_nsec;
|
|
+#endif
|
|
+ hdr->boottime_ns = tsf;
|
|
+ } while (0);
|
|
+#endif
|
|
|
|
hdr->flag = 0;
|
|
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
|
|
- hdr->boottime_ns = ktime_get_boot_ns();
|
|
-#endif
|
|
if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED)) {
|
|
/* STA is stopped. */
|
|
goto drop;
|
|
}
|
|
|
|
/* wakeup device based on frame type */
|
|
- if (!is_multicast_ether_addr(ieee80211_get_DA(frame))) {
|
|
+ if (!is_multicast_ether_addr(ieee80211_get_DA(frame)) && ieee80211_is_data(frame->frame_control)) {
|
|
/* for unicast, wakeup device directly */
|
|
bes2600_pwr_set_busy_event_with_timeout_async(
|
|
hw_priv, BES_PWR_LOCK_ON_RX, BES_PWR_EVENT_RX_TIMEOUT);
|
|
@@ -1628,17 +1654,31 @@ void bes2600_rx_cb(struct bes2600_vif *priv,
|
|
if (hw_priv->start_stop_tsm.start) {
|
|
unsigned queue_id = skb_get_queue_mapping(skb);
|
|
if (queue_id == 0) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ struct timespec64 tmval;
|
|
+ ktime_get_real_ts64(&tmval);
|
|
+#else
|
|
struct timeval tmval;
|
|
do_gettimeofday(&tmval);
|
|
+#endif
|
|
if (hw_priv->tsm_info.sta_roamed &&
|
|
- hw_priv->tsm_info.use_rx_roaming) {
|
|
+ hw_priv->tsm_info.use_rx_roaming) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ hw_priv->tsm_info.roam_delay = tmval.tv_nsec / 1000 -
|
|
+ hw_priv->tsm_info.rx_timestamp_vo;
|
|
+#else
|
|
hw_priv->tsm_info.roam_delay = tmval.tv_usec -
|
|
hw_priv->tsm_info.rx_timestamp_vo;
|
|
+#endif
|
|
bes2600_dbg(BES2600_DBG_TEST_MODE, "[RX] RxInd Roaming:"
|
|
"roam_delay = %u\n", hw_priv->tsm_info.roam_delay);
|
|
hw_priv->tsm_info.sta_roamed = 0;
|
|
}
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
|
+ hw_priv->tsm_info.rx_timestamp_vo = tmval.tv_nsec / 1000;
|
|
+#else
|
|
hw_priv->tsm_info.rx_timestamp_vo = tmval.tv_usec;
|
|
+#endif
|
|
}
|
|
}
|
|
spin_unlock_bh(&hw_priv->tsm_lock);
|
|
diff --git a/drivers/staging/bes2600/txrx_opt.c b/drivers/staging/bes2600/txrx_opt.c
|
|
index 15f6abbb666f..edc1691ce25b 100644
|
|
--- a/drivers/staging/bes2600/txrx_opt.c
|
|
+++ b/drivers/staging/bes2600/txrx_opt.c
|
|
@@ -27,6 +27,7 @@
|
|
#include "sbus.h"
|
|
#include "bes2600_log.h"
|
|
#include "bes_pwr.h"
|
|
+#include "txrx_opt.h"
|
|
|
|
#define TXRX_OPT_CLOSE_EDCA 0
|
|
#define TXRX_OPT_EDCA_MAX_LEVEL 4
|
|
@@ -34,15 +35,25 @@
|
|
#define TXRX_OPT_PEROID 500
|
|
#define TXRX_OPT_DEBUG 1
|
|
|
|
-#define TXRX_HIGH_TP_THRESHOLD_2G4 30000 //unit is kbps
|
|
-#define TXRX_HIGH_TP_THRESHOLD_5G 40000 //unit is kbps
|
|
-#define TXRX_HIGH_TP_DELTA_TIME_2G4 8 //unit ms
|
|
-#define TXRX_HIGH_TP_DELTA_TIME_5G 6 //unit ms
|
|
+#define TXRX_HIGH_TP_THRESHOLD_2G4 30000 // unit is kbps
|
|
+#define TXRX_HIGH_TP_THRESHOLD_5G 40000 // unit is kbps
|
|
+#define TXRX_HIGH_TP_DELTA_TIME_2G4 8 // unit ms
|
|
+#define TXRX_HIGH_TP_DELTA_TIME_5G 6 // unit ms
|
|
+
|
|
+#define TXRX_RTS_PROT_TRIG_THRESH 80 // percent * 100
|
|
+#define TXRX_RTS_PROT_DURATION 10 // unit second
|
|
+
|
|
+#define TXRX_RTS_PROT_OPEN(x) (x = 512)
|
|
+#define TXRX_RTS_PROT_CLOSE(x) (x = 2437)
|
|
+#define TXRX_RTS_PROT_OPENED(x) (x < 1536)
|
|
|
|
static uint32_t tx_delta_time_arr[4][TX_AVG_TIME_COUNT];
|
|
static uint32_t tx_queue_arr[4] = {0};
|
|
static uint32_t tx_delta_time_total = 0;
|
|
static uint32_t tx_delta_time_total_cnt = 0;
|
|
+static u8 cur_pwr_tbl = 1;
|
|
+static u16 cur_rts_thres = 2437;
|
|
+static unsigned long last_rts_set_time = -1;
|
|
|
|
void bes2600_add_tx_delta_time(uint32_t tx_delta_time)
|
|
{
|
|
@@ -185,8 +196,9 @@ int bes2600_set_high_edca_params(struct bes2600_common *hw_priv, struct bes2600_
|
|
if (lev == level)
|
|
return 0;
|
|
|
|
- memcpy(&arg, &(priv->edca), sizeof(struct wsm_edca_params));
|
|
+ lev = level;
|
|
|
|
+ memcpy(&arg, &(priv->edca), sizeof(struct wsm_edca_params));
|
|
|
|
if (level == 0) {
|
|
bes2600_set_default_params(hw_priv, priv);
|
|
@@ -245,6 +257,26 @@ void bes2600_set_dynamic_agc(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
{
|
|
// todo set agc alg
|
|
}
|
|
+
|
|
+int bes2600_update_pwr_table(struct bes2600_common *hw_priv,
|
|
+ struct bes2600_vif *priv,
|
|
+ u8 pwr_tbl_idx)
|
|
+{
|
|
+ int ret = 0;
|
|
+ static u8 cur_pwr_tbl_idx = 0xff;
|
|
+
|
|
+ if (cur_pwr_tbl_idx != pwr_tbl_idx) {
|
|
+ cur_pwr_tbl_idx = pwr_tbl_idx;
|
|
+ ret = WARN_ON(wsm_write_mib(hw_priv,
|
|
+ WSM_MIB_ID_EXT_PWR_TBL_UPDATE,
|
|
+ (u8 *)&cur_pwr_tbl_idx,
|
|
+ sizeof(cur_pwr_tbl_idx),
|
|
+ priv->if_id));
|
|
+ bes2600_info(BES2600_DBG_TXRX_OPT, "%s pwr_tbl_idx=%d\n\r", __func__, pwr_tbl_idx);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int bes2600_get_tx_av_max_delta_time(void)
|
|
{
|
|
int max_avg = 0;
|
|
@@ -278,8 +310,6 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
static u32 tx_bps = 0, rx_bps = 0;
|
|
u32 total_kbps = 0;
|
|
static int level;
|
|
- int rts_value = 2347;
|
|
- int short_gi = 0;
|
|
|
|
/* calculate real time throughput */
|
|
if (hw_priv == NULL || priv == NULL) {
|
|
@@ -295,6 +325,8 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
/* if tx/rx < 100k/s, close*/
|
|
if (total_kbps < 100) {
|
|
level = 0;
|
|
+ last_rts_set_time = -1;
|
|
+ TXRX_RTS_PROT_CLOSE(cur_rts_thres);
|
|
goto txrx_opt_clear;
|
|
}
|
|
|
|
@@ -305,16 +337,18 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
rx_cnt = (priv->dot11ReceivedFragmentCount - l_rx_cnt);
|
|
( (tx_cnt + tx_retry) > 0 ) ? (succPro = tx_cnt * 100 / (tx_cnt + tx_retry)) : (succPro = 0);
|
|
|
|
- if (succPro != 0) {
|
|
- /* hw value 21 is mcs7, dynamic set short GI */
|
|
- if (priv->hw_value == 21 && succPro > 90)
|
|
- short_gi = 1;
|
|
- else
|
|
- short_gi = 0;
|
|
-
|
|
- /* dynamic set RTS/CTS */
|
|
- if (succPro < 80)
|
|
- rts_value = 512;
|
|
+ bes2600_dbg(BES2600_DBG_TXRX_OPT, "%s, tx_cnt:%d prob:%d\n", __func__, tx_cnt, succPro);
|
|
+
|
|
+ /* set rts/cts protection dynamically */
|
|
+ if (tx_cnt > 50 && succPro != 0) {
|
|
+ if (succPro > TXRX_RTS_PROT_TRIG_THRESH &&
|
|
+ TXRX_RTS_PROT_OPENED(cur_rts_thres) &&
|
|
+ time_after(jiffies, last_rts_set_time + TXRX_RTS_PROT_DURATION * HZ)) {
|
|
+ TXRX_RTS_PROT_CLOSE(cur_rts_thres);
|
|
+ } else if (succPro <= TXRX_RTS_PROT_TRIG_THRESH){
|
|
+ TXRX_RTS_PROT_OPEN(cur_rts_thres);
|
|
+ last_rts_set_time = jiffies;
|
|
+ }
|
|
}
|
|
|
|
/* dynamic set edca param */
|
|
@@ -348,14 +382,21 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
|
|
}
|
|
}
|
|
+
|
|
+ /* dynamic set power table */
|
|
+ if (rssi <= BES2600_TX_RSSI_LOW)
|
|
+ cur_pwr_tbl = 2; // use high power table
|
|
+ else if(rssi >= BES2600_TX_RSSI_HIGH)
|
|
+ cur_pwr_tbl = 1; // use standard power table
|
|
+
|
|
#if TXRX_OPT_CLOSE_EDCA
|
|
level = 0;
|
|
#endif
|
|
if (level > TXRX_OPT_EDCA_MAX_LEVEL)
|
|
level = TXRX_OPT_EDCA_MAX_LEVEL;
|
|
|
|
- bes2600_dbg(BES2600_DBG_TXRX_OPT, "txrx_opt: tx(cnt=%d retry=%d psr=%d tx_fail=%d (wsm rts=%d shortgi=%d level=%d) tx=%dk/s)\n\r",
|
|
- tx_cnt, tx_retry, succPro, tx_fail, rts_value, short_gi, level, tx_bps / 128);
|
|
+ bes2600_dbg(BES2600_DBG_TXRX_OPT, "txrx_opt: tx(cnt=%d retry=%d psr=%d tx_fail=%d (wsm level=%d) tx=%dk/s)\n\r",
|
|
+ tx_cnt, tx_retry, succPro, tx_fail, level, tx_bps / 128);
|
|
bes2600_dbg(BES2600_DBG_TXRX_OPT, "txrx_opt: rx(cnt=%d rx=%dk/s) total=%dk/s\n\r", rx_cnt, rx_bps / 128, total_kbps);
|
|
bes2600_dbg(BES2600_DBG_TXRX_OPT, "txrx_opt: tx_delta_time=%d [%d %d %d %d] hw_value=%d ht=%d maxtxcnt=%d\n\r",
|
|
bes2600_get_tx_delta_time(), bes2600_get_tx_ac_delta_time(0), bes2600_get_tx_ac_delta_time(1),
|
|
@@ -367,10 +408,10 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
bes2600_set_cca_method(hw_priv, priv, 0);
|
|
/* dynamic set agc */
|
|
bes2600_set_dynamic_agc(hw_priv, priv, 0);
|
|
+ bes2600_update_pwr_table(hw_priv, priv, cur_pwr_tbl);
|
|
txrx_opt_clear:
|
|
- bes2600_set_rts_threshold(priv->hw, rts_value);
|
|
- bes2600_enable_tx_shortgi(hw_priv, priv, short_gi);
|
|
bes2600_set_high_edca_params(hw_priv, priv, level);
|
|
+ bes2600_set_rts_threshold(hw_priv->hw, cur_rts_thres);
|
|
bes2600_clear_tx_delta_time();
|
|
bes2600_clear_tx_ac_delta_time(0);
|
|
bes2600_clear_tx_ac_delta_time(1);
|
|
@@ -387,6 +428,21 @@ void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv, struct bes2600_vif
|
|
|
|
static struct bes2600_common *txrx_hw_priv = NULL;
|
|
|
|
+static bool bes2600_is_sta_connected(void)
|
|
+{
|
|
+ if (txrx_hw_priv == NULL)
|
|
+ return false;
|
|
+ else
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void bes2600_txrx_opt_timer_restore(void)
|
|
+{
|
|
+ if (bes2600_is_sta_connected()) {
|
|
+ mod_timer(&txrx_hw_priv->txrx_opt_timer, jiffies + msecs_to_jiffies(TXRX_OPT_PEROID));
|
|
+ }
|
|
+}
|
|
+
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)
|
|
static void txrx_opt_timer_callback(struct timer_list* data)
|
|
#else
|
|
@@ -395,7 +451,6 @@ static void txrx_opt_timer_callback(unsigned long data)
|
|
{
|
|
bes2600_dbg(BES2600_DBG_TXRX, "####Timer callback function Called time = %lu\n", jiffies);
|
|
queue_work(txrx_hw_priv->workqueue, &txrx_hw_priv->dynamic_opt_txrx_work);
|
|
- mod_timer(&txrx_hw_priv->txrx_opt_timer, jiffies + msecs_to_jiffies(TXRX_OPT_PEROID));
|
|
}
|
|
|
|
static void txrx_opt_timer_start(struct bes2600_common *hw_priv)
|
|
@@ -410,12 +465,39 @@ static void txrx_opt_timer_stop(struct bes2600_common *hw_priv)
|
|
|
|
int bes2600_set_txrx_opt_default_param(struct bes2600_common * hw_priv)
|
|
{
|
|
- MIB_TXRX_OPT_PARAM g_txrx_param = {2, (PROCTECT_MODE_RTS_CTS | PROCTECT_MODE_RTS_CTS_RETRY), 2002};
|
|
+ MIB_TXRX_OPT_PARAM g_txrx_param = {2, (PROCTECT_MODE_RTS_CTS | PROCTECT_MODE_RTS_CTS_RETRY), 3000};
|
|
struct bes2600_vif *priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, 0);
|
|
+ struct ieee80211_sta *sta = NULL;
|
|
+
|
|
if (priv == NULL)
|
|
return 0;
|
|
+
|
|
+ /* reset states */
|
|
+ cur_pwr_tbl = 1;
|
|
+ TXRX_RTS_PROT_CLOSE(cur_rts_thres);
|
|
+ last_rts_set_time = -1;
|
|
memcpy(&hw_priv->txrx_opt_param, &g_txrx_param, sizeof(MIB_TXRX_OPT_PARAM));
|
|
+
|
|
+ /* reset device states */
|
|
bes2600_set_txrx_opt_param(hw_priv, priv, &hw_priv->txrx_opt_param);
|
|
+ bes2600_set_rts_threshold(hw_priv->hw, cur_rts_thres); // close rts/cts
|
|
+ bes2600_update_pwr_table(hw_priv, priv, cur_pwr_tbl); // use standard pwr table
|
|
+
|
|
+ if (priv->join_status == BES2600_JOIN_STATUS_STA) {
|
|
+ sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid);
|
|
+ if (sta->deflink.ht_cap.ht_supported &&
|
|
+ ((priv->vif->bss_conf.chandef.width == NL80211_CHAN_WIDTH_20 &&
|
|
+ sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
|
|
+ (priv->vif->bss_conf.chandef.width == NL80211_CHAN_WIDTH_40 &&
|
|
+ sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40))) {
|
|
+ bes2600_info(BES2600_DBG_TXRX, "open short gi tx\n");
|
|
+ bes2600_enable_tx_shortgi(hw_priv, priv, 1);
|
|
+ } else {
|
|
+ bes2600_info(BES2600_DBG_TXRX, "close short gi tx\n");
|
|
+ bes2600_enable_tx_shortgi(hw_priv, priv, 0);
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -425,14 +507,35 @@ int bes2600_set_txrx_opt_unjoin_param(struct bes2600_common * hw_priv)
|
|
struct bes2600_vif *priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, 0);
|
|
if (priv == NULL)
|
|
return 0;
|
|
+
|
|
+ /* reset states */
|
|
+ cur_pwr_tbl = 1;
|
|
+ bes2600_update_pwr_table(hw_priv, priv, cur_pwr_tbl);
|
|
memcpy(&hw_priv->txrx_opt_param, &g_txrx_param, sizeof(MIB_TXRX_OPT_PARAM));
|
|
bes2600_set_txrx_opt_param(hw_priv, priv, &hw_priv->txrx_opt_param);
|
|
return 0;
|
|
}
|
|
|
|
-int txrx_opt_timer_init(struct bes2600_common *hw_priv)
|
|
+void bes2600_txrx_opt_multivif_connected_handler(struct bes2600_common *hw_priv, bool multivif_connected)
|
|
{
|
|
+ struct bes2600_vif *priv = __cw12xx_hwpriv_to_vifpriv(hw_priv, 0);
|
|
+
|
|
+ if (multivif_connected) {
|
|
+ bes2600_set_txrx_opt_default_param(hw_priv);
|
|
+ } else {
|
|
+ bes2600_dbg(BES2600_DBG_STA, "%s, rssi:%d\n", __func__, priv->signal);
|
|
+ bes2600_dynamic_opt_rxtx(hw_priv, priv, priv->signal);
|
|
+ mod_timer(&hw_priv->txrx_opt_timer, jiffies + msecs_to_jiffies(TXRX_OPT_PEROID));
|
|
+ }
|
|
+}
|
|
+
|
|
+int txrx_opt_timer_init(struct bes2600_vif *priv)
|
|
+{
|
|
+ struct bes2600_common *hw_priv = cw12xx_vifpriv_to_hwpriv(priv);
|
|
bes2600_info(BES2600_DBG_TXRX_OPT, "txrx_opt_timer_init:%p", txrx_hw_priv);
|
|
+ if (priv->if_id != 0)
|
|
+ return 0;
|
|
+
|
|
if (!txrx_hw_priv) {
|
|
txrx_hw_priv = hw_priv;
|
|
bes2600_info(BES2600_DBG_TXRX, "####Timer init hw_priv = %p\n", txrx_hw_priv);
|
|
@@ -452,16 +555,21 @@ int txrx_opt_timer_init(struct bes2600_common *hw_priv)
|
|
return 0;
|
|
}
|
|
|
|
-void txrx_opt_timer_exit(struct bes2600_common *hw_priv)
|
|
+void txrx_opt_timer_exit(struct bes2600_vif *priv)
|
|
{
|
|
+ struct bes2600_common *hw_priv = cw12xx_vifpriv_to_hwpriv(priv);
|
|
bes2600_info(BES2600_DBG_TXRX_OPT, "txrx_opt_timer_exit");
|
|
|
|
- del_timer_sync(&hw_priv->txrx_opt_timer);
|
|
- cancel_work_sync(&hw_priv->dynamic_opt_txrx_work);
|
|
- bes2600_pwr_unregister_en_lp_cb(hw_priv, txrx_opt_timer_stop);
|
|
- bes2600_pwr_unregister_exit_lp_cb(hw_priv, txrx_opt_timer_start);
|
|
- txrx_hw_priv = NULL;
|
|
- bes2600_set_txrx_opt_unjoin_param(hw_priv);
|
|
+ if (priv->if_id == 0) {
|
|
+ del_timer_sync(&hw_priv->txrx_opt_timer);
|
|
+ cancel_work_sync(&hw_priv->dynamic_opt_txrx_work);
|
|
+ bes2600_pwr_unregister_en_lp_cb(hw_priv, txrx_opt_timer_stop);
|
|
+ bes2600_pwr_unregister_exit_lp_cb(hw_priv, txrx_opt_timer_start);
|
|
+ txrx_hw_priv = NULL;
|
|
+ bes2600_set_txrx_opt_unjoin_param(hw_priv);
|
|
+ } else if (priv->if_id == 1) {
|
|
+ bes2600_txrx_opt_timer_restore();
|
|
+ }
|
|
}
|
|
|
|
|
|
diff --git a/drivers/staging/bes2600/txrx_opt.h b/drivers/staging/bes2600/txrx_opt.h
|
|
index 582ff7fb5221..93c22f4bc5e8 100644
|
|
--- a/drivers/staging/bes2600/txrx_opt.h
|
|
+++ b/drivers/staging/bes2600/txrx_opt.h
|
|
@@ -19,13 +19,20 @@
|
|
#include <linux/list.h>
|
|
/* open it for enhance wifi throughput */
|
|
#define BES2600_TX_RX_OPT 1
|
|
+
|
|
+/* Threshold for powrt table switch */
|
|
+#define BES2600_TX_RSSI_LOW -65
|
|
+#define BES2600_TX_RSSI_HIGH -60
|
|
+
|
|
void bes2600_add_tx_ac_delta_time(int ac, uint32_t del_time);
|
|
void bes2600_add_tx_delta_time(uint32_t tx_time);
|
|
void bes2600_rx_status(struct bes2600_vif *priv, struct sk_buff *skb);
|
|
void bes2600_tx_status(struct bes2600_vif *priv, struct sk_buff *skb);
|
|
void bes2600_dynamic_opt_rxtx(struct bes2600_common *hw_priv,struct bes2600_vif *priv, int rssi);
|
|
-int txrx_opt_timer_init(struct bes2600_common *hw_priv);
|
|
-int txrx_opt_timer_exit(struct bes2600_common *hw_priv);
|
|
+void bes2600_txrx_opt_multivif_connected_handler(struct bes2600_common *hw_priv, bool multivif_connected);
|
|
+void bes2600_txrx_opt_timer_restore(void);
|
|
+int txrx_opt_timer_init(struct bes2600_vif *priv);
|
|
+void txrx_opt_timer_exit(struct bes2600_vif *priv);
|
|
|
|
#endif
|
|
|
|
diff --git a/drivers/staging/bes2600/wifi_testmode_cmd.c b/drivers/staging/bes2600/wifi_testmode_cmd.c
|
|
index 3b3583a6db3d..4022579444be 100644
|
|
--- a/drivers/staging/bes2600/wifi_testmode_cmd.c
|
|
+++ b/drivers/staging/bes2600/wifi_testmode_cmd.c
|
|
@@ -110,6 +110,7 @@ int bes2600_vendor_rf_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8
|
|
case VENDOR_RF_NOSIGNALING_CMD:
|
|
case VENDOR_RF_SAVE_FREQOFFSET_CMD:
|
|
case VENDOR_RF_SAVE_POWERLEVEL_CMD:
|
|
+ case VENDOR_RF_GET_CALI_FROM_EFUSE:
|
|
sema_init(&hw_priv->vendor_rf_cmd_replay_sema, 0);
|
|
ret = wsm_vendor_rf_cmd(hw_priv, if_id, vendor_rf_cmd);
|
|
|
|
diff --git a/drivers/staging/bes2600/wsm.c b/drivers/staging/bes2600/wsm.c
|
|
index 8ba5ce0a0bb3..3dc8642129ff 100644
|
|
--- a/drivers/staging/bes2600/wsm.c
|
|
+++ b/drivers/staging/bes2600/wsm.c
|
|
@@ -314,6 +314,7 @@ int wsm_vendor_rf_test_indication(struct bes2600_common *hw_priv, struct wsm_buf
|
|
break;
|
|
case VENDOR_RF_SIGNALING_CMD:
|
|
case VENDOR_RF_NOSIGNALING_CMD:
|
|
+ case VENDOR_RF_GET_CALI_FROM_EFUSE:
|
|
bes2600_rf_cmd_msg_assembly(cmd_type, buf->data, wsm_len - sizeof(struct wsm_mcu_hdr));
|
|
break;
|
|
default:
|
|
@@ -1213,8 +1214,7 @@ int wsm_cpu_usage_cmd(struct bes2600_common *hw_priv)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
-#ifdef PLAT_ALLWINNER_R329
|
|
-int wsm_save_factory_txt_to_flash(struct bes2600_common *hw_priv, const u8 *data, int if_id)
|
|
+int wsm_save_factory_txt_to_mcu(struct bes2600_common *hw_priv, const u8 *data, int if_id, enum bes2600_rf_cmd_type cmd_type)
|
|
{
|
|
int ret, i;
|
|
const struct factory_t *factory_cali = (const struct factory_t *)data;
|
|
@@ -1223,8 +1223,7 @@ int wsm_save_factory_txt_to_flash(struct bes2600_common *hw_priv, const u8 *data
|
|
wsm_cmd_lock(hw_priv);
|
|
|
|
/* cmd type */
|
|
- WSM_PUT32(buf, BES2600_RF_CMD_CALI_TXT_TO_FLASH);
|
|
-
|
|
+ WSM_PUT32(buf, cmd_type);
|
|
WSM_PUT32(buf, factory_cali->data.iQ_offset);
|
|
WSM_PUT16(buf, factory_cali->data.freq_cal);
|
|
|
|
@@ -1253,10 +1252,7 @@ int wsm_save_factory_txt_to_flash(struct bes2600_common *hw_priv, const u8 *data
|
|
nomem:
|
|
wsm_cmd_unlock(hw_priv);
|
|
return -ENOMEM;
|
|
-
|
|
}
|
|
-#endif
|
|
-
|
|
/* ******************************************************************** */
|
|
#ifdef MCAST_FWDING
|
|
/* 3.66 */
|
|
@@ -1477,6 +1473,7 @@ static int wsm_receive_indication(struct bes2600_common *hw_priv,
|
|
struct sk_buff **skb_p)
|
|
{
|
|
struct bes2600_vif *priv;
|
|
+ s8 pkt_signal = 0;
|
|
|
|
hw_priv->rx_timestamp = jiffies;
|
|
if (hw_priv->wsm_cbc.rx) {
|
|
@@ -1542,8 +1539,23 @@ static int wsm_receive_indication(struct bes2600_common *hw_priv,
|
|
|
|
/* If no RSSI subscription has been made,
|
|
* convert RCPI to RSSI here */
|
|
- if (!priv->cqm_use_rssi)
|
|
+ if (!priv->cqm_use_rssi) {
|
|
+ pkt_signal = rx.rcpiRssi / 2 - 110;
|
|
rx.rcpiRssi = rx.rcpiRssi / 2 - 110;
|
|
+ }
|
|
+
|
|
+ if(ieee80211_is_data(hdr->frame_control)) {
|
|
+ if (priv->signal == 0) {
|
|
+ priv->signal = pkt_signal;
|
|
+ priv->signal_mul = pkt_signal * 100;
|
|
+ } else {
|
|
+ priv->signal_mul = priv->signal_mul * 80 / 100 + pkt_signal * 20;
|
|
+ priv->signal = priv->signal_mul / 100;
|
|
+ }
|
|
+
|
|
+ bes2600_dbg(BES2600_DBG_TXRX, "pkt signal:%d\n", priv->signal);
|
|
+ }
|
|
+
|
|
|
|
fctl = *(__le16 *)buf->data;
|
|
hdr_len = buf->data - buf->begin;
|
|
@@ -1579,7 +1591,7 @@ static int wsm_receive_indication(struct bes2600_common *hw_priv,
|
|
(*skb_p)->len, has_mmie, priv->pmf);
|
|
if (has_mmie ^ priv->pmf)
|
|
ignore = true;
|
|
- } else if (ether_addr_equal(hdr->addr1, hw_priv->addresses[rx.if_id].addr)) {
|
|
+ } else if (ether_addr_equal(hdr->addr1, priv->vif->addr)) {
|
|
bool has_protected = ieee80211_has_protected(fctl);
|
|
bes2600_info(BES2600_DBG_WSM, "[WSM] RX unicast deauth: protected=%d, pmf=%d, connect_in_process=%d\n",
|
|
has_protected, priv->pmf, atomic_read(&priv->connect_in_process));
|
|
@@ -1600,10 +1612,19 @@ static int wsm_receive_indication(struct bes2600_common *hw_priv,
|
|
bes2600_info(BES2600_DBG_WSM, "[WSM] Issue unjoin command (RX).\n");
|
|
wsm_lock_tx_async(hw_priv);
|
|
if (queue_work(hw_priv->workqueue,
|
|
- &priv->unjoin_work) <= 0)
|
|
+ &priv->unjoin_work) <= 0) {
|
|
wsm_unlock_tx(hw_priv);
|
|
+ }
|
|
+#ifdef CONFIG_PM
|
|
+ else if(bes2600_suspend_status_get(hw_priv)) {
|
|
+ bes2600_pending_unjoin_set(hw_priv, priv->if_id);
|
|
+ }
|
|
+#endif
|
|
+ if (bes2600_chrdev_wakeup_by_event_get() == WAKEUP_EVENT_PEER_DETACH)
|
|
+ bes2600_chrdev_wifi_update_wakeup_reason(WAKEUP_REASON_WIFI_DEAUTH_DISASSOC, 0);
|
|
}
|
|
}
|
|
+ bes2600_chrdev_wakeup_by_event_set(WAKEUP_EVENT_NONE);
|
|
}
|
|
hw_priv->wsm_cbc.rx(priv, &rx, skb_p);
|
|
if (*skb_p)
|
|
@@ -2014,7 +2035,7 @@ bool wsm_vif_flush_tx(struct bes2600_vif *priv)
|
|
{
|
|
struct bes2600_common *hw_priv = priv->hw_priv;
|
|
unsigned long timestamp = jiffies;
|
|
- long timeout;
|
|
+ unsigned long timeout;
|
|
int i;
|
|
int if_id = priv->if_id;
|
|
|
|
@@ -2045,11 +2066,17 @@ bool wsm_vif_flush_tx(struct bes2600_vif *priv)
|
|
if (!hw_priv->hw_bufs_used_vif[if_id])
|
|
return true;
|
|
|
|
- timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
|
|
- if (timeout < 0 || wait_event_timeout(hw_priv->bh_evt_wq,
|
|
+ /* calculate wait time */
|
|
+ timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT;
|
|
+ if (timeout >= jiffies)
|
|
+ timeout -= jiffies;
|
|
+ else
|
|
+ timeout += (ULONG_MAX - jiffies);
|
|
+
|
|
+ /* wait packets on vif to be flushed */
|
|
+ if (wait_event_timeout(hw_priv->bh_evt_wq,
|
|
!hw_priv->hw_bufs_used_vif[if_id],
|
|
timeout) <= 0) {
|
|
-
|
|
/* Hmmm... Not good. Frame had stuck in firmware. */
|
|
bes2600_chrdev_wifi_force_close(hw_priv, true);
|
|
}
|
|
@@ -2202,9 +2229,7 @@ int wsm_handle_rx(struct bes2600_common *hw_priv, int id,
|
|
if (IS_DRIVER_TO_MCU_CMD(id))
|
|
ind_confirm_label = __le32_to_cpu(((struct wsm_mcu_hdr *)wsm)->handle_label);
|
|
|
|
- if (id == 0x0C30) {
|
|
- ret = wsm_bt_ts_request(hw_priv, &wsm_buf);
|
|
- } else if (id == 0x404) {
|
|
+ if (id == 0x404) {
|
|
ret = wsm_tx_confirm(hw_priv, &wsm_buf, interface_link_id);
|
|
#ifdef MCAST_FWDING
|
|
#if 1
|
|
@@ -2312,10 +2337,10 @@ int wsm_handle_rx(struct bes2600_common *hw_priv, int id,
|
|
case 0x0C25:
|
|
ret = wsm_vendor_rf_cmd_confirm(hw_priv, wsm_arg, &wsm_buf);
|
|
break;
|
|
+#endif /* CONFIG_BES2600_TESTMODE */
|
|
case 0x0C27:
|
|
ret = wsm_driver_rf_cmd_confirm(hw_priv, wsm_arg, &wsm_buf);
|
|
break;
|
|
-#endif /* CONFIG_BES2600_TESTMODE */
|
|
#ifdef BES_UNIFIED_PM
|
|
case 0x0424: /* wifi sleep disable */
|
|
break;
|
|
@@ -2408,6 +2433,9 @@ int wsm_handle_rx(struct bes2600_common *hw_priv, int id,
|
|
ret = wsm_vendor_rf_test_indication(hw_priv, &wsm_buf);
|
|
break;
|
|
#endif /* CONFIG_BES2600_TESTMODE */
|
|
+ case 0x0C30:
|
|
+ ret = wsm_bt_ts_request(hw_priv, &wsm_buf);
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -2712,7 +2740,7 @@ static int bes2600_get_prio_queue(struct bes2600_vif *priv,
|
|
edca = &priv->edca.params[i];
|
|
score = ((edca->aifns + edca->cwMin) << 16) +
|
|
(edca->cwMax - edca->cwMin) *
|
|
- (get_random_int() & 0xFFFF);
|
|
+ (get_random_long() & 0xFFFF);
|
|
if (score < best && (winner < 0 || i != 3)) {
|
|
best = score;
|
|
winner = i;
|
|
@@ -3127,6 +3155,8 @@ static inline int get_interface_id_scanning(struct bes2600_common *hw_priv)
|
|
{
|
|
if (hw_priv->scan.req)
|
|
return hw_priv->scan.if_id;
|
|
+ else if (hw_priv->scan.direct_probe == 1)
|
|
+ return hw_priv->scan.if_id;
|
|
else
|
|
return -1;
|
|
}
|
|
diff --git a/drivers/staging/bes2600/wsm.h b/drivers/staging/bes2600/wsm.h
|
|
index 5bb5bace57ff..8e229a5428e1 100644
|
|
--- a/drivers/staging/bes2600/wsm.h
|
|
+++ b/drivers/staging/bes2600/wsm.h
|
|
@@ -379,6 +379,9 @@ struct bes2600_vif;
|
|
#define WSM_PS_ERROR_AP_SENT_UNICAST_IN_DOZE 3
|
|
#define WSM_PS_ERROR_AP_NO_DATA_AFTER_TIM 4
|
|
|
|
+/* eth filter extended flags */
|
|
+#define WSM_ETH_FILTER_EXT_DISABLE_IPV6_MATCH BIT(0)
|
|
+
|
|
/* WSM events */
|
|
/* Error */
|
|
#define WSM_EVENT_ERROR (0)
|
|
@@ -570,6 +573,7 @@ struct bes2600_vif;
|
|
#define WSM_MIB_ID_EXT_TCP_KEEP_ALIVE_PERIOD (WSM_MIB_ID_EXT_BASE + 2) /* Mib to set tcp keep alive period */
|
|
#define WSM_MIB_ID_EXT_TX_SHORT_GI_ENABLED (WSM_MIB_ID_EXT_BASE + 3) /* Mib to set tx short enabled */
|
|
#define WSM_MIB_ID_EXT_TXRX_OPT_PARAM (WSM_MIB_ID_EXT_BASE + 4) /* Mib to set tx/rx opt param to enhance wifi throuhput */
|
|
+#define WSM_MIB_ID_EXT_PWR_TBL_UPDATE (WSM_MIB_ID_EXT_BASE + 5) /* Mib to update power table */
|
|
|
|
|
|
#ifdef IPV6_FILTERING
|
|
@@ -591,6 +595,7 @@ struct bes2600_vif;
|
|
|
|
#ifdef IPV6_FILTERING
|
|
#define WSM_FRAME_TYPE_NA (7)
|
|
+#define WSM_MAX_IPV6_ADDR_FILTER_ELTS (8)
|
|
#endif /*IPV6_FILTERING*/
|
|
|
|
#define WSM_FRAME_GREENFIELD (0x80) /* See 4.11 */
|
|
@@ -653,6 +658,9 @@ struct bes2600_vif;
|
|
#define WSM_FILTER_PORT_TYPE_DST (0)
|
|
#define WSM_FILTER_PORT_TYPE_SRC (1)
|
|
|
|
+#define WSM_IP_DATA_FRAME_ADDRMODE_SRC (0x01)
|
|
+#define WSM_IP_DATA_FRAME_ADDRMODE_DEST (0x02)
|
|
+#define WSM_IP_DATA_FRAME_ADDRMODE_TCPACK (0x03)
|
|
|
|
|
|
struct wsm_hdr {
|
|
@@ -1538,34 +1546,41 @@ static inline int wsm_set_beacon_filter_table(struct bes2600_common *hw_priv,
|
|
struct wsm_beacon_filter_table *ft,
|
|
int if_id)
|
|
{
|
|
+ static __le32 numOfIEs;
|
|
size_t size = __le32_to_cpu(ft->numOfIEs) *
|
|
sizeof(struct wsm_beacon_filter_table_entry) +
|
|
sizeof(__le32);
|
|
|
|
+ if (numOfIEs == ft->numOfIEs && numOfIEs == 0) {
|
|
+ return 0;
|
|
+ }
|
|
+ numOfIEs = ft->numOfIEs;
|
|
return wsm_write_mib(hw_priv, WSM_MIB_ID_BEACON_FILTER_TABLE, ft, size,
|
|
if_id);
|
|
}
|
|
|
|
#define WSM_BEACON_FILTER_ENABLE BIT(0) /* Enable/disable beacon filtering */
|
|
#define WSM_BEACON_FILTER_AUTO_ERP BIT(1) /* If 1 FW will handle ERP IE changes internally */
|
|
+#define WSM_BEACON_FILTER_AUTO_HT BIT(2) /* If 1 FW will handle HT OP IE changes internally */
|
|
|
|
struct wsm_beacon_filter_control {
|
|
- int enabled;
|
|
- int bcn_count;
|
|
+ __le32 enabled;
|
|
+ __le32 bcn_count;
|
|
};
|
|
|
|
static inline int wsm_beacon_filter_control(struct bes2600_common *hw_priv,
|
|
struct wsm_beacon_filter_control *arg,
|
|
int if_id)
|
|
{
|
|
- struct {
|
|
- __le32 enabled;
|
|
- __le32 bcn_count;
|
|
- } val;
|
|
- val.enabled = __cpu_to_le32(arg->enabled);
|
|
- val.bcn_count = __cpu_to_le32(arg->bcn_count);
|
|
- return wsm_write_mib(hw_priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, &val,
|
|
- sizeof(val), if_id);
|
|
+ static __le32 enabled, bcn_count;
|
|
+
|
|
+ if (enabled == arg->enabled && bcn_count == arg->bcn_count) {
|
|
+ return 0;
|
|
+ }
|
|
+ enabled = arg->enabled;
|
|
+ bcn_count = arg->bcn_count;
|
|
+ return wsm_write_mib(hw_priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, arg,
|
|
+ sizeof(struct wsm_beacon_filter_control), if_id);
|
|
}
|
|
|
|
enum wsm_power_mode {
|
|
@@ -1734,7 +1749,8 @@ static inline int wsm_set_tx_rate_retry_policy(struct bes2600_common *hw_priv,
|
|
/* 4.32 SetEtherTypeDataFrameFilter */
|
|
struct wsm_ether_type_filter_hdr {
|
|
u8 nrFilters; /* Up to WSM_MAX_FILTER_ELEMENTS */
|
|
- u8 reserved[3];
|
|
+ u8 extFlags;
|
|
+ u8 reserved[2];
|
|
} __packed;
|
|
|
|
struct wsm_ether_type_filter {
|
|
@@ -1932,13 +1948,28 @@ struct wsm_ip6_addr_info {
|
|
u8 ipv6[16];
|
|
};
|
|
|
|
-/* IPV6 Addr Filter */
|
|
-struct wsm_ipv6_filter {
|
|
+struct wsm_ipv6_filter_header {
|
|
u8 numfilter;
|
|
u8 action_mode;
|
|
u8 Reserved[2];
|
|
- struct wsm_ip6_addr_info ipv6filter[0];
|
|
+};
|
|
+
|
|
+/* IPV6 Addr Filter */
|
|
+struct wsm_ipv6_filter {
|
|
+ struct wsm_ipv6_filter_header hdr;
|
|
+ struct wsm_ip6_addr_info ipv6filter[WSM_MAX_IPV6_ADDR_FILTER_ELTS];
|
|
} __packed;
|
|
+
|
|
+static inline int wsm_set_ipv6_filter(struct bes2600_common *hw_priv,
|
|
+ struct wsm_ipv6_filter_header *arg,
|
|
+ int if_id)
|
|
+{
|
|
+ size_t size = sizeof(struct wsm_ipv6_filter_header) +
|
|
+ arg->numfilter * sizeof(struct wsm_ip6_addr_info);
|
|
+
|
|
+ return wsm_write_mib(hw_priv, WSM_MIB_IP_IPV6_ADDR_FILTER,
|
|
+ arg, size, if_id);
|
|
+}
|
|
#endif /*IPV6_FILTERING*/
|
|
|
|
struct wsm_ip4_addr_info {
|
|
@@ -2157,6 +2188,7 @@ enum bes2600_rf_cmd_type {
|
|
BES2600_RF_CMD_CH_INFO = 1,
|
|
BES2600_RF_CMD_CPU_USAGE = 2,
|
|
BES2600_RF_CMD_WIFI_STATUS = 3,
|
|
+ BES2600_RF_CMD_CALI_TXT_TO_EFUSE = 4,
|
|
/* add new here */
|
|
|
|
BES2600_RF_CMD_MAX,
|
|
@@ -2204,8 +2236,7 @@ int wsm_cpu_usage_cmd(struct bes2600_common *hw_priv);
|
|
|
|
int wsm_wifi_status_cmd(struct bes2600_common *hw_priv, uint32_t status);
|
|
|
|
-#ifdef PLAT_ALLWINNER_R329
|
|
-int wsm_save_factory_txt_to_flash(struct bes2600_common *hw_priv, const u8 *data, int if_id);
|
|
+#if defined(PLAT_ALLWINNER_R329) || defined(STANDARD_FACTORY_EFUSE_FLAG)
|
|
+int wsm_save_factory_txt_to_mcu(struct bes2600_common *hw_priv, const u8 *data, int if_id, enum bes2600_rf_cmd_type cmd_type);
|
|
#endif
|
|
-
|
|
#endif /* BES2600_HWIO_H_INCLUDED */
|
|
--
|
|
2.34.1
|
|
|