2017-06-20 00:32:25

by Larry Finger

[permalink] [raw]
Subject: [PATCH 00/10] Set 2 of changes related to updates of btcoexist

To get maximum benefit of the recent changes in btcoexist, changes need
to be made in the drivers for the NIC. This is set 2 of those changes.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>


Ping-Ke Shih (10):
rtlwifi: Fix a2dp choppy while BT RSSI stays on threshold.
rtlwifi: Do IQK only once to reduce wifi occupy antenna
rtlwifi: Modify power mode parameters of 8723be and 8821ae.
rtlwifi: Update some cases in btc_get function -- roam, 5G, AP mode,
and return value.
rtlwifi: Add return value to btc_set.
rtlwifi: Add ap_num field for btcoexist
rtlwifi: Fill ap_num filed by vendor command
rtlwifi: Fill ap_num field by driver
rtlwifi: Add in_4way field for btcoexist
rtlwifi: Fill in_4way field by vendor command

drivers/net/wireless/realtek/rtlwifi/base.c | 194 +++++++++++++++++++++
drivers/net/wireless/realtek/rtlwifi/base.h | 2 +
.../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 36 ++--
drivers/net/wireless/realtek/rtlwifi/core.c | 3 +
drivers/net/wireless/realtek/rtlwifi/debug.h | 1 +
drivers/net/wireless/realtek/rtlwifi/pci.c | 4 +
drivers/net/wireless/realtek/rtlwifi/ps.c | 14 +-
.../net/wireless/realtek/rtlwifi/rtl8192ee/fw.c | 10 +-
.../net/wireless/realtek/rtlwifi/rtl8192ee/hw.c | 3 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/fw.c | 8 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 7 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/phy.c | 3 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 10 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 4 +-
drivers/net/wireless/realtek/rtlwifi/wifi.h | 16 ++
16 files changed, 285 insertions(+), 34 deletions(-)

--
2.12.3


2017-06-20 00:32:28

by Larry Finger

[permalink] [raw]
Subject: [PATCH 03/10] rtlwifi: Modify power mode parameters of 8723be and 8821ae.

From: Ping-Ke Shih <[email protected]>

Change the parameters suggested by FW.
awake int: 2
smart_ps: 2 or 0
ps_mode: 2 (MAX -- every DTIM)

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 4 ++--
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
index 8c0ac96b5430..f9d10f1e7cf8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
@@ -155,8 +155,8 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->cfg->mod_params->disable_watchdog;
if (rtlpriv->cfg->mod_params->disable_watchdog)
pr_info("watchdog disabled\n");
- rtlpriv->psc.reg_fwctrl_lps = 3;
- rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+ rtlpriv->psc.reg_fwctrl_lps = 2;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 2;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0
*/
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
index abaf34cb1433..d71d2776ca03 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
@@ -172,8 +172,8 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->cfg->mod_params->disable_watchdog;
if (rtlpriv->cfg->mod_params->disable_watchdog)
pr_info("watchdog disabled\n");
- rtlpriv->psc.reg_fwctrl_lps = 3;
- rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+ rtlpriv->psc.reg_fwctrl_lps = 2;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 2;

/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0
--
2.12.3

2017-06-20 00:32:26

by Larry Finger

[permalink] [raw]
Subject: [PATCH 01/10] rtlwifi: Fix a2dp choppy while BT RSSI stays on threshold.

From: Ping-Ke Shih <[email protected]>

In this case, BTC asks to enter/leave PS mode frequently to cause A2DP
choppy.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/ps.c | 14 ++++++++------
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c | 10 ++++++++--
drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c | 8 ++++++--
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 10 ++++++++--
4 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 0d152877d969..07ee3096f50e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -356,7 +356,7 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
if (mac->link_state != MAC80211_LINKED)
return;

- if (ppsc->dot11_psmode == rt_psmode)
+ if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE)
return;

/* Update power save mode configured. */
@@ -438,11 +438,13 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw)

spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);

- if (ppsc->dot11_psmode == EACTIVE) {
- RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
- "Enter 802.11 power save mode...\n");
- rtl_lps_set_psmode(hw, EAUTOPS);
- }
+ /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because
+ * bt_ccoexist may ask to enter lps.
+ * In normal case, this constraint move to rtl_lps_set_psmode().
+ */
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ "Enter 802.11 power save mode...\n");
+ rtl_lps_set_psmode(hw, EAUTOPS);

spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
index 2ba9e613a7f6..f4ee7906eb20 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
@@ -427,6 +427,11 @@ void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
+ bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
+ btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
+
+ if (bt_ctrl_lps)
+ mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);

RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
mode, bt_ctrl_lps);
@@ -482,8 +487,9 @@ void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
- (rtlpriv->mac80211.p2p) ?
- ppsc->smart_ps : 1);
+ bt_ctrl_lps ? 0 :
+ ((rtlpriv->mac80211.p2p) ?
+ ppsc->smart_ps : 1));
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
awake_intvl);
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
index a37eb27cefe6..95b2e9a87d20 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
@@ -245,6 +245,11 @@ void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
+ bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
+ btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
+
+ if (bt_ctrl_lps)
+ mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);

RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
mode, bt_ctrl_lps);
@@ -300,8 +305,7 @@ void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
- (rtlpriv->mac80211.p2p) ?
- ppsc->smart_ps : 1);
+ bt_ctrl_lps ? 0 : ppsc->smart_ps);
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
awake_intvl);
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
index cc03f9813824..97401aa4dacb 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
@@ -494,6 +494,11 @@ void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
+ bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
+ btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
+
+ if (bt_ctrl_lps)
+ mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);

RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
mode, bt_ctrl_lps);
@@ -549,8 +554,9 @@ void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
- (rtlpriv->mac80211.p2p) ?
- ppsc->smart_ps : 1);
+ bt_ctrl_lps ? 0 :
+ ((rtlpriv->mac80211.p2p) ?
+ ppsc->smart_ps : 1));
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
awake_intvl);
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
--
2.12.3

2017-06-20 00:32:31

by Larry Finger

[permalink] [raw]
Subject: [PATCH 06/10] rtlwifi: Add ap_num field for btcoexist

From: Ping-Ke Shih <[email protected]>

If there are many AP (dirty environment), we use another strategy set
to resolve coex issue.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 5 +----
drivers/net/wireless/realtek/rtlwifi/pci.c | 1 +
drivers/net/wireless/realtek/rtlwifi/wifi.h | 2 ++
3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index ffa7a517b665..9dbb35f190d1 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -503,10 +503,7 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
ret = false;
break;
case BTC_GET_U1_AP_NUM:
- /* driver do not know AP num,
- * so the return value here is not right
- */
- *u8_tmp = 1;
+ *u8_tmp = rtlpriv->btcoexist.btc_info.ap_num;
break;
case BTC_GET_U1_ANT_TYPE:
*u8_tmp = (u8)BTC_ANT_TYPE_0;
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 2e6b888bd417..00a354c85ece 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -1826,6 +1826,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
rtlpci->driver_is_goingto_unload = false;
if (rtlpriv->cfg->ops->get_btc_status &&
rtlpriv->cfg->ops->get_btc_status()) {
+ rtlpriv->btcoexist.btc_info.ap_num = 36;
rtlpriv->btcoexist.btc_ops->btc_init_variables(rtlpriv);
rtlpriv->btcoexist.btc_ops->btc_init_hal_vars(rtlpriv);
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 49c0d2229274..2fb83a7061dd 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2481,6 +2481,8 @@ struct rtl_btc_info {
u8 btcoexist;
u8 ant_num;
u8 single_ant_path;
+
+ u8 ap_num;
};

struct bt_coexist_info {
--
2.12.3

2017-06-20 00:32:34

by Larry Finger

[permalink] [raw]
Subject: [PATCH 09/10] rtlwifi: Add in_4way field for btcoexist

From: Ping-Ke Shih <[email protected]>

If wifi is in 4way, btcoex give wifi higher priority to use antenna.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 3 +--
drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 +
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 9dbb35f190d1..e6024b013ca5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -428,8 +428,7 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
- /* TODO */
- *bool_tmp = false;
+ *bool_tmp = rtlpriv->btcoexist.btc_info.in_4way;
break;
case BTC_GET_BL_WIFI_UNDER_5G:
if (rtlhal->current_bandtype == BAND_ON_5G)
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 98183dc707aa..fb1ebb01133f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2484,6 +2484,7 @@ struct rtl_btc_info {
u8 single_ant_path;

u8 ap_num;
+ bool in_4way;
};

struct bt_coexist_info {
--
2.12.3

2017-06-20 00:32:31

by Larry Finger

[permalink] [raw]
Subject: [PATCH 05/10] rtlwifi: Add return value to btc_set.

From: Ping-Ke Shih <[email protected]>

We will use return value to handle error case.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index d8fb2442f795..ffa7a517b665 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -534,6 +534,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
bool *bool_tmp = (bool *)in_buf;
u8 *u8_tmp = (u8 *)in_buf;
u32 *u32_tmp = (u32 *)in_buf;
+ bool ret = true;

if (!halbtc_is_bt_coexist_available(btcoexist))
return false;
@@ -577,6 +578,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)

/* the following are some action which will be triggered */
case BTC_SET_ACT_GET_BT_RSSI:
+ ret = false;
break;
case BTC_SET_ACT_AGGREGATE_CTRL:
halbtc_aggregation_check(btcoexist);
@@ -622,7 +624,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
break;
}

- return true;
+ return ret;
}

