linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] wifi: rtw88: support single channel concurrency
@ 2023-04-01 12:44 Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 1/7] wifi: rtw88: add bitmap for dynamic port settings Ping-Ke Shih
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

To support SCC (1 STA + 1 AP), we need to deal some hardware things:
 1. AP mode only can work on hardware port 0
 2. adjust and enlarge reserved pages for two VIFs

Other things are to coordinate two VIFs work well to prevent interference
with each other, like scan thing.

Po-Hao Huang (7):
  wifi: rtw88: add bitmap for dynamic port settings
  wifi: rtw88: add port switch for AP mode
  wifi: rtw88: 8822c: extend reserved page number
  wifi: rtw88: disallow scan and PS during AP mode
  wifi: rtw88: refine reserved page flow for AP mode
  wifi: rtw88: prevent scan abort with other VIFs
  wifi: rtw88: 8822c: add iface combination

 drivers/net/wireless/realtek/rtw88/fw.c       |   9 +-
 drivers/net/wireless/realtek/rtw88/fw.h       |   2 +-
 drivers/net/wireless/realtek/rtw88/mac.c      |   2 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c |  38 ++++++-
 drivers/net/wireless/realtek/rtw88/main.c     | 107 +++++++++++++++++-
 drivers/net/wireless/realtek/rtw88/main.h     |  13 +++
 drivers/net/wireless/realtek/rtw88/rtw8723d.c |   1 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c |   1 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c |   1 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c |   1 +
 10 files changed, 165 insertions(+), 10 deletions(-)

-- 
2.25.1


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

* [PATCH 1/7] wifi: rtw88: add bitmap for dynamic port settings
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 2/7] wifi: rtw88: add port switch for AP mode Ping-Ke Shih
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

In order to support multiple interfaces, multiple port settings will
be required. Current code always uses port 0 and should be changed.
Declare a bitmap with size equal to hardware port number to record
the current usage.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 13 ++++++++++---
 drivers/net/wireless/realtek/rtw88/main.c     |  1 +
 drivers/net/wireless/realtek/rtw88/main.h     | 10 ++++++++++
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 3b92ac611d3fd..d026094a72c40 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -155,25 +155,30 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
 	enum rtw_net_type net_type;
 	u32 config = 0;
-	u8 port = 0;
+	u8 port;
 	u8 bcn_ctrl = 0;
 
 	if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER))
 		vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
 				     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
-	rtwvif->port = port;
 	rtwvif->stats.tx_unicast = 0;
 	rtwvif->stats.rx_unicast = 0;
 	rtwvif->stats.tx_cnt = 0;
 	rtwvif->stats.rx_cnt = 0;
 	rtwvif->scan_req = NULL;
 	memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee));
-	rtwvif->conf = &rtw_vif_port[port];
 	rtw_txq_init(rtwdev, vif->txq);
 	INIT_LIST_HEAD(&rtwvif->rsvd_page_list);
 
 	mutex_lock(&rtwdev->mutex);
 
+	port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM);
+	if (port >= RTW_PORT_NUM)
+		return -EINVAL;
+	set_bit(port, rtwdev->hw_port);
+
+	rtwvif->port = port;
+	rtwvif->conf = &rtw_vif_port[port];
 	rtw_leave_lps_deep(rtwdev);
 
 	switch (vif->type) {
@@ -195,6 +200,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
 		break;
 	default:
 		WARN_ON(1);
+		clear_bit(rtwvif->port, rtwdev->hw_port);
 		mutex_unlock(&rtwdev->mutex);
 		return -EINVAL;
 	}
@@ -236,6 +242,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
 	rtwvif->bcn_ctrl = 0;
 	config |= PORT_SET_BCN_CTRL;
 	rtw_vif_port_config(rtwdev, rtwvif, config);
+	clear_bit(rtwvif->port, rtwdev->hw_port);
 
 	mutex_unlock(&rtwdev->mutex);
 }
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index b2e78737bd5d0..39b18c7468c9e 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -609,6 +609,7 @@ static void __fw_recovery_work(struct rtw_dev *rtwdev)
 	rcu_read_unlock();
 	rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev);
 	rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev);
+	bitmap_zero(rtwdev->hw_port, RTW_PORT_NUM);
 	rtw_enter_ips(rtwdev);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index d4a53d5567451..efac271497f5b 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -395,6 +395,15 @@ enum rtw_snr {
 	RTW_SNR_NUM
 };
 
