ath.git patches for v7.4 (PR #3)

Nothing special here, just a bunch of assorted cleanups and bug fixes
 spread across the ath family of Wi-Fi drivers.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCas2KJAAKCRAsFbugiYzL
 ex3sAP92x3RW0+no4dEb99ucaBGoC3fIqiG8iNKYNAYBhZRtEgEAw33bTq+ARQ2g
 PTOvTOxotiqvNJ4VMfze9frHRTbD1gU=
 =JCrx
 -----END PGP SIGNATURE-----

Merge tag 'ath-next-20261012' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath

Jeff Johnson says:
==================
ath.git patches for v7.4 (PR #3)

Nothing special here, just a bunch of assorted cleanups and bug fixes
spread across the ath family of Wi-Fi drivers.
==================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2026-10-13 14:03:34 +02:00
commit cd026e68fd
19 changed files with 217 additions and 94 deletions

View File

@ -505,9 +505,8 @@ int ath10k_htt_tx_start(struct ath10k_htt *htt)
return ret;
}
static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
static void ath10k_htt_tx_clean_up_pending(int msdu_id, struct ath10k *ar)
{
struct ath10k *ar = ctx;
struct ath10k_htt *htt = &ar->htt;
struct htt_tx_done tx_done = {};
@ -517,8 +516,6 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
ath10k_txrx_tx_unref(htt, &tx_done);
return 0;
}
void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
@ -535,8 +532,13 @@ void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
static void ath10k_htt_flush_tx_queue(struct ath10k_htt *htt)
{
struct sk_buff *msdu;
int msdu_id;
ath10k_htc_stop_hl(htt->ar);
idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
idr_for_each_entry(&htt->pending_tx, msdu, msdu_id)
ath10k_htt_tx_clean_up_pending(msdu_id, htt->ar);
}
void ath10k_htt_tx_stop(struct ath10k_htt *htt)

View File

@ -1128,6 +1128,7 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
err:
kfree(qmi);
ar_snoc->qmi = NULL;
return ret;
}

View File

@ -1275,9 +1275,6 @@ int ath11k_core_suspend_late(struct ath11k_base *ab)
if (ab->actual_pm_policy == ATH11K_PM_WOW)
return 0;
ath11k_hif_irq_disable(ab);
ath11k_hif_ce_irq_disable(ab);
ath11k_hif_power_down(ab, true);
return 0;
@ -2333,17 +2330,9 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
int ret;
mutex_lock(&ab->core_lock);
ath11k_hif_irq_disable(ab);
ath11k_hif_ce_irq_disable(ab);
ath11k_thermal_unregister(ab);
/*
* ath11k_core_reset() already disabled the interrupts on the reset
* path; only the firmware crash path reaches here with them live.
*/
if (!ab->is_reset) {
ath11k_hif_irq_disable(ab);
ath11k_hif_ce_irq_disable(ab);
}
ath11k_dp_pdev_free(ab);
ath11k_cfr_deinit(ab);
ath11k_spectral_deinit(ab);
@ -2459,8 +2448,7 @@ void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
complete(&ar->thermal.wmi_sync);
wake_up(&ar->dp.tx_empty_waitq);
idr_for_each(&ar->txmgmt_idr,
ath11k_mac_tx_mgmt_pending_free, ar);
ath11k_mac_tx_mgmt_pending_free(ar);
idr_destroy(&ar->txmgmt_idr);
wake_up(&ar->txmgmt_empty_waitq);
@ -2605,9 +2593,6 @@ static void ath11k_core_reset(struct work_struct *work)
time_left = wait_for_completion_timeout(&ab->recovery_start,
ATH11K_RECOVER_START_TIMEOUT_HZ);
ath11k_hif_irq_disable(ab);
ath11k_hif_ce_irq_disable(ab);
ath11k_hif_power_down(ab, false);
ath11k_hif_power_up(ab);

View File

