build/patch/kernel/archive/sunxi-6.5/patches.megous/bes2600-Update-the-wifi-driver-from-bestechnic-0.3.5_2023.0209.patch

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