+enum rtw_port {
+	RTW_PORT_0 = 0,
+	RTW_PORT_1 = 1,
+	RTW_PORT_2 = 2,
+	RTW_PORT_3 = 3,
+	RTW_PORT_4 = 4,
+	RTW_PORT_NUM
+};
+
 enum rtw_wow_flags {
 	RTW_WOW_FLAG_EN_MAGIC_PKT,
 	RTW_WOW_FLAG_EN_REKEY_PKT,
@@ -2036,6 +2045,7 @@ struct rtw_dev {
 	u8 sta_cnt;
 	u32 rts_threshold;
 
+	DECLARE_BITMAP(hw_port, RTW_PORT_NUM);
 	DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM);
 	DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS);
 
-- 
2.25.1


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

* [PATCH 2/7] wifi: rtw88: add port switch for AP mode
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 1/7] wifi: rtw88: add bitmap for dynamic port settings Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-12 12:35   ` Kalle Valo
  2023-04-01 12:44 ` [PATCH 3/7] wifi: rtw88: 8822c: extend reserved page number Ping-Ke Shih
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

Switch port settings if AP mode does not start on port 0 because of
hardware limitation. For some ICs, beacons on ports other than zero
could misbehave and do not issue properly, to fix this we change AP
VIFs to port zero when multiple interfaces is active.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c |  1 +
 drivers/net/wireless/realtek/rtw88/main.c     | 79 +++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/main.h     |  1 +
 3 files changed, 81 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index d026094a72c40..19c4d7c29759e 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -212,6 +212,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
 	rtwvif->bcn_ctrl = bcn_ctrl;
 	config |= PORT_SET_BCN_CTRL;
 	rtw_vif_port_config(rtwdev, rtwvif, config);
+	rtw_core_port_switch(rtwdev, vif);
 
 	mutex_unlock(&rtwdev->mutex);
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 39b18c7468c9e..ba05a5d68d05e 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2244,6 +2244,85 @@ void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 }
 EXPORT_SYMBOL(rtw_unregister_hw);
 
+static
+void rtw_swap_reg_nbytes(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1,
+			 const struct rtw_hw_reg *reg2, u8 nbytes)
+{
+	u8 i;
+
+	for (i = 0; i < nbytes; i++) {
+		u8 v1 = rtw_read8(rtwdev, reg1->addr + i);
+		u8 v2 = rtw_read8(rtwdev, reg2->addr + i);
+
+		rtw_write8(rtwdev, reg1->addr + i, v2);
+		rtw_write8(rtwdev, reg2->addr + i, v1);
+	}
+}
+
+static
+void rtw_swap_reg_mask(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1,
+		       const struct rtw_hw_reg *reg2)
+{
+	u32 v1, v2;
+
+	v1 = rtw_read32_mask(rtwdev, reg1->addr, reg1->mask);
+	v2 = rtw_read32_mask(rtwdev, reg2->addr, reg2->mask);
+	rtw_write32_mask(rtwdev, reg2->addr, reg2->mask, v1);
+	rtw_write32_mask(rtwdev, reg1->addr, reg1->mask, v2);
+}
+
+struct rtw_iter_port_switch_data {
+	struct rtw_dev *rtwdev;
+	struct rtw_vif *rtwvif_ap;
+};
+
+static void rtw_port_switch_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct rtw_iter_port_switch_data *iter_data = data;
+	struct rtw_dev *rtwdev = iter_data->rtwdev;
+	struct rtw_vif *rtwvif_target = (struct rtw_vif *)vif->drv_priv;
+	struct rtw_vif *rtwvif_ap = iter_data->rtwvif_ap;
+	const struct rtw_hw_reg *reg1, *reg2;
+
+	if (rtwvif_target->port != RTW_PORT_0)
+		return;
+
+	rtw_info(rtwdev, "AP port switch from %d -> %d\n", rtwvif_ap->port,
+		 rtwvif_target->port);
+
+	reg1 = &rtwvif_ap->conf->net_type;
+	reg2 = &rtwvif_target->conf->net_type;
+	rtw_swap_reg_mask(rtwdev, reg1, reg2);
+
+	reg1 = &rtwvif_ap->conf->mac_addr;
+	reg2 = &rtwvif_target->conf->mac_addr;
+	rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN);
+
+	reg1 = &rtwvif_ap->conf->bssid;
+	reg2 = &rtwvif_target->conf->bssid;
+	rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN);
+
+	reg1 = &rtwvif_ap->conf->bcn_ctrl;
+	reg2 = &rtwvif_target->conf->bcn_ctrl;
+	rtw_swap_reg_nbytes(rtwdev, reg1, reg2, 1);
+
+	swap(rtwvif_target->port, rtwvif_ap->port);
+	swap(rtwvif_target->conf, rtwvif_ap->conf);
+}
+
+void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
+{
+	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+	struct rtw_iter_port_switch_data iter_data;
+
+	if (vif->type != NL80211_IFTYPE_AP || rtwvif->port == RTW_PORT_0)
+		return;
+
+	iter_data.rtwdev = rtwdev;
+	iter_data.rtwvif_ap = rtwvif;
+	rtw_iterate_vifs(rtwdev, rtw_port_switch_iter, &iter_data);
+}
+
 MODULE_AUTHOR("Realtek Corporation");
 MODULE_DESCRIPTION("Realtek 802.11ac wireless core module");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index efac271497f5b..790ebf781bc41 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -2198,4 +2198,5 @@ 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);
