diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76x02_util.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 107 |
1 files changed, 17 insertions, 90 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index cd072ac614f7..ad5323447ed4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -132,7 +132,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev) struct ieee80211_hw *hw = mt76_hw(dev); struct wiphy *wiphy = hw->wiphy; - INIT_DELAYED_WORK(&dev->mac_work, mt76x02_mac_work); + INIT_DELAYED_WORK(&dev->mt76.mac_work, mt76x02_mac_work); hw->queues = 4; hw->max_rates = 1; @@ -142,6 +142,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev) wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | #ifdef CONFIG_MAC80211_MESH BIT(NL80211_IFTYPE_MESH_POINT) | #endif @@ -158,7 +159,6 @@ void mt76x02_init_device(struct mt76x02_dev *dev) wiphy->reg_notifier = mt76x02_regd_notifier; wiphy->iface_combinations = mt76x02_if_comb; wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02_if_comb); - wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; /* init led callbacks */ @@ -378,7 +378,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); break; case IEEE80211_AMPDU_TX_START: - mtxq->agg_ssn = *ssn << 4; + mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(*ssn); ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP_CONT: @@ -424,6 +424,16 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -EOPNOTSUPP; + /* + * In USB AP mode, broadcast/multicast frames are setup in beacon + * data registers and sent via HW beacons engine, they require to + * be already encrypted. + */ + if (mt76_is_usb(dev) && + vif->type == NL80211_IFTYPE_AP && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; wcid = msta ? &msta->wcid : &mvif->group_wcid; @@ -465,7 +475,7 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 cw_min = 5, cw_max = 10, qid; u32 val; - qid = dev->mt76.q_tx[queue].hw_idx; + qid = dev->mt76.q_tx[queue].q->hw_idx; if (params->cw_min) cw_min = fls(params->cw_min); @@ -562,26 +572,9 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, rate.idx = rates->rate[0].idx; rate.flags = rates->rate[0].flags; mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate); - msta->wcid.max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, &rate); } EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update); -int mt76x02_insert_hdr_pad(struct sk_buff *skb) -{ - int len = ieee80211_get_hdrlen_from_skb(skb); - - if (len % 4 == 0) - return 0; - - skb_push(skb, 2); - memmove(skb->data, skb->data + 2, len); - - skb->data[len] = 0; - skb->data[len + 1] = 0; - return 2; -} -EXPORT_SYMBOL_GPL(mt76x02_insert_hdr_pad); - void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) { int hdrlen; @@ -600,8 +593,6 @@ void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x02_dev *dev = hw->priv; - if (mt76_is_mmio(dev)) - tasklet_disable(&dev->pre_tbtt_tasklet); set_bit(MT76_SCANNING, &dev->mt76.state); } EXPORT_SYMBOL_GPL(mt76x02_sw_scan); @@ -612,9 +603,6 @@ void mt76x02_sw_scan_complete(struct ieee80211_hw *hw, struct mt76x02_dev *dev = hw->priv; clear_bit(MT76_SCANNING, &dev->mt76.state); - if (mt76_is_mmio(dev)) - tasklet_enable(&dev->pre_tbtt_tasklet); - if (dev->cal.gain_init_done) { /* Restore AGC gain and resume calibration after scanning. */ dev->cal.low_gain = -1; @@ -631,72 +619,11 @@ void mt76x02_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, int idx = msta->wcid.idx; mt76_stop_tx_queues(&dev->mt76, sta, true); - mt76x02_mac_wcid_set_drop(dev, idx, ps); + if (mt76_is_mmio(dev)) + mt76x02_mac_wcid_set_drop(dev, idx, ps); } EXPORT_SYMBOL_GPL(mt76x02_sta_ps); -const u16 mt76x02_beacon_offsets[16] = { - /* 1024 byte per beacon */ - 0xc000, - 0xc400, - 0xc800, - 0xcc00, - 0xd000, - 0xd400, - 0xd800, - 0xdc00, - /* BSS idx 8-15 not used for beacons */ - 0xc000, - 0xc000, - 0xc000, - 0xc000, - 0xc000, - 0xc000, - 0xc000, - 0xc000, -}; - -static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev) -{ - u16 val, base = MT_BEACON_BASE; - u32 regs[4] = {}; - int i; - - for (i = 0; i < 16; i++) { - val = mt76x02_beacon_offsets[i] - base; - regs[i / 4] |= (val / 64) << (8 * (i % 4)); - } - - for (i = 0; i < 4; i++) - mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]); -} - -void mt76x02_init_beacon_config(struct mt76x02_dev *dev) -{ - int i; - - if (mt76_is_mmio(dev)) { - /* Fire a pre-TBTT interrupt 8 ms before TBTT */ - mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, - 8 << 4); - mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER, - MT_DFS_GP_INTERVAL); - mt76_wr(dev, MT_INT_TIMER_EN, 0); - } - - mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN | - MT_BEACON_TIME_CFG_TBTT_EN | - MT_BEACON_TIME_CFG_BEACON_TX)); - mt76_set(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_SYNC_MODE); - mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff); - - for (i = 0; i < 8; i++) - mt76x02_mac_set_beacon(dev, i, NULL); - - mt76x02_set_beacon_offsets(dev); -} -EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config); - void mt76x02_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -718,7 +645,7 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw, mt76_rmw_field(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_INTVAL, info->beacon_int << 4); - dev->beacon_int = info->beacon_int; + dev->mt76.beacon_int = info->beacon_int; } if (changed & BSS_CHANGED_BEACON_ENABLED) |