diff options
author | Felix Fietkau <nbd@nbd.name> | 2018-11-16 10:49:14 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2018-11-30 12:30:37 +0100 |
commit | e28487ea84a9c081c6d8d7da319427f7fcc32ff5 (patch) | |
tree | cc434c8b2da11aca1d914dbb2a53a847b74cfd04 /drivers/net/wireless/mediatek/mt76/mac80211.c | |
parent | 54f1bf8a9fddf6e9af5b037a47be3074b1aabe96 (diff) |
mt76: replace sta_add/remove ops with common sta_state function
Allows adding unassociated stations from mac80211
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mac80211.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mac80211.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 1098919f5498..b33074cf7e00 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -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); |