All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel
@ 2022-08-09  8:41 Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR Ping-Ke Shih
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

With new flow of hardware scan, it could get wrong channel or causes wrong
driver state. Use this patchset to fix them.

v2:
  - do rebase to the latest wireless-next

Chih-Kang Chang (7):
  wifi: rtw88: add mutex when set SAR
  wifi: rtw88: add mutex when set regulatory and get Tx power table
  wifi: rtw88: add the update channel flow to support setting by
    parameters
  wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan
  wifi: rtw88: add flushing queue before HW scan
  wifi: rtw88: add flag check before enter or leave IPS
  wifi: rtw88: prohibit enter IPS during HW scan

 drivers/net/wireless/realtek/rtw88/debug.c    |  11 +-
 drivers/net/wireless/realtek/rtw88/fw.c       |  41 +++--
 drivers/net/wireless/realtek/rtw88/fw.h       |   2 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c |   7 +-
 drivers/net/wireless/realtek/rtw88/main.c     | 164 +++++++++++-------
 drivers/net/wireless/realtek/rtw88/main.h     |  25 ++-
 drivers/net/wireless/realtek/rtw88/ps.c       |   7 +-
 drivers/net/wireless/realtek/rtw88/regd.c     |   2 +
 8 files changed, 166 insertions(+), 93 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-10  5:49   ` Kalle Valo
  2022-08-09  8:41 ` [PATCH v2 2/7] wifi: rtw88: add mutex when set regulatory and get Tx power table Ping-Ke Shih
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

Applying SAR will access hal data, it should hold rtwdev::mutex
to avoid hal data changed during setting flow.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index b6af199ae5e11..fa6a920fa8054 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -875,7 +875,9 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
 {
 	struct rtw_dev *rtwdev = hw->priv;
 
+	mutex_lock(&rtwdev->mutex);
 	rtw_set_sar_specs(rtwdev, sar);
+	mutex_unlock(&rtwdev->mutex);
 
 	return 0;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/7] wifi: rtw88: add mutex when set regulatory and get Tx power table
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters Ping-Ke Shih
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

Applying regulatory and getting Tx power table will access hal
data, it should hold rtwdev::mutex to avoid hal data changed during
setting flow.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/debug.c | 11 +++++++----
 drivers/net/wireless/realtek/rtw88/regd.c  |  2 ++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 7cde6bcf253b4..9ebe544e51d0d 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -621,11 +621,13 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
 	struct rtw_debugfs_priv *debugfs_priv = m->private;
 	struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
 	struct rtw_hal *hal = &rtwdev->hal;
-	u8 path, rate;
+	u8 path, rate, bw, ch, regd;
 	struct rtw_power_params pwr_param = {0};
-	u8 bw = hal->current_band_width;
-	u8 ch = hal->current_channel;
-	u8 regd = rtw_regd_get(rtwdev);
+
+	mutex_lock(&rtwdev->mutex);
+	bw = hal->current_band_width;
+	ch = hal->current_channel;
+	regd = rtw_regd_get(rtwdev);
 
 	seq_printf(m, "channel: %u\n", ch);
 	seq_printf(m, "bandwidth: %u\n", bw);
@@ -667,6 +669,7 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
 	}
 
 	mutex_unlock(&hal->tx_power_mutex);
+	mutex_unlock(&rtwdev->mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c
index 315c2b193e92c..2f547cbcf6da5 100644
--- a/drivers/net/wireless/realtek/rtw88/regd.c
+++ b/drivers/net/wireless/realtek/rtw88/regd.c
@@ -479,6 +479,7 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 	rtw_dbg(rtwdev, RTW_DBG_REGD, "regd state: %d -> %d\n",
 		rtwdev->regd.state, next_regd.state);
 
+	mutex_lock(&rtwdev->mutex);
 	rtwdev->regd = next_regd;
 	rtw_dbg_regd_dump(rtwdev, "get alpha2 %c%c from initiator %d: ",
 			  request->alpha2[0],
@@ -487,6 +488,7 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 
 	rtw_phy_adaptivity_set_mode(rtwdev);
 	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
+	mutex_unlock(&rtwdev->mutex);
 }
 
 u8 rtw_regd_get(struct rtw_dev *rtwdev)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 2/7] wifi: rtw88: add mutex when set regulatory and get Tx power table Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-13  5:54   ` kernel test robot
  2022-08-09  8:41 ` [PATCH v2 4/7] wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan Ping-Ke Shih
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