+void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif);
 #endif
-- 
2.25.1


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

* [PATCH 3/7] wifi: rtw88: 8822c: extend reserved page number
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 1/7] wifi: rtw88: add bitmap for dynamic port settings Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 2/7] wifi: rtw88: add port switch for AP mode Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode Ping-Ke Shih
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

Extend 8822c's reserved page number to accommodate additional required
pages. Reserved page is an area of memory in the FIFO dedicated for
special purposes. Previously only one interface is supported so 8 pages
should suffice, extend it so we can support 2 interfaces concurrently.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac.c      | 2 +-
 drivers/net/wireless/realtek/rtw88/main.h     | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
 6 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index f3a566cf979b5..b39657b8e88d1 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -1080,7 +1080,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
 	u8 csi_buf_pg_num = chip->csi_buf_pg_num;
 
 	/* config rsvd page num */
-	fifo->rsvd_drv_pg_num = 8;
+	fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
 	fifo->txff_pg_num = chip->txff_size >> 7;
 	if (rtw_chip_wcpu_11n(rtwdev))
 		fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 790ebf781bc41..532c56219a5f5 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1177,6 +1177,7 @@ struct rtw_chip_info {
 	u32 txff_size;
 	u32 rxff_size;
 	u32 fw_rxff_size;
+	u16 rsvd_drv_pg_num;
 	u8 band;
 	u8 page_size;
 	u8 csi_buf_pg_num;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 2d2f768bae2ea..06e7454c9ca69 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2743,6 +2743,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
 	.ptct_efuse_size = 96 + 1,
 	.txff_size = 32768,
 	.rxff_size = 16384,
+	.rsvd_drv_pg_num = 8,
 	.txgi_factor = 1,
 	.is_pwr_by_rate_dec = true,
 	.max_power_index = 0x3f,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 7ae0541d7b995..e538367683784 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -1920,6 +1920,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
 	.ptct_efuse_size = 96,
 	.txff_size = 65536,
 	.rxff_size = 16384,
+	.rsvd_drv_pg_num = 8,
 	.txgi_factor = 1,
 	.is_pwr_by_rate_dec = true,
 	.max_power_index = 0x3f,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 531b67787e2eb..3017a9760da8d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2540,6 +2540,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
 	.txff_size = 262144,
 	.rxff_size = 24576,
 	.fw_rxff_size = 12288,
+	.rsvd_drv_pg_num = 8,
 	.txgi_factor = 1,
 	.is_pwr_by_rate_dec = true,
 	.max_power_index = 0x3f,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 5a2c004b12df1..cd965edc29cea 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -5358,6 +5358,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
 	.txff_size = 262144,
 	.rxff_size = 24576,
 	.fw_rxff_size = 12288,
+	.rsvd_drv_pg_num = 16,
 	.txgi_factor = 2,
 	.is_pwr_by_rate_dec = false,
 	.max_power_index = 0x7f,
-- 
2.25.1


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

* [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2023-04-01 12:44 ` [PATCH 3/7] wifi: rtw88: 8822c: extend reserved page number Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-12 12:39   ` Kalle Valo
  2023-04-01 12:44 ` [PATCH 5/7] wifi: rtw88: refine reserved page flow for " Ping-Ke Shih
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

During concurrent operation, the VIF sharing same channel with AP mode
might scan. Reject those scan requests from driver when there's AP
currently operating. Also, disallow entering power saving mode.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 16 ++++++++++++++++
 drivers/net/wireless/realtek/rtw88/main.c     |  2 +-
 drivers/net/wireless/realtek/rtw88/main.h     |  1 +
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 19c4d7c29759e..37a3146a2910c 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -449,12 +449,24 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw,
 	const struct rtw_chip_info *chip = rtwdev->chip;
 
 	mutex_lock(&rtwdev->mutex);
+	rtwdev->ap_active = true;
 	chip->ops->phy_calibration(rtwdev);
 	mutex_unlock(&rtwdev->mutex);
 
 	return 0;
 }
 
+static void rtw_ops_stop_ap(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ieee80211_bss_conf *link_conf)
+{
+	struct rtw_dev *rtwdev = hw->priv;
+
+	mutex_lock(&rtwdev->mutex);
+	rtwdev->ap_active = false;
+	mutex_unlock(&rtwdev->mutex);
+}
+
 static int rtw_ops_conf_tx(struct ieee80211_hw *hw,
 			   struct ieee80211_vif *vif,
 			   unsigned int link_id, u16 ac,
@@ -853,6 +865,9 @@ static int rtw_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
 		return -EBUSY;
 
+	if (rtwdev->ap_active)
+		return -EOPNOTSUPP;
+
 	mutex_lock(&rtwdev->mutex);
 	rtw_hw_scan_start(rtwdev, vif, req);
 	ret = rtw_hw_scan_offload(rtwdev, vif, true);
@@ -916,6 +931,7 @@ const struct ieee80211_ops rtw_ops = {
 	.configure_filter	= rtw_ops_configure_filter,
 	.bss_info_changed	= rtw_ops_bss_info_changed,
 	.start_ap		= rtw_ops_start_ap,
+	.stop_ap		= rtw_ops_stop_ap,
 	.conf_tx		= rtw_ops_conf_tx,
 	.sta_add		= rtw_ops_sta_add,
 	.sta_remove		= rtw_ops_sta_remove,
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index ba05a5d68d05e..835abbdd87eff 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -256,7 +256,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
 	 * threshold.
 	 */
 	if (rtwdev->ps_enabled && data.rtwvif && !ps_active &&
-	    !rtwdev->beacon_loss)
+	    !rtwdev->beacon_loss && !rtwdev->ap_active)
 		rtw_enter_lps(rtwdev, data.rtwvif->port);
 
 	rtwdev->watch_dog_cnt++;
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 532c56219a5f5..b04ed190ea5d4 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -2058,6 +2058,7 @@ struct rtw_dev {
 
 	bool need_rfk;
 	struct completion fw_scan_density;
+	bool ap_active;
 
 	/* hci related data, must be last */
 	u8 priv[] __aligned(sizeof(void *));
-- 
2.25.1


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

* [PATCH 5/7] wifi: rtw88: refine reserved page flow for AP mode
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2023-04-01 12:44 ` [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 6/7] wifi: rtw88: prevent scan abort with other VIFs Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 7/7] wifi: rtw88: 8822c: add iface combination Ping-Ke Shih
  6 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

Only gather reserved pages from AP interface after it has started. Or
else ieee80211_beacon_get_*() returns NULL and causes other VIFs'
reserved pages fail to download. Update location of current reserved page
after beacon renews so offsets changed by beacon can be recognized.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c       | 5 +++++
 drivers/net/wireless/realtek/rtw88/mac80211.c | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 82295ac6402ee..049473accdb97 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1393,6 +1393,10 @@ static void rtw_build_rsvd_page_iter(void *data, u8 *mac,
 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
 	struct rtw_rsvd_page *rsvd_pkt;
 
+	/* AP not yet started, don't gather its rsvd pages */
+	if (vif->type == NL80211_IFTYPE_AP && !rtwdev->ap_active)
+		return;
+
 	list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) {
 		if (rsvd_pkt->type == RSVD_BEACON)
 			list_add(&rsvd_pkt->build_list,
@@ -1614,6 +1618,7 @@ void rtw_fw_update_beacon_work(struct work_struct *work)
 
 	mutex_lock(&rtwdev->mutex);
 	rtw_fw_download_rsvd_page(rtwdev);
+	rtw_send_rsvd_page_h2c(rtwdev);
 	mutex_unlock(&rtwdev->mutex);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 37a3146a2910c..1c2213957f449 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -417,6 +417,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_BEACON) {
 		rtw_set_dtim_period(rtwdev, conf->dtim_period);
 		rtw_fw_download_rsvd_page(rtwdev);
+		rtw_send_rsvd_page_h2c(rtwdev);
 	}
 
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
-- 
2.25.1


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

* [PATCH 6/7] wifi: rtw88: prevent scan abort with other VIFs
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2023-04-01 12:44 ` [PATCH 5/7] wifi: rtw88: refine reserved page flow for " Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  2023-04-01 12:44 ` [PATCH 7/7] wifi: rtw88: 8822c: add iface combination Ping-Ke Shih
  6 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

Only abort scan with current scanning VIF. If we have more than one
interface, we could call rtw_hw_scan_abort() with the wrong VIF as
input. This avoids potential null pointer being accessed when actually
the other VIF is scanning.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c       | 4 +++-
 drivers/net/wireless/realtek/rtw88/fw.h       | 2 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c | 7 ++++---
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 049473accdb97..f2d48091b1e98 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -2163,8 +2163,10 @@ int rtw_hw_scan_offload(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 	return ret;
 }
 
-void rtw_hw_scan_abort(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw_hw_scan_abort(struct rtw_dev *rtwdev)
 {
+	struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
+
 	if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD))
 		return;
 
diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index 0a386e6d6e0d1..397cbc3f6af6e 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -868,5 +868,5 @@ int rtw_hw_scan_offload(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 			bool enable);
 void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb);
 void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb);
