summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /drivers/net/wireless
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath11k/mhi.c4
-rw-r--r--drivers/net/wireless/ath/ath11k/pci.c8
-rw-r--r--drivers/net/wireless/ath/ath12k/ahb.c25
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.c10
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.c6
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c21
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c4
-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/mt7921/pci.c15
-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/dma.c2
-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/mt7996/pci.c2
-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
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c23
38 files changed, 190 insertions, 112 deletions
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index f994233df2bb..a6c9ff112c68 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/msi.h>
@@ -282,8 +282,10 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
break;
}
+ spin_lock_bh(&ab->base_lock);
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
+ spin_unlock_bh(&ab->base_lock);
break;
default:
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 7114eca8810d..35bb9e7a63a2 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -1210,6 +1210,14 @@ static void ath11k_pci_shutdown(struct pci_dev *pdev)
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
+ spin_lock_bh(&ab->base_lock);
+ set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
+ spin_unlock_bh(&ab->base_lock);
+
+ cancel_work_sync(&ab->reset_work);
+ cancel_work_sync(&ab->dump_work);
+
ath11k_pci_power_down(ab, false);
}
diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 2dcf0a52e4c1..30733a244454 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -583,31 +583,36 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab)
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
ath12k_ahb_ext_grp_napi_poll);
- for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
- /* For TX ring, ensure that the ring mask and the
- * tcl_to_wbm_rbm_map point to the same ring number.
- */
+ for (j = 0; j < DP_TCL_NUM_RING_MAX; j++) {
if (ring_mask->tx[i] &
- BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num)) {
+ BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
irq_grp->irqs[num_irq++] =
wbm2host_tx_completions_ring1 - j;
}
+ }
- if (ring_mask->rx[i] & BIT(j)) {
+ for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
+ if (ring_mask->rx[i] & BIT(j) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
irq_grp->irqs[num_irq++] =
reo2host_destination_ring1 - j;
}
- if (ring_mask->rx_err[i] & BIT(j))
+ if (ring_mask->rx_err[i] & BIT(j) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX)
irq_grp->irqs[num_irq++] = reo2host_exception;
- if (ring_mask->rx_wbm_rel[i] & BIT(j))
+ if (ring_mask->rx_wbm_rel[i] & BIT(j) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX)
irq_grp->irqs[num_irq++] = wbm2host_rx_release;
- if (ring_mask->reo_status[i] & BIT(j))
+ if (ring_mask->reo_status[i] & BIT(j) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX)
irq_grp->irqs[num_irq++] = reo2host_status;
- if (ring_mask->rx_mon_dest[i] & BIT(j))
+ if (ring_mask->rx_mon_dest[i] & BIT(j) &&
+ num_irq < ATH12K_EXT_IRQ_NUM_MAX)
irq_grp->irqs[num_irq++] =
rxdma2host_monitor_destination_mac1;
}
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index 90802ed1aa59..af5f11fc1d84 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -943,11 +943,11 @@ void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif)
dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id);
- dp_link_vif->tcl_metadata |= u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) |
- u32_encode_bits(arvif->vdev_id,
- HTT_TCL_META_DATA_VDEV_ID) |
- u32_encode_bits(ar->pdev->pdev_id,
- HTT_TCL_META_DATA_PDEV_ID);
+ dp_link_vif->tcl_metadata = u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) |
+ u32_encode_bits(arvif->vdev_id,
+ HTT_TCL_META_DATA_VDEV_ID) |
+ u32_encode_bits(ar->pdev->pdev_id,
+ HTT_TCL_META_DATA_PDEV_ID);
/* set HTT extension valid bit to 0 by default */
dp_link_vif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 737287a9aa46..44c5cff75f16 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -115,13 +115,14 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev,
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) {
struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev);
@@ -471,13 +472,10 @@ void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev,
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 {
struct ath12k *ar;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 2cff9485c95a..7190aafd3ae6 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -8054,16 +8054,16 @@ 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) {
@@ -8399,6 +8399,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 */
@@ -10293,7 +10297,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
if (ret) {
ath12k_warn(ab, "failed to create WMI vdev %d: %d\n",
arvif->vdev_id, ret);
- return ret;
+ goto err;
}
ar->num_created_vdevs++;
@@ -10440,13 +10444,13 @@ err_peer_del:
if (ret) {
ath12k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n",
arvif->vdev_id, arvif->bssid);
- goto err;
+ goto err_dp_peer_del;
}
ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id,
arvif->bssid);
if (ret)
- goto err_vdev_del;
+ goto err_dp_peer_del;
ar->num_peers--;
}
@@ -10463,8 +10467,6 @@ err_vdev_del:
ath12k_wmi_vdev_delete(ar, arvif->vdev_id);
ar->num_created_vdevs--;
- arvif->is_created = false;
- arvif->ar = NULL;
ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
ab->free_vdev_map |= 1LL << arvif->vdev_id;
ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id);
@@ -10473,6 +10475,7 @@ err_vdev_del:
spin_unlock_bh(&ar->data_lock);
err:
+ arvif->is_created = false;
arvif->ar = NULL;
return ret;
}
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 375277ca2b89..d9a22d6afbb0 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1639,7 +1639,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
ret = ab_pci->device_family_ops->arch_init(ab);
if (ret) {
ath12k_err(ab, "PCI arch_init failed %d\n", ret);
- goto err_pci_msi_free;
+ goto err_free_irq;
}
ret = ath12k_core_init(ab);
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index 945680b3ebdf..a5e290edaa89 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -1028,8 +1028,10 @@ mic_fail:
skb_pull(msdu, hal_rx_desc_sz);
if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu,
- rx_info)))
+ rx_info))) {
+ dev_kfree_skb_any(msdu);
return -EINVAL;
+ }
ath12k_dp_rx_h_ppdu(dp_pdev, rx_info);
ath12k_dp_rx_h_undecap(dp_pdev, msdu, HAL_ENCRYPT_TYPE_TKIP_MIC, true,
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 813553edcb78..c0b477345832 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2599,6 +2599,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++) {
@@ -2805,6 +2808,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);
@@ -3293,6 +3302,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 ce09d44fa73c..873754be5174 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
@@ -293,6 +293,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 c9a651bdf882..ca04aaae1e2f 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4333,7 +4333,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 05eee64706ea..6edcb3b8f279 100644
--- a/drivers/net/wireless/mediatek/mt76/channel.c
+++ b/drivers/net/wireless/mediatek/mt76/channel.c
@@ -307,7 +307,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 b78b4cd206e0..13c4e8abe281 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)
@@ -1321,7 +1323,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 42e11ba1206e..e437e088b2e9 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 cec2c4208255..334c19ab2b22 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 03b4960db73f..668bfa195380 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/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 7a790ddf43bb..49a37185f056 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -343,11 +343,14 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, mdev);
+ dev = container_of(mdev, struct mt792x_dev, mt76);
+
regs = pcim_iomap_region(pdev, 0, pci_name(pdev));
- if (IS_ERR(regs))
- return PTR_ERR(regs);
+ if (IS_ERR(regs)) {
+ ret = PTR_ERR(regs);
+ goto err_free_dev;
+ }
- dev = container_of(mdev, struct mt792x_dev, mt76);
dev->fw_features = features;
dev->hif_ops = &mt7921_pcie_ops;
dev->irq_map = &irq_map;
@@ -359,8 +362,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
/* MT7902 needs a mutable copy because wm2_complete_mask differs */
map = devm_kmemdup(&pdev->dev, &irq_map,
sizeof(irq_map), GFP_KERNEL);
- if (!map)
- return -ENOMEM;
+ if (!map) {
+ ret = -ENOMEM;
+ goto err_free_dev;
+ }
map->rx.wm2_complete_mask = 0;
dev->irq_map = map;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index c47bd812b66b..50034d7c04f0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -841,7 +841,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;
@@ -880,14 +879,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);
+
}
}
@@ -1141,8 +1140,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 9dc5ee51eb9f..8765121b916a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2182,9 +2182,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 c4161754c01d..48837723024d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -415,10 +415,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 3d40aacfc011..22a8f1ddc321 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 152cfcca2f90..dc63400c1b99 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/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
index 8f5d297dafce..3d9353811a02 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
@@ -683,7 +683,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
ret = mt7996_init_tx_queues(&dev->phy, MT_TXQ_ID(0),
MT7996_NPU_TX_RING_SIZE,
MT_TXQ_RING_BASE(0) + hif1_ofs,
- NULL);
+ wed);
else
ret = mt7996_init_tx_queues(&dev->phy,
MT_TXQ_ID(dev->mphy.band_idx),
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index e2a83da3a09c..2a0511b2e4d2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -757,6 +757,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;
@@ -819,7 +820,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);
@@ -839,12 +840,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);
}
@@ -856,7 +857,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);
@@ -866,7 +868,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 |
@@ -874,17 +875,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]);
}
@@ -1067,11 +1062,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);
@@ -1096,7 +1091,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
@@ -1176,6 +1171,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)
@@ -1360,13 +1359,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 a8a6552d49f6..26b8c91db0a8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1959,7 +1959,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)
@@ -1972,7 +1976,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;
@@ -1985,7 +1988,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 16420375112d..2748bfeb4797 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -3098,7 +3098,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);
}
@@ -3244,7 +3244,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 bdcf72457954..5f39a583bd37 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -855,7 +855,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/mt7996/pci.c b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
index 12523ddba630..b7d9193e042f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
@@ -141,7 +141,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
dev->hif2 = hif2;
mt76_npu_init(mdev, pci_resource_start(pdev, 0),
- pdev->bus && pci_domain_nr(pdev->bus) ? 3 : 2);
+ pci_domain_nr(pdev->bus) ? 3 : 2);
ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
if (ret < 0)
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 22f9690634c9..f96d9c471853 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -933,7 +933,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 82fb230a73bb..4d94b7062f44 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1388,7 +1388,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
GFP_KERNEL);
if (!rt2x00dev->drv_data) {
retval = -ENOMEM;
- goto exit;
+ return retval;
}
}
@@ -1422,7 +1422,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);
@@ -1495,6 +1495,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 bba370ad510c..c2bf44e880cf 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1077,6 +1077,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;
@@ -1711,9 +1716,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;
}
@@ -1730,12 +1735,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 fd29dbbb120d..05adf20a65be 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -6492,6 +6492,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 17704f054727..089c9071b58f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -8318,7 +8318,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 43c61b3dc969..64554eb35a72 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -4624,9 +4624,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;
}
@@ -4643,12 +4643,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 = {
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 1c340a4a0930..be583ae331c0 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -32,6 +32,15 @@
#define WL1271_BOOT_RETRIES 3
#define WL1271_WAKEUP_TIMEOUT 500
+static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+ WL1271_CIPHER_SUITE_GEM,
+ WLAN_CIPHER_SUITE_AES_CMAC,
+};
+
static char *fwlog_param;
static int fwlog_mem_blocks = -1;
static int bug_on_recovery = -1;
@@ -2367,6 +2376,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
static int wl12xx_init_fw(struct wl1271 *wl)
{
+ struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
int retries = WL1271_BOOT_RETRIES;
bool booted = false;
struct wiphy *wiphy = wl->hw->wiphy;
@@ -2421,8 +2431,9 @@ power_off:
/* WLAN_CIPHER_SUITE_AES_CMAC must be last in cipher_suites;
support only with firmware 8.9.1 and newer */
- if (wl->chip.fw_ver[FW_VER_MAJOR] < 1)
- wl->hw->wiphy->n_cipher_suites--;
+ if (wl->chip.fw_ver[FW_VER_MAJOR] < 1 ||
+ (!strncmp(pdev_data->family->name, "wl12", 4)))
+ wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites) - 1;
/*
* Now we know if 11a is supported (info from the NVS), so disable
@@ -6198,14 +6209,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl)
static int wl1271_init_ieee80211(struct wl1271 *wl)
{
int i;
- static const u32 cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
- WL1271_CIPHER_SUITE_GEM,
- WLAN_CIPHER_SUITE_AES_CMAC,
- };
/* The tx descriptor buffer */
wl->hw->extra_tx_headroom = sizeof(struct wl1271_tx_hw_descr);