]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: mt76: mt7915: use mac80211 .sta_state op
authorFelix Fietkau <nbd@nbd.name>
Tue, 27 Aug 2024 09:29:59 +0000 (11:29 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 6 Sep 2024 12:23:06 +0000 (14:23 +0200)
Allows adding stations before assoc, though they are not passed to the
firmware yet at that point.

Link: https://patch.msgid.link/20240827093011.18621-12-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/main.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
drivers/net/wireless/mediatek/mt76/tx.c

index f1cd9dc86b42303e1774a5ae9e99d85f68517c2c..43e743b510ba6cabca86db821517e1eb9228d8b4 100644 (file)
@@ -347,6 +347,7 @@ struct mt76_wcid {
        u8 hw_key_idx2;
 
        u8 sta:1;
+       u8 sta_disabled:1;
        u8 amsdu:1;
        u8 phy_idx:2;
        u8 link_id:4;
index 7afb9ac30ab95adf5a10b3ae50f59aa9bfa931ac..3a575cebe4a9ab9bf1bec9b10bf30c8bcc948fa5 100644 (file)
@@ -283,7 +283,7 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
        };
        struct sk_buff *skb;
 
-       if (wcid && !wcid->sta)
+       if (wcid && !wcid->sta && !wcid->sta_disabled)
                hdr.muar_idx = 0xe;
 
        mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
index a89674d6b6029a98fb1f0b7957dfc5a583948089..9bf308429db396249efb56edb317ceccd47c50a9 100644 (file)
@@ -274,7 +274,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
        memset(&mvif->cap, -1, sizeof(mvif->cap));
 
        mt7915_mcu_add_bss_info(phy, vif, true);
-       mt7915_mcu_add_sta(dev, vif, NULL, true);
+       mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true);
        rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
 
 out:
@@ -293,7 +293,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
        int idx = msta->wcid.idx;
 
        mt7915_mcu_add_bss_info(phy, vif, false);
-       mt7915_mcu_add_sta(dev, vif, NULL, false);
+       mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);
        mt76_wcid_mask_clear(dev->mt76.wcid_mask, mvif->sta.wcid.idx);
 
        mutex_lock(&dev->mt76.mutex);
@@ -366,6 +366,9 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        int idx = key->keyidx;
        int err = 0;
 
+       if (sta && !wcid->sta)
+               return -EOPNOTSUPP;
+
        /* The hardware does not support per-STA RX GTK, fallback
         * to software mode for these.
         */
@@ -623,7 +626,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
        if (set_bss_info == 1)
                mt7915_mcu_add_bss_info(phy, vif, true);
        if (set_sta == 1)
-               mt7915_mcu_add_sta(dev, vif, NULL, true);
+               mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT)
                mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
@@ -658,7 +661,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
        if (set_bss_info == 0)
                mt7915_mcu_add_bss_info(phy, vif, false);
        if (set_sta == 0)
-               mt7915_mcu_add_sta(dev, vif, NULL, false);
+               mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);
 
        mutex_unlock(&dev->mt76.mutex);
 }
@@ -696,7 +699,7 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        err = mt7915_mcu_add_bss_info(phy, vif, true);
        if (err)
                goto out;
-       err = mt7915_mcu_add_sta(dev, vif, NULL, true);
+       err = mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);
 out:
        mutex_unlock(&dev->mt76.mutex);
 
@@ -710,7 +713,7 @@ mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct mt7915_dev *dev = mt7915_hw_dev(hw);
 
        mutex_lock(&dev->mt76.mutex);
-       mt7915_mcu_add_sta(dev, vif, NULL, false);
+       mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);
        mutex_unlock(&dev->mt76.mutex);
 }
 
@@ -733,8 +736,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
        struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
        bool ext_phy = mvif->phy != &dev->phy;
-       int ret, idx;
-       u32 addr;
+       int idx;
 
        idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
        if (idx < 0)
@@ -743,25 +745,61 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        INIT_LIST_HEAD(&msta->rc_list);
        INIT_LIST_HEAD(&msta->wcid.poll_list);
        msta->vif = mvif;