-void rtw_hw_scan_abort(struct rtw_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw_hw_scan_abort(struct rtw_dev *rtwdev);
 #endif
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 1c2213957f449..41a9e4fe58b47 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -393,7 +393,8 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
 			 * when disconnected by peer
 			 */
 			if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
-				rtw_hw_scan_abort(rtwdev, vif);
+				rtw_hw_scan_abort(rtwdev);
+
 		}
 
 		config |= PORT_SET_NET_TYPE;
@@ -873,7 +874,7 @@ static int rtw_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	rtw_hw_scan_start(rtwdev, vif, req);
 	ret = rtw_hw_scan_offload(rtwdev, vif, true);
 	if (ret) {
-		rtw_hw_scan_abort(rtwdev, vif);
+		rtw_hw_scan_abort(rtwdev);
 		rtw_err(rtwdev, "HW scan failed with status: %d\n", ret);
 	}
 	mutex_unlock(&rtwdev->mutex);
@@ -893,7 +894,7 @@ static void rtw_ops_cancel_hw_scan(struct ieee80211_hw *hw,
 		return;
 
 	mutex_lock(&rtwdev->mutex);
-	rtw_hw_scan_abort(rtwdev, vif);
+	rtw_hw_scan_abort(rtwdev);
 	mutex_unlock(&rtwdev->mutex);
 }
 
