diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7925/main.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7925/main.c | 130 |
1 files changed, 89 insertions, 41 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 791c8b00e112..98daf80ac131 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -130,7 +130,7 @@ mt7925_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band, if (he_cap_elem->phy_cap_info[6] & IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) { - mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss); + mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss, band); } else { he_cap_elem->phy_cap_info[9] |= u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, @@ -310,6 +310,7 @@ void mt7925_set_stream_he_eht_caps(struct mt792x_phy *phy) int __mt7925_start(struct mt792x_phy *phy) { struct mt76_phy *mphy = phy->mt76; + struct mt792x_dev *dev = phy->dev; int err; err = mt7925_mcu_set_channel_domain(mphy); @@ -320,9 +321,12 @@ int __mt7925_start(struct mt792x_phy *phy) if (err) return err; - err = mt7925_set_tx_sar_pwr(mphy->hw, NULL); - if (err) - return err; + if (!dev->sar_inited) { + err = mt7925_set_tx_sar_pwr(mphy->hw, NULL); + if (err) + return err; + dev->sar_inited = true; + } mt792x_mac_reset_counters(phy); set_bit(MT76_STATE_RUNNING, &mphy->state); @@ -365,29 +369,22 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev, mconf->mt76.omac_idx = ieee80211_vif_is_mld(vif) ? 0 : mconf->mt76.idx; mconf->mt76.band_idx = 0xff; - mconf->mt76.wmm_idx = mconf->mt76.idx % MT76_CONNAC_MAX_WMM_SETS; + mconf->mt76.wmm_idx = ieee80211_vif_is_mld(vif) ? + 0 : mconf->mt76.idx % MT76_CONNAC_MAX_WMM_SETS; if (mvif->phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ) mconf->mt76.basic_rates_idx = MT792x_BASIC_RATES_TBL + 4; else mconf->mt76.basic_rates_idx = MT792x_BASIC_RATES_TBL; - ret = mt76_connac_mcu_uni_add_dev(&dev->mphy, link_conf, - &mlink->wcid, true); - if (ret) - goto out; - dev->mt76.vif_mask |= BIT_ULL(mconf->mt76.idx); mvif->phy->omac_mask |= BIT_ULL(mconf->mt76.omac_idx); idx = MT792x_WTBL_RESERVED - mconf->mt76.idx; - INIT_LIST_HEAD(&mlink->wcid.poll_list); mlink->wcid.idx = idx; - mlink->wcid.phy_idx = mconf->mt76.band_idx; - mlink->wcid.hw_key_idx = -1; mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mlink->wcid); + mt76_wcid_init(&mlink->wcid, 0); mt7925_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); @@ -395,6 +392,12 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev, ewma_rssi_init(&mconf->rssi); rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->wcid); + + ret = mt76_connac_mcu_uni_add_dev(&dev->mphy, link_conf, &mconf->mt76, + &mlink->wcid, true); + if (ret) + goto out; + if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; mtxq->wcid = idx; @@ -801,12 +804,12 @@ static u8 mt7925_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_phy *mphy = hw->priv; u16 rate; u8 i, idx, ht; - rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast); + rate = mt76_connac2_mac_tx_rate_val(mphy, &vif->bss_conf, beacon, mcast); ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM; if (beacon && ht) { @@ -837,6 +840,7 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, u8 link_id = link_sta->link_id; struct mt792x_link_sta *mlink; struct mt792x_sta *msta; + struct mt76_wcid *wcid; int ret, idx; msta = (struct mt792x_sta *)link_sta->sta->drv_priv; @@ -847,14 +851,22 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, return -ENOSPC; mconf = mt792x_vif_to_link(mvif, link_id); - INIT_LIST_HEAD(&mlink->wcid.poll_list); + mt76_wcid_init(&mlink->wcid, 0); mlink->wcid.sta = 1; mlink->wcid.idx = idx; - mlink->wcid.phy_idx = mconf->mt76.band_idx; mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET; mlink->last_txs = jiffies; mlink->wcid.link_id = link_sta->link_id; mlink->wcid.link_valid = !!link_sta->sta->valid_links; + mlink->sta = msta; + + wcid = &mlink->wcid; + ewma_signal_init(&wcid->rssi); + rcu_assign_pointer(dev->mt76.wcid[wcid->idx], wcid); + mt76_wcid_init(wcid, 0); + ewma_avg_signal_init(&mlink->avg_ack_signal); + memset(mlink->airtime_ac, 0, + sizeof(msta->deflink.airtime_ac)); ret = mt76_connac_pm_wake(&dev->mphy, &dev->pm); if (ret) @@ -866,9 +878,14 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, link_conf = mt792x_vif_to_bss_conf(vif, link_id); /* should update bss info before STA add */ - if (vif->type == NL80211_IFTYPE_STATION && !link_sta->sta->tdls) - mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, - link_conf, link_sta, false); + if (vif->type == NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { + if (ieee80211_vif_is_mld(vif)) + mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, + link_conf, link_sta, link_sta != mlink->pri_link); + else + mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, + link_conf, link_sta, false); + } if (ieee80211_vif_is_mld(vif) && link_sta == mlink->pri_link) { @@ -904,7 +921,6 @@ mt7925_mac_sta_add_links(struct mt792x_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, unsigned long new_links) { struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; - struct mt76_wcid *wcid; unsigned int link_id; int err = 0; @@ -921,14 +937,6 @@ mt7925_mac_sta_add_links(struct mt792x_dev *dev, struct ieee80211_vif *vif, err = -ENOMEM; break; } - - wcid = &mlink->wcid; - ewma_signal_init(&wcid->rssi); - rcu_assign_pointer(dev->mt76.wcid[wcid->idx], wcid); - mt76_wcid_init(wcid); - ewma_avg_signal_init(&mlink->avg_ack_signal); - memset(mlink->airtime_ac, 0, - sizeof(msta->deflink.airtime_ac)); } msta->valid_links |= BIT(link_id); @@ -1141,8 +1149,7 @@ static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev, struct mt792x_bss_conf *mconf; mconf = mt792x_link_conf_to_mconf(link_conf); - mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf, - link_sta, false); + mt792x_mac_link_bss_remove(dev, mconf, mlink); } spin_lock_bh(&mdev->sta_poll_lock); @@ -1185,7 +1192,6 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif, if (link_sta != mlink->pri_link) { mt76_wcid_cleanup(mdev, wcid); mt76_wcid_mask_clear(mdev->wcid_mask, wcid->idx); - mt76_wcid_mask_clear(mdev->wcid_phy_mask, wcid->idx); } if (msta->deflink_id == link_id) @@ -1200,12 +1206,45 @@ void mt7925_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, { struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct { + struct { + u8 omac_idx; + u8 band_idx; + __le16 pad; + } __packed hdr; + struct req_tlv { + __le16 tag; + __le16 len; + u8 active; + u8 link_idx; /* hw link idx */ + u8 omac_addr[ETH_ALEN]; + } __packed tlv; + } dev_req = { + .hdr = { + .omac_idx = 0, + .band_idx = 0, + }, + .tlv = { + .tag = cpu_to_le16(DEV_INFO_ACTIVE), + .len = cpu_to_le16(sizeof(struct req_tlv)), + .active = true, + }, + }; unsigned long rem; rem = ieee80211_vif_is_mld(vif) ? msta->valid_links : BIT(0); mt7925_mac_sta_remove_links(dev, vif, sta, rem); + if (ieee80211_vif_is_mld(vif)) { + mt7925_mcu_set_dbdc(&dev->mphy, false); + + /* recovery omac address for the legacy interface */ + memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN); + mt76_mcu_send_msg(mdev, MCU_UNI_CMD(DEV_INFO_UPDATE), + &dev_req, sizeof(dev_req), true); + } + if (vif->type == NL80211_IFTYPE_STATION) { struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; @@ -1250,22 +1289,22 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->deflink.wcid, tid, ssn, params->buf_size); - mt7925_mcu_uni_rx_ba(dev, params, true); + mt7925_mcu_uni_rx_ba(dev, vif, params, true); break; case IEEE80211_AMPDU_RX_STOP: mt76_rx_aggr_stop(&dev->mt76, &msta->deflink.wcid, tid); - mt7925_mcu_uni_rx_ba(dev, params, false); + mt7925_mcu_uni_rx_ba(dev, vif, params, false); break; case IEEE80211_AMPDU_TX_OPERATIONAL: mtxq->aggr = true; mtxq->send_bar = false; - mt7925_mcu_uni_tx_ba(dev, params, true); + mt7925_mcu_uni_tx_ba(dev, vif, params, true); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mtxq->aggr = false; clear_bit(tid, &msta->deflink.wcid.ampdu_state); - mt7925_mcu_uni_tx_ba(dev, params, false); + mt7925_mcu_uni_tx_ba(dev, vif, params, false); break; case IEEE80211_AMPDU_TX_START: set_bit(tid, &msta->deflink.wcid.ampdu_state); @@ -1274,7 +1313,7 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; clear_bit(tid, &msta->deflink.wcid.ampdu_state); - mt7925_mcu_uni_tx_ba(dev, params, false); + mt7925_mcu_uni_tx_ba(dev, vif, params, false); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } @@ -1895,6 +1934,13 @@ static void mt7925_link_info_changed(struct ieee80211_hw *hw, if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED)) mt7925_mcu_set_tx(dev, info); + if (changed & BSS_CHANGED_BSSID) { + if (ieee80211_vif_is_mld(vif) && + hweight16(mvif->valid_links) == 2) + /* Indicate the secondary setup done */ + mt7925_mcu_uni_bss_bcnft(dev, info, true); + } + mt792x_mutex_release(dev); } @@ -1946,6 +1992,8 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, GFP_KERNEL); mlink = devm_kzalloc(dev->mt76.dev, sizeof(*mlink), GFP_KERNEL); + if (!mconf || !mlink) + return -ENOMEM; } mconfs[link_id] = mconf; @@ -1974,6 +2022,8 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto free; if (mconf != &mvif->bss_conf) { + mt7925_mcu_set_bss_pm(dev, link_conf, true); + err = mt7925_set_mlo_roc(phy, &mvif->bss_conf, vif->active_links); if (err < 0) @@ -2071,18 +2121,16 @@ static void mt7925_unassign_vif_chanctx(struct ieee80211_hw *hw, struct mt792x_chanctx *mctx = (struct mt792x_chanctx *)ctx->drv_priv; struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct mt792x_dev *dev = mt792x_hw_dev(hw); - struct ieee80211_bss_conf *pri_link_conf; struct mt792x_bss_conf *mconf; mutex_lock(&dev->mt76.mutex); if (ieee80211_vif_is_mld(vif)) { mconf = mt792x_vif_to_link(mvif, link_conf->link_id); - pri_link_conf = mt792x_vif_to_bss_conf(vif, mvif->deflink_id); if (vif->type == NL80211_IFTYPE_STATION && mconf == &mvif->bss_conf) - mt7925_mcu_add_bss_info(&dev->phy, NULL, pri_link_conf, + mt7925_mcu_add_bss_info(&dev->phy, NULL, link_conf, NULL, false); } else { mconf = &mvif->bss_conf; |