@ -6167,25 +6167,27 @@ static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id)
ath11k_mgmt_over_wmi_tx_drop(ar, msdu);
}
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
void ath11k_mac_tx_mgmt_pending_free(struct ath11k *ar)
{
struct ath11k *ar = ctx;
struct sk_buff *msdu;
int buf_id;
ath11k_mac_tx_mgmt_free(ar, buf_id);
return 0;
idr_for_each_entry(&ar->txmgmt_idr, msdu, buf_id)
ath11k_mac_tx_mgmt_free(ar, buf_id);
}
static int ath11k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)
static void ath11k_mac_vif_txmgmt_cleanup(struct ath11k *ar,
struct ieee80211_vif *vif)
{
struct ieee80211_vif *vif = ctx;
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);
struct ath11k *ar = skb_cb->ar;
struct ath11k_skb_cb *skb_cb;
struct sk_buff *skb;
int buf_id;
if (skb_cb->vif == vif)
ath11k_mac_tx_mgmt_free(ar, buf_id);
return 0;
idr_for_each_entry(&ar->txmgmt_idr, skb, buf_id) {
skb_cb = ATH11K_SKB_CB(skb);
if (skb_cb->vif == vif)
ath11k_mac_tx_mgmt_free(ar, buf_id);
}
}
static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,
@ -7417,8 +7419,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
ath11k_peer_cleanup(ar, arvif->vdev_id);
idr_for_each(&ar->txmgmt_idr,
ath11k_mac_vif_txmgmt_idr_remove, vif);
ath11k_mac_vif_txmgmt_cleanup(ar, vif);
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock);
@ -10418,7 +10419,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar)
ieee80211_unregister_hw(ar->hw);
idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, ar);
ath11k_mac_tx_mgmt_pending_free(ar);
idr_destroy(&ar->txmgmt_idr);
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);

View File

@ -162,7 +162,7 @@ struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id)
void ath11k_mac_drain_tx(struct ath11k *ar);
void ath11k_mac_peer_cleanup_all(struct ath11k *ar);
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
void ath11k_mac_tx_mgmt_pending_free(struct ath11k *ar);
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw);
enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi);
enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy);

View File

@ -191,6 +191,26 @@ static void __ath12k_ahb_ext_irq_disable(struct ath12k_base *ab)
}
}
static void ath12k_ahb_free_napi_for_group(struct ath12k_ext_irq_grp *irq_grp)
{
netif_napi_del(&irq_grp->napi);
free_netdev(irq_grp->napi_ndev);
irq_grp->napi_ndev = NULL;
}
static void ath12k_ahb_free_napi(struct ath12k_base *ab, int num_ext_irq_grp)
{
int i;
for (i = 0; i < num_ext_irq_grp; i++)
ath12k_ahb_free_napi_for_group(&ab->ext_irq_grp[i]);
}
static void ath12k_ahb_free_ext_napi(struct ath12k_base *ab)
{
ath12k_ahb_free_napi(ab, ATH12K_EXT_IRQ_GRP_NUM_MAX);
}
static void ath12k_ahb_ext_grp_enable(struct ath12k_ext_irq_grp *irq_grp)
{
int i;
@ -622,8 +642,10 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab)
irq_grp->grp_id = i;
irq_grp->napi_ndev = alloc_netdev_dummy(0);
if (!irq_grp->napi_ndev)
return -ENOMEM;
if (!irq_grp->napi_ndev) {
ret = -ENOMEM;
goto free_napi_ndev;
}
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
ath12k_ahb_ext_grp_napi_poll);
@ -675,12 +697,19 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab)
ath12k_ahb_ext_interrupt_handler,
IRQF_TRIGGER_RISING,
irq_name[irq_idx], irq_grp);
if (ret)
if (ret) {
ath12k_warn(ab, "failed request_irq for %d\n", irq);
ath12k_ahb_free_napi_for_group(irq_grp);
goto free_napi_ndev;
}
}
}
return 0;
free_napi_ndev:
ath12k_ahb_free_napi(ab, i);
return ret;
}
static int ath12k_ahb_config_irq(struct ath12k_base *ab)
@ -1353,7 +1382,7 @@ static int ath12k_ahb_probe(struct platform_device *pdev)
ret = ab_ahb->device_family_ops->arch_init(ab);
if (ret) {
ath12k_err(ab, "AHB arch_init failed %d\n", ret);
goto err_rproc_deconfigure;
goto err_free_ext_napi;
}
ret = ath12k_core_init(ab);
@ -1367,6 +1396,9 @@ static int ath12k_ahb_probe(struct platform_device *pdev)
err_deinit_arch:
ab_ahb->device_family_ops->arch_deinit(ab);
err_free_ext_napi:
ath12k_ahb_free_ext_napi(ab);
err_rproc_deconfigure:
mutex_lock(&ath12k_rproc_info_lock);
ath12k_ahb_deconfigure_rproc(ab);
@ -1409,6 +1441,7 @@ static void ath12k_ahb_free_resources(struct ath12k_base *ab)
struct platform_device *pdev = ab->pdev;
struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
ath12k_ahb_free_ext_napi(ab);
ath12k_hal_srng_deinit(ab);
ath12k_ce_free_pipes(ab);
ath12k_ahb_resource_deinit(ab);