/************************************************************
--
2.12.3

2017-06-20 00:32:27

by Larry Finger

[permalink] [raw]
Subject: [PATCH 02/10] rtlwifi: Do IQK only once to reduce wifi occupy antenna

From: Ping-Ke Shih <[email protected]>

Modify 8723be and 8192e only.
8812/8821 do IQK in DM, so we may do it later.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c | 3 ++-
drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 7 +++++--
drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c | 3 ++-
3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
index 11d97fa0e921..d84ac7adfd82 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
@@ -1670,7 +1670,8 @@ void rtl92ee_card_disable(struct ieee80211_hw *hw)
_rtl92ee_poweroff_adapter(hw);

/* after power off we should do iqk again */
- rtlpriv->phy.iqk_initialized = false;
+ if (!rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->phy.iqk_initialized = false;
}

void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index 0ce2900722f4..2a7ad5ffe997 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -1443,7 +1443,9 @@ int rtl8723be_hw_init(struct ieee80211_hw *hw)
*/
if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
!rtlpriv->cfg->ops->get_btc_status()) {
- rtl8723be_phy_iq_calibrate(hw, false);
+ rtl8723be_phy_iq_calibrate(hw,
+ (rtlphy->iqk_initialized ?
+ true : false));
rtlphy->iqk_initialized = true;
}
rtl8723be_dm_check_txpower_tracking(hw);
@@ -1677,7 +1679,8 @@ void rtl8723be_card_disable(struct ieee80211_hw *hw)
_rtl8723be_poweroff_adapter(hw);

/* after power off we should do iqk again */
- rtlpriv->phy.iqk_initialized = false;
+ if (!rtlpriv->cfg->ops->get_btc_status())
+ rtlpriv->phy.iqk_initialized = false;
}

void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
index ab0f39e46e1b..9752175cc466 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
@@ -2352,7 +2352,7 @@ void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
if (b_recovery) {
rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
rtlphy->iqk_bb_backup, 9);
- return;
+ goto label_done;
}
/* Save RF Path */
path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
@@ -2460,6 +2460,7 @@ void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
/* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */

+label_done:
spin_lock(&rtlpriv->locks.iqk_lock);
rtlphy->lck_inprogress = false;
spin_unlock(&rtlpriv->locks.iqk_lock);
--
2.12.3

2017-06-21 16:34:40

by Kalle Valo

[permalink] [raw]
Subject: Re: [07/10] rtlwifi: Fill ap_num filed by vendor command

Larry Finger <[email protected]> wrote:

> From: Ping-Ke Shih <[email protected]>
>
> The ap_num can be filled by wpa_cli's VENDOR command.
>
> Signed-off-by: Ping-Ke Shih <[email protected]>
> Signed-off-by: Larry Finger <[email protected]>
> Cc: Yan-Hsuan Chuang <[email protected]>
> Cc: Birming Chiu <[email protected]>
> Cc: Shaofu <[email protected]>
> Cc: Steven Ting <[email protected]>

This is a perfect example why I have been against vendor commands in the past.
I already regret changing my mind...

If you want me to seriously consider taking a patch adding a vendor command I
need GOOD justifications why a normal nl80211 command is not suitable and which
are properly documented in the commit log. One sentence definitely
is not enough.

Larry, please drop all patches related to vendor commands in this patch and
resend. Adding vendor commands should be in a separate patchset so it can be
discussed without blocking anything else.

--
https://patchwork.kernel.org/patch/9798295/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2017-06-20 00:32:35

by Larry Finger

[permalink] [raw]
Subject: [PATCH 10/10] rtlwifi: Fill in_4way field by vendor command

