static int mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { struct mt7601u_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; WARN_ON(msta->wcid.idx > GROUP_WCID(0)); switch (action) { case IEEE80211_AMPDU_RX_START: mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); break; case IEEE80211_AMPDU_RX_STOP: mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); break; case IEEE80211_AMPDU_TX_OPERATIONAL: ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: break; case IEEE80211_AMPDU_TX_START: msta->agg_ssn[tid] = *ssn << 4; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP_CONT: ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } return 0; }
static int mt76x0_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; unsigned int idx; idx = ffs(~dev->vif_mask); if (!idx || idx > 8) return -ENOSPC; idx--; dev->vif_mask |= BIT(idx); mvif->idx = idx; mvif->group_wcid.idx = GROUP_WCID(idx); mvif->group_wcid.hw_key_idx = -1; return 0; }
static int mt7601u_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt7601u_dev *dev = hw->priv; struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; unsigned int idx = 0; unsigned int wcid = GROUP_WCID(idx); /* Note: for AP do the AP-STA things mt76 does: * - beacon offsets * - do mac address tricks * - shift vif idx */ mvif->idx = idx; if (dev->wcid_mask[wcid / BITS_PER_LONG] & BIT(wcid % BITS_PER_LONG)) return -ENOSPC; dev->wcid_mask[wcid / BITS_PER_LONG] |= BIT(wcid % BITS_PER_LONG); mvif->group_wcid.idx = wcid; mvif->group_wcid.hw_key_idx = -1; return 0; }