View File

@ -54,6 +54,7 @@ ath12k_mem_profile_based_param ath12k_mem_profile_based_param[] = {
.num_pool_tx_desc = 32768,
.rx_desc_count = 12288,
.rx_release_ring_size = 16384,
.rxdma_buf_ring_size = 8192,
},
},
[ATH12K_QMI_MEMORY_MODE_LOW_512_M] = {
@ -68,10 +69,40 @@ ath12k_mem_profile_based_param ath12k_mem_profile_based_param[] = {
.num_pool_tx_desc = 16384,
.rx_desc_count = 6144,
.rx_release_ring_size = 8192,
.rxdma_buf_ring_size = 4096,
},
},
};
/*
* On these machines the OS cannot control the WCN7850 hardware rfkill
* input, which reads as "radio off", so hardware rfkill must stay
* disabled. Ideally this would come from the connector node of the board
* DT, but that binding does not exist yet.
*/
static const struct ath12k_core_broken_rfkill_table {
enum ath12k_hw_rev hw_rev;
const char *compatible;
} ath12k_core_broken_rfkill_table[] = {
{ ATH12K_HW_WCN7850_HW20, "microsoft,denali" },
{ ATH12K_HW_WCN7850_HW20, "microsoft,romulus13" },
{ ATH12K_HW_WCN7850_HW20, "microsoft,romulus15" },
{ /* Sentinel */ }
};
static bool ath12k_core_rfkill_is_broken(struct ath12k_base *ab)
{
const struct ath12k_core_broken_rfkill_table *entry;
for (entry = ath12k_core_broken_rfkill_table; entry->compatible; entry++) {
if (ab->hw_rev == entry->hw_rev &&
of_machine_is_compatible(entry->compatible))
return true;
}
return false;
}
static int ath12k_core_rfkill_config(struct ath12k_base *ab)
{
struct ath12k *ar;
@ -83,6 +114,9 @@ static int ath12k_core_rfkill_config(struct ath12k_base *ab)
if (ath12k_acpi_get_disable_rfkill(ab))
return 0;
if (ath12k_core_rfkill_is_broken(ab))
return 0;
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
@ -1537,8 +1571,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
complete_all(&ar->thermal.wmi_sync);
wake_up(&ar->dp.tx_empty_waitq);
idr_for_each(&ar->txmgmt_idr,
ath12k_mac_tx_mgmt_pending_free, ar);
ath12k_mac_tx_mgmt_pending_free(ar);
idr_destroy(&ar->txmgmt_idr);
wake_up(&ar->txmgmt_empty_waitq);

View File

@ -6190,7 +6190,7 @@ static ssize_t ath12k_write_htt_stats_type(struct file *file,
const int size = 32;
int num_args;
if (count > size)
if (count >= size)
return -EINVAL;
char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);

View File

@ -31,6 +31,7 @@ struct ath12k_dp_profile_params {
u32 num_pool_tx_desc;
u32 rx_desc_count;
u32 rx_release_ring_size;
u32 rxdma_buf_ring_size;
};
#define DP_MON_PURGE_TIMEOUT_MS 100
@ -210,7 +211,6 @@ struct ath12k_pdev_dp {
#define DP_REO_EXCEPTION_RING_SIZE 128
#define DP_REO_CMD_RING_SIZE 256
#define DP_REO_STATUS_RING_SIZE 2048
#define DP_RXDMA_BUF_RING_SIZE 4096
#define DP_RX_MAC_BUF_RING_SIZE 4096
#define DP_RXDMA_REFILL_RING_SIZE 2048
#define DP_RXDMA_ERR_DST_RING_SIZE 1024
@ -730,6 +730,12 @@ ath12k_dp_rx_release_ring_size(const struct ath12k_dp_profile_params *p)
return p->rx_release_ring_size;
}
static inline u32
ath12k_dp_rxdma_buf_ring_size(const struct ath12k_dp_profile_params *p)
{
return p->rxdma_buf_ring_size;
}
void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);
void ath12k_dp_partner_cc_init(struct ath12k_base *ab);
int ath12k_dp_pdev_alloc(struct ath12k_base *ab);