In order to set channel info to hal during HW scan, we add the update
channel flow to support setting by parameters to meet the HW scan
requriement.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/main.c | 164 +++++++++++++---------
 drivers/net/wireless/realtek/rtw88/main.h |  24 +++-
 2 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 381f258835a7e..790dcfed1125d 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -675,67 +675,127 @@ void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period)
 	rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1);
 }
 
+void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
+			u8 primary_channel, enum rtw_supported_band band,
+			enum rtw_bandwidth bandwidth)
+{
+	enum nl80211_band nl_band = rtw_hw_to_nl80211_band(band);
+	struct rtw_hal *hal = &rtwdev->hal;
+	u8 *cch_by_bw = hal->cch_by_bw;
+	u32 center_freq, primary_freq;
+	enum rtw_sar_bands sar_band;
+	u8 primary_channel_idx;
+
+	center_freq = ieee80211_channel_to_frequency(center_channel, nl_band);
+	primary_freq = ieee80211_channel_to_frequency(primary_channel, nl_band);
+
+	/* assign the center channel used while 20M bw is selected */
+	cch_by_bw[RTW_CHANNEL_WIDTH_20] = primary_channel;
+
+	/* assign the center channel used while current bw is selected */
+	cch_by_bw[bandwidth] = center_channel;
+
+	switch (bandwidth) {
+	case RTW_CHANNEL_WIDTH_20:
+		primary_channel_idx = RTW_SC_DONT_CARE;
+		break;
+	case RTW_CHANNEL_WIDTH_40:
+		if (primary_freq > center_freq)
+			primary_channel_idx = RTW_SC_20_UPPER;
+		else
+			primary_channel_idx = RTW_SC_20_LOWER;
+		break;
+	case RTW_CHANNEL_WIDTH_80:
+		if (primary_freq > center_freq) {
+			if (primary_freq - center_freq == 10)
+				primary_channel_idx = RTW_SC_20_UPPER;
+			else
+				primary_channel_idx = RTW_SC_20_UPMOST;
+
+			/* assign the center channel used
+			 * while 40M bw is selected
+			 */
+			cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel + 4;
+		} else {
+			if (center_freq - primary_freq == 10)
+				primary_channel_idx = RTW_SC_20_LOWER;
+			else
+				primary_channel_idx = RTW_SC_20_LOWEST;
+
+			/* assign the center channel used
+			 * while 40M bw is selected
+			 */
+			cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel - 4;
+		}
+		break;
+	default:
+		break;
+	}
+
+	switch (center_channel) {
+	case 1 ... 14:
+		sar_band = RTW_SAR_BAND_0;
+		break;
+	case 36 ... 64:
+		sar_band = RTW_SAR_BAND_1;
+		break;
+	case 100 ... 144:
+		sar_band = RTW_SAR_BAND_3;
+		break;
+	case 149 ... 177:
+		sar_band = RTW_SAR_BAND_4;
+		break;
+	default:
+		WARN(1, "unknown ch(%u) to SAR band\n", center_channel);
+		sar_band = RTW_SAR_BAND_0;
+		break;
+	}
+
+	hal->current_primary_channel_index = primary_channel_idx;
+	hal->current_band_width = bandwidth;
+	hal->primary_channel = primary_channel;
+	hal->current_channel = center_channel;
+	hal->current_band_type = band;
+	hal->sar_band = sar_band;
+}
+
 void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
 			    struct rtw_channel_params *chan_params)
 {
 	struct ieee80211_channel *channel = chandef->chan;
 	enum nl80211_chan_width width = chandef->width;
-	u8 *cch_by_bw = chan_params->cch_by_bw;
 	u32 primary_freq, center_freq;
 	u8 center_chan;
 	u8 bandwidth = RTW_CHANNEL_WIDTH_20;
-	u8 primary_chan_idx = 0;
-	u8 i;
 
 	center_chan = channel->hw_value;
 	primary_freq = channel->center_freq;
 	center_freq = chandef->center_freq1;
 
-	/* assign the center channel used while 20M bw is selected */
-	cch_by_bw[RTW_CHANNEL_WIDTH_20] = channel->hw_value;
-
 	switch (width) {
 	case NL80211_CHAN_WIDTH_20_NOHT:
 	case NL80211_CHAN_WIDTH_20:
 		bandwidth = RTW_CHANNEL_WIDTH_20;
-		primary_chan_idx = RTW_SC_DONT_CARE;
 		break;
 	case NL80211_CHAN_WIDTH_40:
 		bandwidth = RTW_CHANNEL_WIDTH_40;
-		if (primary_freq > center_freq) {
-			primary_chan_idx = RTW_SC_20_UPPER;
+		if (primary_freq > center_freq)
 			center_chan -= 2;
-		} else {
-			primary_chan_idx = RTW_SC_20_LOWER;
+		else
 			center_chan += 2;
-		}
 		break;
 	case NL80211_CHAN_WIDTH_80:
 		bandwidth = RTW_CHANNEL_WIDTH_80;
 		if (primary_freq > center_freq) {
-			if (primary_freq - center_freq == 10) {
-				primary_chan_idx = RTW_SC_20_UPPER;
+			if (primary_freq - center_freq == 10)
 				center_chan -= 2;
-			} else {
-				primary_chan_idx = RTW_SC_20_UPMOST;
+			else
 				center_chan -= 6;
-			}
-			/* assign the center channel used
-			 * while 40M bw is selected
-			 */
-			cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan + 4;
 		} else {
-			if (center_freq - primary_freq == 10) {
-				primary_chan_idx = RTW_SC_20_LOWER;
+			if (center_freq - primary_freq == 10)
 				center_chan += 2;
-			} else {
-				primary_chan_idx = RTW_SC_20_LOWEST;
+			else
 				center_chan += 6;
-			}
-			/* assign the center channel used
-			 * while 40M bw is selected
-			 */
-			cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan - 4;
 		}
 		break;
 	default:
@@ -745,13 +805,7 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
 
 	chan_params->center_chan = center_chan;
 	chan_params->bandwidth = bandwidth;
-	chan_params->primary_chan_idx = primary_chan_idx;
-
-	/* assign the center channel used while current bw is selected */
-	cch_by_bw[bandwidth] = center_chan;
-
-	for (i = bandwidth + 1; i <= RTW_MAX_CHANNEL_WIDTH; i++)
-		cch_by_bw[i] = 0;
+	chan_params->primary_chan = channel->hw_value;
 }
 
 void rtw_set_channel(struct rtw_dev *rtwdev)
@@ -760,45 +814,21 @@ void rtw_set_channel(struct rtw_dev *rtwdev)
 	struct ieee80211_hw *hw = rtwdev->hw;
 	struct rtw_hal *hal = &rtwdev->hal;
 	struct rtw_channel_params ch_param;
-	u8 center_chan, bandwidth, primary_chan_idx;
-	u8 i;
+	u8 center_chan, primary_chan, bandwidth, band;
 
 	rtw_get_channel_params(&hw->conf.chandef, &ch_param);
 	if (WARN(ch_param.center_chan == 0, "Invalid channel\n"))
 		return;
 
 	center_chan = ch_param.center_chan;
+	primary_chan = ch_param.primary_chan;
 	bandwidth = ch_param.bandwidth;
-	primary_chan_idx = ch_param.primary_chan_idx;
-
-	hal->current_band_width = bandwidth;
-	hal->current_channel = center_chan;
-	hal->current_primary_channel_index = primary_chan_idx;
-	hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
-
-	switch (center_chan) {
-	case 1 ... 14:
-		hal->sar_band = RTW_SAR_BAND_0;
-		break;
-	case 36 ... 64:
-		hal->sar_band = RTW_SAR_BAND_1;
-		break;
-	case 100 ... 144:
-		hal->sar_band = RTW_SAR_BAND_3;
-		break;
-	case 149 ... 177:
-		hal->sar_band = RTW_SAR_BAND_4;
-		break;
-	default:
-		WARN(1, "unknown ch(%u) to SAR band\n", center_chan);
-		hal->sar_band = RTW_SAR_BAND_0;
-		break;
-	}
+	band = ch_param.center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
 
-	for (i = RTW_CHANNEL_WIDTH_20; i <= RTW_MAX_CHANNEL_WIDTH; i++)
-		hal->cch_by_bw[i] = ch_param.cch_by_bw[i];
+	rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth);
 
