]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw88: assign mac_id for vif/sta and update to TX desc
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 19 Aug 2024 02:52:48 +0000 (10:52 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 2 Sep 2024 00:44:54 +0000 (08:44 +0800)
A mac_id as an instance in firmware has to be assigned for each station
including AP and connected stations. Firmware will use the mac_id to
control TX rate and do statistics.

Assignment rule is to assign mac_id to each vif when adding vif.
For station mode, sta->mac_id will reuse vif->mac_id. For AP mode,
dynamically allocate an sta->mac_id to a station, and vif->mac_id is
used to send broadcast/multicast packets which are not belong to
a station. For example,

                  vif->mac_id      sta->mac_id
vif0 (STA mode)        0               0
vif1 (AP mode)         1               2...

By the way, remove unused RTW_BC_MC_MACID, which was planed to send
broadcast/multicast packets on fixed mac_id.

Tested-on RTL8822CE with STA + AP SCC mode.

Link: https://lore.kernel.org/linux-wireless/e4be0a75-43b2-4ae5-9aab-5c4a88e78097@gmail.com/
Cc: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240819025248.17939-1-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/mac80211.c
drivers/net/wireless/realtek/rtw88/main.c
drivers/net/wireless/realtek/rtw88/main.h
drivers/net/wireless/realtek/rtw88/tx.c
drivers/net/wireless/realtek/rtw88/tx.h

index 63326b35273895e7f45a4e1ec16af96a5afd4b04..b39e90fb66b41ddb29e7b8f6dd441d3eb6877dc6 100644 (file)
@@ -167,6 +167,12 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
 
        mutex_lock(&rtwdev->mutex);
 
+       rtwvif->mac_id = rtw_acquire_macid(rtwdev);
+       if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) {
+               mutex_unlock(&rtwdev->mutex);
+               return -ENOSPC;
+       }
+
        port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM);
        if (port >= RTW_PORT_NUM) {
                mutex_unlock(&rtwdev->mutex);
@@ -214,7 +220,8 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
 
        mutex_unlock(&rtwdev->mutex);
 
-       rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n",
+               vif->addr, rtwvif->mac_id, rtwvif->port);
        return 0;
 }
 
@@ -225,7 +232,8 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
        struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
        u32 config = 0;
 
-       rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n",
+               vif->addr, rtwvif->mac_id, rtwvif->port);
 
        mutex_lock(&rtwdev->mutex);
 
@@ -242,6 +250,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
        config |= PORT_SET_BCN_CTRL;
        rtw_vif_port_config(rtwdev, rtwvif, config);
        clear_bit(rtwvif->port, rtwdev->hw_port);
+       rtw_release_macid(rtwdev, rtwvif->mac_id);
        rtw_recalc_lps(rtwdev, NULL);
 
        mutex_unlock(&rtwdev->mutex);
index b0c9b0ff7017a68d7f26dee7ac1894a60f9ed582..bbdef38c7e341c992c18c6e2d729d1d00acb985d 100644 (file)
@@ -311,17 +311,6 @@ static void rtw_ips_work(struct work_struct *work)
        mutex_unlock(&rtwdev->mutex);
 }
 