View File

@ -1699,7 +1699,7 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
ret = ath12k_dp_srng_setup(ab,
&dp->rx_refill_buf_ring.refill_buf_ring,
HAL_RXDMA_BUF, 0, 0,
DP_RXDMA_BUF_RING_SIZE);
ath12k_dp_rxdma_buf_ring_size(dp_params));
if (ret) {
ath12k_warn(ab, "failed to setup rx_refill_buf_ring\n");
return ret;

View File

@ -239,6 +239,7 @@ struct ath12k_hw_params {
} client;
bool host_alloc_ml_id;
bool advertise_iface_mac_pool;
};
struct ath12k_hw_ops {

View File

@ -9194,25 +9194,27 @@ static void ath12k_mac_tx_mgmt_free(struct ath12k *ar, int buf_id)
ath12k_mgmt_over_wmi_tx_drop(ar, msdu);
}
int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
void ath12k_mac_tx_mgmt_pending_free(struct ath12k *ar)
{
struct ath12k *ar = ctx;
struct sk_buff *msdu;
int buf_id;
ath12k_mac_tx_mgmt_free(ar, buf_id);
return 0;
idr_for_each_entry(&ar->txmgmt_idr, msdu, buf_id)
ath12k_mac_tx_mgmt_free(ar, buf_id);
}
static int ath12k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)
static void ath12k_mac_vif_txmgmt_cleanup(struct ath12k *ar,
struct ieee80211_vif *vif)
{
struct ieee80211_vif *vif = ctx;
struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
struct ath12k *ar = skb_cb->ar;
struct ath12k_skb_cb *skb_cb;
struct sk_buff *skb;
int buf_id;
if (skb_cb->vif == vif)
ath12k_mac_tx_mgmt_free(ar, buf_id);
return 0;
idr_for_each_entry(&ar->txmgmt_idr, skb, buf_id) {
skb_cb = ATH12K_SKB_CB(skb);
if (skb_cb->vif == vif)
ath12k_mac_tx_mgmt_free(ar, buf_id);
}
}
static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arvif,
@ -10977,8 +10979,7 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv
ath12k_peer_cleanup(ar, arvif->vdev_id);
ath12k_ahvif_put_link_cache(ahvif, arvif->link_id);
idr_for_each(&ar->txmgmt_idr,
ath12k_mac_vif_txmgmt_idr_remove, vif);
ath12k_mac_vif_txmgmt_cleanup(ar, vif);
ath12k_mac_vif_unref(ath12k_ab_to_dp(ab), vif);
@ -14738,7 +14739,7 @@ static struct wiphy_iftype_ext_capab ath12k_iftypes_ext_capa[] = {
static void ath12k_mac_cleanup_unregister(struct ath12k *ar)
{
idr_for_each(&ar->txmgmt_idr, ath12k_mac_tx_mgmt_pending_free, ar);
ath12k_mac_tx_mgmt_pending_free(ar);
idr_destroy(&ar->txmgmt_idr);
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
@ -14746,6 +14747,56 @@ static void ath12k_mac_cleanup_unregister(struct ath12k *ar)
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
}
static void ath12k_mac_cleanup_mac_address_list(struct ath12k_hw *ah)
{
kfree(ah->hw->wiphy->addresses);
ah->hw->wiphy->addresses = NULL;
ah->hw->wiphy->n_addresses = 0;
}
static void ath12k_mac_setup_mac_address_list(struct ath12k_hw *ah,
const u8 *mac_addr)
{
struct mac_address *addresses;
struct ath12k *ar;
u16 n_addresses;
int i;
/*
* wiphy->addresses is per wiphy, so the generated interface MAC
* pool is advertised for the whole ath12k_hw. The hw_params flag is
* expected to be consistent across all radios in an ath12k_hw, so
* use the first radio as the source.
*/
ar = ath12k_ah_to_ar(ah, 0);
if (!ar->ab->hw_params->advertise_iface_mac_pool)
return;
/*
* Only the upper nibble of the first octet is varied, so at most 16
* addresses can be derived from one base.
*/
n_addresses = min_t(u16, TARGET_NUM_VDEVS(ar->ab), 16);
if (n_addresses <= 1)
return;
addresses = kzalloc_objs(*addresses, n_addresses);
if (!addresses)
return;
ether_addr_copy(addresses[0].addr, mac_addr);
for (i = 1; i < n_addresses; i++) {
ether_addr_copy(addresses[i].addr, mac_addr);
/* set Local Administered Address bit */
addresses[i].addr[0] |= 0x2;
addresses[i].addr[0] += i << 4;
}
ah->hw->wiphy->addresses = addresses;
ah->hw->wiphy->n_addresses = n_addresses;
}
static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
{
struct ieee80211_hw *hw = ah->hw;
@ -14765,6 +14816,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
ath12k_mac_cleanup_unregister(ar);
ath12k_mac_cleanup_iface_combinations(ah);
ath12k_mac_cleanup_mac_address_list(ah);
SET_IEEE80211_DEV(hw, NULL);
}
@ -14881,6 +14933,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
wiphy->available_antennas_tx = antennas_tx;
SET_IEEE80211_PERM_ADDR(hw, mac_addr);
ath12k_mac_setup_mac_address_list(ah, mac_addr);
SET_IEEE80211_DEV(hw, ab->dev);
ret = ath12k_mac_setup_iface_combinations(ah);
@ -15123,6 +15176,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
ath12k_mac_cleanup_unregister(ar);
}
ath12k_mac_cleanup_mac_address_list(ah);
SET_IEEE80211_DEV(hw, NULL);
return ret;

