static int mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; int ret = 0; int idx = 0; mutex_lock(&dev->mutex); idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); if (idx < 0) { ret = -ENOSPC; goto out; } msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; mt76x0_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); rcu_assign_pointer(dev->wcid[idx], &msta->wcid); mt76x0_mac_set_ampdu_factor(dev); out: mutex_unlock(&dev->mutex); return ret; }
static int mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; int idx = msta->wcid.idx; mutex_lock(&dev->mutex); rcu_assign_pointer(dev->wcid[idx], NULL); mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); mt76x0_mac_wcid_setup(dev, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); mutex_unlock(&dev->mutex); return 0; }
static int mt76_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; int idx = msta->wcid.idx; int i; mutex_lock(&dev->mutex); rcu_assign_pointer(dev->wcid[idx], NULL); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76_txq_remove(dev, sta->txq[i]); mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); mt76_mac_wcid_setup(dev, idx, 0, NULL); mutex_unlock(&dev->mutex); return 0; }