-static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
-{
-       unsigned long mac_id;
-
-       mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
-       if (mac_id < RTW_MAX_MAC_ID_NUM)
-               set_bit(mac_id, rtwdev->mac_id_map);
-
-       return mac_id;
-}
-
 static void rtw_sta_rc_work(struct work_struct *work)
 {
        struct rtw_sta_info *si = container_of(work, struct rtw_sta_info,
@@ -340,12 +329,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
        struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
        int i;
 
-       si->mac_id = rtw_acquire_macid(rtwdev);
-       if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
-               return -ENOSPC;
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               si->mac_id = rtwvif->mac_id;
+       } else {
+               si->mac_id = rtw_acquire_macid(rtwdev);
+               if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
+                       return -ENOSPC;
+       }
 
-       if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
-               rtwvif->mac_id = si->mac_id;
        si->rtwdev = rtwdev;
        si->sta = sta;
        si->vif = vif;
@@ -370,11 +361,13 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
                    bool fw_exist)
 {
        struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
+       struct ieee80211_vif *vif = si->vif;
        int i;
 
        cancel_work_sync(&si->rc_work);
 
-       rtw_release_macid(rtwdev, si->mac_id);
+       if (vif->type != NL80211_IFTYPE_STATION)
+               rtw_release_macid(rtwdev, si->mac_id);
        if (fw_exist)
                rtw_fw_media_status_report(rtwdev, si->mac_id, false);
 
@@ -614,6 +607,8 @@ static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
        rtw_bf_disassoc(rtwdev, vif, NULL);
        rtw_vif_assoc_changed(rtwvif, NULL);
        rtw_txq_cleanup(rtwdev, vif->txq);
+
+       rtw_release_macid(rtwdev, rtwvif->mac_id);
 }
 
 void rtw_fw_recovery(struct rtw_dev *rtwdev)
@@ -2139,7 +2134,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
        rtwdev->sec.total_cam_num = 32;
        rtwdev->hal.current_channel = 1;
        rtwdev->dm_info.fix_rate = U8_MAX;
-       set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
 
        rtw_stats_init(rtwdev);
 
index 12b564ad3a58c7af180317c518f68562c4443e44..945117afe1438bc5c9c2788bc727f6b9dd1089a9 100644 (file)
@@ -742,7 +742,6 @@ struct rtw_txq {
        unsigned long flags;
 };
 
-#define RTW_BC_MC_MACID 1
 DECLARE_EWMA(rssi, 10, 16);
 
 struct rtw_sta_info {
@@ -805,7 +804,7 @@ struct rtw_bf_info {
 struct rtw_vif {
        enum rtw_net_type net_type;
        u16 aid;
-       u8 mac_id; /* for STA mode only */
+       u8 mac_id;
        u8 mac_addr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
        u8 port;
@@ -2131,6 +2130,17 @@ static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev)
        return rtwdev->chip->tx_stbc;
 }
 
+static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
+{
+       unsigned long mac_id;
+
+       mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
+       if (mac_id < RTW_MAX_MAC_ID_NUM)
+               set_bit(mac_id, rtwdev->mac_id_map);
+
+       return mac_id;
+}
+
 static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
 {
        clear_bit(mac_id, rtwdev->mac_id_map);
index c02ac673be321dbb171234c2c6300185dfacbada..dae7ca14886507905c5aaca05b1bb13a981789dd 100644 (file)
@@ -46,7 +46,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
                      le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) |
                      le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ);
 
-       tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
+       tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) |
+                     le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
                      le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) |
                      le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) |
                      le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) |
@@ -401,14 +402,18 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
        const struct rtw_chip_info *chip = rtwdev->chip;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_vif *vif = info->control.vif;
        struct rtw_sta_info *si;
-       struct ieee80211_vif *vif = NULL;
+       struct rtw_vif *rtwvif;
        __le16 fc = hdr->frame_control;
        bool bmc;
 
        if (sta) {
                si = (struct rtw_sta_info *)sta->drv_priv;
-               vif = si->vif;
+               pkt_info->mac_id = si->mac_id;
+       } else if (vif) {
+               rtwvif = (struct rtw_vif *)vif->drv_priv;
+               pkt_info->mac_id = rtwvif->mac_id;
        }
 
        if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
index 3241896062577ba771cc6225ae503c273856ada7..3d544fd7f60f517aa2067eaa5809c4a7becc306c 100644 (file)
@@ -27,6 +27,7 @@ struct rtw_tx_desc {
 #define RTW_TX_DESC_W0_BMC BIT(24)
 #define RTW_TX_DESC_W0_LS BIT(26)
 #define RTW_TX_DESC_W0_DISQSELSEQ BIT(31)
+#define RTW_TX_DESC_W1_MACID GENMASK(7, 0)
 #define RTW_TX_DESC_W1_QSEL GENMASK(12, 8)
 #define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16)
 #define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22)