Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
* All further fragments will be validated by mac80211 only.
*/
if (ieee80211_is_frag(hdr) &&
!ieee80211_is_first_frag(hdr->frame_control))
!ieee80211_is_first_frag(hdr->seq_ctrl))
return;
}

Expand Down
16 changes: 12 additions & 4 deletions drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
wtbl_hdr);

ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
if (ret) {
dev_kfree_skb(skb);
return ret;
}

ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
if (ret)
Expand All @@ -1297,8 +1299,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);

ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
if (ret) {
dev_kfree_skb(skb);
return ret;
}

return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
}
Expand Down Expand Up @@ -2689,12 +2693,16 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);

ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd);
if (ret)
if (ret) {
dev_kfree_skb(skb);
return ret;
}

ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
if (ret) {
dev_kfree_skb(skb);
return ret;
}

return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/wireless/mediatek/mt76/mt7915/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,16 +916,16 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
}

if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
u32 tx_retries = 0, tx_failed = 0;
u32 tx_retries = 0, tx_failed = 0, count;

if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) {
tx_retries =
FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1;
count = FIELD_GET(MT_TX_FREE_COUNT_V3, info);
tx_retries = count ? count - 1 : 0;
tx_failed = tx_retries +
!!FIELD_GET(MT_TX_FREE_STAT_V3, info);
} else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) {
tx_retries =
FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
count = FIELD_GET(MT_TX_FREE_COUNT, info);
tx_retries = count ? count - 1 : 0;
tx_failed = tx_retries +
!!FIELD_GET(MT_TX_FREE_STAT, info);
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1715,8 +1715,10 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
}
out:
ret = mt76_connac_mcu_sta_wed_update(&dev->mt76, skb);
if (ret)
if (ret) {
dev_kfree_skb(skb);
return ret;
}

return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/wireless/mediatek/mt76/mt7921/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,9 @@ static void mt7921_mac_tx_free(struct mt792x_dev *dev, void *data, int len)
stat = FIELD_GET(MT_TX_FREE_STATUS, info);

if (wcid) {
wcid->stats.tx_retries +=
FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
u32 count = FIELD_GET(MT_TX_FREE_COUNT, info);

wcid->stats.tx_retries += count ? count - 1 : 0;
wcid->stats.tx_failed += !!stat;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt7925/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ int mt7925_register_device(struct mt792x_dev *dev)
dev->mt76.tx_worker.fn = mt792x_tx_worker;

INIT_DELAYED_WORK(&dev->pm.ps_work, mt792x_pm_power_save_work);
INIT_DELAYED_WORK(&dev->mlo_pm_work, mt7925_mlo_pm_work);
INIT_WORK(&dev->pm.wake_work, mt792x_pm_wake_work);
spin_lock_init(&dev->pm.wake.lock);
mutex_init(&dev->pm.mutex);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt7925/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,8 +1150,9 @@ mt7925_mac_tx_free(struct mt792x_dev *dev, void *data, int len)

if (info & MT_TXFREE_INFO_HEADER) {
if (wcid) {
wcid->stats.tx_retries +=
FIELD_GET(MT_TXFREE_INFO_COUNT, info) - 1;
u32 count = FIELD_GET(MT_TXFREE_INFO_COUNT, info);

wcid->stats.tx_retries += count ? count - 1 : 0;
wcid->stats.tx_failed +=
!!FIELD_GET(MT_TXFREE_INFO_STAT, info);
}
Expand Down Expand Up @@ -1464,7 +1465,7 @@ void mt7925_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
sta = wcid_to_sta(wcid);

if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
mt76_connac2_tx_check_aggr(sta, txwi);
mt7925_tx_check_aggr(sta, e->skb, wcid);

skb_pull(e->skb, headroom);
mt76_tx_complete_skb(mdev, e->wcid, e->skb);
Expand Down
166 changes: 119 additions & 47 deletions drivers/net/wireless/mediatek/mt76/mt7925/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ mt7925_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mvif->bss_conf.vif = mvif;
mvif->sta.vif = mvif;
mvif->deflink_id = IEEE80211_LINK_UNSPECIFIED;
mvif->mlo_pm_state = MT792x_MLO_LINK_DISASSOC;

ret = mt7925_mac_link_bss_add(dev, &vif->bss_conf, &mvif->sta.deflink);
if (ret < 0)
Expand All @@ -447,6 +448,19 @@ static void mt7925_roc_iter(void *priv, u8 *mac,
mt7925_mcu_abort_roc(phy, &mvif->bss_conf, phy->roc_token_id);
}

void mt7925_roc_abort_sync(struct mt792x_dev *dev)
{
struct mt792x_phy *phy = &dev->phy;

del_timer_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
ieee80211_iterate_interfaces(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7925_roc_iter, (void *)phy);
}
EXPORT_SYMBOL_GPL(mt7925_roc_abort_sync);

void mt7925_roc_work(struct work_struct *work)
{
struct mt792x_phy *phy;
Expand Down Expand Up @@ -871,9 +885,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) {
Expand Down Expand Up @@ -1118,6 +1137,8 @@ static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev,
msta = (struct mt792x_sta *)link_sta->sta->drv_priv;
mlink = mt792x_sta_to_link(msta, link_id);

mt7925_roc_abort_sync(dev);

mt76_connac_free_pending_tx_skbs(&dev->pm, &mlink->wcid);
mt76_connac_pm_wake(&dev->mphy, &dev->pm);

Expand All @@ -1132,7 +1153,12 @@ static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev,
struct mt792x_bss_conf *mconf;

mconf = mt792x_link_conf_to_mconf(link_conf);
mt792x_mac_link_bss_remove(dev, mconf, mlink);

if (ieee80211_vif_is_mld(vif))
mt792x_mac_link_bss_remove(dev, mconf, mlink);
else
mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf,
link_sta, false);
}

spin_lock_bh(&mdev->sta_poll_lock);
Expand All @@ -1152,6 +1178,37 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
struct mt76_wcid *wcid;
unsigned int link_id;

/* clean up bss before starec */
for_each_set_bit(link_id, &old_links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_link_sta *link_sta;
struct ieee80211_bss_conf *link_conf;
struct mt792x_bss_conf *mconf;
struct mt792x_link_sta *mlink;

if (vif->type == NL80211_IFTYPE_AP)
break;

if (vif->type == NL80211_IFTYPE_STATION && sta->tdls)
continue;

link_sta = mt792x_sta_to_link_sta(vif, sta, link_id);
if (!link_sta)
continue;

mlink = mt792x_sta_to_link(msta, link_id);
if (!mlink)
continue;

link_conf = mt792x_vif_to_bss_conf(vif, link_id);
if (!link_conf)
continue;

mconf = mt792x_link_conf_to_mconf(link_conf);

mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf,
link_sta, false);
}

