From 243874c64c8137bc90455200a7735da72836ecab Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Mon, 16 Mar 2020 07:37:19 +0200 Subject: ath11k: handle RX fragments IPQ8074 HW has support to verify the PN of the received frames. For all frames except for fragmented ones, HW checks the PN and delivers them to the driver. For fragmented frames, driver is required to do a little more; it has to reassemble the fragments and then reinject them to the HW for verifying the PN. Currently, to keep the logic simple, PN verifcation is disabled in HW and is handled in mac80211 for all the frames (fragmented and unfragmented). On the contrary, offloading PN Validation to the HW brings important benefits. It reduces CPU cycles spent on the host CPU for verifying the same; helps in enabling features which improve performance like mac80211 fast RX path, enabling multiple REO rings for parallel RX processing, 802.11 decapsulation offloading. All these features are dependent on PN offload which in turn is dependent on handling of the received fragments in the driver. When TKIP security is used, additional handling is required while processing the fragments; since MIC is computed on an MSDU in TKIP, only the last fragment has the MIC info. In this case, driver has to compute the MIC after reassembly and compare it against the MIC present in the frame. For this, MICHAEL_MIC kernel crypto library APIs are used and the dependencies are appropriately set. Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/Kconfig | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/dp.c | 8 + drivers/net/wireless/ath/ath11k/dp.h | 12 + drivers/net/wireless/ath/ath11k/dp_rx.c | 755 ++++++++++++++++++++++++++---- drivers/net/wireless/ath/ath11k/dp_rx.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 14 +- drivers/net/wireless/ath/ath11k/peer.h | 7 + drivers/net/wireless/ath/ath11k/rx_desc.h | 2 +- 9 files changed, 709 insertions(+), 92 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig index c88e16d4022b..738f99090d83 100644 --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -3,6 +3,7 @@ config ATH11K tristate "Qualcomm Technologies 802.11ax chipset support" depends on MAC80211 && HAS_DMA depends on REMOTEPROC + depends on CRYPTO_MICHAEL_MIC depends on ARCH_QCOM || COMPILE_TEST select ATH_COMMON select QCOM_QMI_HELPERS diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 5c767d87c174..af83429fb4fd 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -77,6 +77,7 @@ struct ath11k_skb_rxcb { u8 err_code; u8 mac_id; u8 unmapped; + u8 is_frag; }; enum ath11k_hw_rev { diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index ce7634111bcf..99717447ca1d 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -3,6 +3,7 @@ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ +#include #include "core.h" #include "dp_tx.h" #include "hal_tx.h" @@ -33,6 +34,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr) } ath11k_peer_rx_tid_cleanup(ar, peer); + crypto_free_shash(peer->tfm_mmic); spin_unlock_bh(&ab->base_lock); } @@ -65,6 +67,12 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr) } } + ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id); + if (ret) { + ath11k_warn(ab, "failed to setup rx defrag context\n"); + return ret; + } + /* TODO: Setup other peer specific resource used in data path */ return 0; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 4f9e4cea056a..ed11728478e9 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -22,6 +22,18 @@ struct dp_rx_tid { u32 size; u32 ba_win_sz; bool active; + + /* Info related to rx fragments */ + u32 cur_sn; + u16 last_frag_no; + u16 rx_frag_bitmap; + + struct sk_buff_head rx_frags; + struct hal_reo_dest_ring *dst_ring_desc; + + /* Timer info related to fragments */ + struct timer_list frag_timer; + struct ath11k_base *ab; }; #define DP_REO_DESC_FREE_TIMEOUT_MS 1000 diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index dc7881baf809..9871f2d18ad3 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -4,6 +4,7 @@ */ #include +#include #include "core.h" #include "debug.h" #include "hal_desc.h" @@ -13,6 +14,8 @@ #include "dp_tx.h" #include "peer.h" +#define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + static u8 *ath11k_dp_rx_h_80211_hdr(struct hal_rx_desc *desc) { return desc->hdr_status; @@ -28,10 +31,44 @@ static enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct hal_rx_des __le32_to_cpu(desc->mpdu_start.info2)); } -static u8 ath11k_dp_rx_h_mpdu_start_decap_type(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_decap_type(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT, + __le32_to_cpu(desc->msdu_start.info2)); +} + +static bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID, + __le32_to_cpu(desc->mpdu_start.info1)); +} + +static bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_FCTRL_VALID, + __le32_to_cpu(desc->mpdu_start.info1)); +} + +static bool ath11k_dp_rx_h_mpdu_start_more_frags(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + return ieee80211_has_morefrags(hdr->frame_control); +} + +static u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct sk_buff *skb) { - return FIELD_GET(RX_MPDU_START_INFO5_DECAP_TYPE, - __le32_to_cpu(desc->mpdu_start.info5)); + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; +} + +static u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_NUM, + __le32_to_cpu(desc->mpdu_start.info1)); } static bool ath11k_dp_rx_h_attn_msdu_done(struct hal_rx_desc *desc) @@ -137,6 +174,17 @@ static u8 ath11k_dp_rx_h_msdu_start_nss(struct hal_rx_desc *desc) return hweight8(mimo_ss_bitmap); } +static u8 ath11k_dp_rx_h_mpdu_start_tid(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO2_TID, + __le32_to_cpu(desc->mpdu_start.info2)); +} + +static u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->mpdu_start.sw_peer_id); +} + static u8 ath11k_dp_rx_h_msdu_end_l3pad(struct hal_rx_desc *desc) { return FIELD_GET(RX_MSDU_END_INFO2_L3_HDR_PADDING, @@ -661,12 +709,75 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar, rx_tid->active = false; } +static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, + u32 *link_desc, + enum hal_wbm_rel_bm_act action) +{ + struct ath11k_dp *dp = &ab->dp; + struct hal_srng *srng; + u32 *desc; + int ret = 0; + + srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath11k_hal_srng_access_begin(ab, srng); + + desc = ath11k_hal_srng_src_get_next_entry(ab, srng); + if (!desc) { + ret = -ENOBUFS; + goto exit; + } + + ath11k_hal_rx_msdu_link_desc_set(ab, (void *)desc, (void *)link_desc, + action); + +exit: + ath11k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + return ret; +} + +static void ath11k_dp_rx_frags_cleanup(struct dp_rx_tid *rx_tid, bool rel_link_desc) +{ + struct ath11k_base *ab = rx_tid->ab; + + lockdep_assert_held(&ab->base_lock); + + if (rx_tid->dst_ring_desc) { + if (rel_link_desc) + ath11k_dp_rx_link_desc_return(ab, (u32 *)rx_tid->dst_ring_desc, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + kfree(rx_tid->dst_ring_desc); + rx_tid->dst_ring_desc = NULL; + } + + rx_tid->cur_sn = 0; + rx_tid->last_frag_no = 0; + rx_tid->rx_frag_bitmap = 0; + __skb_queue_purge(&rx_tid->rx_frags); +} + void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer) { + struct dp_rx_tid *rx_tid; int i; - for (i = 0; i <= IEEE80211_NUM_TIDS; i++) + lockdep_assert_held(&ar->ab->base_lock); + + for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { + rx_tid = &peer->rx_tid[i]; + ath11k_peer_rx_tid_delete(ar, peer, i); + ath11k_dp_rx_frags_cleanup(rx_tid, true); + + spin_unlock_bh(&ar->ab->base_lock); + del_timer_sync(&rx_tid->frag_timer); + spin_lock_bh(&ar->ab->base_lock); + } } static int ath11k_peer_rx_tid_reo_update(struct ath11k *ar, @@ -1525,7 +1636,9 @@ static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar, msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc); - if (!rxcb->is_continuation) { + if (rxcb->is_frag) { + skb_pull(msdu, HAL_RX_DESC_SIZE); + } else if (!rxcb->is_continuation) { skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len); skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes); } else { @@ -1830,7 +1943,7 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, u8 decap; first_hdr = ath11k_dp_rx_h_80211_hdr(rx_desc); - decap = ath11k_dp_rx_h_mpdu_start_decap_type(rx_desc); + decap = ath11k_dp_rx_h_msdu_start_decap_type(rx_desc); switch (decap) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: @@ -2668,99 +2781,563 @@ exit: return num_buffs_reaped; } -static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, - u32 *link_desc, - enum hal_wbm_rel_bm_act action) +static void ath11k_dp_rx_frag_timer(struct timer_list *timer) { - struct ath11k_dp *dp = &ab->dp; - struct hal_srng *srng; - u32 *desc; - int ret = 0; + struct dp_rx_tid *rx_tid = from_timer(rx_tid, timer, frag_timer); - srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + spin_lock_bh(&rx_tid->ab->base_lock); + if (rx_tid->last_frag_no && + rx_tid->rx_frag_bitmap == GENMASK(rx_tid->last_frag_no, 0)) { + spin_unlock_bh(&rx_tid->ab->base_lock); + return; + } + ath11k_dp_rx_frags_cleanup(rx_tid, true); + spin_unlock_bh(&rx_tid->ab->base_lock); +} - spin_lock_bh(&srng->lock); +int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id) +{ + struct ath11k_base *ab = ar->ab; + struct crypto_shash *tfm; + struct ath11k_peer *peer; + struct dp_rx_tid *rx_tid; + int i; - ath11k_hal_srng_access_begin(ab, srng); + tfm = crypto_alloc_shash("michael_mic", 0, 0); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - desc = ath11k_hal_srng_src_get_next_entry(ab, srng); - if (!desc) { - ret = -ENOBUFS; - goto exit; + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find(ab, vdev_id, peer_mac); + if (!peer) { + ath11k_warn(ab, "failed to find the peer to set up fragment info\n"); + spin_unlock_bh(&ab->base_lock); + return -ENOENT; } - ath11k_hal_rx_msdu_link_desc_set(ab, (void *)desc, (void *)link_desc, - action); + for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { + rx_tid = &peer->rx_tid[i]; + rx_tid->ab = ab; + timer_setup(&rx_tid->frag_timer, ath11k_dp_rx_frag_timer, 0); + skb_queue_head_init(&rx_tid->rx_frags); + } -exit: - ath11k_hal_srng_access_end(ab, srng); + peer->tfm_mmic = tfm; + spin_unlock_bh(&ab->base_lock); - spin_unlock_bh(&srng->lock); + return 0; +} + +static int ath11k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, + struct ieee80211_hdr *hdr, u8 *data, + size_t data_len, u8 *mic) +{ + SHASH_DESC_ON_STACK(desc, tfm); + u8 mic_hdr[16] = {0}; + u8 tid = 0; + int ret; + + if (!tfm) + return -EINVAL; + + desc->tfm = tfm; + + ret = crypto_shash_setkey(tfm, key, 8); + if (ret) + goto out; + ret = crypto_shash_init(desc); + if (ret) + goto out; + + /* TKIP MIC header */ + memcpy(mic_hdr, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(mic_hdr + ETH_ALEN, ieee80211_get_SA(hdr), ETH_ALEN); + if (ieee80211_is_data_qos(hdr->frame_control)) + tid = ieee80211_get_tid(hdr); + mic_hdr[12] = tid; + + ret = crypto_shash_update(desc, mic_hdr, 16); + if (ret) + goto out; + ret = crypto_shash_update(desc, data, data_len); + if (ret) + goto out; + ret = crypto_shash_final(desc, mic); +out: + shash_desc_zero(desc); return ret; } -static void ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ieee80211_rx_status *rx_status) +static int ath11k_dp_rx_h_verify_tkip_mic(struct ath11k *ar, struct ath11k_peer *peer, + struct sk_buff *msdu) { - u8 rx_channel; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); + struct ieee80211_key_conf *key_conf; + struct ieee80211_hdr *hdr; + u8 mic[IEEE80211_CCMP_MIC_LEN]; + int head_len, tail_len, ret; + size_t data_len; + u32 hdr_len; + u8 *key, *data; + u8 key_idx; + + if (ath11k_dp_rx_h_mpdu_start_enctype(rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + return 0; + + hdr = (struct ieee80211_hdr *)(msdu->data + HAL_RX_DESC_SIZE); + hdr_len = ieee80211_hdrlen(hdr->frame_control); + head_len = hdr_len + HAL_RX_DESC_SIZE + IEEE80211_TKIP_IV_LEN; + tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; + + if (!is_multicast_ether_addr(hdr->addr1)) + key_idx = peer->ucast_keyidx; + else + key_idx = peer->mcast_keyidx; + + key_conf = peer->keys[key_idx]; + + data = msdu->data + head_len; + data_len = msdu->len - head_len - tail_len; + key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; + + ret = ath11k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); + if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) + goto mic_fail; + + return 0; + +mic_fail: + (ATH11K_SKB_RXCB(msdu))->is_first_msdu = 1; + (ATH11K_SKB_RXCB(msdu))->is_last_msdu = 1; + + rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | + RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; + skb_pull(msdu, HAL_RX_DESC_SIZE); + + ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs); + ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); + ieee80211_rx(ar->hw, msdu); + return -EINVAL; +} + +static void ath11k_dp_rx_h_undecap_frag(struct ath11k *ar, struct sk_buff *msdu, + enum hal_encrypt_type enctype, u32 flags) +{ + struct ieee80211_hdr *hdr; + size_t hdr_len; + size_t crypto_len; + + if (!flags) + return; + + hdr = (struct ieee80211_hdr *)(msdu->data + HAL_RX_DESC_SIZE); + + if (flags & RX_FLAG_MIC_STRIPPED) + skb_trim(msdu, msdu->len - + ath11k_dp_rx_crypto_mic_len(ar, enctype)); + + if (flags & RX_FLAG_ICV_STRIPPED) + skb_trim(msdu, msdu->len - + ath11k_dp_rx_crypto_icv_len(ar, enctype)); + + if (flags & RX_FLAG_IV_STRIPPED) { + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); + + memmove((void *)msdu->data + HAL_RX_DESC_SIZE + crypto_len, + (void *)msdu->data + HAL_RX_DESC_SIZE, hdr_len); + skb_pull(msdu, crypto_len); + } +} + +static int ath11k_dp_rx_h_defrag(struct ath11k *ar, + struct ath11k_peer *peer, + struct dp_rx_tid *rx_tid, + struct sk_buff **defrag_skb) +{ + struct hal_rx_desc *rx_desc; + struct sk_buff *skb, *first_frag, *last_frag; + struct ieee80211_hdr *hdr; enum hal_encrypt_type enctype; - bool is_decrypted; - u32 err_bitmap; + bool is_decrypted = false; + int msdu_len = 0; + int extra_space; + u32 flags; + + first_frag = skb_peek(&rx_tid->rx_frags); + last_frag = skb_peek_tail(&rx_tid->rx_frags); + + skb_queue_walk(&rx_tid->rx_frags, skb) { + flags = 0; + rx_desc = (struct hal_rx_desc *)skb->data; + hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + + enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN) + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); + + if (is_decrypted) { + if (skb != first_frag) + flags |= RX_FLAG_IV_STRIPPED; + if (skb != last_frag) + flags |= RX_FLAG_ICV_STRIPPED | + RX_FLAG_MIC_STRIPPED; + } - is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); - enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); - err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc); + /* RX fragments are always raw packets */ + if (skb != last_frag) + skb_trim(skb, skb->len - FCS_LEN); + ath11k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); - if (err_bitmap & DP_RX_MPDU_ERR_FCS) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (skb != first_frag) + skb_pull(skb, HAL_RX_DESC_SIZE + + ieee80211_hdrlen(hdr->frame_control)); + msdu_len += skb->len; + } - if (err_bitmap & DP_RX_MPDU_ERR_TKIP_MIC) - rx_status->flag |= RX_FLAG_MMIC_ERROR; + extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag)); + if (extra_space > 0 && + (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0)) + return -ENOMEM; - rx_status->encoding = RX_ENC_LEGACY; - rx_status->bw = RATE_INFO_BW_20; + __skb_unlink(first_frag, &rx_tid->rx_frags); + while ((skb = __skb_dequeue(&rx_tid->rx_frags))) { + skb_put_data(first_frag, skb->data, skb->len); + dev_kfree_skb_any(skb); + } - rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + hdr = (struct ieee80211_hdr *)(first_frag->data + HAL_RX_DESC_SIZE); + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); + ATH11K_SKB_RXCB(first_frag)->is_frag = 1; - rx_channel = ath11k_dp_rx_h_msdu_start_freq(rx_desc); + if (ath11k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) + first_frag = NULL; - if (rx_channel >= 1 && rx_channel <= 14) { - rx_status->band = NL80211_BAND_2GHZ; - } else if (rx_channel >= 36 && rx_channel <= 173) { - rx_status->band = NL80211_BAND_5GHZ; - } else { - ath11k_warn(ar->ab, "Unsupported Channel info received %d\n", - rx_channel); + *defrag_skb = first_frag; + return 0; +} + +static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_tid *rx_tid, + struct sk_buff *defrag_skb) +{ + struct ath11k_base *ab = ar->ab; + struct ath11k_pdev_dp *dp = &ar->dp; + struct dp_rxdma_ring *rx_refill_ring = &dp->rx_refill_buf_ring; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; + struct hal_reo_entrance_ring *reo_ent_ring; + struct hal_reo_dest_ring *reo_dest_ring; + struct dp_link_desc_bank *link_desc_banks; + struct hal_rx_msdu_link *msdu_link; + struct hal_rx_msdu_details *msdu0; + struct hal_srng *srng; + dma_addr_t paddr; + u32 desc_bank, msdu_info, mpdu_info; + u32 dst_idx, cookie; + u32 *msdu_len_offset; + int ret, buf_id; + + link_desc_banks = ab->dp.link_desc_banks; + reo_dest_ring = rx_tid->dst_ring_desc; + + ath11k_hal_rx_reo_ent_paddr_get(ab, reo_dest_ring, &paddr, &desc_bank); + msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + + (paddr - link_desc_banks[desc_bank].paddr)); + msdu0 = &msdu_link->msdu_link[0]; + dst_idx = FIELD_GET(RX_MSDU_DESC_INFO0_REO_DEST_IND, msdu0->rx_msdu_info.info0); + memset(msdu0, 0, sizeof(*msdu0)); + + msdu_info = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1) | + FIELD_PREP(RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU, 1) | + FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_CONTINUATION, 0) | + FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_LENGTH, + defrag_skb->len - HAL_RX_DESC_SIZE) | + FIELD_PREP(RX_MSDU_DESC_INFO0_REO_DEST_IND, dst_idx) | + FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_SA, 1) | + FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_DA, 1); + msdu0->rx_msdu_info.info0 = msdu_info; + + /* change msdu len in hal rx desc */ + msdu_len_offset = (u32 *)&rx_desc->msdu_start; + *msdu_len_offset &= ~(RX_MSDU_START_INFO1_MSDU_LENGTH); + *msdu_len_offset |= defrag_skb->len - HAL_RX_DESC_SIZE; + + paddr = dma_map_single(ab->dev, defrag_skb->data, + defrag_skb->len + skb_tailroom(defrag_skb), + DMA_FROM_DEVICE); + if (dma_mapping_error(ab->dev, paddr)) + return -ENOMEM; + + spin_lock_bh(&rx_refill_ring->idr_lock); + buf_id = idr_alloc(&rx_refill_ring->bufs_idr, defrag_skb, 0, + rx_refill_ring->bufs_max * 3, GFP_ATOMIC); + spin_unlock_bh(&rx_refill_ring->idr_lock); + if (buf_id < 0) { + ret = -ENOMEM; + goto err_unmap_dma; + } + + ATH11K_SKB_RXCB(defrag_skb)->paddr = paddr; + cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) | + FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); + + ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM); + + /* Fill mpdu details into reo entrace ring */ + srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id]; + + spin_lock_bh(&srng->lock); + ath11k_hal_srng_access_begin(ab, srng); + + reo_ent_ring = (struct hal_reo_entrance_ring *) + ath11k_hal_srng_src_get_next_entry(ab, srng); + if (!reo_ent_ring) { + ath11k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + ret = -ENOSPC; + goto err_free_idr; + } + memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); + + ath11k_hal_rx_reo_ent_paddr_get(ab, reo_dest_ring, &paddr, &desc_bank); + ath11k_hal_rx_buf_addr_info_set(reo_ent_ring, paddr, desc_bank, + HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST); + + mpdu_info = FIELD_PREP(RX_MPDU_DESC_INFO0_MSDU_COUNT, 1) | + FIELD_PREP(RX_MPDU_DESC_INFO0_SEQ_NUM, rx_tid->cur_sn) | + FIELD_PREP(RX_MPDU_DESC_INFO0_FRAG_FLAG, 0) | + FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_SA, 1) | + FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_DA, 1) | + FIELD_PREP(RX_MPDU_DESC_INFO0_RAW_MPDU, 1) | + FIELD_PREP(RX_MPDU_DESC_INFO0_VALID_PN, 1); + + reo_ent_ring->rx_mpdu_info.info0 = mpdu_info; + reo_ent_ring->rx_mpdu_info.meta_data = reo_dest_ring->rx_mpdu_info.meta_data; + reo_ent_ring->queue_addr_lo = reo_dest_ring->queue_addr_lo; + reo_ent_ring->info0 = FIELD_PREP(HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI, + FIELD_GET(HAL_REO_DEST_RING_INFO0_QUEUE_ADDR_HI, + reo_dest_ring->info0)) | + FIELD_PREP(HAL_REO_ENTR_RING_INFO0_DEST_IND, dst_idx); + ath11k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return 0; + +err_free_idr: + spin_lock_bh(&rx_refill_ring->idr_lock); + idr_remove(&rx_refill_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_refill_ring->idr_lock); +err_unmap_dma: + dma_unmap_single(ab->dev, paddr, defrag_skb->len + skb_tailroom(defrag_skb), + DMA_FROM_DEVICE); + return ret; +} + +static int ath11k_dp_rx_h_cmp_frags(struct sk_buff *a, struct sk_buff *b) +{ + int frag1, frag2; + + frag1 = ath11k_dp_rx_h_mpdu_start_frag_no(a); + frag2 = ath11k_dp_rx_h_mpdu_start_frag_no(b); + + return frag1 - frag2; +} + +static void ath11k_dp_rx_h_sort_frags(struct sk_buff_head *frag_list, + struct sk_buff *cur_frag) +{ + struct sk_buff *skb; + int cmp; + + skb_queue_walk(frag_list, skb) { + cmp = ath11k_dp_rx_h_cmp_frags(skb, cur_frag); + if (cmp < 0) + continue; + __skb_queue_before(frag_list, skb, cur_frag); return; } + __skb_queue_tail(frag_list, cur_frag); +} - rx_status->freq = ieee80211_channel_to_frequency(rx_channel, - rx_status->band); - ath11k_dp_rx_h_rate(ar, rx_desc, rx_status); +static u64 ath11k_dp_rx_h_get_pn(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + u64 pn = 0; + u8 *ehdr; - /* Rx fragments are received in raw mode */ - skb_trim(msdu, msdu->len - FCS_LEN); + hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + ehdr = skb->data + HAL_RX_DESC_SIZE + ieee80211_hdrlen(hdr->frame_control); - if (is_decrypted) { - rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MIC_STRIPPED; - skb_trim(msdu, msdu->len - - ath11k_dp_rx_crypto_mic_len(ar, enctype)); + pn = ehdr[0]; + pn |= (u64)ehdr[1] << 8; + pn |= (u64)ehdr[4] << 16; + pn |= (u64)ehdr[5] << 24; + pn |= (u64)ehdr[6] << 32; + pn |= (u64)ehdr[7] << 40; + + return pn; +} + +static bool +ath11k_dp_rx_h_defrag_validate_incr_pn(struct ath11k *ar, struct dp_rx_tid *rx_tid) +{ + enum hal_encrypt_type encrypt_type; + struct sk_buff *first_frag, *skb; + struct hal_rx_desc *desc; + u64 last_pn; + u64 cur_pn; + + first_frag = skb_peek(&rx_tid->rx_frags); + desc = (struct hal_rx_desc *)first_frag->data; + + encrypt_type = ath11k_dp_rx_h_mpdu_start_enctype(desc); + if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && + encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) + return true; + + last_pn = ath11k_dp_rx_h_get_pn(first_frag); + skb_queue_walk(&rx_tid->rx_frags, skb) { + if (skb == first_frag) + continue; + + cur_pn = ath11k_dp_rx_h_get_pn(skb); + if (cur_pn != last_pn + 1) + return false; + last_pn = cur_pn; } + return true; +} + +static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar, + struct sk_buff *msdu, + u32 *ring_desc) +{ + struct ath11k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct ath11k_peer *peer; + struct dp_rx_tid *rx_tid; + struct sk_buff *defrag_skb = NULL; + u32 peer_id; + u16 seqno, frag_no; + u8 tid; + int ret = 0; + bool more_frags; + + rx_desc = (struct hal_rx_desc *)msdu->data; + peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(rx_desc); + tid = ath11k_dp_rx_h_mpdu_start_tid(rx_desc); + seqno = ath11k_dp_rx_h_mpdu_start_seq_no(rx_desc); + frag_no = ath11k_dp_rx_h_mpdu_start_frag_no(msdu); + more_frags = ath11k_dp_rx_h_mpdu_start_more_frags(msdu); + + if (!ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(rx_desc) || + !ath11k_dp_rx_h_mpdu_start_fc_valid(rx_desc) || + tid > IEEE80211_NUM_TIDS) + return -EINVAL; + + /* received unfragmented packet in reo + * exception ring, this shouldn't happen + * as these packets typically come from + * reo2sw srngs. + */ + if (WARN_ON_ONCE(!frag_no && !more_frags)) + return -EINVAL; + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath11k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", + peer_id); + ret = -ENOENT; + goto out_unlock; + } + rx_tid = &peer->rx_tid[tid]; + + if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || + skb_queue_empty(&rx_tid->rx_frags)) { + /* Flush stored fragments and start a new sequence */ + ath11k_dp_rx_frags_cleanup(rx_tid, true); + rx_tid->cur_sn = seqno; + } + + if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { + /* Fragment already present */ + ret = -EINVAL; + goto out_unlock; + } + + if (frag_no > __fls(rx_tid->rx_frag_bitmap)) + __skb_queue_tail(&rx_tid->rx_frags, msdu); + else + ath11k_dp_rx_h_sort_frags(&rx_tid->rx_frags, msdu); + + rx_tid->rx_frag_bitmap |= BIT(frag_no); + if (!more_frags) + rx_tid->last_frag_no = frag_no; + + if (frag_no == 0) { + rx_tid->dst_ring_desc = kmemdup(ring_desc, + sizeof(*rx_tid->dst_ring_desc), + GFP_ATOMIC); + if (!rx_tid->dst_ring_desc) { + ret = -ENOMEM; + goto out_unlock; + } + } else { + ath11k_dp_rx_link_desc_return(ab, ring_desc, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + if (!rx_tid->last_frag_no || + rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { + mod_timer(&rx_tid->frag_timer, jiffies + + ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS); + goto out_unlock; + } + + spin_unlock_bh(&ab->base_lock); + del_timer_sync(&rx_tid->frag_timer); + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find_by_id(ab, peer_id); + if (!peer) + goto err_frags_cleanup; + + if (!ath11k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + goto err_frags_cleanup; + + if (ath11k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + goto err_frags_cleanup; + + if (!defrag_skb) + goto err_frags_cleanup; + + if (ath11k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + goto err_frags_cleanup; + + ath11k_dp_rx_frags_cleanup(rx_tid, false); + goto out_unlock; + +err_frags_cleanup: + dev_kfree_skb_any(defrag_skb); + ath11k_dp_rx_frags_cleanup(rx_tid, true); +out_unlock: + spin_unlock_bh(&ab->base_lock); + return ret; } static int -ath11k_dp_process_rx_err_buf(struct ath11k *ar, struct napi_struct *napi, - int buf_id, bool frag) +ath11k_dp_process_rx_err_buf(struct ath11k *ar, u32 *ring_desc, int buf_id, bool drop) { struct ath11k_pdev_dp *dp = &ar->dp; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - struct ieee80211_rx_status rx_status = {0}; struct sk_buff *msdu; struct ath11k_skb_rxcb *rxcb; - struct ieee80211_rx_status *status; struct hal_rx_desc *rx_desc; u16 msdu_len; @@ -2781,10 +3358,7 @@ ath11k_dp_process_rx_err_buf(struct ath11k *ar, struct napi_struct *napi, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); - if (!frag) { - /* Process only rx fragments below, and drop - * msdu's indicated due to error reasons. - */ + if (drop) { dev_kfree_skb_any(msdu); return 0; } @@ -2803,16 +3377,12 @@ ath11k_dp_process_rx_err_buf(struct ath11k *ar, struct napi_struct *napi, rx_desc = (struct hal_rx_desc *)msdu->data; msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE); - - ath11k_dp_rx_frag_h_mpdu(ar, msdu, rx_desc, &rx_status); - - status = IEEE80211_SKB_RXCB(msdu); - - *status = rx_status; - - ath11k_dp_rx_deliver_msdu(ar, napi, msdu); + if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) { + dev_kfree_skb_any(msdu); + ath11k_dp_rx_link_desc_return(ar->ab, ring_desc, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } exit: rcu_read_unlock(); return 0; @@ -2837,6 +3407,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, dma_addr_t paddr; u32 *desc; bool is_frag; + u8 drop = 0; tot_n_bufs_reaped = 0; quota = budget; @@ -2878,9 +3449,15 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, is_frag = !!(reo_desc->rx_mpdu_info.info0 & RX_MPDU_DESC_INFO0_FRAG_FLAG); - /* Return the link desc back to wbm idle list */ - ath11k_dp_rx_link_desc_return(ab, desc, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + /* Process only rx fragments with one msdu per link desc below, and drop + * msdu's indicated due to error reasons. + */ + if (!is_frag || num_msdus > 1) { + drop = 1; + /* Return the link desc back to wbm idle list */ + ath11k_dp_rx_link_desc_return(ab, desc, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } for (i = 0; i < num_msdus; i++) { buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, @@ -2891,8 +3468,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, ar = ab->pdevs[mac_id].ar; - if (!ath11k_dp_process_rx_err_buf(ar, napi, buf_id, - is_frag)) { + if (!ath11k_dp_process_rx_err_buf(ar, desc, buf_id, drop)) { n_bufs_reaped[mac_id]++; tot_n_bufs_reaped++; } @@ -2961,7 +3537,7 @@ static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu, msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(desc); - if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) { + if (!rxcb->is_frag && ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE); ath11k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); @@ -2989,14 +3565,17 @@ static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu, rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(desc); rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(desc); - l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(desc); - - if ((HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) - return -EINVAL; + if (rxcb->is_frag) { + skb_pull(msdu, HAL_RX_DESC_SIZE); + } else { + l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(desc); - skb_put(msdu, HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE + l3pad_bytes); + if ((HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) + return -EINVAL; + skb_put(msdu, HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len); + skb_pull(msdu, HAL_RX_DESC_SIZE + l3pad_bytes); + } ath11k_dp_rx_h_ppdu(ar, desc, status); __skb_queue_tail(&amsdu_list, msdu); diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h index 1b08b7dcafbc..c3f3ccd03a90 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h @@ -84,5 +84,6 @@ int ath11k_dp_rx_mon_status_bufs_replenish(struct ath11k_base *ab, int mac_id, gfp_t gfp); int ath11k_dp_rx_pdev_mon_detach(struct ath11k *ar); int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar); +int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id); #endif /* ATH11K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e28f5a348be6..2b9097557d95 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2384,11 +2384,19 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); - if (peer && cmd == SET_KEY) + if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; - else if (peer && cmd == DISABLE_KEY) + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + peer->ucast_keyidx = key->keyidx; + else + peer->mcast_keyidx = key->keyidx; + } else if (peer && cmd == DISABLE_KEY) { peer->keys[key->keyidx] = NULL; - else if (!peer) + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + peer->ucast_keyidx = 0; + else + peer->mcast_keyidx = 0; + } else if (!peer) /* impossible unless FW goes crazy */ ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr); spin_unlock_bh(&ab->base_lock); diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h index 9a40d1f6ccd9..55d9919b8b5d 100644 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -17,6 +17,13 @@ struct ath11k_peer { /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; struct dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; + + /* Info used in MMIC verification of + * RX fragments + */ + struct crypto_shash *tfm_mmic; + u8 mcast_keyidx; + u8 ucast_keyidx; }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); diff --git a/drivers/net/wireless/ath/ath11k/rx_desc.h b/drivers/net/wireless/ath/ath11k/rx_desc.h index 4d586fd1f872..1c4264637a41 100644 --- a/drivers/net/wireless/ath/ath11k/rx_desc.h +++ b/drivers/net/wireless/ath/ath11k/rx_desc.h @@ -342,7 +342,7 @@ struct rx_attention { #define RX_MPDU_START_INFO0_PROTO_VER_ERR BIT(12) #define RX_MPDU_START_INFO0_AST_LOOKUP_VALID BIT(13) -#define RX_MPDU_START_INFO1_MPDU_CTRL_VALID BIT(0) +#define RX_MPDU_START_INFO1_MPDU_FCTRL_VALID BIT(0) #define RX_MPDU_START_INFO1_MPDU_DUR_VALID BIT(1) #define RX_MPDU_START_INFO1_MAC_ADDR1_VALID BIT(2) #define RX_MPDU_START_INFO1_MAC_ADDR2_VALID BIT(3) -- cgit From 1441b2f205a7c78dc2da11b830751b26cb55ae51 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Mon, 16 Mar 2020 07:37:22 +0200 Subject: ath11k: enable PN offload Enabling PN checking in the hardware; hardware checks the PN of the received packets and reports the errors to the host for further handling; default action is to drop such packets. TSC (TKIP sequence counter) validation is also offloaded. Hardware validates PN/TSC only for unicast packets; for group addressed packets, PN validation is done in mac80211. PN errors are reported to the driver via WBM RX release ring and can be dumped by using the following command. "cat /sys/kernel/debug/ath11k/soc_rx_stats | grep -i pn" Sample Output: PN check fail: 210 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/dp.c | 4 +- drivers/net/wireless/ath/ath11k/dp_rx.c | 115 ++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath11k/dp_rx.h | 7 +- drivers/net/wireless/ath/ath11k/hal.h | 2 +- drivers/net/wireless/ath/ath11k/hal_rx.c | 14 +++- drivers/net/wireless/ath/ath11k/mac.c | 27 ++++++++ 7 files changed, 156 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index af83429fb4fd..af04e1281c3a 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -333,6 +333,7 @@ struct ath11k_sta { u32 bw; u32 nss; u32 smps; + enum hal_pn_type pn_type; struct work_struct update_wk; struct rate_info txrate; diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index 99717447ca1d..a1371ab773ab 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -58,8 +58,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr) } for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) { - ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id, - tid, 1, 0); + ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id, tid, 1, 0, + HAL_PN_TYPE_NONE); if (ret) { ath11k_warn(ab, "failed to setup rxd tid queue for tid %d: %d\n", tid, ret); diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 9871f2d18ad3..320fec2aede3 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -843,7 +843,8 @@ unlock_exit: } int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id, - u8 tid, u32 ba_win_sz, u16 ssn) + u8 tid, u32 ba_win_sz, u16 ssn, + enum hal_pn_type pn_type) { struct ath11k_base *ab = ar->ab; struct ath11k_peer *peer; @@ -904,7 +905,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id, addr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); - ath11k_hal_reo_qdesc_setup(addr_aligned, tid, ba_win_sz, ssn); + ath11k_hal_reo_qdesc_setup(addr_aligned, tid, ba_win_sz, + ssn, pn_type); paddr = dma_map_single(ab->dev, addr_aligned, hw_desc_sz, DMA_BIDIRECTIONAL); @@ -948,7 +950,7 @@ int ath11k_dp_rx_ampdu_start(struct ath11k *ar, ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, params->tid, params->buf_size, - params->ssn); + params->ssn, arsta->pn_type); if (ret) ath11k_warn(ab, "failed to setup rx tid %d\n", ret); @@ -1001,8 +1003,80 @@ int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, return ret; } -static int ath11k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, - u16 peer_id) +int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif, + const u8 *peer_addr, + enum set_key_cmd key_cmd, + struct ieee80211_key_conf *key) +{ + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + struct ath11k_hal_reo_cmd cmd = {0}; + struct ath11k_peer *peer; + struct dp_rx_tid *rx_tid; + u8 tid; + int ret = 0; + + /* NOTE: Enable PN/TSC replay check offload only for unicast frames. + * We use mac80211 PN/TSC replay check functionality for bcast/mcast + * for now. + */ + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return 0; + + cmd.flag |= HAL_REO_CMD_FLG_NEED_STATUS; + cmd.upd0 |= HAL_REO_CMD_UPD0_PN | + HAL_REO_CMD_UPD0_PN_SIZE | + HAL_REO_CMD_UPD0_PN_VALID | + HAL_REO_CMD_UPD0_PN_CHECK | + HAL_REO_CMD_UPD0_SVLD; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (key_cmd == SET_KEY) { + cmd.upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; + cmd.pn_size = 48; + } + break; + default: + break; + } + + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); + if (!peer) { + ath11k_warn(ab, "failed to find the peer to configure pn replay detection\n"); + spin_unlock_bh(&ab->base_lock); + return -ENOENT; + } + + for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) { + rx_tid = &peer->rx_tid[tid]; + if (!rx_tid->active) + continue; + cmd.addr_lo = lower_32_bits(rx_tid->paddr); + cmd.addr_hi = upper_32_bits(rx_tid->paddr); + ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, + &cmd, NULL); + if (ret) { + ath11k_warn(ab, "failed to configure rx tid %d queue for pn replay detection %d\n", + tid, ret); + break; + } + } + + spin_unlock_bh(&ar->ab->base_lock); + + return ret; +} + +static inline int ath11k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, + u16 peer_id) { int i; @@ -1974,7 +2048,7 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, struct sk_buff *last_msdu; struct sk_buff *msdu; struct ath11k_skb_rxcb *last_rxcb; - bool is_decrypted; + bool is_decrypted = false, fill_crypto_hdr; u32 err_bitmap; u8 *qos; @@ -1991,6 +2065,9 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; } + /* PN for multicast packets will be checked in mac80211 */ + fill_crypto_hdr = is_multicast_ether_addr(hdr->addr1); + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); @@ -2013,14 +2090,27 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, if (err_bitmap & DP_RX_MPDU_ERR_TKIP_MIC) rx_status->flag |= RX_FLAG_MMIC_ERROR; - if (is_decrypted) - rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED | - RX_FLAG_MIC_STRIPPED | RX_FLAG_ICV_STRIPPED; + if (is_decrypted) { + rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; + + if (fill_crypto_hdr) + rx_status->flag |= RX_FLAG_MIC_STRIPPED | + RX_FLAG_ICV_STRIPPED; + else + rx_status->flag |= RX_FLAG_IV_STRIPPED | + RX_FLAG_PN_VALIDATED; + } skb_queue_walk(amsdu_list, msdu) { ath11k_dp_rx_h_csum_offload(msdu); ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, enctype, rx_status, is_decrypted); + + if (!is_decrypted || fill_crypto_hdr) + continue; + + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); } } @@ -3603,6 +3693,13 @@ static bool ath11k_dp_rx_h_reo_err(struct ath11k *ar, struct sk_buff *msdu, if (ath11k_dp_rx_h_null_q_desc(ar, msdu, status, msdu_list)) drop = true; break; + case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: + /* TODO: Do not drop PN failed packets in the driver; + * instead, it is good to drop such packets in mac80211 + * after incrementing the replay counters. + */ + + /* fall through */ default: /* TODO: Review other errors and process them to mac80211 * as appropriate. diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h index c3f3ccd03a90..9ab535fde5a8 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h @@ -43,11 +43,16 @@ int ath11k_dp_rx_ampdu_start(struct ath11k *ar, struct ieee80211_ampdu_params *params); int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, struct ieee80211_ampdu_params *params); +int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif, + const u8 *peer_addr, + enum set_key_cmd key_cmd, + struct ieee80211_key_conf *key); void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer); void ath11k_peer_rx_tid_delete(struct ath11k *ar, struct ath11k_peer *peer, u8 tid); int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id, - u8 tid, u32 ba_win_sz, u16 ssn); + u8 tid, u32 ba_win_sz, u16 ssn, + enum hal_pn_type pn_type); void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, struct sk_buff *skb); int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h index 5b13ccdf39e4..4cfd93494c03 100644 --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -847,7 +847,7 @@ struct ath11k_hal { u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, - u32 start_seqtype); + u32 start_seq, enum hal_pn_type type); void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, struct hal_srng *srng); void ath11k_hal_reo_hw_setup(struct ath11k_base *ab); diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 58c57f91b672..3a666565cd1e 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -694,7 +694,7 @@ u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) } void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, - u32 start_seq) + u32 start_seq, enum hal_pn_type type) { struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr; struct hal_rx_reo_queue_ext *ext_desc; @@ -723,6 +723,18 @@ void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE, ba_window_size - 1); + switch (type) { + case HAL_PN_TYPE_NONE: + case HAL_PN_TYPE_WAPI_EVEN: + case HAL_PN_TYPE_WAPI_UNEVEN: + break; + case HAL_PN_TYPE_WPA: + qdesc->info0 |= + FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) | + FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE, + HAL_RX_REO_QUEUE_PN_SIZE_48); + break; + } /* TODO: Set Ignore ampdu flags based on BA window size and/or * AMPDU capabilities diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2b9097557d95..c02e4a3eaef2 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2325,6 +2325,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ath11k_base *ab = ar->ab; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ath11k_peer *peer; + struct ath11k_sta *arsta; const u8 *peer_addr; int ret = 0; u32 flags = 0; @@ -2382,6 +2383,12 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, goto exit; } + ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key); + if (ret) { + ath11k_warn(ab, "failed to offload PN replay detection %d\n", ret); + goto exit; + } + spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); if (peer && cmd == SET_KEY) { @@ -2399,6 +2406,26 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } else if (!peer) /* impossible unless FW goes crazy */ ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr); + + if (sta) { + arsta = (struct ath11k_sta *)sta->drv_priv; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (cmd == SET_KEY) + arsta->pn_type = HAL_PN_TYPE_WPA; + else + arsta->pn_type = HAL_PN_TYPE_NONE; + break; + default: + arsta->pn_type = HAL_PN_TYPE_NONE; + break; + } + } spin_unlock_bh(&ab->base_lock); exit: -- cgit From 107560d847e6092c3fe3a25a1704b28029230c02 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 11 Feb 2020 13:26:05 +0100 Subject: ath11k: set queue_len to 4096 The driver currently does not use wake_txq_queue. This leads to the tx_queue_len being defaulted to 1000. Setting this parameter will change the queue_len to 4096 which is more fitting for HE. Signed-off-by: John Crispin Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index dd39333ec0ea..9973477ae373 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -62,6 +62,7 @@ #define TARGET_RX_BATCHMODE 1 #define ATH11K_HW_MAX_QUEUES 4 +#define ATH11K_QUEUE_LEN 4096 #define ATH11k_HW_RATECODE_CCK_SHORT_PREAM_MASK 0x4 diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c02e4a3eaef2..61fd81d63efc 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5797,6 +5797,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations; ar->hw->queues = ATH11K_HW_MAX_QUEUES; + ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN; ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1; ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; -- cgit From 5a032c8d19539997f3ed1850082a747f0d6b206e Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 17 Dec 2019 15:19:20 +0100 Subject: ath11k: add WMI calls required for handling BSS color If the he_operation field of the beacon sets a BSS color, we need to inform the FW of the settings. This patch adds the WMI command handlers required to do so. Signed-off-by: John Crispin Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/wmi.c | 78 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 31 ++++++++++++++ 2 files changed, 109 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 5b35d06a0d81..2e8ce886bfe4 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2707,6 +2707,84 @@ ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id, return ret; } +int +ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, + u8 bss_color, u32 period, + bool enable) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct ath11k_base *ab = wmi->wmi_ab->ab; + struct wmi_obss_color_collision_cfg_params_cmd *cmd; + struct sk_buff *skb; + int ret, len; + + len = sizeof(*cmd); + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_obss_color_collision_cfg_params_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_OBSS_COLOR_COLLISION_DET_CONFIG) | + FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); + cmd->vdev_id = vdev_id; + cmd->evt_type = enable ? ATH11K_OBSS_COLOR_COLLISION_DETECTION : + ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE; + cmd->current_bss_color = bss_color; + cmd->detection_period_ms = period; + cmd->scan_period_ms = ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS; + cmd->free_slot_expiry_time_ms = 0; + cmd->flags = 0; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi_send_obss_color_collision_cfg id %d type %d bss_color %d detect_period %d scan_period %d\n", + cmd->vdev_id, cmd->evt_type, cmd->current_bss_color, + cmd->detection_period_ms, cmd->scan_period_ms); + + ret = ath11k_wmi_cmd_send(wmi, skb, + WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID); + if (ret) { + ath11k_warn(ab, "Failed to send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID"); + dev_kfree_skb(skb); + } + return ret; +} + +int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id, + bool enable) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct ath11k_base *ab = wmi->wmi_ab->ab; + struct wmi_bss_color_change_enable_params_cmd *cmd; + struct sk_buff *skb; + int ret, len; + + len = sizeof(*cmd); + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_bss_color_change_enable_params_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_BSS_COLOR_CHANGE_ENABLE) | + FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); + cmd->vdev_id = vdev_id; + cmd->enable = enable ? 1 : 0; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi_send_bss_color_change_enable id %d enable %d\n", + cmd->vdev_id, cmd->enable); + + ret = ath11k_wmi_cmd_send(wmi, skb, + WMI_BSS_COLOR_CHANGE_ENABLE_CMDID); + if (ret) { + ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID"); + dev_kfree_skb(skb); + } + return ret; +} + static void ath11k_fill_band_to_mac_param(struct ath11k_base *soc, struct wmi_host_pdev_band_to_mac *band_to_mac) diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 742fcd6e37a3..31e14ef0456e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -488,6 +488,7 @@ enum wmi_tlv_cmd_id { WMI_SAR_LIMITS_CMDID, WMI_OBSS_SCAN_ENABLE_CMDID = WMI_TLV_CMD(WMI_GRP_OBSS_OFL), WMI_OBSS_SCAN_DISABLE_CMDID, + WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID = WMI_TLV_CMD(WMI_GRP_LPI), WMI_LPI_START_SCAN_CMDID, WMI_LPI_STOP_SCAN_CMDID, @@ -4620,6 +4621,30 @@ struct wmi_obss_spatial_reuse_params_cmd { u32 vdev_id; } __packed; +#define ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200 +#define ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0 +#define ATH11K_OBSS_COLOR_COLLISION_DETECTION 1 + +#define ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS 10000 +#define ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS 5000 + +struct wmi_obss_color_collision_cfg_params_cmd { + u32 tlv_header; + u32 vdev_id; + u32 flags; + u32 evt_type; + u32 current_bss_color; + u32 detection_period_ms; + u32 scan_period_ms; + u32 free_slot_expiry_time_ms; +} __packed; + +struct wmi_bss_color_change_enable_params_cmd { + u32 tlv_header; + u32 vdev_id; + u32 enable; +} __packed; + struct target_resource_config { u32 num_vdevs; u32 num_peers; @@ -4814,4 +4839,10 @@ int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id); int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id); int ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id, struct ieee80211_he_obss_pd *he_obss_pd); +int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, + u8 bss_color, u32 period, + bool enable); +int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id, + bool enable); + #endif -- cgit From beb2f77297b0b7640e20ca2894104c87e21f5a47 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 16 Mar 2020 07:59:26 +0200 Subject: ath11k: add handling for BSS color This patch adds code to handle the BSS_CHANGED_BSS_COLOR flag. It will trigger the propagation of BSS color settings into the FW. Handling is slightly different between AP and STA interfaces. Signed-off-by: John Crispin Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/mac.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 61fd81d63efc..4e38913172ec 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1956,6 +1956,31 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, &info->he_obss_pd); + if (changed & BSS_CHANGED_HE_BSS_COLOR) { + if (vif->type == NL80211_IFTYPE_AP) { + ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( + ar, arvif->vdev_id, info->he_bss_color.color, + ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS, + !info->he_bss_color.disabled); + if (ret) + ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", + arvif->vdev_id, ret); + } else if (vif->type == NL80211_IFTYPE_STATION) { + ret = ath11k_wmi_send_bss_color_change_enable_cmd(ar, + arvif->vdev_id, + 1); + if (ret) + ath11k_warn(ar->ab, "failed to enable bss color change on vdev %i: %d\n", + arvif->vdev_id, ret); + ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( + ar, arvif->vdev_id, 0, + ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS, 1); + if (ret) + ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", + arvif->vdev_id, ret); + } + } + mutex_unlock(&ar->conf_mutex); } -- cgit From 678e8414bf4eadd58dff8845b632d1cb30abc7f6 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Mon, 16 Mar 2020 14:58:40 +0530 Subject: ath11k: Supporting RX ring backpressure HTT event and stats handling The Firmware sends HTT event to host whenever there is a backpressure on RX rings, Handling such event and dumping info on the console under the "ATH11K_DBG_DP_HTT" debug level. Fetching RX ring backpressure histogram from FW via htt_stats debugfs. #echo "24" > /sys/kernel/debug/ath11k/ipq8074/macX/htt_stats_type #cat /sys/kernel/debug/ath11k/ipq8074/macX/htt_stats Signed-off-by: Vikas Patel Signed-off-by: Sriram R Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/debug.h | 2 ++ drivers/net/wireless/ath/ath11k/debug_htt_stats.c | 44 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/debug_htt_stats.h | 28 +++++++++++++++ drivers/net/wireless/ath/ath11k/dp.h | 8 +++++ drivers/net/wireless/ath/ath11k/dp_rx.c | 26 ++++++++++++++ 5 files changed, 108 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h index 427d3ac5c909..97e7306c506d 100644 --- a/drivers/net/wireless/ath/ath11k/debug.h +++ b/drivers/net/wireless/ath/ath11k/debug.h @@ -53,6 +53,8 @@ enum ath11k_dbg_htt_ext_stats_type { ATH11K_DBG_HTT_EXT_STATS_TWT_SESSIONS = 20, ATH11K_DBG_HTT_EXT_STATS_REO_RESOURCE_STATS = 21, ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO = 22, + ATH11K_DBG_HTT_EXT_STATS_PDEV_OBSS_PD_STATS = 23, + ATH11K_DBG_HTT_EXT_STATS_RING_BACKPRESSURE_STATS = 24, /* keep this last */ ATH11K_DBG_HTT_NUM_EXT_STATS, diff --git a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c index f44dec839e70..5db0c27de475 100644 --- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c @@ -3854,6 +3854,47 @@ htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf, stats_req->buf_len = len; } +static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf, + u8 *data) +{ + struct debug_htt_stats_req *stats_req = + (struct debug_htt_stats_req *)data; + struct htt_ring_backpressure_stats_tlv *htt_stats_buf = + (struct htt_ring_backpressure_stats_tlv *)tag_buf; + int i; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + + len += HTT_DBG_OUT(buf + len, buf_len - len, "pdev_id = %u", + htt_stats_buf->pdev_id); + len += HTT_DBG_OUT(buf + len, buf_len - len, "current_head_idx = %u", + htt_stats_buf->current_head_idx); + len += HTT_DBG_OUT(buf + len, buf_len - len, "current_tail_idx = %u", + htt_stats_buf->current_tail_idx); + len += HTT_DBG_OUT(buf + len, buf_len - len, "num_htt_msgs_sent = %u", + htt_stats_buf->num_htt_msgs_sent); + len += HTT_DBG_OUT(buf + len, buf_len - len, + "backpressure_time_ms = %u", + htt_stats_buf->backpressure_time_ms); + + for (i = 0; i < 5; i++) + len += HTT_DBG_OUT(buf + len, buf_len - len, + "backpressure_hist_%u = %u", + i + 1, htt_stats_buf->backpressure_hist[i]); + + len += HTT_DBG_OUT(buf + len, buf_len - len, + "============================"); + + if (len >= buf_len) { + buf[buf_len - 1] = 0; + stats_req->buf_len = buf_len - 1; + } else { + buf[len] = 0; + stats_req->buf_len = len; + } +} + static inline void htt_htt_stats_debug_dump(const u32 *tag_buf, struct debug_htt_stats_req *stats_req) { @@ -4246,6 +4287,9 @@ static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab, case HTT_STATS_PDEV_OBSS_PD_TAG: htt_print_pdev_obss_pd_stats_tlv_v(tag_buf, stats_req); break; + case HTT_STATS_RING_BACKPRESSURE_STATS_TAG: + htt_print_backpressure_stats_tlv_v(tag_buf, user_data); + break; default: break; } diff --git a/drivers/net/wireless/ath/ath11k/debug_htt_stats.h b/drivers/net/wireless/ath/ath11k/debug_htt_stats.h index 4bdb62dd7b8d..23a6baa9e95a 100644 --- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.h +++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.h @@ -100,6 +100,8 @@ enum htt_tlv_tag_t { HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG = 86, HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG = 87, HTT_STATS_PDEV_OBSS_PD_TAG = 88, + HTT_STATS_HW_WAR_TAG = 89, + HTT_STATS_RING_BACKPRESSURE_STATS_TAG = 90, HTT_STATS_MAX_TAG, }; @@ -1659,4 +1661,30 @@ struct htt_pdev_obss_pd_stats_tlv { }; void ath11k_debug_htt_stats_init(struct ath11k *ar); + +struct htt_ring_backpressure_stats_tlv { + u32 pdev_id; + u32 current_head_idx; + u32 current_tail_idx; + u32 num_htt_msgs_sent; + /* Time in milliseconds for which the ring has been in + * its current backpressure condition + */ + u32 backpressure_time_ms; + /* backpressure_hist - histogram showing how many times + * different degrees of backpressure duration occurred: + * Index 0 indicates the number of times ring was + * continuously in backpressure state for 100 - 200ms. + * Index 1 indicates the number of times ring was + * continuously in backpressure state for 200 - 300ms. + * Index 2 indicates the number of times ring was + * continuously in backpressure state for 300 - 400ms. + * Index 3 indicates the number of times ring was + * continuously in backpressure state for 400 - 500ms. + * Index 4 indicates the number of times ring was + * continuously in backpressure state beyond 500ms. + */ + u32 backpressure_hist[5]; +}; + #endif diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index ed11728478e9..f504077086da 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -936,6 +936,7 @@ enum htt_t2h_msg_type { HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x1f, HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d, HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c, + HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24, }; #define HTT_TARGET_VERSION_MAJOR 3 @@ -984,6 +985,13 @@ struct htt_resp_msg { }; } __packed; +#define HTT_BACKPRESSURE_EVENT_PDEV_ID_M GENMASK(15, 8) +#define HTT_BACKPRESSURE_EVENT_RING_TYPE_M GENMASK(23, 16) +#define HTT_BACKPRESSURE_EVENT_RING_ID_M GENMASK(31, 24) + +#define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0) +#define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16) + /* ppdu stats * * @details diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 320fec2aede3..61ff9a9a32cf 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -1499,6 +1499,29 @@ static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb) trace_ath11k_htt_pktlog(ar, data->payload, hdr->size); } +static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab, + struct sk_buff *skb) +{ + u32 *data = (u32 *)skb->data; + u8 pdev_id, ring_type, ring_id; + u16 hp, tp; + u32 backpressure_time; + + pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data); + ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data); + ring_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_ID_M, *data); + ++data; + + hp = FIELD_GET(HTT_BACKPRESSURE_EVENT_HP_M, *data); + tp = FIELD_GET(HTT_BACKPRESSURE_EVENT_TP_M, *data); + ++data; + + backpressure_time = *data; + + ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n", + pdev_id, ring_type, ring_id, hp, tp, backpressure_time); +} + void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, struct sk_buff *skb) { @@ -1548,6 +1571,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, case HTT_T2H_MSG_TYPE_PKTLOG: ath11k_htt_pktlog(ab, skb); break; + case HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND: + ath11k_htt_backpressure_event_handler(ab, skb); + break; default: ath11k_warn(ab, "htt event %d not handled\n", type); break; -- cgit From de06b2f75190e691467e89d191c7752dfa340a3a Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Tue, 17 Mar 2020 09:48:18 +0530 Subject: ath11k: fill channel info from rx channel Fill the channel information from rx channel for the packet which has invalid channel info from meta data. Signed-off-by: Venkateswara Naralasetty Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/dp_rx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 61ff9a9a32cf..c4affc45c2f6 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -2227,9 +2227,13 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, } else if (channel_num >= 36 && channel_num <= 173) { rx_status->band = NL80211_BAND_5GHZ; } else { - ath11k_warn(ar->ab, "Unsupported Channel info received %d\n", - channel_num); - return; + spin_lock_bh(&ar->data_lock); + rx_status->band = ar->rx_channel->band; + channel_num = + ieee80211_frequency_to_channel(ar->rx_channel->center_freq); + spin_unlock_bh(&ar->data_lock); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "rx_desc: ", + rx_desc, sizeof(struct hal_rx_desc)); } rx_status->freq = ieee80211_channel_to_frequency(channel_num, -- cgit From 5118935b1bc28d0bce9427e584e11e905e68ee9a Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Tue, 17 Mar 2020 15:02:14 +0530 Subject: ath11k: dump SRNG stats during FW assert Dumping the SRNG stats during FW assert, this would help in debugging ring stuck issues. Co-developed-by: Karthikeyan Periyasamy Signed-off-by: Karthikeyan Periyasamy Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/ahb.c | 6 ++++ drivers/net/wireless/ath/ath11k/ce.h | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/hal.c | 66 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/hal.h | 9 +++++ drivers/net/wireless/ath/ath11k/qmi.c | 1 + 6 files changed, 82 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index e7e3e64c07aa..eab7ed6b359e 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -681,6 +681,9 @@ static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg) { struct ath11k_ce_pipe *ce_pipe = arg; + /* last interrupt received for this CE */ + ce_pipe->timestamp = jiffies; + ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num); tasklet_schedule(&ce_pipe->intr_tq); @@ -712,6 +715,9 @@ static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg) { struct ath11k_ext_irq_grp *irq_grp = arg; + /* last interrupt received for this group */ + irq_grp->timestamp = jiffies; + ath11k_ahb_ext_grp_disable(irq_grp); napi_schedule(&irq_grp->napi); diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h index e355dfda48bf..688f357e6eaf 100644 --- a/drivers/net/wireless/ath/ath11k/ce.h +++ b/drivers/net/wireless/ath/ath11k/ce.h @@ -161,6 +161,7 @@ struct ath11k_ce_pipe { struct ath11k_ce_ring *src_ring; struct ath11k_ce_ring *dest_ring; struct ath11k_ce_ring *status_ring; + u64 timestamp; }; struct ath11k_ce { diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index af04e1281c3a..83f1f770e920 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -110,6 +110,7 @@ struct ath11k_ext_irq_grp { u32 irqs[ATH11K_EXT_IRQ_NUM_MAX]; u32 num_irq; u32 grp_id; + u64 timestamp; struct napi_struct napi; struct net_device napi_ndev; /* Queue of pending packets, not expected to be accessed concurrently diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index b58ac11c2747..9e40c4bdd674 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -877,23 +877,32 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng) /* For LMAC rings, ring pointer updates are done through FW and * hence written to a shared memory location that is read by FW */ - if (srng->ring_dir == HAL_SRNG_DIR_SRC) + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; *srng->u.src_ring.hp_addr = srng->u.src_ring.hp; - else + } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; + } } else { if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + srng->u.src_ring.last_tp = + *(volatile u32 *)srng->u.src_ring.tp_addr; ath11k_ahb_write32(ab, (unsigned long)srng->u.src_ring.hp_addr - (unsigned long)ab->mem, srng->u.src_ring.hp); } else { + srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; ath11k_ahb_write32(ab, (unsigned long)srng->u.dst_ring.tp_addr - (unsigned long)ab->mem, srng->u.dst_ring.tp); } } + + srng->timestamp = jiffies; } void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, @@ -1017,6 +1026,7 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type, params->intr_batch_cntr_thres_entries; srng->intr_timer_thres_us = params->intr_timer_thres_us; srng->flags = params->flags; + srng->initialized = 1; spin_lock_init(&srng->lock); for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { @@ -1122,3 +1132,55 @@ void ath11k_hal_srng_deinit(struct ath11k_base *ab) ath11k_hal_free_cont_rdp(ab); ath11k_hal_free_cont_wrp(ab); } + +void ath11k_hal_dump_srng_stats(struct ath11k_base *ab) +{ + struct hal_srng *srng; + struct ath11k_ext_irq_grp *irq_grp; + struct ath11k_ce_pipe *ce_pipe; + int i; + + ath11k_err(ab, "Last interrupt received for each CE:\n"); + for (i = 0; i < CE_COUNT; i++) { + ce_pipe = &ab->ce.ce_pipe[i]; + + if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) + continue; + + ath11k_err(ab, "CE_id %d pipe_num %d %ums before\n", + i, ce_pipe->pipe_num, + jiffies_to_msecs(jiffies - ce_pipe->timestamp)); + } + + ath11k_err(ab, "\nLast interrupt received for each group:\n"); + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + irq_grp = &ab->ext_irq_grp[i]; + ath11k_err(ab, "group_id %d %ums before\n", + irq_grp->grp_id, + jiffies_to_msecs(jiffies - irq_grp->timestamp)); + } + + for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) { + srng = &ab->hal.srng_list[i]; + + if (!srng->initialized) + continue; + + if (srng->ring_dir == HAL_SRNG_DIR_SRC) + ath11k_err(ab, + "src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n", + srng->ring_id, srng->u.src_ring.hp, + srng->u.src_ring.reap_hp, + *srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp, + srng->u.src_ring.last_tp, + jiffies_to_msecs(jiffies - srng->timestamp)); + else if (srng->ring_dir == HAL_SRNG_DIR_DST) + ath11k_err(ab, + "dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n", + srng->ring_id, srng->u.dst_ring.tp, + *srng->u.dst_ring.hp_addr, + srng->u.dst_ring.cached_hp, + srng->u.dst_ring.last_hp, + jiffies_to_msecs(jiffies - srng->timestamp)); + } +} diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h index 4cfd93494c03..36df37449e30 100644 --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -529,6 +529,8 @@ struct hal_srng { */ u32 hwreg_base[HAL_SRNG_NUM_REG_GRP]; + u64 timestamp; + /* Source or Destination ring */ enum hal_srng_dir ring_dir; @@ -554,6 +556,9 @@ struct hal_srng { /* max transfer size */ u16 max_buffer_length; + + /* head pointer at access end */ + u32 last_hp; } dst_ring; struct { @@ -577,6 +582,9 @@ struct hal_srng { /* Low threshold - in number of ring entries */ u32 low_threshold; + + /* tail pointer at access end */ + u32 last_tp; } src_ring; } u; }; @@ -893,5 +901,6 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type, struct hal_srng_params *params); int ath11k_hal_srng_init(struct ath11k_base *ath11k); void ath11k_hal_srng_deinit(struct ath11k_base *ath11k); +void ath11k_hal_dump_srng_stats(struct ath11k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 2377895a58ec..c00a99ad8dbc 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2365,6 +2365,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) break; case ATH11K_QMI_EVENT_FW_READY: if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { + ath11k_hal_dump_srng_stats(ab); queue_work(ab->workqueue, &ab->restart_work); break; } -- cgit From fe0ebb51604f190b13b20a5f6c2821772c0cfc22 Mon Sep 17 00:00:00 2001 From: Pravas Kumar Panda Date: Tue, 17 Mar 2020 17:29:29 +0530 Subject: ath11k: Adding proper validation before accessing tx_stats Before dumping tx_stats proper validation was not been taken care of. Due to which we were encountering null pointer dereference(kernel panic). This scenario will arise when a station is getting disconnected and we are changing the STA state by ath11k_mac_op_sta_state and assigning tx_stats as NULL and after this the mac80211 will destroy the debugfs entry from where we are trying to read the stats. If anyone tries to dump tx_stats for that STA in between setting tx_stats to NULL and debugfs file removal without checking the NULL value it will run into a NULL pointer exception. Proceeding with the analysis of "ARM Kernel Panic". The APSS crash happened due to OOPS on CPU 3. Crash Signature : Unable to handle kernel NULL pointer dereference at virtual address 00000360 During the crash, PC points to "ath11k_debug_htt_stats_init+0x16ac/0x1acc [ath11k]" LR points to "ath11k_debug_htt_stats_init+0x1688/0x1acc [ath11k]". The Backtrace obtained is as follows: [] ath11k_debug_htt_stats_init+0x16ac/0x1acc [ath11k] [] do_loop_readv_writev+0x60/0xa4 [] do_readv_writev+0xd8/0x19c [] vfs_readv+0x34/0x48 [] default_file_splice_read+0x1a8/0x2e4 [] do_splice_to+0x78/0x98 [] splice_direct_to_actor+0xb0/0x1a4 [] do_splice_direct+0x84/0xa8 [] do_sendfile+0x160/0x2a4 [] SyS_sendfile64+0xb4/0xc8 Signed-off-by: Pravas Kumar Panda Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/debugfs_sta.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c index 872f3ef4d2a8..389dac219238 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c @@ -219,6 +219,9 @@ static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file, const int size = 2 * 4096; char *buf; + if (!arsta->tx_stats) + return -ENOENT; + buf = kzalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; -- cgit From 26c79927f12356ef26a6c3c061e2d40e943f254a Mon Sep 17 00:00:00 2001 From: Sriram R Date: Tue, 17 Mar 2020 17:07:02 +0530 Subject: ath11k: Configure hash based reo destination ring selection Current implementation of pdev based reo destination ring selection is replaced by hash based ring selection so as to ensure all the available rings are utilized for better performance. The 4 reo destination rings are selected by the HW based on the hash value computed from the received packet based on the 5 tuple {ip src/ip dst/src port/dst port/protocol}. Out of the 32 hash values used by the hw, the driver assigns 8 values per reo destination ring to each of the 4 reo destination rings. Signed-off-by: Sriram R Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/dp.c | 17 +++++++++++++++- drivers/net/wireless/ath/ath11k/dp.h | 2 +- drivers/net/wireless/ath/ath11k/hal.h | 12 ++++++++++- drivers/net/wireless/ath/ath11k/hal_rx.c | 15 +++++++++++++- drivers/net/wireless/ath/ath11k/mac.c | 4 ++++ drivers/net/wireless/ath/ath11k/wmi.c | 35 ++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 14 ++++++++++++- 7 files changed, 94 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index a1371ab773ab..b8875209f826 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -218,6 +218,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) struct ath11k_dp *dp = &ab->dp; struct hal_srng *srng; int i, ret; + u32 ring_hash_map; ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring, HAL_SW2WBM_RELEASE, 0, 0, @@ -305,7 +306,21 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) goto err; } - ath11k_hal_reo_hw_setup(ab); + /* When hash based routing of rx packet is enabled, 32 entries to map + * the hash values to the ring will be configured. Each hash entry uses + * three bits to map to a particular ring. The ring mapping will be + * 0:TCL, 1:SW1, 2:SW2, 3:SW3, 4:SW4, 5:Release, 6:FW and 7:Not used. + */ + ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | + HAL_HASH_ROUTING_RING_SW2 << 3 | + HAL_HASH_ROUTING_RING_SW3 << 6 | + HAL_HASH_ROUTING_RING_SW4 << 9 | + HAL_HASH_ROUTING_RING_SW1 << 12 | + HAL_HASH_ROUTING_RING_SW2 << 15 | + HAL_HASH_ROUTING_RING_SW3 << 18 | + HAL_HASH_ROUTING_RING_SW4 << 21; + + ath11k_hal_reo_hw_setup(ab, ring_hash_map); return 0; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index f504077086da..3edfe92279f8 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -160,7 +160,7 @@ struct ath11k_pdev_dp { #define DP_AVG_MPDUS_PER_TID_MAX 128 #define DP_AVG_MSDUS_PER_MPDU 4 -#define DP_RX_HASH_ENABLE 0 /* Disable hash based Rx steering */ +#define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */ #define DP_BA_WIN_SZ_MAX 256 diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h index 36df37449e30..7722822a0456 100644 --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -96,6 +96,8 @@ struct ath11k_base; /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 +#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 +#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 #define HAL_REO1_RING_BASE_LSB 0x0000029c @@ -725,6 +727,14 @@ enum hal_ce_desc { HAL_CE_DESC_DST_STATUS, }; +#define HAL_HASH_ROUTING_RING_TCL 0 +#define HAL_HASH_ROUTING_RING_SW1 1 +#define HAL_HASH_ROUTING_RING_SW2 2 +#define HAL_HASH_ROUTING_RING_SW3 3 +#define HAL_HASH_ROUTING_RING_SW4 4 +#define HAL_HASH_ROUTING_RING_REL 5 +#define HAL_HASH_ROUTING_RING_FW 6 + struct hal_reo_status_header { u16 cmd_num; enum hal_reo_cmd_status cmd_status; @@ -858,7 +868,7 @@ void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, u32 start_seq, enum hal_pn_type type); void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, struct hal_srng *srng); -void ath11k_hal_reo_hw_setup(struct ath11k_base *ab); +void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map); void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, struct hal_wbm_idle_scatter_list *sbuf, u32 nsbufs, u32 tot_link_desc, diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 3a666565cd1e..f277c9434a25 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -799,7 +799,7 @@ void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, } } -void ath11k_hal_reo_hw_setup(struct ath11k_base *ab) +void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map) { u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; @@ -821,6 +821,19 @@ void ath11k_hal_reo_hw_setup(struct ath11k_base *ab) HAL_DEFAULT_REO_TIMEOUT_USEC); ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3, HAL_DEFAULT_REO_TIMEOUT_USEC); + + ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, + FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, + ring_hash_map)); + ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, + FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, + ring_hash_map)); + ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, + FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, + ring_hash_map)); + ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, + FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, + ring_hash_map)); } static enum hal_rx_mon_status diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 4e38913172ec..6a0d0f654623 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -3974,6 +3974,9 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) goto err; } + /* Configure the hash seed for hash based reo dest ring selection */ + ath11k_wmi_pdev_lro_cfg(ar, ar->pdev->pdev_id); + mutex_unlock(&ar->conf_mutex); rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], @@ -5791,6 +5794,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW); ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER); ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(ar->hw, USES_RSS); } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 2e8ce886bfe4..e7ce36966d6a 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2995,6 +2995,41 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, return ret; } +int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, + int pdev_id) +{ + struct ath11k_wmi_pdev_lro_config_cmd *cmd; + struct sk_buff *skb; + int ret; + + skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct ath11k_wmi_pdev_lro_config_cmd *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_LRO_INFO_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + + get_random_bytes(cmd->th_4, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE); + get_random_bytes(cmd->th_6, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE); + + cmd->pdev_id = pdev_id; + + ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_LRO_CONFIG_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "failed to send lro cfg req wmi cmd\n"); + goto err; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "WMI lro cfg cmd pdev_id 0x%x\n", pdev_id); + return 0; +err: + dev_kfree_skb(skb); + return ret; +} + int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab) { unsigned long time_left; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 31e14ef0456e..510f9c6bc1d7 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -4645,6 +4645,18 @@ struct wmi_bss_color_change_enable_params_cmd { u32 enable; } __packed; +#define ATH11K_IPV4_TH_SEED_SIZE 5 +#define ATH11K_IPV6_TH_SEED_SIZE 11 + +struct ath11k_wmi_pdev_lro_config_cmd { + u32 tlv_header; + u32 lro_enable; + u32 res; + u32 th_4[ATH11K_IPV4_TH_SEED_SIZE]; + u32 th_6[ATH11K_IPV6_TH_SEED_SIZE]; + u32 pdev_id; +} __packed; + struct target_resource_config { u32 num_vdevs; u32 num_peers; @@ -4844,5 +4856,5 @@ int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, bool enable); int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id, bool enable); - +int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id); #endif -- cgit From acc79d981c1462b22a7a2cb0d39725f8c01fc425 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Tue, 17 Mar 2020 16:52:38 +0200 Subject: ath11k: Perform per-msdu rx processing As Hash based reo destination selection is configured, the decapped packets reach different reo destintion rings based on the destintaion ring selected for the computed hash (based on the 5-tuple {ip src/ip dst/src port/dst port/protocol}) by hw and as configured by driver. Hence the current implementation of amsdu list based processing after all the subframes of amsdu are received (since all msdu's for a pdev are received in same reo dest ring), is not applicable here and hence is replaced with per msdu based handling as these subframes can be received in different reo dest rings. Also, as some of the rx descriptor fields might be valid only for the first msdu (for ex. received 80211 header, encryption type, etc), it might not be useful now as we cannot sync between different subframes received in different rings. Hence do not rely on those fields and replace them with fieds valid only on per msdu descriptors. Also cache other details such as encryption type for a peer so that it can be reused when a packet is received from it. Co-developed-by: Tamizh Chelvam Raja Signed-off-by: Tamizh Chelvam Raja Signed-off-by: Sriram R Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath11k/ahb.c | 5 - drivers/net/wireless/ath/ath11k/core.h | 5 +- drivers/net/wireless/ath/ath11k/dp.c | 18 +- drivers/net/wireless/ath/ath11k/dp.h | 2 +- drivers/net/wireless/ath/ath11k/dp_rx.c | 513 ++++++++++++++------------------ drivers/net/wireless/ath/ath11k/dp_rx.h | 4 +- drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +- drivers/net/wireless/ath/ath11k/mac.c | 8 +- drivers/net/wireless/ath/ath11k/mac.h | 1 + drivers/net/wireless/ath/ath11k/peer.c | 3 + drivers/net/wireless/ath/ath11k/peer.h | 2 + 11 files changed, 245 insertions(+), 318 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index eab7ed6b359e..59342d2797ca 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -458,7 +458,6 @@ static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) { - struct sk_buff *skb; int i; for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { @@ -468,9 +467,6 @@ static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) napi_synchronize(&irq_grp->napi); napi_disable(&irq_grp->napi); - - while ((skb = __skb_dequeue(&irq_grp->pending_q))) - dev_kfree_skb_any(skb); } } @@ -740,7 +736,6 @@ static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab) init_dummy_netdev(&irq_grp->napi_ndev); netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT); - __skb_queue_head_init(&irq_grp->pending_q); for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { if (ath11k_tx_ring_mask[i] & BIT(j)) { diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 83f1f770e920..6e7b8ecd09a6 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -78,6 +78,7 @@ struct ath11k_skb_rxcb { u8 mac_id; u8 unmapped; u8 is_frag; + u8 tid; }; enum ath11k_hw_rev { @@ -113,10 +114,6 @@ struct ath11k_ext_irq_grp { u64 timestamp; struct napi_struct napi; struct net_device napi_ndev; - /* Queue of pending packets, not expected to be accessed concurrently - * to avoid locking overhead. - */ - struct sk_buff_head pending_q; }; #define HEHANDLE_CAP_PHYINFO_SIZE 3 diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index b8875209f826..50350f77b309 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -650,17 +650,13 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, } if (ath11k_rx_ring_mask[grp_id]) { - for (i = 0; i < ab->num_radios; i++) { - if (ath11k_rx_ring_mask[grp_id] & BIT(i)) { - work_done = ath11k_dp_process_rx(ab, i, napi, - &irq_grp->pending_q, - budget); - budget -= work_done; - tot_work_done += work_done; - } - if (budget <= 0) - goto done; - } + i = fls(ath11k_rx_ring_mask[grp_id]) - 1; + work_done = ath11k_dp_process_rx(ab, i, napi, + budget); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; } if (rx_mon_status_ring_mask[grp_id]) { diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 3edfe92279f8..551f9c9fb847 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -140,7 +140,6 @@ struct ath11k_pdev_dp { u32 mac_id; atomic_t num_tx_pending; wait_queue_head_t tx_empty_waitq; - struct dp_srng reo_dst_ring; struct dp_rxdma_ring rx_refill_buf_ring; struct dp_srng rxdma_err_dst_ring; struct dp_srng rxdma_mon_dst_ring; @@ -218,6 +217,7 @@ struct ath11k_dp { struct dp_srng reo_except_ring; struct dp_srng reo_cmd_ring; struct dp_srng reo_status_ring; + struct dp_srng reo_dst_ring[DP_REO_DST_RING_MAX]; struct dp_tx_ring tx_ring[DP_TCL_NUM_RING_MAX]; struct hal_wbm_idle_scatter_list scatter_list[DP_IDLE_SCATTER_BUFS_MAX]; struct list_head reo_cmd_list; diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index c4affc45c2f6..f74a0e74bf3e 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include #include "core.h" #include "debug.h" @@ -37,6 +39,12 @@ static u8 ath11k_dp_rx_h_msdu_start_decap_type(struct hal_rx_desc *desc) __le32_to_cpu(desc->msdu_start.info2)); } +static u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT, + __le32_to_cpu(desc->msdu_start.info2)); +} + static bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct hal_rx_desc *desc) { return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID, @@ -77,12 +85,6 @@ static bool ath11k_dp_rx_h_attn_msdu_done(struct hal_rx_desc *desc) __le32_to_cpu(desc->attention.info2)); } -static bool ath11k_dp_rx_h_attn_first_mpdu(struct hal_rx_desc *desc) -{ - return !!FIELD_GET(RX_ATTENTION_INFO1_FIRST_MPDU, - __le32_to_cpu(desc->attention.info1)); -} - static bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct hal_rx_desc *desc) { return !!FIELD_GET(RX_ATTENTION_INFO1_TCP_UDP_CKSUM_FAIL, @@ -450,32 +452,25 @@ static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar) void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab) { - struct ath11k_pdev_dp *dp; - struct ath11k *ar; + struct ath11k_dp *dp = &ab->dp; int i; - for (i = 0; i < ab->num_radios; i++) { - ar = ab->pdevs[i].ar; - dp = &ar->dp; - ath11k_dp_srng_cleanup(ab, &dp->reo_dst_ring); - } + for (i = 0; i < DP_REO_DST_RING_MAX; i++) + ath11k_dp_srng_cleanup(ab, &dp->reo_dst_ring[i]); } int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab) { - struct ath11k *ar; - struct ath11k_pdev_dp *dp; + struct ath11k_dp *dp = &ab->dp; int ret; int i; - for (i = 0; i < ab->num_radios; i++) { - ar = ab->pdevs[i].ar; - dp = &ar->dp; - ret = ath11k_dp_srng_setup(ab, &dp->reo_dst_ring, HAL_REO_DST, - dp->mac_id, dp->mac_id, + for (i = 0; i < DP_REO_DST_RING_MAX; i++) { + ret = ath11k_dp_srng_setup(ab, &dp->reo_dst_ring[i], + HAL_REO_DST, i, 0, DP_REO_DST_RING_SIZE); if (ret) { - ath11k_warn(ar->ab, "failed to setup reo_dst_ring\n"); + ath11k_warn(ab, "failed to setup reo_dst_ring\n"); goto err_reo_cleanup; } } @@ -1685,90 +1680,6 @@ static struct sk_buff *ath11k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_ return NULL; } -static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar, - struct sk_buff_head *msdu_list, - struct sk_buff_head *amsdu_list) -{ - struct sk_buff *msdu = skb_peek(msdu_list); - struct sk_buff *last_buf; - struct ath11k_skb_rxcb *rxcb; - struct ieee80211_hdr *hdr; - struct hal_rx_desc *rx_desc, *lrx_desc; - u16 msdu_len; - u8 l3_pad_bytes; - u8 *hdr_status; - int ret; - - if (!msdu) - return -ENOENT; - - rx_desc = (struct hal_rx_desc *)msdu->data; - hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc); - hdr = (struct ieee80211_hdr *)hdr_status; - /* Process only data frames */ - if (!ieee80211_is_data(hdr->frame_control)) { - __skb_unlink(msdu, msdu_list); - dev_kfree_skb_any(msdu); - return -EINVAL; - } - - do { - __skb_unlink(msdu, msdu_list); - last_buf = ath11k_dp_rx_get_msdu_last_buf(msdu_list, msdu); - if (!last_buf) { - ath11k_warn(ar->ab, - "No valid Rx buffer to access Atten/MSDU_END/MPDU_END tlvs\n"); - ret = -EIO; - goto free_out; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - lrx_desc = (struct hal_rx_desc *)last_buf->data; - - if (!ath11k_dp_rx_h_attn_msdu_done(lrx_desc)) { - ath11k_warn(ar->ab, "msdu_done bit in attention is not set\n"); - ret = -EIO; - goto free_out; - } - - rxcb = ATH11K_SKB_RXCB(msdu); - rxcb->rx_desc = rx_desc; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); - l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc); - - if (rxcb->is_frag) { - skb_pull(msdu, HAL_RX_DESC_SIZE); - } else if (!rxcb->is_continuation) { - skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes); - } else { - ret = ath11k_dp_rx_msdu_coalesce(ar, msdu_list, - msdu, last_buf, - l3_pad_bytes, msdu_len); - if (ret) { - ath11k_warn(ar->ab, - "failed to coalesce msdu rx buffer%d\n", ret); - goto free_out; - } - } - __skb_queue_tail(amsdu_list, msdu); - - /* Should we also consider msdu_cnt from mpdu_meta while - * preparing amsdu list? - */ - if (rxcb->is_last_msdu) - break; - } while ((msdu = skb_peek(msdu_list)) != NULL); - - return 0; - -free_out: - dev_kfree_skb_any(msdu); - __skb_queue_purge(amsdu_list); - - return ret; -} - static void ath11k_dp_rx_h_csum_offload(struct sk_buff *msdu) { struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); @@ -1867,20 +1778,53 @@ static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, enum hal_encrypt_type enctype, struct ieee80211_rx_status *status) { + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; size_t hdr_len; u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; + u8 *qos; - /* pull decapped header and copy SA & DA */ + /* copy SA & DA and pull decapped header */ hdr = (struct ieee80211_hdr *)msdu->data; + hdr_len = ieee80211_hdrlen(hdr->frame_control); ether_addr_copy(da, ieee80211_get_DA(hdr)); ether_addr_copy(sa, ieee80211_get_SA(hdr)); skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control)); - /* push original 802.11 header */ - hdr = (struct ieee80211_hdr *)first_hdr; - hdr_len = ieee80211_hdrlen(hdr->frame_control); + if (rxcb->is_first_msdu) { + /* original 802.11 header is valid for the first msdu + * hence we can reuse the same header + */ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + + /* Each A-MSDU subframe will be reported as a separate MSDU, + * so strip the A-MSDU bit from QoS Ctl. + */ + if (ieee80211_is_data_qos(hdr->frame_control)) { + qos = ieee80211_get_qos_ctl(hdr); + qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + } + } else { + /* Rebuild qos header if this is a middle/last msdu */ + hdr->frame_control |= __cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + + /* Reset the order bit as the HT_Control header is stripped */ + hdr->frame_control &= ~(__cpu_to_le16(IEEE80211_FCTL_ORDER)); + + qos_ctl = rxcb->tid; + + if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(rxcb->rx_desc)) + qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; + + /* TODO Add other QoS ctl fields when required */ + + /* copy decap header before overwriting for reuse below */ + memcpy(decap_hdr, (uint8_t *)hdr, hdr_len); + } if (!(status->flag & RX_FLAG_IV_STRIPPED)) { memcpy(skb_push(msdu, @@ -1889,6 +1833,14 @@ static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, ath11k_dp_rx_crypto_param_len(ar, enctype)); } + if (!rxcb->is_first_msdu) { + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_LEN); + memcpy(skb_push(msdu, hdr_len), decap_hdr, hdr_len); + return; + } + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); /* original 802.11 header has a different DA and in @@ -2055,6 +2007,7 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, decrypted); break; case DP_RX_DECAP_TYPE_ETHERNET2_DIX: + /* TODO undecap support for middle/last msdu's of amsdu */ ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr, enctype, status); break; @@ -2065,45 +2018,41 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, } static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, - struct sk_buff_head *amsdu_list, + struct sk_buff *msdu, struct hal_rx_desc *rx_desc, struct ieee80211_rx_status *rx_status) { - struct ieee80211_hdr *hdr; + bool fill_crypto_hdr, mcast; enum hal_encrypt_type enctype; - struct sk_buff *last_msdu; - struct sk_buff *msdu; - struct ath11k_skb_rxcb *last_rxcb; - bool is_decrypted = false, fill_crypto_hdr; + bool is_decrypted = false; + struct ieee80211_hdr *hdr; + struct ath11k_peer *peer; u32 err_bitmap; - u8 *qos; - - if (skb_queue_empty(amsdu_list)) - return; - - hdr = (struct ieee80211_hdr *)ath11k_dp_rx_h_80211_hdr(rx_desc); - /* Each A-MSDU subframe will use the original header as the base and be - * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. - */ - if (ieee80211_is_data_qos(hdr->frame_control)) { - qos = ieee80211_get_qos_ctl(hdr); - qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - } + hdr = (struct ieee80211_hdr *)msdu->data; /* PN for multicast packets will be checked in mac80211 */ - fill_crypto_hdr = is_multicast_ether_addr(hdr->addr1); + + mcast = is_multicast_ether_addr(hdr->addr1); + fill_crypto_hdr = mcast; is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); - enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); - /* Some attention flags are valid only in the last MSDU. */ - last_msdu = skb_peek_tail(amsdu_list); - last_rxcb = ATH11K_SKB_RXCB(last_msdu); + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2); + if (peer) { + if (mcast) + enctype = peer->sec_type_grp; + else + enctype = peer->sec_type; + } else { + enctype = HAL_ENCRYPT_TYPE_OPEN; + } + spin_unlock_bh(&ar->ab->base_lock); - err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(last_rxcb->rx_desc); + err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc); - /* Clear per-MPDU flags while leaving per-PPDU flags intact. */ + /* Clear per-MPDU flags while leaving per-PPDU flags intact */ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | RX_FLAG_MMIC_ERROR | RX_FLAG_DECRYPTED | @@ -2112,7 +2061,6 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, if (err_bitmap & DP_RX_MPDU_ERR_FCS) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - if (err_bitmap & DP_RX_MPDU_ERR_TKIP_MIC) rx_status->flag |= RX_FLAG_MMIC_ERROR; @@ -2127,17 +2075,15 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, RX_FLAG_PN_VALIDATED; } - skb_queue_walk(amsdu_list, msdu) { - ath11k_dp_rx_h_csum_offload(msdu); - ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, - enctype, rx_status, is_decrypted); + ath11k_dp_rx_h_csum_offload(msdu); + ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, + enctype, rx_status, is_decrypted); - if (!is_decrypted || fill_crypto_hdr) - continue; + if (!is_decrypted || fill_crypto_hdr) + return; - hdr = (void *)msdu->data; - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); - } + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); } static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc, @@ -2242,29 +2188,6 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, ath11k_dp_rx_h_rate(ar, rx_desc, rx_status); } -static void ath11k_dp_rx_process_amsdu(struct ath11k *ar, - struct sk_buff_head *amsdu_list, - struct ieee80211_rx_status *rx_status) -{ - struct sk_buff *first; - struct ath11k_skb_rxcb *rxcb; - struct hal_rx_desc *rx_desc; - bool first_mpdu; - - if (skb_queue_empty(amsdu_list)) - return; - - first = skb_peek(amsdu_list); - rxcb = ATH11K_SKB_RXCB(first); - rx_desc = rxcb->rx_desc; - - first_mpdu = ath11k_dp_rx_h_attn_first_mpdu(rx_desc); - if (first_mpdu) - ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status); - - ath11k_dp_rx_h_mpdu(ar, amsdu_list, rx_desc, rx_status); -} - static char *ath11k_print_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size) { @@ -2331,55 +2254,115 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap ieee80211_rx_napi(ar->hw, NULL, msdu, napi); } -static void ath11k_dp_rx_pre_deliver_amsdu(struct ath11k *ar, - struct sk_buff_head *amsdu_list, - struct ieee80211_rx_status *rxs) +static int ath11k_dp_rx_process_msdu(struct ath11k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) { - struct sk_buff *msdu; - struct sk_buff *first_subframe; + struct hal_rx_desc *rx_desc, *lrx_desc; + struct ieee80211_rx_status rx_status = {0}; struct ieee80211_rx_status *status; + struct ath11k_skb_rxcb *rxcb; + struct ieee80211_hdr *hdr; + struct sk_buff *last_buf; + u8 l3_pad_bytes; + u16 msdu_len; + int ret; - first_subframe = skb_peek(amsdu_list); + last_buf = ath11k_dp_rx_get_msdu_last_buf(msdu_list, msdu); + if (!last_buf) { + ath11k_warn(ar->ab, + "No valid Rx buffer to access Atten/MSDU_END/MPDU_END tlvs\n"); + ret = -EIO; + goto free_out; + } - skb_queue_walk(amsdu_list, msdu) { - /* Setup per-MSDU flags */ - if (skb_queue_empty(amsdu_list)) - rxs->flag &= ~RX_FLAG_AMSDU_MORE; - else - rxs->flag |= RX_FLAG_AMSDU_MORE; + rx_desc = (struct hal_rx_desc *)msdu->data; + lrx_desc = (struct hal_rx_desc *)last_buf->data; + if (!ath11k_dp_rx_h_attn_msdu_done(lrx_desc)) { + ath11k_warn(ar->ab, "msdu_done bit in attention is not set\n"); + ret = -EIO; + goto free_out; + } - if (msdu == first_subframe) { - first_subframe = NULL; - rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; - } else { - rxs->flag |= RX_FLAG_ALLOW_SAME_PN; - } - rxs->flag |= RX_FLAG_SKIP_MONITOR; + rxcb = ATH11K_SKB_RXCB(msdu); + rxcb->rx_desc = rx_desc; + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); + l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc); - status = IEEE80211_SKB_RXCB(msdu); - *status = *rxs; + if (rxcb->is_frag) { + skb_pull(msdu, HAL_RX_DESC_SIZE); + } else if (!rxcb->is_continuation) { + if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) { + ret = -EINVAL; + ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len); + goto free_out; + } + skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len); + skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes); + } else { + ret = ath11k_dp_rx_msdu_coalesce(ar, msdu_list, + msdu, last_buf, + l3_pad_bytes, msdu_len); + if (ret) { + ath11k_warn(ar->ab, + "failed to coalesce msdu rx buffer%d\n", ret); + goto free_out; + } } + + hdr = (struct ieee80211_hdr *)msdu->data; + + /* Process only data frames */ + if (!ieee80211_is_data(hdr->frame_control)) + return -EINVAL; + + ath11k_dp_rx_h_ppdu(ar, rx_desc, &rx_status); + ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, &rx_status); + + rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + + status = IEEE80211_SKB_RXCB(msdu); + *status = rx_status; + return 0; + +free_out: + return ret; } -static void ath11k_dp_rx_process_pending_packets(struct ath11k_base *ab, - struct napi_struct *napi, - struct sk_buff_head *pending_q, - int *quota, u8 mac_id) +static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab, + struct napi_struct *napi, + struct sk_buff_head *msdu_list, + int *quota, int ring_id) { - struct ath11k *ar; + struct ath11k_skb_rxcb *rxcb; struct sk_buff *msdu; - struct ath11k_pdev *pdev; + struct ath11k *ar; + u8 mac_id; + int ret; - if (skb_queue_empty(pending_q)) + if (skb_queue_empty(msdu_list)) return; - ar = ab->pdevs[mac_id].ar; - rcu_read_lock(); - pdev = rcu_dereference(ab->pdevs_active[mac_id]); - while (*quota && (msdu = __skb_dequeue(pending_q))) { - if (!pdev) { + while (*quota && (msdu = __skb_dequeue(msdu_list))) { + rxcb = ATH11K_SKB_RXCB(msdu); + mac_id = rxcb->mac_id; + ar = ab->pdevs[mac_id].ar; + if (!rcu_dereference(ab->pdevs_active[mac_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list); + if (ret) { + ath11k_dbg(ab, ATH11K_DBG_DATA, + "Unable to process msdu %d", ret); dev_kfree_skb_any(msdu); continue; } @@ -2387,46 +2370,31 @@ static void ath11k_dp_rx_process_pending_packets(struct ath11k_base *ab, ath11k_dp_rx_deliver_msdu(ar, napi, msdu); (*quota)--; } + rcu_read_unlock(); } -int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id, - struct napi_struct *napi, struct sk_buff_head *pending_q, - int budget) +int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, + struct napi_struct *napi, int budget) { - struct ath11k *ar = ab->pdevs[mac_id].ar; - struct ath11k_pdev_dp *dp = &ar->dp; - struct ieee80211_rx_status *rx_status = &dp->rx_status; - struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - struct hal_srng *srng; - struct sk_buff *msdu; + struct ath11k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring; + int num_buffs_reaped[MAX_RADIOS] = {0}; struct sk_buff_head msdu_list; - struct sk_buff_head amsdu_list; struct ath11k_skb_rxcb *rxcb; - u32 *rx_desc; - int buf_id; - int num_buffs_reaped = 0; + int total_msdu_reaped = 0; + struct hal_srng *srng; + struct sk_buff *msdu; int quota = budget; - int ret; bool done = false; - - /* Process any pending packets from the previous napi poll. - * Note: All msdu's in this pending_q corresponds to the same mac id - * due to pdev based reo dest mapping and also since each irq group id - * maps to specific reo dest ring. - */ - ath11k_dp_rx_process_pending_packets(ab, napi, pending_q, "a, - mac_id); - - /* If all quota is exhausted by processing the pending_q, - * Wait for the next napi poll to reap the new info - */ - if (!quota) - goto exit; + int buf_id, mac_id; + struct ath11k *ar; + u32 *rx_desc; + int i; __skb_queue_head_init(&msdu_list); - srng = &ab->hal.srng_list[dp->reo_dst_ring.ring_id]; + srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; spin_lock_bh(&srng->lock); @@ -2442,6 +2410,10 @@ try_again: desc->buf_addr_info.info1); buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie); + mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie); + + ar = ab->pdevs[mac_id].ar; + rx_ring = &ar->dp.rx_refill_buf_ring; spin_lock_bh(&rx_ring->idr_lock); msdu = idr_find(&rx_ring->bufs_idr, buf_id); if (!msdu) { @@ -2459,15 +2431,15 @@ try_again: msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); - num_buffs_reaped++; + num_buffs_reaped[mac_id]++; + total_msdu_reaped++; push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, desc->info0); if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { - /* TODO: Check if the msdu can be sent up for processing */ dev_kfree_skb_any(msdu); - ab->soc_stats.hal_reo_error[dp->reo_dst_ring.ring_id]++; + ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; continue; } @@ -2478,19 +2450,12 @@ try_again: rxcb->is_continuation = !!(desc->rx_msdu_info.info0 & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); rxcb->mac_id = mac_id; + rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM, + desc->info0); + __skb_queue_tail(&msdu_list, msdu); - /* Stop reaping from the ring once quota is exhausted - * and we've received all msdu's in the the AMSDU. The - * additional msdu's reaped in excess of quota here would - * be pushed into the pending queue to be processed during - * the next napi poll. - * Note: More profiling can be done to see the impact on - * pending_q and throughput during various traffic & density - * and how use of budget instead of remaining quota affects it. - */ - if (num_buffs_reaped >= quota && rxcb->is_last_msdu && - !rxcb->is_continuation) { + if (total_msdu_reaped >= quota && !rxcb->is_continuation) { done = true; break; } @@ -2511,58 +2476,23 @@ try_again: spin_unlock_bh(&srng->lock); - if (!num_buffs_reaped) + if (!total_msdu_reaped) goto exit; - /* Should we reschedule it later if we are not able to replenish all - * the buffers? - */ - ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buffs_reaped, - HAL_RX_BUF_RBM_SW3_BM, GFP_ATOMIC); - - rcu_read_lock(); - if (!rcu_dereference(ab->pdevs_active[mac_id])) { - __skb_queue_purge(&msdu_list); - goto rcu_unlock; - } - - if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) { - __skb_queue_purge(&msdu_list); - goto rcu_unlock; - } - - while (!skb_queue_empty(&msdu_list)) { - __skb_queue_head_init(&amsdu_list); - ret = ath11k_dp_rx_retrieve_amsdu(ar, &msdu_list, &amsdu_list); - if (ret) { - if (ret == -EIO) { - ath11k_err(ab, "rx ring got corrupted %d\n", ret); - __skb_queue_purge(&msdu_list); - /* Should stop processing any more rx in - * future from this ring? - */ - goto rcu_unlock; - } - - /* A-MSDU retrieval got failed due to non-fatal condition, - * continue processing with the next msdu. - */ + for (i = 0; i < ab->num_radios; i++) { + if (!num_buffs_reaped[i]) continue; - } - ath11k_dp_rx_process_amsdu(ar, &amsdu_list, rx_status); + ar = ab->pdevs[i].ar; + rx_ring = &ar->dp.rx_refill_buf_ring; - ath11k_dp_rx_pre_deliver_amsdu(ar, &amsdu_list, rx_status); - skb_queue_splice_tail(&amsdu_list, pending_q); + ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], + HAL_RX_BUF_RBM_SW3_BM, GFP_ATOMIC); } - while (quota && (msdu = __skb_dequeue(pending_q))) { - ath11k_dp_rx_deliver_msdu(ar, napi, msdu); - quota--; - } + ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list, + "a, ring_id); -rcu_unlock: - rcu_read_unlock(); exit: return budget - quota; } @@ -3649,7 +3579,6 @@ static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu, struct ieee80211_rx_status *status, struct sk_buff_head *msdu_list) { - struct sk_buff_head amsdu_list; u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes; @@ -3680,8 +3609,6 @@ static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu, * This error can show up both in a REO destination or WBM release ring. */ - __skb_queue_head_init(&amsdu_list); - rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(desc); rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(desc); @@ -3698,9 +3625,9 @@ static int ath11k_dp_rx_h_null_q_desc(struct ath11k *ar, struct sk_buff *msdu, } ath11k_dp_rx_h_ppdu(ar, desc, status); - __skb_queue_tail(&amsdu_list, msdu); + ath11k_dp_rx_h_mpdu(ar, msdu, desc, status); - ath11k_dp_rx_h_mpdu(ar, &amsdu_list, desc, status); + rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(desc); /* Please note that caller will having the access to msdu and completing * rx with mac80211. Need not worry about cleaning up amsdu_list. diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h index 9ab535fde5a8..88bbcae14e34 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h @@ -9,6 +9,8 @@ #include "rx_desc.h" #include "debug.h" +#define DP_MAX_NWIFI_HDR_LEN 30 + #define DP_RX_MPDU_ERR_FCS BIT(0) #define DP_RX_MPDU_ERR_DECRYPT BIT(1) #define DP_RX_MPDU_ERR_TKIP_MIC BIT(2) @@ -67,7 +69,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, int budget); int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id, - struct napi_struct *napi, struct sk_buff_head *pending_q, + struct napi_struct *napi, int budget); int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id, struct dp_rxdma_ring *rx_ring, diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 8c3f973923d6..7aac4b0eea0c 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -47,7 +47,7 @@ static u8 ath11k_dp_tx_get_tid(struct sk_buff *skb) return skb->priority & IEEE80211_QOS_CTL_TID_MASK; } -static enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) +enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) { switch (cipher) { case WLAN_CIPHER_SUITE_WEP40: diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 6a0d0f654623..9f8bc19cc5ae 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2418,10 +2418,13 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { peer->ucast_keyidx = key->keyidx; - else + peer->sec_type = ath11k_dp_tx_get_encrypt_type(key->cipher); + } else { peer->mcast_keyidx = key->keyidx; + peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher); + } } else if (peer && cmd == DISABLE_KEY) { peer->keys[key->keyidx] = NULL; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) @@ -2451,6 +2454,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; } } + spin_unlock_bh(&ab->base_lock); exit: diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index f4937a03e92b..0607479774a9 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -145,4 +145,5 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar); int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw); +enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher); #endif diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 4bf1dfa498b6..f43deacc01bd 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -228,6 +228,9 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, peer->sta = sta; arvif->ast_hash = peer->ast_hash; + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + ar->num_peers++; spin_unlock_bh(&ar->ab->base_lock); diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h index 55d9919b8b5d..ccca1523a6ea 100644 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -24,6 +24,8 @@ struct ath11k_peer { struct crypto_shash *tfm_mmic; u8 mcast_keyidx; u8 ucast_keyidx; + u16 sec_type; + u16 sec_type_grp; }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); -- cgit From 95a568c4a4611020d403b1ae8bc284133c53a7fe Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Wed, 18 Mar 2020 19:45:11 +0530 Subject: ath10k: Fill GCMP MIC length for PMF GCMP MIC length is not filled for GCMP/GCMP-256 cipher suites in PMF enabled case. Due to mismatch in MIC length, deauth/disassoc frames are unencrypted. This patch fills proper MIC length for GCMP/GCMP-256 cipher suites. Tested HW: QCA9984, QCA9888 Tested FW: 10.4-3.6-00104 Signed-off-by: Yingying Tang Co-developed-by: Sowmiya Sree Elavalagan Signed-off-by: Sowmiya Sree Elavalagan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 ++ drivers/net/wireless/ath/ath10k/htt_tx.c | 12 +++++++++++- drivers/net/wireless/ath/ath10k/mac.c | 25 ++++++++++++++++++++----- drivers/net/wireless/ath/ath10k/wmi.c | 17 +++++++++++++++-- 4 files changed, 48 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index edf314e3e19e..bd8ef576c590 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -119,6 +119,7 @@ struct ath10k_skb_cb { u16 airtime_est; struct ieee80211_vif *vif; struct ieee80211_txq *txq; + u32 ucast_cipher; } __packed; struct ath10k_skb_rxcb { @@ -504,6 +505,7 @@ struct ath10k_sta { struct work_struct update_wk; u64 rx_duration; struct ath10k_htt_tx_stats *tx_stats; + u32 ucast_cipher; #ifdef CONFIG_MAC80211_DEBUGFS /* protected by conf_mutex */ diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index a182c0944cc7..e9d12ea708b6 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -1163,6 +1163,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) int len = 0; int msdu_id = -1; int res; + const u8 *peer_addr; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; len += sizeof(cmd->hdr); @@ -1178,7 +1179,16 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) ieee80211_is_deauth(hdr->frame_control) || ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + peer_addr = hdr->addr1; + if (is_multicast_ether_addr(peer_addr)) { + skb_put(msdu, sizeof(struct ieee80211_mmie_16)); + } else { + if (skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP || + skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256) + skb_put(msdu, IEEE80211_GCMP_MIC_LEN); + else + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } } txdesc = ath10k_htc_alloc_skb(ar, len); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 23d9830d6ed6..2d03b8dd3b8c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -258,6 +258,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM]; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; break; case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: @@ -3576,6 +3577,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, struct ieee80211_vif *vif, struct ieee80211_txq *txq, + struct ieee80211_sta *sta, struct sk_buff *skb, u16 airtime) { struct ieee80211_hdr *hdr = (void *)skb->data; @@ -3583,6 +3585,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); bool is_data = ieee80211_is_data(hdr->frame_control) || ieee80211_is_data_qos(hdr->frame_control); + struct ath10k_sta *arsta; cb->flags = 0; if (!ath10k_tx_h_use_hwcrypto(vif, skb)) @@ -3607,6 +3610,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, cb->vif = vif; cb->txq = txq; cb->airtime_est = airtime; + if (sta) { + arsta = (struct ath10k_sta *)sta->drv_priv; + spin_lock_bh(&ar->data_lock); + cb->ucast_cipher = arsta->ucast_cipher; + spin_unlock_bh(&ar->data_lock); + } } bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar) @@ -4078,7 +4087,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, } airtime = ath10k_mac_update_airtime(ar, txq, skb); - ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime); + ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime); skb_len = skb->len; txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); @@ -4348,7 +4357,7 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw, u16 airtime; airtime = ath10k_mac_update_airtime(ar, txq, skb); - ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime); + ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime); txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); @@ -6197,6 +6206,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, { struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = (void *)vif->drv_priv; + struct ath10k_sta *arsta; struct ath10k_peer *peer; const u8 *peer_addr; bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 || @@ -6221,12 +6231,17 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&ar->conf_mutex); - if (sta) + if (sta) { + arsta = (struct ath10k_sta *)sta->drv_priv; peer_addr = sta->addr; - else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) + spin_lock_bh(&ar->data_lock); + arsta->ucast_cipher = key->cipher; + spin_unlock_bh(&ar->data_lock); + } else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { peer_addr = vif->bss_conf.bssid; - else + } else { peer_addr = vif->addr; + } key->hw_key_idx = key->keyidx; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index e76e3654126a..2ea77bb880b1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1926,6 +1926,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) u32 vdev_id; u32 buf_len = msdu->len; u16 fc; + const u8 *peer_addr; hdr = (struct ieee80211_hdr *)msdu->data; fc = le16_to_cpu(hdr->frame_control); @@ -1946,8 +1947,20 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) ieee80211_is_deauth(hdr->frame_control) || ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { - len += IEEE80211_CCMP_MIC_LEN; - buf_len += IEEE80211_CCMP_MIC_LEN; + peer_addr = hdr->addr1; + if (is_multicast_ether_addr(peer_addr)) { + len += sizeof(struct ieee80211_mmie_16); + buf_len += sizeof(struct ieee80211_mmie_16); + } else { + if (cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP || + cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256) { + len += IEEE80211_GCMP_MIC_LEN; + buf_len += IEEE80211_GCMP_MIC_LEN; + } else { + len += IEEE80211_CCMP_MIC_LEN; + buf_len += IEEE80211_CCMP_MIC_LEN; + } + } } len = round_up(len, 4); -- cgit From 1fe188da9de58c1021aedb9ea1e7a3d95895ea5c Mon Sep 17 00:00:00 2001 From: Yan-Hsuan Chuang Date: Fri, 13 Mar 2020 11:30:06 +0800 Subject: rtw88: add a debugfs entry to dump coex's info Add a new entry "coex_info" in debugfs to dump coex's states for us to debug on coex's issues. The basic concept for co-existence (coex, usually for WiFi + BT) is to decide a strategy based on the current status of WiFi and BT. So, it means the WiFi driver requires to gather information from BT side and choose a strategy (TDMA/table/HW settings). Althrough we can easily check the current status of WiFi, e.g., from kernel log or just dump the hardware registers, it is still very difficult for us to gather so many different types of WiFi states (such as RFE config, antenna, channel/band, TRX, Power save). Also we will need BT's information that is stored in "struct rtw_coex". So it is necessary for us to have a debugfs that can dump all of the WiFi/BT information required. Note that to debug on coex related issues, we usually need a longer period of time of coex_info dump every 2 seconds (for example, 30 secs, so we should have 15 times of coex_info's dump). Signed-off-by: Yan-Hsuan Chuang Reviewed-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200313033008.20070-2-yhchuang@realtek.com --- drivers/net/wireless/realtek/rtw88/coex.c | 492 ++++++++++++++++++++++++++ drivers/net/wireless/realtek/rtw88/coex.h | 10 + drivers/net/wireless/realtek/rtw88/debug.c | 17 + drivers/net/wireless/realtek/rtw88/main.h | 18 + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 30 ++ drivers/net/wireless/realtek/rtw88/rtw8822c.c | 28 ++ 6 files changed, 595 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c index f91dc21a8bf1..567372fb4e12 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.c +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -2503,3 +2503,495 @@ void rtw_coex_defreeze_work(struct work_struct *work) rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); mutex_unlock(&rtwdev->mutex); } + +#ifdef CONFIG_RTW88_DEBUGFS +#define INFO_SIZE 80 + +#define case_BTINFO(src) \ + case COEX_BTINFO_SRC_##src: return #src + +static const char *rtw_coex_get_bt_info_src_string(u8 bt_info_src) +{ + switch (bt_info_src) { + case_BTINFO(WL_FW); + case_BTINFO(BT_RSP); + case_BTINFO(BT_ACT); + default: + return "Unknown"; + } +} + +#define case_RSN(src) \ + case COEX_RSN_##src: return #src + +static const char *rtw_coex_get_reason_string(u8 reason) +{ + switch (reason) { + case_RSN(2GSCANSTART); + case_RSN(5GSCANSTART); + case_RSN(SCANFINISH); + case_RSN(2GSWITCHBAND); + case_RSN(5GSWITCHBAND); + case_RSN(2GCONSTART); + case_RSN(5GCONSTART); + case_RSN(2GCONFINISH); + case_RSN(5GCONFINISH); + case_RSN(2GMEDIA); + case_RSN(5GMEDIA); + case_RSN(MEDIADISCON); + case_RSN(BTINFO); + case_RSN(LPS); + case_RSN(WLSTATUS); + default: + return "Unknown"; + } +} + +static int rtw_coex_addr_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char addr_info[], int n) +{ + const char *rf_prefix = ""; + const char *sep = n == 0 ? "" : "/ "; + int ffs, fls; + int max_fls; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + max_fls = 31; + break; + case RTW_REG_DOMAIN_MAC16: + max_fls = 15; + break; + case RTW_REG_DOMAIN_MAC8: + max_fls = 7; + break; + case RTW_REG_DOMAIN_RF_A: + case RTW_REG_DOMAIN_RF_B: + rf_prefix = "RF_"; + max_fls = 19; + break; + default: + return 0; + } + + ffs = __ffs(reg->mask); + fls = __fls(reg->mask); + + if (ffs == 0 && fls == max_fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x", + sep, rf_prefix, reg->addr); + else if (ffs == fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d]", + sep, rf_prefix, reg->addr, ffs); + else + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d:%d]", + sep, rf_prefix, reg->addr, fls, ffs); +} + +static int rtw_coex_val_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char val_info[], int n) +{ + const char *sep = n == 0 ? "" : "/ "; + u8 rf_path; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read32_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC16: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read16_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC8: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read8_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_RF_A: + rf_path = RF_PATH_A; + break; + case RTW_REG_DOMAIN_RF_B: + rf_path = RF_PATH_B; + break; + default: + return 0; + } + + /* only RF go through here */ + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read_rf(rtwdev, rf_path, reg->addr, reg->mask)); +} + +static void rtw_coex_set_coexinfo_hw(struct rtw_dev *rtwdev, struct seq_file *m) +{ + struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_reg_domain *reg; + char addr_info[INFO_SIZE]; + int n_addr = 0; + char val_info[INFO_SIZE]; + int n_val = 0; + int i; + + for (i = 0; i < chip->coex_info_hw_regs_num; i++) { + reg = &chip->coex_info_hw_regs[i]; + + n_addr += rtw_coex_addr_info(rtwdev, reg, addr_info, n_addr); + n_val += rtw_coex_val_info(rtwdev, reg, val_info, n_val); + + if (reg->domain == RTW_REG_DOMAIN_NL) { + seq_printf(m, "%-40s = %s\n", addr_info, val_info); + n_addr = 0; + n_val = 0; + } + } + + if (n_addr != 0 && n_val != 0) + seq_printf(m, "%-40s = %s\n", addr_info, val_info); +} + +static bool rtw_coex_get_bt_reg(struct rtw_dev *rtwdev, + u8 type, u16 addr, u16 *val) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + __le16 le_addr; + u8 *payload; + + le_addr = cpu_to_le16(addr); + req.op_code = BT_MP_INFO_OP_READ_REG; + req.para1 = type; + req.para2 = le16_get_bits(le_addr, GENMASK(7, 0)); + req.para3 = le16_get_bits(le_addr, GENMASK(15, 8)); + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) { + *val = 0xeaea; + return false; + } + + payload = get_payload_from_coex_resp(skb); + *val = GET_COEX_RESP_BT_REG_VAL(payload); + + return true; +} + +static bool rtw_coex_get_bt_patch_version(struct rtw_dev *rtwdev, + u32 *patch_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_PATCH_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *patch_version = GET_COEX_RESP_BT_PATCH_VER(payload); + ret = true; + +out: + return ret; +} + +static bool rtw_coex_get_bt_supported_version(struct rtw_dev *rtwdev, + u32 *supported_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_SUPP_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *supported_version = GET_COEX_RESP_BT_SUPP_VER(payload); + ret = true; + +out: + return ret; +} + +static bool rtw_coex_get_bt_supported_feature(struct rtw_dev *rtwdev, + u32 *supported_feature) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_SUPP_FEAT; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *supported_feature = GET_COEX_RESP_BT_SUPP_FEAT(payload); + ret = true; + +out: + return ret; +} + +struct rtw_coex_sta_stat_iter_data { + struct rtw_vif *rtwvif; + struct seq_file *file; +}; + +static void rtw_coex_sta_stat_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_coex_sta_stat_iter_data *sta_iter_data = data; + struct rtw_vif *rtwvif = sta_iter_data->rtwvif; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct seq_file *m = sta_iter_data->file; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 rssi; + + if (si->vif != vif) + return; + + rssi = ewma_rssi_read(&si->avg_rssi); + seq_printf(m, "\tPeer %3d\n", si->mac_id); + seq_printf(m, "\t\t%-24s = %d\n", "RSSI", rssi); + seq_printf(m, "\t\t%-24s = %d\n", "BW mode", si->bw_mode); +} + +struct rtw_coex_vif_stat_iter_data { + struct rtw_dev *rtwdev; + struct seq_file *file; +}; + +static void rtw_coex_vif_stat_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_coex_vif_stat_iter_data *vif_iter_data = data; + struct rtw_coex_sta_stat_iter_data sta_iter_data; + struct rtw_dev *rtwdev = vif_iter_data->rtwdev; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct seq_file *m = vif_iter_data->file; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + seq_printf(m, "Iface on Port (%d)\n", rtwvif->port); + seq_printf(m, "\t%-32s = %d\n", + "Beacon interval", bss_conf->beacon_int); + seq_printf(m, "\t%-32s = %d\n", + "Network Type", rtwvif->net_type); + + sta_iter_data.rtwvif = rtwvif; + sta_iter_data.file = m; + rtw_iterate_stas_atomic(rtwdev, rtw_coex_sta_stat_iter, + &sta_iter_data); +} + +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_coex_vif_stat_iter_data vif_iter_data; + u8 reason = coex_dm->reason; + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; + u32 lte_coex, bt_coex; + u32 bt_hi_pri, bt_lo_pri; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); + score_board_WB = coex_stat->score_board; + wl_reg_6c0 = rtw_read32(rtwdev, 0x6c0); + wl_reg_6c4 = rtw_read32(rtwdev, 0x6c4); + wl_reg_6c8 = rtw_read32(rtwdev, 0x6c8); + wl_reg_6cc = rtw_read32(rtwdev, 0x6cc); + wl_reg_778 = rtw_read32(rtwdev, 0x778); + bt_hi_pri = rtw_read32(rtwdev, 0x770); + bt_lo_pri = rtw_read32(rtwdev, 0x774); + rtw_write8(rtwdev, 0x76e, 0xc); + sys_lte = rtw_read8(rtwdev, 0x73); + lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); + bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); + + if (!coex_stat->bt_disabled && !coex_stat->bt_mailbox_reply) { + rtw_coex_get_bt_supported_version(rtwdev, + &coex_stat->bt_supported_version); + rtw_coex_get_bt_patch_version(rtwdev, &coex_stat->patch_ver); + rtw_coex_get_bt_supported_feature(rtwdev, + &coex_stat->bt_supported_feature); + rtw_coex_get_bt_reg(rtwdev, 3, 0xae, &coex_stat->bt_reg_vendor_ae); + rtw_coex_get_bt_reg(rtwdev, 3, 0xac, &coex_stat->bt_reg_vendor_ac); + + if (coex_stat->patch_ver != 0) + coex_stat->bt_mailbox_reply = true; + } + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Coexist info %x\n", chip->id); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %d\n", + "Mech/ RFE", + efuse->share_ant ? "Shared" : "Non-Shared", + efuse->rfe_option); + seq_printf(m, "%-40s = %08x/ 0x%02x/ 0x%08x %s\n", + "Coex Ver/ BT Dez/ BT Rpt", + chip->coex_para_ver, chip->bt_desired_ver, + coex_stat->bt_supported_version, + coex_stat->bt_disabled ? "(BT disabled)" : + coex_stat->bt_supported_version >= chip->bt_desired_ver ? + "(Match)" : "(Mismatch)"); + seq_printf(m, "%-40s = %s/ %u/ %d\n", + "Role/ RoleSwCnt/ IgnWL/ Feature", + coex_stat->bt_slave ? "Slave" : "Master", + coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH], + coex_dm->ignore_wl_act); + seq_printf(m, "%-40s = %u.%u/ 0x%x/ %c\n", + "WL FW/ BT FW/ KT", + fw->version, fw->sub_version, + coex_stat->patch_ver, coex_stat->kt_ver + 65); + seq_printf(m, "%-40s = %u/ %u/ %u/ ch-(%u)\n", + "AFH Map", + coex_dm->wl_ch_info[0], coex_dm->wl_ch_info[1], + coex_dm->wl_ch_info[2], hal->current_channel); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %ddBm/ %u/ %u\n", + "BT status/ rssi/ retry/ pop", + coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ? "non-conn" : + coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE ? "conn-idle" : "busy", + coex_stat->bt_rssi - 100, + coex_stat->cnt_bt[COEX_CNT_BT_RETRY], + coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]); + seq_printf(m, "%-40s = %s%s%s%s%s (multi-link %d)\n", + "Profiles", + coex_stat->bt_a2dp_exist ? (coex_stat->bt_a2dp_sink ? + "A2DP sink," : "A2DP,") : "", + coex_stat->bt_hfp_exist ? "HFP," : "", + coex_stat->bt_hid_exist ? + (coex_stat->bt_ble_exist ? "HID(RCU)," : + coex_stat->bt_hid_slot >= 2 ? "HID(4/18)" : + "HID(2/18),") : "", + coex_stat->bt_pan_exist ? coex_stat->bt_opp_exist ? + "OPP," : "PAN," : "", + coex_stat->bt_ble_voice ? "Voice," : "", + coex_stat->bt_multi_link); + seq_printf(m, "%-40s = %u/ %u/ %u/ 0x%08x\n", + "Reinit/ Relink/ IgnWl/ Feature", + coex_stat->cnt_bt[COEX_CNT_BT_REINIT], + coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK], + coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT], + coex_stat->bt_supported_feature); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "Page/ Inq/ iqk/ iqk fail", + coex_stat->cnt_bt[COEX_CNT_BT_PAGE], + coex_stat->cnt_bt[COEX_CNT_BT_INQ], + coex_stat->cnt_bt[COEX_CNT_BT_IQK], + coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]); + seq_printf(m, "%-40s = 0x%04x/ 0x%04x/ 0x%04x/ 0x%04x\n", + "0xae/ 0xac/ score board (W->B)/ (B->W)", + coex_stat->bt_reg_vendor_ae, + coex_stat->bt_reg_vendor_ac, + score_board_WB, score_board_BW); + seq_printf(m, "%-40s = %u/%u, %u/%u\n", + "Hi-Pri TX/RX, Lo-Pri TX/RX", + bt_hi_pri & 0xffff, bt_hi_pri >> 16, + bt_lo_pri & 0xffff, bt_lo_pri >> 16); + for (i = 0; i < COEX_BTINFO_SRC_BT_IQK; i++) + seq_printf(m, "%-40s = %7ph\n", + rtw_coex_get_bt_info_src_string(i), + coex_stat->bt_info_c2h[i]); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tWiFi Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %d\n", + "Scanning", test_bit(RTW_FLAG_SCANNING, rtwdev->flags)); + seq_printf(m, "%-40s = %u/ TX %d Mbps/ RX %d Mbps\n", + "G_busy/ TX/ RX", + coex_stat->wl_gl_busy, + rtwdev->stats.tx_throughput, rtwdev->stats.rx_throughput); + seq_printf(m, "%-40s = %u/ %u/ %u\n", + "IPS/ Low Power/ PS mode", + test_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags), + test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags), + rtwdev->lps_conf.mode); + + vif_iter_data.rtwdev = rtwdev; + vif_iter_data.file = m; + rtw_iterate_vifs_atomic(rtwdev, rtw_coex_vif_stat_iter, &vif_iter_data); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tMechanism\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %5ph (case-%d)\n", + "TDMA", + coex_dm->ps_tdma_para, coex_dm->cur_ps_tdma); + seq_printf(m, "%-40s = %d\n", + "Timer base", coex_stat->tdma_timer_base); + seq_printf(m, "%-40s = %d/ 0x%08x/ 0x%08x/ 0x%08x\n", + "Table/ 0x6c0/ 0x6c4/ 0x6c8", + coex_dm->cur_table, wl_reg_6c0, wl_reg_6c4, wl_reg_6c8); + seq_printf(m, "%-40s = 0x%08x/ 0x%08x/ reason (%s)\n", + "0x778/ 0x6cc/ Reason", + wl_reg_778, wl_reg_6cc, rtw_coex_get_reason_string(reason)); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u/ %u\n", + "Null All/ Retry/ Ack/ BT Empty/ BT Late", + coex_stat->wl_fw_dbg_info[1], coex_stat->wl_fw_dbg_info[2], + coex_stat->wl_fw_dbg_info[3], coex_stat->wl_fw_dbg_info[4], + coex_stat->wl_fw_dbg_info[5]); + seq_printf(m, "%-40s = %u/ %u/ %s/ %u\n", + "Cnt TDMA Toggle/ Lk 5ms/ Lk 5ms on/ FW", + coex_stat->wl_fw_dbg_info[6], + coex_stat->wl_fw_dbg_info[7], + coex_stat->wl_slot_extend ? "Yes" : "No", + coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tHW setting\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %s\n", + "LTE Coex/ Path Owner", + lte_coex & BIT(7) ? "ON" : "OFF", + sys_lte & BIT(2) ? "WL" : "BT"); + seq_printf(m, "%-40s = RF:%s_BB:%s/ RF:%s_BB:%s/ %s\n", + "GNT_WL_CTRL/ GNT_BT_CTRL/ Dbg", + lte_coex & BIT(12) ? "SW" : "HW", + lte_coex & BIT(8) ? "SW" : "HW", + lte_coex & BIT(14) ? "SW" : "HW", + lte_coex & BIT(10) ? "SW" : "HW", + sys_lte & BIT(3) ? "On" : "Off"); + seq_printf(m, "%-40s = %lu/ %lu\n", + "GNT_WL/ GNT_BT", + (bt_coex & BIT(2)) >> 2, (bt_coex & BIT(3)) >> 3); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC OK CCK/ OFDM/ HT/ VHT", + dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt, + dm_info->ht_ok_cnt, dm_info->vht_ok_cnt); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC ERR CCK/ OFDM/ HT/ VHT", + dm_info->cck_err_cnt, dm_info->ofdm_err_cnt, + dm_info->ht_err_cnt, dm_info->vht_err_cnt); + seq_printf(m, "%-40s = %s/ %s/ %s/ %u\n", + "HiPr/ Locking/ Locked/ Noisy", + coex_stat->wl_hi_pri_task1 ? "Y" : "N", + coex_stat->wl_cck_lock ? "Y" : "N", + coex_stat->wl_cck_lock_ever ? "Y" : "N", + coex_stat->wl_noisy_level); + + rtw_coex_set_coexinfo_hw(rtwdev, m); +} +#endif /* CONFIG_RTW88_DEBUGFS */ diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h index 008d1af5996b..4c3a01968f5e 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.h +++ b/drivers/net/wireless/realtek/rtw88/coex.h @@ -46,6 +46,14 @@ (__rssi__ == COEX_RSSI_STATE_LOW || \ __rssi__ == COEX_RSSI_STATE_STAY_LOW ? true : false); }) +#define GET_COEX_RESP_BT_SUPP_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 32)) +#define GET_COEX_RESP_BT_SUPP_FEAT(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) +#define GET_COEX_RESP_BT_PATCH_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(55, 24)) +#define GET_COEX_RESP_BT_REG_VAL(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) #define GET_COEX_RESP_BT_SCAN_TYPE(payload) \ le64_get_bits(*((__le64 *)(payload)), GENMASK(31, 24)) @@ -367,4 +375,6 @@ void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev); +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m); + #endif diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c index 5a181e01ebef..b2d264270752 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.c +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -5,6 +5,7 @@ #include #include #include "main.h" +#include "coex.h" #include "sec.h" #include "fw.h" #include "debug.h" @@ -691,6 +692,17 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) dm_info->ht_ok_cnt, dm_info->ht_err_cnt); seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", dm_info->vht_ok_cnt, dm_info->vht_err_cnt); + + return 0; +} + +static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + rtw_coex_display_coex_info(rtwdev, m); + return 0; } @@ -784,6 +796,10 @@ static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { .cb_read = rtw_debugfs_get_phy_info, }; +static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { + .cb_read = rtw_debugfs_get_coex_info, +}; + #define rtw_debugfs_add_core(name, mode, fopname, parent) \ do { \ rtw_debug_priv_ ##name.rtwdev = rtwdev; \ @@ -814,6 +830,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) rtw_debugfs_add_rw(dump_cam); rtw_debugfs_add_rw(rsvd_page); rtw_debugfs_add_r(phy_info); + rtw_debugfs_add_r(coex_info); rtw_debugfs_add_r(mac_0); rtw_debugfs_add_r(mac_1); rtw_debugfs_add_r(mac_2); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 279410a87141..bcc07cf9f481 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -515,6 +515,18 @@ struct rtw_hw_reg { u32 mask; }; +struct rtw_reg_domain { + u32 addr; + u32 mask; +#define RTW_REG_DOMAIN_MAC32 0 +#define RTW_REG_DOMAIN_MAC16 1 +#define RTW_REG_DOMAIN_MAC8 2 +#define RTW_REG_DOMAIN_RF_A 3 +#define RTW_REG_DOMAIN_RF_B 4 +#define RTW_REG_DOMAIN_NL 0xFF + u8 domain; +}; + struct rtw_backup_info { u8 len; u32 reg; @@ -1107,6 +1119,7 @@ struct rtw_chip_info { u8 bt_afh_span_bw40; u8 afh_5g_num; u8 wl_rf_para_num; + u8 coex_info_hw_regs_num; const u8 *bt_rssi_step; const u8 *wl_rssi_step; const struct coex_table_para *table_nsant; @@ -1116,6 +1129,7 @@ struct rtw_chip_info { const struct coex_rf_para *wl_rf_para_tx; const struct coex_rf_para *wl_rf_para_rx; const struct coex_5g_afh_map *afh_5g; + const struct rtw_reg_domain *coex_info_hw_regs; }; enum rtw_coex_bt_state_cnt { @@ -1162,6 +1176,7 @@ struct rtw_coex_rfe { struct rtw_coex_dm { bool cur_ps_tdma_on; bool cur_wl_rx_low_gain_en; + bool ignore_wl_act; u8 reason; u8 bt_rssi_state[4]; @@ -1242,6 +1257,9 @@ struct rtw_coex_stat { u32 bt_supported_version; u32 bt_supported_feature; + u32 patch_ver; + u16 bt_reg_vendor_ae; + u16 bt_reg_vendor_ac; s8 bt_rssi; u8 kt_ver; u8 gnt_workaround_state; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 96aa332fb28d..4dd7d4143b04 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -2371,6 +2371,33 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, }; +static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + struct rtw_chip_info rtw8822b_hw_spec = { .ops = &rtw8822b_ops, .id = RTW_CHIP_TYPE_8822B, @@ -2439,6 +2466,9 @@ struct rtw_chip_info rtw8822b_hw_spec = { .bt_afh_span_bw40 = 0x36, .afh_5g_num = ARRAY_SIZE(afh_5g_8822b), .afh_5g = afh_5g_8822b, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), + .coex_info_hw_regs = coex_info_hw_regs_8822b, }; EXPORT_SYMBOL(rtw8822b_hw_spec); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index d2469f91976b..dc07e6be38e8 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -4092,6 +4092,31 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = { }; #endif +static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = { + {0x1860, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x4160, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8}, + {0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + struct rtw_chip_info rtw8822c_hw_spec = { .ops = &rtw8822c_ops, .id = RTW_CHIP_TYPE_8822C, @@ -4168,6 +4193,9 @@ struct rtw_chip_info rtw8822c_hw_spec = { .bt_afh_span_bw40 = 0x36, .afh_5g_num = ARRAY_SIZE(afh_5g_8822c), .afh_5g = afh_5g_8822c, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), + .coex_info_hw_regs = coex_info_hw_regs_8822c, }; EXPORT_SYMBOL(rtw8822c_hw_spec); -- cgit From d05550936ac87bd067351e96f781051d6a2a642e Mon Sep 17 00:00:00 2001 From: Yan-Hsuan Chuang Date: Fri, 13 Mar 2020 11:30:07 +0800 Subject: rtw88: add a debugfs entry to enable/disable coex mechanism Sometimes we need to stop the coex mechanism to debug, so that we can manually control the device through various outer commands. Hence, add a new debugfs coex_enable to allow us to enable/disable the coex mechanism when driver is running. To disable coex echo 0 > /sys/kernel/debug/ieee80211/phyX/rtw88/coex_enable To enable coex echo 1 > /sys/kernel/debug/ieee80211/phyX/rtw88/coex_enable To check coex dm is enabled or not cat /sys/kernel/debug/ieee80211/phyX/rtw88/coex_enable Signed-off-by: Yan-Hsuan Chuang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200313033008.20070-3-yhchuang@realtek.com --- drivers/net/wireless/realtek/rtw88/debug.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c index b2d264270752..b4964306de61 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.c +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -706,6 +706,45 @@ static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) return 0; } +static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + char tmp[32 + 1]; + bool enable; + int ret; + + rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); + + ret = kstrtobool(tmp, &enable); + if (ret) { + rtw_warn(rtwdev, "invalid arguments\n"); + return ret; + } + + mutex_lock(&rtwdev->mutex); + coex->stop_dm = enable == 0; + mutex_unlock(&rtwdev->mutex); + + return count; +} + +static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + + seq_printf(m, "coex mechanism %s\n", + coex->stop_dm ? "disabled" : "enabled"); + + return 0; +} + #define rtw_debug_impl_mac(page, addr) \ static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ .cb_read = rtw_debug_get_mac_page, \ @@ -796,6 +835,11 @@ static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { .cb_read = rtw_debugfs_get_phy_info, }; +static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { + .cb_write = rtw_debugfs_set_coex_enable, + .cb_read = rtw_debugfs_get_coex_enable, +}; + static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { .cb_read = rtw_debugfs_get_coex_info, }; @@ -831,6 +875,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) rtw_debugfs_add_rw(rsvd_page); rtw_debugfs_add_r(phy_info); rtw_debugfs_add_r(coex_info); + rtw_debugfs_add_rw(coex_enable); rtw_debugfs_add_r(mac_0); rtw_debugfs_add_r(mac_1); rtw_debugfs_add_r(mac_2); -- cgit From a66b8b4108f178f34394681232c7df07e9b0f6be Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 20 Mar 2020 14:38:32 +0800 Subject: rtl8xxxu: add enumeration for channel bandwidth There's a data field in H2C and C2H commands which is used to carry channel bandwidth information. Add enumeration to make it more descriptive in code. Signed-off-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200320063833.1058-2-chiu@endlessm.com --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 9 +++++++++ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index 440d164443bc..bb000dd2c333 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1133,6 +1133,15 @@ enum bt_mp_oper_opcode_8723b { BT_MP_OP_ENABLE_CFO_TRACKING = 0x24, }; +enum rtl8xxxu_bw_mode { + RTL8XXXU_CHANNEL_WIDTH_20 = 0, + RTL8XXXU_CHANNEL_WIDTH_40 = 1, + RTL8XXXU_CHANNEL_WIDTH_80 = 2, + RTL8XXXU_CHANNEL_WIDTH_160 = 3, + RTL8XXXU_CHANNEL_WIDTH_80_80 = 4, + RTL8XXXU_CHANNEL_WIDTH_MAX = 5, +}; + struct rtl8723bu_c2h { u8 id; u8 seq; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index daa6ce14c68b..c334418cd7ae 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4328,7 +4328,7 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, u8 rateid, int sgi) { struct h2c_cmd h2c; - u8 bw = 0; + u8 bw = RTL8XXXU_CHANNEL_WIDTH_20; memset(&h2c, 0, sizeof(struct h2c_cmd)); -- cgit From 0985d3a410ace005ce62666b67c9372dfc14bd7f Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 20 Mar 2020 14:38:33 +0800 Subject: rtl8xxxu: Feed current txrate information for mac80211 The nl80211 commands such as 'iw link' can't get current txrate information from the driver. This commit fills in the tx rate information from the C2H RA report in the sta_statistics function. Signed-off-by: Chris Chiu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200320063833.1058-3-chiu@endlessm.com --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 12 +++- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 75 +++++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index bb000dd2c333..d6d1be4169e5 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1183,13 +1183,16 @@ struct rtl8723bu_c2h { } __packed bt_info; struct { u8 rate:7; - u8 dummy0_0:1; + u8 sgi:1; u8 macid; u8 ldpc:1; u8 txbf:1; u8 noisy_state:1; u8 dummy2_0:5; u8 dummy3_0; + u8 dummy4_0; + u8 dummy5_0; + u8 bw; } __packed ra_report; }; }; @@ -1269,6 +1272,12 @@ struct rtl8xxxu_btcoex { #define RTL8XXXU_SNR_THRESH_HIGH 50 #define RTL8XXXU_SNR_THRESH_LOW 20 +struct rtl8xxxu_ra_report { + struct rate_info txrate; + u32 bit_rate; + u8 desc_rate; +}; + struct rtl8xxxu_priv { struct ieee80211_hw *hw; struct usb_device *udev; @@ -1384,6 +1393,7 @@ struct rtl8xxxu_priv { struct sk_buff_head c2hcmd_queue; spinlock_t c2hcmd_lock; struct rtl8xxxu_btcoex bt_coex; + struct rtl8xxxu_ra_report ra_report; }; struct rtl8xxxu_rx_urb { diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index c334418cd7ae..19efae462a24 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -5389,6 +5389,35 @@ void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv) } } +static struct ieee80211_rate rtl8xxxu_legacy_ratetable[] = { + {.bitrate = 10, .hw_value = 0x00,}, + {.bitrate = 20, .hw_value = 0x01,}, + {.bitrate = 55, .hw_value = 0x02,}, + {.bitrate = 110, .hw_value = 0x03,}, + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + +static void rtl8xxxu_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) +{ + if (rate <= DESC_RATE_54M) + return; + + if (rate >= DESC_RATE_MCS0 && rate <= DESC_RATE_MCS15) { + if (rate < DESC_RATE_MCS8) + *nss = 1; + else + *nss = 2; + *mcs = rate - DESC_RATE_MCS0; + } +} + static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) { struct rtl8xxxu_priv *priv; @@ -5397,9 +5426,14 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) unsigned long flags; u8 bt_info = 0; struct rtl8xxxu_btcoex *btcoex; + struct rtl8xxxu_ra_report *rarpt; + u8 rate, sgi, bw; + u32 bit_rate; + u8 mcs = 0, nss = 0; priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work); btcoex = &priv->bt_coex; + rarpt = &priv->ra_report; if (priv->rf_paths > 1) goto out; @@ -5422,6 +5456,34 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) } rtl8723bu_handle_bt_info(priv); break; + case C2H_8723B_RA_REPORT: + rarpt->txrate.flags = 0; + rate = c2h->ra_report.rate; + sgi = c2h->ra_report.sgi; + bw = c2h->ra_report.bw; + + if (rate < DESC_RATE_MCS0) { + rarpt->txrate.legacy = + rtl8xxxu_legacy_ratetable[rate].bitrate; + } else { + rtl8xxxu_desc_to_mcsrate(rate, &mcs, &nss); + rarpt->txrate.flags |= RATE_INFO_FLAGS_MCS; + + rarpt->txrate.mcs = mcs; + rarpt->txrate.nss = nss; + + if (sgi) { + rarpt->txrate.flags |= + RATE_INFO_FLAGS_SHORT_GI; + } + + if (bw == RATE_INFO_BW_20) + rarpt->txrate.bw |= RATE_INFO_BW_20; + } + bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate); + rarpt->bit_rate = bit_rate; + rarpt->desc_rate = rate; + break; default: break; } @@ -5465,7 +5527,7 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, case C2H_8723B_RA_REPORT: dev_dbg(dev, "C2H RA RPT: rate %02x, unk %i, macid %02x, noise %i\n", - c2h->ra_report.rate, c2h->ra_report.dummy0_0, + c2h->ra_report.rate, c2h->ra_report.sgi, c2h->ra_report.macid, c2h->ra_report.noisy_state); break; default: @@ -6069,6 +6131,16 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return 0; } +static void +rtl8xxxu_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct station_info *sinfo) +{ + struct rtl8xxxu_priv *priv = hw->priv; + + sinfo->txrate = priv->ra_report.txrate; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +} + static u8 rtl8xxxu_signal_to_snr(int signal) { if (signal < RTL8XXXU_NOISE_FLOOR_MIN) @@ -6371,6 +6443,7 @@ static const struct ieee80211_ops rtl8xxxu_ops = { .sw_scan_complete = rtl8xxxu_sw_scan_complete, .set_key = rtl8xxxu_set_key, .ampdu_action = rtl8xxxu_ampdu_action, + .sta_statistics = rtl8xxxu_sta_statistics, }; static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv, -- cgit From 93a5bfbc7cad8bf3dea81c9bc07761c1226a0860 Mon Sep 17 00:00:00 2001 From: Raveendran Somu Date: Wed, 25 Mar 2020 03:20:24 -0500 Subject: brcmfmac: Fix driver crash on USB control transfer timeout When the control transfer gets timed out, the error status was returned without killing that urb, this leads to using the same urb. This issue causes the kernel crash as the same urb is sumbitted multiple times. The fix is to kill the urb for timeout transfer before returning error Signed-off-by: Raveendran Somu Signed-off-by: Chi-hsien Lin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1585124429-97371-2-git-send-email-chi-hsien.lin@cypress.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 575ed19e9195..10387a7f5d56 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -328,11 +328,12 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) return err; } timeout = brcmf_usb_ioctl_resp_wait(devinfo); - clear_bit(0, &devinfo->ctl_op); if (!timeout) { brcmf_err("Txctl wait timed out\n"); + usb_kill_urb(devinfo->ctl_urb); err = -EIO; } + clear_bit(0, &devinfo->ctl_op); return err; } @@ -358,11 +359,12 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) } timeout = brcmf_usb_ioctl_resp_wait(devinfo); err = devinfo->ctl_urb_status; - clear_bit(0, &devinfo->ctl_op); if (!timeout) { brcmf_err("rxctl wait timed out\n"); + usb_kill_urb(devinfo->ctl_urb); err = -EIO; } + clear_bit(0, &devinfo->ctl_op); if (!err) return devinfo->ctl_urb_actual_length; else -- cgit From 78179869dc3f5c0059bbf5d931a2717f1ad97ecd Mon Sep 17 00:00:00 2001 From: Raveendran Somu Date: Wed, 25 Mar 2020 03:20:25 -0500 Subject: brcmfmac: Fix double freeing in the fmac usb data path When the brcmf_fws_process_skb() fails to get hanger slot for queuing the skb, it tries to free the skb. But the caller brcmf_netdev_start_xmit() of that funciton frees the packet on error return value. This causes the double freeing and which caused the kernel crash. Signed-off-by: Raveendran Somu Signed-off-by: Chi-hsien Lin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1585124429-97371-3-git-send-email-chi-hsien.lin@cypress.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 5e1a11c07551..10022c765354 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -2145,8 +2145,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); brcmf_fws_schedule_deq(fws); } else { - bphy_err(drvr, "drop skb: no hanger slot\n"); - brcmf_txfinalize(ifp, skb, false); + bphy_err(drvr, "no hanger slot available\n"); rc = -ENOMEM; } brcmf_fws_unlock(fws); -- cgit From bd9944918ceb28ede97f715d209e220db5e92c09 Mon Sep 17 00:00:00 2001 From: Raveendran Somu Date: Wed, 25 Mar 2020 03:20:26 -0500 Subject: brcmfmac: fix the incorrect return value in brcmf_inform_single_bss(). The function brcmf_inform_single_bss returns the value as success, even when the length exceeds the maximum value. The fix is to send appropriate code on this error. This issue is observed when Cypress test group reported random fmac crashes when running their tests and the path was identified from the crash logs. With this fix the random failure issue in Cypress test group was resolved. Reviewed-by: Arend van Spriel Signed-off-by: Raveendran Somu Signed-off-by: Chi-hsien Lin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1585124429-97371-4-git-send-email-chi-hsien.lin@cypress.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index a2328d3eee03..2ba165330038 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -2953,7 +2953,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { bphy_err(drvr, "Bss info is larger than buffer. Discarding\n"); - return 0; + return -EINVAL; } if (!bi->ctl_ch) { -- cgit From 2bc50d8828ad7cc52ecd99f50074aa25f957af41 Mon Sep 17 00:00:00 2001 From: Madhan Mohan R Date: Wed, 25 Mar 2020 03:20:27 -0500 Subject: brcmfmac: increase max hanger slots from 1K to 3K in fws layer Will enable FMAC to push more packets to bus tx queue and help improve throughput when fws queuing is enabled. This change is required to tune the throughput for passing WMM CERT tests. Signed-off-by: Madhan Mohan R Signed-off-by: Chi-hsien Lin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1585124429-97371-5-git-send-email-chi-hsien.lin@cypress.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 10022c765354..8cc52935fd41 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -404,7 +404,7 @@ struct brcmf_fws_mac_descriptor { u8 traffic_lastreported_bmp; }; -#define BRCMF_FWS_HANGER_MAXITEMS 1024 +#define BRCMF_FWS_HANGER_MAXITEMS 3072 /** * enum brcmf_fws_hanger_item_state - state of hanger item. -- cgit From 7f1d42304d933c310592c91df70b661965a36121 Mon Sep 17 00:00:00 2001 From: Wright Feng Date: Wed, 25 Mar 2020 03:20:28 -0500 Subject: brcmfmac: add USB autosuspend feature support We add enable dynamic suspend (autosuspend) support in host driver, and it can let platform cut down idle power consumption. To support autosuspend feature in host driver, kernel need to be built with CONFIG_USB_SUSPEND and autosuspend need to be turn on. And we also replace wowl feature with adding "needs_remote_wakeup", so that host still can be waken by wireless device. Signed-off-by: Wright Feng Signed-off-by: Chi-Hsien Lin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1585124429-97371-6-git-send-email-chi-hsien.lin@cypress.com --- .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 121 ++++++++++++--------- 1 file changed, 71 insertions(+), 50 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 10387a7f5d56..ac5463838fcf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -164,7 +164,6 @@ struct brcmf_usbdev_info { struct urb *bulk_urb; /* used for FW download */ - bool wowl_enabled; struct brcmf_mp_device *settings; }; @@ -312,28 +311,43 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) int err = 0; int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + struct usb_interface *intf = to_usb_interface(dev); brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) - return -EIO; - if (test_and_set_bit(0, &devinfo->ctl_op)) - return -EIO; + err = usb_autopm_get_interface(intf); + if (err) + goto out; + + if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { + err = -EIO; + goto fail; + } + + if (test_and_set_bit(0, &devinfo->ctl_op)) { + err = -EIO; + goto fail; + } devinfo->ctl_completed = false; err = brcmf_usb_send_ctl(devinfo, buf, len); if (err) { brcmf_err("fail %d bytes: %d\n", err, len); clear_bit(0, &devinfo->ctl_op); - return err; + goto fail; } timeout = brcmf_usb_ioctl_resp_wait(devinfo); if (!timeout) { brcmf_err("Txctl wait timed out\n"); usb_kill_urb(devinfo->ctl_urb); err = -EIO; + goto fail; } clear_bit(0, &devinfo->ctl_op); + +fail: + usb_autopm_put_interface(intf); +out: return err; } @@ -342,20 +356,30 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) int err = 0; int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + struct usb_interface *intf = to_usb_interface(dev); brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) - return -EIO; - if (test_and_set_bit(0, &devinfo->ctl_op)) - return -EIO; + err = usb_autopm_get_interface(intf); + if (err) + goto out; + + if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { + err = -EIO; + goto fail; + } + + if (test_and_set_bit(0, &devinfo->ctl_op)) { + err = -EIO; + goto fail; + } devinfo->ctl_completed = false; err = brcmf_usb_recv_ctl(devinfo, buf, len); if (err) { brcmf_err("fail %d bytes: %d\n", err, len); clear_bit(0, &devinfo->ctl_op); - return err; + goto fail; } timeout = brcmf_usb_ioctl_resp_wait(devinfo); err = devinfo->ctl_urb_status; @@ -363,12 +387,15 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) brcmf_err("rxctl wait timed out\n"); usb_kill_urb(devinfo->ctl_urb); err = -EIO; + goto fail; } clear_bit(0, &devinfo->ctl_op); +fail: + usb_autopm_put_interface(intf); if (!err) return devinfo->ctl_urb_actual_length; - else - return err; +out: + return err; } static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo, @@ -502,10 +529,12 @@ static void brcmf_usb_rx_complete(struct urb *urb) return; } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { + if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP || + devinfo->bus_pub.state == BRCMFMAC_USB_STATE_SLEEP) { skb_put(skb, urb->actual_length); brcmf_rx_frame(devinfo->dev, skb, true); brcmf_usb_rx_refill(devinfo, req); + usb_mark_last_busy(urb->dev); } else { brcmu_pkt_buf_free_skb(skb); brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); @@ -589,6 +618,11 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) struct brcmf_usbreq *req; int ret; unsigned long flags; + struct usb_interface *intf = to_usb_interface(dev); + + ret = usb_autopm_get_interface(intf); + if (ret) + goto out; brcmf_dbg(USB, "Enter, skb=%p\n", skb); if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { @@ -627,9 +661,10 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) devinfo->tx_flowblock = true; } spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags); - return 0; fail: + usb_autopm_put_interface(intf); +out: return ret; } @@ -993,20 +1028,32 @@ static int brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) { int err; + struct usb_interface *intf; brcmf_dbg(USB, "Enter\n"); - if (devinfo == NULL) - return -ENODEV; + if (!devinfo) { + err = -ENODEV; + goto out; + } if (!devinfo->image) { brcmf_err("No firmware!\n"); - return -ENOENT; + err = -ENOENT; + goto out; } + intf = to_usb_interface(devinfo->dev); + err = usb_autopm_get_interface(intf); + if (err) + goto out; + err = brcmf_usb_dlstart(devinfo, (u8 *)devinfo->image, devinfo->image_len); if (err == 0) err = brcmf_usb_dlrun(devinfo); + + usb_autopm_put_interface(intf); +out: return err; } @@ -1107,18 +1154,6 @@ error: return NULL; } -static void brcmf_usb_wowl_config(struct device *dev, bool enabled) -{ - struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - - brcmf_dbg(USB, "Configuring WOWL, enabled=%d\n", enabled); - devinfo->wowl_enabled = enabled; - if (enabled) - device_set_wakeup_enable(devinfo->dev, true); - else - device_set_wakeup_enable(devinfo->dev, false); -} - static int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name) { @@ -1145,7 +1180,6 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = { .txdata = brcmf_usb_tx, .txctl = brcmf_usb_tx_ctlpkt, .rxctl = brcmf_usb_rx_ctlpkt, - .wowl_config = brcmf_usb_wowl_config, .get_fwname = brcmf_usb_get_fwname, }; @@ -1334,6 +1368,8 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_set_intfdata(intf, devinfo); + intf->needs_remote_wakeup = 1; + /* Check that the device supports only one configuration */ if (usb->descriptor.bNumConfigurations != 1) { brcmf_err("Number of configurations: %d not supported\n", @@ -1447,12 +1483,8 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) brcmf_dbg(USB, "Enter\n"); devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; - if (devinfo->wowl_enabled) { - brcmf_cancel_all_urbs(devinfo); - } else { - brcmf_detach(&usb->dev); - brcmf_free(&usb->dev); - } + brcmf_cancel_all_urbs(devinfo); + device_set_wakeup_enable(devinfo->dev, true); return 0; } @@ -1465,22 +1497,10 @@ static int brcmf_usb_resume(struct usb_interface *intf) struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); brcmf_dbg(USB, "Enter\n"); - if (!devinfo->wowl_enabled) { - int err; - - err = brcmf_alloc(&usb->dev, devinfo->settings); - if (err) - return err; - - err = brcmf_attach(devinfo->dev); - if (err) { - brcmf_free(devinfo->dev); - return err; - } - } devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; brcmf_usb_rx_fill_all(devinfo); + device_set_wakeup_enable(devinfo->dev, false); return 0; } @@ -1537,6 +1557,7 @@ static struct usb_driver brcmf_usbdrvr = { .suspend = brcmf_usb_suspend, .resume = brcmf_usb_resume, .reset_resume = brcmf_usb_reset_resume, + .supports_autosuspend = true, .disable_hub_initiated_lpm = 1, }; -- cgit From 2542469d1258b2b2f2849ce1f4df88e86a761f7c Mon Sep 17 00:00:00 2001 From: Tzu-En Huang Date: Thu, 26 Mar 2020 10:04:08 +0800 Subject: rtw88: fix non-increase management packet sequence number In previous setting, management packets' sequence numbers will not increase and always stay at 0. Add hw sequence number support for mgmt packets. The table below shows different sequence number setting in the tx descriptor. seq num ctrl | EN_HWSEQ | DISQSELSEL | HW_SSN_SEL ------------------------------------------------------ sw ctrl | 0 | N/A | N/A hw ctrl per MACID | 1 | 0 | N/A hw ctrl per HWREG | 1 | 1 |HWREG(0/1/2/3) Signed-off-by: Tzu-En Huang Signed-off-by: Yan-Hsuan Chuang Reviewed-by: Brian Norris Tested-by: Brian Norris Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200326020408.25218-1-yhchuang@realtek.com --- drivers/net/wireless/realtek/rtw88/main.h | 3 +++ drivers/net/wireless/realtek/rtw88/tx.c | 6 ++++++ drivers/net/wireless/realtek/rtw88/tx.h | 6 ++++++ 3 files changed, 15 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index bcc07cf9f481..c6b590fdb573 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -574,6 +574,9 @@ struct rtw_tx_pkt_info { bool short_gi; bool report; bool rts; + bool dis_qselseq; + bool en_hwseq; + u8 hw_ssn_sel; }; struct rtw_rx_pkt_stat { diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index b31eb4d9664b..60989987f67b 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -58,6 +58,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); + SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); + SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); } EXPORT_SYMBOL(rtw_tx_fill_tx_desc); @@ -227,6 +230,9 @@ static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev, pkt_info->use_rate = true; pkt_info->rate_id = 6; pkt_info->dis_rate_fallback = true; + pkt_info->dis_qselseq = true; + pkt_info->en_hwseq = true; + pkt_info->hw_ssn_sel = 0; } static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h index e488a2643eb3..b973de0f4dc0 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.h +++ b/drivers/net/wireless/realtek/rtw88/tx.h @@ -53,6 +53,12 @@ le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) #define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) enum rtw_tx_desc_queue_select { TX_DESC_QSEL_TID0 = 0, -- cgit From 3af4da165f487a3956fe5a7b4ee08b12c7a3a9af Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 26 Mar 2020 11:24:32 +0800 Subject: hostap: convert to struct proc_ops commit 97a32539b956 ("proc: convert everything to "struct proc_ops"") forget do this convering for prism2_download_aux_dump_proc_fops. Fixes: 97a32539b956 ("proc: convert everything to "struct proc_ops"") Signed-off-by: YueHaibing Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200326032432.20384-1-yuehaibing@huawei.com --- drivers/net/wireless/intersil/hostap/hostap_download.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intersil/hostap/hostap_download.c b/drivers/net/wireless/intersil/hostap/hostap_download.c index 8722000b6c27..7c6a5a6d1d45 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_download.c +++ b/drivers/net/wireless/intersil/hostap/hostap_download.c @@ -232,11 +232,11 @@ static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file * return ret; } -static const struct file_operations prism2_download_aux_dump_proc_fops = { - .open = prism2_download_aux_dump_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, +static const struct proc_ops prism2_download_aux_dump_proc_ops = { + .proc_open = prism2_download_aux_dump_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release_private, }; -- cgit From cceb45078a62cda3ebdb97bd96916c3f8d811e7c Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 20 Sep 2016 17:48:25 +0300 Subject: iwlwifi: mvm: add soc latency support Some devices require longer time to stabilize the power and XTAL. This is especially true for devices integrated in the SoC. Add support for a new firmware API that allows the driver to set the latency value accordingly. Change-Id: I6829a46b89e4e701f80a0e4033f4dd41ee44ed12 Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/commands.h | 9 ++- drivers/net/wireless/intel/iwlwifi/fw/api/soc.h | 83 ++++++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 11 ++- drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 32 +++++++-- 5 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/soc.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index 22dff2c92d4f..4f46f3ed8794 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -5,9 +5,9 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2012 - 2014, 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -27,9 +27,9 @@ * * BSD LICENSE * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2012 - 2014, 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -646,6 +646,11 @@ enum iwl_system_subcmd_ids { */ SHARED_MEM_CFG_CMD = 0x0, + /** + * @SOC_CONFIGURATION_CMD: &struct iwl_soc_configuration_cmd + */ + SOC_CONFIGURATION_CMD = 0x01, + /** * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h new file mode 100644 index 000000000000..5d1fb98fe667 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h @@ -0,0 +1,83 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH + * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH + * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#ifndef __iwl_fw_api_soc_h__ +#define __iwl_fw_api_soc_h__ + +/* type of devices for defining SOC latency */ +enum iwl_soc_device_types { + SOC_CONFIG_CMD_INTEGRATED = 0x0, + SOC_CONFIG_CMD_DISCRETE = 0x1, +}; + +/** + * struct iwl_soc_configuration_cmd - Set device stabilization latency + * + * @device_type: the device type as defined in &enum iwl_soc_device_types + * @soc_latency: time for SOC to ensure stable power & XTAL + */ +struct iwl_soc_configuration_cmd { + __le32 device_type; + __le32 soc_latency; +} __packed; /* SOC_CONFIGURATION_CMD_S_VER_1 */ + +#endif /* __iwl_fw_api_soc_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 1554f5fdd483..35f42e529a6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -5,11 +5,9 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation - * Copyright(c) 2019 Intel Corporation + * Copyright(c) 2008 - 2014, 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -29,11 +27,9 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation - * Copyright(c) 2019 Intel Corporation + * Copyright(c) 2008 - 2014, 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -369,6 +365,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * is supported. * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC * @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan (no longer used) + * @IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT: the firmware supports setting + * stabilization latency for SoCs. * @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm * @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related @@ -437,6 +435,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31, /* set 1 */ + IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT = (__force iwl_ucode_tlv_capa_t)37, IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38, IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39, IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index e3eb812e0248..05a06f88db6c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -73,6 +73,7 @@ #include "fw/api/datapath.h" #include "fw/api/phy.h" #include "fw/api/config.h" +#include "fw/api/soc.h" #include "fw/api/alive.h" #include "fw/api/binding.h" #include "fw/api/cmdhdr.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 54c094e88474..1b3a2f52e13f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -5,10 +5,9 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -28,10 +27,9 @@ * * BSD LICENSE * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,6 +87,25 @@ struct iwl_mvm_alive_data { u32 scd_base_addr; }; +/* set device type and latency */ +static int iwl_set_soc_latency(struct iwl_mvm *mvm) +{ + struct iwl_soc_configuration_cmd cmd; + int ret; + + cmd.device_type = (mvm->trans->cfg->integrated) ? + cpu_to_le32(SOC_CONFIG_CMD_INTEGRATED) : + cpu_to_le32(SOC_CONFIG_CMD_DISCRETE); + cmd.soc_latency = cpu_to_le32(mvm->trans->cfg->soc_latency); + + ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SOC_CONFIGURATION_CMD, + SYSTEM_GROUP, 0), 0, + sizeof(cmd), &cmd); + if (ret) + IWL_ERR(mvm, "Failed to set soc latency: %d\n", ret); + return ret; +} + static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant) { struct iwl_tx_ant_cfg_cmd tx_ant_cmd = { @@ -1103,6 +1120,13 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; + if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT)) { + ret = iwl_set_soc_latency(mvm); + if (ret) + goto error; + } + /* Init RSS configuration */ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { ret = iwl_configure_rxq(mvm); -- cgit From f696a7ee254f7e4e96bd1a21addd1315169b8a8a Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 1 Nov 2019 15:31:02 +0200 Subject: iwlwifi: yoyo: add PCI config space region type Add a new region type that allows us to dump the PCI config space. This is mostly the same as dumping a memory region, but reading from the device's config space instead. In order to make this generic and independent of the trans type, we make a function called iwl_dump_ini_config_iter() that calls a new op in the transport to read its config space. Change-Id: I15151bddf589f13b0e0a45c28b96bbcd73bcfdeb Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 39 +++++++++++++++++++++++- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 6 ++++ drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 3 ++ 3 files changed, 47 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 91df1ee25dd0..d5dda93c3953 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1108,6 +1108,38 @@ static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } +static int iwl_dump_ini_config_iter(struct iwl_fw_runtime *fwrt, + struct iwl_dump_ini_region_data *reg_data, + void *range_ptr, int idx) +{ + struct iwl_trans *trans = fwrt->trans; + struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data; + struct iwl_fw_ini_error_dump_range *range = range_ptr; + __le32 *val = range->data; + u32 addr = le32_to_cpu(reg->addrs[idx]) + + le32_to_cpu(reg->dev_addr.offset); + int i; + + /* we shouldn't get here if the trans doesn't have read_config32 */ + if (WARN_ON_ONCE(!trans->ops->read_config32)) + return -EOPNOTSUPP; + + range->internal_base_addr = cpu_to_le32(addr); + range->range_data_size = reg->dev_addr.size; + for (i = 0; i < le32_to_cpu(reg->dev_addr.size); i += 4) { + int ret; + u32 tmp; + + ret = trans->ops->read_config32(trans, addr + i, &tmp); + if (ret < 0) + return ret; + + *val++ = cpu_to_le32(tmp); + } + + return sizeof(*range) + le32_to_cpu(range->range_data_size); +} + static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_region_data *reg_data, void *range_ptr, int idx) @@ -2052,7 +2084,12 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = { .fill_range = iwl_dump_ini_csr_iter, }, [IWL_FW_INI_REGION_DRAM_IMR] = {}, - [IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = {}, + [IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_config_iter, + }, }; static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 4208e720f6e6..bf2f00b89214 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -236,6 +236,12 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans, return -EINVAL; } + if (type == IWL_FW_INI_REGION_PCI_IOSF_CONFIG && + !trans->ops->read_config32) { + IWL_ERR(trans, "WRT: Unsupported region type %u\n", type); + return -EOPNOTSUPP; + } + active_reg = &trans->dbg.active_regions[id]; if (*active_reg) { IWL_WARN(trans, "WRT: Overriding region id %u\n", id); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 7b3b1f4c99b4..bba527b339b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -544,6 +544,8 @@ struct iwl_trans_rxq_dma_data { * @read_mem: read device's SRAM in DWORD * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory * will be zeroed. + * @read_config32: read a u32 value from the device's config space at + * the given offset. * @configure: configure parameters required by the transport layer from * the op_mode. May be called several times before start_fw, can't be * called after that. @@ -614,6 +616,7 @@ struct iwl_trans_ops { void *buf, int dwords); int (*write_mem)(struct iwl_trans *trans, u32 addr, const void *buf, int dwords); + int (*read_config32)(struct iwl_trans *trans, u32 ofs, u32 *val); void (*configure)(struct iwl_trans *trans, const struct iwl_trans_config *trans_cfg); void (*set_pmi)(struct iwl_trans *trans, bool state); -- cgit From 7f1fe1d49043f43d4ab6fa928da9004e76d81210 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 1 Nov 2019 16:13:33 +0200 Subject: iwlwifi: pcie: implement read_config32 Add the read_config32 op to allow dumping the config space when needed. Change-Id: Ib2d254a38a4bfb95dcc3d04eec91781827a0c623 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 38d8fe21690a..46832bbfcae7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2206,6 +2206,13 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, return ret; } +static int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs, + u32 *val) +{ + return pci_read_config_dword(IWL_TRANS_GET_PCIE_TRANS(trans)->pci_dev, + ofs, val); +} + static void iwl_trans_pcie_freeze_txq_timer(struct iwl_trans *trans, unsigned long txqs, bool freeze) @@ -3380,6 +3387,7 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans) .write_prph = iwl_trans_pcie_write_prph, \ .read_mem = iwl_trans_pcie_read_mem, \ .write_mem = iwl_trans_pcie_write_mem, \ + .read_config32 = iwl_trans_pcie_read_config32, \ .configure = iwl_trans_pcie_configure, \ .set_pmi = iwl_trans_pcie_set_pmi, \ .sw_reset = iwl_trans_pcie_sw_reset, \ -- cgit From df65890856645542a56748df7fb76b9e500b44f6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Nov 2019 12:22:06 +0100 Subject: iwlwifi: pass trans and NVM data to HE capability parsing We'll need this data in the future, pass the values. Change-Id: Iaeff50716e783f5c0bcea86ca1c93ada1560525e Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index bab0999f002c..9e9810d2b262 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -684,7 +684,9 @@ static struct ieee80211_sband_iftype_data iwl_he_capa[] = { }, }; -static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband, +static void iwl_init_he_hw_capab(struct iwl_trans *trans, + struct iwl_nvm_data *data, + struct ieee80211_supported_band *sband, u8 tx_chains, u8 rx_chains) { sband->iftype_data = iwl_he_capa; @@ -728,7 +730,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, tx_chains, rx_chains); if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax) - iwl_init_he_hw_capab(sband, tx_chains, rx_chains); + iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains); sband = &data->bands[NL80211_BAND_5GHZ]; sband->band = NL80211_BAND_5GHZ; @@ -743,7 +745,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, tx_chains, rx_chains); if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax) - iwl_init_he_hw_capab(sband, tx_chains, rx_chains); + iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains); if (n_channels != n_used) IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", -- cgit From 453f26822844bf08991616b9d5def122deba8514 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 29 Sep 2019 12:48:42 +0300 Subject: iwlwifi: scan: support scan req cmd ver 14 Modify adaptive dwell number of APs override API Instead of using channel to index mapping, add the adaptive dwell override parameters as part of the configuration per channel in the scan request command. Support 2 different override values and use them as follows: 1. 10 APs for friendly GO channels in p2p scan. 2. 2 APs for social channels in p2p scan. Change-Id: I3b461108abf2306c3d054099112f2c3afce1cc92 Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 52 ++++++++- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 129 +++++++++++++++++++++-- 2 files changed, 173 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 1b2b5fa56e19..2e70e4e752e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -702,13 +702,16 @@ struct iwl_scan_channel_cfg_umac { u8 channel_num; u8 iter_count; __le16 iter_interval; - } v1; /* SCAN_CHANNEL_CFG_S_VER1 */ + } v1; /* SCAN_CHANNEL_CONFIG_API_S_VER_1 */ struct { u8 channel_num; u8 band; u8 iter_count; u8 iter_interval; - } v2; /* SCAN_CHANNEL_CFG_S_VER2 */ + } v2; /* SCAN_CHANNEL_CONFIG_API_S_VER_2 + * SCAN_CHANNEL_CONFIG_API_S_VER_3 + * SCAN_CHANNEL_CONFIG_API_S_VER_4 + */ }; } __packed; @@ -943,6 +946,25 @@ struct iwl_scan_channel_params_v4 { u8 adwell_ch_override_bitmap[16]; } __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_4 also SCAN_CHANNEL_PARAMS_API_S_VER_5 */ + +/** + * struct iwl_scan_channel_params_v6 + * @flags: channel flags &enum iwl_scan_channel_flags + * @count: num of channels in scan request + * @n_aps_override: override the number of APs the FW uses to calculate dwell + * time when adaptive dwell is used. + * Channel k will use n_aps_override[i] when BIT(20 + i) is set in + * channel_config[k].flags + * @channel_config: array of explicit channel configurations + * for 2.4Ghz and 5.2Ghz bands + */ +struct iwl_scan_channel_params_v6 { + u8 flags; + u8 count; + u8 n_aps_override[2]; + struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3]; +} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */ + /** * struct iwl_scan_general_params_v10 * @flags: &enum iwl_umac_scan_flags @@ -1023,6 +1045,20 @@ struct iwl_scan_req_params_v13 { struct iwl_scan_probe_params_v4 probe_params; } __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_13 */ +/** + * struct iwl_scan_req_params_v14 + * @general_params: &struct iwl_scan_general_params_v10 + * @channel_params: &struct iwl_scan_channel_params_v6 + * @periodic_params: &struct iwl_scan_periodic_parms_v1 + * @probe_params: &struct iwl_scan_probe_params_v4 + */ +struct iwl_scan_req_params_v14 { + struct iwl_scan_general_params_v10 general_params; + struct iwl_scan_channel_params_v6 channel_params; + struct iwl_scan_periodic_parms_v1 periodic_params; + struct iwl_scan_probe_params_v4 probe_params; +} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_14 */ + /** * struct iwl_scan_req_umac_v12 * @uid: scan id, &enum iwl_umac_scan_uid_offsets @@ -1047,6 +1083,18 @@ struct iwl_scan_req_umac_v13 { struct iwl_scan_req_params_v13 scan_params; } __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_13 */ +/** + * struct iwl_scan_req_umac_v14 + * @uid: scan id, &enum iwl_umac_scan_uid_offsets + * @ooc_priority: out of channel priority - &enum iwl_scan_priority + * @scan_params: scan parameters + */ +struct iwl_scan_req_umac_v14 { + __le32 uid; + __le32 ooc_priority; + struct iwl_scan_req_params_v14 scan_params; +} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_14 */ + /** * struct iwl_umac_scan_abort * @uid: scan id, &enum iwl_umac_scan_uid_offsets diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 3b263c81bcae..1fa74086a4f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -91,8 +91,14 @@ #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10 /* number of scan channels */ #define IWL_SCAN_NUM_CHANNELS 112 -/* adaptive dwell default number of APs override */ -#define IWL_SCAN_ADWELL_DEFAULT_N_APS_OVERRIDE 10 +/* adaptive dwell number of APs override mask for p2p friendly GO */ +#define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT BIT(20) +/* adaptive dwell number of APs override mask for social channels */ +#define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT BIT(21) +/* adaptive dwell number of APs override for p2p friendly GO channels */ +#define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY 10 +/* adaptive dwell number of APs override for social channels */ +#define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2 struct iwl_mvm_scan_timing_params { u32 suspend_time; @@ -1529,14 +1535,19 @@ static int iwl_mvm_scan_ch_and_band_to_idx(u8 channel_id, u8 band) return -EINVAL; } +static const u8 p2p_go_friendly_chs[] = { + 36, 40, 44, 48, 149, 153, 157, 161, 165, +}; + +static const u8 social_chs[] = { + 1, 6, 11 +}; + static void iwl_mvm_scan_ch_add_n_aps_override(enum nl80211_iftype vif_type, u8 ch_id, u8 band, u8 *ch_bitmap, size_t bitmap_n_entries) { int i; - static const u8 p2p_go_friendly_chs[] = { - 36, 40, 44, 48, 149, 153, 157, 161, 165, - }; if (vif_type != NL80211_IFTYPE_P2P_DEVICE) return; @@ -1561,6 +1572,35 @@ static void iwl_mvm_scan_ch_add_n_aps_override(enum nl80211_iftype vif_type, } } +static u32 iwl_mvm_scan_ch_n_aps_flag(enum nl80211_iftype vif_type, u8 ch_id) +{ + int i; + u32 flags = 0; + + if (vif_type != NL80211_IFTYPE_P2P_DEVICE) + goto out; + + for (i = 0; i < ARRAY_SIZE(p2p_go_friendly_chs); i++) { + if (p2p_go_friendly_chs[i] == ch_id) { + flags |= IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT; + break; + } + } + + if (flags) + goto out; + + for (i = 0; i < ARRAY_SIZE(social_chs); i++) { + if (social_chs[i] == ch_id) { + flags |= IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT; + break; + } + } + +out: + return flags; +} + static void iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm, struct ieee80211_channel **channels, @@ -1615,6 +1655,30 @@ iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm *mvm, } } +static void +iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm, + struct ieee80211_channel **channels, + struct iwl_scan_channel_params_v6 *cp, + int n_channels, u32 flags, + enum nl80211_iftype vif_type) +{ + int i; + + for (i = 0; i < n_channels; i++) { + enum nl80211_band band = channels[i]->band; + struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i]; + u32 n_aps_flag = + iwl_mvm_scan_ch_n_aps_flag(vif_type, + cfg->v2.channel_num); + + cfg->flags = cpu_to_le32(flags | n_aps_flag); + cfg->v2.channel_num = channels[i]->hw_value; + cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band); + cfg->v2.iter_count = 1; + cfg->v2.iter_interval = 0; + } +} + static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm, struct iwl_mvm_scan_params *params, struct ieee80211_vif *vif) @@ -1915,7 +1979,7 @@ iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm, { cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif); cp->count = params->n_channels; - cp->num_of_aps_override = IWL_SCAN_ADWELL_DEFAULT_N_APS_OVERRIDE; + cp->num_of_aps_override = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY; iwl_mvm_umac_scan_cfg_channels_v4(mvm, params->channels, cp, params->n_channels, @@ -1923,6 +1987,23 @@ iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm, vif->type); } +static void +iwl_mvm_scan_umac_fill_ch_p_v6(struct iwl_mvm *mvm, + struct iwl_mvm_scan_params *params, + struct ieee80211_vif *vif, + struct iwl_scan_channel_params_v6 *cp, + u32 channel_cfg_flags) +{ + cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif); + cp->count = params->n_channels; + cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY; + cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS; + + iwl_mvm_umac_scan_cfg_channels_v6(mvm, params->channels, cp, + params->n_channels, + channel_cfg_flags, + vif->type); +} static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_scan_params *params, int type, @@ -1990,6 +2071,40 @@ static int iwl_mvm_scan_umac_v13(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return 0; } +static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct iwl_mvm_scan_params *params, int type, + int uid) +{ + struct iwl_scan_req_umac_v14 *cmd = mvm->scan_cmd; + struct iwl_scan_req_params_v14 *scan_p = &cmd->scan_params; + int ret; + u16 gen_flags; + u32 bitmap_ssid = 0; + + mvm->scan_uid_status[uid] = type; + + cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params)); + cmd->uid = cpu_to_le32(uid); + + gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type); + iwl_mvm_scan_umac_fill_general_p_v10(mvm, params, vif, + &scan_p->general_params, + gen_flags); + + ret = iwl_mvm_fill_scan_sched_params(params, + scan_p->periodic_params.schedule, + &scan_p->periodic_params.delay); + if (ret) + return ret; + + iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params, + &bitmap_ssid); + iwl_mvm_scan_umac_fill_ch_p_v6(mvm, params, vif, + &scan_p->channel_params, bitmap_ssid); + + return 0; +} + static int iwl_mvm_num_scans(struct iwl_mvm *mvm) { return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK); @@ -2105,6 +2220,7 @@ struct iwl_scan_umac_handler { static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = { /* set the newest version first to shorten the list traverse time */ + IWL_SCAN_UMAC_HANDLER(14), IWL_SCAN_UMAC_HANDLER(13), IWL_SCAN_UMAC_HANDLER(12), }; @@ -2463,6 +2579,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type) static int iwl_scan_req_umac_get_size(u8 scan_ver) { switch (scan_ver) { + IWL_SCAN_REQ_UMAC_HANDLE_SIZE(14); IWL_SCAN_REQ_UMAC_HANDLE_SIZE(13); IWL_SCAN_REQ_UMAC_HANDLE_SIZE(12); } -- cgit From 9124061ad9e7fdac9b957e69b7a2b735fcf1a327 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Nov 2019 11:50:55 +0100 Subject: iwlwifi: mvm: rs-fw: fix some indentation That closing brace for the switch statement is misplaced, fix it. Change-Id: I39af135a9e3fc64337d2cced43a70cb48fe3b9c1 Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index e2cf9e015ef8..d6e144fbb941 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -399,8 +399,7 @@ u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) return IEEE80211_MAX_MPDU_LEN_VHT_7991; default: return IEEE80211_MAX_MPDU_LEN_VHT_3895; - } - + } } else if (ht_cap->ht_supported) { if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU) /* -- cgit From 1454edcad7180e7e4caeb3eb47239c13c407b4a8 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 11:53:41 +0200 Subject: iwlwifi: remove redundant iwl9560_2ac_cfg struct The iwl9560_2ac_cfg struct is used for PNJ devices and the configuration is the same as iwl9260_2ac_cfg, so we can remove the former to avoid redundancy. Change-Id: I17ac1802f00bd80006930b922a9fc21df60e3c16 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 12 ++++++------ 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index d02936a8e11d..cb2604b01a99 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -200,11 +200,6 @@ const char iwl9560_killer_1550i_name[] = const char iwl9560_killer_1550s_name[] = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)"; -const struct iwl_cfg iwl9560_2ac_cfg = { - .fw_name_pre = IWL9260_FW_PRE, - IWL_DEVICE_9000, -}; - const struct iwl_cfg iwl9560_2ac_cfg_soc = { .fw_name_pre = IWL9000_FW_PRE, IWL_DEVICE_9000, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 5413e80f86bb..5f10dba12c8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -885,28 +885,28 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9461_160_name), + iwl9260_2ac_cfg, iwl9461_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9461_name), + iwl9260_2ac_cfg, iwl9461_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9462_160_name), + iwl9260_2ac_cfg, iwl9462_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9462_name), + iwl9260_2ac_cfg, iwl9462_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9560_160_name), + iwl9260_2ac_cfg, iwl9560_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg, iwl9560_name), + iwl9260_2ac_cfg, iwl9560_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, -- cgit From 85ea9833995aaee2fd0b1753b9f45e998999bf35 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Nov 2019 12:04:45 +0100 Subject: iwlwifi: mvm: enable SF also when we have HE We shouldn't do this just for HT/VHT, but be future-proof and also check for HE. Change-Id: Icaeff714c00a773681dbfee72558afd1c7121c5d Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c index 9da0dae78510..368b9d117f73 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c @@ -7,7 +7,7 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018-2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -29,7 +29,7 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018-2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -162,7 +162,9 @@ static void iwl_mvm_fill_sf_command(struct iwl_mvm *mvm, * capabilities of the AP station, and choose the watermark accordingly. */ if (sta) { - if (sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) { + if (sta->ht_cap.ht_supported || + sta->vht_cap.vht_supported || + sta->he_cap.has_he) { switch (sta->rx_nss) { case 1: watermark = SF_W_MARK_SISO; -- cgit From 7897dfa2bc8fdfd47e95f94375e7af88d465d71a Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 12:31:22 +0200 Subject: iwlwifi: move integrated, extra_phy and soc_latency to trans_cfg These values are selected based on the PCI device ID, so the decision to use them can be made early. By moving them to the trans_cfg, we avoid duplicating the large cfg structs for small pieces of data (sometimes a single boolean). This will also allow us to make more decisions based on, for instance, the SoC type in used. The trans_cfg concept changes a bit, because previously it was used only to boot the device before reading further characteristics and now it also contains more data that is associated with the device ID. Change-Id: Ib71b07ea9e322eb74571dc5e8aa58f17eece5c9c Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 24 +++++++------- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 31 +++++++++++------- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 21 +++++++------ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 7 +++-- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 42 +++++-------------------- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 7 files changed, 58 insertions(+), 71 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 53568bbcf214..bfabe0ed4ee8 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -464,8 +464,8 @@ const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; @@ -479,8 +479,8 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; @@ -494,8 +494,8 @@ const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; @@ -509,8 +509,8 @@ const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; @@ -524,8 +524,8 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; @@ -539,8 +539,8 @@ const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .integrated = true, - .soc_latency = 5000, + .trans.integrated = true, + .trans.xtal_latency = 5000, .num_rbds = IWL_NUM_RBDS_NON_HE, }; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index cb2604b01a99..f84b8e5d3f0b 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -174,9 +174,23 @@ const struct iwl_cfg_trans_params iwl9000_trans_cfg = { .rf_id = true, }; -const struct iwl_cfg iwl9260_2ac_cfg = { - .fw_name_pre = IWL9260_FW_PRE, - IWL_DEVICE_9000, +const struct iwl_cfg_trans_params iwl9560_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_9000, + .base_params = &iwl9000_base_params, + .mq_rx_supported = true, + .rf_id = true, + .integrated = true, + .xtal_latency = 5000, +}; + +const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_9000, + .base_params = &iwl9000_base_params, + .mq_rx_supported = true, + .rf_id = true, + .integrated = true, + .xtal_latency = 5000, + .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK }; const char iwl9162_name[] = "Intel(R) Wireless-AC 9162"; @@ -200,19 +214,14 @@ const char iwl9560_killer_1550i_name[] = const char iwl9560_killer_1550s_name[] = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)"; -const struct iwl_cfg iwl9560_2ac_cfg_soc = { - .fw_name_pre = IWL9000_FW_PRE, +const struct iwl_cfg iwl9260_2ac_cfg = { + .fw_name_pre = IWL9260_FW_PRE, IWL_DEVICE_9000, - .integrated = true, - .soc_latency = 5000, }; -const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = { +const struct iwl_cfg iwl9560_2ac_cfg_soc = { .fw_name_pre = IWL9000_FW_PRE, IWL_DEVICE_9000, - .integrated = true, - .soc_latency = 5000, - .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK }; MODULE_FIRMWARE(IWL9000_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index dc32ccf95be5..2e9a85a9ee67 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -287,27 +287,34 @@ struct iwl_pwr_tx_backoff { /** * struct iwl_cfg_trans - information needed to start the trans * - * These values cannot be changed when multiple configs are used for a - * single PCI ID, because they are needed before the HW REV or RFID - * can be read. + * These values are specific to the device ID and do not change when + * multiple configs are used for a single device ID. They values are + * used, among other things, to boot the NIC so that the HW REV or + * RFID can be read before deciding the remaining parameters to use. * * @base_params: pointer to basic parameters * @csr: csr flags and addresses that are different across devices * @device_family: the device family * @umac_prph_offset: offset to add to UMAC periphery address + * @xtal_latency: power up latency to get the xtal stabilized + * @extra_phy_cfg_flags: extra configuration flags to pass to the PHY * @rf_id: need to read rf_id to determine the firmware image * @use_tfh: use TFH * @gen2: 22000 and on transport operation * @mq_rx_supported: multi-queue rx support + * @integrated: discrete or integrated */ struct iwl_cfg_trans_params { const struct iwl_base_params *base_params; enum iwl_device_family device_family; u32 umac_prph_offset; + u32 xtal_latency; + u32 extra_phy_cfg_flags; u32 rf_id:1, use_tfh:1, gen2:1, mq_rx_supported:1, + integrated:1, bisr_workaround:1; }; @@ -374,7 +381,6 @@ struct iwl_fw_mon_regs { * @smem_offset: offset from which the SMEM begins * @smem_len: the length of SMEM * @vht_mu_mimo_supported: VHT MU-MIMO support - * @integrated: discrete or integrated * @cdb: CDB support * @nvm_type: see &enum iwl_nvm_type * @d3_debug_data_base_addr: base address where D3 debug data is stored @@ -413,7 +419,6 @@ struct iwl_cfg { u32 dccm2_len; u32 smem_offset; u32 smem_len; - u32 soc_latency; u16 nvm_ver; u16 nvm_calib_ver; u32 rx_with_siso_diversity:1, @@ -427,7 +432,6 @@ struct iwl_cfg { disable_dummy_notification:1, apmg_not_supported:1, vht_mu_mimo_supported:1, - integrated:1, cdb:1, dbgc_supported:1, uhb_supported:1; @@ -442,7 +446,6 @@ struct iwl_cfg { u8 ucode_api_min; u16 num_rbds; u32 min_umac_error_event_table; - u32 extra_phy_cfg_flags; u32 d3_debug_data_base_addr; u32 d3_debug_data_length; u32 min_txq_size; @@ -496,6 +499,8 @@ struct iwl_dev_info { * This list declares the config structures for all devices. */ extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; +extern const struct iwl_cfg_trans_params iwl9560_trans_cfg; +extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg; extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; extern const char iwl9162_name[]; extern const char iwl9260_name[]; @@ -586,7 +591,6 @@ extern const struct iwl_cfg iwl9260_2ac_cfg; extern const struct iwl_cfg iwl9260_2ac_160_cfg; extern const struct iwl_cfg iwl9260_killer_2ac_cfg; extern const struct iwl_cfg iwl9270_2ac_cfg; -extern const struct iwl_cfg iwl9560_2ac_cfg; extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; @@ -596,7 +600,6 @@ extern const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9560_2ac_160_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 1b3a2f52e13f..98978a475d93 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -93,10 +93,10 @@ static int iwl_set_soc_latency(struct iwl_mvm *mvm) struct iwl_soc_configuration_cmd cmd; int ret; - cmd.device_type = (mvm->trans->cfg->integrated) ? + cmd.device_type = (mvm->trans->trans_cfg->integrated) ? cpu_to_le32(SOC_CONFIG_CMD_INTEGRATED) : cpu_to_le32(SOC_CONFIG_CMD_DISCRETE); - cmd.soc_latency = cpu_to_le32(mvm->trans->cfg->soc_latency); + cmd.soc_latency = cpu_to_le32(mvm->trans->trans_cfg->xtal_latency); ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SOC_CONFIGURATION_CMD, SYSTEM_GROUP, 0), 0, @@ -561,7 +561,8 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm)); /* set flags extra PHY configuration flags from the device's cfg */ - phy_cfg_cmd.phy_cfg |= cpu_to_le32(mvm->cfg->extra_phy_cfg_flags); + phy_cfg_cmd.phy_cfg |= + cpu_to_le32(mvm->trans->trans_cfg->extra_phy_cfg_flags); phy_cfg_cmd.calib_control.event_trigger = mvm->fw->default_calib[ucode_type].event_trigger; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 5f10dba12c8c..76c8df244dba 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -567,12 +567,12 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9000_trans_cfg)}, + {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_trans_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_trans_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, @@ -825,37 +825,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x2526, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), IWL_DEV_INFO(0x30DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), IWL_DEV_INFO(0x30DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0x31DC, 0x1551, iwl9560_2ac_cfg_shared_clk, iwl9560_killer_1550s_name), - IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_shared_clk, iwl9560_killer_1550i_name), + IWL_DEV_INFO(0x31DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), + IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, - IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9461_160_name), - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9461_name), - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, - IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9462_160_name), - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9462_name), - - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, - IWL_CFG_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9560_160_name), - _IWL_DEV_INFO(0x31DC, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, - iwl9560_2ac_cfg_shared_clk, iwl9560_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_160, IWL_CFG_CORES_BT, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 427fcea5cb2d..8c29071cb415 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1043,7 +1043,7 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) RFH_GEN_CFG_VAL(DEFAULT_RXQ_NUM, 0) | RFH_GEN_CFG_SERVICE_DMA_SNOOP | RFH_GEN_CFG_VAL(RB_CHUNK_SIZE, - trans->cfg->integrated ? + trans->trans_cfg->integrated ? RFH_GEN_CFG_RB_CHUNK_SIZE_64 : RFH_GEN_CFG_RB_CHUNK_SIZE_128)); /* Enable the relevant rx queues */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 46832bbfcae7..e4cbd8daa7c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1817,7 +1817,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_trans_pcie_sw_reset(trans); if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && - trans->cfg->integrated) { + trans->trans_cfg->integrated) { err = iwl_pcie_gen2_force_power_gating(trans); if (err) return err; -- cgit From c990fb19f5232389e6741fe0953686dcdec639fc Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 12:40:13 +0200 Subject: iwlwifi: remove some unused extern declarations from iwl-config.h After the refactoring, a few extern declarations were accidentally left in the iwl-config.h file. Remove them Change-Id: I79745e440ed5a0a90db61b0daaae374ecef09e86 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 2e9a85a9ee67..09eec2ef1b07 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -588,9 +588,6 @@ extern const struct iwl_cfg iwl8265_2ac_cfg; extern const struct iwl_cfg iwl8275_2ac_cfg; extern const struct iwl_cfg iwl4165_2ac_cfg; extern const struct iwl_cfg iwl9260_2ac_cfg; -extern const struct iwl_cfg iwl9260_2ac_160_cfg; -extern const struct iwl_cfg iwl9260_killer_2ac_cfg; -extern const struct iwl_cfg iwl9270_2ac_cfg; extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; @@ -598,15 +595,9 @@ extern const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_cfg_soc; extern const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc; -extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl9560_2ac_160_cfg_shared_clk; -extern const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; extern const struct iwl_cfg iwl_ax101_cfg_quz_hr; -extern const struct iwl_cfg iwl22000_2ax_cfg_hr; extern const struct iwl_cfg iwl_ax200_cfg_cc; extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; -- cgit From be2f6886a34eb121f5599313769bfc7ebdc852e4 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 17:29:55 +0200 Subject: iwlwifi: add HW step to new cfg device table We need to use different firmware versions for different HW steps with certain devices. Prepare for this differentiation by adding HW step to the new device table. Change-Id: Ib1afb7b0c89e9dc2d26e6d32ea19e978c17ba1dd Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 67 +++++++++++++++++-------- 2 files changed, 46 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 09eec2ef1b07..13f38c21cbd7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -488,6 +488,7 @@ struct iwl_dev_info { u16 subdevice; u16 mac_type; u16 rf_type; + u8 mac_step; u8 rf_id; u8 no_160; u8 cores; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 76c8df244dba..ee692e45bdb3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -807,15 +807,17 @@ static const struct pci_device_id iwl_hw_card_ids[] = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); -#define _IWL_DEV_INFO(_device, _subdevice, _mac_type, _rf_type, _rf_id, \ - _no_160, _cores, _cfg, _name) \ +#define _IWL_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ + _rf_id, _no_160, _cores, _cfg, _name) \ { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ .name = _name, .mac_type = _mac_type, .rf_type = _rf_type, \ - .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, } + .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ + .mac_step = _mac_step } #define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \ _IWL_DEV_INFO(_device, _subdevice, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, _cfg, _name) + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \ + _cfg, _name) static const struct iwl_dev_info iwl_dev_info_table[] = { #if IS_ENABLED(CONFIG_IWLMVM) @@ -831,81 +833,99 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9461_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9461_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9462_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9462_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9560_160_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9560_2ac_cfg_soc, iwl9560_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9461_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9461_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9462_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9462_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9560_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9560_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_160, IWL_CFG_CORES_BT_GNSS, iwl9260_2ac_cfg, iwl9270_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_NO_160, IWL_CFG_CORES_BT_GNSS, iwl9260_2ac_cfg, iwl9270_name), _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9162_160_name), _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9162_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9260_160_name), _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9260_name), @@ -960,6 +980,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (dev_info->mac_type == (u16)IWL_CFG_ANY || dev_info->mac_type == CSR_HW_REV_TYPE(iwl_trans->hw_rev)) && + (dev_info->mac_step == (u8)IWL_CFG_ANY || + dev_info->mac_step == + CSR_HW_REV_STEP(iwl_trans->hw_rev)) && (dev_info->rf_type == (u16)IWL_CFG_ANY || dev_info->rf_type == CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id)) && -- cgit From 32ed101aa140020ca8806896892f97bab799c41e Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 21:02:47 +0200 Subject: iwlwifi: convert all Qu with Jf devices to the new config table Add new generic iwl_trans structures for these devices and apply the correct cfg depending on the device characteristics. Since we have to match Qu with IWL_CONFIG_ANY, we also need to move the Hr devices to the new table, but for now we keep matching on PCI device and subsystem device IDs. Change-Id: I14e9146a99621ff11ce50bc746a4b88af508fee0 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 35 ++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 5 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 493 ++++++++++++------------ 3 files changed, 283 insertions(+), 250 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index bfabe0ed4ee8..d86752ad96b7 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -235,6 +235,17 @@ static const struct iwl_ht_params iwl_22000_ht_params = { }, \ } +const struct iwl_cfg_trans_params iwl_qu_trans_cfg = { + .mq_rx_supported = true, + .use_tfh = true, + .rf_id = true, + .gen2 = true, + .device_family = IWL_DEVICE_FAMILY_22000, + .base_params = &iwl_22000_base_params, + .integrated = true, + .xtal_latency = 5000, +}; + /* * If the device doesn't support HE, no need to have that many buffers. * 22000 devices can split multiple frames into a single RB, so fewer are @@ -246,6 +257,30 @@ static const struct iwl_ht_params iwl_22000_ht_params = { #define IWL_NUM_RBDS_22000_HE 2048 #define IWL_NUM_RBDS_AX210_HE 4096 +const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg = { + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, +}; + +const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg = { + .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, + IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, +}; + +const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg = { + .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, + IWL_DEVICE_22500, + /* + * This device doesn't support receiving BlockAck with a large bitmap + * so we need to restrict the size of transmitted aggregation to the + * HT size; mac80211 would otherwise pick the HE max (256) by default. + */ + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_NON_HE, +}; + const struct iwl_cfg_trans_params iwl_ax200_trans_cfg = { .device_family = IWL_DEVICE_FAMILY_22000, .base_params = &iwl_22000_base_params, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 13f38c21cbd7..af7b6a67dfb1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -461,6 +461,7 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_PNJ 0x32 #define IWL_CFG_MAC_TYPE_TH 0x32 #define IWL_CFG_MAC_TYPE_QU 0x33 +#define IWL_CFG_MAC_TYPE_QUZ 0x35 #define IWL_CFG_RF_TYPE_TH 0x105 #define IWL_CFG_RF_TYPE_TH1 0x108 @@ -502,6 +503,7 @@ struct iwl_dev_info { extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_qu_trans_cfg; extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; extern const char iwl9162_name[]; extern const char iwl9260_name[]; @@ -589,6 +591,9 @@ extern const struct iwl_cfg iwl8265_2ac_cfg; extern const struct iwl_cfg iwl8275_2ac_cfg; extern const struct iwl_cfg iwl4165_2ac_cfg; extern const struct iwl_cfg iwl9260_2ac_cfg; +extern const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg; +extern const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg; +extern const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index ee692e45bdb3..609c4c5bd32c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -513,67 +513,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, /* 9000 Series */ - {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - - {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - - {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_trans_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, @@ -600,140 +539,27 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - - {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - - {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - - {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, + {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_trans_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_trans_cfg)}, + +/* Qu devices */ + {IWL_PCI_DEVICE(0x02F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0x06F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0x34F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0x3DF0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)}, /* 22000 Series */ {IWL_PCI_DEVICE(0x2723, PCI_ANY_ID, iwl_ax200_trans_cfg)}, - {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x1651, iwl_ax1650s_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x1652, iwl_ax1650i_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x2074, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x4244, iwl_ax101_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x1651, iwl_ax1650s_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x1652, iwl_ax1650i_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x2074, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax201_cfg_quz_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x4244, iwl_ax101_cfg_quz_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)}, @@ -750,41 +576,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x2074, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x4244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x2074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x4244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x4244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x2074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0)}, @@ -832,6 +623,83 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), +/* AX200 */ + IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), + IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), + IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), + +/* Qu with Hr */ + IWL_DEV_INFO(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x4244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0A10, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0xA0F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x4244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x0070, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x0074, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x0078, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x007C, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x0244, iwl_ax101_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x0310, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x1651, iwl_ax1650s_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x1652, iwl_ax1650i_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x2074, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x4070, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x02F0, 0x4244, iwl_ax101_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x0070, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x0074, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x0078, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x007C, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x0244, iwl_ax101_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x0310, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x1651, iwl_ax1650s_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x1652, iwl_ax1650i_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x2074, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x4070, iwl_ax201_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x06F0, 0x4244, iwl_ax101_cfg_quz_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x0310, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x34F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x34F0, 0x4244, iwl_ax101_cfg_qu_hr, NULL), + + IWL_DEV_INFO(0x3DF0, 0x0044, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x0244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x0310, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x3DF0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), + IWL_DEV_INFO(0x3DF0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x3DF0, 0x4244, iwl_ax101_cfg_qu_hr, NULL), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, @@ -929,11 +797,138 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9260_2ac_cfg, iwl9260_name), -/* AX200 */ - IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), - IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), - IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), + /* Qu with Jf */ + /* Qu B step */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9461_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9461_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9462_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9462_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9560_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9560_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550s_name), + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550i_name), + /* Qu C step */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9461_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9461_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9462_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9462_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9560_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9560_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550s_name), + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550i_name), + + /* QuZ */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9461_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9461_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9462_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9462_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9560_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9560_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550s_name), + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, + IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550i_name), #endif /* CONFIG_IWLMVM */ }; @@ -997,7 +992,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) IWL_SUBDEVICE_CORES(pdev->subsystem_device))) { iwl_trans->cfg = dev_info->cfg; iwl_trans->name = dev_info->name; - goto found; } } @@ -1079,38 +1073,38 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * thing to do to support Qu C-step. */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { - if (cfg == &iwl_ax101_cfg_qu_hr) + if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; - else if (cfg == &iwl_ax201_cfg_qu_hr) + else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; - else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) + else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; - else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) + else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; - else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) + else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; - else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) + else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; - else if (cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) + else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; - else if (cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) + else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; } /* same thing for QuZ... */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { - if (cfg == &iwl_ax101_cfg_qu_hr) - cfg = &iwl_ax101_cfg_quz_hr; - else if (cfg == &iwl_ax201_cfg_qu_hr) - cfg = &iwl_ax201_cfg_quz_hr; - else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc; - else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc; - else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc; - else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; + if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) + iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; + else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) + iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; + else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) + iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc; + else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) + iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc; + else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) + iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc; + else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) + iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; } #endif @@ -1121,7 +1115,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!iwl_trans->cfg) iwl_trans->cfg = cfg; -found: /* if we don't have a name yet, copy name from the old cfg */ if (!iwl_trans->name) iwl_trans->name = iwl_trans->cfg->name; -- cgit From 612509d6bd4a37d21a97187448d7811a54d6b5c3 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 21:29:55 +0200 Subject: iwlwifi: convert QnJ with Jf devices to new config table All the QnJ devices have a similar matching to the other Qu devices, but needs a different configuration. Convert the QnJ devices to the new table accordingly. Change-Id: If236ef3d0da3e605a3379922818f5897e0affd7e Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 78 +++++------------ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 8 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 107 ++++++++++++++---------- 3 files changed, 86 insertions(+), 107 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index d86752ad96b7..76f2ee06d8f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -246,6 +246,15 @@ const struct iwl_cfg_trans_params iwl_qu_trans_cfg = { .xtal_latency = 5000, }; +const struct iwl_cfg_trans_params iwl_qnj_trans_cfg = { + .mq_rx_supported = true, + .use_tfh = true, + .rf_id = true, + .gen2 = true, + .device_family = IWL_DEVICE_FAMILY_22000, + .base_params = &iwl_22000_base_params, +}; + /* * If the device doesn't support HE, no need to have that many buffers. * 22000 devices can split multiple frames into a single RB, so fewer are @@ -281,6 +290,18 @@ const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg = { .num_rbds = IWL_NUM_RBDS_NON_HE, }; +const struct iwl_cfg iwl9560_qnj_b0_jf_b0_cfg = { + .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE, + IWL_DEVICE_22500, + /* + * This device doesn't support receiving BlockAck with a large bitmap + * so we need to restrict the size of transmitted aggregation to the + * HT size; mac80211 would otherwise pick the HE max (256) by default. + */ + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_NON_HE, +}; + const struct iwl_cfg_trans_params iwl_ax200_trans_cfg = { .device_family = IWL_DEVICE_FAMILY_22000, .base_params = &iwl_22000_base_params, @@ -476,19 +497,6 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = { .num_rbds = IWL_NUM_RBDS_NON_HE, }; -const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, @@ -549,50 +557,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { .num_rbds = IWL_NUM_RBDS_NON_HE, }; -const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { - .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { - .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { - .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = { - .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index af7b6a67dfb1..2ecc94799e57 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -462,6 +462,7 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_TH 0x32 #define IWL_CFG_MAC_TYPE_QU 0x33 #define IWL_CFG_MAC_TYPE_QUZ 0x35 +#define IWL_CFG_MAC_TYPE_QNJ 0x36 #define IWL_CFG_RF_TYPE_TH 0x105 #define IWL_CFG_RF_TYPE_TH1 0x108 @@ -504,6 +505,7 @@ extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg; extern const struct iwl_cfg_trans_params iwl_qu_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_qnj_trans_cfg; extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; extern const char iwl9162_name[]; extern const char iwl9260_name[]; @@ -594,13 +596,12 @@ extern const struct iwl_cfg iwl9260_2ac_cfg; extern const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg; +extern const struct iwl_cfg iwl9560_qnj_b0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_cfg_soc; -extern const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc; -extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; extern const struct iwl_cfg iwl_ax101_cfg_quz_hr; @@ -625,13 +626,10 @@ extern const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0; extern const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0; extern const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0; extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0; -extern const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0; -extern const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0; extern const struct iwl_cfg iwl22000_2ax_cfg_jf; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; -extern const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0; extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 609c4c5bd32c..7c228aa66a0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -513,32 +513,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, /* 9000 Series */ - {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9560_trans_cfg)}, {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9560_trans_cfg)}, @@ -555,28 +529,10 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, PCI_ANY_ID, iwl_qnj_trans_cfg)}, -/* 22000 Series */ {IWL_PCI_DEVICE(0x2723, PCI_ANY_ID, iwl_ax200_trans_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0310, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x1080, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x2074, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x4244, iwl_ax101_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_ty_gf_a0)}, @@ -700,6 +656,23 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x3DF0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), IWL_DEV_INFO(0x3DF0, 0x4244, iwl_ax101_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x2720, 0x0000, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0040, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0044, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0070, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0074, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0078, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x007C, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0244, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0310, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x0A10, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x1080, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x1651, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x1652, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x2074, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x4070, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + IWL_DEV_INFO(0x2720, 0x4244, iwl22000_2ax_cfg_qnj_hr_b0, NULL), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, @@ -929,6 +902,50 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_NO_160, IWL_CFG_CORES_BT, iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550i_name), + + /* QnJ */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9461_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9461_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9462_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9462_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9560_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9560_name), + + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9560_killer_1550s_name), + _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, + IWL_CFG_MAC_TYPE_QNJ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, + iwl9560_qnj_b0_jf_b0_cfg, iwl9560_killer_1550i_name), #endif /* CONFIG_IWLMVM */ }; -- cgit From 68ceba3ff484d31d13a8e5ccc49b2c655aa7b83a Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 21:38:33 +0200 Subject: iwlwifi: remove unnecessary cfg mangling for Qu C and QuZ with Jf Now that we identify the correct cfgs with the new tables for Qu step C and QuZ with Jf, we can remove the mangling we do later on. Change-Id: Ic01ce67db147e897ad2424f0e05a70a00d2c620e Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 139 +----------------------- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 13 --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 25 +---- 3 files changed, 8 insertions(+), 169 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 76f2ee06d8f6..66f5df74a321 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -266,6 +266,11 @@ const struct iwl_cfg_trans_params iwl_qnj_trans_cfg = { #define IWL_NUM_RBDS_22000_HE 2048 #define IWL_NUM_RBDS_AX210_HE 4096 +/* + * All JF radio modules are part of the 9000 series, but the MAC part + * looks more like 22000. That's why this device is here, but called + * 9560 nevertheless. + */ const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg = { .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, @@ -436,127 +441,6 @@ const struct iwl_cfg iwl_ax200_cfg_cc = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; -/* - * All JF radio modules are part of the 9000 series, but the MAC part - * looks more like 22000. That's why this device is here, but called - * 9560 nevertheless. - */ -const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9461", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9462", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9461", - .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9462", - .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560", - .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { - .name = "Intel(R) Dual Band Wireless AC 9461", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { - .name = "Intel(R) Dual Band Wireless AC 9462", - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .trans.integrated = true, - .trans.xtal_latency = 5000, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, @@ -609,19 +493,6 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; -const struct iwl_cfg iwl22000_2ax_cfg_jf = { - .name = "Intel(R) Dual Band Wireless AX 22000", - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = { .name = "Intel(R) Dual Band Wireless AX 22000", .fw_name_pre = IWL_22000_HR_A_F0_FW_PRE, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 2ecc94799e57..8549e8a39705 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -597,10 +597,6 @@ extern const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg; extern const struct iwl_cfg iwl9560_qnj_b0_jf_b0_cfg; -extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; -extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; -extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; -extern const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc; extern const struct iwl_cfg iwl9560_2ac_cfg_soc; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; @@ -618,15 +614,6 @@ extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0; extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0; extern const struct iwl_cfg killer1650x_2ax_cfg; extern const struct iwl_cfg killer1650w_2ax_cfg; -extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0; -extern const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0; -extern const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0; -extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0; -extern const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0; -extern const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0; -extern const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0; -extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0; -extern const struct iwl_cfg iwl22000_2ax_cfg_jf; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 7c228aa66a0f..ba4773e07bf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1057,9 +1057,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { iwl_trans->cfg = &iwl_ax101_cfg_qu_hr; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - iwl_trans->cfg = &iwl22000_2ax_cfg_jf; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) { IWL_ERR(iwl_trans, "RF ID HRCDB is not supported\n"); @@ -1085,23 +1082,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* * This is a hack to switch from Qu B0 to Qu C0. We need to - * do this for all cfgs that use Qu B0. All this code is in - * urgent need for a refactor, but for now this is the easiest - * thing to do to support Qu C-step. + * do this for all cfgs that use Qu B0, except for those using + * Jf, which have already been moved to the new table. The + * rest must be removed once we convert Qu with Hr as well. */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) @@ -1114,14 +1103,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; - else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; } #endif -- cgit From 6815e3d0bbee886dfd13bba485066ff830ed7f14 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Sun, 6 Oct 2019 12:28:47 +0300 Subject: iwlwifi: mvm: add support for non EDCA based measurements Add support for requesting trigger-based / non trigger-based measurements. Change-Id: Ib4d0c471da9c50d9981541a7f5926db384a0f7ce Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/location.h | 6 ++++++ drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c | 9 +++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 ++++- 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index a0d6802c2715..0214e553d5ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -427,6 +427,9 @@ struct iwl_tof_range_req_ap_entry_v2 { * Default algo type is ML. * @IWL_INITIATOR_AP_FLAGS_MCSI_REPORT: Send the MCSI for each FTM frame to the * driver. + * @IWL_INITIATOR_AP_FLAGS_NON_TB: Use non trigger based flow + * @IWL_INITIATOR_AP_FLAGS_TB: Use trigger based flow + * @IWL_INITIATOR_AP_FLAGS_SECURED: request secured measurement */ enum iwl_initiator_ap_flags { IWL_INITIATOR_AP_FLAGS_ASAP = BIT(1), @@ -436,6 +439,9 @@ enum iwl_initiator_ap_flags { IWL_INITIATOR_AP_FLAGS_ALGO_LR = BIT(5), IWL_INITIATOR_AP_FLAGS_ALGO_FFT = BIT(6), IWL_INITIATOR_AP_FLAGS_MCSI_REPORT = BIT(8), + IWL_INITIATOR_AP_FLAGS_NON_TB = BIT(9), + IWL_INITIATOR_AP_FLAGS_TB = BIT(10), + IWL_INITIATOR_AP_FLAGS_SECURED = BIT(11), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index 6e1ea921c299..9e21f5e5d364 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -278,6 +278,10 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm, return -EINVAL; } + /* non EDCA based measurement must use HE preamble */ + if (peer->ftm.trigger_based || peer->ftm.non_trigger_based) + *format_bw |= IWL_LOCATION_FRAME_FORMAT_HE; + *ctrl_ch_position = (peer->chandef.width > NL80211_CHAN_WIDTH_20) ? iwl_mvm_get_ctrl_pos(&peer->chandef) : 0; @@ -349,6 +353,11 @@ iwl_mvm_ftm_put_target_common(struct iwl_mvm *mvm, FTM_PUT_FLAG(ALGO_LR); else if (IWL_MVM_FTM_INITIATOR_ALGO == IWL_TOF_ALGO_TYPE_FFT) FTM_PUT_FLAG(ALGO_FFT); + + if (peer->ftm.trigger_based) + FTM_PUT_FLAG(TB); + else if (peer->ftm.non_trigger_based) + FTM_PUT_FLAG(NON_TB); } static int diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 7b6d14445f1b..c9c40965de4c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -193,6 +193,8 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = { .non_asap = 1, .request_lci = 1, .request_civicloc = 1, + .trigger_based = 1, + .non_trigger_based = 1, .max_bursts_exponent = -1, /* all supported */ .max_ftms_per_burst = 0, /* no limits */ .bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | @@ -201,7 +203,8 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = { BIT(NL80211_CHAN_WIDTH_80), .preambles = BIT(NL80211_PREAMBLE_LEGACY) | BIT(NL80211_PREAMBLE_HT) | - BIT(NL80211_PREAMBLE_VHT), + BIT(NL80211_PREAMBLE_VHT) | + BIT(NL80211_PREAMBLE_HE), }, }; -- cgit From 095650c0541e1898751a25073f1a57cfd309f7eb Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 6 Nov 2019 09:27:51 +0200 Subject: iwlwifi: add support for version 2 of SOC_CONFIGURATION_CMD This new command is mostly backwards compatible, with the exception that the device_type element was changed into a bitmask. The device type bit remains the same (because we only had 0 and 1 anyway), but when using v1 we can't set any other bits, because that would change the integer. Other than that, the struct remains the same and the driver can set the device_type bit in both cases, but it can only set the low_latency bit if VER_2 is used. Change-Id: Ib68d4c821ebcce253b42ed0ea15881fb4e3e01da Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/soc.h | 24 ++++++++++++++---------- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 21 ++++++++++++++++----- 3 files changed, 32 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h index 5d1fb98fe667..aadca78e9846 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2019 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2019 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,21 +65,23 @@ #ifndef __iwl_fw_api_soc_h__ #define __iwl_fw_api_soc_h__ -/* type of devices for defining SOC latency */ -enum iwl_soc_device_types { - SOC_CONFIG_CMD_INTEGRATED = 0x0, - SOC_CONFIG_CMD_DISCRETE = 0x1, -}; +#define SOC_CONFIG_CMD_FLAGS_DISCRETE BIT(0) +#define SOC_CONFIG_CMD_FLAGS_LOW_LATENCY BIT(1) /** * struct iwl_soc_configuration_cmd - Set device stabilization latency * - * @device_type: the device type as defined in &enum iwl_soc_device_types - * @soc_latency: time for SOC to ensure stable power & XTAL + * @flags: soc settings flags. In VER_1, we can only set the DISCRETE + * flag, because the FW treats the whole value as an integer. In + * VER_2, we can set the bits independently. + * @latency: time for SOC to ensure stable power & XTAL */ struct iwl_soc_configuration_cmd { - __le32 device_type; - __le32 soc_latency; -} __packed; /* SOC_CONFIGURATION_CMD_S_VER_1 */ + __le32 flags; + __le32 latency; +} __packed; /* + * SOC_CONFIGURATION_CMD_S_VER_1 (see description above) + * SOC_CONFIGURATION_CMD_S_VER_2 + */ #endif /* __iwl_fw_api_soc_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 8549e8a39705..3069a322ca75 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -303,6 +303,7 @@ struct iwl_pwr_tx_backoff { * @gen2: 22000 and on transport operation * @mq_rx_supported: multi-queue rx support * @integrated: discrete or integrated + * @low_latency_xtal: use the low latency xtal if supported */ struct iwl_cfg_trans_params { const struct iwl_base_params *base_params; @@ -315,6 +316,7 @@ struct iwl_cfg_trans_params { gen2:1, mq_rx_supported:1, integrated:1, + low_latency_xtal:1, bisr_workaround:1; }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 98978a475d93..bc040e9ca55f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -90,13 +90,24 @@ struct iwl_mvm_alive_data { /* set device type and latency */ static int iwl_set_soc_latency(struct iwl_mvm *mvm) { - struct iwl_soc_configuration_cmd cmd; + struct iwl_soc_configuration_cmd cmd = {}; int ret; - cmd.device_type = (mvm->trans->trans_cfg->integrated) ? - cpu_to_le32(SOC_CONFIG_CMD_INTEGRATED) : - cpu_to_le32(SOC_CONFIG_CMD_DISCRETE); - cmd.soc_latency = cpu_to_le32(mvm->trans->trans_cfg->xtal_latency); + /* + * In VER_1 of this command, the discrete value is considered + * an integer; In VER_2, it's a bitmask. Since we have only 2 + * values in VER_1, this is backwards-compatible with VER_2, + * as long as we don't set any other bits. + */ + if (!mvm->trans->trans_cfg->integrated) + cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE); + + if (iwl_mvm_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP, + SCAN_REQ_UMAC) >= 2 && + (mvm->trans->trans_cfg->low_latency_xtal)) + cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY); + + cmd.latency = cpu_to_le32(mvm->trans->trans_cfg->xtal_latency); ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SOC_CONFIGURATION_CMD, SYSTEM_GROUP, 0), 0, -- cgit From a72abfca95f36dea268b5e19e3cbeb0959e83518 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 4 Nov 2019 22:51:54 +0200 Subject: iwlwifi: add trans_cfg for devices with long latency A couple of SoCs, which can be recognized by PCI device IDs 0xA0F0 and 0x43F0, need a longer wait for the xtal to stabilize. To handle this, add a new trans_cfg structure for Qu devices with a larger xtal_latency value and apply them to the devices recognized by these IDs. Also add a flag that allows us to inform the FW that the low latency xtal should be used. Change-Id: I8a14c6af45ea14d8e7f1ef38a589158f38d0c0ea Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 12 ++++++++++++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 5 +++-- 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 66f5df74a321..7b67c1ebbedf 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -246,6 +246,18 @@ const struct iwl_cfg_trans_params iwl_qu_trans_cfg = { .xtal_latency = 5000, }; +const struct iwl_cfg_trans_params iwl_qu_long_latency_trans_cfg = { + .mq_rx_supported = true, + .use_tfh = true, + .rf_id = true, + .gen2 = true, + .device_family = IWL_DEVICE_FAMILY_22000, + .base_params = &iwl_22000_base_params, + .integrated = true, + .xtal_latency = 12000, + .low_latency_xtal = true, +}; + const struct iwl_cfg_trans_params iwl_qnj_trans_cfg = { .mq_rx_supported = true, .use_tfh = true, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 3069a322ca75..ec715ee17156 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -507,6 +507,7 @@ extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_trans_cfg; extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg; extern const struct iwl_cfg_trans_params iwl_qu_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_qu_long_latency_trans_cfg; extern const struct iwl_cfg_trans_params iwl_qnj_trans_cfg; extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; extern const char iwl9162_name[]; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index ba4773e07bf2..d6735453849d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -526,8 +526,9 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x06F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, {IWL_PCI_DEVICE(0x34F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, {IWL_PCI_DEVICE(0x3DF0, PCI_ANY_ID, iwl_qu_trans_cfg)}, - {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, - {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + + {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_long_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x2720, PCI_ANY_ID, iwl_qnj_trans_cfg)}, -- cgit From a661bfac2a6e2b00b5220aec54ed69736c917f08 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 11 Nov 2019 17:22:59 +0200 Subject: iwlwifi: remove support for QnJ Hr STEP A We don't support QnJ HR STEP A anymore. Remove the structures we used for it. Change-Id: I0dfd88232bdc8ff2dd9c4368b8ed9a0c40c86bc8 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 17 ----------------- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 - 2 files changed, 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 7b67c1ebbedf..cafc322f01a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -79,7 +79,6 @@ #define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" -#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" #define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0-" #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" #define IWL_QU_C_JF_B_FW_PRE "iwlwifi-Qu-c0-jf-b0-" @@ -104,8 +103,6 @@ IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode" -#define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ - IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" #define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \ IWL_QUZ_A_HR_B_FW_PRE __stringify(api) ".ucode" #define IWL_QUZ_A_JF_B_MODULE_FIRMWARE(api) \ @@ -531,19 +528,6 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; -const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { - .name = "Intel(R) Dual Band Wireless AX 22000", - .fw_name_pre = IWL_22000_HR_A0_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE, @@ -594,7 +578,6 @@ MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index ec715ee17156..9a10bd593d95 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -620,7 +620,6 @@ extern const struct iwl_cfg killer1650w_2ax_cfg; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; -extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0; extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0; extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0; -- cgit From f4ed93a192199bd238888efd7a7c226b72263be2 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 11 Nov 2019 17:32:08 +0200 Subject: iwlwifi: remove support for QnJ HR FPGA We don't support the FPGA versions of this card combination anymore. Remove the cfg mangling that tries to load it and all the relevant structures. Change-Id: I190652101afcab682cfba873d062992f11efca32 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 17 ----------------- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 - drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 12 ------------ 3 files changed, 30 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index cafc322f01a4..a88aa15afc8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -76,7 +76,6 @@ #define IWL_22000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-" #define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" #define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" -#define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" #define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0-" @@ -97,8 +96,6 @@ IWL_22000_HR_FW_PRE __stringify(api) ".ucode" #define IWL_22000_JF_MODULE_FIRMWARE(api) \ IWL_22000_JF_FW_PRE __stringify(api) ".ucode" -#define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \ - IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode" #define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \ IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ @@ -502,19 +499,6 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; -const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = { - .name = "Intel(R) Dual Band Wireless AX 22000", - .fw_name_pre = IWL_22000_HR_A_F0_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = { .name = "Intel(R) Dual Band Wireless AX 22000", .fw_name_pre = IWL_22000_HR_B_FW_PRE, @@ -576,7 +560,6 @@ const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0 = { MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 9a10bd593d95..d5d984d7ce83 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -617,7 +617,6 @@ extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0; extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0; extern const struct iwl_cfg killer1650x_2ax_cfg; extern const struct iwl_cfg killer1650w_2ax_cfg; -extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index d6735453849d..6744c0281ffb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1067,18 +1067,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id)); return -EINVAL; } - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && - iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) { - u32 hw_status; - - hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS); - if (CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_B_STEP) - iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; - else if ((hw_status & UMAG_GEN_HW_IS_FPGA) && - CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == - SILICON_A_STEP) - iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; } /* -- cgit From e8b61560efd4fe280008c12a702e0f34380e1120 Mon Sep 17 00:00:00 2001 From: rotem saado Date: Wed, 13 Nov 2019 14:20:11 +0200 Subject: iwlwifi: yoyo: don't block dumping internal memory when not in SRAM mode When we have an assert during D3 we want to dump the internal buffer memory even if are we working in DRAM debug mode. We should not block dumping it. Change-Id: I69aad2d4904c4f8bb653c61e8781a2e07780054f Signed-off-by: Rotem Saado Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index d5dda93c3953..1746a0c472a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1737,13 +1737,7 @@ iwl_dump_ini_mon_smem_get_size(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_region_data *reg_data) { struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data; - struct iwl_fw_ini_allocation_tlv *fw_mon_cfg; - u32 alloc_id = le32_to_cpu(reg->internal_buffer.alloc_id), size; - - fw_mon_cfg = &fwrt->trans->dbg.fw_mon_cfg[alloc_id]; - if (le32_to_cpu(fw_mon_cfg->buf_location) != - IWL_FW_INI_LOCATION_SRAM_PATH) - return 0; + u32 size; size = le32_to_cpu(reg->internal_buffer.size); if (!size) -- cgit From 5d1234ba25b8c6ecbbe5a6aa1f099016c5d2c708 Mon Sep 17 00:00:00 2001 From: Tova Mussai Date: Tue, 5 Nov 2019 12:56:14 +0200 Subject: iwlwifi: scan: support FW APIs with variable number of profiles The FW changed the maximum number of scan offload profiles to 8 in new APIs. Support it by changing the scan_offload_profile_cfg struct to be more dynamic, so we can reuse most of the code and only change size of the profiles array. Change-Id: I65210cf541af46e2675a8c764d5871f7f5b070d6 Signed-off-by: Tova Mussai Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 31 ++++++++++++++---- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 5 +-- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +-- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 ++++ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 40 +++++++++++++++-------- 5 files changed, 65 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 2e70e4e752e1..3d770f406c38 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -95,6 +95,7 @@ struct iwl_ssid_ie { #define IWL_SCAN_MAX_BLACKLIST_LEN 64 #define IWL_SCAN_SHORT_BLACKLIST_LEN 16 #define IWL_SCAN_MAX_PROFILES 11 +#define IWL_SCAN_MAX_PROFILES_V2 8 #define SCAN_OFFLOAD_PROBE_REQ_SIZE 512 #define SCAN_NUM_BAND_PROBE_DATA_V_1 2 #define SCAN_NUM_BAND_PROBE_DATA_V_2 3 @@ -160,8 +161,7 @@ struct iwl_scan_offload_profile { } __packed; /** - * struct iwl_scan_offload_profile_cfg - SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1 - * @profiles: profiles to search for match + * struct iwl_scan_offload_profile_cfg_data * @blacklist_len: length of blacklist * @num_profiles: num of profiles in the list * @match_notify: clients waiting for match found notification @@ -170,8 +170,7 @@ struct iwl_scan_offload_profile { * @any_beacon_notify: clients waiting for match notification without match * @reserved: reserved */ -struct iwl_scan_offload_profile_cfg { - struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; +struct iwl_scan_offload_profile_cfg_data { u8 blacklist_len; u8 num_profiles; u8 match_notify; @@ -181,6 +180,26 @@ struct iwl_scan_offload_profile_cfg { u8 reserved[2]; } __packed; +/** + * struct iwl_scan_offload_profile_cfg + * @profiles: profiles to search for match + * @data: the rest of the data for profile_cfg + */ +struct iwl_scan_offload_profile_cfg_v1 { + struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; + struct iwl_scan_offload_profile_cfg_data data; +} __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1-2*/ + +/** + * struct iwl_scan_offload_profile_cfg + * @profiles: profiles to search for match + * @data: the rest of the data for profile_cfg + */ +struct iwl_scan_offload_profile_cfg { + struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES_V2]; + struct iwl_scan_offload_profile_cfg_data data; +} __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_3*/ + /** * struct iwl_scan_schedule_lmac - schedule of scan offload * @delay: delay between iterations, in seconds. @@ -1169,7 +1188,7 @@ struct iwl_scan_offload_profiles_query_v1 { u8 resume_while_scanning; u8 self_recovery; __le16 reserved; - struct iwl_scan_offload_profile_match_v1 matches[IWL_SCAN_MAX_PROFILES]; + struct iwl_scan_offload_profile_match_v1 matches[0]; } __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */ /** @@ -1213,7 +1232,7 @@ struct iwl_scan_offload_profiles_query { u8 resume_while_scanning; u8 self_recovery; __le16 reserved; - struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES]; + struct iwl_scan_offload_profile_match matches[0]; } __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 22a32eb10f01..122ca7624073 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1709,6 +1709,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, }; int ret, len; size_t query_len, matches_len; + int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw); ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret) { @@ -1720,11 +1721,11 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) { query_len = sizeof(struct iwl_scan_offload_profiles_query); matches_len = sizeof(struct iwl_scan_offload_profile_match) * - IWL_SCAN_MAX_PROFILES; + max_profiles; } else { query_len = sizeof(struct iwl_scan_offload_profiles_query_v1); matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) * - IWL_SCAN_MAX_PROFILES; + max_profiles; } len = iwl_rx_packet_payload_len(cmd.resp_pkt); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index c9c40965de4c..7aa1350b093e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -617,7 +617,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->max_sched_scan_reqs = 1; hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; - hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; + hw->wiphy->max_match_sets = iwl_umac_scan_get_max_profiles(mvm->fw); /* we create the 802.11 header and zero length SSID IE. */ hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2; @@ -705,7 +705,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; - mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES; + mvm->wowlan.max_nd_match_sets = + iwl_umac_scan_get_max_profiles(mvm->fw); hw->wiphy->wowlan = &mvm->wowlan; } #endif diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index d6ecc2d2bf21..afcf2b98a9cb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2147,4 +2147,11 @@ iwl_mvm_set_chan_info_chandef(struct iwl_mvm *mvm, iwl_mvm_get_ctrl_pos(chandef)); } +static inline int iwl_umac_scan_get_max_profiles(const struct iwl_fw *fw) +{ + u8 ver = iwl_mvm_lookup_cmd_ver(fw, IWL_ALWAYS_LONG_GROUP, + SCAN_OFFLOAD_UPDATE_PROFILES_CMD); + return (ver == IWL_FW_CMD_VER_UNKNOWN || ver < 3) ? + IWL_SCAN_MAX_PROFILES : IWL_SCAN_MAX_PROFILES_V2; +} #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 1fa74086a4f7..7a6ad1ff7055 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -594,11 +594,15 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req) { struct iwl_scan_offload_profile *profile; - struct iwl_scan_offload_profile_cfg *profile_cfg; + struct iwl_scan_offload_profile_cfg_v1 *profile_cfg_v1; struct iwl_scan_offload_blacklist *blacklist; + struct iwl_scan_offload_profile_cfg_data *data; + int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw); + int profile_cfg_size = sizeof(*data) + + sizeof(*profile) * max_profiles; struct iwl_host_cmd cmd = { .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD, - .len[1] = sizeof(*profile_cfg), + .len[1] = profile_cfg_size, .dataflags[0] = IWL_HCMD_DFL_NOCOPY, .dataflags[1] = IWL_HCMD_DFL_NOCOPY, }; @@ -606,7 +610,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, int i; int ret; - if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES)) + if (WARN_ON(req->n_match_sets > max_profiles)) return -EIO; if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL) @@ -618,27 +622,37 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, if (!blacklist) return -ENOMEM; - profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL); - if (!profile_cfg) { + profile_cfg_v1 = kzalloc(profile_cfg_size, GFP_KERNEL); + if (!profile_cfg_v1) { ret = -ENOMEM; goto free_blacklist; } cmd.data[0] = blacklist; cmd.len[0] = sizeof(*blacklist) * blacklist_len; - cmd.data[1] = profile_cfg; + cmd.data[1] = profile_cfg_v1; + + /* if max_profile is MAX_PROFILES_V2, we have the new API */ + if (max_profiles == IWL_SCAN_MAX_PROFILES_V2) { + struct iwl_scan_offload_profile_cfg *profile_cfg = + (struct iwl_scan_offload_profile_cfg *)profile_cfg_v1; + + data = &profile_cfg->data; + } else { + data = &profile_cfg_v1->data; + } /* No blacklist configuration */ + data->num_profiles = req->n_match_sets; + data->active_clients = SCAN_CLIENT_SCHED_SCAN; + data->pass_match = SCAN_CLIENT_SCHED_SCAN; + data->match_notify = SCAN_CLIENT_SCHED_SCAN; - profile_cfg->num_profiles = req->n_match_sets; - profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; - profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; - profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) - profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; + data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; for (i = 0; i < req->n_match_sets; i++) { - profile = &profile_cfg->profiles[i]; + profile = &profile_cfg_v1->profiles[i]; profile->ssid_index = i; /* Support any cipher and auth algorithm */ profile->unicast_cipher = 0xff; @@ -651,7 +665,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n"); ret = iwl_mvm_send_cmd(mvm, &cmd); - kfree(profile_cfg); + kfree(profile_cfg_v1); free_blacklist: kfree(blacklist); -- cgit From b0d8d2c27007daa6125842dd0f797efe38a54b00 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 7 Nov 2019 15:59:43 +0200 Subject: iwlwifi: yoyo: enable yoyo by default Now that YoYo is more mature, we can enable it by default, so we collect data in the new way. Change-Id: Ic1a147f935286b085ca8bdb248a7493b7c6341ea Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 2d1cb4647c3b..43ebfa20a4e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1715,6 +1715,7 @@ struct iwl_mod_params iwlwifi_mod_params = { .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, .uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT, + .enable_ini = true, /* the rest are 0 by default */ }; IWL_EXPORT_SYMBOL(iwlwifi_mod_params); @@ -1837,7 +1838,7 @@ MODULE_PARM_DESC(uapsd_disable, module_param_named(enable_ini, iwlwifi_mod_params.enable_ini, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(enable_ini, - "Enable debug INI TLV FW debug infrastructure (default: 0"); + "Enable debug INI TLV FW debug infrastructure (default: true"); /* * set bt_coex_active to true, uCode will do kill/defer -- cgit From 2681f15d94b1a01d60acc313c6b61688209c9c2d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Nov 2019 13:48:15 +0100 Subject: iwlwifi: remove IWL_FW_DBG_DOMAIN macro This is used to initialize the default value, but refers back to the value itself, essentially leading to a val = val assignment at init time ... that's useless, remove it and use _NODEF. Change-Id: I725923016563c34ce2fa057bf7c12984e1041c49 Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index f8c6ed823bc5..da0d90e2b537 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -69,8 +69,6 @@ #include "iwl-eeprom-parse.h" #include "fw/acpi.h" -#define IWL_FW_DBG_DOMAIN IWL_TRANS_FW_DBG_DOMAIN(fwrt->trans) - struct iwl_fw_runtime_ops { int (*dump_start)(void *ctx); void (*dump_end)(void *ctx); -- cgit From adc311a5bbf643eef6702006c03d34d827392f05 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 1 Oct 2019 09:38:08 +0300 Subject: iwlwifi: bump FW API to 53 for 22000 series Start supporting API version 53 for 22000 series. Change-Id: I5725e46394f3f53c3069723fd513cc53c7df383d Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index a88aa15afc8c..73dbd012cac7 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -57,7 +57,7 @@ #include "iwl-prph.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 52 +#define IWL_22000_UCODE_API_MAX 53 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39 -- cgit From 7216dc99b75814b06b3532e85a2fae07f5166bde Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 16 Nov 2019 17:05:00 +0100 Subject: iwlwifi: pcie: make iwl_pcie_cmdq_reclaim static There's no need for this to be exposed outside of the tx.c file, make it static. Change-Id: I41d40008311b108d0578bd2ec73c5477e700a839 Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 - drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 72f144c3a46e..595e6873d56e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -718,7 +718,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_tx_cmd *dev_cmd, int txq_id); void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); -void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx); void iwl_pcie_gen2_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq); void iwl_pcie_hcmd_complete(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 2f69a6469fe7..4582d418ba4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1287,7 +1287,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, * need to be reclaimed. As result, some free space forms. If there is * enough free space (> low mark), wake the stack that feeds us. */ -void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) +static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans_pcie->txq[txq_id]; -- cgit From 84acc85a62a171de98706b9b2cc73a660088314a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Nov 2019 11:25:28 +0100 Subject: iwlwifi: mvm: remove newline from rs_pretty_print_rate() Some of the places using this want the newline, but not all, so remove the newline from it and generate it in the debugfs files where it's desired. The effect of this is not printing double newlines in debug log messages. Change-Id: Ia59b0abbef16b6783fcabc095c5fde16bd047a26 Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 190cf15b825c..3beef8d077b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -461,6 +461,8 @@ static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf, desc += rs_pretty_print_rate(buff + desc, bufsz - desc, lq_sta->last_rate_n_flags); + if (desc < bufsz - 1) + buff[desc++] = '\n'; mutex_unlock(&mvm->mutex); ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); @@ -1013,6 +1015,8 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm, (int)(ARRAY_SIZE(stats->last_rates) - i)); pos += rs_pretty_print_rate(pos, endpos - pos, stats->last_rates[idx]); + if (pos < endpos - 1) + *pos++ = '\n'; } spin_unlock_bh(&mvm->drv_stats_lock); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 1a990ed9c3ca..c1aba2bf73cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3697,7 +3697,7 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) !(rate & RATE_MCS_HE_MSK)) { int index = iwl_hwrate_to_plcp_idx(rate); - return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps\n", + return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", rs_pretty_ant(ant), index == IWL_RATE_INVALID ? "BAD" : iwl_rate_mcs[index].mbps); @@ -3740,7 +3740,7 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) } return scnprintf(buf, bufsz, - "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s\n", + "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s", rate, type, rs_pretty_ant(ant), bw, mcs, nss, (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", @@ -3888,6 +3888,8 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, desc += scnprintf(buff + desc, bufsz - desc, " rate[%d] 0x%X ", i, r); desc += rs_pretty_print_rate(buff + desc, bufsz - desc, r); + if (desc < bufsz - 1) + buff[desc++] = '\n'; } ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); -- cgit