linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/19] rtw89: support AP mode
@ 2022-01-07  3:42 Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ Ping-Ke Shih
                   ` (18 more replies)
  0 siblings, 19 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

To support AP mode, we implement ::start_ap and ::stop_ap to configure
firmware and hardware to play an AP. Then, we download beacon content to
firmware, so firmware can send out periodically the frames that must have
continual sequence number with other management frames.

When mac80211 buffers unicast packets for certain STAs, it tells driver via
::set_tim, and then we download the beacon content to firmware again. On the
other hand, if a broadcast packet is going to send out, it should go via
HIQ (HI queue) that hardware will raise group frame bit in TIM of beacon
frame. But if no STA sleeps, a broadcast packet is sent via AC queue.

When a STA is going to connect, it issues a probe request frame and then
auth/assoc frames. To receive these frames before it is connected, we need
to consider more RX filter flags to set registers properly.

When a connection is established, we need to assign a mac_id as a behalf of
this peer in firmware and hardware, and then use this mac_id to initialize
an instance in firmware via H2C(s). The most important part is to add a
corresponding address CAM entry that contains peer's MAC address and BSSID,
so hardware can determine a packet is belong to which peer. If it is a
security connection, keys will be filled to security CAM as well.

Since there are many CAM ID(s), I add a debugfs entry to see if the
relations between ID(s) and STA(s) are expected.

Ping-Ke Shih (19):
  rtw89: configure rx_filter according to FIF_PROBE_REQ
  rtw89: use hardware SSN to TX management frame
  rtw89: download beacon content to firmware
  rtw89: add C2H handle of BCN_CNT
  rtw89: implement mac80211_ops::set_tim to indicate STA to receive
    packets
  rtw89: allocate mac_id for each station in AP mode
  rtw89: extend firmware commands on states of sta_assoc and
    sta_disconnect
  rtw89: rename vif_maintain to role_maintain
  rtw89: configure mac port HIQ registers
  rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep
    mode
  rtw89: set mac_id and port ID to TXWD
  rtw89: separate {init,deinit}_addr_cam functions
  rtw89: extend role_maintain to support AP mode
  rtw89: add addr_cam field to sta to support AP mode
  rtw89: only STA mode change vif_type mapping dynamically
  rtw89: maintain assoc/disassoc STA states of firmware and hardware
  rtw89: implement ieee80211_ops::start_ap and stop_ap
  rtw89: debug: add stations entry to show ID assignment
  rtw89: declare AP mode support

 drivers/net/wireless/realtek/rtw89/cam.c      |  40 +++---
 drivers/net/wireless/realtek/rtw89/cam.h      |   5 +
 drivers/net/wireless/realtek/rtw89/core.c     | 107 ++++++++++++++--
 drivers/net/wireless/realtek/rtw89/core.h     |  83 ++++++++-----
 drivers/net/wireless/realtek/rtw89/debug.c    |  71 +++++++++++
 drivers/net/wireless/realtek/rtw89/fw.c       | 110 ++++++++++++++---
 drivers/net/wireless/realtek/rtw89/fw.h       | 115 +++++++++++++++++-
 drivers/net/wireless/realtek/rtw89/mac.c      |  50 +++++++-
 drivers/net/wireless/realtek/rtw89/mac.h      |   2 +
 drivers/net/wireless/realtek/rtw89/mac80211.c |  67 +++++++++-
 drivers/net/wireless/realtek/rtw89/reg.h      |  14 ++-
 drivers/net/wireless/realtek/rtw89/txrx.h     |   3 +
 12 files changed, 575 insertions(+), 92 deletions(-)

-- 
2.25.1


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

* [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-28 15:57   ` Kalle Valo
  2022-01-07  3:42 ` [PATCH 02/19] rtw89: use hardware SSN to TX management frame Ping-Ke Shih
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

With this patch, we can receive probe_req and reply probe_resp, and STA
can find us.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/mac80211.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 90b2e2e1473fc..f068c3008b06a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -161,7 +161,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
 	rtw89_leave_ps_mode(rtwdev);
 
 	*new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
-		      FIF_BCN_PRBRESP_PROMISC;
+		      FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ;
 
 	if (changed_flags & FIF_ALLMULTI) {
 		if (*new_flags & FIF_ALLMULTI)
@@ -192,6 +192,15 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
 			rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
 		}
 	}
+	if (changed_flags & FIF_PROBE_REQ) {
+		if (*new_flags & FIF_PROBE_REQ) {
+			rtwdev->hal.rx_fltr &= ~B_AX_A_BC_CAM_MATCH;
+			rtwdev->hal.rx_fltr &= ~B_AX_A_UC_CAM_MATCH;
+		} else {
+			rtwdev->hal.rx_fltr |= B_AX_A_BC_CAM_MATCH;
+			rtwdev->hal.rx_fltr |= B_AX_A_UC_CAM_MATCH;
+		}
+	}
 
 	rtw89_write32_mask(rtwdev,
 			   rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
-- 
2.25.1


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

* [PATCH 02/19] rtw89: use hardware SSN to TX management frame
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 03/19] rtw89: download beacon content to firmware Ping-Ke Shih
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Since firmware transmits beacon by hardware SSN, driver does it with the
same setting, then packets in the air have continual sequence number.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 6 +++++-
 drivers/net/wireless/realtek/rtw89/core.h | 4 ++++
 drivers/net/wireless/realtek/rtw89/txrx.h | 2 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 3d1c4c3b4dcb1..7c5e9bc309706 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -383,6 +383,8 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
 
 	desc_info->qsel = RTW89_TX_QSEL_B0_MGMT;
 	desc_info->ch_dma = ch_dma;
+	desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
+	desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
 
 	/* fixed data rate for mgmt frames */
 	desc_info->en_wd_info = true;
@@ -708,7 +710,9 @@ static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info)
 		    FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) |
 		    FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) |
 		    FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) |
-		    FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl);
+		    FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl) |
+		    FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_SEL, desc_info->hw_ssn_sel) |
+		    FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_MODE, desc_info->hw_seq_mode);
 
 	return cpu_to_le32(dword);
 }
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index afadfc5349d35..defa0ceebc20e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -691,6 +691,10 @@ struct rtw89_tx_desc_info {
 	bool fw_dl;
 	u16 seq;
 	bool a_ctrl_bsr;
+	u8 hw_ssn_sel;
+#define RTW89_MGMT_HW_SSN_SEL	1
+	u8 hw_seq_mode;
+#define RTW89_MGMT_HW_SEQ_MODE	1
 };
 
 struct rtw89_core_tx_request {
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h
index 75b11249f3065..fb92973e96c66 100644
--- a/drivers/net/wireless/realtek/rtw89/txrx.h
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h
@@ -31,6 +31,8 @@
 #define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11)
 #define RTW89_TXWD_BODY0_WD_PAGE BIT(7)
 #define RTW89_TXWD_BODY0_HW_AMSDU BIT(5)
+#define RTW89_TXWD_BODY0_HW_SSN_SEL GENMASK(3, 2)
+#define RTW89_TXWD_BODY0_HW_SSN_MODE GENMASK(1, 0)
 
 /* TX WD BODY DWORD 1 */
 #define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16)
-- 
2.25.1


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

* [PATCH 03/19] rtw89: download beacon content to firmware
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 02/19] rtw89: use hardware SSN to TX management frame Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 04/19] rtw89: add C2H handle of BCN_CNT Ping-Ke Shih
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Firmware sends out beacon content generated by mac80211, and then stations
can receive beacon and work with this AP properly. Also, we download
beacon content again if TIM is changed.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/fw.c       |  53 +++++++++
 drivers/net/wireless/realtek/rtw89/fw.h       | 103 ++++++++++++++++++
 drivers/net/wireless/realtek/rtw89/mac80211.c |   3 +
 3 files changed, 159 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 79bc3e20ab94b..441a8ef838570 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -928,6 +928,59 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
 	return -EBUSY;
 }
 
+#define H2C_BCN_BASE_LEN 12
+int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
+			       struct rtw89_vif *rtwvif)
+{
+	struct rtw89_hal *hal = &rtwdev->hal;
+	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+	struct sk_buff *skb;
+	struct sk_buff *skb_beacon;
+	u16 tim_offset;
+	int bcn_total_len;
+
+	skb_beacon = ieee80211_beacon_get_tim(rtwdev->hw, vif, &tim_offset, NULL);
+	if (!skb_beacon) {
+		rtw89_err(rtwdev, "failed to get beacon skb\n");
+		return -ENOMEM;
+	}
+
+	bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len;
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(bcn_total_len);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
+		dev_kfree_skb_any(skb_beacon);
+		return -ENOMEM;
+	}
+	skb_put(skb, H2C_BCN_BASE_LEN);
+
+	SET_BCN_UPD_PORT(skb->data, rtwvif->port);
+	SET_BCN_UPD_MBSSID(skb->data, 0);
+	SET_BCN_UPD_BAND(skb->data, rtwvif->mac_idx);
+	SET_BCN_UPD_GRP_IE_OFST(skb->data, tim_offset);
+	SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
+	SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
+	SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
+	SET_BCN_UPD_RATE(skb->data, hal->current_band_type == RTW89_BAND_2G ?
+				    RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);
+
+	skb_put_data(skb, skb_beacon->data, skb_beacon->len);
+	dev_kfree_skb_any(skb_beacon);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
+			      H2C_FUNC_MAC_BCN_UPD, 0, 1,
+			      bcn_total_len);
+
+	if (rtw89_h2c_tx(rtwdev, skb, false)) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		dev_kfree_skb_any(skb);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 #define H2C_VIF_MAINTAIN_LEN 4
 int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
 			      struct rtw89_vif *rtwvif,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index b10f6e6a534c4..c6e83e4e49fa3 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1056,6 +1056,106 @@ static inline void SET_CMC_TBL_CSI_BW(void *table, u32 val)
 			   GENMASK(31, 30));
 }
 
+static inline void SET_BCN_UPD_PORT(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
+}
+
+static inline void SET_BCN_UPD_MBSSID(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8));
+}
+
+static inline void SET_BCN_UPD_BAND(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16));
+}
+
+static inline void SET_BCN_UPD_GRP_IE_OFST(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)h2c, (val - 24) | BIT(7), GENMASK(31, 24));
+}
+
+static inline void SET_BCN_UPD_MACID(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0));
+}
+
+static inline void SET_BCN_UPD_SSN_SEL(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(9, 8));
+}
+
+static inline void SET_BCN_UPD_SSN_MODE(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(11, 10));
+}
+
+static inline void SET_BCN_UPD_RATE(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(20, 12));
+}
+
+static inline void SET_BCN_UPD_TXPWR(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(23, 21));
+}
+
+static inline void SET_BCN_UPD_TXINFO_CTRL_EN(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val, BIT(0));
+}
+
+static inline void SET_BCN_UPD_NTX_PATH_EN(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(4, 1));
+}
+
+static inline void SET_BCN_UPD_PATH_MAP_A(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(6, 5));
+}
+
+static inline void SET_BCN_UPD_PATH_MAP_B(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(8, 7));
+}
+
+static inline void SET_BCN_UPD_PATH_MAP_C(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(10, 9));
+}
+
+static inline void SET_BCN_UPD_PATH_MAP_D(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(12, 11));
+}
+
+static inline void SET_BCN_UPD_PATH_ANTSEL_A(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  BIT(13));
+}
+
+static inline void SET_BCN_UPD_PATH_ANTSEL_B(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  BIT(14));
+}
+
+static inline void SET_BCN_UPD_PATH_ANTSEL_C(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  BIT(15));
+}
+
+static inline void SET_BCN_UPD_PATH_ANTSEL_D(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  BIT(16));
+}
+
+static inline void SET_BCN_UPD_CSA_OFST(void *h2c, u32 val)
+{
+	le32p_replace_bits((__le32 *)(h2c) + 2, val,  GENMASK(31, 17));
+}
+
 static inline void SET_FWROLE_MAINTAIN_MACID(void *h2c, u32 val)
 {
 	le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
@@ -1729,6 +1829,7 @@ struct rtw89_fw_h2c_rf_reg_info {
 /* CLASS 5 - Frame Exchange */
 #define H2C_CL_MAC_FR_EXCHG		0x5
 #define H2C_FUNC_MAC_CCTLINFO_UD	0x2
+#define H2C_FUNC_MAC_BCN_UPD		0x5
 
 /* CLASS 6 - Address CAM */
 #define H2C_CL_MAC_ADDR_CAM_UPDATE	0x6
@@ -1776,6 +1877,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 				struct ieee80211_sta *sta);
 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
 				 struct rtw89_sta *rtwsta);
+int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
+			       struct rtw89_vif *rtwvif);
 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif,
 		     struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);
 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index f068c3008b06a..682680e18ff46 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -349,6 +349,9 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
 		rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
 	}
 
+	if (changed & BSS_CHANGED_BEACON)
+		rtw89_fw_h2c_update_beacon(rtwdev, rtwvif);
+
 	if (changed & BSS_CHANGED_ERP_SLOT)
 		rtw89_conf_tx(rtwdev, rtwvif);
 
-- 
2.25.1


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

* [PATCH 04/19] rtw89: add C2H handle of BCN_CNT
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 03/19] rtw89: download beacon content to firmware Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 05/19] rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets Ping-Ke Shih
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

This C2H notify driver the beacon count we send out. We don't handle the
content for now, so add a dummy handler to avoid messages, like
  rtw89_pci 0000:03:00.0: c2h class 0 func 3 not support
  C2H: 00000000: 01 03 01 3f 0f 00 00 00 80 0a 00 00 00 00 a0
  rtw89_pci 0000:03:00.0: c2h class 0 func 3 not support
  C2H: 00000000: 01 03 01 40 0f 00 00 00 00 03 20 00 00 00 a5

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++
 drivers/net/wireless/realtek/rtw89/mac.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index b98c47e9ecfe3..59b6ef91afb0a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3114,6 +3114,11 @@ rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
 		   RTW89_GET_C2H_LOG_SRT_PRT(c2h->data));
 }
 
+static void
+rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
 static
 void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
 					    struct sk_buff *c2h, u32 len) = {
@@ -3130,6 +3135,7 @@ void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev,
 	[RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack,
 	[RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack,
 	[RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log,
+	[RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt,
 };
 
 void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index b7d13edf7dd19..65e4ebe05f6ad 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -308,6 +308,7 @@ enum rtw89_mac_c2h_info_func {
 	RTW89_MAC_C2H_FUNC_REC_ACK,
 	RTW89_MAC_C2H_FUNC_DONE_ACK,
 	RTW89_MAC_C2H_FUNC_C2H_LOG,
+	RTW89_MAC_C2H_FUNC_BCN_CNT,
 	RTW89_MAC_C2H_FUNC_INFO_MAX,
 };
 
-- 
2.25.1


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

* [PATCH 05/19] rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 04/19] rtw89: add C2H handle of BCN_CNT Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 06/19] rtw89: allocate mac_id for each station in AP mode Ping-Ke Shih
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Update beacon content if TIM bitmap maintained by mac80211 is changed.
Since .set_tim must be atomic but driver uses mutex lock, we add a work.
Otherwise, kernel says "sched: RT throttling activated" and lock down.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c     | 15 +++++++++++++++
 drivers/net/wireless/realtek/rtw89/core.h     |  3 +++
 drivers/net/wireless/realtek/rtw89/mac80211.c | 17 +++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 7c5e9bc309706..7fee45d8b82a1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2238,6 +2238,21 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev)
 		rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX;
 }
 
+void rtw89_core_update_beacon_work(struct work_struct *work)
+{
+	struct rtw89_dev *rtwdev;
+	struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
+						update_beacon_work);
+
+	if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE)
+		return;
+
+	rtwdev = rtwvif->rtwdev;
+	mutex_lock(&rtwdev->mutex);
+	rtw89_fw_h2c_update_beacon(rtwdev, rtwvif);
+	mutex_unlock(&rtwdev->mutex);
+}
+
 int rtw89_core_start(struct rtw89_dev *rtwdev)
 {
 	int ret;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index defa0ceebc20e..542afe2133b0f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1928,6 +1928,7 @@ struct rtw89_phy_rate_pattern {
 
 struct rtw89_vif {
 	struct list_head list;
+	struct rtw89_dev *rtwdev;
 	u8 mac_id;
 	u8 port;
 	u8 mac_addr[ETH_ALEN];
@@ -1949,6 +1950,7 @@ struct rtw89_vif {
 	bool wowlan_magic;
 	bool is_hesta;
 	bool last_a_ctrl;
+	struct work_struct update_beacon_work;
 	struct rtw89_addr_cam_entry addr_cam;
 	struct rtw89_bssid_cam_entry bssid_cam;
 	struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
@@ -3396,5 +3398,6 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
 			      struct rtw89_traffic_stats *stats);
 int rtw89_core_start(struct rtw89_dev *rtwdev);
 void rtw89_core_stop(struct rtw89_dev *rtwdev);
+void rtw89_core_update_beacon_work(struct work_struct *work);
 
 #endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 682680e18ff46..26abbe7aa17d8 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -102,7 +102,9 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
 	int ret = 0;
 
 	mutex_lock(&rtwdev->mutex);
+	rtwvif->rtwdev = rtwdev;
 	list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
+	INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
 	rtw89_leave_ps_mode(rtwdev);
 
 	rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
@@ -141,6 +143,8 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
 	struct rtw89_dev *rtwdev = hw->priv;
 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
 
+	cancel_work_sync(&rtwvif->update_beacon_work);
+
 	mutex_lock(&rtwdev->mutex);
 	rtw89_leave_ps_mode(rtwdev);
 	rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
@@ -364,6 +368,18 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
 	mutex_unlock(&rtwdev->mutex);
 }
 
+static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+			     bool set)
+{
+	struct rtw89_dev *rtwdev = hw->priv;
+	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+
+	ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
+
+	return 0;
+}
+
 static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif, u16 ac,
 			     const struct ieee80211_tx_queue_params *params)
@@ -680,6 +696,7 @@ const struct ieee80211_ops rtw89_ops = {
 	.remove_interface	= rtw89_ops_remove_interface,
 	.configure_filter	= rtw89_ops_configure_filter,
 	.bss_info_changed	= rtw89_ops_bss_info_changed,
+	.set_tim		= rtw89_ops_set_tim,
 	.conf_tx		= rtw89_ops_conf_tx,
 	.sta_state		= rtw89_ops_sta_state,
 	.set_key		= rtw89_ops_set_key,
-- 
2.25.1


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

* [PATCH 06/19] rtw89: allocate mac_id for each station in AP mode
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 05/19] rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 07/19] rtw89: extend firmware commands on states of sta_assoc and sta_disconnect Ping-Ke Shih
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

In station mode, mac_id of station is the same as rtwvif's one.
In AP mode, each station uses individual mac_id.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 7fee45d8b82a1..3163c63091868 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1885,6 +1885,9 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
 		rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
 					 BTC_ROLE_MSTS_STA_CONN_START);
 		rtw89_chip_rfk_channel(rtwdev);
+	} else if (vif->type == NL80211_IFTYPE_AP) {
+		rtwsta->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map,
+							    RTW89_MAX_MAC_ID_NUM);
 	}
 
 	return 0;
@@ -1997,6 +2000,8 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
 	if (vif->type == NL80211_IFTYPE_STATION)
 		rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
 					 BTC_ROLE_MSTS_STA_DIS_CONN);
+	else if (vif->type == NL80211_IFTYPE_AP)
+		rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id);
 
 	return 0;
 }
-- 
2.25.1


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

* [PATCH 07/19] rtw89: extend firmware commands on states of sta_assoc and sta_disconnect
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (5 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 06/19] rtw89: allocate mac_id for each station in AP mode Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 08/19] rtw89: rename vif_maintain to role_maintain Ping-Ke Shih
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

The h2c_join firmware command is used to indicate a station is connected,
and the assoc_cmac_tbl firmware command is used to set CMAC table
corresponding to a mac_id. Both commands must work in both station and AP
modes. Use the mac_id of rtw89_sta naturally and intuitively.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c |  4 +--
 drivers/net/wireless/realtek/rtw89/fw.c   | 35 +++++++++++++++++------
 drivers/net/wireless/realtek/rtw89/fw.h   |  5 ++--
 drivers/net/wireless/realtek/rtw89/mac.c  |  2 +-
 4 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 3163c63091868..175d9924761c1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1925,7 +1925,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
 		return ret;
 	}
 
-	ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 1);
+	ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, true);
 	if (ret) {
 		rtw89_warn(rtwdev, "failed to send h2c join info\n");
 		return ret;
@@ -1957,7 +1957,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
 		return ret;
 	}
 
-	ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 0);
+	ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, false);
 	if (ret) {
 		rtw89_warn(rtwdev, "failed to send h2c join info\n");
 		return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 441a8ef838570..e9f27382d2ba8 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -733,12 +733,14 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
 }
 
 #define H2C_CMC_TBL_LEN 68
-int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid)
+int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
+				  struct rtw89_vif *rtwvif)
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
 	struct sk_buff *skb;
 	u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
 	u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0;
+	u8 macid = rtwvif->mac_id;
 
 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN);
 	if (!skb) {
@@ -760,6 +762,8 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid)
 	SET_CMC_TBL_ANTSEL_D(skb->data, 0);
 	SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
 	SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
+	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+		SET_CMC_TBL_DATA_DCM(skb->data, 0);
 
 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
@@ -838,13 +842,15 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 				struct ieee80211_sta *sta)
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
-	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+	struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
 	struct sk_buff *skb;
 	u8 pads[RTW89_PPE_BW_NUM];
+	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
 
 	memset(pads, 0, sizeof(pads));
-	__get_sta_he_pkt_padding(rtwdev, sta, pads);
+	if (sta)
+		__get_sta_he_pkt_padding(rtwdev, sta, pads);
 
 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN);
 	if (!skb) {
@@ -852,7 +858,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 		return -ENOMEM;
 	}
 	skb_put(skb, H2C_CMC_TBL_LEN);
-	SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
+	SET_CTRL_INFO_MACID(skb->data, mac_id);
 	SET_CTRL_INFO_OPERATION(skb->data, 1);
 	SET_CMC_TBL_DISRTSFB(skb->data, 1);
 	SET_CMC_TBL_DISDATAFB(skb->data, 1);
@@ -870,7 +876,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 	SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
 	SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
 	SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
-	SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->he_cap.has_he);
+	if (sta)
+		SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->he_cap.has_he);
+	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+		SET_CMC_TBL_DATA_DCM(skb->data, 0);
 
 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 			      H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
@@ -1018,9 +1027,17 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
 
 #define H2C_JOIN_INFO_LEN 4
 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
-			   u8 dis_conn)
+			   struct rtw89_sta *rtwsta, bool dis_conn)
 {
 	struct sk_buff *skb;
+	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+	u8 self_role = rtwvif->self_role;
+	u8 net_type = rtwvif->net_type;
+
+	if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
+		self_role = RTW89_SELF_ROLE_AP_CLIENT;
+		net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
+	}
 
 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN);
 	if (!skb) {
@@ -1028,7 +1045,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 		return -ENOMEM;
 	}
 	skb_put(skb, H2C_JOIN_INFO_LEN);
-	SET_JOININFO_MACID(skb->data, rtwvif->mac_id);
+	SET_JOININFO_MACID(skb->data, mac_id);
 	SET_JOININFO_OP(skb->data, dis_conn);
 	SET_JOININFO_BAND(skb->data, rtwvif->mac_idx);
 	SET_JOININFO_WMM(skb->data, rtwvif->wmm);
@@ -1038,9 +1055,9 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 	SET_JOININFO_TF_MAC_PAD(skb->data, 0);
 	SET_JOININFO_DL_T_PE(skb->data, 0);
 	SET_JOININFO_PORT_ID(skb->data, rtwvif->port);
-	SET_JOININFO_NET_TYPE(skb->data, rtwvif->net_type);
+	SET_JOININFO_NET_TYPE(skb->data, net_type);
 	SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role);
-	SET_JOININFO_SELF_ROLE(skb->data, rtwvif->self_role);
+	SET_JOININFO_SELF_ROLE(skb->data, self_role);
 
 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 			      H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index c6e83e4e49fa3..55f11e7886d52 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1871,7 +1871,8 @@ int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev);
 void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 			   u8 type, u8 cat, u8 class, u8 func,
 			   bool rack, bool dack, u32 len);
-int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid);
+int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
+				  struct rtw89_vif *rtwvif);
 int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 				struct ieee80211_vif *vif,
 				struct ieee80211_sta *sta);
@@ -1887,7 +1888,7 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
 			      struct rtw89_vif *rtwvif,
 			      enum rtw89_upd_mode upd_mode);
 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
-			   u8 dis_conn);
+			   struct rtw89_sta *rtwsta, bool dis_conn);
 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
 			     bool pause);
 int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 59b6ef91afb0a..58f47b46c2f95 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -2994,7 +2994,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	if (ret)
 		return ret;
 
-	ret = rtw89_fw_h2c_default_cmac_tbl(rtwdev, rtwvif->mac_id);
+	ret = rtw89_fw_h2c_default_cmac_tbl(rtwdev, rtwvif);
 	if (ret)
 		return ret;
 
-- 
2.25.1


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

* [PATCH 08/19] rtw89: rename vif_maintain to role_maintain
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (6 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 07/19] rtw89: extend firmware commands on states of sta_assoc and sta_disconnect Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 09/19] rtw89: configure mac port HIQ registers Ping-Ke Shih
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

The H2C_FUNC_MAC_FWROLE_MAINTAIN also maintains the roles of all connected
stations; not just the role of VIF. So, I correct the name, but don't
change the logic at all.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.h | 10 +++++-----
 drivers/net/wireless/realtek/rtw89/fw.c   | 14 +++++++-------
 drivers/net/wireless/realtek/rtw89/fw.h   |  6 +++---
 drivers/net/wireless/realtek/rtw89/mac.c  |  4 ++--
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 542afe2133b0f..ae8943d4fb43d 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -140,11 +140,11 @@ enum rtw89_wifi_role {
 };
 
 enum rtw89_upd_mode {
-	RTW89_VIF_CREATE,
-	RTW89_VIF_REMOVE,
-	RTW89_VIF_TYPE_CHANGE,
-	RTW89_VIF_INFO_CHANGE,
-	RTW89_VIF_CON_DISCONN
+	RTW89_ROLE_CREATE,
+	RTW89_ROLE_REMOVE,
+	RTW89_ROLE_TYPE_CHANGE,
+	RTW89_ROLE_INFO_CHANGE,
+	RTW89_ROLE_CON_DISCONN
 };
 
 enum rtw89_self_role {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index e9f27382d2ba8..5209813275676 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -990,19 +990,19 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
 	return 0;
 }
 
-#define H2C_VIF_MAINTAIN_LEN 4
-int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
-			      struct rtw89_vif *rtwvif,
-			      enum rtw89_upd_mode upd_mode)
+#define H2C_ROLE_MAINTAIN_LEN 4
+int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
+			       struct rtw89_vif *rtwvif,
+			       enum rtw89_upd_mode upd_mode)
 {
 	struct sk_buff *skb;
 
-	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_VIF_MAINTAIN_LEN);
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_ROLE_MAINTAIN_LEN);
 	if (!skb) {
 		rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
 		return -ENOMEM;
 	}
-	skb_put(skb, H2C_VIF_MAINTAIN_LEN);
+	skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
 	SET_FWROLE_MAINTAIN_MACID(skb->data, rtwvif->mac_id);
 	SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, rtwvif->self_role);
 	SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
@@ -1011,7 +1011,7 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 			      H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
 			      H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
-			      H2C_VIF_MAINTAIN_LEN);
+			      H2C_ROLE_MAINTAIN_LEN);
 
 	if (rtw89_h2c_tx(rtwdev, skb, false)) {
 		rtw89_err(rtwdev, "failed to send h2c\n");
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 55f11e7886d52..b30cf0a2cc1e0 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1884,9 +1884,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif,
 		     struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);
 void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
 void rtw89_fw_c2h_work(struct work_struct *work);
-int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,
-			      struct rtw89_vif *rtwvif,
-			      enum rtw89_upd_mode upd_mode);
+int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
+			       struct rtw89_vif *rtwvif,
+			       enum rtw89_upd_mode upd_mode);
 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 			   struct rtw89_sta *rtwsta, bool dis_conn);
 int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 58f47b46c2f95..a0ff3d8a3f61b 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -2982,7 +2982,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	if (ret)
 		return ret;
 
-	ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_CREATE);
+	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_CREATE);
 	if (ret)
 		return ret;
 
@@ -3005,7 +3005,7 @@ int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
 	int ret;
 
-	ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_REMOVE);
+	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_REMOVE);
 	if (ret)
 		return ret;
 
-- 
2.25.1


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

* [PATCH 09/19] rtw89: configure mac port HIQ registers
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (7 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 08/19] rtw89: rename vif_maintain to role_maintain Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 10/19] rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode Ping-Ke Shih
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

HIQ is short for high queue that is used to send broadcast/multicast
packets right after TBTT in AP mode. Two registers, DTIM and window size,
are configured accordingly.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/mac.c | 34 +++++++++++++++++++++++-
 drivers/net/wireless/realtek/rtw89/reg.h | 14 +++++++++-
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index a0ff3d8a3f61b..58aa24e71637d 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -2864,6 +2864,36 @@ static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
 				bcn_int);
 }
 
+static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
+				       struct rtw89_vif *rtwvif)
+{
+	static const u32 hiq_win_addr[RTW89_PORT_NUM] = {
+		R_AX_P0MB_HGQ_WINDOW_CFG_0, R_AX_PORT_HGQ_WINDOW_CFG,
+		R_AX_PORT_HGQ_WINDOW_CFG + 1, R_AX_PORT_HGQ_WINDOW_CFG + 2,
+		R_AX_PORT_HGQ_WINDOW_CFG + 3,
+	};
+	u8 win = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
+	u8 port = rtwvif->port;
+	u32 reg;
+
+	reg = rtw89_mac_reg_by_idx(hiq_win_addr[port], rtwvif->mac_idx);
+	rtw89_write8(rtwdev, reg, win);
+}
+
+static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
+					struct rtw89_vif *rtwvif)
+{
+	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+	const struct rtw89_port_reg *p = &rtw_port_base;
+	u32 addr;
+
+	addr = rtw89_mac_reg_by_idx(R_AX_MD_TSFT_STMP_CTL, rtwvif->mac_idx);
+	rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
+
+	rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
+				vif->bss_conf.dtim_period);
+}
+
 static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
 					      struct rtw89_vif *rtwvif)
 {
@@ -3034,13 +3064,15 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
+	rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
+	rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
+	rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif);
-	rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif);
 	rtw89_mac_port_cfg_func_en(rtwdev, rtwvif);
 	fsleep(BCN_ERLY_SET_DLY);
 	rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif);
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index e0a416d37d0e8..5e5cb0fcfa859 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -913,7 +913,7 @@
 #define R_AX_DTIM_CTRL_P2 0xC4A6
 #define R_AX_DTIM_CTRL_P3 0xC4E6
 #define R_AX_DTIM_CTRL_P4 0xC526
-#define B_AX_DTIM_NUM_MASK GENMASK(15, 0)
+#define B_AX_DTIM_NUM_MASK GENMASK(15, 8)
 #define B_AX_DTIM_CURRCNT_MASK GENMASK(7, 0)
 
 #define R_AX_TBTT_SHIFT_P0 0xC428
@@ -964,6 +964,11 @@
 #define B_AX_P0MB2_EN BIT(2)
 #define B_AX_P0MB1_EN BIT(1)
 
+#define R_AX_P0MB_HGQ_WINDOW_CFG_0 0xC590
+#define R_AX_P0MB_HGQ_WINDOW_CFG_0_C1 0xE590
+#define R_AX_PORT_HGQ_WINDOW_CFG 0xC5A0
+#define R_AX_PORT_HGQ_WINDOW_CFG_C1 0xE5A0
+
 #define R_AX_AMPDU_AGG_LIMIT 0xC610
 #define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24)
 #define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16)
@@ -1080,6 +1085,13 @@
 #define B_AX_TCR_ZLD_USTIME_AFTERPHYTXON GENMASK(11, 8)
 #define B_AX_TCR_TXTIMEOUT GENMASK(7, 0)
 
+#define R_AX_MD_TSFT_STMP_CTL 0xCA08
+#define R_AX_MD_TSFT_STMP_CTL_C1 0xEA08
+#define B_AX_TSFT_OFS_MASK GENMASK(31, 16)
+#define B_AX_STMP_THSD_MASK GENMASK(15, 8)
+#define B_AX_UPD_HGQMD BIT(1)
+#define B_AX_UPD_TIMIE BIT(0)
+
 #define R_AX_PPWRBIT_SETTING 0xCA0C
 #define R_AX_PPWRBIT_SETTING_C1 0xEA0C
 
-- 
2.25.1


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

* [PATCH 10/19] rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (8 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 09/19] rtw89: configure mac port HIQ registers Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 11/19] rtw89: set mac_id and port ID to TXWD Ping-Ke Shih
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

If a packet we are going to send is broadcast/multicast and certain STAs
are in sleep mode, a flag IEEE80211_TX_CTL_SEND_AFTER_DTIM is added to
txinfo. Then, this kind of packets must be sent via HIQ instead of regular
AC queues, because they should be sent right after beacon.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 8 +++++---
 drivers/net/wireless/realtek/rtw89/core.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 175d9924761c1..50bbc93196085 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -378,10 +378,10 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
 	struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
 	u8 qsel, ch_dma;
 
-	qsel = RTW89_TX_QSEL_B0_MGMT;
+	qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
 	ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel);
 
-	desc_info->qsel = RTW89_TX_QSEL_B0_MGMT;
+	desc_info->qsel = qsel;
 	desc_info->ch_dma = ch_dma;
 	desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
 	desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
@@ -535,7 +535,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
 
 	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
 	tid_indicate = rtw89_core_get_tid_indicate(rtwdev, tid);
-	qsel = rtw89_core_get_qsel(rtwdev, tid);
+	qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : rtw89_core_get_qsel(rtwdev, tid);
 	ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel);
 
 	desc_info->ch_dma = ch_dma;
@@ -601,6 +601,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
 {
 	struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
 	struct sk_buff *skb = tx_req->skb;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hdr *hdr = (void *)skb->data;
 	enum rtw89_core_tx_type tx_type;
 	enum btc_pkt_type pkt_type;
@@ -619,6 +620,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
 	desc_info->pkt_size = skb->len;
 	desc_info->is_bmc = is_bmc;
 	desc_info->wd_page = true;
+	desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM;
 
 	switch (tx_req->tx_type) {
 	case RTW89_CORE_TX_TYPE_MGMT:
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index ae8943d4fb43d..cf795d2f14776 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -695,6 +695,7 @@ struct rtw89_tx_desc_info {
 #define RTW89_MGMT_HW_SSN_SEL	1
 	u8 hw_seq_mode;
 #define RTW89_MGMT_HW_SEQ_MODE	1
+	bool hiq;
 };
 
 struct rtw89_core_tx_request {
-- 
2.25.1


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

* [PATCH 11/19] rtw89: set mac_id and port ID to TXWD
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (9 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 10/19] rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 12/19] rtw89: separate {init,deinit}_addr_cam functions Ping-Ke Shih
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

One mac_id is corresponding to one connected station, and port ID is a
ID of virtual interfaces. With proper mac_id and port ID, firmware and
hardware can handle a packet with correct context.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 26 +++++++++++++++++++++--
 drivers/net/wireless/realtek/rtw89/core.h |  2 ++
 drivers/net/wireless/realtek/rtw89/txrx.h |  1 +
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 50bbc93196085..8f8891badf0e8 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -375,6 +375,8 @@ static void
 rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
 			       struct rtw89_core_tx_request *tx_req)
 {
+	struct ieee80211_vif *vif = tx_req->vif;
+	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
 	struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
 	u8 qsel, ch_dma;
 
@@ -383,6 +385,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
 
 	desc_info->qsel = qsel;
 	desc_info->ch_dma = ch_dma;
+	desc_info->port = desc_info->hiq ? rtwvif->port : 0;
 	desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
 	desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
 
@@ -520,6 +523,21 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
 	desc_info->bk = true;
 }
 
+static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
+				   struct rtw89_core_tx_request *tx_req)
+{
+	struct ieee80211_vif *vif = tx_req->vif;
+	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+	struct ieee80211_sta *sta = tx_req->sta;
+	struct rtw89_sta *rtwsta;
+
+	if (!sta)
+		return rtwvif->mac_id;
+
+	rtwsta = (struct rtw89_sta *)sta->drv_priv;
+	return rtwsta->mac_id;
+}
+
 static void
 rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
 			       struct rtw89_core_tx_request *tx_req)
@@ -541,6 +559,8 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
 	desc_info->ch_dma = ch_dma;
 	desc_info->tid_indicate = tid_indicate;
 	desc_info->qsel = qsel;
+	desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
+	desc_info->port = desc_info->hiq ? rtwvif->port : 0;
 
 	/* enable wd_info for AMPDU */
 	desc_info->en_wd_info = true;
@@ -723,7 +743,8 @@ static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info)
 {
 	u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) |
 		    FIELD_PREP(RTW89_TXWD_BODY2_QSEL, desc_info->qsel) |
-		    FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size);
+		    FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size) |
+		    FIELD_PREP(RTW89_TXWD_BODY2_MACID, desc_info->mac_id);
 
 	return cpu_to_le32(dword);
 }
@@ -741,7 +762,8 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info)
 {
 	u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) |
 		    FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) |
-		    FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb);
+		    FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
+		    FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port);
 
 	return cpu_to_le32(dword);
 }
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index cf795d2f14776..8cb907da6cb05 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -670,6 +670,7 @@ struct rtw89_rxdesc_long {
 struct rtw89_tx_desc_info {
 	u16 pkt_size;
 	u8 wp_offset;
+	u8 mac_id;
 	u8 qsel;
 	u8 ch_dma;
 	u8 hdr_llc_len;
@@ -696,6 +697,7 @@ struct rtw89_tx_desc_info {
 	u8 hw_seq_mode;
 #define RTW89_MGMT_HW_SEQ_MODE	1
 	bool hiq;
+	u8 port;
 };
 
 struct rtw89_core_tx_request {
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h
index fb92973e96c66..86e3d8b400d6c 100644
--- a/drivers/net/wireless/realtek/rtw89/txrx.h
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h
@@ -58,6 +58,7 @@
 #define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25)
 #define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16)
 #define RTW89_TXWD_INFO0_DISDATAFB BIT(10)
+#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)
 
 /* TX WD INFO DWORD 1 */
 #define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16)
-- 
2.25.1


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

* [PATCH 12/19] rtw89: separate {init,deinit}_addr_cam functions
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (10 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 11/19] rtw89: set mac_id and port ID to TXWD Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 13/19] rtw89: extend role_maintain to support AP mode Ping-Ke Shih
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Each stations connected to AP needs to set an address CAM, so don't combine
address and BSSID CAM.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/cam.c  | 34 ++++++++++++++---------
 drivers/net/wireless/realtek/rtw89/cam.h  |  5 ++++
 drivers/net/wireless/realtek/rtw89/core.h |  1 -
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index bd34e4bbe107b..2114d117b603d 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -427,15 +427,23 @@ static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,
 	rtw89_cam_deinit(rtwdev, rtwvif);
 }
 
+void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
+			       struct rtw89_addr_cam_entry *addr_cam)
+{
+	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+
+	addr_cam->valid = false;
+	clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
+}
+
 void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
 	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
 	struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
 	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
 
-	addr_cam->valid = false;
+	rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
 	bssid_cam->valid = false;
-	clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
 	clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
 }
 
@@ -464,10 +472,10 @@ static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
 	return 0;
 }
 
-static int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
-				   struct rtw89_vif *rtwvif)
+int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
+			    struct rtw89_addr_cam_entry *addr_cam,
+			    const struct rtw89_bssid_cam_entry *bssid_cam)
 {
-	struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
 	u8 addr_cam_idx;
 	int i;
 	int ret;
@@ -484,14 +492,17 @@ static int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
 	addr_cam->valid = true;
 	addr_cam->addr_mask = 0;
 	addr_cam->mask_sel = RTW89_NO_MSK;
+	addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
 	bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
-	ether_addr_copy(addr_cam->sma, rtwvif->mac_addr);
 
 	for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
 		addr_cam->sec_ent_keyid[i] = 0;
 		addr_cam->sec_ent[i] = 0;
 	}
 
+	/* associate addr cam with bssid cam */
+	addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
+
 	return 0;
 }
 
@@ -549,21 +560,18 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
 	int ret;
 
-	ret = rtw89_cam_init_addr_cam(rtwdev, rtwvif);
+	ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif);
 	if (ret) {
-		rtw89_err(rtwdev, "failed to init addr cam\n");
+		rtw89_err(rtwdev, "failed to init bssid cam\n");
 		return ret;
 	}
 
-	ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif);
+	ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam);
 	if (ret) {
-		rtw89_err(rtwdev, "failed to init bssid cam\n");
+		rtw89_err(rtwdev, "failed to init addr cam\n");
 		return ret;
 	}
 
-	/* associate addr cam with bssid cam */
-	addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
-
 	return 0;
 }
 
diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h
index 33a3ad582b818..3a6a786530d17 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.h
+++ b/drivers/net/wireless/realtek/rtw89/cam.h
@@ -346,6 +346,11 @@ static inline void FWCMD_SET_ADDR_BSSID_BSSID5(void *cmd, u32 value)
 
 int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
 void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
+int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
+			    struct rtw89_addr_cam_entry *addr_cam,
+			    const struct rtw89_bssid_cam_entry *bssid_cam);
+void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
+			       struct rtw89_addr_cam_entry *addr_cam);
 void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
 				  struct rtw89_vif *vif,
 				  struct rtw89_sta *rtwsta,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 8cb907da6cb05..2dd5c4f0a3636 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1884,7 +1884,6 @@ struct rtw89_addr_cam_entry {
 	u8 wapi		: 1;
 	u8 mask_sel	: 2;
 	u8 bssid_cam_idx: 6;
-	u8 sma[ETH_ALEN];
 
 	u8 sec_ent_mode;
 	DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
-- 
2.25.1


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

* [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (11 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 12/19] rtw89: separate {init,deinit}_addr_cam functions Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-28 15:51   ` Kalle Valo
  2022-01-28 15:53   ` Kalle Valo
  2022-01-07  3:42 ` [PATCH 14/19] rtw89: add addr_cam field to sta " Ping-Ke Shih
                   ` (5 subsequent siblings)
  18 siblings, 2 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Fill mac_id and self_role depends on the operation mode.

In AP mode, echo connected station has an unique mac_id, and each vif also
has one mac_id to represent itself.

The self_role is assigned to vif if the operation mode is decided, and
RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/fw.c  | 8 ++++++--
 drivers/net/wireless/realtek/rtw89/fw.h  | 1 +
 drivers/net/wireless/realtek/rtw89/mac.c | 4 ++--
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 5209813275676..4641aadea0386 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
 #define H2C_ROLE_MAINTAIN_LEN 4
 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
 			       struct rtw89_vif *rtwvif,
+			       struct rtw89_sta *rtwsta,
 			       enum rtw89_upd_mode upd_mode)
 {
 	struct sk_buff *skb;
+	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+	u8 self_role = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta ?
+		       RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;
 
 	skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_ROLE_MAINTAIN_LEN);
 	if (!skb) {
@@ -1003,8 +1007,8 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
 		return -ENOMEM;
 	}
 	skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
-	SET_FWROLE_MAINTAIN_MACID(skb->data, rtwvif->mac_id);
-	SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, rtwvif->self_role);
+	SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
+	SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
 	SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
 	SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
 
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index b30cf0a2cc1e0..83f4eaaf90f3b 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1886,6 +1886,7 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
 void rtw89_fw_c2h_work(struct work_struct *work);
 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
 			       struct rtw89_vif *rtwvif,
+			       struct rtw89_sta *rtwsta,
 			       enum rtw89_upd_mode upd_mode);
 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 			   struct rtw89_sta *rtwsta, bool dis_conn);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 58aa24e71637d..19eb8ea1ba915 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3012,7 +3012,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	if (ret)
 		return ret;
 
-	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_CREATE);
+	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE);
 	if (ret)
 		return ret;
 
@@ -3035,7 +3035,7 @@ int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
 	int ret;
 
-	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_REMOVE);
+	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE);
 	if (ret)
 		return ret;
 
-- 
2.25.1


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

* [PATCH 14/19] rtw89: add addr_cam field to sta to support AP mode
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (12 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 13/19] rtw89: extend role_maintain to support AP mode Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 15/19] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

In AP mode, each connected station needs an entry of address CAM. The
address CAM of vif is still needed to assit in AP itself.

For station mode, it still uses vif's address CAM.

Add a help macro rtw89_get_addr_cam_of() to get addr_cam from vif or sta
for all use cases.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/cam.c  |  6 +--
 drivers/net/wireless/realtek/rtw89/core.c |  5 +-
 drivers/net/wireless/realtek/rtw89/core.h | 62 +++++++++++++----------
 3 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index 2114d117b603d..305dbbebff6bb 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -231,7 +231,7 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
 	}
 
 	rtwvif = (struct rtw89_vif *)vif->drv_priv;
-	addr_cam = &rtwvif->addr_cam;
+	addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
 	ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
 	if (ret) {
 		rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
@@ -387,7 +387,7 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
 	}
 
 	rtwvif = (struct rtw89_vif *)vif->drv_priv;
-	addr_cam = &rtwvif->addr_cam;
+	addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
 	sec_cam = addr_cam->sec_entries[key_idx];
 	if (!sec_cam)
 		return -EINVAL;
@@ -617,7 +617,7 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
 				  u8 *cmd)
 {
 	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
-	struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
+	struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
 	struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
 	const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
 	u8 sma_hash, tma_hash, addr_msk_start;
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 8f8891badf0e8..aeb7289bd8c33 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2,6 +2,7 @@
 /* Copyright(c) 2019-2020  Realtek Corporation
  */
 
+#include "cam.h"
 #include "coex.h"
 #include "core.h"
 #include "efuse.h"
@@ -298,9 +299,11 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
 			     struct rtw89_core_tx_request *tx_req)
 {
 	struct ieee80211_vif *vif = tx_req->vif;
+	struct ieee80211_sta *sta = tx_req->sta;
 	struct ieee80211_tx_info *info;
 	struct ieee80211_key_conf *key;
 	struct rtw89_vif *rtwvif;
+	struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
 	struct rtw89_addr_cam_entry *addr_cam;
 	struct rtw89_sec_cam_entry *sec_cam;
 	struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
@@ -313,7 +316,7 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
 	}
 
 	rtwvif = (struct rtw89_vif *)vif->drv_priv;
-	addr_cam = &rtwvif->addr_cam;
+	addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
 
 	info = IEEE80211_SKB_CB(skb);
 	key = info->control.hw_key;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 2dd5c4f0a3636..cf5981497a299 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1844,32 +1844,6 @@ struct rtw89_ba_cam_entry {
 	u8 tid;
 };
 
-struct rtw89_sta {
-	u8 mac_id;
-	bool disassoc;
-	struct rtw89_vif *rtwvif;
-	struct rtw89_ra_info ra;
-	struct rtw89_ra_report ra_report;
-	int max_agg_wait;
-	u8 prev_rssi;
-	struct ewma_rssi avg_rssi;
-	struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
-	struct ieee80211_rx_status rx_status;
-	u16 rx_hw_rate;
-	__le32 htc_template;
-
-	bool use_cfg_mask;
-	struct cfg80211_bitrate_mask mask;
-
-	bool cctl_tx_time;
-	u32 ampdu_max_time:4;
-	bool cctl_tx_retry_limit;
-	u32 data_tx_cnt_lmt:6;
-
-	DECLARE_BITMAP(ba_cam_map, RTW89_BA_CAM_NUM);
-	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_BA_CAM_NUM];
-};
-
 #define RTW89_MAX_ADDR_CAM_NUM		128
 #define RTW89_MAX_BSSID_CAM_NUM		20
 #define RTW89_MAX_SEC_CAM_NUM		128
@@ -1913,6 +1887,33 @@ struct rtw89_sec_cam_entry {
 	u8 key[32];
 };
 
+struct rtw89_sta {
+	u8 mac_id;
+	bool disassoc;
+	struct rtw89_vif *rtwvif;
+	struct rtw89_ra_info ra;
+	struct rtw89_ra_report ra_report;
+	int max_agg_wait;
+	u8 prev_rssi;
+	struct ewma_rssi avg_rssi;
+	struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
+	struct ieee80211_rx_status rx_status;
+	u16 rx_hw_rate;
+	__le32 htc_template;
+	struct rtw89_addr_cam_entry addr_cam; /* AP mode only */
+
+	bool use_cfg_mask;
+	struct cfg80211_bitrate_mask mask;
+
+	bool cctl_tx_time;
+	u32 ampdu_max_time:4;
+	bool cctl_tx_retry_limit;
+	u32 data_tx_cnt_lmt:6;
+
+	DECLARE_BITMAP(ba_cam_map, RTW89_BA_CAM_NUM);
+	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_BA_CAM_NUM];
+};
+
 struct rtw89_efuse {
 	bool valid;
 	u8 xtal_cap;
@@ -3145,6 +3146,15 @@ static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta)
 	return sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
 }
 
+static inline
+struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
+						   struct rtw89_sta *rtwsta)
+{
+	if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
+		return &rtwsta->addr_cam;
+	return &rtwvif->addr_cam;
+}
+
 static inline
 void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev,
 				    struct rtw89_channel_help_params *p)
-- 
2.25.1


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

* [PATCH 15/19] rtw89: only STA mode change vif_type mapping dynamically
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (13 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 14/19] rtw89: add addr_cam field to sta " Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

vif_type mapping indicates hardware operating mode corresponding to vif
type. In STA mode, hardware mode should be INFRA or NO_LINK mode
dynamically according to association status. Since AP mode don't need to
change this by association status intuitively, just do the mapping in
STA mode.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c     | 4 ++--
 drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index aeb7289bd8c33..4756a2e7a2389 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1944,7 +1944,8 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
 	rtw89_mac_bf_disassoc(rtwdev, vif, sta);
 	rtw89_core_free_sta_pending_ba(rtwdev, sta);
 
-	rtw89_vif_type_mapping(vif, false);
+	if (vif->type == NL80211_IFTYPE_STATION)
+		rtw89_vif_type_mapping(vif, false);
 
 	ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
 	if (ret) {
@@ -1976,7 +1977,6 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
 	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
 	int ret;
 
-	rtw89_vif_type_mapping(vif, true);
 
 	ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
 	if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 26abbe7aa17d8..c7208fad31dd6 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -324,6 +324,9 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
 		rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
 		return;
 	}
+
+	rtw89_vif_type_mapping(vif, true);
+
 	rtw89_core_sta_assoc(rtwdev, vif, sta);
 }
 
-- 
2.25.1


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

* [PATCH 16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (14 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 15/19] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

In AP mode, when a STA associate to us, we need to create an entry in
firmware and hardware, and then they can transmit data properly.

The entry index called mac_id which is assigned when sta_add, and we ask
firmware to create an entry for an associated station. Also, the address
CAM should be filled so hardware can know which packet is ours, and lookup
the mac_id for further use.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 31 ++++++++++++++++++++++-
 drivers/net/wireless/realtek/rtw89/mac.c  |  4 +--
 drivers/net/wireless/realtek/rtw89/mac.h  |  1 +
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 4756a2e7a2389..d23bd87661d7a 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1943,6 +1943,8 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
 	rtw89_mac_bf_monitor_calc(rtwdev, sta, true);
 	rtw89_mac_bf_disassoc(rtwdev, vif, sta);
 	rtw89_core_free_sta_pending_ba(rtwdev, sta);
+	if (vif->type == NL80211_IFTYPE_AP)
+		rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
 
 	if (vif->type == NL80211_IFTYPE_STATION)
 		rtw89_vif_type_mapping(vif, false);
@@ -1959,8 +1961,16 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
 		return ret;
 	}
 
+	if (vif->type == NL80211_IFTYPE_AP) {
+		ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_REMOVE);
+		if (ret) {
+			rtw89_warn(rtwdev, "failed to send h2c role info\n");
+			return ret;
+		}
+	}
+
 	/* update cam aid mac_id net_type */
-	rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+	ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
 	if (ret) {
 		rtw89_warn(rtwdev, "failed to send h2c cam\n");
 		return ret;
@@ -1977,6 +1987,25 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
 	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
 	int ret;
 
+	if (vif->type == NL80211_IFTYPE_AP) {
+		ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false);
+		if (ret) {
+			rtw89_warn(rtwdev, "failed to send h2c macid pause\n");
+			return ret;
+		}
+
+		ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_CREATE);
+		if (ret) {
+			rtw89_warn(rtwdev, "failed to send h2c role info\n");
+			return ret;
+		}
+
+		ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta->addr_cam, &rtwvif->bssid_cam);
+		if (ret) {
+			rtw89_warn(rtwdev, "failed to send h2c init addr cam\n");
+			return ret;
+		}
+	}
 
 	ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
 	if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 19eb8ea1ba915..17a41fddc62e4 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -2705,7 +2705,7 @@ static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
 	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109);
 }
 
-static int rtw89_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
+int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
 {
 	u8 sh =  FIELD_GET(GENMASK(4, 0), macid);
 	u8 grp = macid >> 5;
@@ -3008,7 +3008,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id);
 	rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id);
 
-	ret = rtw89_set_macid_pause(rtwdev, rtwvif->mac_id, false);
+	ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false);
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 65e4ebe05f6ad..ead385c53331b 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -811,6 +811,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
 int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
 int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
 				 struct rtw89_vif *rtwvif, bool en);
+int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause);
 
 static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
 {
-- 
2.25.1


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

* [PATCH 17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (15 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 18/19] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 19/19] rtw89: declare AP mode support Ping-Ke Shih
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Configure firmware and hardware to run AP mode. The start_ap() setup
bssid, mac port, mac_id entry, and does RFK. The stop_ap() reset the
state.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/mac80211.c | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index c7208fad31dd6..091c0aa631855 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -371,6 +371,37 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
 	mutex_unlock(&rtwdev->mutex);
 }
 
+static int rtw89_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct rtw89_dev *rtwdev = hw->priv;
+	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+
+	mutex_lock(&rtwdev->mutex);
+	ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
+	rtw89_cam_bssid_changed(rtwdev, rtwvif);
+	rtw89_mac_port_update(rtwdev, rtwvif);
+	rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
+	rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
+	rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+	rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+	rtw89_chip_rfk_channel(rtwdev);
+	mutex_unlock(&rtwdev->mutex);
+
+	return 0;
+}
+
+static
+void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct rtw89_dev *rtwdev = hw->priv;
+	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+
+	mutex_lock(&rtwdev->mutex);
+	rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
+	rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+	mutex_unlock(&rtwdev->mutex);
+}
+
 static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
 			     bool set)
 {
@@ -699,6 +730,8 @@ const struct ieee80211_ops rtw89_ops = {
 	.remove_interface	= rtw89_ops_remove_interface,
 	.configure_filter	= rtw89_ops_configure_filter,
 	.bss_info_changed	= rtw89_ops_bss_info_changed,
+	.start_ap		= rtw89_ops_start_ap,
+	.stop_ap		= rtw89_ops_stop_ap,
 	.set_tim		= rtw89_ops_set_tim,
 	.conf_tx		= rtw89_ops_conf_tx,
 	.sta_state		= rtw89_ops_sta_state,
-- 
2.25.1


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

* [PATCH 18/19] rtw89: debug: add stations entry to show ID assignment
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (16 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  2022-01-07  3:42 ` [PATCH 19/19] rtw89: declare AP mode support Ping-Ke Shih
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