-	chip->ops->set_channel(rtwdev, center_chan, bandwidth, primary_chan_idx);
+	chip->ops->set_channel(rtwdev, center_chan, bandwidth,
+			       hal->current_primary_channel_index);
 
 	if (hal->current_band_type == RTW_BAND_5G) {
 		rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index b3a7969b2b81c..e15d35f2c5957 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -510,12 +510,8 @@ struct rtw_timer_list {
 
 struct rtw_channel_params {
 	u8 center_chan;
+	u8 primary_chan;
 	u8 bandwidth;
-	u8 primary_chan_idx;
-	/* center channel by different available bandwidth,
-	 * val of (bw > current bandwidth) is invalid
-	 */
-	u8 cch_by_bw[RTW_MAX_CHANNEL_WIDTH + 1];
 };
 
 struct rtw_hw_reg {
@@ -1898,6 +1894,7 @@ struct rtw_hal {
 	u8 current_primary_channel_index;
 	u8 current_band_width;
 	u8 current_band_type;
+	u8 primary_channel;
 
 	/* center channel for different available bandwidth,
 	 * val of (bw > current_band_width) is invalid
@@ -2134,6 +2131,20 @@ static inline int rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev)
 	return 0;
 }
 
+static inline
+enum nl80211_band rtw_hw_to_nl80211_band(enum rtw_supported_band hw_band)
+{
+	switch (hw_band) {
+	default:
+	case RTW_BAND_2G:
+		return NL80211_BAND_2GHZ;
+	case RTW_BAND_5G:
+		return NL80211_BAND_5GHZ;
+	case RTW_BAND_60G:
+		return NL80211_BAND_60GHZ;
+	}
+}
+
 void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel);
 void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period);
 void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
@@ -2175,4 +2186,7 @@ int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
 		u32 fwcd_item);
 int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size);
 void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool config_1ss);
+void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
+			u8 primary_channel, enum rtw_supported_band band,
+			enum rtw_bandwidth bandwidth);
 #endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 4/7] wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2022-08-09  8:41 ` [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 5/7] wifi: rtw88: add flushing queue before " Ping-Ke Shih
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

During HW scan, the channel related feilds in hal struct changed partially.
If setting Tx power will get WARNING:rtw_get_tx_power_params() due to some
of fields in hal struct mismatch. Therefore, we fix to change all required
fields in hal struct when channel switch during HW scan.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c       | 37 +++++++++++++------
 drivers/net/wireless/realtek/rtw88/fw.h       |  2 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c |  2 +-
 drivers/net/wireless/realtek/rtw88/main.h     |  1 +
 4 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index c08220ae65fe1..992cae1b05fbb 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -14,6 +14,7 @@
 #include "util.h"
 #include "wow.h"
 #include "ps.h"
+#include "phy.h"
 
 static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
 				      struct sk_buff *skb)
@@ -2087,10 +2088,9 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 	rtw_core_scan_complete(rtwdev, vif, true);
 
 	rtwvif = (struct rtw_vif *)vif->drv_priv;
-	if (chan) {
-		hal->current_channel = chan;
-		hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
-	}
+	if (chan)
+		rtw_store_op_chan(rtwdev, false);
+	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
 	ieee80211_wake_queues(rtwdev->hw);
 	ieee80211_scan_completed(rtwdev->hw, &info);
 
@@ -2179,14 +2179,23 @@ void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb)
 		rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, "HW scan aborted with code: %d\n", rc);
 }
 
-void rtw_store_op_chan(struct rtw_dev *rtwdev)
+void rtw_store_op_chan(struct rtw_dev *rtwdev, bool backup)
 {
 	struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info;
 	struct rtw_hal *hal = &rtwdev->hal;
+	u8 band;
 
-	scan_info->op_chan = hal->current_channel;
-	scan_info->op_bw = hal->current_band_width;
-	scan_info->op_pri_ch_idx = hal->current_primary_channel_index;
+	if (backup) {
+		scan_info->op_chan = hal->current_channel;
+		scan_info->op_bw = hal->current_band_width;
+		scan_info->op_pri_ch_idx = hal->current_primary_channel_index;
+		scan_info->op_pri_ch = hal->primary_channel;
+	} else {
+		band = scan_info->op_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
+		rtw_update_channel(rtwdev, scan_info->op_chan,
+				   scan_info->op_pri_ch,
+				   band, scan_info->op_bw);
+	}
 }
 
 void rtw_clear_op_chan(struct rtw_dev *rtwdev)
@@ -2196,6 +2205,7 @@ void rtw_clear_op_chan(struct rtw_dev *rtwdev)
 	scan_info->op_chan = 0;
 	scan_info->op_bw = 0;
 	scan_info->op_pri_ch_idx = 0;
+	scan_info->op_pri_ch = 0;
 }
 
 static bool rtw_is_op_chan(struct rtw_dev *rtwdev, u8 channel)
@@ -2210,7 +2220,7 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb)
 	struct rtw_hal *hal = &rtwdev->hal;
 	struct rtw_c2h_cmd *c2h;
 	enum rtw_scan_notify_id id;
-	u8 chan, status;
+	u8 chan, band, status;
 
 	if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
 		return;
@@ -2221,10 +2231,13 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb)
 	status = GET_CHAN_SWITCH_STATUS(c2h->payload);
 
 	if (id == RTW_SCAN_NOTIFY_ID_POSTSWITCH) {
-		if (rtw_is_op_chan(rtwdev, chan))
+		band = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
+		rtw_update_channel(rtwdev, chan, chan, band,
+				   RTW_CHANNEL_WIDTH_20);
+		if (rtw_is_op_chan(rtwdev, chan)) {
+			rtw_store_op_chan(rtwdev, false);
 			ieee80211_wake_queues(rtwdev->hw);
-		hal->current_channel = chan;
-		hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
+		}
 	} else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) {
 		if (IS_CH_5G_BAND(chan)) {
 			rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G);
diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index 20c56e0312c1e..a5a965803a3cc 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -847,7 +847,7 @@ int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size,
 		     u32 *buffer);
 void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start);
 void rtw_fw_adaptivity(struct rtw_dev *rtwdev);
-void rtw_store_op_chan(struct rtw_dev *rtwdev);
+void rtw_store_op_chan(struct rtw_dev *rtwdev, bool backup);
 void rtw_clear_op_chan(struct rtw_dev *rtwdev);
 void rtw_hw_scan_start(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 		       struct ieee80211_scan_request *req);
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index fa6a920fa8054..ef60041fe6bf6 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -397,7 +397,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 		if (is_zero_ether_addr(rtwvif->bssid))
 			rtw_clear_op_chan(rtwdev);
 		else
-			rtw_store_op_chan(rtwdev);
+			rtw_store_op_chan(rtwdev, true);
 	}
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index e15d35f2c5957..bccd7b28f60c7 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1966,6 +1966,7 @@ struct rtw_hw_scan_info {
 	struct ieee80211_vif *scanning_vif;
 	u8 probe_pg_size;
 	u8 op_pri_ch_idx;
+	u8 op_pri_ch;
 	u8 op_chan;
 	u8 op_bw;
 };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 5/7] wifi: rtw88: add flushing queue before HW scan
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2022-08-09  8:41 ` [PATCH v2 4/7] wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 6/7] wifi: rtw88: add flag check before enter or leave IPS Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 7/7] wifi: rtw88: prohibit enter IPS during HW scan Ping-Ke Shih
  6 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

We need to flush queue before HW scan to avoid packets dropped by hardware.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 992cae1b05fbb..babba68a71325 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -15,6 +15,7 @@
 #include "wow.h"
 #include "ps.h"
 #include "phy.h"
+#include "mac.h"
 
 static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
 				      struct sk_buff *skb)
@@ -2056,6 +2057,9 @@ void rtw_hw_scan_start(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 	rtwvif->scan_req = req;
 
 	ieee80211_stop_queues(rtwdev->hw);
+	rtw_leave_lps_deep(rtwdev);
+	rtw_hci_flush_all_queues(rtwdev, false);
+	rtw_mac_flush_all_queues(rtwdev, false);
 	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
 		get_random_mask_addr(mac_addr, req->mac_addr,
 				     req->mac_addr_mask);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 6/7] wifi: rtw88: add flag check before enter or leave IPS
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2022-08-09  8:41 ` [PATCH v2 5/7] wifi: rtw88: add flushing queue before " Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  2022-08-09  8:41 ` [PATCH v2 7/7] wifi: rtw88: prohibit enter IPS during HW scan Ping-Ke Shih
  6 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

Enter or leave IPS controlled by mac80211 before driver support HW
scan. After support HW scan, driver need to control IPS before start
HW scan and scan complete, but mac80211 also ask driver enter or leave
IPS. Therefore, we add flag check in IPS to prevent entering or
leaving IPS twice.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/ps.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c
index bfa64c038f5f0..c93da743681fc 100644
--- a/drivers/net/wireless/realtek/rtw88/ps.c
+++ b/drivers/net/wireless/realtek/rtw88/ps.c
@@ -19,14 +19,14 @@ static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
 		rtw_err(rtwdev, "leave idle state failed\n");
 
 	rtw_set_channel(rtwdev);
-	clear_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);
 
 	return ret;
 }
 
 int rtw_enter_ips(struct rtw_dev *rtwdev)
 {
-	set_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);
+	if (test_and_set_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags))
+		return 0;
 
 	rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER);
 
@@ -50,6 +50,9 @@ int rtw_leave_ips(struct rtw_dev *rtwdev)
 {
 	int ret;
 
+	if (!test_and_clear_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags))
+		return 0;
+
 	rtw_hci_link_ps(rtwdev, false);
 
 	ret = rtw_ips_pwr_up(rtwdev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 7/7] wifi: rtw88: prohibit enter IPS during HW scan
  2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
                   ` (5 preceding siblings ...)
  2022-08-09  8:41 ` [PATCH v2 6/7] wifi: rtw88: add flag check before enter or leave IPS Ping-Ke Shih
@ 2022-08-09  8:41 ` Ping-Ke Shih
  6 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2022-08-09  8:41 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: gary.chang, linux-wireless

From: Chih-Kang Chang <gary.chang@realtek.com>

Mac80211 core may ask driver to change to idle mode during HW scan,
then H2C command for HW scan will send failed since chip is in idle
mode. Therefore, We check the SCANNING flag before entering IPS to
prevent this behavior.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index ef60041fe6bf6..07578ccc4bab3 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -101,7 +101,8 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
 		rtw_set_channel(rtwdev);
 
 	if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
-	    (hw->conf.flags & IEEE80211_CONF_IDLE))
+	    (hw->conf.flags & IEEE80211_CONF_IDLE) &&
+	    !test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
 		rtw_enter_ips(rtwdev);
 
 out:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR
  2022-08-09  8:41 ` [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR Ping-Ke Shih
@ 2022-08-10  5:49   ` Kalle Valo
  0 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2022-08-10  5:49 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: tony0620emma, gary.chang, linux-wireless

Ping-Ke Shih <pkshih@realtek.com> wrote:

> From: Chih-Kang Chang <gary.chang@realtek.com>
> 
> Applying SAR will access hal data, it should hold rtwdev::mutex
> to avoid hal data changed during setting flow.
> 
> Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

7 patches applied to wireless-next.git, thanks.

9a72db413385 wifi: rtw88: add mutex when set SAR
685b474b7d8a wifi: rtw88: add mutex when set regulatory and get Tx power table
341dd1f7de4c wifi: rtw88: add the update channel flow to support setting by parameters
68c539144397 wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan
d08458b57a50 wifi: rtw88: add flushing queue before HW scan
6bf3a083407b wifi: rtw88: add flag check before enter or leave IPS
7dad3e39fde1 wifi: rtw88: prohibit enter IPS during HW scan

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220809084107.38137-2-pkshih@realtek.com/

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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters
  2022-08-09  8:41 ` [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters Ping-Ke Shih
@ 2022-08-13  5:54   ` kernel test robot
  0 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2022-08-13  5:54 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: llvm, kbuild-all

Hi Ping-Ke,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main linus/master v5.19 next-20220812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ping-Ke-Shih/wifi-rtw88-add-proper-mutex-lock-to-safely-access-channel/20220809-164550
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
config: i386-randconfig-a012-20220808 (https://download.01.org/0day-ci/archive/20220813/202208131336.sIxFnpKS-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 5f1c7e2cc5a3c07cbc2412e851a7283c1841f520)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/3843bb3c07b213146fba1ec4f02a694498228d84
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ping-Ke-Shih/wifi-rtw88-add-proper-mutex-lock-to-safely-access-channel/20220809-164550
        git checkout 3843bb3c07b213146fba1ec4f02a694498228d84
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/net/wireless/realtek/rtw88/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/wireless/realtek/rtw88/main.c:731:2: warning: variable 'primary_channel_idx' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
           default:
           ^~~~~~~
   drivers/net/wireless/realtek/rtw88/main.c:754:39: note: uninitialized use occurs here
           hal->current_primary_channel_index = primary_channel_idx;
                                                ^~~~~~~~~~~~~~~~~~~
   drivers/net/wireless/realtek/rtw88/main.c:687:24: note: initialize the variable 'primary_channel_idx' to silence this warning
           u8 primary_channel_idx;
                                 ^
                                  = '\0'
   1 warning generated.


vim +/primary_channel_idx +731 drivers/net/wireless/realtek/rtw88/main.c

   677	
   678	void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
   679				u8 primary_channel, enum rtw_supported_band band,
   680				enum rtw_bandwidth bandwidth)
   681	{
   682		enum nl80211_band nl_band = rtw_hw_to_nl80211_band(band);
   683		struct rtw_hal *hal = &rtwdev->hal;
   684		u8 *cch_by_bw = hal->cch_by_bw;
   685		u32 center_freq, primary_freq;
   686		enum rtw_sar_bands sar_band;
   687		u8 primary_channel_idx;
   688	
   689		center_freq = ieee80211_channel_to_frequency(center_channel, nl_band);
   690		primary_freq = ieee80211_channel_to_frequency(primary_channel, nl_band);
   691	
   692		/* assign the center channel used while 20M bw is selected */
   693		cch_by_bw[RTW_CHANNEL_WIDTH_20] = primary_channel;
   694	
   695		/* assign the center channel used while current bw is selected */
   696		cch_by_bw[bandwidth] = center_channel;
   697	
   698		switch (bandwidth) {
   699		case RTW_CHANNEL_WIDTH_20:
   700			primary_channel_idx = RTW_SC_DONT_CARE;
   701			break;
   702		case RTW_CHANNEL_WIDTH_40:
   703			if (primary_freq > center_freq)
   704				primary_channel_idx = RTW_SC_20_UPPER;
   705			else
   706				primary_channel_idx = RTW_SC_20_LOWER;
   707			break;
   708		case RTW_CHANNEL_WIDTH_80:
   709			if (primary_freq > center_freq) {
   710				if (primary_freq - center_freq == 10)
   711					primary_channel_idx = RTW_SC_20_UPPER;
   712				else
   713					primary_channel_idx = RTW_SC_20_UPMOST;
   714	
   715				/* assign the center channel used
   716				 * while 40M bw is selected
   717				 */
   718				cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel + 4;
   719			} else {
   720				if (center_freq - primary_freq == 10)
   721					primary_channel_idx = RTW_SC_20_LOWER;
   722				else
   723					primary_channel_idx = RTW_SC_20_LOWEST;
   724	
   725				/* assign the center channel used
   726				 * while 40M bw is selected
   727				 */
   728				cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel - 4;
   729			}
   730			break;
 > 731		default:
   732			break;
   733		}
   734	
   735		switch (center_channel) {
   736		case 1 ... 14:
   737			sar_band = RTW_SAR_BAND_0;
   738			break;
   739		case 36 ... 64:
   740			sar_band = RTW_SAR_BAND_1;
   741			break;
   742		case 100 ... 144:
   743			sar_band = RTW_SAR_BAND_3;
   744			break;
   745		case 149 ... 177:
   746			sar_band = RTW_SAR_BAND_4;
   747			break;
   748		default:
   749			WARN(1, "unknown ch(%u) to SAR band\n", center_channel);
   750			sar_band = RTW_SAR_BAND_0;
   751			break;
   752		}
   753	
   754		hal->current_primary_channel_index = primary_channel_idx;
   755		hal->current_band_width = bandwidth;
   756		hal->primary_channel = primary_channel;
   757		hal->current_channel = center_channel;
   758		hal->current_band_type = band;
   759		hal->sar_band = sar_band;
   760	}
   761	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-08-13  5:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-09  8:41 [PATCH v2 0/7] wifi: rtw88: add proper mutex lock to safely access channel Ping-Ke Shih
2022-08-09  8:41 ` [PATCH v2 1/7] wifi: rtw88: add mutex when set SAR Ping-Ke Shih
2022-08-10  5:49   ` Kalle Valo
2022-08-09  8:41 ` [PATCH v2 2/7] wifi: rtw88: add mutex when set regulatory and get Tx power table Ping-Ke Shih
2022-08-09  8:41 ` [PATCH v2 3/7] wifi: rtw88: add the update channel flow to support setting by parameters Ping-Ke Shih
2022-08-13  5:54   ` kernel test robot
2022-08-09  8:41 ` [PATCH v2 4/7] wifi: rtw88: fix WARNING:rtw_get_tx_power_params() during HW scan Ping-Ke Shih
2022-08-09  8:41 ` [PATCH v2 5/7] wifi: rtw88: add flushing queue before " Ping-Ke Shih
2022-08-09  8:41 ` [PATCH v2 6/7] wifi: rtw88: add flag check before enter or leave IPS Ping-Ke Shih
2022-08-09  8:41 ` [PATCH v2 7/7] wifi: rtw88: prohibit enter IPS during HW scan Ping-Ke Shih

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.