View File

@ -173,7 +173,7 @@ struct ath12k *ath12k_mac_get_ar_by_pdev_id(struct ath12k_base *ab, u32 pdev_id)
void ath12k_mac_drain_tx(struct ath12k *ar);
void ath12k_mac_peer_cleanup_all(struct ath12k *ar);
void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah);
int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
void ath12k_mac_tx_mgmt_pending_free(struct ath12k *ar);
enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw);
enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw);
enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher);

View File

@ -2100,41 +2100,15 @@ enum hal_rx_reo_queue_pn_size {
#define HAL_RX_REO_QUEUE_INFO0_VLD BIT(0)
#define HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER GENMASK(2, 1)
#define HAL_RX_REO_QUEUE_INFO0_DIS_DUP_DETECTION BIT(3)
#define HAL_RX_REO_QUEUE_INFO0_SOFT_REORDER_EN BIT(4)
#define HAL_RX_REO_QUEUE_INFO0_AC GENMASK(6, 5)
#define HAL_RX_REO_QUEUE_INFO0_BAR BIT(7)
#define HAL_RX_REO_QUEUE_INFO0_RETRY BIT(8)
#define HAL_RX_REO_QUEUE_INFO0_CHECK_2K_MODE BIT(9)
#define HAL_RX_REO_QUEUE_INFO0_OOR_MODE BIT(10)
#define HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE GENMASK(20, 11)
#define HAL_RX_REO_QUEUE_INFO0_PN_CHECK BIT(21)
#define HAL_RX_REO_QUEUE_INFO0_EVEN_PN BIT(22)
#define HAL_RX_REO_QUEUE_INFO0_UNEVEN_PN BIT(23)
#define HAL_RX_REO_QUEUE_INFO0_PN_HANDLE_ENABLE BIT(24)
#define HAL_RX_REO_QUEUE_INFO0_PN_SIZE GENMASK(26, 25)
#define HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG BIT(27)
#define HAL_RX_REO_QUEUE_INFO1_SVLD BIT(0)
#define HAL_RX_REO_QUEUE_INFO1_SSN GENMASK(12, 1)
#define HAL_RX_REO_QUEUE_INFO1_CURRENT_IDX GENMASK(22, 13)
#define HAL_RX_REO_QUEUE_INFO1_SEQ_2K_ERR BIT(23)
#define HAL_RX_REO_QUEUE_INFO1_PN_ERR BIT(24)
#define HAL_RX_REO_QUEUE_INFO1_PN_VALID BIT(31)
#define HAL_RX_REO_QUEUE_INFO2_MPDU_COUNT GENMASK(6, 0)
#define HAL_RX_REO_QUEUE_INFO2_MSDU_COUNT (31, 7)
#define HAL_RX_REO_QUEUE_INFO3_TIMEOUT_COUNT GENMASK(9, 4)
#define HAL_RX_REO_QUEUE_INFO3_FWD_DUE_TO_BAR_CNT GENMASK(15, 10)
#define HAL_RX_REO_QUEUE_INFO3_DUPLICATE_COUNT GENMASK(31, 16)
#define HAL_RX_REO_QUEUE_INFO4_FRAME_IN_ORD_COUNT GENMASK(23, 0)
#define HAL_RX_REO_QUEUE_INFO4_BAR_RECVD_COUNT GENMASK(31, 24)
#define HAL_RX_REO_QUEUE_INFO5_LATE_RX_MPDU_COUNT GENMASK(11, 0)
#define HAL_RX_REO_QUEUE_INFO5_WINDOW_JUMP_2K GENMASK(15, 12)
#define HAL_RX_REO_QUEUE_INFO5_HOLE_COUNT GENMASK(31, 16)
struct hal_rx_reo_queue {
struct hal_desc_header desc_hdr;

View File

@ -447,6 +447,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
.advertise_iface_mac_pool = false,
},
{
.name = "wcn7850 hw2.0",
@ -542,6 +543,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = false,
.advertise_iface_mac_pool = true,
},
{
.name = "qcn9274 hw2.0",
@ -633,6 +635,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
.advertise_iface_mac_pool = false,
},
{
.name = "ipq5332 hw1.0",
@ -718,6 +721,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
.advertise_iface_mac_pool = false,
},
{
.name = "qcc2072 hw1.0",
@ -814,6 +818,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = false,
.advertise_iface_mac_pool = true,
},
{
.name = "ipq5424 hw1.0",
@ -902,6 +907,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
.advertise_iface_mac_pool = false,
},
};