In order to trace the relation of IDs, we add this debugfs entry to make
them clear.

The output looks like:
  map:
          mac_id:    07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          addr_cam:  07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          bssid_cam: 01 00 00 00 00 00 00 00
          sec_cam:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  VIF [0] 94:08:53:8e:ef:21
          bssid_cam_idx=0
          addr_cam_idx=0
          -> bssid_cam_idx=0
          sec_cam_bitmap=00 00 00 00 00 00 00 00
  STA [1] 58:00:e3:bb:9c:4f
          addr_cam_idx=1
          -> bssid_cam_idx=0
          sec_cam_bitmap=00 00 00 00 00 00 00 00
  STA [2] 94:08:53:8e:ef:75
          addr_cam_idx=2
          -> bssid_cam_idx=0
          sec_cam_bitmap=00 00 00 00 00 00 00 00

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/debug.c | 71 ++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 9756d75ef24e1..45fefa8bd9562 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -2364,6 +2364,72 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
 	return 0;
 }
 
+static void rtw89_dump_addr_cam(struct seq_file *m,
+				struct rtw89_addr_cam_entry *addr_cam)
+{
+	struct rtw89_sec_cam_entry *sec_entry;
+	int i;
+
+	seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx);
+	seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx);
+	seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map),
+		   addr_cam->sec_cam_map);
+	for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
+		sec_entry = addr_cam->sec_entries[i];
+		if (!sec_entry)
+			continue;
+		seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx);
+		if (sec_entry->ext_key)
+			seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1);
+		seq_puts(m, "\n");
+	}
+}
+
+static
+void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+	struct seq_file *m = (struct seq_file *)data;
+	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+
+	seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
+	seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
+	rtw89_dump_addr_cam(m, &rtwvif->addr_cam);
+}
+
+static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
+{
+	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+	struct seq_file *m = (struct seq_file *)data;
+
+	seq_printf(m, "STA [%d] %pM\n", rtwsta->mac_id, sta->addr);
+	rtw89_dump_addr_cam(m, &rtwsta->addr_cam);
+}
+
+static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
+{
+	struct rtw89_debugfs_priv *debugfs_priv = m->private;
+	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+
+	seq_puts(m, "map:\n");
+	seq_printf(m, "\tmac_id:    %*ph\n", (int)sizeof(rtwdev->mac_id_map),
+		   rtwdev->mac_id_map);
+	seq_printf(m, "\taddr_cam:  %*ph\n", (int)sizeof(cam_info->addr_cam_map),
+		   cam_info->addr_cam_map);
+	seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map),
+		   cam_info->bssid_cam_map);
+	seq_printf(m, "\tsec_cam:   %*ph\n", (int)sizeof(cam_info->sec_cam_map),
+		   cam_info->sec_cam_map);
+
+	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
+		IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
+
+	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
+
+	return 0;
+}
+
 static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = {
 	.cb_read = rtw89_debug_priv_read_reg_get,
 	.cb_write = rtw89_debug_priv_read_reg_select,
@@ -2430,6 +2496,10 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = {
 	.cb_read = rtw89_debug_priv_phy_info_get,
 };
 
+static struct rtw89_debugfs_priv rtw89_debug_priv_stations = {
+	.cb_read = rtw89_debug_priv_stations_get,
+};
+
 #define rtw89_debugfs_add(name, mode, fopname, parent)				\
 	do {									\
 		rtw89_debug_priv_ ##name.rtwdev = rtwdev;			\
@@ -2468,6 +2538,7 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
 	rtw89_debugfs_add_w(btc_manual);
 	rtw89_debugfs_add_w(fw_log_manual);
 	rtw89_debugfs_add_r(phy_info);
+	rtw89_debugfs_add_r(stations);
 }
 #endif
 
-- 
2.25.1


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

* [PATCH 19/19] rtw89: declare AP mode support
  2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
                   ` (17 preceding siblings ...)
  2022-01-07  3:42 ` [PATCH 18/19] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
@ 2022-01-07  3:42 ` Ping-Ke Shih
  18 siblings, 0 replies; 26+ messages in thread
From: Ping-Ke Shih @ 2022-01-07  3:42 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

Things are ready for AP mode, so declare this driver can support it.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index d23bd87661d7a..10eb575b05be0 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2561,7 +2561,8 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
 	ieee80211_hw_set(hw, SUPPORTS_PS);
 	ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
 
-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+				     BIT(NL80211_IFTYPE_AP);
 	hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1;
 	hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1;
 
-- 
2.25.1


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

* Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-01-07  3:42 ` [PATCH 13/19] rtw89: extend role_maintain to support AP mode Ping-Ke Shih
@ 2022-01-28 15:51   ` Kalle Valo
  2022-01-29  3:36     ` Pkshih
  2022-01-28 15:53   ` Kalle Valo
  1 sibling, 1 reply; 26+ messages in thread
From: Kalle Valo @ 2022-01-28 15:51 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: linux-wireless

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

> Fill mac_id and self_role depends on the operation mode.
>
> In AP mode, echo connected station has an unique mac_id, and each vif also
> has one mac_id to represent itself.
>
> The self_role is assigned to vif if the operation mode is decided, and
> RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> ---
>  drivers/net/wireless/realtek/rtw89/fw.c  | 8 ++++++--
>  drivers/net/wireless/realtek/rtw89/fw.h  | 1 +
>  drivers/net/wireless/realtek/rtw89/mac.c | 4 ++--
>  3 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
> index 5209813275676..4641aadea0386 100644
> --- a/drivers/net/wireless/realtek/rtw89/fw.c
> +++ b/drivers/net/wireless/realtek/rtw89/fw.c
> @@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
>  #define H2C_ROLE_MAINTAIN_LEN 4
>  int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
>  			       struct rtw89_vif *rtwvif,
> +			       struct rtw89_sta *rtwsta,
>  			       enum rtw89_upd_mode upd_mode)
>  {
>  	struct sk_buff *skb;
> +	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
> +	u8 self_role = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta ?
> +		       RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;

It seems you like '?' operator more than I do, and it's ok to use in
simple cases. But the latter statement is not really readable, something
like this is so much easier to read:

if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
    self_role = RTW89_SELF_ROLE_AP_CLIENT
else
    self_role = rtwvif->self_role;

But should there a parenthesis around the == operator? I cannot now
recall what's the preference in the kernel, can someone help on that?

Maybe I also move check for rtwsta first?

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

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

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

* Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-01-07  3:42 ` [PATCH 13/19] rtw89: extend role_maintain to support AP mode Ping-Ke Shih
  2022-01-28 15:51   ` Kalle Valo
@ 2022-01-28 15:53   ` Kalle Valo
  1 sibling, 0 replies; 26+ messages in thread
From: Kalle Valo @ 2022-01-28 15:53 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: linux-wireless

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

> Fill mac_id and self_role depends on the operation mode.
> 
> In AP mode, echo connected station has an unique mac_id, and each vif also
> has one mac_id to represent itself.
> 
> The self_role is assigned to vif if the operation mode is decided, and
> RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
> 
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

Dropping rest of the patches due to my comment.

7 patches set to Changes Requested.

12706170 [13/19] rtw89: extend role_maintain to support AP mode
12706171 [14/19] rtw89: add addr_cam field to sta to support AP mode
12706172 [15/19] rtw89: only STA mode change vif_type mapping dynamically
12706173 [16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware
12706174 [17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap
12706175 [18/19] rtw89: debug: add stations entry to show ID assignment
12706176 [19/19] rtw89: declare AP mode support

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

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


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

* Re: [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ
  2022-01-07  3:42 ` [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ Ping-Ke Shih
@ 2022-01-28 15:57   ` Kalle Valo
  0 siblings, 0 replies; 26+ messages in thread
From: Kalle Valo @ 2022-01-28 15:57 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: linux-wireless

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

> With this patch, we can receive probe_req and reply probe_resp, and STA
> can find us.
> 
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

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

6629dc5697cc rtw89: configure rx_filter according to FIF_PROBE_REQ
91644020dbd9 rtw89: use hardware SSN to TX management frame
f7e76d13bb2b rtw89: download beacon content to firmware
fccca9345b25 rtw89: add C2H handle of BCN_CNT
d62816b4a44e rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets
c7df64c194f6 rtw89: allocate mac_id for each station in AP mode
742c470b5773 rtw89: extend firmware commands on states of sta_assoc and sta_disconnect
8b252070d790 rtw89: rename vif_maintain to role_maintain
283c3d886fdf rtw89: configure mac port HIQ registers
11d261f24be6 rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode
9eecaec238c8 rtw89: set mac_id and port ID to TXWD
14f0999d49e7 rtw89: separate {init,deinit}_addr_cam functions

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

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


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

* Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-01-28 15:51   ` Kalle Valo
@ 2022-01-29  3:36     ` Pkshih
  2022-02-03  8:42       ` Kalle Valo
  0 siblings, 1 reply; 26+ messages in thread
From: Pkshih @ 2022-01-29  3:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

On Fri, 2022-01-28 at 17:51 +0200, Kalle Valo wrote:
> Ping-Ke Shih <pkshih@realtek.com> writes:
> 
> > Fill mac_id and self_role depends on the operation mode.
> > 
> > In AP mode, echo connected station has an unique mac_id, and each vif also
> > has one mac_id to represent itself.
> > 
> > The self_role is assigned to vif if the operation mode is decided, and
> > RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
> > 
> > Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> > ---
> >  drivers/net/wireless/realtek/rtw89/fw.c  | 8 ++++++--
> >  drivers/net/wireless/realtek/rtw89/fw.h  | 1 +
> >  drivers/net/wireless/realtek/rtw89/mac.c | 4 ++--
> >  3 files changed, 9 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
> > index 5209813275676..4641aadea0386 100644
> > --- a/drivers/net/wireless/realtek/rtw89/fw.c
> > +++ b/drivers/net/wireless/realtek/rtw89/fw.c
> > @@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
> >  #define H2C_ROLE_MAINTAIN_LEN 4
> >  int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
> >  			       struct rtw89_vif *rtwvif,
> > +			       struct rtw89_sta *rtwsta,
> >  			       enum rtw89_upd_mode upd_mode)
> >  {
> >  	struct sk_buff *skb;
> > +	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
> > +	u8 self_role = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta ?
> > +		       RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;
> 
> It seems you like '?' operator more than I do, and it's ok to use in
> simple cases. But the latter statement is not really readable, something
> like this is so much easier to read:
> 
> if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
>     self_role = RTW89_SELF_ROLE_AP_CLIENT
> else
>     self_role = rtwvif->self_role;
> 

I use '?' to make code shorter, but your sugeestion would be eaiser to reviewer.
I will send v2 after the Lunar New Year. 


> But should there a parenthesis around the == operator? I cannot now
> recall what's the preference in the kernel, can someone help on that?

The checkpatch will warn this if we add parenthesis, so preence is not to
use parenthesis.

CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'rtwvif->net_type ==
RTW89_NET_TYPE_AP_MODE'
#9: FILE: fw.c:1004:
+	if ((rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) && rtwsta)

> 
> Maybe I also move check for rtwsta first?
> 

The full logic is 

if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
    if (rtwsta)
        self_role = RTW89_SELF_ROLE_AP_CLIENT
    else
        self_role = rtwvif->self_role;
} else {
    self_role = rtwvif->self_role;
}

And, the meaning of 'rtwsta' here is to indicate we are going to setup 
a connected station that connects to this AP, but not check if the
pointer is NULL. To emphasis the case is only existing in AP_MODE,
I prefer to check net_type ahead. Or, this full logic is preferred?


Ping-Ke


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

* Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-01-29  3:36     ` Pkshih
@ 2022-02-03  8:42       ` Kalle Valo
  2022-02-03  9:41         ` Pkshih
  0 siblings, 1 reply; 26+ messages in thread
From: Kalle Valo @ 2022-02-03  8:42 UTC (permalink / raw)
  To: Pkshih; +Cc: linux-wireless

Pkshih <pkshih@realtek.com> writes:

> On Fri, 2022-01-28 at 17:51 +0200, Kalle Valo wrote:
>> Ping-Ke Shih <pkshih@realtek.com> writes:
>> 
>> > Fill mac_id and self_role depends on the operation mode.
>> > 
>> > In AP mode, echo connected station has an unique mac_id, and each vif also
>> > has one mac_id to represent itself.
>> > 
>> > The self_role is assigned to vif if the operation mode is decided, and
>> > RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
>> > 
>> > Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
>> > ---
>> >  drivers/net/wireless/realtek/rtw89/fw.c  | 8 ++++++--
>> >  drivers/net/wireless/realtek/rtw89/fw.h  | 1 +
>> >  drivers/net/wireless/realtek/rtw89/mac.c | 4 ++--
>> >  3 files changed, 9 insertions(+), 4 deletions(-)
>> > 
>> > diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
>> > index 5209813275676..4641aadea0386 100644
>> > --- a/drivers/net/wireless/realtek/rtw89/fw.c
>> > +++ b/drivers/net/wireless/realtek/rtw89/fw.c
>> > @@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
>> >  #define H2C_ROLE_MAINTAIN_LEN 4
>> >  int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
>> >  			       struct rtw89_vif *rtwvif,
>> > +			       struct rtw89_sta *rtwsta,
>> >  			       enum rtw89_upd_mode upd_mode)
>> >  {
>> >  	struct sk_buff *skb;
>> > +	u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
>> > +	u8 self_role = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta ?
>> > +		       RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;
>> 
>> It seems you like '?' operator more than I do, and it's ok to use in
>> simple cases. But the latter statement is not really readable, something
>> like this is so much easier to read:
>> 
>> if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
>>     self_role = RTW89_SELF_ROLE_AP_CLIENT
>> else
>>     self_role = rtwvif->self_role;
>> 
>
> I use '?' to make code shorter, but your sugeestion would be eaiser to reviewer.
> I will send v2 after the Lunar New Year.

Happy New Year :)

>> But should there a parenthesis around the == operator? I cannot now
>> recall what's the preference in the kernel, can someone help on that?
>
> The checkpatch will warn this if we add parenthesis, so preence is not to
> use parenthesis.
>
> CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'rtwvif->net_type ==
> RTW89_NET_TYPE_AP_MODE'
> #9: FILE: fw.c:1004:
> +	if ((rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) && rtwsta)

Ok, I need to remember that :)

>> Maybe I also move check for rtwsta first?
>> 
>
> The full logic is 
>
> if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
>     if (rtwsta)
>         self_role = RTW89_SELF_ROLE_AP_CLIENT
>     else
>         self_role = rtwvif->self_role;
> } else {
>     self_role = rtwvif->self_role;
> }
>
> And, the meaning of 'rtwsta' here is to indicate we are going to setup 
> a connected station that connects to this AP, but not check if the
> pointer is NULL. To emphasis the case is only existing in AP_MODE,
> I prefer to check net_type ahead. Or, this full logic is preferred?

I don't know what others think, but I find this full logic style most
readable.

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

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

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

* Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
  2022-02-03  8:42       ` Kalle Valo
@ 2022-02-03  9:41         ` Pkshih
  0 siblings, 0 replies; 26+ messages in thread
From: Pkshih @ 2022-02-03  9:41 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

On Thu, 2022-02-03 at 10:42 +0200, Kalle Valo wrote:
> Pkshih <pkshih@realtek.com> writes:
> 
> > On Fri, 2022-01-28 at 17:51 +0200, Kalle Valo wrote:
> > > 
> > > Maybe I also move check for rtwsta first?
> > > 
> > 
> > The full logic is 
> > 
> > if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
> >     if (rtwsta)
> >         self_role = RTW89_SELF_ROLE_AP_CLIENT
> >     else
> >         self_role = rtwvif->self_role;
> > } else {
> >     self_role = rtwvif->self_role;
> > }
> > 
> > And, the meaning of 'rtwsta' here is to indicate we are going to setup 
> > a connected station that connects to this AP, but not check if the
> > pointer is NULL. To emphasis the case is only existing in AP_MODE,
> > I prefer to check net_type ahead. Or, this full logic is preferred?
> 
> I don't know what others think, but I find this full logic style most
> readable.
> 