-       msta->wcid.sta = 1;
+       msta->wcid.sta_disabled = 1;
        msta->wcid.idx = idx;
        msta->wcid.phy_idx = ext_phy;
-       msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
        msta->jiffies = jiffies;
 
        ewma_avg_signal_init(&msta->avg_ack_signal);
 
        mt7915_mac_wtbl_update(dev, idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
+       mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, true);
 
-       ret = mt7915_mcu_add_sta(dev, vif, sta, true);
-       if (ret)
-               return ret;
+       return 0;
+}
+
+int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta, enum mt76_sta_event ev)
+{
+       struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
+       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+       int i, ret;
+       u32 addr;
+
+       switch (ev) {
+       case MT76_STA_EVENT_ASSOC:
+               ret = mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true);
+               if (ret)
+                       return ret;
+
+               addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);
+               mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);
+
+               ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
+               if (ret)
+                       return ret;
+
+               msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+               msta->wcid.sta = 1;
+               msta->wcid.sta_disabled = 0;
+
+               return 0;
+
+       case MT76_STA_EVENT_AUTHORIZE:
+               return mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false);
 
-       addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);
-       mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);
+       case MT76_STA_EVENT_DISASSOC:
+               for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
+                       mt7915_mac_twt_teardown_flow(dev, msta, i);
 
-       return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
+               mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);
+               msta->wcid.sta_disabled = 1;
+               msta->wcid.sta = 0;
+               return 0;
+       }
+
+       return 0;
 }
 
 void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -769,16 +807,10 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 {
        struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
        struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
-       int i;
-
-       mt7915_mcu_add_sta(dev, vif, sta, false);
 
        mt7915_mac_wtbl_update(dev, msta->wcid.idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 
-       for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
-               mt7915_mac_twt_teardown_flow(dev, msta, i);
-
        spin_lock_bh(&mdev->sta_poll_lock);
        if (!list_empty(&msta->wcid.poll_list))
                list_del_init(&msta->wcid.poll_list);
@@ -885,22 +917,6 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        return ret;
 }
 
-static int
-mt7915_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-              struct ieee80211_sta *sta)
-{
-       return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST,
-                             IEEE80211_STA_NONE);
-}
-
-static int
-mt7915_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                 struct ieee80211_sta *sta)
-{
-       return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NONE,
-                             IEEE80211_STA_NOTEXIST);
-}
-
 static int
 mt7915_get_stats(struct ieee80211_hw *hw,
                 struct ieee80211_low_level_stats *stats)
@@ -1154,6 +1170,10 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
 {
        struct mt7915_phy *phy = mt7915_hw_phy(hw);
        struct mt7915_dev *dev = phy->dev;
+       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+
+       if (!msta->wcid.sta)
+               return;
 
        mt7915_sta_rc_work(&changed, sta);
        ieee80211_queue_work(hw, &dev->rc_work);
@@ -1197,6 +1217,9 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
        else
                clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
 
+       if (!msta->wcid.sta)
+               return;
+
        mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
 }
 
@@ -1213,6 +1236,9 @@ static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,
        else
                clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
 
+       if (!msta->wcid.sta)
+               return;
+
        mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
 }
 
@@ -1666,8 +1692,7 @@ const struct ieee80211_ops mt7915_ops = {
        .bss_info_changed = mt7915_bss_info_changed,
        .start_ap = mt7915_start_ap,
        .stop_ap = mt7915_stop_ap,
-       .sta_add = mt7915_sta_add,
-       .sta_remove = mt7915_sta_remove,
+       .sta_state = mt76_sta_state,
        .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
        .sta_rc_update = mt7915_sta_rc_update,
        .set_key = mt7915_set_key,
index 10de8b994e2ec994c358ebc536a9aecc4f164809..2ef8d90132ddae2660e944076bf89c8087e6ef07 100644 (file)
@@ -1657,13 +1657,12 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
 }
 
 int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta, bool enable)