-- 
2.25.1


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

* [PATCH 7/7] wifi: rtw88: 8822c: add iface combination
  2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
                   ` (5 preceding siblings ...)
  2023-04-01 12:44 ` [PATCH 6/7] wifi: rtw88: prevent scan abort with other VIFs Ping-Ke Shih
@ 2023-04-01 12:44 ` Ping-Ke Shih
  6 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-01 12:44 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless

From: Po-Hao Huang <phhuang@realtek.com>

Allow 8822c to operate two interface concurrently, only 1 AP mode plus
1 station mode under same frequency is supported. Combination of other
types will not be added until requested.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/main.c | 25 +++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 835abbdd87eff..d60a56508f389 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -102,6 +102,26 @@ static struct ieee80211_rate rtw_ratetable[] = {
 	{.bitrate = 540, .hw_value = 0x0b,},
 };
 
+static const struct ieee80211_iface_limit rtw_iface_limits[] = {
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_STATION),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_AP),
+	}
+};
+
+static const struct ieee80211_iface_combination rtw_iface_combs[] = {
+	{
+		.limits = rtw_iface_limits,
+		.n_limits = ARRAY_SIZE(rtw_iface_limits),
+		.max_interfaces = 2,
+		.num_different_channels = 1,
+	}
+};
+
 u16 rtw_desc_to_bitrate(u8 desc_rate)
 {
 	struct ieee80211_rate rate;
@@ -2195,6 +2215,11 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 	hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS;
 	hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev);
 
+	if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
+		hw->wiphy->iface_combinations = rtw_iface_combs;
+		hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs);
+	}
+
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN);
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
-- 
2.25.1


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

* Re: [PATCH 2/7] wifi: rtw88: add port switch for AP mode
  2023-04-01 12:44 ` [PATCH 2/7] wifi: rtw88: add port switch for AP mode Ping-Ke Shih
