mt76: replace sta_add/remove ops with common sta_state function
authorFelix Fietkau <nbd@nbd.name>
Fri, 16 Nov 2018 09:49:14 +0000 (10:49 +0100)
committerFelix Fietkau <nbd@nbd.name>
Fri, 30 Nov 2018 11:30:37 +0000 (12:30 +0100)
Allows adding unassociated stations from mac80211

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
drivers/net/wireless/mediatek/mt76/mt76x02.h
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c

index 1098919..b33074c 100644 (file)
@@ -631,8 +631,43 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
 }
 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
 
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-                    struct ieee80211_sta *sta)
+static int
+mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
+            struct ieee80211_sta *sta)
+{
+       struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+       int ret;
+       int i;
+
+       mutex_lock(&dev->mutex);
+
+       ret = dev->drv->sta_add(dev, vif, sta);
+       if (ret)
+               goto out;
+
+       for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+               struct mt76_txq *mtxq;
+
+               if (!sta->txq[i])
+                       continue;
+
+               mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
+               mtxq->wcid = wcid;
+
+               mt76_txq_init(dev, sta->txq[i]);
+       }
+
+       rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
+
+out:
+       mutex_unlock(&dev->mutex);
+
+       return ret;
+}
+
+static void
+mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+               struct ieee80211_sta *sta)
 {
        struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
        int idx = wcid->idx;
@@ -642,10 +677,33 @@ void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
        synchronize_rcu();
 
        mutex_lock(&dev->mutex);
+
+       if (dev->drv->sta_remove)
+               dev->drv->sta_remove(dev, vif, sta);
+
        mt76_tx_status_check(dev, wcid, true);
        for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
                mt76_txq_remove(dev, sta->txq[i]);
        mt76_wcid_free(dev->wcid_mask, idx);
+
        mutex_unlock(&dev->mutex);
 }
-EXPORT_SYMBOL_GPL(mt76_sta_remove);
+
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                  struct ieee80211_sta *sta,
+                  enum ieee80211_sta_state old_state,
+                  enum ieee80211_sta_state new_state)
+{
+       struct mt76_dev *dev = hw->priv;
+
+       if (old_state == IEEE80211_STA_NOTEXIST &&
+           new_state == IEEE80211_STA_NONE)
+               return mt76_sta_add(dev, vif, sta);
+
+       if (old_state == IEEE80211_STA_NONE &&
+                new_state == IEEE80211_STA_NOTEXIST)
+               mt76_sta_remove(dev, vif, sta);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_sta_state);
index 878836f..5cd508a 100644 (file)
@@ -288,6 +288,12 @@ struct mt76_driver_ops {
 
        void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
                       bool ps);
+
+       int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+                      struct ieee80211_sta *sta);
+
+       void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+                          struct ieee80211_sta *sta);
 };
 
 struct mt76_channel_state {
@@ -664,8 +670,10 @@ void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
                          bool flush);
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-                    struct ieee80211_sta *sta);
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                  struct ieee80211_sta *sta,
+                  enum ieee80211_sta_state old_state,
+                  enum ieee80211_sta_state new_state);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
index 757816d..d895b6f 100644 (file)
@@ -90,8 +90,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
        .config = mt76x0_config,
        .configure_filter = mt76x02_configure_filter,
        .bss_info_changed = mt76x02_bss_info_changed,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
+       .sta_state = mt76_sta_state,
        .set_key = mt76x02_set_key,
        .conf_tx = mt76x02_conf_tx,
        .sw_scan_start = mt76x02_sw_scan,
@@ -162,6 +161,8 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                .rx_skb = mt76x02_queue_rx_skb,
                .rx_poll_complete = mt76x02_rx_poll_complete,
                .sta_ps = mt76x02_sta_ps,
+               .sta_add = mt76x02_sta_add,
+               .sta_remove = mt76x02_sta_remove,
        };
        struct mt76x02_dev *dev;
        int ret;
index 35b9866..0e6b43b 100644 (file)
@@ -146,8 +146,7 @@ static const struct ieee80211_ops mt76x0u_ops = {
        .config = mt76x0_config,
        .configure_filter = mt76x02_configure_filter,
        .bss_info_changed = mt76x02_bss_info_changed,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
+       .sta_state = mt76_sta_state,
        .set_key = mt76x02_set_key,
        .conf_tx = mt76x02_conf_tx,
        .sw_scan_start = mt76x02_sw_scan,
@@ -219,6 +218,8 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
                .tx_complete_skb = mt76x02u_tx_complete_skb,
                .tx_status_data = mt76x02_tx_status_data,
                .rx_skb = mt76x02_queue_rx_skb,
+               .sta_add = mt76x02_sta_add,
+               .sta_remove = mt76x02_sta_remove,
        };
        struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
        struct mt76x02_dev *dev;