From: Ping-Ke Shih <[email protected]>

The in_4way can be filled by wpa_cli's VENDOR command.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/base.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 574f9943d70e..1b81bfa083ed 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -319,6 +319,7 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,

enum {
RTL_VENDOR_SCMD_COEX_AP_NUM = 2000,
+ RTL_VENDOR_SCMD_COEX_4WAY = 2001,
};

static u32 rtl_data_to_int(struct rtl_priv *rtlpriv, const void *data, int len)
@@ -364,6 +365,24 @@ static int rtl_cfgvendor_coex_ap_num(struct wiphy *wiphy,
return 0;
}

+static int rtl_cfgvendor_coex_4way(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool tmp;
+
+ tmp = (rtl_data_to_int(rtlpriv, data, len) ? true : false);
+
+ rtlpriv->btcoexist.btc_info.in_4way = tmp;
+
+ RT_TRACE(rtlpriv, COMP_VENDOR_CMD, DBG_DMESG,
+ "cfgvendor 4way is %d\n", rtlpriv->btcoexist.btc_info.in_4way);
+
+ return 0;
+}
+
static const struct wiphy_vendor_command rtl_vendor_cmds[] = {
{
{
@@ -374,6 +393,15 @@ static const struct wiphy_vendor_command rtl_vendor_cmds[] = {
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = rtl_cfgvendor_coex_ap_num,
},
+ {
+ {
+ .vendor_id = OUI_REALTEK,
+ .subcmd = RTL_VENDOR_SCMD_COEX_4WAY
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = rtl_cfgvendor_coex_4way,
+ },
};

static void _rtl_init_mac80211(struct ieee80211_hw *hw)
--
2.12.3

2017-06-20 00:32:32

by Larry Finger

[permalink] [raw]
Subject: [PATCH 07/10] rtlwifi: Fill ap_num filed by vendor command

From: Ping-Ke Shih <[email protected]>

The ap_num can be filled by wpa_cli's VENDOR command.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/base.c | 64 ++++++++++++++++++++++++++++
drivers/net/wireless/realtek/rtlwifi/debug.h | 1 +
2 files changed, 65 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 180850cb4671..1994125a21b5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -315,6 +315,67 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,
}
}

+#define OUI_REALTEK 0x00E04C
+
+enum {
+ RTL_VENDOR_SCMD_COEX_AP_NUM = 2000,
+};
+
+static u32 rtl_data_to_int(struct rtl_priv *rtlpriv, const void *data, int len)
+{
+ /* wpa_supplicant translates the string '01234567' to binary as
+ * '01 23 45 67', so we treat it as big-endian.
+ */
+ u32 tmp = 0;
+
+ switch (len) {
+ case 1:
+ tmp = *((u8 *)data);
+ break;
+ case 2:
+ tmp = be16_to_cpu(*((__be16 *)data));
+ break;
+ case 4:
+ tmp = be32_to_cpu(*((__be32 *)data));
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_VENDOR_CMD, DBG_WARNING,
+ "length of vendor command is %d\n", len);
+ break;
+ }
+
+ return tmp;
+}
+
+static int rtl_cfgvendor_coex_ap_num(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->btcoexist.btc_info.ap_num =
+ rtl_data_to_int(rtlpriv, data, len);
+
+ RT_TRACE(rtlpriv, COMP_VENDOR_CMD, DBG_DMESG,
+ "cfgvendor ap_num is %d\n",
+ rtlpriv->btcoexist.btc_info.ap_num);
+
+ return 0;
+}
+
+static const struct wiphy_vendor_command rtl_vendor_cmds[] = {
+ {
+ {
+ .vendor_id = OUI_REALTEK,
+ .subcmd = RTL_VENDOR_SCMD_COEX_AP_NUM
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = rtl_cfgvendor_coex_ap_num,
+ },
+};
+
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -323,6 +384,9 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct ieee80211_supported_band *sband;

+ hw->wiphy->vendor_commands = rtl_vendor_cmds;
+ hw->wiphy->n_vendor_commands = ARRAY_SIZE(rtl_vendor_cmds);
+
if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
rtlhal->bandset == BAND_ON_BOTH) {
/* 1: 2.4 G bands */
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index 947718001457..b39e87cc568a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
@@ -106,6 +106,7 @@
#define COMP_BT_COEXIST BIT(30)
#define COMP_IQK BIT(31)
#define COMP_TX_REPORT BIT_ULL(32)
+#define COMP_VENDOR_CMD BIT_ULL(33)

/*--------------------------------------------------------------
Define the rt_print components
--
2.12.3

2017-06-20 00:32:29

by Larry Finger

[permalink] [raw]
Subject: [PATCH 04/10] rtlwifi: Update some cases in btc_get function -- roam, 5G, AP mode, and return value.

From: Ping-Ke Shih <[email protected]>

Return value may be false in some situations.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
.../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 24 +++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index eaa916a0727b..d8fb2442f795 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -381,6 +381,7 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
u32 *u32_tmp = (u32 *)out_buf;
u8 *u8_tmp = (u8 *)out_buf;
bool tmp = false;
+ bool ret = true;

if (!halbtc_is_bt_coexist_available(btcoexist))
return false;
@@ -388,9 +389,11 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
switch (get_type) {
case BTC_GET_BL_HS_OPERATION:
*bool_tmp = false;
+ ret = false;
break;
case BTC_GET_BL_HS_CONNECTING:
*bool_tmp = false;
+ ret = false;
break;
case BTC_GET_BL_WIFI_CONNECTED:
if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
@@ -429,11 +432,16 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_UNDER_5G:
- /* TODO */
- *bool_tmp = false;
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
break;
case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
- *bool_tmp = false;
+ if (mac->opmode == NL80211_IFTYPE_AP)
+ *bool_tmp = true;
+ else
+ *bool_tmp = false;
break;
case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
@@ -460,8 +468,8 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
*s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
break;
case BTC_GET_S4_HS_RSSI:
- /* TODO */
- *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
+ *s32_tmp = 0;
+ ret = false;
break;
case BTC_GET_U4_WIFI_BW:
*u32_tmp = halbtc_get_wifi_bw(btcoexist);
@@ -491,7 +499,8 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
break;
case BTC_GET_U1_WIFI_HS_CHNL:
- *u8_tmp = 1;
+ *u8_tmp = 0;
+ ret = false;
break;
case BTC_GET_U1_AP_NUM:
/* driver do not know AP num,
@@ -512,10 +521,11 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
break;

default:
+ ret = false;
break;
}

- return true;
+ return ret;
}

static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
--
2.12.3

2017-06-20 00:32:33

by Larry Finger

[permalink] [raw]
Subject: [PATCH 08/10] rtlwifi: Fill ap_num field by driver

From: Ping-Ke Shih <[email protected]>

Check beacon and probe_resp frames to know ap_num

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Yan-Hsuan Chuang <[email protected]>
Cc: Birming Chiu <[email protected]>
Cc: Shaofu <[email protected]>
Cc: Steven Ting <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/base.c | 102 ++++++++++++++++++++++++++++
drivers/net/wireless/realtek/rtlwifi/base.h | 2 +
drivers/net/wireless/realtek/rtlwifi/core.c | 3 +
drivers/net/wireless/realtek/rtlwifi/pci.c | 3 +
drivers/net/wireless/realtek/rtlwifi/wifi.h | 13 ++++
5 files changed, 123 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 1994125a21b5..574f9943d70e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -628,6 +628,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
spin_lock_init(&rtlpriv->locks.waitq_lock);
spin_lock_init(&rtlpriv->locks.entry_list_lock);
spin_lock_init(&rtlpriv->locks.c2hcmd_lock);
+ spin_lock_init(&rtlpriv->locks.scan_list_lock);
spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
spin_lock_init(&rtlpriv->locks.check_sendpkt_lock);
spin_lock_init(&rtlpriv->locks.fw_ps_lock);
@@ -636,6 +637,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
/* <5> init list */
INIT_LIST_HEAD(&rtlpriv->entry_list);
INIT_LIST_HEAD(&rtlpriv->c2hcmd_list);
+ INIT_LIST_HEAD(&rtlpriv->scan_list.list);

rtlmac->link_state = MAC80211_NOLINK;

@@ -646,9 +648,12 @@ int rtl_init_core(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL_GPL(rtl_init_core);

+static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw);
+
void rtl_deinit_core(struct ieee80211_hw *hw)
{
rtl_c2hcmd_launcher(hw, 0);
+ rtl_free_entries_from_scan_list(hw);
}
EXPORT_SYMBOL_GPL(rtl_deinit_core);

@@ -1768,6 +1773,100 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(rtl_beacon_statistic);

+static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_bssid_entry *entry, *next;
+
+ list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ rtlpriv->scan_list.num--;
+ }
+}
+
+void rtl_scan_list_expire(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_bssid_entry *entry, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);
+
+ list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {
+ /* 180 seconds */
+ if (jiffies_to_msecs(jiffies - entry->age) < 180000)
+ continue;
+
+ list_del(&entry->list);
+ kfree(entry);
+ rtlpriv->scan_list.num--;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "BSSID=%pM is expire in scan list (total=%d)\n",
+ entry->bssid, rtlpriv->scan_list.num);
+ }
+
+ spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);
+
+ rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;
+}
+
+void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ unsigned long flags;
+
+ struct rtl_bssid_entry *entry;
+ bool entry_found = false;
+
+ /* check if it is scanning */
+ if (!mac->act_scanning)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control) &&
+ !ieee80211_is_probe_resp(hdr->frame_control))
+ return;
+
+ spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);
+
+ list_for_each_entry(entry, &rtlpriv->scan_list.list, list) {
+ if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) {
+ list_del_init(&entry->list);
+ entry_found = true;
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "Update BSSID=%pM to scan list (total=%d)\n",
+ hdr->addr3, rtlpriv->scan_list.num);
+ break;
+ }
+ }
+
+ if (!entry_found) {
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+
+ if (!entry)
+ goto label_err;
+
+ memcpy(entry->bssid, hdr->addr3, ETH_ALEN);
+ rtlpriv->scan_list.num++;
+
+ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "Add BSSID=%pM to scan list (total=%d)\n",
+ hdr->addr3, rtlpriv->scan_list.num);
+ }
+
+ entry->age = jiffies;
+
+ list_add_tail(&entry->list, &rtlpriv->scan_list.list);
+
+label_err:
+ spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);
+}
+EXPORT_SYMBOL(rtl_collect_scan_list);
+
void rtl_watchdog_wq_callback(void *data)
{
struct rtl_works *rtlworks = container_of_dwork_rtl(data,
@@ -1925,6 +2024,9 @@ void rtl_watchdog_wq_callback(void *data)
rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);

rtlpriv->link_info.bcn_rx_inperiod = 0;
+
+ /* <6> scan list */
+ rtl_scan_list_expire(hw);
}