for_each_set_bit(link_id, &old_links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_link_sta *link_sta;
struct mt792x_link_sta *mlink;
Expand Down Expand Up @@ -1190,51 +1247,22 @@ 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,
},
};
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
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 (ieee80211_vif_is_mld(vif))
mt7925_mcu_del_dev(mdev, vif);

if (vif->type == NL80211_IFTYPE_STATION) {
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;

mvif->wep_sta = NULL;
ewma_rssi_init(&mvif->bss_conf.rssi);
}

mvif->mlo_pm_state = MT792x_MLO_LINK_DISASSOC;
}
EXPORT_SYMBOL_GPL(mt7925_mac_sta_remove);

Expand Down Expand Up @@ -1306,6 +1334,38 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return ret;
}

static void
mt7925_mlo_pm_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
struct mt792x_dev *dev = priv;
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
unsigned long valid = ieee80211_vif_is_mld(vif) ?
mvif->valid_links : BIT(0);
struct ieee80211_bss_conf *bss_conf;
int i;

if (mvif->mlo_pm_state != MT792x_MLO_CHANGED_PS)
return;

mt792x_mutex_acquire(dev);
for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) {
bss_conf = mt792x_vif_to_bss_conf(vif, i);
mt7925_mcu_uni_bss_ps(dev, bss_conf);
}
mt792x_mutex_release(dev);
}

void mt7925_mlo_pm_work(struct work_struct *work)
{
struct mt792x_dev *dev = container_of(work, struct mt792x_dev,
mlo_pm_work.work);
struct ieee80211_hw *hw = mt76_hw(dev);

ieee80211_iterate_active_interfaces(hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7925_mlo_pm_iter, dev);
}

static bool is_valid_alpha2(const char *alpha2)
{
if (!alpha2)
Expand Down Expand Up @@ -1861,6 +1921,9 @@ static void mt7925_vif_cfg_changed(struct ieee80211_hw *hw,
mt7925_mcu_sta_update(dev, NULL, vif, true,
MT76_STA_INFO_STATE_ASSOC);
mt7925_mcu_set_beacon_filter(dev, vif, vif->cfg.assoc);

if (ieee80211_vif_is_mld(vif))
mvif->mlo_pm_state = MT792x_MLO_LINK_ASSOC;
}

if (changed & BSS_CHANGED_ARP_FILTER) {
Expand All @@ -1871,9 +1934,19 @@ static void mt7925_vif_cfg_changed(struct ieee80211_hw *hw,
}

if (changed & BSS_CHANGED_PS) {
for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) {
bss_conf = mt792x_vif_to_bss_conf(vif, i);
if (hweight16(mvif->valid_links) < 2) {
/* legacy */
bss_conf = &vif->bss_conf;
mt7925_mcu_uni_bss_ps(dev, bss_conf);
} else {
if (mvif->mlo_pm_state == MT792x_MLO_LINK_ASSOC) {
mvif->mlo_pm_state = MT792x_MLO_CHANGED_PS_PENDING;
} else if (mvif->mlo_pm_state == MT792x_MLO_CHANGED_PS) {
for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) {
bss_conf = mt792x_vif_to_bss_conf(vif, i);
mt7925_mcu_uni_bss_ps(dev, bss_conf);
}
}
}
}

Expand Down Expand Up @@ -1924,11 +1997,12 @@ 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);
if (mvif->mlo_pm_state == MT792x_MLO_CHANGED_PS_PENDING) {
/* Indicate the secondary setup done */
mt7925_mcu_uni_bss_bcnft(dev, info, true);

ieee80211_queue_delayed_work(hw, &dev->mlo_pm_work, 5 * HZ);
mvif->mlo_pm_state = MT792x_MLO_CHANGED_PS;
}

mt792x_mutex_release(dev);
Expand Down Expand Up @@ -2014,8 +2088,6 @@ 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)
Expand Down
Loading