+                      struct ieee80211_sta *sta, int conn_state, bool newly)
 {
        struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
        struct ieee80211_link_sta *link_sta;
        struct mt7915_sta *msta;
        struct sk_buff *skb;
-       int conn_state;
        int ret;
 
        msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
@@ -1675,14 +1674,10 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                return PTR_ERR(skb);
 
        /* starec basic */
-       conn_state = enable ? CONN_STATE_PORT_SECURE : CONN_STATE_DISCONNECT;
-       mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta, conn_state,
-                                     !rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx]));
-       if (!enable)
-               goto out;
-
+       mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta,
+                                     conn_state, newly);
        /* tag order is in accordance with firmware dependency. */
-       if (sta) {
+       if (sta && conn_state != CONN_STATE_DISCONNECT) {
                /* starec bfer */
                mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta);
                /* starec ht */
@@ -1693,12 +1688,17 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                mt76_connac_mcu_sta_uapsd(skb, vif, sta);
        }
 
-       ret = mt7915_mcu_sta_wtbl_tlv(dev, skb, vif, sta);
-       if (ret) {
-               dev_kfree_skb(skb);
-               return ret;
+       if (newly || conn_state != CONN_STATE_DISCONNECT) {
+               ret = mt7915_mcu_sta_wtbl_tlv(dev, skb, vif, sta);
+               if (ret) {
+                       dev_kfree_skb(skb);
+                       return ret;
+               }
        }
 
+       if (conn_state == CONN_STATE_DISCONNECT)
+               goto out;
+
        if (sta) {
                /* starec amsdu */
                mt7915_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
index ec7cf57521d9d60f631a68cc4be0e8296af0e728..44e112b8b5b368e4e3917b4761d4fda72d771384 100644 (file)
@@ -927,6 +927,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
                .rx_check = mt7915_rx_check,
                .rx_poll_complete = mt7915_rx_poll_complete,
                .sta_add = mt7915_mac_sta_add,
+               .sta_event = mt7915_mac_sta_event,
                .sta_remove = mt7915_mac_sta_remove,
                .update_survey = mt7915_update_channel,
                .set_channel = mt7915_set_channel,
index 712471c2a8e91a69916b398cdce2059632dc8914..ac0b1f0eb27c143c10a7e11a713e80ab63e212da 100644 (file)
@@ -444,7 +444,7 @@ int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
 int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
                            struct ieee80211_vif *vif, int enable);
 int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta, bool enable);
+                      struct ieee80211_sta *sta, int conn_state, bool newly);
 int mt7915_mcu_add_tx_ba(struct mt7915_dev *dev,
                         struct ieee80211_ampdu_params *params,
                         bool add);
@@ -560,6 +560,8 @@ void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
 void mt7915_mac_set_timing(struct mt7915_phy *phy);
 int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta);
+int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta, enum mt76_sta_event ev);
 void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
                           struct ieee80211_sta *sta);
 void mt7915_mac_work(struct work_struct *work);
index 1ed8e77eb549c65bcdc90bb32d4c4fd0dc47f32a..d534fff5c952bdbf03f3ddafb194220ac882676a 100644 (file)
@@ -404,6 +404,7 @@ static void
 mt7915_tm_init(struct mt7915_phy *phy, bool en)
 {
        struct mt7915_dev *dev = phy->dev;
+       int state;
 
        if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
                return;
@@ -415,7 +416,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
        mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
 
        mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
-       mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en);
+       state = en ? CONN_STATE_PORT_SECURE : CONN_STATE_DISCONNECT;
+       mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, state, true);
 
        if (!en)
                mt7915_tm_set_tam_arb(phy, en, 0);
index 34d93f08f4152d9a6e0fa4dd18c813b7faeca0b0..ce193e625666bec7e9d4ec86df25c09d8210760a 100644 (file)
@@ -313,6 +313,9 @@ __mt76_tx_queue_skb(struct mt76_phy *phy, int qid, struct sk_buff *skb,
                return idx;
 
        wcid = (struct mt76_wcid *)sta->drv_priv;
+       if (!wcid->sta)
+               return idx;
+
        q->entry[idx].wcid = wcid->idx;
 
        if (!non_aql)