index 65daa3d..b1d83dd 100644 (file)
@@ -110,10 +110,10 @@ void mt76x02_init_device(struct mt76x02_dev *dev);
 void mt76x02_configure_filter(struct ieee80211_hw *hw,
                             unsigned int changed_flags,
                             unsigned int *total_flags, u64 multicast);
-int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                  struct ieee80211_sta *sta);
-int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                     struct ieee80211_sta *sta);
+int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+                   struct ieee80211_sta *sta);
+void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+                       struct ieee80211_sta *sta);
 
 void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev);
 void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
index 6eb892d..3a70e5b 100644 (file)
@@ -167,23 +167,17 @@ void mt76x02_configure_filter(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x02_configure_filter);
 
-int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
                    struct ieee80211_sta *sta)
 {
-       struct mt76x02_dev *dev = hw->priv;
+       struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
        struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
        struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
-       int ret = 0;
        int idx = 0;
-       int i;
-
-       mutex_lock(&dev->mt76.mutex);
 
        idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid));
-       if (idx < 0) {
-               ret = -ENOSPC;
-               goto out;
-       }
+       if (idx < 0)
+               return -ENOSPC;
 
        msta->vif = mvif;
        msta->wcid.sta = 1;
@@ -191,46 +185,25 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        msta->wcid.hw_key_idx = -1;
        mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
        mt76x02_mac_wcid_set_drop(dev, idx, false);
-       for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
-               struct mt76_txq *mtxq;
-
-               if (!sta->txq[i])
-                       continue;
-
-               mtxq = (struct mt76_txq *) sta->txq[i]->drv_priv;
-               mtxq->wcid = &msta->wcid;
-               mt76_txq_init(&dev->mt76, sta->txq[i]);
-       }
 
        if (vif->type == NL80211_IFTYPE_AP)
                set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
 
        ewma_signal_init(&msta->rssi);
 
-       rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid);
-
-out:
-       mutex_unlock(&dev->mt76.mutex);
-
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(mt76x02_sta_add);
 
-int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta)
+void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+                       struct ieee80211_sta *sta)
 {
-       struct mt76x02_dev *dev = hw->priv;
+       struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
        struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
        int idx = wcid->idx;
 
-       mt76_sta_remove(&dev->mt76, vif, sta);
-
-       mutex_lock(&dev->mt76.mutex);
        mt76x02_mac_wcid_set_drop(dev, idx, true);
        mt76x02_mac_wcid_setup(dev, idx, 0, NULL);
-       mutex_unlock(&dev->mt76.mutex);
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(mt76x02_sta_remove);
 
index 843dda2..6eaab15 100644 (file)
@@ -323,6 +323,8 @@ struct mt76x02_dev *mt76x2_alloc_device(struct device *pdev)
                .rx_skb = mt76x02_queue_rx_skb,
                .rx_poll_complete = mt76x02_rx_poll_complete,
                .sta_ps = mt76x02_sta_ps,
+               .sta_add = mt76x02_sta_add,
+               .sta_remove = mt76x02_sta_remove,
        };
        struct mt76x02_dev *dev;
        struct mt76_dev *mdev;
index 3d73926..b54a323 100644 (file)
@@ -182,8 +182,7 @@ const struct ieee80211_ops mt76x2_ops = {
        .config = mt76x2_config,
        .configure_filter = mt76x02_configure_filter,
        .bss_info_changed = mt76x02_bss_info_changed,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
+       .sta_state = mt76_sta_state,
        .set_key = mt76x02_set_key,
        .conf_tx = mt76x02_conf_tx,
        .sw_scan_start = mt76x02_sw_scan,
index de0fbdb..0be3784 100644 (file)
@@ -141,6 +141,8 @@ struct mt76x02_dev *mt76x2u_alloc_device(struct device *pdev)
                .tx_complete_skb = mt76x02u_tx_complete_skb,
                .tx_status_data = mt76x02_tx_status_data,
                .rx_skb = mt76x02_queue_rx_skb,
+               .sta_add = mt76x02_sta_add,
+               .sta_remove = mt76x02_sta_remove,
        };
        struct mt76x02_dev *dev;
        struct mt76_dev *mdev;
index a9ecc92..2b48cc5 100644 (file)
@@ -127,8 +127,7 @@ const struct ieee80211_ops mt76x2u_ops = {
        .stop = mt76x2u_stop,
        .add_interface = mt76x2u_add_interface,
        .remove_interface = mt76x02_remove_interface,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
+       .sta_state = mt76_sta_state,
        .set_key = mt76x02_set_key,
        .ampdu_action = mt76x02_ampdu_action,
        .config = mt76x2u_config,