void rtl_watch_dog_timer_callback(unsigned long data)
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h
index 21fa4562f631..ab7d81904d25 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.h
+++ b/drivers/net/wireless/realtek/rtlwifi/base.h
@@ -137,6 +137,8 @@ bool rtl_check_tx_report_acked(struct ieee80211_hw *hw);
void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms);

void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_scan_list_expire(struct ieee80211_hw *hw);
int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index 1a53a95d373b..b0ad061048c5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1464,6 +1464,9 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
mac->act_scanning = false;
mac->skip_scan = false;
+
+ rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;
+
if (rtlpriv->link_info.higher_busytraffic)
return;

diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 00a354c85ece..58f69375fd1c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -881,6 +881,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
if (unicast)
rtlpriv->link_info.num_rx_inperiod++;
}
+
+ rtl_collect_scan_list(hw, skb);
+
/* static bcn for roaming */
rtl_beacon_statistic(hw, skb);
rtl_p2p_info(hw, (void *)skb->data, skb->len);
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 2fb83a7061dd..98183dc707aa 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2333,6 +2333,7 @@ struct rtl_locks {
spinlock_t entry_list_lock;
spinlock_t usb_lock;
spinlock_t c2hcmd_lock;
+ spinlock_t scan_list_lock; /* lock for the scan list */

/*FW clock change */
spinlock_t fw_ps_lock;
@@ -2587,6 +2588,17 @@ struct rtl_c2hcmd {
u8 *val;
};

+struct rtl_bssid_entry {
+ struct list_head list;
+ u8 bssid[ETH_ALEN];
+ u32 age;
+};
+
+struct rtl_scan_list {
+ int num;
+ struct list_head list; /* sort by age */
+};
+
struct rtl_priv {
struct ieee80211_hw *hw;
struct completion firmware_loading_complete;
@@ -2608,6 +2620,7 @@ struct rtl_priv {
struct rtl_efuse efuse;
struct rtl_led_ctl ledctl;
struct rtl_tx_report tx_report;
+ struct rtl_scan_list scan_list;

struct rtl_ps_ctl psc;
struct rate_adaptive ra;
--
2.12.3