diff options
-rw-r--r-- | drivers/net/wireless/ath/ath12k/dp_rx.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/hal.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/hal.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/rx_desc.h | 2 |
4 files changed, 45 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 5c2316e40019..ca76c018dd0c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -233,6 +233,12 @@ static u16 ath12k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath12k_base *ab, return ab->hal_rx_ops->rx_desc_get_mpdu_frame_ctl(desc); } +static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); +} + static int ath12k_dp_purge_mon_ring(struct ath12k_base *ab) { int i, reaped = 0; @@ -3695,16 +3701,15 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct hal_rx_wbm_rel_info err_info; struct hal_srng *srng; struct sk_buff *msdu; - struct sk_buff_head msdu_list[MAX_RADIOS]; + struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; void *rx_desc; - int mac_id; + u8 mac_id; int num_buffs_reaped = 0; struct ath12k_rx_desc_info *desc_info; - int ret, i; + int ret, pdev_id; - for (i = 0; i < ab->num_radios; i++) - __skb_queue_head_init(&msdu_list[i]); + __skb_queue_head_init(&msdu_list); srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; rx_ring = &dp->rx_refill_buf_ring; @@ -3737,11 +3742,6 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, } } - /* FIXME: Extract mac id correctly. Since descs are not tied - * to mac, we can extract from vdev id in ring desc. - */ - mac_id = 0; - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); @@ -3771,7 +3771,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, rxcb->err_rel_src = err_info.err_rel_src; rxcb->err_code = err_info.err_code; rxcb->rx_desc = (struct hal_rx_desc *)msdu->data; - __skb_queue_tail(&msdu_list[mac_id], msdu); + + __skb_queue_tail(&msdu_list, msdu); rxcb->is_first_msdu = err_info.first_msdu; rxcb->is_last_msdu = err_info.last_msdu; @@ -3788,21 +3789,22 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped); rcu_read_lock(); - for (i = 0; i < ab->num_radios; i++) { - if (!rcu_dereference(ab->pdevs_active[i])) { - __skb_queue_purge(&msdu_list[i]); + while ((msdu = __skb_dequeue(&msdu_list))) { + mac_id = ath12k_dp_rx_get_msdu_src_link(ab, + (struct hal_rx_desc *)msdu->data); + pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); + ar = ab->pdevs[pdev_id].ar; + + if (!ar || !rcu_dereference(ar->ab->pdevs_active[mac_id])) { + dev_kfree_skb_any(msdu); continue; } - ar = ab->pdevs[i].ar; - if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) { - __skb_queue_purge(&msdu_list[i]); + dev_kfree_skb_any(msdu); continue; } - - while ((msdu = __skb_dequeue(&msdu_list[i])) != NULL) - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list[i]); + ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); } rcu_read_unlock(); done: diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index cb540251acf8..78310da8cfe8 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -700,6 +700,11 @@ static u32 ath12k_hw_qcn9274_get_rx_desc_size(void) return sizeof(struct hal_rx_desc_qcn9274); } +static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return 0; +} + const struct hal_rx_ops hal_rx_qcn9274_ops = { .rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu, @@ -738,6 +743,7 @@ const struct hal_rx_ops hal_rx_qcn9274_ops = { .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted, .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err, .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, + .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, }; static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) @@ -1033,6 +1039,12 @@ static u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) return sizeof(struct hal_rx_desc_qcn9274_compact); } +static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, + RX_MSDU_END_64_TLV_SRC_LINK_ID); +} + const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, @@ -1076,6 +1088,8 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted, .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err, .rx_desc_get_desc_size = ath12k_hw_qcn9274_compact_get_rx_desc_size, + .rx_desc_get_msdu_src_link_id = + ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, }; const struct hal_ops hal_qcn9274_ops = { @@ -1504,6 +1518,11 @@ static u32 ath12k_hw_wcn7850_get_rx_desc_size(void) return sizeof(struct hal_rx_desc_wcn7850); } +static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return 0; +} + const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, @@ -1543,6 +1562,7 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted, .dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err, .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, + .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, }; const struct hal_ops hal_wcn7850_ops = { diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index b7d78ba2b801..107927d64bbb 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1078,6 +1078,7 @@ struct hal_rx_ops { bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); u32 (*rx_desc_get_desc_size)(void); + u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); }; struct hal_ops { diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/rx_desc.h index d5fd3a3b6b4d..a0db6702a189 100644 --- a/drivers/net/wireless/ath/ath12k/rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/rx_desc.h @@ -663,6 +663,8 @@ enum rx_msdu_start_reception_type { RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, }; +#define RX_MSDU_END_64_TLV_SRC_LINK_ID GENMASK(24, 22) + #define RX_MSDU_END_INFO0_RXPCU_MPDU_FITLER GENMASK(1, 0) #define RX_MSDU_END_INFO0_SW_FRAME_GRP_ID GENMASK(8, 2) |