Wi-Fi 8 RX TID setup needs host-created REO queue descriptors so the common datapath can program per-TID reorder state without relying on the Wi-Fi 7 descriptor layout. Add helpers to size, initialize, and release Wi-Fi 8 REO queue descriptors. Keep non-QoS queues simple and allocate extension descriptors only for QoS TIDs that can use a larger reorder window. Tested-on: Compilation only, M=drivers/net/wireless/ath/ath12k Signed-off-by: Pradeep Kumar Chitrapu --- drivers/net/wireless/ath/ath12k/wifi8/hal_desc.h | 98 +++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi8/hal_rx.c | 106 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi8/hal_rx.h | 15 ++++ 3 files changed, 219 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wifi8/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi8/hal_desc.h index e2947dd112ce..a7db304a197c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi8/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi8/hal_desc.h @@ -1108,10 +1108,22 @@ struct hal_uniform_tqm_cmd_hdr { #define HAL_TQM_MSDU_RBM_OVERRIDE GENMASK(23, 20) #define HAL_TQM_MSDU_RESERVED_4 GENMASK(31, 24) +#define HAL_DESC_REO_OWNED 4 +#define HAL_DESC_REO_QUEUE_DESC 8 +#define HAL_DESC_REO_QUEUE_EXT_DESC 10 + +#define HAL_DESC_HDR_INFO0_OWNER GENMASK(3, 0) +#define HAL_DESC_HDR_INFO0_BUF_TYPE GENMASK(7, 4) +#define HAL_DESC_HDR_INFO0_DBG_RESERVED GENMASK(31, 8) + struct hal_desc_header { __le32 info0; } __packed; +struct hal_rx_mpdu_link_ptr { + struct ath12k_buffer_addr addr_info; +} __packed; + /* Per-MSDU entry within a Wi-Fi 8 link descriptor. */ struct hal_rx_msdu_details { struct ath12k_buffer_addr buf_addr_info; @@ -1596,6 +1608,92 @@ struct hal_tqm2sw_completion_ring { __le32 info4; } __packed; +struct hal_rx_reo_queue_ext { + struct hal_desc_header desc_hdr; + __le32 rsvd; + struct hal_rx_mpdu_link_ptr mpdu_link[31]; +} __packed; + +#define HAL_RX_REO_QUEUE_INFO0_VLD BIT(0) +#define HAL_RX_REO_QUEUE_INFO0_ASSOCIATED_LINK_DESCRIPTOR_COUNTER GENMASK(2, 1) +#define HAL_RX_REO_QUEUE_INFO0_LINK_LIST_TIMER_IDX GENMASK(8, 5) +#define HAL_RX_REO_QUEUE_INFO0_RTY BIT(10) +#define HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE GENMASK(22, 13) +#define HAL_RX_REO_QUEUE_INFO0_PN_CHECK_NEEDED BIT(23) +#define HAL_RX_REO_QUEUE_INFO0_PN_SIZE GENMASK(28, 27) +#define HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLAG BIT(29) + +#define HAL_RX_REO_QUEUE_INFO1_SVLD BIT(0) +#define HAL_RX_REO_QUEUE_INFO1_SSN GENMASK(12, 1) + +#define HAL_RX_REO_QUEUE_INFO2_STATS_ID GENMASK(10, 0) + +struct hal_rx_reo_queue { + struct hal_desc_header desc_hdr; + __le16 receive_queue_number; + __le16 rsvd0; + __le32 info0; + __le16 info1; + __le16 rsvd1; + __le32 pn_31_0; + __le16 pn_47_32; + __le16 rsvd2; + __le32 rsvd3[2]; + __le32 last_rx_enqueue_timestamp; + __le32 last_rx_dequeue_timestamp; + __le32 ptr_to_next_aging_queue_31_0; + __le32 rsvd4; + __le32 ptr_to_previous_aging_queue_31_0; + __le16 rsvd5; + __le16 info2; + __le32 rx_bitmap_31_0; + __le32 rx_bitmap_63_32; + __le32 rx_bitmap_95_64; + __le32 rx_bitmap_127_96; + __le32 rx_bitmap_159_128; + __le32 rx_bitmap_191_160; + __le32 rx_bitmap_223_192; + __le32 rx_bitmap_255_224; + __le32 rx_bitmap_287_256; + __le32 rsvd6; + __le16 rsvd7; + __le16 duplicate_count; + __le32 rsvd8; + __le32 mpdu_frames_processed_count; + __le32 msdu_frames_processed_count; + __le32 total_processed_byte_count; + __le16 rsvd9; + __le16 hole_count; + __le16 aging_drop_mpdu_count; + __le16 rsvd10; + __le32 sawf_dropped_msdu_frames_processed_cnt; + __le32 rx_bitmap_319_288; + __le32 rx_bitmap_351_320; + __le32 rx_bitmap_383_352; + __le32 rx_bitmap_415_384; + __le32 rx_bitmap_447_416; + __le32 rx_bitmap_479_448; + __le32 rx_bitmap_511_480; + __le32 rx_bitmap_543_512; + __le32 rx_bitmap_575_544; + __le32 rx_bitmap_607_576; + __le32 rx_bitmap_639_608; + __le32 rx_bitmap_671_640; + __le32 rx_bitmap_703_672; + __le32 rx_bitmap_735_704; + __le32 rx_bitmap_767_736; + __le32 rx_bitmap_799_768; + __le32 rx_bitmap_831_800; + __le32 rx_bitmap_863_832; + __le32 rx_bitmap_895_864; + __le32 rx_bitmap_927_896; + __le32 rx_bitmap_959_928; + __le32 rx_bitmap_991_960; + __le32 rx_bitmap_1023_992; + __le32 rsvd11[9]; + struct hal_rx_reo_queue_ext ext_desc[]; +}; + #define HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO GENMASK(31, 0) #define HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI GENMASK(7, 0) diff --git a/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.c index 12a37c395bb0..ad00c182c2bd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.c @@ -9,6 +9,26 @@ #include "hal_rx.h" #include "hal.h" +static void ath12k_wifi8_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, + u8 owner, u8 buffer_type, + u32 magic) +{ + hdr->info0 = le32_encode_bits(owner, HAL_DESC_HDR_INFO0_OWNER) | + le32_encode_bits(buffer_type, HAL_DESC_HDR_INFO0_BUF_TYPE) | + le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); +} + +static u32 ath12k_wifi8_hal_reo_num_ext_desc(u32 ba_window_size) +{ + if (ba_window_size <= 217) + return 1; + + if (ba_window_size <= 434) + return 2; + + return REO_QUEUE_EXT_DESC_MAX; +} + static void ath12k_wifi8_reo_dest_ring_ctrl_setup(struct ath12k_base *ab, u32 start, u32 end, u32 reg_add) { @@ -886,3 +906,89 @@ void ath12k_wifi8_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, ath12k_wifi8_hal_reo_status_hdr_parse(desc, status); } + +u32 ath12k_wifi8_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) +{ + u32 num_ext_desc = ath12k_wifi8_hal_reo_num_ext_desc(ba_window_size); + + if (tid != HAL_DESC_REO_NON_QOS_TID) + num_ext_desc = REO_QUEUE_EXT_DESC_MAX; + + return sizeof(struct hal_rx_reo_queue) + + num_ext_desc * sizeof(struct hal_rx_reo_queue_ext); +} + +void ath12k_wifi8_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type) +{ + static const u32 reo_queue_desc_magic[REO_QUEUE_EXT_DESC_MAX] = { + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_4, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_5, + }; + struct hal_rx_reo_queue_ext *ext_desc; + u32 num_ext_desc; + int i; + + ath12k_wifi8_hal_reo_set_desc_hdr(&qdesc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); + + qdesc->receive_queue_number = cpu_to_le16(tid); + + qdesc->info0 = + le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_VLD) | + le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_ASSOCIATED_LINK_DESCRIPTOR_COUNTER) | + le32_encode_bits(ath12k_tid_to_ac(tid), HAL_RX_REO_QUEUE_INFO0_LINK_LIST_TIMER_IDX); + + if (ba_window_size < 1) + ba_window_size = 1; + + if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID) + ba_window_size++; + + if (ba_window_size == 1) + qdesc->info0 |= le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_RTY); + + qdesc->info0 |= le32_encode_bits(ba_window_size - 1, + HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE); + + 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 |= + le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_PN_CHECK_NEEDED) | + le32_encode_bits(HAL_RX_REO_QUEUE_PN_SIZE_48, + HAL_RX_REO_QUEUE_INFO0_PN_SIZE); + break; + } + + qdesc->info0 |= le32_encode_bits(1, + HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLAG); + + qdesc->info1 = le16_encode_bits(0, HAL_RX_REO_QUEUE_INFO1_SVLD); + + if (start_seq <= 0xfff) + qdesc->info1 = le16_encode_bits(start_seq, + HAL_RX_REO_QUEUE_INFO1_SSN); + + if (tid == HAL_DESC_REO_NON_QOS_TID) + return; + + ext_desc = qdesc->ext_desc; + num_ext_desc = REO_QUEUE_EXT_DESC_MAX; + + memset(ext_desc, 0, num_ext_desc * sizeof(*ext_desc)); + for (i = 0; i < num_ext_desc; i++) + ath12k_wifi8_hal_reo_set_desc_hdr(&ext_desc[i].desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + reo_queue_desc_magic[i]); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.h index 430b0f07563f..94732f82f614 100644 --- a/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi8/hal_rx.h @@ -7,6 +7,9 @@ #ifndef ATH12K_HAL_RX_H #define ATH12K_HAL_RX_H +#include "hal_desc.h" +#include "hal.h" + #define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) #define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1) #define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2) @@ -84,6 +87,14 @@ /* 8 buffers for max-size SG MPDU + 1 entry to confirm termination */ #define HAL_REO_SG_TERMINATION_MIN_ENTRIES 9 +#define REO_QUEUE_EXT_DESC_MAX 5 +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0 0xDDBEEF +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1 0xADBEEF +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3 0xCDBEEF +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_4 0xEDBEEF +#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_5 0xFDBEEF + struct ath12k_hal_rx_cmd_ring_param { u32 mac_addr_31_0; u32 mac_addr_47_32:16, @@ -142,4 +153,8 @@ void ath12k_wifi8_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, void ath12k_wifi8_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, struct hal_reo_status *status); +u32 ath12k_wifi8_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); +void ath12k_wifi8_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type); #endif -- 2.43.0