View File

@ -5050,6 +5050,7 @@ static int ath12k_wmi_svc_rdy_ext_parse(struct ath12k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
{
struct ath12k_svc_ext_info *svc_ext_info = &ab->wmi_ab.svc_ext_info;
struct ath12k_wmi_pdev *wmi_handle = &ab->wmi_ab.wmi[0];
struct ath12k_wmi_svc_rdy_ext_parse *svc_rdy_ext = data;
int ret;
@ -5094,6 +5095,22 @@ static int ath12k_wmi_svc_rdy_ext_parse(struct ath12k_base *ab,
return ret;
}
if (svc_rdy_ext->tot_phy_id >
ARRAY_SIZE(svc_ext_info->mac_phy_info)) {
ath12k_warn(ab, "too many PHY entries %u (max %zu)\n",
svc_rdy_ext->tot_phy_id,
ARRAY_SIZE(svc_ext_info->mac_phy_info));
return -EINVAL;
}
if (svc_rdy_ext->n_mac_phy_caps < svc_rdy_ext->tot_phy_id) {
ath12k_warn(ab,
"not enough MAC/PHY caps %u, expected %u\n",
svc_rdy_ext->n_mac_phy_caps,
svc_rdy_ext->tot_phy_id);
return -EINVAL;
}
ath12k_wmi_save_all_mac_phy_info(ab, svc_rdy_ext);
svc_rdy_ext->mac_phy_done = true;

View File

@ -1560,9 +1560,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
rtnl_lock();
ath6kl_cfg80211_vif_cleanup(vif);
rtnl_unlock();
return 0;
}

View File

@ -1363,6 +1363,8 @@ void ath9k_init_channel_context(struct ath_softc *sc)
void ath9k_deinit_channel_context(struct ath_softc *sc)
{
timer_shutdown_sync(&sc->sched.timer);
timer_shutdown_sync(&sc->offchannel.timer);
cancel_work_sync(&sc->chanctx_work);
}

View File

@ -805,6 +805,15 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
buf[len] = '\0';
/*
* Every command below drives PHY register writes. Refuse them while
* the hardware is disabled (the interface is down): on the AR9271
* that traffic hangs the firmware until the device is re-enumerated.
* The reset control refuses on the same flag.
*/
if (test_bit(ATH_OP_INVALID, &common->op_flags))
return -EBUSY;
if (strncmp("trigger", buf, 7) == 0) {
ath9k_cmn_spectral_scan_trigger(common, spec_priv);
} else if (strncmp("background", buf, 10) == 0) {