Maybe, a static analysis tool warns two else branches are the same. 
If so, we can make a decision at that time.
 
I will send v2 next week, and wait for people who have other ideas.

Happy New Year.
--
Ping-Ke



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

end of thread, other threads:[~2022-02-03  9:41 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-07  3:42 [PATCH 00/19] rtw89: support AP mode Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ Ping-Ke Shih
2022-01-28 15:57   ` Kalle Valo
2022-01-07  3:42 ` [PATCH 02/19] rtw89: use hardware SSN to TX management frame Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 03/19] rtw89: download beacon content to firmware Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 04/19] rtw89: add C2H handle of BCN_CNT Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 05/19] rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 06/19] rtw89: allocate mac_id for each station in AP mode Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 07/19] rtw89: extend firmware commands on states of sta_assoc and sta_disconnect Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 08/19] rtw89: rename vif_maintain to role_maintain Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 09/19] rtw89: configure mac port HIQ registers Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 10/19] rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 11/19] rtw89: set mac_id and port ID to TXWD Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 12/19] rtw89: separate {init,deinit}_addr_cam functions Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 13/19] rtw89: extend role_maintain to support AP mode Ping-Ke Shih
2022-01-28 15:51   ` Kalle Valo
2022-01-29  3:36     ` Pkshih
2022-02-03  8:42       ` Kalle Valo
2022-02-03  9:41         ` Pkshih
2022-01-28 15:53   ` Kalle Valo
2022-01-07  3:42 ` [PATCH 14/19] rtw89: add addr_cam field to sta " Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 15/19] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 18/19] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
2022-01-07  3:42 ` [PATCH 19/19] rtw89: declare AP mode support 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).