@ 2023-04-12 12:35   ` Kalle Valo
  0 siblings, 0 replies; 11+ messages in thread
From: Kalle Valo @ 2023-04-12 12:35 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: tony0620emma, phhuang, linux-wireless

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

> From: Po-Hao Huang <phhuang@realtek.com>
>
> Switch port settings if AP mode does not start on port 0 because of
> hardware limitation. For some ICs, beacons on ports other than zero
> could misbehave and do not issue properly, to fix this we change AP
> VIFs to port zero when multiple interfaces is active.
>
> Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

[...]

> +static void rtw_port_switch_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
> +{
> +	struct rtw_iter_port_switch_data *iter_data = data;
> +	struct rtw_dev *rtwdev = iter_data->rtwdev;
> +	struct rtw_vif *rtwvif_target = (struct rtw_vif *)vif->drv_priv;
> +	struct rtw_vif *rtwvif_ap = iter_data->rtwvif_ap;
> +	const struct rtw_hw_reg *reg1, *reg2;
> +
> +	if (rtwvif_target->port != RTW_PORT_0)
> +		return;
> +
> +	rtw_info(rtwdev, "AP port switch from %d -> %d\n", rtwvif_ap->port,
> +		 rtwvif_target->port);

This looks more like a debug message. In normal operations (after the
initialisation) the drivers should be quiet and only print messages when
something unexpected happens.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

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

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

* Re: [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode
  2023-04-01 12:44 ` [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode Ping-Ke Shih
@ 2023-04-12 12:39   ` Kalle Valo
  2023-04-14 12:21     ` Ping-Ke Shih
  0 siblings, 1 reply; 11+ messages in thread
From: Kalle Valo @ 2023-04-12 12:39 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: tony0620emma, phhuang, linux-wireless

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

> From: Po-Hao Huang <phhuang@realtek.com>
>
> During concurrent operation, the VIF sharing same channel with AP mode
> might scan. Reject those scan requests from driver when there's AP
> currently operating. Also, disallow entering power saving mode.
>
> Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

How is a station interface useful if it cannot scan at all? IMHO quite
hard limitation.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

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

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

* Re: [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode
  2023-04-12 12:39   ` Kalle Valo
@ 2023-04-14 12:21     ` Ping-Ke Shih
  0 siblings, 0 replies; 11+ messages in thread
From: Ping-Ke Shih @ 2023-04-14 12:21 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Bernie Huang, tony0620emma

On Wed, 2023-04-12 at 15:39 +0300, Kalle Valo wrote:
> 
> Ping-Ke Shih <pkshih@realtek.com> writes:
> 
> > From: Po-Hao Huang <phhuang@realtek.com>
> > 
> > During concurrent operation, the VIF sharing same channel with AP mode
> > might scan. Reject those scan requests from driver when there's AP
> > currently operating. Also, disallow entering power saving mode.
> > 
> > Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
> > Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> 
> How is a station interface useful if it cannot scan at all? IMHO quite
> hard limitation.
> 

Due to hardware limitation, it can't host as AP mode and do scanning at
the same time, so we make this choice before. Now, we don't reject scan
requests, but AP's clients could get lost or disconnected. I think
that is a trade-off, so we leave this decision to user space.

I have sent v2 with this change.

Ping-Ke


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

end of thread, other threads:[~2023-04-14 12:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-01 12:44 [PATCH 0/7] wifi: rtw88: support single channel concurrency Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 1/7] wifi: rtw88: add bitmap for dynamic port settings Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 2/7] wifi: rtw88: add port switch for AP mode Ping-Ke Shih
2023-04-12 12:35   ` Kalle Valo
2023-04-01 12:44 ` [PATCH 3/7] wifi: rtw88: 8822c: extend reserved page number Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 4/7] wifi: rtw88: disallow scan and PS during AP mode Ping-Ke Shih
2023-04-12 12:39   ` Kalle Valo
2023-04-14 12:21     ` Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 5/7] wifi: rtw88: refine reserved page flow for " Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 6/7] wifi: rtw88: prevent scan abort with other VIFs Ping-Ke Shih
2023-04-01 12:44 ` [PATCH 7/7] wifi: rtw88: 8822c: add iface combination Ping-Ke Shih

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).