summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:17:26 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:17:26 +0200
commitb62ed4c93ad71374b54d2c3a72cbc67b506f580c (patch)
tree6ca6ab974bbce902fc9de300fea6aa056170850f /drivers/net/wireless
parent5895db67c12464003afd16c08049b73aa09e58ea (diff)
parent221fc2f4d0eda59d02af2e751a9282fa013a8e97 (diff)
Merge v6.18.40linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.c6
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c5
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c13
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c6
-rw-r--r--drivers/net/wireless/marvell/libertas_tf/main.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/join.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/channel.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/init.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.c10
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mac.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/mac.c20
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/pci.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/testmode.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_core.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mac.c35
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/main.c9
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mcu.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/tx.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dev.c12
-rw-r--r--drivers/net/wireless/realtek/rtw88/pci.c13
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h3
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c8
28 files changed, 126 insertions, 72 deletions
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 009c49502148..4aaaccca9412 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1905,13 +1905,14 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
bool is_cck;
pkt_type = ppdu_info->preamble_type;
- rate_mcs = ppdu_info->rate;
+ rate_mcs = ppdu_info->mcs;
nss = ppdu_info->nss;
sgi = ppdu_info->gi;
switch (pkt_type) {
case RX_MSDU_START_PKT_TYPE_11A:
case RX_MSDU_START_PKT_TYPE_11B:
+ rate_mcs = ppdu_info->rate;
is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B);
if (rx_status->band < NUM_NL80211_BANDS) {
sband = &ar->mac.sbands[rx_status->band];
@@ -2254,13 +2255,10 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
rxs->encoding = RX_ENC_HE;
ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));
ath12k_dp_mon_rx_update_radiotap_he(ppduinfo, ptr);
- rxs->rate_idx = ppduinfo->rate;
} else if (ppduinfo->vht_flags) {
rxs->encoding = RX_ENC_VHT;
- rxs->rate_idx = ppduinfo->rate;
} else if (ppduinfo->ht_flags) {
rxs->encoding = RX_ENC_HT;
- rxs->rate_idx = ppduinfo->rate;
} else {
rxs->encoding = RX_ENC_LEGACY;
sband = &ar->mac.sbands[rxs->band];
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index b97469dca046..4bb4482e2734 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -7330,16 +7330,16 @@ static int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw,
continue;
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
- arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+ if (!arvif || !arvif->is_created)
+ continue;
- if (!arvif || !arsta) {
+ arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+ if (!arsta) {
ath12k_hw_warn(ah, "Failed to alloc/assign link sta");
continue;
}
ar = arvif->ar;
- if (!ar)
- continue;
ret = ath12k_mac_station_add(ar, arvif, arsta);
if (ret) {
@@ -7672,6 +7672,10 @@ ath12k_create_vht_cap(struct ath12k *ar, u32 rate_cap_tx_chainmask,
vht_cap.vht_supported = 1;
vht_cap.cap = ar->pdev->cap.vht_cap;
+ if (ar->pdev->cap.nss_ratio_enabled)
+ vht_cap.vht_mcs.tx_highest |=
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
+
ath12k_set_vht_txbf_cap(ar, &vht_cap.cap);
/* 80P80 is not supported */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 0ac9212e42f7..957646b2df4d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2746,6 +2746,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
continue;
}
+ if (ts.qid >= ATH9K_NUM_TX_QUEUES) {
+ ath_dbg(common, XMIT, "invalid qid %d\n", ts.qid);
+ continue;
+ }
+
txq = &sc->tx.txq[ts.qid];
ath_txq_lock(sc, txq);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 2cf86fc3f8fe..f7457dcd8980 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2659,6 +2659,9 @@ static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba
if (rsp->candidate_cnt < 1)
return rsp->status ? rsp->status : -EINVAL;
+ if (len < sizeof(*rsp) + sizeof(*candidate))
+ return -EINVAL;
+
candidate = (struct wcn36xx_hal_trigger_ba_rsp_candidate *)(buf + sizeof(*rsp));
for (i = 0; i < STACFG_MAX_TC; i++) {
@@ -2865,6 +2868,12 @@ static int wcn36xx_smd_print_reg_info_ind(struct wcn36xx *wcn,
return -EIO;
}
+ if (rsp->count > (len - sizeof(*rsp)) / sizeof(rsp->regs[0])) {
+ wcn36xx_warn("Truncated print reg info indication: count %u, len %zu\n",
+ rsp->count, len);
+ return -EIO;
+ }
+
wcn36xx_dbg(WCN36XX_DBG_HAL,
"reginfo indication, scenario: 0x%x reason: 0x%x\n",
rsp->scenario, rsp->reason);
@@ -3353,6 +3362,10 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
case WCN36XX_HAL_EXIT_IMPS_RSP:
case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP:
case WCN36XX_HAL_ADD_BCN_FILTER_RSP:
+ if (len > WCN36XX_HAL_BUF_SIZE) {
+ wcn36xx_warn("HAL response too large: %d\n", len);
+ break;
+ }
memcpy(wcn->hal_buf, buf, len);
wcn->hal_rsp_len = len;
complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
index 4f0ea4347840..b7472e19dd60 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
@@ -294,6 +294,12 @@ brcmf_notify_auth_frame_rx(struct brcmf_if *ifp,
return -EINVAL;
}
+ if (mgmt_frame_len < offsetof(struct ieee80211_mgmt, u)) {
+ bphy_err(drvr, "Event %s (%d) frame too small. Ignore\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code);
+ return -EINVAL;
+ }
+
wdev = &ifp->vif->wdev;
WARN_ON(!wdev);
diff --git a/drivers/net/wireless/marvell/libertas_tf/main.c b/drivers/net/wireless/marvell/libertas_tf/main.c
index fb20fe31cd36..42be6fa22f9c 100644
--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -174,7 +174,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv)
{
lbtf_deb_enter(LBTF_DEB_MAIN);
lbtf_free_cmd_buffer(priv);
- timer_delete(&priv->command_timer);
+ timer_delete_sync(&priv->command_timer);
lbtf_deb_leave(LBTF_DEB_MAIN);
}
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index be23a29e7de0..ce569d35d051 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4326,7 +4326,7 @@ mwifiex_cfg80211_authenticate(struct wiphy *wiphy,
return -EOPNOTSUPP;
}
- if (!priv->auth_flag) {
+ if (!(priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET,
req->bss->channel,
AUTH_TX_DEFAULT_WAIT_TIME);
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 5a1a0287c1d5..b48f7febaf03 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -736,7 +736,6 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
/* Send a Media Connected event, according to the Spec */
priv->media_connected = true;
- priv->adapter->ps_state = PS_STATE_AWAKE;
priv->adapter->pps_uapsd_mode = false;
priv->adapter->tx_lock_flag = false;
diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c
index eccaee1fd434..6adaeaf63e46 100644
--- a/drivers/net/wireless/mediatek/mt76/channel.c
+++ b/drivers/net/wireless/mediatek/mt76/channel.c
@@ -311,7 +311,7 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
rcu_assign_pointer(mvif->offchannel_link, NULL);
dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
- kfree(mlink);
+ kfree_rcu(mlink, rcu_head);
}
void mt76_roc_complete(struct mt76_phy *phy)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2d24f9fa51a5..7348ac5cf7e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -449,6 +449,8 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
+ if (!wiphy->max_remain_on_channel_duration)
+ wiphy->max_remain_on_channel_duration = 5000;
if (!wiphy->available_antennas_tx)
wiphy->available_antennas_tx = phy->antenna_mask;
if (!wiphy->available_antennas_rx)
@@ -1314,7 +1316,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;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index 3e7af3e58736..c4f5f6ee916a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -195,7 +195,6 @@ mt7615_check_offload_capability(struct mt7615_dev *dev)
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
wiphy->flags &= ~WIPHY_FLAG_4ADDR_STATION;
- wiphy->max_remain_on_channel_duration = 5000;
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 9364e8673eb9..50af0d9f240b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -912,16 +912,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);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index bce26389ab18..d2731e9953bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -530,8 +530,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;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index 0608f0c1fd2c..d951a46e9d48 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -840,7 +840,6 @@ static void mt7925_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb,
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_link_sta *link_sta;
- struct mt792x_link_sta *mlink;
struct mt792x_sta *msta;
bool is_8023;
u16 fc, tid;
@@ -879,14 +878,14 @@ static void mt7925_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb,
msta = (struct mt792x_sta *)sta->drv_priv;
- if (sta->mlo && msta->deflink_id != IEEE80211_LINK_UNSPECIFIED)
- mlink = rcu_dereference(msta->link[msta->deflink_id]);
- else
- mlink = &msta->deflink;
-
- if (!test_and_set_bit(tid, &mlink->wcid.ampdu_state)) {
+ /* Packets belonging to the same TID can be transmitted over multiple
+ * links. Keep the TX BA session state in the primary link so all links
+ * share the same AMPDU bookkeeping.
+ */
+ if (!test_and_set_bit(tid, &msta->deflink.wcid.ampdu_state)) {
if (ieee80211_start_tx_ba_session(sta, tid, 0))
- clear_bit(tid, &mlink->wcid.ampdu_state);
+ clear_bit(tid, &msta->deflink.wcid.ampdu_state);
+
}
}
@@ -1140,8 +1139,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);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 9a8ef3449eea..6c0dc72efc39 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2066,9 +2066,9 @@ free:
rcu_assign_pointer(mvif->link_conf[link_id], NULL);
rcu_assign_pointer(mvif->sta.link[link_id], NULL);
- if (mconf != &mvif->bss_conf)
+ if (mconfs[link_id] != &mvif->bss_conf)
devm_kfree(dev->mt76.dev, mconfs[link_id]);
- if (mlink != &mvif->sta.deflink)
+ if (mlinks[link_id] != &mvif->sta.deflink)
devm_kfree(dev->mt76.dev, mlinks[link_id]);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 8eb1fe1082d1..d6732f50784c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -414,10 +414,12 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
ret = mt7925_register_device(dev);
if (ret)
- goto err_free_irq;
+ goto err_free_dma;
return 0;
+err_free_dma:
+ mt792x_dma_cleanup(dev);
err_free_irq:
devm_free_irq(&pdev->dev, pdev->irq, dev);
err_free_dev:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7925/testmode.c
index a3c97164ba21..329185d72fcc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/testmode.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/testmode.c
@@ -105,6 +105,11 @@ mt7925_tm_query(struct mt792x_dev *dev, struct mt7925_tm_cmd *req,
if (ret)
goto out;
+ if (skb->len < MT7925_EVT_RSP_LEN + 8) {
+ ret = -EINVAL;
+ goto out;
+ }
+
memcpy((char *)evt_resp, (char *)skb->data + 8, MT7925_EVT_RSP_LEN);
out:
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index 9cad572c34a3..96c50a501c1a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -105,7 +105,8 @@ void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
wcid = &mvif->sta.deflink.wcid;
}
- if (vif && control->sta && ieee80211_vif_is_mld(vif)) {
+ if (vif && control->sta && ieee80211_vif_is_mld(vif) &&
+ !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_link_sta *link_sta;
struct ieee80211_bss_conf *conf;
@@ -657,7 +658,6 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE);
- wiphy->max_remain_on_channel_duration = 5000;
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
wiphy->max_scan_ssids = 4;
wiphy->max_sched_scan_plan_interval =
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 149d8d711fc4..29f599a7ad01 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -796,6 +796,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
bool multicast = is_multicast_ether_addr(hdr->addr1);
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
__le16 fc = hdr->frame_control, sc = hdr->seq_ctrl;
+ struct ieee80211_vif *vif = info->control.vif;
u16 seqno = le16_to_cpu(sc);
bool hw_bigtk = false;
u8 fc_type, fc_stype;
@@ -858,7 +859,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
}
- if (multicast && ieee80211_vif_is_mld(info->control.vif)) {
+ if (multicast && vif && ieee80211_vif_is_mld(vif)) {
val = MT_TXD3_SN_VALID |
FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
txwi[3] |= cpu_to_le32(val);
@@ -878,12 +879,12 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
txwi[3] &= ~cpu_to_le32(MT_TXD3_HW_AMSDU);
}
- if (ieee80211_vif_is_mld(info->control.vif) &&
+ if (vif && ieee80211_vif_is_mld(vif) &&
(multicast || unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))))
txwi[5] |= cpu_to_le32(MT_TXD5_FL);
if (ieee80211_is_nullfunc(fc) && ieee80211_has_a4(fc) &&
- ieee80211_vif_is_mld(info->control.vif)) {
+ vif && ieee80211_vif_is_mld(vif)) {
txwi[5] |= cpu_to_le32(MT_TXD5_FL);
txwi[6] |= cpu_to_le32(MT_TXD6_DIS_MAT);
}
@@ -895,7 +896,8 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, int pid,
- enum mt76_txq_id qid, u32 changed)
+ enum mt76_txq_id qid, u32 changed,
+ unsigned int link_id)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -905,7 +907,6 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
struct mt76_vif_link *mlink = NULL;
struct mt7996_vif *mvif;
- unsigned int link_id;
u16 tx_count = 15;
u32 val;
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
@@ -913,17 +914,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
bool beacon = !!(changed & (BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
- if (wcid != &dev->mt76.global_wcid)
- link_id = wcid->link_id;
- else
- link_id = u32_get_bits(info->control.flags,
- IEEE80211_TX_CTRL_MLO_LINK);
-
mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL;
if (mvif) {
if (wcid->offchannel)
mlink = rcu_dereference(mvif->mt76.offchannel_link);
- if (!mlink)
+ if (!mlink && link_id != IEEE80211_LINK_UNSPECIFIED)
mlink = rcu_dereference(mvif->mt76.link[link_id]);
}
@@ -1106,11 +1101,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
link_conf = rcu_dereference(vif->link_conf[wcid->link_id]);
if (!link_conf)
- return -EINVAL;
+ goto error_release_token;
link_sta = rcu_dereference(sta->link[wcid->link_id]);
if (!link_sta)
- return -EINVAL;
+ goto error_release_token;
dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
tx_info->buf[1].len, DMA_TO_DEVICE);
@@ -1135,7 +1130,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
/* Transmit non qos data by 802.11 header and need to fill txd by host*/
if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
- pid, qid, 0);
+ pid, qid, 0, link_id);
/* MT7996 and MT7992 require driver to provide the MAC TXP for AddBA
* req
@@ -1215,6 +1210,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
tx_info->nbuf = MT_CT_DMA_BUF_NUM;
return 0;
+
+error_release_token:
+ mt76_token_release(mdev, id, NULL);
+ return -EINVAL;
}
u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
@@ -1399,13 +1398,13 @@ next:
cur_info++;
continue;
} else if (info & MT_TXFREE_INFO_HEADER) {
- u32 tx_retries = 0, tx_failed = 0;
+ u32 tx_retries = 0, tx_failed = 0, count;
if (!wcid)
continue;
- tx_retries =
- FIELD_GET(MT_TXFREE_INFO_COUNT, info) - 1;
+ count = FIELD_GET(MT_TXFREE_INFO_COUNT, info);
+ tx_retries = count ? count - 1 : 0;
tx_failed = tx_retries +
!!FIELD_GET(MT_TXFREE_INFO_STAT, info);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index d714b7f3efe5..20da0c10669a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1795,7 +1795,11 @@ static void mt7996_sta_rate_ctrl_update(void *data, struct ieee80211_sta *sta)
{
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt7996_sta_link *msta_link;
- u32 *changed = data;
+ struct mt7996_vif *mvif = data;
+ u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
+
+ if (msta->vif != mvif)
+ return;
msta_link = rcu_dereference(msta->link[msta->deflink_id]);
if (msta_link)
@@ -1808,7 +1812,6 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
mvif->deflink.bitrate_mask = *mask;
@@ -1821,7 +1824,7 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
* then multiple MCS setting (MCS 4,5,6) is not supported.
*/
ieee80211_iterate_stations_atomic(hw, mt7996_sta_rate_ctrl_update,
- &changed);
+ mvif);
ieee80211_queue_work(hw, &dev->rc_work);
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 38b8743409a0..a3f813be107d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -2763,7 +2763,7 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev,
buf = (u8 *)bcn + sizeof(*bcn);
mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
- BSS_CHANGED_BEACON);
+ BSS_CHANGED_BEACON, link_conf->link_id);
memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
}
@@ -2906,7 +2906,8 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
buf = (u8 *)tlv + sizeof(*discov);
- mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);
+ mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
+ changed, link_conf->link_id);
memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index 6793161ed198..b8ffa42c5a1d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -813,7 +813,8 @@ void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, int pid,
- enum mt76_txq_id qid, u32 changed);
+ enum mt76_txq_id qid, u32 changed,
+ unsigned int link_id);
void mt7996_mac_update_beacons(struct mt7996_phy *phy);
void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
void mt7996_mac_work(struct work_struct *work);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index b78ae6a34b65..9fb0cca5524a 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -903,7 +903,7 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
#endif
}
- if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
+ if (wake && dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
dev->phy.q_tx[0]->blocked)
*wake = true;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index f8a6f9c968a1..847b64e586f6 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1382,7 +1382,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
GFP_KERNEL);
if (!rt2x00dev->drv_data) {
retval = -ENOMEM;
- goto exit;
+ return retval;
}
}
@@ -1416,7 +1416,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
alloc_ordered_workqueue("%s", 0, wiphy_name(rt2x00dev->hw->wiphy));
if (!rt2x00dev->workqueue) {
retval = -ENOMEM;
- goto exit;
+ goto exit_free_drv_data;
}
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
@@ -1489,6 +1489,14 @@ exit:
rt2x00lib_remove_dev(rt2x00dev);
return retval;
+
+exit_free_drv_data:
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+
+ kfree(rt2x00dev->drv_data);
+ rt2x00dev->drv_data = NULL;
+
+ return retval;
}
EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev);
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index ec0a45bfb670..eae54f50485c 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1076,6 +1076,11 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
* discard the frame if none available
*/
new_len = pkt_stat.pkt_len + pkt_offset;
+ if (unlikely(new_len > RTK_PCI_RX_BUF_SIZE)) {
+ rtw_dbg(rtwdev, RTW_DBG_RX,
+ "oversized RX packet: %u\n", new_len);
+ goto next_rp;
+ }
new = dev_alloc_skb(new_len);
if (WARN_ONCE(!new, "rx routine starvation\n"))
goto next_rp;
@@ -1710,9 +1715,9 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
static pci_ers_result_t rtw_pci_io_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- netif_device_detach(netdev);
+ ieee80211_stop_queues(hw);
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -1729,12 +1734,12 @@ static pci_ers_result_t rtw_pci_io_slot_reset(struct pci_dev *pdev)
static void rtw_pci_io_resume(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
- netif_device_attach(netdev);
+ ieee80211_wake_queues(hw);
}
const struct pci_error_handlers rtw_pci_err_handler = {
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index c3839d49f442..e146fd082f21 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -6254,6 +6254,9 @@ static inline void rtw89_assoc_link_clr(struct rtw89_sta_link *rtwsta_link)
static inline struct rtw89_sta_link *
rtw89_assoc_link_rcu_dereference(struct rtw89_dev *rtwdev, u8 macid)
{
+ if (unlikely(macid >= RTW89_MAX_MAC_ID_NUM))
+ return NULL;
+
return rcu_dereference(rtwdev->assoc_link_on_macid[macid]);
}
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index c9851aafe649..15ac357bbdba 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -7198,7 +7198,7 @@ static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev,
struct sk_buff *skb;
bool found;
int ret = 0;
- u8 i;
+ u32 i;
if (!req->n_6ghz_params)
return 0;
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 6be1849b0c4d..17a199ee1d4a 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -4605,9 +4605,9 @@ EXPORT_SYMBOL(rtw89_pm_ops);
static pci_ers_result_t rtw89_pci_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- netif_device_detach(netdev);
+ ieee80211_stop_queues(hw);
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -4624,12 +4624,12 @@ static pci_ers_result_t rtw89_pci_io_slot_reset(struct pci_dev *pdev)
static void rtw89_pci_io_resume(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
- netif_device_attach(netdev);
+ ieee80211_wake_queues(hw);
}
const struct pci_error_handlers rtw89_pci_err_handler = {