1 From 902cb7b11f9a7ff07233cc4c626b54c3e4703149 Mon Sep 17 00:00:00 2001
2 From: Ping-Ke Shih <pkshih@realtek.com>
3 Date: Mon, 19 Aug 2024 10:52:48 +0800
4 Subject: [PATCH] wifi: rtw88: assign mac_id for vif/sta and update to TX desc
6 A mac_id as an instance in firmware has to be assigned for each station
7 including AP and connected stations. Firmware will use the mac_id to
8 control TX rate and do statistics.
10 Assignment rule is to assign mac_id to each vif when adding vif.
11 For station mode, sta->mac_id will reuse vif->mac_id. For AP mode,
12 dynamically allocate an sta->mac_id to a station, and vif->mac_id is
13 used to send broadcast/multicast packets which are not belong to
14 a station. For example,
16 vif->mac_id sta->mac_id
20 By the way, remove unused RTW_BC_MC_MACID, which was planed to send
21 broadcast/multicast packets on fixed mac_id.
23 Tested-on RTL8822CE with STA + AP SCC mode.
25 Link: https://lore.kernel.org/linux-wireless/e4be0a75-43b2-4ae5-9aab-5c4a88e78097@gmail.com/
26 Cc: Bitterblue Smith <rtl8821cerfe2@gmail.com>
27 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
28 Link: https://patch.msgid.link/20240819025248.17939-1-pkshih@realtek.com
30 drivers/net/wireless/realtek/rtw88/mac80211.c | 13 ++++++--
31 drivers/net/wireless/realtek/rtw88/main.c | 30 ++++++++-----------
32 drivers/net/wireless/realtek/rtw88/main.h | 14 +++++++--
33 drivers/net/wireless/realtek/rtw88/tx.c | 11 +++++--
34 drivers/net/wireless/realtek/rtw88/tx.h | 1 +
35 5 files changed, 44 insertions(+), 25 deletions(-)
37 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c
38 +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
39 @@ -167,6 +167,12 @@ static int rtw_ops_add_interface(struct
41 mutex_lock(&rtwdev->mutex);
43 + rtwvif->mac_id = rtw_acquire_macid(rtwdev);
44 + if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) {
45 + mutex_unlock(&rtwdev->mutex);
49 port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM);
50 if (port >= RTW_PORT_NUM) {
51 mutex_unlock(&rtwdev->mutex);
52 @@ -214,7 +220,8 @@ static int rtw_ops_add_interface(struct
54 mutex_unlock(&rtwdev->mutex);
56 - rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
57 + rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n",
58 + vif->addr, rtwvif->mac_id, rtwvif->port);
62 @@ -225,7 +232,8 @@ static void rtw_ops_remove_interface(str
63 struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
66 - rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
67 + rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n",
68 + vif->addr, rtwvif->mac_id, rtwvif->port);
70 mutex_lock(&rtwdev->mutex);
72 @@ -242,6 +250,7 @@ static void rtw_ops_remove_interface(str
73 config |= PORT_SET_BCN_CTRL;
74 rtw_vif_port_config(rtwdev, rtwvif, config);
75 clear_bit(rtwvif->port, rtwdev->hw_port);
76 + rtw_release_macid(rtwdev, rtwvif->mac_id);
77 rtw_recalc_lps(rtwdev, NULL);
79 mutex_unlock(&rtwdev->mutex);
80 --- a/drivers/net/wireless/realtek/rtw88/main.c
81 +++ b/drivers/net/wireless/realtek/rtw88/main.c
82 @@ -311,17 +311,6 @@ static void rtw_ips_work(struct work_str
83 mutex_unlock(&rtwdev->mutex);
86 -static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
88 - unsigned long mac_id;
90 - mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
91 - if (mac_id < RTW_MAX_MAC_ID_NUM)
92 - set_bit(mac_id, rtwdev->mac_id_map);
97 static void rtw_sta_rc_work(struct work_struct *work)
99 struct rtw_sta_info *si = container_of(work, struct rtw_sta_info,
100 @@ -340,12 +329,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev,
101 struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
104 - si->mac_id = rtw_acquire_macid(rtwdev);
105 - if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
107 + if (vif->type == NL80211_IFTYPE_STATION) {
108 + si->mac_id = rtwvif->mac_id;
110 + si->mac_id = rtw_acquire_macid(rtwdev);
111 + if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
115 - if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
116 - rtwvif->mac_id = si->mac_id;
120 @@ -370,11 +361,13 @@ void rtw_sta_remove(struct rtw_dev *rtwd
123 struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
124 + struct ieee80211_vif *vif = si->vif;
127 cancel_work_sync(&si->rc_work);
129 - rtw_release_macid(rtwdev, si->mac_id);
130 + if (vif->type != NL80211_IFTYPE_STATION)
131 + rtw_release_macid(rtwdev, si->mac_id);
133 rtw_fw_media_status_report(rtwdev, si->mac_id, false);
135 @@ -614,6 +607,8 @@ static void rtw_reset_vif_iter(void *dat
136 rtw_bf_disassoc(rtwdev, vif, NULL);
137 rtw_vif_assoc_changed(rtwvif, NULL);
138 rtw_txq_cleanup(rtwdev, vif->txq);
140 + rtw_release_macid(rtwdev, rtwvif->mac_id);
143 void rtw_fw_recovery(struct rtw_dev *rtwdev)
144 @@ -2139,7 +2134,6 @@ int rtw_core_init(struct rtw_dev *rtwdev
145 rtwdev->sec.total_cam_num = 32;
146 rtwdev->hal.current_channel = 1;
147 rtwdev->dm_info.fix_rate = U8_MAX;
148 - set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
150 rtw_stats_init(rtwdev);
152 --- a/drivers/net/wireless/realtek/rtw88/main.h
153 +++ b/drivers/net/wireless/realtek/rtw88/main.h
154 @@ -742,7 +742,6 @@ struct rtw_txq {
158 -#define RTW_BC_MC_MACID 1
159 DECLARE_EWMA(rssi, 10, 16);
161 struct rtw_sta_info {
162 @@ -805,7 +804,7 @@ struct rtw_bf_info {
164 enum rtw_net_type net_type;
166 - u8 mac_id; /* for STA mode only */
168 u8 mac_addr[ETH_ALEN];
171 @@ -2131,6 +2130,17 @@ static inline bool rtw_chip_has_tx_stbc(
172 return rtwdev->chip->tx_stbc;
175 +static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
177 + unsigned long mac_id;
179 + mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
180 + if (mac_id < RTW_MAX_MAC_ID_NUM)
181 + set_bit(mac_id, rtwdev->mac_id_map);
186 static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
188 clear_bit(mac_id, rtwdev->mac_id_map);
189 --- a/drivers/net/wireless/realtek/rtw88/tx.c
190 +++ b/drivers/net/wireless/realtek/rtw88/tx.c
191 @@ -46,7 +46,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p
192 le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) |
193 le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ);
195 - tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
196 + tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) |
197 + le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
198 le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) |
199 le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) |
200 le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) |
201 @@ -401,14 +402,18 @@ void rtw_tx_pkt_info_update(struct rtw_d
202 const struct rtw_chip_info *chip = rtwdev->chip;
203 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
204 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
205 + struct ieee80211_vif *vif = info->control.vif;
206 struct rtw_sta_info *si;
207 - struct ieee80211_vif *vif = NULL;
208 + struct rtw_vif *rtwvif;
209 __le16 fc = hdr->frame_control;
213 si = (struct rtw_sta_info *)sta->drv_priv;
215 + pkt_info->mac_id = si->mac_id;
217 + rtwvif = (struct rtw_vif *)vif->drv_priv;
218 + pkt_info->mac_id = rtwvif->mac_id;
221 if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
222 --- a/drivers/net/wireless/realtek/rtw88/tx.h
223 +++ b/drivers/net/wireless/realtek/rtw88/tx.h
224 @@ -27,6 +27,7 @@ struct rtw_tx_desc {
225 #define RTW_TX_DESC_W0_BMC BIT(24)
226 #define RTW_TX_DESC_W0_LS BIT(26)
227 #define RTW_TX_DESC_W0_DISQSELSEQ BIT(31)
228 +#define RTW_TX_DESC_W1_MACID GENMASK(7, 0)
229 #define RTW_TX_DESC_W1_QSEL GENMASK(12, 8)
230 #define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16)
231 #define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22)