diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k')
29 files changed, 4725 insertions, 2666 deletions
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 969bf1a590d9..b5a2af3ffc3e 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -37,7 +37,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw = { .dir = "IPQ8074/hw2.0", .board_size = 256 * 1024, - .cal_size = 256 * 1024, + .cal_offset = 128 * 1024, }, .max_radios = 3, .bdf_addr = 0x4B0C0000, @@ -58,8 +58,17 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, - .spectral_fft_sz = 2, + + .spectral = { + .fft_sz = 2, + /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes. + * so added pad size as 2 bytes to compensate the BIN size + */ + .fft_pad_sz = 2, + .summary_pad_sz = 0, + .fft_hdr_len = 16, + .max_fft_bins = 512, + }, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -71,6 +80,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -78,7 +89,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw = { .dir = "IPQ6018/hw1.0", .board_size = 256 * 1024, - .cal_size = 256 * 1024, + .cal_offset = 128 * 1024, }, .max_radios = 2, .bdf_addr = 0x4ABC0000, @@ -99,8 +110,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, - .spectral_fft_sz = 4, + + .spectral = { + .fft_sz = 4, + .fft_pad_sz = 0, + .summary_pad_sz = 0, + .fft_hdr_len = 16, + .max_fft_bins = 512, + }, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -112,6 +129,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .name = "qca6390 hw2.0", @@ -119,7 +138,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw = { .dir = "QCA6390/hw2.0", .board_size = 256 * 1024, - .cal_size = 256 * 1024, + .cal_offset = 128 * 1024, }, .max_radios = 3, .bdf_addr = 0x4B0C0000, @@ -140,8 +159,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = true, .vdev_start_delay = true, .htt_peer_map_v2 = false, - .tcl_0_only = true, - .spectral_fft_sz = 0, + + .spectral = { + .fft_sz = 0, + .fft_pad_sz = 0, + .summary_pad_sz = 0, + .fft_hdr_len = 0, + .max_fft_bins = 0, + }, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), @@ -152,6 +177,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, }, { .name = "qcn9074 hw1.0", @@ -159,7 +186,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw = { .dir = "QCN9074/hw1.0", .board_size = 256 * 1024, - .cal_size = 256 * 1024, + .cal_offset = 128 * 1024, }, .max_radios = 1, .single_pdev_only = false, @@ -179,7 +206,15 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = false, .vdev_start_delay = false, .htt_peer_map_v2 = true, - .tcl_0_only = false, + + .spectral = { + .fft_sz = 2, + .fft_pad_sz = 0, + .summary_pad_sz = 16, + .fft_hdr_len = 24, + .max_fft_bins = 1024, + }, + .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT), @@ -190,6 +225,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .fix_l1ss = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .name = "wcn6855 hw2.0", @@ -197,7 +234,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw = { .dir = "WCN6855/hw2.0", .board_size = 256 * 1024, - .cal_size = 256 * 1024, + .cal_offset = 128 * 1024, }, .max_radios = 3, .bdf_addr = 0x4B0C0000, @@ -218,8 +255,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .rx_mac_buf_ring = true, .vdev_start_delay = true, .htt_peer_map_v2 = false, - .tcl_0_only = true, - .spectral_fft_sz = 0, + + .spectral = { + .fft_sz = 0, + .fft_pad_sz = 0, + .summary_pad_sz = 0, + .fft_hdr_len = 0, + .max_fft_bins = 0, + }, .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), @@ -230,6 +273,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .fix_l1ss = false, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, }, }; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 018fb2385f2a..31d234a51c79 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -93,6 +93,8 @@ struct ath11k_skb_rxcb { bool is_first_msdu; bool is_last_msdu; bool is_continuation; + bool is_mcbc; + bool is_eapol; struct hal_rx_desc *rx_desc; u8 err_rel_src; u8 err_code; @@ -100,6 +102,8 @@ struct ath11k_skb_rxcb { u8 unmapped; u8 is_frag; u8 tid; + u16 peer_id; + u16 seq_no; }; enum ath11k_hw_rev { @@ -193,7 +197,9 @@ enum ath11k_dev_flags { }; enum ath11k_monitor_flags { - ATH11K_FLAG_MONITOR_ENABLED, + ATH11K_FLAG_MONITOR_CONF_ENABLED, + ATH11K_FLAG_MONITOR_STARTED, + ATH11K_FLAG_MONITOR_VDEV_CREATED, }; struct ath11k_vif { @@ -362,6 +368,7 @@ struct ath11k_sta { enum hal_pn_type pn_type; struct work_struct update_wk; + struct work_struct set_4addr_wk; struct rate_info txrate; struct rate_info last_txrate; u64 rx_duration; @@ -374,12 +381,15 @@ struct ath11k_sta { /* protected by conf_mutex */ bool aggr_mode; #endif + + bool use_4addr_set; + u16 tcl_metadata; }; #define ATH11K_MIN_5G_FREQ 4150 -#define ATH11K_MIN_6G_FREQ 5945 +#define ATH11K_MIN_6G_FREQ 5925 #define ATH11K_MAX_6G_FREQ 7115 -#define ATH11K_NUM_CHANS 100 +#define ATH11K_NUM_CHANS 101 #define ATH11K_MAX_5G_CHAN 173 enum ath11k_state { @@ -484,7 +494,6 @@ struct ath11k { u32 chan_tx_pwr; u32 num_stations; u32 max_num_stations; - bool monitor_present; /* To synchronize concurrent synchronous mac80211 callback operations, * concurrent debugfs configuration and concurrent FW statistics events. */ @@ -559,6 +568,7 @@ struct ath11k { struct ath11k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; u32 cached_ppdu_id; + int monitor_vdev_id; #ifdef CONFIG_ATH11K_DEBUGFS struct ath11k_debug debug; #endif @@ -591,6 +601,8 @@ struct ath11k_pdev_cap { u32 tx_chain_mask_shift; u32 rx_chain_mask_shift; struct ath11k_band_cap band[NUM_NL80211_BANDS]; + bool nss_ratio_enabled; + u8 nss_ratio_info; }; struct ath11k_pdev { @@ -794,12 +806,15 @@ struct ath11k_fw_stats_pdev { s32 hw_reaped; /* Num underruns */ s32 underrun; + /* Num hw paused */ + u32 hw_paused; /* Num PPDUs cleaned up in TX abort */ s32 tx_abort; /* Num MPDUs requeued by SW */ s32 mpdus_requeued; /* excessive retries */ u32 tx_ko; + u32 tx_xretry; /* data hw rate code */ u32 data_rc; /* Scheduler self triggers */ @@ -820,6 +835,30 @@ struct ath11k_fw_stats_pdev { u32 phy_underrun; /* MPDU is more than txop limit */ u32 txop_ovf; + /* Num sequences posted */ + u32 seq_posted; + /* Num sequences failed in queueing */ + u32 seq_failed_queueing; + /* Num sequences completed */ + u32 seq_completed; + /* Num sequences restarted */ + u32 seq_restarted; + /* Num of MU sequences posted */ + u32 mu_seq_posted; + /* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT + * (Reset,channel change) + */ + s32 mpdus_sw_flush; + /* Num MPDUs filtered by HW, all filter condition (TTL expired) */ + s32 mpdus_hw_filter; + /* Num MPDUs truncated by PDG (TXOP, TBTT, + * PPDU_duration based on rate, dyn_bw) + */ + s32 mpdus_truncated; + /* Num MPDUs that was tried but didn't receive ACK or BA */ + s32 mpdus_ack_failed; + /* Num MPDUs that was dropped du to expiry. */ + s32 mpdus_expired; /* PDEV RX stats */ /* Cnts any change in ring routing mid-ppdu */ @@ -845,6 +884,8 @@ struct ath11k_fw_stats_pdev { s32 phy_err_drop; /* Number of mpdu errors - FCS, MIC, ENC etc. */ s32 mpdu_errs; + /* Num overflow errors */ + s32 rx_ovfl_errs; }; struct ath11k_fw_stats_vdev { diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c index 5e1f5437b418..fd98ba5b1130 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -8,8 +8,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, struct ath11k_dbring *ring, - struct ath11k_dbring_element *buff, - gfp_t gfp) + struct ath11k_dbring_element *buff) { struct ath11k_base *ab = ar->ab; struct hal_srng *srng; @@ -35,7 +34,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, goto err; spin_lock_bh(&ring->idr_lock); - buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp); + buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, GFP_ATOMIC); spin_unlock_bh(&ring->idr_lock); if (buf_id < 0) { ret = -ENOBUFS; @@ -72,8 +71,7 @@ err: } static int ath11k_dbring_fill_bufs(struct ath11k *ar, - struct ath11k_dbring *ring, - gfp_t gfp) + struct ath11k_dbring *ring) { struct ath11k_dbring_element *buff; struct hal_srng *srng; @@ -92,11 +90,11 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar, size = sizeof(*buff) + ring->buf_sz + align - 1; while (num_remain > 0) { - buff = kzalloc(size, gfp); + buff = kzalloc(size, GFP_ATOMIC); if (!buff) break; - ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp); + ret = ath11k_dbring_bufs_replenish(ar, ring, buff); if (ret) { ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n", num_remain, req_entries); @@ -176,7 +174,7 @@ int ath11k_dbring_buf_setup(struct ath11k *ar, ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng); ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng); - ret = ath11k_dbring_fill_bufs(ar, ring, GFP_KERNEL); + ret = ath11k_dbring_fill_bufs(ar, ring); return ret; } @@ -322,7 +320,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, } memset(buff, 0, size); - ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC); + ath11k_dbring_bufs_replenish(ar, ring, buff); } spin_unlock_bh(&srng->lock); diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 554feaf1ed5c..80afd35337a1 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -806,7 +806,7 @@ static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file, len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n"); len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + for (i = 0; i < ab->hw_params.max_tx_ring; i++) len += scnprintf(buf + len, size - len, "ring%d: %u\n", i, soc_stats->tx_err.desc_na[i]); @@ -902,7 +902,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, struct htt_rx_ring_tlv_filter tlv_filter = {0}; u32 rx_filter = 0, ring_id, filter, mode; u8 buf[128] = {0}; - int i, ret; + int i, ret, rx_buf_sz = 0; ssize_t rc; mutex_lock(&ar->conf_mutex); @@ -940,6 +940,17 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, } } + /* Clear rx filter set for monitor mode and rx status */ + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id, + HAL_RXDMA_MONITOR_STATUS, + rx_buf_sz, &tlv_filter); + if (ret) { + ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n"); + goto out; + } + } #define HTT_RX_FILTER_TLV_LITE_MODE \ (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ @@ -955,6 +966,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, HTT_RX_FILTER_TLV_FLAGS_MPDU_END | HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | HTT_RX_FILTER_TLV_FLAGS_ATTENTION; + rx_buf_sz = DP_RX_BUFFER_SIZE; } else if (mode == ATH11K_PKTLOG_MODE_LITE) { ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, HTT_PPDU_STATS_TAG_PKTLOG); @@ -964,7 +976,12 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, } rx_filter = HTT_RX_FILTER_TLV_LITE_MODE; + rx_buf_sz = DP_RX_BUFFER_SIZE_LITE; } else { + rx_buf_sz = DP_RX_BUFFER_SIZE; + tlv_filter = ath11k_mac_mon_status_filter_default; + rx_filter = tlv_filter.rx_filter; + ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, HTT_PPDU_STATS_TAG_DEFAULT); if (ret) { @@ -988,7 +1005,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id, ar->dp.mac_id + i, HAL_RXDMA_MONITOR_STATUS, - DP_RX_BUFFER_SIZE, &tlv_filter); + rx_buf_sz, &tlv_filter); if (ret) { ath11k_warn(ab, "failed to set rx filter for monitor status ring\n"); @@ -996,8 +1013,8 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file, } } - ath11k_dbg(ab, ATH11K_DBG_WMI, "pktlog filter %d mode %s\n", - filter, ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite")); + ath11k_info(ab, "pktlog mode %s\n", + ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite")); ar->debug.pktlog_filter = filter; ar->debug.pktlog_mode = mode; diff --git a/drivers/net/wireless/ath/ath11k/debugfs.h b/drivers/net/wireless/ath/ath11k/debugfs.h index e5346af71f24..ec743a015dc7 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.h +++ b/drivers/net/wireless/ath/ath11k/debugfs.h @@ -38,6 +38,10 @@ enum ath11k_dbg_htt_ext_stats_type { 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, + ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS = 29, + ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_RATE_TXBF_STATS = 31, + ATH11K_DBG_HTT_EXT_STATS_TXBF_OFDMA = 32, + ATH11K_DBG_HTT_EXT_PHY_COUNTERS_AND_PHY_STATS = 37, /* keep this last */ ATH11K_DBG_HTT_NUM_EXT_STATS, diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c index 9e0c90da99d3..4484235bcda4 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c @@ -10,23 +10,28 @@ #include "debug.h" #include "debugfs_htt_stats.h" -#define HTT_DBG_OUT(buf, len, fmt, ...) \ - scnprintf(buf, len, fmt "\n", ##__VA_ARGS__) - -#define HTT_MAX_STRING_LEN 256 #define HTT_MAX_PRINT_CHAR_PER_ELEM 15 #define HTT_TLV_HDR_LEN 4 -#define ARRAY_TO_STRING(out, arr, len) \ +#define PRINT_ARRAY_TO_BUF(out, buflen, arr, str, len, newline) \ do { \ - int index = 0; u8 i; \ + int index = 0; u8 i; const char *str_val = str; \ + const char *new_line = newline; \ + if (str_val) { \ + index += scnprintf((out + buflen), \ + (ATH11K_HTT_STATS_BUF_SIZE - buflen), \ + "%s = ", str_val); \ + } \ for (i = 0; i < len; i++) { \ - index += scnprintf(out + index, HTT_MAX_STRING_LEN - index, \ - " %u:%u,", i, arr[i]); \ - if (index < 0 || index >= HTT_MAX_STRING_LEN) \ - break; \ + index += scnprintf((out + buflen) + index, \ + (ATH11K_HTT_STATS_BUF_SIZE - buflen) - index, \ + " %u:%u,", i, arr[i]); \ } \ + index += scnprintf((out + buflen) + index, \ + (ATH11K_HTT_STATS_BUF_SIZE - buflen) - index, \ + "%s", new_line); \ + buflen += index; \ } while (0) static inline void htt_print_stats_string_tlv(const void *tag_buf, @@ -38,22 +43,20 @@ static inline void htt_print_stats_string_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u8 i; - u16 index = 0; - char data[HTT_MAX_STRING_LEN] = {0}; tag_len = tag_len >> 2; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, + "data = "); for (i = 0; i < tag_len; i++) { - index += scnprintf(&data[index], - HTT_MAX_STRING_LEN - index, - "%.*s", 4, (char *)&(htt_stats_buf->data[i])); - if (index >= HTT_MAX_STRING_LEN) - break; + len += scnprintf(buf + len, + buf_len - len, + "%.*s", 4, (char *)&(htt_stats_buf->data[i])); } - - len += HTT_DBG_OUT(buf + len, buf_len - len, "data = %s\n", data); + /* New lines are added for better display */ + len += scnprintf(buf + len, buf_len - len, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -71,107 +74,107 @@ static inline void htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_queued = %u", - htt_stats_buf->hw_queued); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_reaped = %u", - htt_stats_buf->hw_reaped); - len += HTT_DBG_OUT(buf + len, buf_len - len, "underrun = %u", - htt_stats_buf->underrun); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_paused = %u", - htt_stats_buf->hw_paused); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_flush = %u", - htt_stats_buf->hw_flush); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_filt = %u", - htt_stats_buf->hw_filt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_abort = %u", - htt_stats_buf->tx_abort); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_requeued = %u", - htt_stats_buf->mpdu_requeued); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_xretry = %u", - htt_stats_buf->tx_xretry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "data_rc = %u", - htt_stats_buf->data_rc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_dropped_xretry = %u", - htt_stats_buf->mpdu_dropped_xretry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "illegal_rate_phy_err = %u", - htt_stats_buf->illgl_rate_phy_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cont_xretry = %u", - htt_stats_buf->cont_xretry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_timeout = %u", - htt_stats_buf->tx_timeout); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pdev_resets = %u", - htt_stats_buf->pdev_resets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "phy_underrun = %u", - htt_stats_buf->phy_underrun); - len += HTT_DBG_OUT(buf + len, buf_len - len, "txop_ovf = %u", - htt_stats_buf->txop_ovf); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_posted = %u", - htt_stats_buf->seq_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_failed_queueing = %u", - htt_stats_buf->seq_failed_queueing); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_completed = %u", - htt_stats_buf->seq_completed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_restarted = %u", - htt_stats_buf->seq_restarted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_seq_posted = %u", - htt_stats_buf->mu_seq_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_switch_hw_paused = %u", - htt_stats_buf->seq_switch_hw_paused); - len += HTT_DBG_OUT(buf + len, buf_len - len, "next_seq_posted_dsr = %u", - htt_stats_buf->next_seq_posted_dsr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_posted_isr = %u", - htt_stats_buf->seq_posted_isr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "seq_ctrl_cached = %u", - htt_stats_buf->seq_ctrl_cached); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_count_tqm = %u", - htt_stats_buf->mpdu_count_tqm); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_count_tqm = %u", - htt_stats_buf->msdu_count_tqm); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_removed_tqm = %u", - htt_stats_buf->mpdu_removed_tqm); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_removed_tqm = %u", - htt_stats_buf->msdu_removed_tqm); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_sw_flush = %u", - htt_stats_buf->mpdus_sw_flush); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_hw_filter = %u", - htt_stats_buf->mpdus_hw_filter); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_truncated = %u", - htt_stats_buf->mpdus_truncated); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_ack_failed = %u", - htt_stats_buf->mpdus_ack_failed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_expired = %u", - htt_stats_buf->mpdus_expired); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u", - htt_stats_buf->mpdus_seq_hw_retry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ack_tlv_proc = %u", - htt_stats_buf->ack_tlv_proc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u", - htt_stats_buf->coex_abort_mpdu_cnt_valid); - len += HTT_DBG_OUT(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u", - htt_stats_buf->coex_abort_mpdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u", - htt_stats_buf->num_total_ppdus_tried_ota); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u", - htt_stats_buf->num_data_ppdus_tried_ota); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u", - htt_stats_buf->local_ctrl_mgmt_enqued); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u", - htt_stats_buf->local_ctrl_mgmt_freed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_data_enqued = %u", - htt_stats_buf->local_data_enqued); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_data_freed = %u", - htt_stats_buf->local_data_freed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_tried = %u", - htt_stats_buf->mpdu_tried); - len += HTT_DBG_OUT(buf + len, buf_len - len, "isr_wait_seq_posted = %u", - htt_stats_buf->isr_wait_seq_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_active_dur_us_low = %u", - htt_stats_buf->tx_active_dur_us_low); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n", - htt_stats_buf->tx_active_dur_us_high); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n", + htt_stats_buf->hw_queued); + len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n", + htt_stats_buf->hw_reaped); + len += scnprintf(buf + len, buf_len - len, "underrun = %u\n", + htt_stats_buf->underrun); + len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n", + htt_stats_buf->hw_paused); + len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n", + htt_stats_buf->hw_flush); + len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n", + htt_stats_buf->hw_filt); + len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n", + htt_stats_buf->tx_abort); + len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n", + htt_stats_buf->mpdu_requeued); + len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n", + htt_stats_buf->tx_xretry); + len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n", + htt_stats_buf->data_rc); + len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n", + htt_stats_buf->mpdu_dropped_xretry); + len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n", + htt_stats_buf->illgl_rate_phy_err); + len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n", + htt_stats_buf->cont_xretry); + len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n", + htt_stats_buf->tx_timeout); + len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n", + htt_stats_buf->pdev_resets); + len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n", + htt_stats_buf->phy_underrun); + len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n", + htt_stats_buf->txop_ovf); + len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n", + htt_stats_buf->seq_posted); + len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n", + htt_stats_buf->seq_failed_queueing); + len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n", + htt_stats_buf->seq_completed); + len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n", + htt_stats_buf->seq_restarted); + len += scnprintf(buf + len, buf_len - len, "mu_seq_posted = %u\n", + htt_stats_buf->mu_seq_posted); + len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n", + htt_stats_buf->seq_switch_hw_paused); + len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n", + htt_stats_buf->next_seq_posted_dsr); + len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n", + htt_stats_buf->seq_posted_isr); + len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n", + htt_stats_buf->seq_ctrl_cached); + len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n", + htt_stats_buf->mpdu_count_tqm); + len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n", + htt_stats_buf->msdu_count_tqm); + len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n", + htt_stats_buf->mpdu_removed_tqm); + len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n", + htt_stats_buf->msdu_removed_tqm); + len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n", + htt_stats_buf->mpdus_sw_flush); + len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n", + htt_stats_buf->mpdus_hw_filter); + len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n", + htt_stats_buf->mpdus_truncated); + len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n", + htt_stats_buf->mpdus_ack_failed); + len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n", + htt_stats_buf->mpdus_expired); + len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n", + htt_stats_buf->mpdus_seq_hw_retry); + len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", + htt_stats_buf->ack_tlv_proc); + len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n", + htt_stats_buf->coex_abort_mpdu_cnt_valid); + len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n", + htt_stats_buf->coex_abort_mpdu_cnt); + len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n", + htt_stats_buf->num_total_ppdus_tried_ota); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n", + htt_stats_buf->num_data_ppdus_tried_ota); + len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n", + htt_stats_buf->local_ctrl_mgmt_enqued); + len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n", + htt_stats_buf->local_ctrl_mgmt_freed); + len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n", + htt_stats_buf->local_data_enqued); + len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n", + htt_stats_buf->local_data_freed); + len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n", + htt_stats_buf->mpdu_tried); + len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n", + htt_stats_buf->isr_wait_seq_posted); + len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n", + htt_stats_buf->tx_active_dur_us_low); + len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n\n", + htt_stats_buf->tx_active_dur_us_high); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -190,13 +193,12 @@ htt_print_tx_pdev_stats_urrn_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char urrn_stats[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_URRN_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_URRN_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_URRN_TLV_V:\n"); - ARRAY_TO_STRING(urrn_stats, htt_stats_buf->urrn_stats, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "urrn_stats = %s\n", urrn_stats); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->urrn_stats, "urrn_stats", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -215,13 +217,12 @@ htt_print_tx_pdev_stats_flush_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char flush_errs[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_FLUSH_REASON_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_FLUSH_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_FLUSH_TLV_V:\n"); - ARRAY_TO_STRING(flush_errs, htt_stats_buf->flush_errs, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "flush_errs = %s\n", flush_errs); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->flush_errs, "flush_errs", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -240,14 +241,12 @@ htt_print_tx_pdev_stats_sifs_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sifs_status[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_SIFS_BURST_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_SIFS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_SIFS_TLV_V:\n"); - ARRAY_TO_STRING(sifs_status, htt_stats_buf->sifs_status, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sifs_status = %s\n", - sifs_status); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sifs_status, "sifs_status", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -266,13 +265,12 @@ htt_print_tx_pdev_stats_phy_err_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char phy_errs[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_PHY_ERR_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_PHY_ERR_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_PHY_ERR_TLV_V:\n"); - ARRAY_TO_STRING(phy_errs, htt_stats_buf->phy_errs, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "phy_errs = %s\n", phy_errs); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->phy_errs, "phy_errs", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -291,15 +289,13 @@ htt_print_tx_pdev_stats_sifs_hist_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sifs_hist_status[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_STATS_SIFS_HIST_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_STATS_SIFS_HIST_TLV_V:\n"); - ARRAY_TO_STRING(sifs_hist_status, htt_stats_buf->sifs_hist_status, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sifs_hist_status = %s\n", - sifs_hist_status); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sifs_hist_status, + "sifs_hist_status", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -318,23 +314,23 @@ htt_print_tx_pdev_stats_tx_ppdu_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_STATS_TX_PPDU_STATS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_STATS_TX_PPDU_STATS_TLV_V:\n"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_legacy_su = %u", - htt_stats_buf->num_data_ppdus_legacy_su); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_legacy_su = %u\n", + htt_stats_buf->num_data_ppdus_legacy_su); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_ac_su = %u", - htt_stats_buf->num_data_ppdus_ac_su); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ac_su = %u\n", + htt_stats_buf->num_data_ppdus_ac_su); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_ax_su = %u", - htt_stats_buf->num_data_ppdus_ax_su); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ax_su = %u\n", + htt_stats_buf->num_data_ppdus_ax_su); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_ac_su_txbf = %u", - htt_stats_buf->num_data_ppdus_ac_su_txbf); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ac_su_txbf = %u\n", + htt_stats_buf->num_data_ppdus_ac_su_txbf); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_data_ppdus_ax_su_txbf = %u\n", - htt_stats_buf->num_data_ppdus_ax_su_txbf); + len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ax_su_txbf = %u\n\n", + htt_stats_buf->num_data_ppdus_ax_su_txbf); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -353,25 +349,15 @@ htt_print_tx_pdev_stats_tried_mpdu_cnt_hist_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char tried_mpdu_cnt_hist[HTT_MAX_STRING_LEN] = {0}; u32 num_elements = ((tag_len - sizeof(htt_stats_buf->hist_bin_size)) >> 2); - u32 required_buffer_size = HTT_MAX_PRINT_CHAR_PER_ELEM * num_elements; - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_STATS_TRIED_MPDU_CNT_HIST_TLV_V:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u", - htt_stats_buf->hist_bin_size); - - if (required_buffer_size < HTT_MAX_STRING_LEN) { - ARRAY_TO_STRING(tried_mpdu_cnt_hist, - htt_stats_buf->tried_mpdu_cnt_hist, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tried_mpdu_cnt_hist = %s\n", - tried_mpdu_cnt_hist); - } else { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "INSUFFICIENT PRINT BUFFER\n"); - } + + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_STATS_TRIED_MPDU_CNT_HIST_TLV_V:\n"); + len += scnprintf(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u\n", + htt_stats_buf->hist_bin_size); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tried_mpdu_cnt_hist, + "tried_mpdu_cnt_hist", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -390,14 +376,14 @@ static inline void htt_print_hw_stats_intr_misc_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; char hw_intr_name[HTT_STATS_MAX_HW_INTR_NAME_LEN + 1] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n"); memcpy(hw_intr_name, &(htt_stats_buf->hw_intr_name[0]), HTT_STATS_MAX_HW_INTR_NAME_LEN); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_intr_name = %s ", hw_intr_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mask = %u", - htt_stats_buf->mask); - len += HTT_DBG_OUT(buf + len, buf_len - len, "count = %u\n", - htt_stats_buf->count); + len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n", hw_intr_name); + len += scnprintf(buf + len, buf_len - len, "mask = %u\n", + htt_stats_buf->mask); + len += scnprintf(buf + len, buf_len - len, "count = %u\n\n", + htt_stats_buf->count); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -417,13 +403,13 @@ htt_print_hw_stats_wd_timeout_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; char hw_module_name[HTT_STATS_MAX_HW_MODULE_NAME_LEN + 1] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_HW_STATS_WD_TIMEOUT_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WD_TIMEOUT_TLV:\n"); memcpy(hw_module_name, &(htt_stats_buf->hw_module_name[0]), HTT_STATS_MAX_HW_MODULE_NAME_LEN); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_module_name = %s ", - hw_module_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "count = %u", - htt_stats_buf->count); + len += scnprintf(buf + len, buf_len - len, "hw_module_name = %s\n", + hw_module_name); + len += scnprintf(buf + len, buf_len - len, "count = %u\n", + htt_stats_buf->count); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -441,29 +427,29 @@ static inline void htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_abort = %u", - htt_stats_buf->tx_abort); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_abort_fail_count = %u", - htt_stats_buf->tx_abort_fail_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_abort = %u", - htt_stats_buf->rx_abort); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_abort_fail_count = %u", - htt_stats_buf->rx_abort_fail_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "warm_reset = %u", - htt_stats_buf->warm_reset); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cold_reset = %u", - htt_stats_buf->cold_reset); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_flush = %u", - htt_stats_buf->tx_flush); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_glb_reset = %u", - htt_stats_buf->tx_glb_reset); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_txq_reset = %u", - htt_stats_buf->tx_txq_reset); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_timeout_reset = %u\n", - htt_stats_buf->rx_timeout_reset); + len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n", + htt_stats_buf->tx_abort); + len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n", + htt_stats_buf->tx_abort_fail_count); + len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n", + htt_stats_buf->rx_abort); + len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n", + htt_stats_buf->rx_abort_fail_count); + len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n", + htt_stats_buf->warm_reset); + len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n", + htt_stats_buf->cold_reset); + len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n", + htt_stats_buf->tx_flush); + len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n", + htt_stats_buf->tx_glb_reset); + len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n", + htt_stats_buf->tx_txq_reset); + len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n", + htt_stats_buf->rx_timeout_reset); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -481,35 +467,36 @@ static inline void htt_print_msdu_flow_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_MSDU_FLOW_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_update_timestamp = %u", - htt_stats_buf->last_update_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_add_timestamp = %u", - htt_stats_buf->last_add_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_remove_timestamp = %u", - htt_stats_buf->last_remove_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "total_processed_msdu_count = %u", - htt_stats_buf->total_processed_msdu_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cur_msdu_count_in_flowq = %u", - htt_stats_buf->cur_msdu_count_in_flowq); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sw_peer_id = %u", - htt_stats_buf->sw_peer_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_flow_no = %u", - htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_num = %u", - (htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0xF0000) >> - 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "drop_rule = %u", - (htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0x100000) >> - 20); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_cycle_enqueue_count = %u", - htt_stats_buf->last_cycle_enqueue_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_cycle_dequeue_count = %u", - htt_stats_buf->last_cycle_dequeue_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_cycle_drop_count = %u", - htt_stats_buf->last_cycle_drop_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "current_drop_th = %u\n", - htt_stats_buf->current_drop_th); + len += scnprintf(buf + len, buf_len - len, "HTT_MSDU_FLOW_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "last_update_timestamp = %u\n", + htt_stats_buf->last_update_timestamp); + len += scnprintf(buf + len, buf_len - len, "last_add_timestamp = %u\n", + htt_stats_buf->last_add_timestamp); + len += scnprintf(buf + len, buf_len - len, "last_remove_timestamp = %u\n", + htt_stats_buf->last_remove_timestamp); + len += scnprintf(buf + len, buf_len - len, "total_processed_msdu_count = %u\n", + htt_stats_buf->total_processed_msdu_count); + len += scnprintf(buf + len, buf_len - len, "cur_msdu_count_in_flowq = %u\n", + htt_stats_buf->cur_msdu_count_in_flowq); + len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n", + htt_stats_buf->sw_peer_id); + len += scnprintf(buf + len, buf_len - len, "tx_flow_no = %lu\n", + FIELD_GET(HTT_MSDU_FLOW_STATS_TX_FLOW_NO, + htt_stats_buf->tx_flow_no__tid_num__drop_rule)); + len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n", + FIELD_GET(HTT_MSDU_FLOW_STATS_TID_NUM, + htt_stats_buf->tx_flow_no__tid_num__drop_rule)); + len += scnprintf(buf + len, buf_len - len, "drop_rule = %lu\n", + FIELD_GET(HTT_MSDU_FLOW_STATS_DROP_RULE, + htt_stats_buf->tx_flow_no__tid_num__drop_rule)); + len += scnprintf(buf + len, buf_len - len, "last_cycle_enqueue_count = %u\n", + htt_stats_buf->last_cycle_enqueue_count); + len += scnprintf(buf + len, buf_len - len, "last_cycle_dequeue_count = %u\n", + htt_stats_buf->last_cycle_dequeue_count); + len += scnprintf(buf + len, buf_len - len, "last_cycle_drop_count = %u\n", + htt_stats_buf->last_cycle_drop_count); + len += scnprintf(buf + len, buf_len - len, "current_drop_th = %u\n\n", + htt_stats_buf->current_drop_th); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -528,38 +515,41 @@ static inline void htt_print_tx_tid_stats_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; char tid_name[MAX_HTT_TID_NAME + 1] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TID_STATS_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_TLV:\n"); memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_name = %s ", tid_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sw_peer_id = %u", - htt_stats_buf->sw_peer_id__tid_num & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_num = %u", - (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_sched_pending = %u", - htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_ppdu_in_hwq = %u", - (htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & - 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_flags = 0x%x", - htt_stats_buf->tid_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_queued = %u", - htt_stats_buf->hw_queued); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hw_reaped = %u", - htt_stats_buf->hw_reaped); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdus_hw_filter = %u", - htt_stats_buf->mpdus_hw_filter); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_bytes = %u", - htt_stats_buf->qdepth_bytes); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_num_msdu = %u", - htt_stats_buf->qdepth_num_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_num_mpdu = %u", - htt_stats_buf->qdepth_num_mpdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_scheduled_tsmp = %u", - htt_stats_buf->last_scheduled_tsmp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pause_module_id = %u", - htt_stats_buf->pause_module_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "block_module_id = %u\n", - htt_stats_buf->block_module_id); + len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name); + len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_SW_PEER_ID, + htt_stats_buf->sw_peer_id__tid_num)); + len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_TID_NUM, + htt_stats_buf->sw_peer_id__tid_num)); + len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_NUM_SCHED_PENDING, + htt_stats_buf->num_sched_pending__num_ppdu_in_hwq)); + len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ, + htt_stats_buf->num_sched_pending__num_ppdu_in_hwq)); + len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n", + htt_stats_buf->tid_flags); + len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n", + htt_stats_buf->hw_queued); + len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n", + htt_stats_buf->hw_reaped); + len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n", + htt_stats_buf->mpdus_hw_filter); + len += scnprintf(buf + len, buf_len - len, "qdepth_bytes = %u\n", + htt_stats_buf->qdepth_bytes); + len += scnprintf(buf + len, buf_len - len, "qdepth_num_msdu = %u\n", + htt_stats_buf->qdepth_num_msdu); + len += scnprintf(buf + len, buf_len - len, "qdepth_num_mpdu = %u\n", + htt_stats_buf->qdepth_num_mpdu); + len += scnprintf(buf + len, buf_len - len, "last_scheduled_tsmp = %u\n", + htt_stats_buf->last_scheduled_tsmp); + len += scnprintf(buf + len, buf_len - len, "pause_module_id = %u\n", + htt_stats_buf->pause_module_id); + len += scnprintf(buf + len, buf_len - len, "block_module_id = %u\n\n", + htt_stats_buf->block_module_id); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -578,42 +568,45 @@ static inline void htt_print_tx_tid_stats_v1_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; char tid_name[MAX_HTT_TID_NAME + 1] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TID_STATS_V1_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_V1_TLV:\n"); memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_name = %s ", tid_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sw_peer_id = %u", - htt_stats_buf->sw_peer_id__tid_num & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_num = %u", - (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_sched_pending = %u", - htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_ppdu_in_hwq = %u", - (htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & - 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_flags = 0x%x", - htt_stats_buf->tid_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "max_qdepth_bytes = %u", - htt_stats_buf->max_qdepth_bytes); - len += HTT_DBG_OUT(buf + len, buf_len - len, "max_qdepth_n_msdus = %u", - htt_stats_buf->max_qdepth_n_msdus); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rsvd = %u", - htt_stats_buf->rsvd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_bytes = %u", - htt_stats_buf->qdepth_bytes); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_num_msdu = %u", - htt_stats_buf->qdepth_num_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qdepth_num_mpdu = %u", - htt_stats_buf->qdepth_num_mpdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_scheduled_tsmp = %u", - htt_stats_buf->last_scheduled_tsmp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pause_module_id = %u", - htt_stats_buf->pause_module_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "block_module_id = %u", - htt_stats_buf->block_module_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "allow_n_flags = 0x%x", - htt_stats_buf->allow_n_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sendn_frms_allowed = %u\n", - htt_stats_buf->sendn_frms_allowed); + len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name); + len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_V1_SW_PEER_ID, + htt_stats_buf->sw_peer_id__tid_num)); + len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_V1_TID_NUM, + htt_stats_buf->sw_peer_id__tid_num)); + len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING, + htt_stats_buf->num_sched_pending__num_ppdu_in_hwq)); + len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n", + FIELD_GET(HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ, + htt_stats_buf->num_sched_pending__num_ppdu_in_hwq)); + len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n", + htt_stats_buf->tid_flags); + len += scnprintf(buf + len, buf_len - len, "max_qdepth_bytes = %u\n", + htt_stats_buf->max_qdepth_bytes); + len += scnprintf(buf + len, buf_len - len, "max_qdepth_n_msdus = %u\n", + htt_stats_buf->max_qdepth_n_msdus); + len += scnprintf(buf + len, buf_len - len, "rsvd = %u\n", + htt_stats_buf->rsvd); + len += scnprintf(buf + len, buf_len - len, "qdepth_bytes = %u\n", + htt_stats_buf->qdepth_bytes); + len += scnprintf(buf + len, buf_len - len, "qdepth_num_msdu = %u\n", + htt_stats_buf->qdepth_num_msdu); + len += scnprintf(buf + len, buf_len - len, "qdepth_num_mpdu = %u\n", + htt_stats_buf->qdepth_num_mpdu); + len += scnprintf(buf + len, buf_len - len, "last_scheduled_tsmp = %u\n", + htt_stats_buf->last_scheduled_tsmp); + len += scnprintf(buf + len, buf_len - len, "pause_module_id = %u\n", + htt_stats_buf->pause_module_id); + len += scnprintf(buf + len, buf_len - len, "block_module_id = %u\n", + htt_stats_buf->block_module_id); + len += scnprintf(buf + len, buf_len - len, "allow_n_flags = 0x%x\n", + htt_stats_buf->allow_n_flags); + len += scnprintf(buf + len, buf_len - len, "sendn_frms_allowed = %u\n\n", + htt_stats_buf->sendn_frms_allowed); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -632,21 +625,23 @@ static inline void htt_print_rx_tid_stats_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; char tid_name[MAX_HTT_TID_NAME + 1] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_TID_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sw_peer_id = %u", - htt_stats_buf->sw_peer_id__tid_num & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_num = %u", - (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_TID_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n", + FIELD_GET(HTT_RX_TID_STATS_SW_PEER_ID, + htt_stats_buf->sw_peer_id__tid_num)); + len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n", + FIELD_GET(HTT_RX_TID_STATS_TID_NUM, + htt_stats_buf->sw_peer_id__tid_num)); memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tid_name = %s ", tid_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dup_in_reorder = %u", - htt_stats_buf->dup_in_reorder); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dup_past_outside_window = %u", - htt_stats_buf->dup_past_outside_window); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dup_past_within_window = %u", - htt_stats_buf->dup_past_within_window); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rxdesc_err_decrypt = %u\n", - htt_stats_buf->rxdesc_err_decrypt); + len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name); + len += scnprintf(buf + len, buf_len - len, "dup_in_reorder = %u\n", + htt_stats_buf->dup_in_reorder); + len += scnprintf(buf + len, buf_len - len, "dup_past_outside_window = %u\n", + htt_stats_buf->dup_past_outside_window); + len += scnprintf(buf + len, buf_len - len, "dup_past_within_window = %u\n", + htt_stats_buf->dup_past_within_window); + len += scnprintf(buf + len, buf_len - len, "rxdesc_err_decrypt = %u\n\n", + htt_stats_buf->rxdesc_err_decrypt); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -663,16 +658,14 @@ static inline void htt_print_counter_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char counter_name[HTT_MAX_STRING_LEN] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_COUNTER_TLV:"); + len += scnprintf(buf + len, buf_len - len, "HTT_COUNTER_TLV:\n"); - ARRAY_TO_STRING(counter_name, - htt_stats_buf->counter_name, - HTT_MAX_COUNTER_NAME); - len += HTT_DBG_OUT(buf + len, buf_len - len, "counter_name = %s ", counter_name); - len += HTT_DBG_OUT(buf + len, buf_len - len, "count = %u\n", - htt_stats_buf->count); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->counter_name, + "counter_name", + HTT_MAX_COUNTER_NAME, "\n"); + len += scnprintf(buf + len, buf_len - len, "count = %u\n\n", + htt_stats_buf->count); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -690,35 +683,35 @@ static inline void htt_print_peer_stats_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_PEER_STATS_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ppdu_cnt = %u", - htt_stats_buf->ppdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_cnt = %u", - htt_stats_buf->mpdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_cnt = %u", - htt_stats_buf->msdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pause_bitmap = %u", - htt_stats_buf->pause_bitmap); - len += HTT_DBG_OUT(buf + len, buf_len - len, "block_bitmap = %u", - htt_stats_buf->block_bitmap); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_rssi = %d", - htt_stats_buf->rssi); - len += HTT_DBG_OUT(buf + len, buf_len - len, "enqueued_count = %llu", - htt_stats_buf->peer_enqueued_count_low | - ((u64)htt_stats_buf->peer_enqueued_count_high << 32)); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dequeued_count = %llu", - htt_stats_buf->peer_dequeued_count_low | - ((u64)htt_stats_buf->peer_dequeued_count_high << 32)); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dropped_count = %llu", - htt_stats_buf->peer_dropped_count_low | - ((u64)htt_stats_buf->peer_dropped_count_high << 32)); - len += HTT_DBG_OUT(buf + len, buf_len - len, "transmitted_ppdu_bytes = %llu", - htt_stats_buf->ppdu_transmitted_bytes_low | - ((u64)htt_stats_buf->ppdu_transmitted_bytes_high << 32)); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ttl_removed_count = %u", - htt_stats_buf->peer_ttl_removed_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "inactive_time = %u\n", - htt_stats_buf->inactive_time); + len += scnprintf(buf + len, buf_len - len, "HTT_PEER_STATS_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ppdu_cnt = %u\n", + htt_stats_buf->ppdu_cnt); + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt = %u\n", + htt_stats_buf->mpdu_cnt); + len += scnprintf(buf + len, buf_len - len, "msdu_cnt = %u\n", + htt_stats_buf->msdu_cnt); + len += scnprintf(buf + len, buf_len - len, "pause_bitmap = %u\n", + htt_stats_buf->pause_bitmap); + len += scnprintf(buf + len, buf_len - len, "block_bitmap = %u\n", + htt_stats_buf->block_bitmap); + len += scnprintf(buf + len, buf_len - len, "last_rssi = %d\n", + htt_stats_buf->rssi); + len += scnprintf(buf + len, buf_len - len, "enqueued_count = %llu\n", + htt_stats_buf->peer_enqueued_count_low | + ((u64)htt_stats_buf->peer_enqueued_count_high << 32)); + len += scnprintf(buf + len, buf_len - len, "dequeued_count = %llu\n", + htt_stats_buf->peer_dequeued_count_low | + ((u64)htt_stats_buf->peer_dequeued_count_high << 32)); + len += scnprintf(buf + len, buf_len - len, "dropped_count = %llu\n", + htt_stats_buf->peer_dropped_count_low | + ((u64)htt_stats_buf->peer_dropped_count_high << 32)); + len += scnprintf(buf + len, buf_len - len, "transmitted_ppdu_bytes = %llu\n", + htt_stats_buf->ppdu_transmitted_bytes_low | + ((u64)htt_stats_buf->ppdu_transmitted_bytes_high << 32)); + len += scnprintf(buf + len, buf_len - len, "ttl_removed_count = %u\n", + htt_stats_buf->peer_ttl_removed_count); + len += scnprintf(buf + len, buf_len - len, "inactive_time = %u\n\n", + htt_stats_buf->inactive_time); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -736,29 +729,38 @@ static inline void htt_print_peer_details_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_PEER_DETAILS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "peer_type = %u", - htt_stats_buf->peer_type); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sw_peer_id = %u", - htt_stats_buf->sw_peer_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "vdev_id = %u", - htt_stats_buf->vdev_pdev_ast_idx & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pdev_id = %u", - (htt_stats_buf->vdev_pdev_ast_idx & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ast_idx = %u", - (htt_stats_buf->vdev_pdev_ast_idx & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "mac_addr = %02x:%02x:%02x:%02x:%02x:%02x", - htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF, - (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF00) >> 8, - (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF0000) >> 16, - (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF000000) >> 24, - (htt_stats_buf->mac_addr.mac_addr_h16 & 0xFF), - (htt_stats_buf->mac_addr.mac_addr_h16 & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "peer_flags = 0x%x", - htt_stats_buf->peer_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qpeer_flags = 0x%x\n", - htt_stats_buf->qpeer_flags); + len += scnprintf(buf + len, buf_len - len, "HTT_PEER_DETAILS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "peer_type = %u\n", + htt_stats_buf->peer_type); + len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n", + htt_stats_buf->sw_peer_id); + len += scnprintf(buf + len, buf_len - len, "vdev_id = %lu\n", + FIELD_GET(HTT_PEER_DETAILS_VDEV_ID, + htt_stats_buf->vdev_pdev_ast_idx)); + len += scnprintf(buf + len, buf_len - len, "pdev_id = %lu\n", + FIELD_GET(HTT_PEER_DETAILS_PDEV_ID, + htt_stats_buf->vdev_pdev_ast_idx)); + len += scnprintf(buf + len, buf_len - len, "ast_idx = %lu\n", + FIELD_GET(HTT_PEER_DETAILS_AST_IDX, + htt_stats_buf->vdev_pdev_ast_idx)); + len += scnprintf(buf + len, buf_len - len, + "mac_addr = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n", + FIELD_GET(HTT_MAC_ADDR_L32_0, + htt_stats_buf->mac_addr.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_1, + htt_stats_buf->mac_addr.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_2, + htt_stats_buf->mac_addr.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_3, + htt_stats_buf->mac_addr.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_H16_0, + htt_stats_buf->mac_addr.mac_addr_h16), + FIELD_GET(HTT_MAC_ADDR_H16_1, + htt_stats_buf->mac_addr.mac_addr_h16)); + len += scnprintf(buf + len, buf_len - len, "peer_flags = 0x%x\n", + htt_stats_buf->peer_flags); + len += scnprintf(buf + len, buf_len - len, "qpeer_flags = 0x%x\n\n", + htt_stats_buf->qpeer_flags); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -775,74 +777,40 @@ static inline void htt_print_tx_peer_rate_stats_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char str_buf[HTT_MAX_STRING_LEN] = {0}; - char *tx_gi[HTT_TX_PEER_STATS_NUM_GI_COUNTERS] = {NULL}; u8 j; - for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) { - tx_gi[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!tx_gi[j]) - goto fail; - } - - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PEER_RATE_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_ldpc = %u", - htt_stats_buf->tx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts_cnt = %u", - htt_stats_buf->rts_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ack_rssi = %u", - htt_stats_buf->ack_rssi); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_su_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_su_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mu_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mu_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, - htt_stats_buf->tx_nss, - HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, - htt_stats_buf->tx_bw, - HTT_TX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_bw = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_stbc, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_stbc = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_pream, - HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_pream = %s ", str_buf); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PEER_RATE_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "tx_ldpc = %u\n", + htt_stats_buf->tx_ldpc); + len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n", + htt_stats_buf->rts_cnt); + len += scnprintf(buf + len, buf_len - len, "ack_rssi = %u\n", + htt_stats_buf->ack_rssi); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mcs, "tx_mcs", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_su_mcs, "tx_su_mcs", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mu_mcs, "tx_mu_mcs", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_nss, "tx_nss", + HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_bw, "tx_bw", + HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_stbc, "tx_stbc", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_pream, "tx_pream", + HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n"); for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(tx_gi[j], - htt_stats_buf->tx_gi[j], - HTT_TX_PEER_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_gi[%u] = %s ", - j, tx_gi[j]); + len += scnprintf(buf + len, buf_len - len, + "tx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_gi[j], NULL, + HTT_TX_PEER_STATS_NUM_MCS_COUNTERS, "\n"); } - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, - htt_stats_buf->tx_dcm, - HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_dcm = %s\n", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_dcm, "tx_dcm", + HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -850,10 +818,6 @@ static inline void htt_print_tx_peer_rate_stats_tlv(const void *tag_buf, buf[len] = 0; stats_req->buf_len = len; - -fail: - for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) - kfree(tx_gi[j]); } static inline void htt_print_rx_peer_rate_stats_tlv(const void *tag_buf, @@ -864,79 +828,48 @@ static inline void htt_print_rx_peer_rate_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u8 j; - char *rssi_chain[HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS] = {NULL}; - char *rx_gi[HTT_RX_PEER_STATS_NUM_GI_COUNTERS] = {NULL}; - char str_buf[HTT_MAX_STRING_LEN] = {0}; - - for (j = 0; j < HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS; j++) { - rssi_chain[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!rssi_chain[j]) - goto fail; - } - - for (j = 0; j < HTT_RX_PEER_STATS_NUM_GI_COUNTERS; j++) { - rx_gi[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!rx_gi[j]) - goto fail; - } - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PEER_RATE_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "nsts = %u", - htt_stats_buf->nsts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ldpc = %u", - htt_stats_buf->rx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts_cnt = %u", - htt_stats_buf->rts_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_mgmt = %u", - htt_stats_buf->rssi_mgmt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_data = %u", - htt_stats_buf->rssi_data); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_comb = %u", - htt_stats_buf->rssi_comb); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_mcs, - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_nss, - HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_dcm, - HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_dcm = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_stbc, - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_stbc = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_bw, - HTT_RX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_bw = %s ", str_buf); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PEER_RATE_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "nsts = %u\n", + htt_stats_buf->nsts); + len += scnprintf(buf + len, buf_len - len, "rx_ldpc = %u\n", + htt_stats_buf->rx_ldpc); + len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n", + htt_stats_buf->rts_cnt); + len += scnprintf(buf + len, buf_len - len, "rssi_mgmt = %u\n", + htt_stats_buf->rssi_mgmt); + len += scnprintf(buf + len, buf_len - len, "rssi_data = %u\n", + htt_stats_buf->rssi_data); + len += scnprintf(buf + len, buf_len - len, "rssi_comb = %u\n", + htt_stats_buf->rssi_comb); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_mcs, "rx_mcs", + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_nss, "rx_nss", + HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_dcm, "rx_dcm", + HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_stbc, "rx_stbc", + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_bw, "rx_bw", + HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); for (j = 0; j < HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS; j++) { - ARRAY_TO_STRING(rssi_chain[j], htt_stats_buf->rssi_chain[j], - HTT_RX_PEER_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_chain[%u] = %s ", - j, rssi_chain[j]); + len += scnprintf(buf + len, (buf_len - len), + "rssi_chain[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rssi_chain[j], NULL, + HTT_RX_PEER_STATS_NUM_BW_COUNTERS, "\n"); } for (j = 0; j < HTT_RX_PEER_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->rx_gi[j], - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_gi[%u] = %s ", - j, rx_gi[j]); + len += scnprintf(buf + len, (buf_len - len), + "rx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_gi[j], NULL, + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_pream, - HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_pream = %s\n", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_pream, "rx_pream", + HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -944,13 +877,6 @@ static inline void htt_print_rx_peer_rate_stats_tlv(const void *tag_buf, buf[len] = 0; stats_req->buf_len = len; - -fail: - for (j = 0; j < HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS; j++) - kfree(rssi_chain[j]); - - for (j = 0; j < HTT_RX_PEER_STATS_NUM_GI_COUNTERS; j++) - kfree(rx_gi[j]); } static inline void @@ -962,13 +888,13 @@ htt_print_tx_hwq_mu_mimo_sch_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_SCH_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_sch_posted = %u", - htt_stats_buf->mu_mimo_sch_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_sch_failed = %u", - htt_stats_buf->mu_mimo_sch_failed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n", - htt_stats_buf->mu_mimo_ppdu_posted); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_SCH_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n", + htt_stats_buf->mu_mimo_sch_posted); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n", + htt_stats_buf->mu_mimo_sch_failed); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n\n", + htt_stats_buf->mu_mimo_ppdu_posted); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -987,22 +913,22 @@ htt_print_tx_hwq_mu_mimo_mpdu_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_MU_MIMO_MPDU_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_mpdus_queued_usr = %u", - htt_stats_buf->mu_mimo_mpdus_queued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_mpdus_tried_usr = %u", - htt_stats_buf->mu_mimo_mpdus_tried_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_mpdus_failed_usr = %u", - htt_stats_buf->mu_mimo_mpdus_failed_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_mpdus_requeued_usr = %u", - htt_stats_buf->mu_mimo_mpdus_requeued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_err_no_ba_usr = %u", - htt_stats_buf->mu_mimo_err_no_ba_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_mpdu_underrun_usr = %u", - htt_stats_buf->mu_mimo_mpdu_underrun_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_ampdu_underrun_usr = %u\n", - htt_stats_buf->mu_mimo_ampdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_MU_MIMO_MPDU_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_queued_usr = %u\n", + htt_stats_buf->mu_mimo_mpdus_queued_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_tried_usr = %u\n", + htt_stats_buf->mu_mimo_mpdus_tried_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_failed_usr = %u\n", + htt_stats_buf->mu_mimo_mpdus_failed_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_requeued_usr = %u\n", + htt_stats_buf->mu_mimo_mpdus_requeued_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_err_no_ba_usr = %u\n", + htt_stats_buf->mu_mimo_err_no_ba_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdu_underrun_usr = %u\n", + htt_stats_buf->mu_mimo_mpdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_ampdu_underrun_usr = %u\n\n", + htt_stats_buf->mu_mimo_ampdu_underrun_usr); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1021,11 +947,13 @@ htt_print_tx_hwq_mu_mimo_cmn_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_CMN_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__hwq_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwq_id = %u\n", - (htt_stats_buf->mac_id__hwq_id__word & 0xFF00) >> 8); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_CMN_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID, + htt_stats_buf->mac_id__hwq_id__word)); + len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n\n", + FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID, + htt_stats_buf->mac_id__hwq_id__word)); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1044,51 +972,53 @@ htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, struct debug_htt_stats_req * u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; /* TODO: HKDBG */ - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__hwq_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwq_id = %u", - (htt_stats_buf->mac_id__hwq_id__word & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "xretry = %u", - htt_stats_buf->xretry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "underrun_cnt = %u", - htt_stats_buf->underrun_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "flush_cnt = %u", - htt_stats_buf->flush_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "filt_cnt = %u", - htt_stats_buf->filt_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "null_mpdu_bmap = %u", - htt_stats_buf->null_mpdu_bmap); - len += HTT_DBG_OUT(buf + len, buf_len - len, "user_ack_failure = %u", - htt_stats_buf->user_ack_failure); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ack_tlv_proc = %u", - htt_stats_buf->ack_tlv_proc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_id_proc = %u", - htt_stats_buf->sched_id_proc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "null_mpdu_tx_count = %u", - htt_stats_buf->null_mpdu_tx_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u", - htt_stats_buf->mpdu_bmap_not_recvd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_bar = %u", - htt_stats_buf->num_bar); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts = %u", - htt_stats_buf->rts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cts2self = %u", - htt_stats_buf->cts2self); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qos_null = %u", - htt_stats_buf->qos_null); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_tried_cnt = %u", - htt_stats_buf->mpdu_tried_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_queued_cnt = %u", - htt_stats_buf->mpdu_queued_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u", - htt_stats_buf->mpdu_ack_fail_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_filt_cnt = %u", - htt_stats_buf->mpdu_filt_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "false_mpdu_ack_count = %u", - htt_stats_buf->false_mpdu_ack_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "txq_timeout = %u\n", - htt_stats_buf->txq_timeout); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID, + htt_stats_buf->mac_id__hwq_id__word)); + len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n", + FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID, + htt_stats_buf->mac_id__hwq_id__word)); + len += scnprintf(buf + len, buf_len - len, "xretry = %u\n", + htt_stats_buf->xretry); + len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n", + htt_stats_buf->underrun_cnt); + len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n", + htt_stats_buf->flush_cnt); + len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n", + htt_stats_buf->filt_cnt); + len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n", + htt_stats_buf->null_mpdu_bmap); + len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n", + htt_stats_buf->user_ack_failure); + len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", + htt_stats_buf->ack_tlv_proc); + len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n", + htt_stats_buf->sched_id_proc); + len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n", + htt_stats_buf->null_mpdu_tx_count); + len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n", + htt_stats_buf->mpdu_bmap_not_recvd); + len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n", + htt_stats_buf->num_bar); + len += scnprintf(buf + len, buf_len - len, "rts = %u\n", + htt_stats_buf->rts); + len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n", + htt_stats_buf->cts2self); + len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n", + htt_stats_buf->qos_null); + len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n", + htt_stats_buf->mpdu_tried_cnt); + len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n", + htt_stats_buf->mpdu_queued_cnt); + len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n", + htt_stats_buf->mpdu_ack_fail_cnt); + len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n", + htt_stats_buf->mpdu_filt_cnt); + len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n", + htt_stats_buf->false_mpdu_ack_count); + len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n\n", + htt_stats_buf->txq_timeout); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1108,17 +1038,14 @@ htt_print_tx_hwq_difs_latency_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u16 data_len = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_DIFS_LATENCY_BINS); - char difs_latency_hist[HTT_MAX_STRING_LEN] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_DIFS_LATENCY_STATS_TLV_V:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hist_intvl = %u", - htt_stats_buf->hist_intvl); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_DIFS_LATENCY_STATS_TLV_V:\n"); + len += scnprintf(buf + len, buf_len - len, "hist_intvl = %u\n", + htt_stats_buf->hist_intvl); - ARRAY_TO_STRING(difs_latency_hist, htt_stats_buf->difs_latency_hist, - data_len); - len += HTT_DBG_OUT(buf + len, buf_len - len, "difs_latency_hist = %s\n", - difs_latency_hist); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->difs_latency_hist, + "difs_latency_hist", data_len, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1138,16 +1065,14 @@ htt_print_tx_hwq_cmd_result_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u16 data_len; - char cmd_result[HTT_MAX_STRING_LEN] = {0}; data_len = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_CMD_RESULT_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_CMD_RESULT_STATS_TLV_V:"); - - ARRAY_TO_STRING(cmd_result, htt_stats_buf->cmd_result, data_len); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_CMD_RESULT_STATS_TLV_V:\n"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cmd_result = %s\n", cmd_result); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->cmd_result, "cmd_result", + data_len, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1167,15 +1092,13 @@ htt_print_tx_hwq_cmd_stall_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u16 num_elems; - char cmd_stall_status[HTT_MAX_STRING_LEN] = {0}; num_elems = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_CMD_STALL_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_HWQ_CMD_STALL_STATS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_CMD_STALL_STATS_TLV_V:\n"); - ARRAY_TO_STRING(cmd_stall_status, htt_stats_buf->cmd_stall_status, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cmd_stall_status = %s\n", - cmd_stall_status); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->cmd_stall_status, + "cmd_stall_status", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1195,15 +1118,14 @@ htt_print_tx_hwq_fes_result_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u16 num_elems; - char fes_result[HTT_MAX_STRING_LEN] = {0}; num_elems = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_FES_RESULT_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_FES_RESULT_STATS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_FES_RESULT_STATS_TLV_V:\n"); - ARRAY_TO_STRING(fes_result, htt_stats_buf->fes_result, num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fes_result = %s\n", fes_result); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fes_result, "fes_result", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1222,27 +1144,16 @@ htt_print_tx_hwq_tried_mpdu_cnt_hist_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char tried_mpdu_cnt_hist[HTT_MAX_STRING_LEN] = {0}; u32 num_elements = ((tag_len - sizeof(htt_stats_buf->hist_bin_size)) >> 2); - u32 required_buffer_size = HTT_MAX_PRINT_CHAR_PER_ELEM * num_elements; - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_TRIED_MPDU_CNT_HIST_TLV_V:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u", - htt_stats_buf->hist_bin_size); - - if (required_buffer_size < HTT_MAX_STRING_LEN) { - ARRAY_TO_STRING(tried_mpdu_cnt_hist, - htt_stats_buf->tried_mpdu_cnt_hist, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "tried_mpdu_cnt_hist = %s\n", - tried_mpdu_cnt_hist); - } else { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "INSUFFICIENT PRINT BUFFER "); - } + + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_TRIED_MPDU_CNT_HIST_TLV_V:\n"); + len += scnprintf(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u\n", + htt_stats_buf->hist_bin_size); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tried_mpdu_cnt_hist, + "tried_mpdu_cnt_hist", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1261,23 +1172,14 @@ htt_print_tx_hwq_txop_used_cnt_hist_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char txop_used_cnt_hist[HTT_MAX_STRING_LEN] = {0}; u32 num_elements = tag_len >> 2; - u32 required_buffer_size = HTT_MAX_PRINT_CHAR_PER_ELEM * num_elements; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_HWQ_TXOP_USED_CNT_HIST_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_HWQ_TXOP_USED_CNT_HIST_TLV_V:\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->txop_used_cnt_hist, + "txop_used_cnt_hist", num_elements, "\n\n"); - if (required_buffer_size < HTT_MAX_STRING_LEN) { - ARRAY_TO_STRING(txop_used_cnt_hist, - htt_stats_buf->txop_used_cnt_hist, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, "txop_used_cnt_hist = %s\n", - txop_used_cnt_hist); - } else { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "INSUFFICIENT PRINT BUFFER "); - } if (len >= buf_len) buf[buf_len - 1] = 0; else @@ -1300,86 +1202,86 @@ static inline void htt_print_tx_sounding_stats_tlv(const void *tag_buf, const u32 *cbf_160 = htt_stats_buf->cbf_160; if (htt_stats_buf->tx_sounding_mode == HTT_TX_AC_SOUNDING_MODE) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "\nHTT_TX_AC_SOUNDING_STATS_TLV:\n"); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u ", - cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "\nHTT_TX_AC_SOUNDING_STATS_TLV:\n\n"); + len += scnprintf(buf + len, buf_len - len, + "ac_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ac_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ac_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ac_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u ", - i, - htt_stats_buf->sounding[0], - htt_stats_buf->sounding[1], - htt_stats_buf->sounding[2], - htt_stats_buf->sounding[3]); + len += scnprintf(buf + len, buf_len - len, + "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u\n", + i, + htt_stats_buf->sounding[0], + htt_stats_buf->sounding[1], + htt_stats_buf->sounding[2], + htt_stats_buf->sounding[3]); } } else if (htt_stats_buf->tx_sounding_mode == HTT_TX_AX_SOUNDING_MODE) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "\nHTT_TX_AX_SOUNDING_STATS_TLV:\n"); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u ", - cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u", - cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], - cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "\nHTT_TX_AX_SOUNDING_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, + "ax_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ax_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ax_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); + len += scnprintf(buf + len, buf_len - len, + "ax_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n", + cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS], + cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u ", - i, - htt_stats_buf->sounding[0], - htt_stats_buf->sounding[1], - htt_stats_buf->sounding[2], - htt_stats_buf->sounding[3]); + len += scnprintf(buf + len, buf_len - len, + "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u\n", + i, + htt_stats_buf->sounding[0], + htt_stats_buf->sounding[1], + htt_stats_buf->sounding[2], + htt_stats_buf->sounding[3]); } } @@ -1400,31 +1302,31 @@ htt_print_tx_selfgen_cmn_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "su_bar = %u", - htt_stats_buf->su_bar); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts = %u", - htt_stats_buf->rts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cts2self = %u", - htt_stats_buf->cts2self); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qos_null = %u", - htt_stats_buf->qos_null); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_1 = %u", - htt_stats_buf->delayed_bar_1); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_2 = %u", - htt_stats_buf->delayed_bar_2); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_3 = %u", - htt_stats_buf->delayed_bar_3); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_4 = %u", - htt_stats_buf->delayed_bar_4); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_5 = %u", - htt_stats_buf->delayed_bar_5); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_6 = %u", - htt_stats_buf->delayed_bar_6); - len += HTT_DBG_OUT(buf + len, buf_len - len, "delayed_bar_7 = %u\n", - htt_stats_buf->delayed_bar_7); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "su_bar = %u\n", + htt_stats_buf->su_bar); + len += scnprintf(buf + len, buf_len - len, "rts = %u\n", + htt_stats_buf->rts); + len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n", + htt_stats_buf->cts2self); + len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n", + htt_stats_buf->qos_null); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_1 = %u\n", + htt_stats_buf->delayed_bar_1); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_2 = %u\n", + htt_stats_buf->delayed_bar_2); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_3 = %u\n", + htt_stats_buf->delayed_bar_3); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_4 = %u\n", + htt_stats_buf->delayed_bar_4); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_5 = %u\n", + htt_stats_buf->delayed_bar_5); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_6 = %u\n", + htt_stats_buf->delayed_bar_6); + len += scnprintf(buf + len, buf_len - len, "delayed_bar_7 = %u\n\n", + htt_stats_buf->delayed_bar_7); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1443,21 +1345,21 @@ htt_print_tx_selfgen_ac_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_su_ndpa = %u", - htt_stats_buf->ac_su_ndpa); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_su_ndp = %u", - htt_stats_buf->ac_su_ndp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_ndpa = %u", - htt_stats_buf->ac_mu_mimo_ndpa); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_ndp = %u", - htt_stats_buf->ac_mu_mimo_ndp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brpoll_1 = %u", - htt_stats_buf->ac_mu_mimo_brpoll_1); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brpoll_2 = %u", - htt_stats_buf->ac_mu_mimo_brpoll_2); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brpoll_3 = %u\n", - htt_stats_buf->ac_mu_mimo_brpoll_3); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa = %u\n", + htt_stats_buf->ac_su_ndpa); + len += scnprintf(buf + len, buf_len - len, "ac_su_ndp = %u\n", + htt_stats_buf->ac_su_ndp); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa = %u\n", + htt_stats_buf->ac_mu_mimo_ndpa); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp = %u\n", + htt_stats_buf->ac_mu_mimo_ndp); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_1 = %u\n", + htt_stats_buf->ac_mu_mimo_brpoll_1); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_2 = %u\n", + htt_stats_buf->ac_mu_mimo_brpoll_2); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_3 = %u\n\n", + htt_stats_buf->ac_mu_mimo_brpoll_3); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1476,37 +1378,37 @@ htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_su_ndpa = %u", - htt_stats_buf->ax_su_ndpa); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_su_ndp = %u", - htt_stats_buf->ax_su_ndp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_ndpa = %u", - htt_stats_buf->ax_mu_mimo_ndpa); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_ndp = %u", - htt_stats_buf->ax_mu_mimo_ndp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_1 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_1); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_2 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_2); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_3 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_3); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_4 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_4); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_5 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_5); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_6 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_6); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brpoll_7 = %u", - htt_stats_buf->ax_mu_mimo_brpoll_7); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_basic_trigger = %u", - htt_stats_buf->ax_basic_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_bsr_trigger = %u", - htt_stats_buf->ax_bsr_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_bar_trigger = %u", - htt_stats_buf->ax_mu_bar_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n", - htt_stats_buf->ax_mu_rts_trigger); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa = %u\n", + htt_stats_buf->ax_su_ndpa); + len += scnprintf(buf + len, buf_len - len, "ax_su_ndp = %u\n", + htt_stats_buf->ax_su_ndp); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa = %u\n", + htt_stats_buf->ax_mu_mimo_ndpa); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp = %u\n", + htt_stats_buf->ax_mu_mimo_ndp); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_1 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_1); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_2 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_2); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_3 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_3); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_4 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_4); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_5 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_5); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_6 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_6); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_7 = %u\n", + htt_stats_buf->ax_mu_mimo_brpoll_7); + len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n", + htt_stats_buf->ax_basic_trigger); + len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n", + htt_stats_buf->ax_bsr_trigger); + len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n", + htt_stats_buf->ax_mu_bar_trigger); + len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n\n", + htt_stats_buf->ax_mu_rts_trigger); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1525,21 +1427,21 @@ htt_print_tx_selfgen_ac_err_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_su_ndp_err = %u", - htt_stats_buf->ac_su_ndp_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_su_ndpa_err = %u", - htt_stats_buf->ac_su_ndpa_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u", - htt_stats_buf->ac_mu_mimo_ndpa_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u", - htt_stats_buf->ac_mu_mimo_ndp_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u", - htt_stats_buf->ac_mu_mimo_brp1_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u", - htt_stats_buf->ac_mu_mimo_brp2_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n", - htt_stats_buf->ac_mu_mimo_brp3_err); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_err = %u\n", + htt_stats_buf->ac_su_ndp_err); + len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_err = %u\n", + htt_stats_buf->ac_su_ndpa_err); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u\n", + htt_stats_buf->ac_mu_mimo_ndpa_err); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u\n", + htt_stats_buf->ac_mu_mimo_ndp_err); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u\n", + htt_stats_buf->ac_mu_mimo_brp1_err); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u\n", + htt_stats_buf->ac_mu_mimo_brp2_err); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n\n", + htt_stats_buf->ac_mu_mimo_brp3_err); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1558,37 +1460,37 @@ htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_su_ndp_err = %u", - htt_stats_buf->ax_su_ndp_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_su_ndpa_err = %u", - htt_stats_buf->ax_su_ndpa_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u", - htt_stats_buf->ax_mu_mimo_ndpa_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u", - htt_stats_buf->ax_mu_mimo_ndp_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp1_err = %u", - htt_stats_buf->ax_mu_mimo_brp1_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp2_err = %u", - htt_stats_buf->ax_mu_mimo_brp2_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp3_err = %u", - htt_stats_buf->ax_mu_mimo_brp3_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp4_err = %u", - htt_stats_buf->ax_mu_mimo_brp4_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp5_err = %u", - htt_stats_buf->ax_mu_mimo_brp5_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp6_err = %u", - htt_stats_buf->ax_mu_mimo_brp6_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_brp7_err = %u", - htt_stats_buf->ax_mu_mimo_brp7_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_basic_trigger_err = %u", - htt_stats_buf->ax_basic_trigger_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_bsr_trigger_err = %u", - htt_stats_buf->ax_bsr_trigger_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u", - htt_stats_buf->ax_mu_bar_trigger_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n", - htt_stats_buf->ax_mu_rts_trigger_err); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_err = %u\n", + htt_stats_buf->ax_su_ndp_err); + len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_err = %u\n", + htt_stats_buf->ax_su_ndpa_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u\n", + htt_stats_buf->ax_mu_mimo_ndpa_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u\n", + htt_stats_buf->ax_mu_mimo_ndp_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp1_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp1_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp2_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp2_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp3_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp3_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp4_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp4_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp5_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp5_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp6_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp6_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp7_err = %u\n", + htt_stats_buf->ax_mu_mimo_brp7_err); + len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n", + htt_stats_buf->ax_basic_trigger_err); + len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n", + htt_stats_buf->ax_bsr_trigger_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n", + htt_stats_buf->ax_mu_bar_trigger_err); + len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n\n", + htt_stats_buf->ax_mu_rts_trigger_err); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1608,35 +1510,35 @@ htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u8 i; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_sch_posted = %u", - htt_stats_buf->mu_mimo_sch_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_sch_failed = %u", - htt_stats_buf->mu_mimo_sch_failed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n", - htt_stats_buf->mu_mimo_ppdu_posted); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n", + htt_stats_buf->mu_mimo_sch_posted); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n", + htt_stats_buf->mu_mimo_sch_failed); + len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n\n", + htt_stats_buf->mu_mimo_ppdu_posted); - len += HTT_DBG_OUT(buf + len, buf_len - len, "11ac MU_MIMO SCH STATS:"); + len += scnprintf(buf + len, buf_len - len, "11ac MU_MIMO SCH STATS:\n"); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_sch_nusers_%u = %u", - i, htt_stats_buf->ac_mu_mimo_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_sch_nusers_%u = %u\n", + i, htt_stats_buf->ac_mu_mimo_sch_nusers[i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:"); + len += scnprintf(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:\n"); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_sch_nusers_%u = %u", - i, htt_stats_buf->ax_mu_mimo_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_mu_mimo_sch_nusers[i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:"); + len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n"); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_ofdma_sch_nusers_%u = %u", - i, htt_stats_buf->ax_ofdma_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ofdma_sch_nusers[i]); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1657,114 +1559,114 @@ htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void *tag_buf, if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_MIMO_AC) { if (!htt_stats_buf->user_index) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n"); if (htt_stats_buf->user_index < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_mpdus_queued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_queued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_mpdus_tried_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_tried_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_mpdus_failed_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_failed_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_mpdus_requeued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_requeued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_err_no_ba_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->err_no_ba_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_mpdu_underrun_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdu_underrun_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_ampdu_underrun_usr_%u = %u\n", - htt_stats_buf->user_index, - htt_stats_buf->ampdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_mpdus_queued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_queued_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_mpdus_tried_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_tried_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_mpdus_failed_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_failed_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_mpdus_requeued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_requeued_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_err_no_ba_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->err_no_ba_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_mpdu_underrun_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_ampdu_underrun_usr_%u = %u\n\n", + htt_stats_buf->user_index, + htt_stats_buf->ampdu_underrun_usr); } } if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_MIMO_AX) { if (!htt_stats_buf->user_index) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n"); if (htt_stats_buf->user_index < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_mpdus_queued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_queued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_mpdus_tried_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_tried_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_mpdus_failed_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_failed_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_mpdus_requeued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_requeued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_err_no_ba_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->err_no_ba_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_mpdu_underrun_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdu_underrun_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n", - htt_stats_buf->user_index, - htt_stats_buf->ampdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_mpdus_queued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_queued_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_mpdus_tried_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_tried_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_mpdus_failed_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_failed_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_mpdus_requeued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_requeued_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_err_no_ba_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->err_no_ba_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_mpdu_underrun_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n\n", + htt_stats_buf->user_index, + htt_stats_buf->ampdu_underrun_usr); } } if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_OFDMA_AX) { if (!htt_stats_buf->user_index) - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n"); if (htt_stats_buf->user_index < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS) { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_mpdus_queued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_queued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_mpdus_tried_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_tried_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_mpdus_failed_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_failed_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_mpdus_requeued_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdus_requeued_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_err_no_ba_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->err_no_ba_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_mpdu_underrun_usr_%u = %u", - htt_stats_buf->user_index, - htt_stats_buf->mpdu_underrun_usr); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n", - htt_stats_buf->user_index, - htt_stats_buf->ampdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_mpdus_queued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_queued_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_mpdus_tried_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_tried_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_mpdus_failed_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_failed_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_mpdus_requeued_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdus_requeued_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_err_no_ba_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->err_no_ba_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_mpdu_underrun_usr_%u = %u\n", + htt_stats_buf->user_index, + htt_stats_buf->mpdu_underrun_usr); + len += scnprintf(buf + len, buf_len - len, + "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n\n", + htt_stats_buf->user_index, + htt_stats_buf->ampdu_underrun_usr); } } @@ -1785,15 +1687,12 @@ htt_print_sched_txq_cmd_posted_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sched_cmd_posted[HTT_MAX_STRING_LEN] = {0}; u16 num_elements = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_SCHED_TX_MODE_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV_V:\n"); - ARRAY_TO_STRING(sched_cmd_posted, htt_stats_buf->sched_cmd_posted, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmd_posted = %s\n", - sched_cmd_posted); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_cmd_posted, + "sched_cmd_posted", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1812,15 +1711,12 @@ htt_print_sched_txq_cmd_reaped_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sched_cmd_reaped[HTT_MAX_STRING_LEN] = {0}; u16 num_elements = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_SCHED_TX_MODE_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV_V:\n"); - ARRAY_TO_STRING(sched_cmd_reaped, htt_stats_buf->sched_cmd_reaped, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmd_reaped = %s\n", - sched_cmd_reaped); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_cmd_reaped, + "sched_cmd_reaped", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1839,18 +1735,15 @@ htt_print_sched_txq_sched_order_su_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sched_order_su[HTT_MAX_STRING_LEN] = {0}; /* each entry is u32, i.e. 4 bytes */ u32 sched_order_su_num_entries = min_t(u32, (tag_len >> 2), HTT_TX_PDEV_NUM_SCHED_ORDER_LOG); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV_V:\n"); - ARRAY_TO_STRING(sched_order_su, htt_stats_buf->sched_order_su, - sched_order_su_num_entries); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_order_su = %s\n", - sched_order_su); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_order_su, "sched_order_su", + sched_order_su_num_entries, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1869,17 +1762,15 @@ htt_print_sched_txq_sched_ineligibility_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char sched_ineligibility[HTT_MAX_STRING_LEN] = {0}; /* each entry is u32, i.e. 4 bytes */ u32 sched_ineligibility_num_entries = tag_len >> 2; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_SCHED_TXQ_SCHED_INELIGIBILITY_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_SCHED_TXQ_SCHED_INELIGIBILITY_V:\n"); - ARRAY_TO_STRING(sched_ineligibility, htt_stats_buf->sched_ineligibility, - sched_ineligibility_num_entries); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_ineligibility = %s\n", - sched_ineligibility); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_ineligibility, + "sched_ineligibility", sched_ineligibility_num_entries, + "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1898,54 +1789,56 @@ htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__txq_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "txq_id = %u", - (htt_stats_buf->mac_id__txq_id__word & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_policy = %u", - htt_stats_buf->sched_policy); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "last_sched_cmd_posted_timestamp = %u", - htt_stats_buf->last_sched_cmd_posted_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "last_sched_cmd_compl_timestamp = %u", - htt_stats_buf->last_sched_cmd_compl_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u", - htt_stats_buf->sched_2_tac_lwm_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_2_tac_ring_full = %u", - htt_stats_buf->sched_2_tac_ring_full); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmd_post_failure = %u", - htt_stats_buf->sched_cmd_post_failure); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_active_tids = %u", - htt_stats_buf->num_active_tids); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_ps_schedules = %u", - htt_stats_buf->num_ps_schedules); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmds_pending = %u", - htt_stats_buf->sched_cmds_pending); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_tid_register = %u", - htt_stats_buf->num_tid_register); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_tid_unregister = %u", - htt_stats_buf->num_tid_unregister); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_qstats_queried = %u", - htt_stats_buf->num_qstats_queried); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qstats_update_pending = %u", - htt_stats_buf->qstats_update_pending); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_qstats_query_timestamp = %u", - htt_stats_buf->last_qstats_query_timestamp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_tqm_cmdq_full = %u", - htt_stats_buf->num_tqm_cmdq_full); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u", - htt_stats_buf->num_de_sched_algo_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u", - htt_stats_buf->num_rt_sched_algo_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u", - htt_stats_buf->num_tqm_sched_algo_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "notify_sched = %u\n", - htt_stats_buf->notify_sched); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dur_based_sendn_term = %u\n", - htt_stats_buf->dur_based_sendn_term); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID, + htt_stats_buf->mac_id__txq_id__word)); + len += scnprintf(buf + len, buf_len - len, "txq_id = %lu\n", + FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID, + htt_stats_buf->mac_id__txq_id__word)); + len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n", + htt_stats_buf->sched_policy); + len += scnprintf(buf + len, buf_len - len, + "last_sched_cmd_posted_timestamp = %u\n", + htt_stats_buf->last_sched_cmd_posted_timestamp); + len += scnprintf(buf + len, buf_len - len, + "last_sched_cmd_compl_timestamp = %u\n", + htt_stats_buf->last_sched_cmd_compl_timestamp); + len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n", + htt_stats_buf->sched_2_tac_lwm_count); + len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n", + htt_stats_buf->sched_2_tac_ring_full); + len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n", + htt_stats_buf->sched_cmd_post_failure); + len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n", + htt_stats_buf->num_active_tids); + len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n", + htt_stats_buf->num_ps_schedules); + len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n", + htt_stats_buf->sched_cmds_pending); + len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n", + htt_stats_buf->num_tid_register); + len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n", + htt_stats_buf->num_tid_unregister); + len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n", + htt_stats_buf->num_qstats_queried); + len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n", + htt_stats_buf->qstats_update_pending); + len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n", + htt_stats_buf->last_qstats_query_timestamp); + len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n", + htt_stats_buf->num_tqm_cmdq_full); + len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n", + htt_stats_buf->num_de_sched_algo_trigger); + len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n", + htt_stats_buf->num_rt_sched_algo_trigger); + len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n", + htt_stats_buf->num_tqm_sched_algo_trigger); + len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n\n", + htt_stats_buf->notify_sched); + len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n\n", + htt_stats_buf->dur_based_sendn_term); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1963,11 +1856,11 @@ static inline void htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "current_timestamp = %u\n", - htt_stats_buf->current_timestamp); + len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n", + htt_stats_buf->current_timestamp); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -1986,16 +1879,13 @@ htt_print_tx_tqm_gen_mpdu_stats_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char gen_mpdu_end_reason[HTT_MAX_STRING_LEN] = {0}; u16 num_elements = min_t(u16, (tag_len >> 2), HTT_TX_TQM_MAX_LIST_MPDU_END_REASON); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV_V:\n"); - ARRAY_TO_STRING(gen_mpdu_end_reason, htt_stats_buf->gen_mpdu_end_reason, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, "gen_mpdu_end_reason = %s\n", - gen_mpdu_end_reason); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->gen_mpdu_end_reason, + "gen_mpdu_end_reason", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2014,16 +1904,14 @@ htt_print_tx_tqm_list_mpdu_stats_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char list_mpdu_end_reason[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_TQM_MAX_LIST_MPDU_END_REASON); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_TQM_LIST_MPDU_STATS_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_TQM_LIST_MPDU_STATS_TLV_V:\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->list_mpdu_end_reason, + "list_mpdu_end_reason", num_elems, "\n\n"); - ARRAY_TO_STRING(list_mpdu_end_reason, htt_stats_buf->list_mpdu_end_reason, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "list_mpdu_end_reason = %s\n", - list_mpdu_end_reason); if (len >= buf_len) buf[buf_len - 1] = 0; else @@ -2041,16 +1929,13 @@ htt_print_tx_tqm_list_mpdu_cnt_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char list_mpdu_cnt_hist[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n"); - ARRAY_TO_STRING(list_mpdu_cnt_hist, htt_stats_buf->list_mpdu_cnt_hist, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "list_mpdu_cnt_hist = %s\n", - list_mpdu_cnt_hist); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->list_mpdu_cnt_hist, + "list_mpdu_cnt_hist", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2069,69 +1954,69 @@ htt_print_tx_tqm_pdev_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_count = %u", - htt_stats_buf->msdu_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_count = %u", - htt_stats_buf->mpdu_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_msdu = %u", - htt_stats_buf->remove_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_mpdu = %u", - htt_stats_buf->remove_mpdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_msdu_ttl = %u", - htt_stats_buf->remove_msdu_ttl); - len += HTT_DBG_OUT(buf + len, buf_len - len, "send_bar = %u", - htt_stats_buf->send_bar); - len += HTT_DBG_OUT(buf + len, buf_len - len, "bar_sync = %u", - htt_stats_buf->bar_sync); - len += HTT_DBG_OUT(buf + len, buf_len - len, "notify_mpdu = %u", - htt_stats_buf->notify_mpdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sync_cmd = %u", - htt_stats_buf->sync_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "write_cmd = %u", - htt_stats_buf->write_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_trigger = %u", - htt_stats_buf->hwsch_trigger); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ack_tlv_proc = %u", - htt_stats_buf->ack_tlv_proc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "gen_mpdu_cmd = %u", - htt_stats_buf->gen_mpdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "gen_list_cmd = %u", - htt_stats_buf->gen_list_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_mpdu_cmd = %u", - htt_stats_buf->remove_mpdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u", - htt_stats_buf->remove_mpdu_tried_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u", - htt_stats_buf->mpdu_queue_stats_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_head_info_cmd = %u", - htt_stats_buf->mpdu_head_info_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u", - htt_stats_buf->msdu_flow_stats_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_msdu_cmd = %u", - htt_stats_buf->remove_msdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u", - htt_stats_buf->remove_msdu_ttl_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "flush_cache_cmd = %u", - htt_stats_buf->flush_cache_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "update_mpduq_cmd = %u", - htt_stats_buf->update_mpduq_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "enqueue = %u", - htt_stats_buf->enqueue); - len += HTT_DBG_OUT(buf + len, buf_len - len, "enqueue_notify = %u", - htt_stats_buf->enqueue_notify); - len += HTT_DBG_OUT(buf + len, buf_len - len, "notify_mpdu_at_head = %u", - htt_stats_buf->notify_mpdu_at_head); - len += HTT_DBG_OUT(buf + len, buf_len - len, "notify_mpdu_state_valid = %u", - htt_stats_buf->notify_mpdu_state_valid); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_udp_notify1 = %u", - htt_stats_buf->sched_udp_notify1); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_udp_notify2 = %u", - htt_stats_buf->sched_udp_notify2); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_nonudp_notify1 = %u", - htt_stats_buf->sched_nonudp_notify1); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n", - htt_stats_buf->sched_nonudp_notify2); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n"); + len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n", + htt_stats_buf->msdu_count); + len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n", + htt_stats_buf->mpdu_count); + len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n", + htt_stats_buf->remove_msdu); + len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n", + htt_stats_buf->remove_mpdu); + len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n", + htt_stats_buf->remove_msdu_ttl); + len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n", + htt_stats_buf->send_bar); + len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n", + htt_stats_buf->bar_sync); + len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n", + htt_stats_buf->notify_mpdu); + len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n", + htt_stats_buf->sync_cmd); + len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n", + htt_stats_buf->write_cmd); + len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n", + htt_stats_buf->hwsch_trigger); + len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", + htt_stats_buf->ack_tlv_proc); + len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n", + htt_stats_buf->gen_mpdu_cmd); + len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n", + htt_stats_buf->gen_list_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n", + htt_stats_buf->remove_mpdu_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n", + htt_stats_buf->remove_mpdu_tried_cmd); + len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n", + htt_stats_buf->mpdu_queue_stats_cmd); + len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n", + htt_stats_buf->mpdu_head_info_cmd); + len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n", + htt_stats_buf->msdu_flow_stats_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n", + htt_stats_buf->remove_msdu_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n", + htt_stats_buf->remove_msdu_ttl_cmd); + len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n", + htt_stats_buf->flush_cache_cmd); + len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n", + htt_stats_buf->update_mpduq_cmd); + len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n", + htt_stats_buf->enqueue); + len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n", + htt_stats_buf->enqueue_notify); + len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n", + htt_stats_buf->notify_mpdu_at_head); + len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n", + htt_stats_buf->notify_mpdu_state_valid); + len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n", + htt_stats_buf->sched_udp_notify1); + len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n", + htt_stats_buf->sched_udp_notify2); + len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n", + htt_stats_buf->sched_nonudp_notify1); + len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n", + htt_stats_buf->sched_nonudp_notify2); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2149,23 +2034,23 @@ static inline void htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "max_cmdq_id = %u", - htt_stats_buf->max_cmdq_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u", - htt_stats_buf->list_mpdu_cnt_hist_intvl); - len += HTT_DBG_OUT(buf + len, buf_len - len, "add_msdu = %u", - htt_stats_buf->add_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "q_empty = %u", - htt_stats_buf->q_empty); - len += HTT_DBG_OUT(buf + len, buf_len - len, "q_not_empty = %u", - htt_stats_buf->q_not_empty); - len += HTT_DBG_OUT(buf + len, buf_len - len, "drop_notification = %u", - htt_stats_buf->drop_notification); - len += HTT_DBG_OUT(buf + len, buf_len - len, "desc_threshold = %u\n", - htt_stats_buf->desc_threshold); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n", + htt_stats_buf->max_cmdq_id); + len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n", + htt_stats_buf->list_mpdu_cnt_hist_intvl); + len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n", + htt_stats_buf->add_msdu); + len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n", + htt_stats_buf->q_empty); + len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n", + htt_stats_buf->q_not_empty); + len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n", + htt_stats_buf->drop_notification); + len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n\n", + htt_stats_buf->desc_threshold); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2183,13 +2068,13 @@ static inline void htt_print_tx_tqm_error_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "q_empty_failure = %u", - htt_stats_buf->q_empty_failure); - len += HTT_DBG_OUT(buf + len, buf_len - len, "q_not_empty_failure = %u", - htt_stats_buf->q_not_empty_failure); - len += HTT_DBG_OUT(buf + len, buf_len - len, "add_msdu_failure = %u\n", - htt_stats_buf->add_msdu_failure); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n", + htt_stats_buf->q_empty_failure); + len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n", + htt_stats_buf->q_not_empty_failure); + len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n", + htt_stats_buf->add_msdu_failure); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2207,33 +2092,35 @@ static inline void htt_print_tx_tqm_cmdq_status_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_CMDQ_STATUS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__cmdq_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cmdq_id = %u\n", - (htt_stats_buf->mac_id__cmdq_id__word & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sync_cmd = %u", - htt_stats_buf->sync_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "write_cmd = %u", - htt_stats_buf->write_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "gen_mpdu_cmd = %u", - htt_stats_buf->gen_mpdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u", - htt_stats_buf->mpdu_queue_stats_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_head_info_cmd = %u", - htt_stats_buf->mpdu_head_info_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u", - htt_stats_buf->msdu_flow_stats_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_mpdu_cmd = %u", - htt_stats_buf->remove_mpdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "remove_msdu_cmd = %u", - htt_stats_buf->remove_msdu_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "flush_cache_cmd = %u", - htt_stats_buf->flush_cache_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "update_mpduq_cmd = %u", - htt_stats_buf->update_mpduq_cmd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "update_msduq_cmd = %u\n", - htt_stats_buf->update_msduq_cmd); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMDQ_STATUS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_MAC_ID, + htt_stats_buf->mac_id__cmdq_id__word)); + len += scnprintf(buf + len, buf_len - len, "cmdq_id = %lu\n\n", + FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID, + htt_stats_buf->mac_id__cmdq_id__word)); + len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n", + htt_stats_buf->sync_cmd); + len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n", + htt_stats_buf->write_cmd); + len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n", + htt_stats_buf->gen_mpdu_cmd); + len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n", + htt_stats_buf->mpdu_queue_stats_cmd); + len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n", + htt_stats_buf->mpdu_head_info_cmd); + len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n", + htt_stats_buf->msdu_flow_stats_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n", + htt_stats_buf->remove_mpdu_cmd); + len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n", + htt_stats_buf->remove_msdu_cmd); + len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n", + htt_stats_buf->flush_cache_cmd); + len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n", + htt_stats_buf->update_mpduq_cmd); + len += scnprintf(buf + len, buf_len - len, "update_msduq_cmd = %u\n\n", + htt_stats_buf->update_msduq_cmd); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2252,20 +2139,20 @@ htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "m1_packets = %u", - htt_stats_buf->m1_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "m2_packets = %u", - htt_stats_buf->m2_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "m3_packets = %u", - htt_stats_buf->m3_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "m4_packets = %u", - htt_stats_buf->m4_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "g1_packets = %u", - htt_stats_buf->g1_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "g2_packets = %u\n", - htt_stats_buf->g2_packets); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n", + htt_stats_buf->m1_packets); + len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n", + htt_stats_buf->m2_packets); + len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n", + htt_stats_buf->m3_packets); + len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n", + htt_stats_buf->m4_packets); + len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n", + htt_stats_buf->g1_packets); + len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n\n", + htt_stats_buf->g2_packets); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2284,34 +2171,34 @@ htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ap_bss_peer_not_found = %u", - htt_stats_buf->ap_bss_peer_not_found); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u", - htt_stats_buf->ap_bcast_mcast_no_peer); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sta_delete_in_progress = %u", - htt_stats_buf->sta_delete_in_progress); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ibss_no_bss_peer = %u", - htt_stats_buf->ibss_no_bss_peer); - len += HTT_DBG_OUT(buf + len, buf_len - len, "invalid_vdev_type = %u", - htt_stats_buf->invalid_vdev_type); - len += HTT_DBG_OUT(buf + len, buf_len - len, "invalid_ast_peer_entry = %u", - htt_stats_buf->invalid_ast_peer_entry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "peer_entry_invalid = %u", - htt_stats_buf->peer_entry_invalid); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ethertype_not_ip = %u", - htt_stats_buf->ethertype_not_ip); - len += HTT_DBG_OUT(buf + len, buf_len - len, "eapol_lookup_failed = %u", - htt_stats_buf->eapol_lookup_failed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qpeer_not_allow_data = %u", - htt_stats_buf->qpeer_not_allow_data); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_tid_override = %u", - htt_stats_buf->fse_tid_override); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u", - htt_stats_buf->ipv6_jumbogram_zero_length); - len += HTT_DBG_OUT(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n", - htt_stats_buf->qos_to_non_qos_in_prog); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n", + htt_stats_buf->ap_bss_peer_not_found); + len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n", + htt_stats_buf->ap_bcast_mcast_no_peer); + len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n", + htt_stats_buf->sta_delete_in_progress); + len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n", + htt_stats_buf->ibss_no_bss_peer); + len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n", + htt_stats_buf->invalid_vdev_type); + len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n", + htt_stats_buf->invalid_ast_peer_entry); + len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n", + htt_stats_buf->peer_entry_invalid); + len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n", + htt_stats_buf->ethertype_not_ip); + len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n", + htt_stats_buf->eapol_lookup_failed); + len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n", + htt_stats_buf->qpeer_not_allow_data); + len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n", + htt_stats_buf->fse_tid_override); + len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n", + htt_stats_buf->ipv6_jumbogram_zero_length); + len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n\n", + htt_stats_buf->qos_to_non_qos_in_prog); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2330,73 +2217,73 @@ htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "arp_packets = %u", - htt_stats_buf->arp_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "igmp_packets = %u", - htt_stats_buf->igmp_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dhcp_packets = %u", - htt_stats_buf->dhcp_packets); - len += HTT_DBG_OUT(buf + len, buf_len - len, "host_inspected = %u", - htt_stats_buf->host_inspected); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_included = %u", - htt_stats_buf->htt_included); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_mcs = %u", - htt_stats_buf->htt_valid_mcs); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_nss = %u", - htt_stats_buf->htt_valid_nss); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_preamble_type = %u", - htt_stats_buf->htt_valid_preamble_type); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_chainmask = %u", - htt_stats_buf->htt_valid_chainmask); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_guard_interval = %u", - htt_stats_buf->htt_valid_guard_interval); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_retries = %u", - htt_stats_buf->htt_valid_retries); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_bw_info = %u", - htt_stats_buf->htt_valid_bw_info); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_power = %u", - htt_stats_buf->htt_valid_power); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x", - htt_stats_buf->htt_valid_key_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_valid_no_encryption = %u", - htt_stats_buf->htt_valid_no_encryption); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_entry_count = %u", - htt_stats_buf->fse_entry_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_priority_be = %u", - htt_stats_buf->fse_priority_be); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_priority_high = %u", - htt_stats_buf->fse_priority_high); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_priority_low = %u", - htt_stats_buf->fse_priority_low); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u", - htt_stats_buf->fse_traffic_ptrn_be); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u", - htt_stats_buf->fse_traffic_ptrn_over_sub); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u", - htt_stats_buf->fse_traffic_ptrn_bursty); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u", - htt_stats_buf->fse_traffic_ptrn_interactive); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u", - htt_stats_buf->fse_traffic_ptrn_periodic); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_hwqueue_alloc = %u", - htt_stats_buf->fse_hwqueue_alloc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_hwqueue_created = %u", - htt_stats_buf->fse_hwqueue_created); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u", - htt_stats_buf->fse_hwqueue_send_to_host); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mcast_entry = %u", - htt_stats_buf->mcast_entry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "bcast_entry = %u", - htt_stats_buf->bcast_entry); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_update_peer_cache = %u", - htt_stats_buf->htt_update_peer_cache); - len += HTT_DBG_OUT(buf + len, buf_len - len, "htt_learning_frame = %u", - htt_stats_buf->htt_learning_frame); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fse_invalid_peer = %u", - htt_stats_buf->fse_invalid_peer); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mec_notify = %u\n", - htt_stats_buf->mec_notify); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n", + htt_stats_buf->arp_packets); + len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n", + htt_stats_buf->igmp_packets); + len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n", + htt_stats_buf->dhcp_packets); + len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n", + htt_stats_buf->host_inspected); + len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n", + htt_stats_buf->htt_included); + len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n", + htt_stats_buf->htt_valid_mcs); + len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n", + htt_stats_buf->htt_valid_nss); + len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n", + htt_stats_buf->htt_valid_preamble_type); + len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n", + htt_stats_buf->htt_valid_chainmask); + len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n", + htt_stats_buf->htt_valid_guard_interval); + len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n", + htt_stats_buf->htt_valid_retries); + len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n", + htt_stats_buf->htt_valid_bw_info); + len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n", + htt_stats_buf->htt_valid_power); + len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n", + htt_stats_buf->htt_valid_key_flags); + len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n", + htt_stats_buf->htt_valid_no_encryption); + len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n", + htt_stats_buf->fse_entry_count); + len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n", + htt_stats_buf->fse_priority_be); + len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n", + htt_stats_buf->fse_priority_high); + len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n", + htt_stats_buf->fse_priority_low); + len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n", + htt_stats_buf->fse_traffic_ptrn_be); + len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n", + htt_stats_buf->fse_traffic_ptrn_over_sub); + len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n", + htt_stats_buf->fse_traffic_ptrn_bursty); + len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n", + htt_stats_buf->fse_traffic_ptrn_interactive); + len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n", + htt_stats_buf->fse_traffic_ptrn_periodic); + len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n", + htt_stats_buf->fse_hwqueue_alloc); + len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n", + htt_stats_buf->fse_hwqueue_created); + len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n", + htt_stats_buf->fse_hwqueue_send_to_host); + len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n", + htt_stats_buf->mcast_entry); + len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n", + htt_stats_buf->bcast_entry); + len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n", + htt_stats_buf->htt_update_peer_cache); + len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n", + htt_stats_buf->htt_learning_frame); + len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n", + htt_stats_buf->fse_invalid_peer); + len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n", + htt_stats_buf->mec_notify); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2415,24 +2302,24 @@ htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "eok = %u", - htt_stats_buf->eok); - len += HTT_DBG_OUT(buf + len, buf_len - len, "classify_done = %u", - htt_stats_buf->classify_done); - len += HTT_DBG_OUT(buf + len, buf_len - len, "lookup_failed = %u", - htt_stats_buf->lookup_failed); - len += HTT_DBG_OUT(buf + len, buf_len - len, "send_host_dhcp = %u", - htt_stats_buf->send_host_dhcp); - len += HTT_DBG_OUT(buf + len, buf_len - len, "send_host_mcast = %u", - htt_stats_buf->send_host_mcast); - len += HTT_DBG_OUT(buf + len, buf_len - len, "send_host_unknown_dest = %u", - htt_stats_buf->send_host_unknown_dest); - len += HTT_DBG_OUT(buf + len, buf_len - len, "send_host = %u", - htt_stats_buf->send_host); - len += HTT_DBG_OUT(buf + len, buf_len - len, "status_invalid = %u\n", - htt_stats_buf->status_invalid); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "eok = %u\n", + htt_stats_buf->eok); + len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n", + htt_stats_buf->classify_done); + len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n", + htt_stats_buf->lookup_failed); + len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n", + htt_stats_buf->send_host_dhcp); + len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n", + htt_stats_buf->send_host_mcast); + len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n", + htt_stats_buf->send_host_unknown_dest); + len += scnprintf(buf + len, buf_len - len, "send_host = %u\n", + htt_stats_buf->send_host); + len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n", + htt_stats_buf->status_invalid); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2451,14 +2338,14 @@ htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "enqueued_pkts = %u", - htt_stats_buf->enqueued_pkts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "to_tqm = %u", - htt_stats_buf->to_tqm); - len += HTT_DBG_OUT(buf + len, buf_len - len, "to_tqm_bypass = %u\n", - htt_stats_buf->to_tqm_bypass); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n", + htt_stats_buf->enqueued_pkts); + len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n", + htt_stats_buf->to_tqm); + len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n", + htt_stats_buf->to_tqm_bypass); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2477,14 +2364,14 @@ htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "discarded_pkts = %u", - htt_stats_buf->discarded_pkts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_frames = %u", - htt_stats_buf->local_frames); - len += HTT_DBG_OUT(buf + len, buf_len - len, "is_ext_msdu = %u\n", - htt_stats_buf->is_ext_msdu); + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n", + htt_stats_buf->discarded_pkts); + len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n", + htt_stats_buf->local_frames); + len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n", + htt_stats_buf->is_ext_msdu); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2502,17 +2389,17 @@ static inline void htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tcl_dummy_frame = %u", - htt_stats_buf->tcl_dummy_frame); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tqm_dummy_frame = %u", - htt_stats_buf->tqm_dummy_frame); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tqm_notify_frame = %u", - htt_stats_buf->tqm_notify_frame); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw2wbm_enq = %u", - htt_stats_buf->fw2wbm_enq); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tqm_bypass_frame = %u\n", - htt_stats_buf->tqm_bypass_frame); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n", + htt_stats_buf->tcl_dummy_frame); + len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n", + htt_stats_buf->tqm_dummy_frame); + len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n", + htt_stats_buf->tqm_notify_frame); + len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n", + htt_stats_buf->fw2wbm_enq); + len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n", + htt_stats_buf->tqm_bypass_frame); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2531,24 +2418,13 @@ htt_print_tx_de_fw2wbm_ring_full_hist_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char fw2wbm_ring_full_hist[HTT_MAX_STRING_LEN] = {0}; u16 num_elements = tag_len >> 2; - u32 required_buffer_size = HTT_MAX_PRINT_CHAR_PER_ELEM * num_elements; - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_TX_DE_FW2WBM_RING_FULL_HIST_TLV"); - - if (required_buffer_size < HTT_MAX_STRING_LEN) { - ARRAY_TO_STRING(fw2wbm_ring_full_hist, - htt_stats_buf->fw2wbm_ring_full_hist, - num_elements); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "fw2wbm_ring_full_hist = %s\n", - fw2wbm_ring_full_hist); - } else { - len += HTT_DBG_OUT(buf + len, buf_len - len, - "INSUFFICIENT PRINT BUFFER "); - } + + len += scnprintf(buf + len, buf_len - len, + "HTT_TX_DE_FW2WBM_RING_FULL_HIST_TLV"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw2wbm_ring_full_hist, + "fw2wbm_ring_full_hist", num_elements, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2566,21 +2442,21 @@ htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, struct debug_htt_stats_req *s u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tcl2fw_entry_count = %u", - htt_stats_buf->tcl2fw_entry_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "not_to_fw = %u", - htt_stats_buf->not_to_fw); - len += HTT_DBG_OUT(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u", - htt_stats_buf->invalid_pdev_vdev_peer); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u", - htt_stats_buf->tcl_res_invalid_addrx); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wbm2fw_entry_count = %u", - htt_stats_buf->wbm2fw_entry_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "invalid_pdev = %u\n", - htt_stats_buf->invalid_pdev); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n", + htt_stats_buf->tcl2fw_entry_count); + len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n", + htt_stats_buf->not_to_fw); + len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n", + htt_stats_buf->invalid_pdev_vdev_peer); + len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n", + htt_stats_buf->tcl_res_invalid_addrx); + len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n", + htt_stats_buf->wbm2fw_entry_count); + len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n\n", + htt_stats_buf->invalid_pdev); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2597,52 +2473,51 @@ static inline void htt_print_ring_if_stats_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char low_wm_hit_count[HTT_MAX_STRING_LEN] = {0}; - char high_wm_hit_count[HTT_MAX_STRING_LEN] = {0}; - - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RING_IF_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "base_addr = %u", - htt_stats_buf->base_addr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "elem_size = %u", - htt_stats_buf->elem_size); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_elems = %u", - htt_stats_buf->num_elems__prefetch_tail_idx & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "prefetch_tail_idx = %u", - (htt_stats_buf->num_elems__prefetch_tail_idx & - 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "head_idx = %u", - htt_stats_buf->head_idx__tail_idx & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tail_idx = %u", - (htt_stats_buf->head_idx__tail_idx & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "shadow_head_idx = %u", - htt_stats_buf->shadow_head_idx__shadow_tail_idx & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "shadow_tail_idx = %u", - (htt_stats_buf->shadow_head_idx__shadow_tail_idx & - 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_tail_incr = %u", - htt_stats_buf->num_tail_incr); - len += HTT_DBG_OUT(buf + len, buf_len - len, "lwm_thresh = %u", - htt_stats_buf->lwm_thresh__hwm_thresh & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwm_thresh = %u", - (htt_stats_buf->lwm_thresh__hwm_thresh & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "overrun_hit_count = %u", - htt_stats_buf->overrun_hit_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "underrun_hit_count = %u", - htt_stats_buf->underrun_hit_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "prod_blockwait_count = %u", - htt_stats_buf->prod_blockwait_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "cons_blockwait_count = %u", - htt_stats_buf->cons_blockwait_count); - - ARRAY_TO_STRING(low_wm_hit_count, htt_stats_buf->low_wm_hit_count, - HTT_STATS_LOW_WM_BINS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "low_wm_hit_count = %s ", - low_wm_hit_count); - - ARRAY_TO_STRING(high_wm_hit_count, htt_stats_buf->high_wm_hit_count, - HTT_STATS_HIGH_WM_BINS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "high_wm_hit_count = %s\n", - high_wm_hit_count); + + len += scnprintf(buf + len, buf_len - len, "HTT_RING_IF_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "base_addr = %u\n", + htt_stats_buf->base_addr); + len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n", + htt_stats_buf->elem_size); + len += scnprintf(buf + len, buf_len - len, "num_elems = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_NUM_ELEMS, + htt_stats_buf->num_elems__prefetch_tail_idx)); + len += scnprintf(buf + len, buf_len - len, "prefetch_tail_idx = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX, + htt_stats_buf->num_elems__prefetch_tail_idx)); + len += scnprintf(buf + len, buf_len - len, "head_idx = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_HEAD_IDX, + htt_stats_buf->head_idx__tail_idx)); + len += scnprintf(buf + len, buf_len - len, "tail_idx = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_TAIL_IDX, + htt_stats_buf->head_idx__tail_idx)); + len += scnprintf(buf + len, buf_len - len, "shadow_head_idx = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_SHADOW_HEAD_IDX, + htt_stats_buf->shadow_head_idx__shadow_tail_idx)); + len += scnprintf(buf + len, buf_len - len, "shadow_tail_idx = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_SHADOW_TAIL_IDX, + htt_stats_buf->shadow_head_idx__shadow_tail_idx)); + len += scnprintf(buf + len, buf_len - len, "num_tail_incr = %u\n", + htt_stats_buf->num_tail_incr); + len += scnprintf(buf + len, buf_len - len, "lwm_thresh = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_LWM_THRESH, + htt_stats_buf->lwm_thresh__hwm_thresh)); + len += scnprintf(buf + len, buf_len - len, "hwm_thresh = %lu\n", + FIELD_GET(HTT_RING_IF_STATS_HWM_THRESH, + htt_stats_buf->lwm_thresh__hwm_thresh)); + len += scnprintf(buf + len, buf_len - len, "overrun_hit_count = %u\n", + htt_stats_buf->overrun_hit_count); + len += scnprintf(buf + len, buf_len - len, "underrun_hit_count = %u\n", + htt_stats_buf->underrun_hit_count); + len += scnprintf(buf + len, buf_len - len, "prod_blockwait_count = %u\n", + htt_stats_buf->prod_blockwait_count); + len += scnprintf(buf + len, buf_len - len, "cons_blockwait_count = %u\n", + htt_stats_buf->cons_blockwait_count); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->low_wm_hit_count, + "low_wm_hit_count", HTT_STATS_LOW_WM_BINS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->high_wm_hit_count, + "high_wm_hit_count", HTT_STATS_HIGH_WM_BINS, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2660,11 +2535,11 @@ static inline void htt_print_ring_if_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RING_IF_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_records = %u\n", - htt_stats_buf->num_records); + len += scnprintf(buf + len, buf_len - len, "HTT_RING_IF_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n", + htt_stats_buf->num_records); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2682,16 +2557,12 @@ static inline void htt_print_sfm_client_user_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char dwords_used_by_user_n[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = tag_len >> 2; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV_V:\n"); - ARRAY_TO_STRING(dwords_used_by_user_n, - htt_stats_buf->dwords_used_by_user_n, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dwords_used_by_user_n = %s\n", - dwords_used_by_user_n); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->dwords_used_by_user_n, + "dwords_used_by_user_n", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2709,21 +2580,21 @@ static inline void htt_print_sfm_client_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "client_id = %u", - htt_stats_buf->client_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_min = %u", - htt_stats_buf->buf_min); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_max = %u", - htt_stats_buf->buf_max); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_busy = %u", - htt_stats_buf->buf_busy); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_alloc = %u", - htt_stats_buf->buf_alloc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_avail = %u", - htt_stats_buf->buf_avail); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_users = %u\n", - htt_stats_buf->num_users); + len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "client_id = %u\n", + htt_stats_buf->client_id); + len += scnprintf(buf + len, buf_len - len, "buf_min = %u\n", + htt_stats_buf->buf_min); + len += scnprintf(buf + len, buf_len - len, "buf_max = %u\n", + htt_stats_buf->buf_max); + len += scnprintf(buf + len, buf_len - len, "buf_busy = %u\n", + htt_stats_buf->buf_busy); + len += scnprintf(buf + len, buf_len - len, "buf_alloc = %u\n", + htt_stats_buf->buf_alloc); + len += scnprintf(buf + len, buf_len - len, "buf_avail = %u\n", + htt_stats_buf->buf_avail); + len += scnprintf(buf + len, buf_len - len, "num_users = %u\n\n", + htt_stats_buf->num_users); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2741,17 +2612,17 @@ static inline void htt_print_sfm_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "buf_total = %u", - htt_stats_buf->buf_total); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mem_empty = %u", - htt_stats_buf->mem_empty); - len += HTT_DBG_OUT(buf + len, buf_len - len, "deallocate_bufs = %u", - htt_stats_buf->deallocate_bufs); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_records = %u\n", - htt_stats_buf->num_records); + len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n", + htt_stats_buf->buf_total); + len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n", + htt_stats_buf->mem_empty); + len += scnprintf(buf + len, buf_len - len, "deallocate_bufs = %u\n", + htt_stats_buf->deallocate_bufs); + len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n", + htt_stats_buf->num_records); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2769,42 +2640,51 @@ static inline void htt_print_sring_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ring_id = %u", - (htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "arena = %u", - (htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ep = %u", - (htt_stats_buf->mac_id__ring_id__arena__ep & 0x1000000) >> 24); - len += HTT_DBG_OUT(buf + len, buf_len - len, "base_addr_lsb = 0x%x", - htt_stats_buf->base_addr_lsb); - len += HTT_DBG_OUT(buf + len, buf_len - len, "base_addr_msb = 0x%x", - htt_stats_buf->base_addr_msb); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ring_size = %u", - htt_stats_buf->ring_size); - len += HTT_DBG_OUT(buf + len, buf_len - len, "elem_size = %u", - htt_stats_buf->elem_size); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_avail_words = %u", - htt_stats_buf->num_avail_words__num_valid_words & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_valid_words = %u", - (htt_stats_buf->num_avail_words__num_valid_words & - 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "head_ptr = %u", - htt_stats_buf->head_ptr__tail_ptr & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tail_ptr = %u", - (htt_stats_buf->head_ptr__tail_ptr & 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "consumer_empty = %u", - htt_stats_buf->consumer_empty__producer_full & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "producer_full = %u", - (htt_stats_buf->consumer_empty__producer_full & - 0xFFFF0000) >> 16); - len += HTT_DBG_OUT(buf + len, buf_len - len, "prefetch_count = %u", - htt_stats_buf->prefetch_count__internal_tail_ptr & 0xFFFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "internal_tail_ptr = %u\n", - (htt_stats_buf->prefetch_count__internal_tail_ptr & - 0xFFFF0000) >> 16); + len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_SRING_STATS_MAC_ID, + htt_stats_buf->mac_id__ring_id__arena__ep)); + len += scnprintf(buf + len, buf_len - len, "ring_id = %lu\n", + FIELD_GET(HTT_SRING_STATS_RING_ID, + htt_stats_buf->mac_id__ring_id__arena__ep)); + len += scnprintf(buf + len, buf_len - len, "arena = %lu\n", + FIELD_GET(HTT_SRING_STATS_ARENA, + htt_stats_buf->mac_id__ring_id__arena__ep)); + len += scnprintf(buf + len, buf_len - len, "ep = %lu\n", + FIELD_GET(HTT_SRING_STATS_EP, + htt_stats_buf->mac_id__ring_id__arena__ep)); + len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n", + htt_stats_buf->base_addr_lsb); + len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n", + htt_stats_buf->base_addr_msb); + len += scnprintf(buf + len, buf_len - len, "ring_size = %u\n", + htt_stats_buf->ring_size); + len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n", + htt_stats_buf->elem_size); + len += scnprintf(buf + len, buf_len - len, "num_avail_words = %lu\n", + FIELD_GET(HTT_SRING_STATS_NUM_AVAIL_WORDS, + htt_stats_buf->num_avail_words__num_valid_words)); + len += scnprintf(buf + len, buf_len - len, "num_valid_words = %lu\n", + FIELD_GET(HTT_SRING_STATS_NUM_VALID_WORDS, + htt_stats_buf->num_avail_words__num_valid_words)); + len += scnprintf(buf + len, buf_len - len, "head_ptr = %lu\n", + FIELD_GET(HTT_SRING_STATS_HEAD_PTR, + htt_stats_buf->head_ptr__tail_ptr)); + len += scnprintf(buf + len, buf_len - len, "tail_ptr = %lu\n", + FIELD_GET(HTT_SRING_STATS_TAIL_PTR, + htt_stats_buf->head_ptr__tail_ptr)); + len += scnprintf(buf + len, buf_len - len, "consumer_empty = %lu\n", + FIELD_GET(HTT_SRING_STATS_CONSUMER_EMPTY, + htt_stats_buf->consumer_empty__producer_full)); + len += scnprintf(buf + len, buf_len - len, "producer_full = %lu\n", + FIELD_GET(HTT_SRING_STATS_PRODUCER_FULL, + htt_stats_buf->consumer_empty__producer_full)); + len += scnprintf(buf + len, buf_len - len, "prefetch_count = %lu\n", + FIELD_GET(HTT_SRING_STATS_PREFETCH_COUNT, + htt_stats_buf->prefetch_count__internal_tail_ptr)); + len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %lu\n\n", + FIELD_GET(HTT_SRING_STATS_INTERNAL_TAIL_PTR, + htt_stats_buf->prefetch_count__internal_tail_ptr)); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2822,9 +2702,9 @@ static inline void htt_print_sring_cmn_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SRING_CMN_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_records = %u\n", - htt_stats_buf->num_records); + len += scnprintf(buf + len, buf_len - len, "HTT_SRING_CMN_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n", + htt_stats_buf->num_records); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2842,165 +2722,115 @@ static inline void htt_print_tx_pdev_rate_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u8 j; - char str_buf[HTT_MAX_STRING_LEN] = {0}; - char *tx_gi[HTT_TX_PEER_STATS_NUM_GI_COUNTERS] = {NULL}; - - for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) { - tx_gi[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!tx_gi[j]) - goto fail; - } - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_RATE_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_ldpc = %u", - htt_stats_buf->tx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_ldpc = %u", - htt_stats_buf->ac_mu_mimo_tx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_ldpc = %u", - htt_stats_buf->ax_mu_mimo_tx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_ldpc = %u", - htt_stats_buf->ofdma_tx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts_cnt = %u", - htt_stats_buf->rts_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts_success = %u", - htt_stats_buf->rts_success); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ack_rssi = %u", - htt_stats_buf->ack_rssi); - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "Legacy CCK Rates: 1 Mbps: %u, 2 Mbps: %u, 5.5 Mbps: %u, 11 Mbps: %u", - htt_stats_buf->tx_legacy_cck_rate[0], - htt_stats_buf->tx_legacy_cck_rate[1], - htt_stats_buf->tx_legacy_cck_rate[2], - htt_stats_buf->tx_legacy_cck_rate[3]); - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "Legacy OFDM Rates: 6 Mbps: %u, 9 Mbps: %u, 12 Mbps: %u, 18 Mbps: %u\n" - " 24 Mbps: %u, 36 Mbps: %u, 48 Mbps: %u, 54 Mbps: %u", - htt_stats_buf->tx_legacy_ofdm_rate[0], - htt_stats_buf->tx_legacy_ofdm_rate[1], - htt_stats_buf->tx_legacy_ofdm_rate[2], - htt_stats_buf->tx_legacy_ofdm_rate[3], - htt_stats_buf->tx_legacy_ofdm_rate[4], - htt_stats_buf->tx_legacy_ofdm_rate[5], - htt_stats_buf->tx_legacy_ofdm_rate[6], - htt_stats_buf->tx_legacy_ofdm_rate[7]); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_mcs, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_nss, - HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_nss, - HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_nss, - HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_nss, - HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_bw, - HTT_TX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_bw = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_bw, - HTT_TX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_bw = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_bw, - HTT_TX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_bw = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_bw, - HTT_TX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_bw = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_stbc, - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_stbc = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_pream, - HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_pream = %s ", str_buf); - - len += HTT_DBG_OUT(buf + len, buf_len - len, "HE LTF: 1x: %u, 2x: %u, 4x: %u", - htt_stats_buf->tx_he_ltf[1], - htt_stats_buf->tx_he_ltf[2], - htt_stats_buf->tx_he_ltf[3]); + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_RATE_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "tx_ldpc = %u\n", + htt_stats_buf->tx_ldpc); + len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_tx_ldpc = %u\n", + htt_stats_buf->ac_mu_mimo_tx_ldpc); + len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_tx_ldpc = %u\n", + htt_stats_buf->ax_mu_mimo_tx_ldpc); + len += scnprintf(buf + len, buf_len - len, "ofdma_tx_ldpc = %u\n", + htt_stats_buf->ofdma_tx_ldpc); + len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n", + htt_stats_buf->rts_cnt); + len += scnprintf(buf + len, buf_len - len, "rts_success = %u\n", + htt_stats_buf->rts_success); + len += scnprintf(buf + len, buf_len - len, "ack_rssi = %u\n", + htt_stats_buf->ack_rssi); + + len += scnprintf(buf + len, buf_len - len, + "Legacy CCK Rates: 1 Mbps: %u, 2 Mbps: %u, 5.5 Mbps: %u, 11 Mbps: %u\n", + htt_stats_buf->tx_legacy_cck_rate[0], + htt_stats_buf->tx_legacy_cck_rate[1], + htt_stats_buf->tx_legacy_cck_rate[2], + htt_stats_buf->tx_legacy_cck_rate[3]); + + len += scnprintf(buf + len, buf_len - len, + "Legacy OFDM Rates: 6 Mbps: %u, 9 Mbps: %u, 12 Mbps: %u, 18 Mbps: %u\n" + " 24 Mbps: %u, 36 Mbps: %u, 48 Mbps: %u, 54 Mbps: %u\n", + htt_stats_buf->tx_legacy_ofdm_rate[0], + htt_stats_buf->tx_legacy_ofdm_rate[1], + htt_stats_buf->tx_legacy_ofdm_rate[2], + htt_stats_buf->tx_legacy_ofdm_rate[3], + htt_stats_buf->tx_legacy_ofdm_rate[4], + htt_stats_buf->tx_legacy_ofdm_rate[5], + htt_stats_buf->tx_legacy_ofdm_rate[6], + htt_stats_buf->tx_legacy_ofdm_rate[7]); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mcs, "tx_mcs", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_mcs, + "ac_mu_mimo_tx_mcs", HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_mcs, + "ax_mu_mimo_tx_mcs", HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_mcs, "ofdma_tx_mcs", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_nss, "tx_nss", + HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_nss, + "ac_mu_mimo_tx_nss", + HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_nss, + "ax_mu_mimo_tx_nss", + HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_nss, "ofdma_tx_nss", + HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_bw, "tx_bw", + HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_bw, + "ac_mu_mimo_tx_bw", HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_bw, + "ax_mu_mimo_tx_bw", + HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_bw, "ofdma_tx_bw", + HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_stbc, "tx_stbc", + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_pream, "tx_pream", + HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n"); + + len += scnprintf(buf + len, buf_len - len, "HE LTF: 1x: %u, 2x: %u, 4x: %u\n", + htt_stats_buf->tx_he_ltf[1], + htt_stats_buf->tx_he_ltf[2], + htt_stats_buf->tx_he_ltf[3]); /* SU GI Stats */ for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->tx_gi[j], - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_gi[%u] = %s ", - j, tx_gi[j]); + len += scnprintf(buf + len, (buf_len - len), + "tx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_gi[j], NULL, + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } /* AC MU-MIMO GI Stats */ for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ac_mu_mimo_tx_gi[j], - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ac_mu_mimo_tx_gi[%u] = %s ", - j, tx_gi[j]); + len += scnprintf(buf + len, (buf_len - len), + "ac_mu_mimo_tx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_gi[j], + NULL, HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } /* AX MU-MIMO GI Stats */ for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ax_mu_mimo_tx_gi[j], - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ax_mu_mimo_tx_gi[%u] = %s ", - j, tx_gi[j]); + len += scnprintf(buf + len, (buf_len - len), + "ax_mu_mimo_tx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_gi[j], + NULL, HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } /* DL OFDMA GI Stats */ for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ofdma_tx_gi[j], - HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_gi[%u] = %s ", - j, tx_gi[j]); + len += scnprintf(buf + len, (buf_len - len), + "ofdma_tx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_gi[j], NULL, + HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_dcm, - HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_dcm = %s\n", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_dcm, "tx_dcm", + HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3008,9 +2838,6 @@ static inline void htt_print_tx_pdev_rate_stats_tlv(const void *tag_buf, buf[len] = 0; stats_req->buf_len = len; -fail: - for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) - kfree(tx_gi[j]); } static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf, @@ -3021,226 +2848,168 @@ static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; u8 i, j; - u16 index = 0; - char *rssi_chain[HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS] = {NULL}; - char *rx_gi[HTT_RX_PDEV_STATS_NUM_GI_COUNTERS] = {NULL}; - char str_buf[HTT_MAX_STRING_LEN] = {0}; - char *rx_pilot_evm_db[HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS] = {NULL}; - for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - rssi_chain[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!rssi_chain[j]) - goto fail; - } - - for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - rx_gi[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!rx_gi[j]) - goto fail; - } - - for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - rx_pilot_evm_db[j] = kmalloc(HTT_MAX_STRING_LEN, GFP_ATOMIC); - if (!rx_pilot_evm_db[j]) - goto fail; - } - - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_RATE_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "nsts = %u", - htt_stats_buf->nsts); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ldpc = %u", - htt_stats_buf->rx_ldpc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rts_cnt = %u", - htt_stats_buf->rts_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_mgmt = %u", - htt_stats_buf->rssi_mgmt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_data = %u", - htt_stats_buf->rssi_data); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_comb = %u", - htt_stats_buf->rssi_comb); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_in_dbm = %d", - htt_stats_buf->rssi_in_dbm); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_mcs, - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_mcs = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_nss, - HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_nss = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_dcm, - HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_dcm = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_stbc, - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_stbc = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_bw, - HTT_RX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_bw = %s ", str_buf); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_evm_nss_count = %u", - htt_stats_buf->nss_count); - - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_evm_pilot_count = %u", - htt_stats_buf->pilot_count); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_RATE_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "nsts = %u\n", + htt_stats_buf->nsts); + len += scnprintf(buf + len, buf_len - len, "rx_ldpc = %u\n", + htt_stats_buf->rx_ldpc); + len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n", + htt_stats_buf->rts_cnt); + len += scnprintf(buf + len, buf_len - len, "rssi_mgmt = %u\n", + htt_stats_buf->rssi_mgmt); + len += scnprintf(buf + len, buf_len - len, "rssi_data = %u\n", + htt_stats_buf->rssi_data); + len += scnprintf(buf + len, buf_len - len, "rssi_comb = %u\n", + htt_stats_buf->rssi_comb); + len += scnprintf(buf + len, buf_len - len, "rssi_in_dbm = %d\n", + htt_stats_buf->rssi_in_dbm); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_mcs, "rx_mcs", + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_nss, "rx_nss", + HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_dcm, "rx_dcm", + HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_stbc, "rx_stbc", + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_bw, "rx_bw", + HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); + + len += scnprintf(buf + len, buf_len - len, "rx_evm_nss_count = %u\n", + htt_stats_buf->nss_count); + + len += scnprintf(buf + len, buf_len - len, "rx_evm_pilot_count = %u\n", + htt_stats_buf->pilot_count); for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - index = 0; - + len += scnprintf(buf + len, buf_len - len, + "pilot_evm_db[%u] = ", j); for (i = 0; i < HTT_RX_PDEV_STATS_RXEVM_MAX_PILOTS_PER_NSS; i++) - index += scnprintf(&rx_pilot_evm_db[j][index], - HTT_MAX_STRING_LEN - index, - " %u:%d,", - i, - htt_stats_buf->rx_pilot_evm_db[j][i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pilot_evm_dB[%u] = %s ", - j, rx_pilot_evm_db[j]); + len += scnprintf(buf + len, + buf_len - len, + " %u:%d,", + i, + htt_stats_buf->rx_pilot_evm_db[j][i]); + len += scnprintf(buf + len, buf_len - len, "\n"); } - index = 0; - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); + len += scnprintf(buf + len, buf_len - len, + "pilot_evm_db_mean = "); for (i = 0; i < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++) - index += scnprintf(&str_buf[index], - HTT_MAX_STRING_LEN - index, - " %u:%d,", i, htt_stats_buf->rx_pilot_evm_db_mean[i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, "pilot_evm_dB_mean = %s ", str_buf); + len += scnprintf(buf + len, + buf_len - len, + " %u:%d,", i, + htt_stats_buf->rx_pilot_evm_db_mean[i]); + len += scnprintf(buf + len, buf_len - len, "\n"); for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - ARRAY_TO_STRING(rssi_chain[j], htt_stats_buf->rssi_chain[j], - HTT_RX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_chain[%u] = %s ", - j, rssi_chain[j]); + len += scnprintf(buf + len, buf_len - len, + "rssi_chain[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rssi_chain[j], NULL, + HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); } for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->rx_gi[j], - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_gi[%u] = %s ", - j, rx_gi[j]); + len += scnprintf(buf + len, buf_len - len, + "rx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_gi[j], NULL, + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_pream, - HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_pream = %s", str_buf); - - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ax_su_ext = %u", - htt_stats_buf->rx_11ax_su_ext); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ac_mumimo = %u", - htt_stats_buf->rx_11ac_mumimo); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ax_mumimo = %u", - htt_stats_buf->rx_11ax_mumimo); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ax_ofdma = %u", - htt_stats_buf->rx_11ax_ofdma); - len += HTT_DBG_OUT(buf + len, buf_len - len, "txbf = %u", - htt_stats_buf->txbf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_legacy_cck_rate, - HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_legacy_cck_rate = %s ", - str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_legacy_ofdm_rate, - HTT_RX_PDEV_STATS_NUM_LEGACY_OFDM_STATS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_legacy_ofdm_rate = %s ", - str_buf); - - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_active_dur_us_low = %u", - htt_stats_buf->rx_active_dur_us_low); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_active_dur_us_high = %u", - htt_stats_buf->rx_active_dur_us_high); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ax_ul_ofdma = %u", - htt_stats_buf->rx_11ax_ul_ofdma); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_mcs, - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_mcs = %s ", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_pream, "rx_pream", + HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n"); + + len += scnprintf(buf + len, buf_len - len, "rx_11ax_su_ext = %u\n", + htt_stats_buf->rx_11ax_su_ext); + len += scnprintf(buf + len, buf_len - len, "rx_11ac_mumimo = %u\n", + htt_stats_buf->rx_11ac_mumimo); + len += scnprintf(buf + len, buf_len - len, "rx_11ax_mumimo = %u\n", + htt_stats_buf->rx_11ax_mumimo); + len += scnprintf(buf + len, buf_len - len, "rx_11ax_ofdma = %u\n", + htt_stats_buf->rx_11ax_ofdma); + len += scnprintf(buf + len, buf_len - len, "txbf = %u\n", + htt_stats_buf->txbf); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_legacy_cck_rate, + "rx_legacy_cck_rate", + HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS, "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_legacy_ofdm_rate, + "rx_legacy_ofdm_rate", + HTT_RX_PDEV_STATS_NUM_LEGACY_OFDM_STATS, "\n"); + + len += scnprintf(buf + len, buf_len - len, "rx_active_dur_us_low = %u\n", + htt_stats_buf->rx_active_dur_us_low); + len += scnprintf(buf + len, buf_len - len, "rx_active_dur_us_high = %u\n", + htt_stats_buf->rx_active_dur_us_high); + len += scnprintf(buf + len, buf_len - len, "rx_11ax_ul_ofdma = %u\n", + htt_stats_buf->rx_11ax_ul_ofdma); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_mcs, + "ul_ofdma_rx_mcs", + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) { - ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->ul_ofdma_rx_gi[j], - HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_gi[%u] = %s ", - j, rx_gi[j]); + len += scnprintf(buf + len, buf_len - len, + "ul_ofdma_rx_gi[%u] = ", j); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_gi[j], NULL, + HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n"); } - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_nss, - HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_nss = %s ", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_nss, + "ul_ofdma_rx_nss", + HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n"); - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_bw, - HTT_RX_PDEV_STATS_NUM_BW_COUNTERS); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_bw = %s ", str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_bw, "ul_ofdma_rx_bw", + HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_stbc = %u", + len += scnprintf(buf + len, buf_len - len, "ul_ofdma_rx_stbc = %u\n", htt_stats_buf->ul_ofdma_rx_stbc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_ldpc = %u", + len += scnprintf(buf + len, buf_len - len, "ul_ofdma_rx_ldpc = %u\n", htt_stats_buf->ul_ofdma_rx_ldpc); - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_non_data_ppdu, - HTT_RX_PDEV_MAX_OFDMA_NUM_USER); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_non_data_ppdu = %s ", - str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_data_ppdu, - HTT_RX_PDEV_MAX_OFDMA_NUM_USER); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_data_ppdu = %s ", - str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_mpdu_ok, - HTT_RX_PDEV_MAX_OFDMA_NUM_USER); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_mpdu_ok = %s ", str_buf); - - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); - ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_mpdu_fail, - HTT_RX_PDEV_MAX_OFDMA_NUM_USER); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_mpdu_fail = %s", - str_buf); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_non_data_ppdu, + "rx_ulofdma_non_data_ppdu", + HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_data_ppdu, + "rx_ulofdma_data_ppdu", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_mpdu_ok, + "rx_ulofdma_mpdu_ok", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_mpdu_fail, + "rx_ulofdma_mpdu_fail", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n"); for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - index = 0; - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); + len += scnprintf(buf + len, buf_len - len, + "rx_ul_fd_rssi: nss[%u] = ", j); for (i = 0; i < HTT_RX_PDEV_MAX_OFDMA_NUM_USER; i++) - index += scnprintf(&str_buf[index], - HTT_MAX_STRING_LEN - index, - " %u:%d,", - i, htt_stats_buf->rx_ul_fd_rssi[j][i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "rx_ul_fd_rssi: nss[%u] = %s", j, str_buf); + len += scnprintf(buf + len, + buf_len - len, + " %u:%d,", + i, htt_stats_buf->rx_ul_fd_rssi[j][i]); + len += scnprintf(buf + len, buf_len - len, "\n"); } - len += HTT_DBG_OUT(buf + len, buf_len - len, "per_chain_rssi_pkt_type = %#x", - htt_stats_buf->per_chain_rssi_pkt_type); + len += scnprintf(buf + len, buf_len - len, "per_chain_rssi_pkt_type = %#x\n", + htt_stats_buf->per_chain_rssi_pkt_type); for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) { - index = 0; - memset(str_buf, 0x0, HTT_MAX_STRING_LEN); + len += scnprintf(buf + len, buf_len - len, + "rx_per_chain_rssi_in_dbm[%u] = ", j); for (i = 0; i < HTT_RX_PDEV_STATS_NUM_BW_COUNTERS; i++) - index += scnprintf(&str_buf[index], - HTT_MAX_STRING_LEN - index, - " %u:%d,", - i, - htt_stats_buf->rx_per_chain_rssi_in_dbm[j][i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "rx_per_chain_rssi_in_dbm[%u] = %s ", j, str_buf); + len += scnprintf(buf + len, + buf_len - len, + " %u:%d,", + i, + htt_stats_buf->rx_per_chain_rssi_in_dbm[j][i]); + len += scnprintf(buf + len, buf_len - len, "\n"); } - len += HTT_DBG_OUT(buf + len, buf_len - len, "\n"); + len += scnprintf(buf + len, buf_len - len, "\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3248,16 +3017,6 @@ static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf, buf[len] = 0; stats_req->buf_len = len; - -fail: - for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) - kfree(rssi_chain[j]); - - for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) - kfree(rx_pilot_evm_db[j]); - - for (i = 0; i < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; i++) - kfree(rx_gi[i]); } static inline void htt_print_rx_soc_fw_stats_tlv(const void *tag_buf, @@ -3268,34 +3027,34 @@ static inline void htt_print_rx_soc_fw_stats_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_SOC_FW_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_reo_ring_data_msdu = %u", - htt_stats_buf->fw_reo_ring_data_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_to_host_data_msdu_bcmc = %u", - htt_stats_buf->fw_to_host_data_msdu_bcmc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_to_host_data_msdu_uc = %u", - htt_stats_buf->fw_to_host_data_msdu_uc); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ofld_remote_data_buf_recycle_cnt = %u", - htt_stats_buf->ofld_remote_data_buf_recycle_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ofld_remote_free_buf_indication_cnt = %u", - htt_stats_buf->ofld_remote_free_buf_indication_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ofld_buf_to_host_data_msdu_uc = %u", - htt_stats_buf->ofld_buf_to_host_data_msdu_uc); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "reo_fw_ring_to_host_data_msdu_uc = %u", - htt_stats_buf->reo_fw_ring_to_host_data_msdu_uc); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wbm_sw_ring_reap = %u", - htt_stats_buf->wbm_sw_ring_reap); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wbm_forward_to_host_cnt = %u", - htt_stats_buf->wbm_forward_to_host_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wbm_target_recycle_cnt = %u", - htt_stats_buf->wbm_target_recycle_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "target_refill_ring_recycle_cnt = %u", - htt_stats_buf->target_refill_ring_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_SOC_FW_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "fw_reo_ring_data_msdu = %u\n", + htt_stats_buf->fw_reo_ring_data_msdu); + len += scnprintf(buf + len, buf_len - len, "fw_to_host_data_msdu_bcmc = %u\n", + htt_stats_buf->fw_to_host_data_msdu_bcmc); + len += scnprintf(buf + len, buf_len - len, "fw_to_host_data_msdu_uc = %u\n", + htt_stats_buf->fw_to_host_data_msdu_uc); + len += scnprintf(buf + len, buf_len - len, + "ofld_remote_data_buf_recycle_cnt = %u\n", + htt_stats_buf->ofld_remote_data_buf_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, + "ofld_remote_free_buf_indication_cnt = %u\n", + htt_stats_buf->ofld_remote_free_buf_indication_cnt); + len += scnprintf(buf + len, buf_len - len, + "ofld_buf_to_host_data_msdu_uc = %u\n", + htt_stats_buf->ofld_buf_to_host_data_msdu_uc); + len += scnprintf(buf + len, buf_len - len, + "reo_fw_ring_to_host_data_msdu_uc = %u\n", + htt_stats_buf->reo_fw_ring_to_host_data_msdu_uc); + len += scnprintf(buf + len, buf_len - len, "wbm_sw_ring_reap = %u\n", + htt_stats_buf->wbm_sw_ring_reap); + len += scnprintf(buf + len, buf_len - len, "wbm_forward_to_host_cnt = %u\n", + htt_stats_buf->wbm_forward_to_host_cnt); + len += scnprintf(buf + len, buf_len - len, "wbm_target_recycle_cnt = %u\n", + htt_stats_buf->wbm_target_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, + "target_refill_ring_recycle_cnt = %u\n", + htt_stats_buf->target_refill_ring_recycle_cnt); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3314,17 +3073,13 @@ htt_print_rx_soc_fw_refill_ring_empty_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char refill_ring_empty_cnt[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_REFILL_MAX_RING); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_RX_SOC_FW_REFILL_RING_EMPTY_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_RX_SOC_FW_REFILL_RING_EMPTY_TLV_V:\n"); - ARRAY_TO_STRING(refill_ring_empty_cnt, - htt_stats_buf->refill_ring_empty_cnt, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "refill_ring_empty_cnt = %s\n", - refill_ring_empty_cnt); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->refill_ring_empty_cnt, + "refill_ring_empty_cnt", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3344,17 +3099,13 @@ htt_print_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char rxdma_err_cnt[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_RXDMA_MAX_ERR_CODE); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_RX_SOC_FW_REFILL_RING_NUM_RXDMA_ERR_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_RX_SOC_FW_REFILL_RING_NUM_RXDMA_ERR_TLV_V:\n"); - ARRAY_TO_STRING(rxdma_err_cnt, - htt_stats_buf->rxdma_err, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rxdma_err = %s\n", - rxdma_err_cnt); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rxdma_err, "rxdma_err", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3373,17 +3124,13 @@ htt_print_rx_soc_fw_refill_ring_num_reo_err_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char reo_err_cnt[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_REO_MAX_ERR_CODE); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_RX_SOC_FW_REFILL_RING_NUM_REO_ERR_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_RX_SOC_FW_REFILL_RING_NUM_REO_ERR_TLV_V:\n"); - ARRAY_TO_STRING(reo_err_cnt, - htt_stats_buf->reo_err, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "reo_err = %s\n", - reo_err_cnt); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->reo_err, "reo_err", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3402,27 +3149,27 @@ htt_print_rx_reo_debug_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_REO_RESOURCE_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sample_id = %u", - htt_stats_buf->sample_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "total_max = %u", - htt_stats_buf->total_max); - len += HTT_DBG_OUT(buf + len, buf_len - len, "total_avg = %u", - htt_stats_buf->total_avg); - len += HTT_DBG_OUT(buf + len, buf_len - len, "total_sample = %u", - htt_stats_buf->total_sample); - len += HTT_DBG_OUT(buf + len, buf_len - len, "non_zeros_avg = %u", - htt_stats_buf->non_zeros_avg); - len += HTT_DBG_OUT(buf + len, buf_len - len, "non_zeros_sample = %u", - htt_stats_buf->non_zeros_sample); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_non_zeros_max = %u", - htt_stats_buf->last_non_zeros_max); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_non_zeros_min %u", - htt_stats_buf->last_non_zeros_min); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_non_zeros_avg %u", - htt_stats_buf->last_non_zeros_avg); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_non_zeros_sample %u\n", - htt_stats_buf->last_non_zeros_sample); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_REO_RESOURCE_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "sample_id = %u\n", + htt_stats_buf->sample_id); + len += scnprintf(buf + len, buf_len - len, "total_max = %u\n", + htt_stats_buf->total_max); + len += scnprintf(buf + len, buf_len - len, "total_avg = %u\n", + htt_stats_buf->total_avg); + len += scnprintf(buf + len, buf_len - len, "total_sample = %u\n", + htt_stats_buf->total_sample); + len += scnprintf(buf + len, buf_len - len, "non_zeros_avg = %u\n", + htt_stats_buf->non_zeros_avg); + len += scnprintf(buf + len, buf_len - len, "non_zeros_sample = %u\n", + htt_stats_buf->non_zeros_sample); + len += scnprintf(buf + len, buf_len - len, "last_non_zeros_max = %u\n", + htt_stats_buf->last_non_zeros_max); + len += scnprintf(buf + len, buf_len - len, "last_non_zeros_min %u\n", + htt_stats_buf->last_non_zeros_min); + len += scnprintf(buf + len, buf_len - len, "last_non_zeros_avg %u\n", + htt_stats_buf->last_non_zeros_avg); + len += scnprintf(buf + len, buf_len - len, "last_non_zeros_sample %u\n\n", + htt_stats_buf->last_non_zeros_sample); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3441,17 +3188,13 @@ htt_print_rx_soc_fw_refill_ring_num_refill_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char refill_ring_num_refill[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_REFILL_MAX_RING); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_RX_SOC_FW_REFILL_RING_NUM_REFILL_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_RX_SOC_FW_REFILL_RING_NUM_REFILL_TLV_V:\n"); - ARRAY_TO_STRING(refill_ring_num_refill, - htt_stats_buf->refill_ring_num_refill, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "refill_ring_num_refill = %s\n", - refill_ring_num_refill); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->refill_ring_num_refill, + "refill_ring_num_refill", num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3468,113 +3211,106 @@ static inline void htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char fw_ring_mgmt_subtype[HTT_MAX_STRING_LEN] = {0}; - char fw_ring_ctrl_subtype[HTT_MAX_STRING_LEN] = {0}; - - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ppdu_recvd = %u", - htt_stats_buf->ppdu_recvd); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u", - htt_stats_buf->mpdu_cnt_fcs_ok); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u", - htt_stats_buf->mpdu_cnt_fcs_err); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tcp_msdu_cnt = %u", - htt_stats_buf->tcp_msdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u", - htt_stats_buf->tcp_ack_msdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "udp_msdu_cnt = %u", - htt_stats_buf->udp_msdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "other_msdu_cnt = %u", - htt_stats_buf->other_msdu_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u", - htt_stats_buf->fw_ring_mpdu_ind); - - ARRAY_TO_STRING(fw_ring_mgmt_subtype, - htt_stats_buf->fw_ring_mgmt_subtype, - HTT_STATS_SUBTYPE_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mgmt_subtype = %s ", - fw_ring_mgmt_subtype); - - ARRAY_TO_STRING(fw_ring_ctrl_subtype, - htt_stats_buf->fw_ring_ctrl_subtype, - HTT_STATS_SUBTYPE_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_ctrl_subtype = %s ", - fw_ring_ctrl_subtype); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u", - htt_stats_buf->fw_ring_mcast_data_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u", - htt_stats_buf->fw_ring_bcast_data_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u", - htt_stats_buf->fw_ring_ucast_data_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u", - htt_stats_buf->fw_ring_null_data_msdu); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u", - htt_stats_buf->fw_ring_mpdu_drop); - len += HTT_DBG_OUT(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u", - htt_stats_buf->ofld_local_data_ind_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "ofld_local_data_buf_recycle_cnt = %u", - htt_stats_buf->ofld_local_data_buf_recycle_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u", - htt_stats_buf->drx_local_data_ind_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "drx_local_data_buf_recycle_cnt = %u", - htt_stats_buf->drx_local_data_buf_recycle_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_nondata_ind_cnt = %u", - htt_stats_buf->local_nondata_ind_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u", - htt_stats_buf->local_nondata_buf_recycle_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u", - htt_stats_buf->fw_status_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u", - htt_stats_buf->fw_status_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u", - htt_stats_buf->fw_pkt_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u", - htt_stats_buf->fw_pkt_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u", - htt_stats_buf->fw_link_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u", - htt_stats_buf->fw_link_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u", - htt_stats_buf->host_pkt_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u", - htt_stats_buf->host_pkt_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u", - htt_stats_buf->mon_pkt_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u", - htt_stats_buf->mon_pkt_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "mon_status_buf_ring_refill_cnt = %u", - htt_stats_buf->mon_status_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u", - htt_stats_buf->mon_status_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u", - htt_stats_buf->mon_desc_buf_ring_refill_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u", - htt_stats_buf->mon_desc_buf_ring_empty_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u", - htt_stats_buf->mon_dest_ring_update_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u", - htt_stats_buf->mon_dest_ring_full_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_suspend_cnt = %u", - htt_stats_buf->rx_suspend_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u", - htt_stats_buf->rx_suspend_fail_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_resume_cnt = %u", - htt_stats_buf->rx_resume_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_resume_fail_cnt = %u", - htt_stats_buf->rx_resume_fail_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ring_switch_cnt = %u", - htt_stats_buf->rx_ring_switch_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ring_restore_cnt = %u", - htt_stats_buf->rx_ring_restore_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_flush_cnt = %u", - htt_stats_buf->rx_flush_cnt); - len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n", - htt_stats_buf->rx_recovery_reset_cnt); + + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n", + htt_stats_buf->ppdu_recvd); + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n", + htt_stats_buf->mpdu_cnt_fcs_ok); + len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u\n", + htt_stats_buf->mpdu_cnt_fcs_err); + len += scnprintf(buf + len, buf_len - len, "tcp_msdu_cnt = %u\n", + htt_stats_buf->tcp_msdu_cnt); + len += scnprintf(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u\n", + htt_stats_buf->tcp_ack_msdu_cnt); + len += scnprintf(buf + len, buf_len - len, "udp_msdu_cnt = %u\n", + htt_stats_buf->udp_msdu_cnt); + len += scnprintf(buf + len, buf_len - len, "other_msdu_cnt = %u\n", + htt_stats_buf->other_msdu_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u\n", + htt_stats_buf->fw_ring_mpdu_ind); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_mgmt_subtype, + "fw_ring_mgmt_subtype", HTT_STATS_SUBTYPE_MAX, "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_ctrl_subtype, + "fw_ring_ctrl_subtype", HTT_STATS_SUBTYPE_MAX, "\n"); + + len += scnprintf(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u\n", + htt_stats_buf->fw_ring_mcast_data_msdu); + len += scnprintf(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u\n", + htt_stats_buf->fw_ring_bcast_data_msdu); + len += scnprintf(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u\n", + htt_stats_buf->fw_ring_ucast_data_msdu); + len += scnprintf(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u\n", + htt_stats_buf->fw_ring_null_data_msdu); + len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u\n", + htt_stats_buf->fw_ring_mpdu_drop); + len += scnprintf(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u\n", + htt_stats_buf->ofld_local_data_ind_cnt); + len += scnprintf(buf + len, buf_len - len, + "ofld_local_data_buf_recycle_cnt = %u\n", + htt_stats_buf->ofld_local_data_buf_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u\n", + htt_stats_buf->drx_local_data_ind_cnt); + len += scnprintf(buf + len, buf_len - len, + "drx_local_data_buf_recycle_cnt = %u\n", + htt_stats_buf->drx_local_data_buf_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, "local_nondata_ind_cnt = %u\n", + htt_stats_buf->local_nondata_ind_cnt); + len += scnprintf(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u\n", + htt_stats_buf->local_nondata_buf_recycle_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u\n", + htt_stats_buf->fw_status_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u\n", + htt_stats_buf->fw_status_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u\n", + htt_stats_buf->fw_pkt_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u\n", + htt_stats_buf->fw_pkt_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u\n", + htt_stats_buf->fw_link_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u\n", + htt_stats_buf->fw_link_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u\n", + htt_stats_buf->host_pkt_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u\n", + htt_stats_buf->host_pkt_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u\n", + htt_stats_buf->mon_pkt_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u\n", + htt_stats_buf->mon_pkt_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, + "mon_status_buf_ring_refill_cnt = %u\n", + htt_stats_buf->mon_status_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u\n", + htt_stats_buf->mon_status_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u\n", + htt_stats_buf->mon_desc_buf_ring_refill_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u\n", + htt_stats_buf->mon_desc_buf_ring_empty_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u\n", + htt_stats_buf->mon_dest_ring_update_cnt); + len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u\n", + htt_stats_buf->mon_dest_ring_full_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_suspend_cnt = %u\n", + htt_stats_buf->rx_suspend_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u\n", + htt_stats_buf->rx_suspend_fail_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_resume_cnt = %u\n", + htt_stats_buf->rx_resume_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_resume_fail_cnt = %u\n", + htt_stats_buf->rx_resume_fail_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_ring_switch_cnt = %u\n", + htt_stats_buf->rx_ring_switch_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_ring_restore_cnt = %u\n", + htt_stats_buf->rx_ring_restore_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n", + htt_stats_buf->rx_flush_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n\n", + htt_stats_buf->rx_recovery_reset_cnt); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3592,16 +3328,12 @@ htt_print_rx_pdev_fw_ring_mpdu_err_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char fw_ring_mpdu_err[HTT_MAX_STRING_LEN] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_RX_PDEV_FW_RING_MPDU_ERR_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, + "HTT_RX_PDEV_FW_RING_MPDU_ERR_TLV_V:\n"); - ARRAY_TO_STRING(fw_ring_mpdu_err, - htt_stats_buf->fw_ring_mpdu_err, - HTT_RX_STATS_RXDMA_MAX_ERR); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mpdu_err = %s\n", - fw_ring_mpdu_err); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_mpdu_err, + "fw_ring_mpdu_err", HTT_RX_STATS_RXDMA_MAX_ERR, "\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3620,15 +3352,12 @@ htt_print_rx_pdev_fw_mpdu_drop_tlv_v(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char fw_mpdu_drop[HTT_MAX_STRING_LEN] = {0}; u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_FW_DROP_REASON_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_FW_MPDU_DROP_TLV_V:"); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_MPDU_DROP_TLV_V:\n"); - ARRAY_TO_STRING(fw_mpdu_drop, - htt_stats_buf->fw_mpdu_drop, - num_elems); - len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_mpdu_drop = %s\n", fw_mpdu_drop); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_mpdu_drop, "fw_mpdu_drop", + num_elems, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3646,18 +3375,15 @@ htt_print_rx_pdev_fw_stats_phy_err_tlv(const void *tag_buf, u8 *buf = stats_req->buf; u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - char phy_errs[HTT_MAX_STRING_LEN] = {0}; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_PHY_ERR_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id__word = %u", - htt_stats_buf->mac_id__word); - len += HTT_DBG_OUT(buf + len, buf_len - len, "total_phy_err_nct = %u", - htt_stats_buf->total_phy_err_cnt); + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_PHY_ERR_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id__word = %u\n", + htt_stats_buf->mac_id__word); + len += scnprintf(buf + len, buf_len - len, "total_phy_err_nct = %u\n", + htt_stats_buf->total_phy_err_cnt); - ARRAY_TO_STRING(phy_errs, - htt_stats_buf->phy_err, - HTT_STATS_PHY_ERR_MAX); - len += HTT_DBG_OUT(buf + len, buf_len - len, "phy_errs = %s\n", phy_errs); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->phy_err, "phy_errs", + HTT_STATS_PHY_ERR_MAX, "\n\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3676,20 +3402,20 @@ htt_print_pdev_cca_stats_hist_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "\nHTT_PDEV_CCA_STATS_HIST_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "chan_num = %u", - htt_stats_buf->chan_num); - len += HTT_DBG_OUT(buf + len, buf_len - len, "num_records = %u", - htt_stats_buf->num_records); - len += HTT_DBG_OUT(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x", - htt_stats_buf->valid_cca_counters_bitmap); - len += HTT_DBG_OUT(buf + len, buf_len - len, "collection_interval = %u\n", - htt_stats_buf->collection_interval); - - len += HTT_DBG_OUT(buf + len, buf_len - len, - "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)"); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "| tx_frame| rx_frame| rx_clear| my_rx_frame| cnt| med_rx_idle| med_tx_idle_global| cca_obss|"); + len += scnprintf(buf + len, buf_len - len, "\nHTT_PDEV_CCA_STATS_HIST_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n", + htt_stats_buf->chan_num); + len += scnprintf(buf + len, buf_len - len, "num_records = %u\n", + htt_stats_buf->num_records); + len += scnprintf(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x\n", + htt_stats_buf->valid_cca_counters_bitmap); + len += scnprintf(buf + len, buf_len - len, "collection_interval = %u\n\n", + htt_stats_buf->collection_interval); + + len += scnprintf(buf + len, buf_len - len, + "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)\n"); + len += scnprintf(buf + len, buf_len - len, + "| tx_frame| rx_frame| rx_clear| my_rx_frame| cnt| med_rx_idle| med_tx_idle_global| cca_obss|\n"); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3708,16 +3434,16 @@ htt_print_pdev_stats_cca_counters_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, - "|%10u| %10u| %10u| %11u| %10u| %11u| %18u| %10u|", - htt_stats_buf->tx_frame_usec, - htt_stats_buf->rx_frame_usec, - htt_stats_buf->rx_clear_usec, - htt_stats_buf->my_rx_frame_usec, - htt_stats_buf->usec_cnt, - htt_stats_buf->med_rx_idle_usec, - htt_stats_buf->med_tx_idle_global_usec, - htt_stats_buf->cca_obss_usec); + len += scnprintf(buf + len, buf_len - len, + "|%10u| %10u| %10u| %11u| %10u| %11u| %18u| %10u|\n", + htt_stats_buf->tx_frame_usec, + htt_stats_buf->rx_frame_usec, + htt_stats_buf->rx_clear_usec, + htt_stats_buf->my_rx_frame_usec, + htt_stats_buf->usec_cnt, + htt_stats_buf->med_rx_idle_usec, + htt_stats_buf->med_tx_idle_global_usec, + htt_stats_buf->cca_obss_usec); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3735,32 +3461,32 @@ static inline void htt_print_hw_stats_whal_tx_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id = %u", - htt_stats_buf->mac_id__word & 0xFF); - len += HTT_DBG_OUT(buf + len, buf_len - len, "last_unpause_ppdu_id = %u", - htt_stats_buf->last_unpause_ppdu_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u", - htt_stats_buf->hwsch_unpause_wait_tqm_write); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u", - htt_stats_buf->hwsch_dummy_tlv_skipped); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "hwsch_misaligned_offset_received = %u", - htt_stats_buf->hwsch_misaligned_offset_received); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_reset_count = %u", - htt_stats_buf->hwsch_reset_count); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_dev_reset_war = %u", - htt_stats_buf->hwsch_dev_reset_war); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_delayed_pause = %u", - htt_stats_buf->hwsch_delayed_pause); - len += HTT_DBG_OUT(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u", - htt_stats_buf->hwsch_long_delayed_pause); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u", - htt_stats_buf->sch_rx_ppdu_no_response); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sch_selfgen_response = %u", - htt_stats_buf->sch_selfgen_response); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n", - htt_stats_buf->sch_rx_sifs_resp_trigger); + len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n", + FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word)); + len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n", + htt_stats_buf->last_unpause_ppdu_id); + len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n", + htt_stats_buf->hwsch_unpause_wait_tqm_write); + len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n", + htt_stats_buf->hwsch_dummy_tlv_skipped); + len += scnprintf(buf + len, buf_len - len, + "hwsch_misaligned_offset_received = %u\n", + htt_stats_buf->hwsch_misaligned_offset_received); + len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n", + htt_stats_buf->hwsch_reset_count); + len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n", + htt_stats_buf->hwsch_dev_reset_war); + len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n", + htt_stats_buf->hwsch_delayed_pause); + len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n", + htt_stats_buf->hwsch_long_delayed_pause); + len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n", + htt_stats_buf->sch_rx_ppdu_no_response); + len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n", + htt_stats_buf->sch_selfgen_response); + len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n", + htt_stats_buf->sch_rx_sifs_resp_trigger); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3779,11 +3505,11 @@ htt_print_pdev_stats_twt_sessions_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSIONS_TLV:"); - 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, "num_sessions = %u\n", - htt_stats_buf->num_sessions); + len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSIONS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", + htt_stats_buf->pdev_id); + len += scnprintf(buf + len, buf_len - len, "num_sessions = %u\n\n", + htt_stats_buf->num_sessions); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3802,27 +3528,33 @@ htt_print_pdev_stats_twt_session_tlv(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSION_TLV:"); - len += HTT_DBG_OUT(buf + len, buf_len - len, "vdev_id = %u", - htt_stats_buf->vdev_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "peer_mac = %02x:%02x:%02x:%02x:%02x:%02x", - htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF, - (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF00) >> 8, - (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF0000) >> 16, - (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF000000) >> 24, - (htt_stats_buf->peer_mac.mac_addr_h16 & 0xFF), - (htt_stats_buf->peer_mac.mac_addr_h16 & 0xFF00) >> 8); - len += HTT_DBG_OUT(buf + len, buf_len - len, "flow_id_flags = %u", - htt_stats_buf->flow_id_flags); - len += HTT_DBG_OUT(buf + len, buf_len - len, "dialog_id = %u", - htt_stats_buf->dialog_id); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wake_dura_us = %u", - htt_stats_buf->wake_dura_us); - len += HTT_DBG_OUT(buf + len, buf_len - len, "wake_intvl_us = %u", - htt_stats_buf->wake_intvl_us); - len += HTT_DBG_OUT(buf + len, buf_len - len, "sp_offset_us = %u\n", - htt_stats_buf->sp_offset_us); + len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSION_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "vdev_id = %u\n", + htt_stats_buf->vdev_id); + len += scnprintf(buf + len, buf_len - len, + "peer_mac = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n", + FIELD_GET(HTT_MAC_ADDR_L32_0, + htt_stats_buf->peer_mac.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_1, + htt_stats_buf->peer_mac.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_2, + htt_stats_buf->peer_mac.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_L32_3, + htt_stats_buf->peer_mac.mac_addr_l32), + FIELD_GET(HTT_MAC_ADDR_H16_0, + htt_stats_buf->peer_mac.mac_addr_h16), + FIELD_GET(HTT_MAC_ADDR_H16_1, + htt_stats_buf->peer_mac.mac_addr_h16)); + len += scnprintf(buf + len, buf_len - len, "flow_id_flags = %u\n", + htt_stats_buf->flow_id_flags); + len += scnprintf(buf + len, buf_len - len, "dialog_id = %u\n", + htt_stats_buf->dialog_id); + len += scnprintf(buf + len, buf_len - len, "wake_dura_us = %u\n", + htt_stats_buf->wake_dura_us); + len += scnprintf(buf + len, buf_len - len, "wake_intvl_us = %u\n", + htt_stats_buf->wake_intvl_us); + len += scnprintf(buf + len, buf_len - len, "sp_offset_us = %u\n\n", + htt_stats_buf->sp_offset_us); if (len >= buf_len) buf[buf_len - 1] = 0; @@ -3841,21 +3573,21 @@ htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf, u32 len = stats_req->buf_len; u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; - len += HTT_DBG_OUT(buf + len, buf_len - len, "OBSS Tx success PPDU = %u", + len += scnprintf(buf + len, buf_len - len, "OBSS Tx success PPDU = %u\n", htt_stats_buf->num_obss_tx_ppdu_success); - len += HTT_DBG_OUT(buf + len, buf_len - len, "OBSS Tx failures PPDU = %u\n", + len += scnprintf(buf + len, buf_len - len, "OBSS Tx failures PPDU = %u\n", htt_stats_buf->num_obss_tx_ppdu_failure); - len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG Opportunities = %u\n", + len += scnprintf(buf + len, buf_len - len, "Non-SRG Opportunities = %u\n", htt_stats_buf->num_non_srg_opportunities); - len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG tried PPDU = %u\n", + len += scnprintf(buf + len, buf_len - len, "Non-SRG tried PPDU = %u\n", htt_stats_buf->num_non_srg_ppdu_tried); - len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG success PPDU = %u\n", + len += scnprintf(buf + len, buf_len - len, "Non-SRG success PPDU = %u\n", htt_stats_buf->num_non_srg_ppdu_success); - len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG Opportunities = %u\n", + len += scnprintf(buf + len, buf_len - len, "SRG Opportunities = %u\n", htt_stats_buf->num_srg_opportunities); - len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG tried PPDU = %u\n", + len += scnprintf(buf + len, buf_len - len, "SRG tried PPDU = %u\n", htt_stats_buf->num_srg_ppdu_tried); - len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG success PPDU = %u\n", + len += scnprintf(buf + len, buf_len - len, "SRG success PPDU = %u\n\n", htt_stats_buf->num_srg_ppdu_success); if (len >= buf_len) @@ -3878,25 +3610,25 @@ static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_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); + len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", + htt_stats_buf->pdev_id); + len += scnprintf(buf + len, buf_len - len, "current_head_idx = %u\n", + htt_stats_buf->current_head_idx); + len += scnprintf(buf + len, buf_len - len, "current_tail_idx = %u\n", + htt_stats_buf->current_tail_idx); + len += scnprintf(buf + len, buf_len - len, "num_htt_msgs_sent = %u\n", + htt_stats_buf->num_htt_msgs_sent); + len += scnprintf(buf + len, buf_len - len, + "backpressure_time_ms = %u\n", + 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 += scnprintf(buf + len, buf_len - len, + "backpressure_hist_%u = %u\n", + i + 1, htt_stats_buf->backpressure_hist[i]); - len += HTT_DBG_OUT(buf + len, buf_len - len, - "============================"); + len += scnprintf(buf + len, buf_len - len, + "============================\n"); if (len >= buf_len) { buf[buf_len - 1] = 0; @@ -3907,6 +3639,334 @@ static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf, } } +static inline +void htt_print_pdev_tx_rate_txbf_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_pdev_txrate_txbf_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, + "HTT_STATS_PDEV_TX_RATE_TXBF_STATS:\n"); + + len += scnprintf(buf + len, buf_len - len, "tx_ol_mcs = "); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ol_mcs[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_mcs = "); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ibf_mcs[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_mcs ="); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_txbf_mcs[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_ol_nss = "); + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ol_nss[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_nss = "); + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ibf_nss[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_nss = "); + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_txbf_nss[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_ol_bw = "); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ol_bw[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_bw = "); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_ibf_bw[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_bw = "); + for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++) + len += scnprintf(buf + len, buf_len - len, + "%d:%u,", i, htt_stats_buf->tx_su_txbf_bw[i]); + len--; + + len += scnprintf(buf + len, buf_len - len, "\n"); + + stats_req->buf_len = len; +} + +static inline +void htt_print_txbf_ofdma_ndpa_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_txbf_ofdma_ndpa_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, + "HTT_TXBF_OFDMA_NDPA_STATS_TLV:\n"); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) { + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndpa_queued_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndpa_queued[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndpa_tried_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndpa_tried[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndpa_flushed_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndpa_flushed[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndpa_err_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndpa_err[i]); + len += scnprintf(buf + len, buf_len - len, "\n"); + } + + stats_req->buf_len = len; +} + +static inline +void htt_print_txbf_ofdma_ndp_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_txbf_ofdma_ndp_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, + "HTT_TXBF_OFDMA_NDP_STATS_TLV:\n"); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) { + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndp_queued_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndp_queued[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndp_tried_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndp_tried[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndp_flushed_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndp_flushed[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_ndp_err_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_ndp_err[i]); + len += scnprintf(buf + len, buf_len - len, "\n"); + } + + stats_req->buf_len = len; +} + +static inline +void htt_print_txbf_ofdma_brp_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_txbf_ofdma_brp_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, + "HTT_TXBF_OFDMA_BRP_STATS_TLV:\n"); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) { + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_brpoll_queued_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_brpoll_queued[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_brpoll_tried_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_brpoll_tried[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_brpoll_flushed_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_brpoll_flushed[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_brp_err_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_brp_err[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_brp_err_num_cbf_rcvd_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_brp_err_num_cbf_rcvd[i]); + len += scnprintf(buf + len, buf_len - len, "\n"); + } + + stats_req->buf_len = len; +} + +static inline +void htt_print_txbf_ofdma_steer_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_txbf_ofdma_steer_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, + "HTT_TXBF_OFDMA_STEER_STATS_TLV:\n"); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) { + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_num_ppdu_steer_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_num_ppdu_steer[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_num_ppdu_ol_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_num_ppdu_ol[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_num_usrs_prefetch_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_num_usrs_prefetch[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_num_usrs_sound_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_num_usrs_sound[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ofdma_num_usrs_force_sound_user%d = %u\n", + i, htt_stats_buf->ax_ofdma_num_usrs_force_sound[i]); + len += scnprintf(buf + len, buf_len - len, "\n"); + } + + stats_req->buf_len = len; +} + +static inline +void htt_print_phy_counters_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_phy_counters_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, "HTT_PHY_COUNTERS_TLV:\n"); + len += scnprintf(buf + len, buf_len - len, "rx_ofdma_timing_err_cnt = %u\n", + htt_stats_buf->rx_ofdma_timing_err_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_cck_fail_cnt = %u\n", + htt_stats_buf->rx_cck_fail_cnt); + len += scnprintf(buf + len, buf_len - len, "mactx_abort_cnt = %u\n", + htt_stats_buf->mactx_abort_cnt); + len += scnprintf(buf + len, buf_len - len, "macrx_abort_cnt = %u\n", + htt_stats_buf->macrx_abort_cnt); + len += scnprintf(buf + len, buf_len - len, "phytx_abort_cnt = %u\n", + htt_stats_buf->phytx_abort_cnt); + len += scnprintf(buf + len, buf_len - len, "phyrx_abort_cnt = %u\n", + htt_stats_buf->phyrx_abort_cnt); + len += scnprintf(buf + len, buf_len - len, "phyrx_defer_abort_cnt = %u\n", + htt_stats_buf->phyrx_defer_abort_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_lstf_event_cnt = %u\n", + htt_stats_buf->rx_gain_adj_lstf_event_cnt); + len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_non_legacy_cnt = %u\n", + htt_stats_buf->rx_gain_adj_non_legacy_cnt); + + for (i = 0; i < HTT_MAX_RX_PKT_CNT; i++) + len += scnprintf(buf + len, buf_len - len, "rx_pkt_cnt[%d] = %u\n", + i, htt_stats_buf->rx_pkt_cnt[i]); + + for (i = 0; i < HTT_MAX_RX_PKT_CRC_PASS_CNT; i++) + len += scnprintf(buf + len, buf_len - len, + "rx_pkt_crc_pass_cnt[%d] = %u\n", + i, htt_stats_buf->rx_pkt_crc_pass_cnt[i]); + + for (i = 0; i < HTT_MAX_PER_BLK_ERR_CNT; i++) + len += scnprintf(buf + len, buf_len - len, + "per_blk_err_cnt[%d] = %u\n", + i, htt_stats_buf->per_blk_err_cnt[i]); + + for (i = 0; i < HTT_MAX_RX_OTA_ERR_CNT; i++) + len += scnprintf(buf + len, buf_len - len, + "rx_ota_err_cnt[%d] = %u\n", + i, htt_stats_buf->rx_ota_err_cnt[i]); + + stats_req->buf_len = len; +} + +static inline +void htt_print_phy_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_phy_stats_tlv *htt_stats_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + + len += scnprintf(buf + len, buf_len - len, "HTT_PHY_STATS_TLV:\n"); + + for (i = 0; i < HTT_STATS_MAX_CHAINS; i++) + len += scnprintf(buf + len, buf_len - len, "nf_chain[%d] = %d\n", + i, htt_stats_buf->nf_chain[i]); + + len += scnprintf(buf + len, buf_len - len, "false_radar_cnt = %u\n", + htt_stats_buf->false_radar_cnt); + len += scnprintf(buf + len, buf_len - len, "radar_cs_cnt = %u\n", + htt_stats_buf->radar_cs_cnt); + len += scnprintf(buf + len, buf_len - len, "ani_level = %d\n", + htt_stats_buf->ani_level); + len += scnprintf(buf + len, buf_len - len, "fw_run_time = %u\n", + htt_stats_buf->fw_run_time); + + stats_req->buf_len = len; +} + +static inline +void htt_print_peer_ctrl_path_txrx_stats_tlv(const void *tag_buf, + struct debug_htt_stats_req *stats_req) +{ + const struct htt_peer_ctrl_path_txrx_stats_tlv *htt_stat_buf = tag_buf; + u8 *buf = stats_req->buf; + u32 len = stats_req->buf_len; + u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; + int i; + const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1] = { + "assoc_req", "assoc_resp", + "reassoc_req", "reassoc_resp", + "probe_req", "probe_resp", + "timing_advertisement", "reserved", + "beacon", "atim", "disassoc", + "auth", "deauth", "action", "action_no_ack"}; + + len += scnprintf(buf + len, buf_len - len, + "HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG:\n"); + len += scnprintf(buf + len, buf_len - len, + "peer_mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", + htt_stat_buf->peer_mac_addr[0], htt_stat_buf->peer_mac_addr[1], + htt_stat_buf->peer_mac_addr[2], htt_stat_buf->peer_mac_addr[3], + htt_stat_buf->peer_mac_addr[4], htt_stat_buf->peer_mac_addr[5]); + + len += scnprintf(buf + len, buf_len - len, "peer_tx_mgmt_subtype:\n"); + for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++) + len += scnprintf(buf + len, buf_len - len, "%s:%u\n", + mgmt_frm_type[i], + htt_stat_buf->peer_rx_mgmt_subtype[i]); + + len += scnprintf(buf + len, buf_len - len, "peer_rx_mgmt_subtype:\n"); + for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++) + len += scnprintf(buf + len, buf_len - len, "%s:%u\n", + mgmt_frm_type[i], + htt_stat_buf->peer_rx_mgmt_subtype[i]); + + len += scnprintf(buf + len, buf_len - len, "\n"); + + stats_req->buf_len = len; +} + static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab, u16 tag, u16 len, const void *tag_buf, void *user_data) @@ -4258,6 +4318,30 @@ static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab, case HTT_STATS_RING_BACKPRESSURE_STATS_TAG: htt_print_backpressure_stats_tlv_v(tag_buf, user_data); break; + case HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG: + htt_print_pdev_tx_rate_txbf_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG: + htt_print_txbf_ofdma_ndpa_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG: + htt_print_txbf_ofdma_ndp_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG: + htt_print_txbf_ofdma_brp_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG: + htt_print_txbf_ofdma_steer_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_PHY_COUNTERS_TAG: + htt_print_phy_counters_tlv(tag_buf, stats_req); + break; + case HTT_STATS_PHY_STATS_TAG: + htt_print_phy_stats_tlv(tag_buf, stats_req); + break; + case HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG: + htt_print_peer_ctrl_path_txrx_stats_tlv(tag_buf, stats_req); + break; default: break; } @@ -4345,8 +4429,7 @@ static ssize_t ath11k_write_htt_stats_type(struct file *file, if (type >= ATH11K_DBG_HTT_NUM_EXT_STATS) return -E2BIG; - if (type == ATH11K_DBG_HTT_EXT_STATS_RESET || - type == ATH11K_DBG_HTT_EXT_STATS_PEER_INFO) + if (type == ATH11K_DBG_HTT_EXT_STATS_RESET) return -EPERM; ar->debug.htt_stats.type = type; @@ -4407,6 +4490,15 @@ static int ath11k_prep_htt_stats_cfg_params(struct ath11k *ar, u8 type, case ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO: cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS; break; + case ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS: + cfg_params->cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR; + cfg_params->cfg1 |= FIELD_PREP(GENMASK(7, 0), mac_addr[0]); + cfg_params->cfg1 |= FIELD_PREP(GENMASK(15, 8), mac_addr[1]); + cfg_params->cfg1 |= FIELD_PREP(GENMASK(23, 16), mac_addr[2]); + cfg_params->cfg1 |= FIELD_PREP(GENMASK(31, 24), mac_addr[3]); + cfg_params->cfg2 |= FIELD_PREP(GENMASK(7, 0), mac_addr[4]); + cfg_params->cfg2 |= FIELD_PREP(GENMASK(15, 8), mac_addr[5]); + break; default: break; } @@ -4464,7 +4556,9 @@ static int ath11k_open_htt_stats(struct inode *inode, struct file *file) u8 type = ar->debug.htt_stats.type; int ret; - if (type == ATH11K_DBG_HTT_EXT_STATS_RESET) + if (type == ATH11K_DBG_HTT_EXT_STATS_RESET || + type == ATH11K_DBG_HTT_EXT_STATS_PEER_INFO || + type == ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) return -EPERM; mutex_lock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h index d428f52003a4..dc210c54d131 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h @@ -102,6 +102,14 @@ enum htt_tlv_tag_t { HTT_STATS_PDEV_OBSS_PD_TAG = 88, HTT_STATS_HW_WAR_TAG = 89, HTT_STATS_RING_BACKPRESSURE_STATS_TAG = 90, + HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG = 101, + HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG = 108, + HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG = 113, + HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG = 114, + HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG = 115, + HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116, + HTT_STATS_PHY_COUNTERS_TAG = 121, + HTT_STATS_PHY_STATS_TAG = 122, HTT_STATS_MAX_TAG, }; @@ -137,6 +145,8 @@ struct htt_stats_string_tlv { u32 data[0]; /* Can be variable length */ } __packed; +#define HTT_STATS_MAC_ID GENMASK(7, 0) + /* == TX PDEV STATS == */ struct htt_tx_pdev_stats_cmn_tlv { u32 mac_id__word; @@ -290,6 +300,10 @@ struct htt_hw_stats_whal_tx_tlv { }; /* ============ PEER STATS ============ */ +#define HTT_MSDU_FLOW_STATS_TX_FLOW_NO GENMASK(15, 0) +#define HTT_MSDU_FLOW_STATS_TID_NUM GENMASK(19, 16) +#define HTT_MSDU_FLOW_STATS_DROP_RULE BIT(20) + struct htt_msdu_flow_stats_tlv { u32 last_update_timestamp; u32 last_add_timestamp; @@ -306,6 +320,11 @@ struct htt_msdu_flow_stats_tlv { #define MAX_HTT_TID_NAME 8 +#define HTT_TX_TID_STATS_SW_PEER_ID GENMASK(15, 0) +#define HTT_TX_TID_STATS_TID_NUM GENMASK(31, 16) +#define HTT_TX_TID_STATS_NUM_SCHED_PENDING GENMASK(7, 0) +#define HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ GENMASK(15, 8) + /* Tidq stats */ struct htt_tx_tid_stats_tlv { /* Stored as little endian */ @@ -326,6 +345,11 @@ struct htt_tx_tid_stats_tlv { u32 tid_tx_airtime; }; +#define HTT_TX_TID_STATS_V1_SW_PEER_ID GENMASK(15, 0) +#define HTT_TX_TID_STATS_V1_TID_NUM GENMASK(31, 16) +#define HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING GENMASK(7, 0) +#define HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ GENMASK(15, 8) + /* Tidq stats */ struct htt_tx_tid_stats_v1_tlv { /* Stored as little endian */ @@ -348,6 +372,9 @@ struct htt_tx_tid_stats_v1_tlv { u32 sendn_frms_allowed; }; +#define HTT_RX_TID_STATS_SW_PEER_ID GENMASK(15, 0) +#define HTT_RX_TID_STATS_TID_NUM GENMASK(31, 16) + struct htt_rx_tid_stats_tlv { u32 sw_peer_id__tid_num; u8 tid_name[MAX_HTT_TID_NAME]; @@ -386,6 +413,10 @@ struct htt_peer_stats_cmn_tlv { u32 inactive_time; }; +#define HTT_PEER_DETAILS_VDEV_ID GENMASK(7, 0) +#define HTT_PEER_DETAILS_PDEV_ID GENMASK(15, 8) +#define HTT_PEER_DETAILS_AST_IDX GENMASK(31, 16) + struct htt_peer_details_tlv { u32 peer_type; u32 sw_peer_id; @@ -510,6 +541,9 @@ struct htt_tx_hwq_mu_mimo_mpdu_stats_tlv { u32 mu_mimo_ampdu_underrun_usr; }; +#define HTT_TX_HWQ_STATS_MAC_ID GENMASK(7, 0) +#define HTT_TX_HWQ_STATS_HWQ_ID GENMASK(15, 8) + struct htt_tx_hwq_mu_mimo_cmn_stats_tlv { u32 mac_id__hwq_id__word; }; @@ -789,6 +823,9 @@ struct htt_sched_txq_sched_ineligibility_tlv_v { u32 sched_ineligibility[0]; }; +#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0) +#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID GENMASK(15, 8) + struct htt_tx_pdev_stats_sched_per_txq_tlv { u32 mac_id__txq_id__word; u32 sched_policy; @@ -910,6 +947,9 @@ struct htt_tx_tqm_error_stats_tlv { }; /* == TQM CMDQ stats == */ +#define HTT_TX_TQM_CMDQ_STATUS_MAC_ID GENMASK(7, 0) +#define HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID GENMASK(15, 8) + struct htt_tx_tqm_cmdq_status_tlv { u32 mac_id__cmdq_id__word; u32 sync_cmd; @@ -1055,6 +1095,15 @@ struct htt_tx_de_cmn_stats_tlv { #define HTT_STATS_LOW_WM_BINS 5 #define HTT_STATS_HIGH_WM_BINS 5 +#define HTT_RING_IF_STATS_NUM_ELEMS GENMASK(15, 0) +#define HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX GENMASK(31, 16) +#define HTT_RING_IF_STATS_HEAD_IDX GENMASK(15, 0) +#define HTT_RING_IF_STATS_TAIL_IDX GENMASK(31, 16) +#define HTT_RING_IF_STATS_SHADOW_HEAD_IDX GENMASK(15, 0) +#define HTT_RING_IF_STATS_SHADOW_TAIL_IDX GENMASK(31, 16) +#define HTT_RING_IF_STATS_LWM_THRESH GENMASK(15, 0) +#define HTT_RING_IF_STATS_HWM_THRESH GENMASK(31, 16) + struct htt_ring_if_stats_tlv { u32 base_addr; /* DWORD aligned base memory address of the ring */ u32 elem_size; @@ -1117,6 +1166,19 @@ struct htt_sfm_cmn_tlv { }; /* == SRNG STATS == */ +#define HTT_SRING_STATS_MAC_ID GENMASK(7, 0) +#define HTT_SRING_STATS_RING_ID GENMASK(15, 8) +#define HTT_SRING_STATS_ARENA GENMASK(23, 16) +#define HTT_SRING_STATS_EP BIT(24) +#define HTT_SRING_STATS_NUM_AVAIL_WORDS GENMASK(15, 0) +#define HTT_SRING_STATS_NUM_VALID_WORDS GENMASK(31, 16) +#define HTT_SRING_STATS_HEAD_PTR GENMASK(15, 0) +#define HTT_SRING_STATS_TAIL_PTR GENMASK(31, 16) +#define HTT_SRING_STATS_CONSUMER_EMPTY GENMASK(15, 0) +#define HTT_SRING_STATS_PRODUCER_FULL GENMASK(31, 16) +#define HTT_SRING_STATS_PREFETCH_COUNT GENMASK(15, 0) +#define HTT_SRING_STATS_INTERNAL_TAIL_PTR GENMASK(31, 16) + struct htt_sring_stats_tlv { u32 mac_id__ring_id__arena__ep; u32 base_addr_lsb; /* DWORD aligned base memory address of the ring */ @@ -1696,6 +1758,170 @@ struct htt_ring_backpressure_stats_tlv { u32 backpressure_hist[5]; }; +#define HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS 14 +#define HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS 5 +#define HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS 8 + +struct htt_pdev_txrate_txbf_stats_tlv { + /* SU TxBF TX MCS stats */ + u32 tx_su_txbf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS]; + /* Implicit BF TX MCS stats */ + u32 tx_su_ibf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS]; + /* Open loop TX MCS stats */ + u32 tx_su_ol_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS]; + /* SU TxBF TX NSS stats */ + u32 tx_su_txbf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS]; + /* Implicit BF TX NSS stats */ + u32 tx_su_ibf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS]; + /* Open loop TX NSS stats */ + u32 tx_su_ol_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS]; + /* SU TxBF TX BW stats */ + u32 tx_su_txbf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS]; + /* Implicit BF TX BW stats */ + u32 tx_su_ibf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS]; + /* Open loop TX BW stats */ + u32 tx_su_ol_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS]; +}; + +struct htt_txbf_ofdma_ndpa_stats_tlv { + /* 11AX HE OFDMA NDPA frame queued to the HW */ + u32 ax_ofdma_ndpa_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame sent over the air */ + u32 ax_ofdma_ndpa_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame flushed by HW */ + u32 ax_ofdma_ndpa_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame completed with error(s) */ + u32 ax_ofdma_ndpa_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; +}; + +struct htt_txbf_ofdma_ndp_stats_tlv { + /* 11AX HE OFDMA NDP frame queued to the HW */ + u32 ax_ofdma_ndp_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame sent over the air */ + u32 ax_ofdma_ndp_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame flushed by HW */ + u32 ax_ofdma_ndp_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA NDPA frame completed with error(s) */ + u32 ax_ofdma_ndp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; +}; + +struct htt_txbf_ofdma_brp_stats_tlv { + /* 11AX HE OFDMA MU BRPOLL frame queued to the HW */ + u32 ax_ofdma_brpoll_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA MU BRPOLL frame sent over the air */ + u32 ax_ofdma_brpoll_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA MU BRPOLL frame flushed by HW */ + u32 ax_ofdma_brpoll_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA MU BRPOLL frame completed with error(s) */ + u32 ax_ofdma_brp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* Number of CBF(s) received when 11AX HE OFDMA MU BRPOLL frame + * completed with error(s). + */ + u32 ax_ofdma_brp_err_num_cbf_rcvd[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS + 1]; +}; + +struct htt_txbf_ofdma_steer_stats_tlv { + /* 11AX HE OFDMA PPDUs that were sent over the air with steering (TXBF + OFDMA) */ + u32 ax_ofdma_num_ppdu_steer[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA PPDUs that were sent over the air in open loop */ + u32 ax_ofdma_num_ppdu_ol[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA number of users for which CBF prefetch was + * initiated to PHY HW during TX. + */ + u32 ax_ofdma_num_usrs_prefetch[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA number of users for which sounding was initiated during TX */ + u32 ax_ofdma_num_usrs_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + /* 11AX HE OFDMA number of users for which sounding was forced during TX */ + u32 ax_ofdma_num_usrs_force_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; +}; + +#define HTT_MAX_RX_PKT_CNT 8 +#define HTT_MAX_RX_PKT_CRC_PASS_CNT 8 +#define HTT_MAX_PER_BLK_ERR_CNT 20 +#define HTT_MAX_RX_OTA_ERR_CNT 14 +#define HTT_STATS_MAX_CHAINS 8 +#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16 + +struct htt_phy_counters_tlv { + /* number of RXTD OFDMA OTA error counts except power surge and drop */ + u32 rx_ofdma_timing_err_cnt; + /* rx_cck_fail_cnt: + * number of cck error counts due to rx reception failure because of + * timing error in cck + */ + u32 rx_cck_fail_cnt; + /* number of times tx abort initiated by mac */ + u32 mactx_abort_cnt; + /* number of times rx abort initiated by mac */ + u32 macrx_abort_cnt; + /* number of times tx abort initiated by phy */ + u32 phytx_abort_cnt; + /* number of times rx abort initiated by phy */ + u32 phyrx_abort_cnt; + /* number of rx defered count initiated by phy */ + u32 phyrx_defer_abort_cnt; + /* number of sizing events generated at LSTF */ + u32 rx_gain_adj_lstf_event_cnt; + /* number of sizing events generated at non-legacy LTF */ + u32 rx_gain_adj_non_legacy_cnt; + /* rx_pkt_cnt - + * Received EOP (end-of-packet) count per packet type; + * [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF + * [6-7]=RSVD + */ + u32 rx_pkt_cnt[HTT_MAX_RX_PKT_CNT]; + /* rx_pkt_crc_pass_cnt - + * Received EOP (end-of-packet) count per packet type; + * [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF + * [6-7]=RSVD + */ + u32 rx_pkt_crc_pass_cnt[HTT_MAX_RX_PKT_CRC_PASS_CNT]; + /* per_blk_err_cnt - + * Error count per error source; + * [0] = unknown; [1] = LSIG; [2] = HTSIG; [3] = VHTSIG; [4] = HESIG; + * [5] = RXTD_OTA; [6] = RXTD_FATAL; [7] = DEMF; [8] = ROBE; + * [9] = PMI; [10] = TXFD; [11] = TXTD; [12] = PHYRF + * [13-19]=RSVD + */ + u32 per_blk_err_cnt[HTT_MAX_PER_BLK_ERR_CNT]; + /* rx_ota_err_cnt - + * RXTD OTA (over-the-air) error count per error reason; + * [0] = voting fail; [1] = weak det fail; [2] = strong sig fail; + * [3] = cck fail; [4] = power surge; [5] = power drop; + * [6] = btcf timing timeout error; [7] = btcf packet detect error; + * [8] = coarse timing timeout error + * [9-13]=RSVD + */ + u32 rx_ota_err_cnt[HTT_MAX_RX_OTA_ERR_CNT]; +}; + +struct htt_phy_stats_tlv { + /* per chain hw noise floor values in dBm */ + s32 nf_chain[HTT_STATS_MAX_CHAINS]; + /* number of false radars detected */ + u32 false_radar_cnt; + /* number of channel switches happened due to radar detection */ + u32 radar_cs_cnt; + /* ani_level - + * ANI level (noise interference) corresponds to the channel + * the desense levels range from -5 to 15 in dB units, + * higher values indicating more noise interference. + */ + s32 ani_level; + /* running time in minutes since FW boot */ + u32 fw_run_time; +}; + +struct htt_peer_ctrl_path_txrx_stats_tlv { + /* peer mac address */ + u8 peer_mac_addr[ETH_ALEN]; + u8 rsvd[2]; + /* Num of tx mgmt frames with subtype on peer level */ + u32 peer_tx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; + /* Num of rx mgmt frames with subtype on peer level */ + u32 peer_rx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; +}; + #ifdef CONFIG_ATH11K_DEBUGFS void ath11k_debugfs_htt_stats_init(struct ath11k *ar); diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c index 270c0edbb10f..fecd9718f5ce 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c @@ -419,15 +419,21 @@ ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file) struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; struct ath11k *ar = arsta->arvif->ar; struct debug_htt_stats_req *stats_req; + int type = ar->debug.htt_stats.type; int ret; + if ((type != ATH11K_DBG_HTT_EXT_STATS_PEER_INFO && + type != ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) || + type == ATH11K_DBG_HTT_EXT_STATS_RESET) + return -EPERM; + stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE); if (!stats_req) return -ENOMEM; mutex_lock(&ar->conf_mutex); ar->debug.htt_stats.stats_req = stats_req; - stats_req->type = ATH11K_DBG_HTT_EXT_STATS_PEER_INFO; + stats_req->type = type; memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN); ret = ath11k_debugfs_htt_stats_req(ar); mutex_unlock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index b0c8f6290099..8baaeeb8cf82 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -311,7 +311,7 @@ void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab) if (!ab->hw_params.supports_shadow_regs) return; - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + for (i = 0; i < ab->hw_params.max_tx_ring; i++) ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]); ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer); @@ -326,7 +326,7 @@ static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab) ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring); ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring); } @@ -366,7 +366,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) goto err; } - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, HAL_TCL_DATA, i, 0, DP_TCL_DATA_RING_SIZE); @@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, int budget) { struct napi_struct *napi = &irq_grp->napi; + const struct ath11k_hw_hal_params *hal_params; int grp_id = irq_grp->grp_id; int work_done = 0; int i = 0, j; @@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, struct ath11k_pdev_dp *dp = &ar->dp; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + hal_params = ab->hw_params.hal_params; ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); } } } @@ -996,7 +998,7 @@ void ath11k_dp_free(struct ath11k_base *ab) ath11k_dp_reo_cmd_list_cleanup(ab); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { spin_lock_bh(&dp->tx_ring[i].tx_idr_lock); idr_for_each(&dp->tx_ring[i].txbuf_idr, ath11k_dp_tx_pending_cleanup, ab); @@ -1046,7 +1048,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab) size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { idr_init(&dp->tx_ring[i].txbuf_idr); spin_lock_init(&dp->tx_ring[i].tx_idr_lock); dp->tx_ring[i].tcl_data_ring_id = i; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index ee768ccce46e..4794ca04f213 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -170,6 +170,7 @@ struct ath11k_pdev_dp { #define DP_BA_WIN_SZ_MAX 256 #define DP_TCL_NUM_RING_MAX 3 +#define DP_TCL_NUM_RING_MAX_QCA6390 1 #define DP_IDLE_SCATTER_BUFS_MAX 16 @@ -195,6 +196,7 @@ struct ath11k_pdev_dp { #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 #define DP_RX_BUFFER_SIZE 2048 +#define DP_RX_BUFFER_SIZE_LITE 1024 #define DP_RX_BUFFER_ALIGN_SIZE 128 #define DP_RXDMA_BUF_COOKIE_BUF_ID GENMASK(17, 0) @@ -1592,6 +1594,13 @@ struct ath11k_htt_extd_stats_msg { u8 data[0]; } __packed; +#define HTT_MAC_ADDR_L32_0 GENMASK(7, 0) +#define HTT_MAC_ADDR_L32_1 GENMASK(15, 8) +#define HTT_MAC_ADDR_L32_2 GENMASK(23, 16) +#define HTT_MAC_ADDR_L32_3 GENMASK(31, 24) +#define HTT_MAC_ADDR_H16_0 GENMASK(7, 0) +#define HTT_MAC_ADDR_H16_1 GENMASK(15, 8) + struct htt_mac_addr { u32 mac_addr_l32; u32 mac_addr_h16; diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 9a224817630a..c5320847b80a 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -142,6 +142,18 @@ static u32 ath11k_dp_rx_h_attn_mpdu_err(struct rx_attention *attn) return errmap; } +static bool ath11k_dp_rx_h_attn_msdu_len_err(struct ath11k_base *ab, + struct hal_rx_desc *desc) +{ + struct rx_attention *rx_attention; + u32 errmap; + + rx_attention = ath11k_dp_rx_get_attention(ab, desc); + errmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention); + + return errmap & DP_RX_MPDU_ERR_MSDU_LEN; +} + static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab, struct hal_rx_desc *desc) { @@ -270,6 +282,18 @@ static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, __le32_to_cpu(attn->info1))); } +static bool ath11k_dp_rxdesc_mac_addr2_valid(struct ath11k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc); +} + +static u8 *ath11k_dp_rxdesc_mpdu_start_addr2(struct ath11k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); +} + static void ath11k_dp_service_mon_ring(struct timer_list *t) { struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer); @@ -475,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar, rx_ring->bufs_max = num_entries; ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, - HAL_RX_BUF_RBM_SW3_BM); + ar->ab->hw_params.hal_params->rx_buf_rbm); return 0; } @@ -2156,6 +2180,7 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, { u8 *first_hdr; u8 decap; + struct ethhdr *ehdr; first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc); decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); @@ -2170,9 +2195,22 @@ 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); + ehdr = (struct ethhdr *)msdu->data; + + /* mac80211 allows fast path only for authorized STA */ + if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { + ATH11K_SKB_RXCB(msdu)->is_eapol = true; + ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr, + enctype, status); + break; + } + + /* PN for mcast packets will be validated in mac80211; + * remove eth header and add 802.11 header. + */ + if (ATH11K_SKB_RXCB(msdu)->is_mcbc && decrypted) + ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr, + enctype, status); break; case DP_RX_DECAP_TYPE_8023: /* TODO: Handle undecap for these formats */ @@ -2180,35 +2218,62 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, } } +static struct ath11k_peer * +ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu) +{ + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + struct hal_rx_desc *rx_desc = rxcb->rx_desc; + struct ath11k_peer *peer = NULL; + + lockdep_assert_held(&ab->base_lock); + + if (rxcb->peer_id) + peer = ath11k_peer_find_by_id(ab, rxcb->peer_id); + + if (peer) + return peer; + + if (!rx_desc || !(ath11k_dp_rxdesc_mac_addr2_valid(ab, rx_desc))) + return NULL; + + peer = ath11k_peer_find_by_addr(ab, + ath11k_dp_rxdesc_mpdu_start_addr2(ab, rx_desc)); + return peer; +} + static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, struct ieee80211_rx_status *rx_status) { - bool fill_crypto_hdr, mcast; + bool fill_crypto_hdr; enum hal_encrypt_type enctype; bool is_decrypted = false; + struct ath11k_skb_rxcb *rxcb; struct ieee80211_hdr *hdr; struct ath11k_peer *peer; struct rx_attention *rx_attention; u32 err_bitmap; - hdr = (struct ieee80211_hdr *)msdu->data; - /* PN for multicast packets will be checked in mac80211 */ + rxcb = ATH11K_SKB_RXCB(msdu); + fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); + rxcb->is_mcbc = fill_crypto_hdr; - mcast = is_multicast_ether_addr(hdr->addr1); - fill_crypto_hdr = mcast; + if (rxcb->is_mcbc) { + rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc); + rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc); + } spin_lock_bh(&ar->ab->base_lock); - peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2); + peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); if (peer) { - if (mcast) + if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else enctype = peer->sec_type; } else { - enctype = HAL_ENCRYPT_TYPE_OPEN; + enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc); } spin_unlock_bh(&ar->ab->base_lock); @@ -2247,8 +2312,11 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, if (!is_decrypted || fill_crypto_hdr) return; - hdr = (void *)msdu->data; - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + if (ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc) != + DP_RX_DECAP_TYPE_ETHERNET2_DIX) { + 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, @@ -2337,8 +2405,10 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, channel_num = meta_data; center_freq = meta_data >> 16; - if (center_freq >= 5935 && center_freq <= 7105) { + if (center_freq >= ATH11K_MIN_6G_FREQ && + center_freq <= ATH11K_MAX_6G_FREQ) { rx_status->band = NL80211_BAND_6GHZ; + rx_status->freq = center_freq; } else if (channel_num >= 1 && channel_num <= 14) { rx_status->band = NL80211_BAND_2GHZ; } else if (channel_num >= 36 && channel_num <= 173) { @@ -2356,57 +2426,56 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, rx_desc, sizeof(struct hal_rx_desc)); } - rx_status->freq = ieee80211_channel_to_frequency(channel_num, - rx_status->band); + if (rx_status->band != NL80211_BAND_6GHZ) + rx_status->freq = ieee80211_channel_to_frequency(channel_num, + rx_status->band); ath11k_dp_rx_h_rate(ar, rx_desc, rx_status); } -static char *ath11k_print_get_tid(struct ieee80211_hdr *hdr, char *out, - size_t size) -{ - u8 *qc; - int tid; - - if (!ieee80211_is_data_qos(hdr->frame_control)) - return ""; - - qc = ieee80211_get_qos_ctl(hdr); - tid = *qc & IEEE80211_QOS_CTL_TID_MASK; - snprintf(out, size, "tid %d", tid); - - return out; -} - static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *napi, - struct sk_buff *msdu) + struct sk_buff *msdu, + struct ieee80211_rx_status *status) { static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), }; - struct ieee80211_rx_status *status; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; + struct ieee80211_rx_status *rx_status; struct ieee80211_radiotap_he *he = NULL; - char tid[32]; + struct ieee80211_sta *pubsta = NULL; + struct ath11k_peer *peer; + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + u8 decap = DP_RX_DECAP_TYPE_RAW; + bool is_mcbc = rxcb->is_mcbc; + bool is_eapol = rxcb->is_eapol; - status = IEEE80211_SKB_RXCB(msdu); - if (status->encoding == RX_ENC_HE) { + if (status->encoding == RX_ENC_HE && + !(status->flag & RX_FLAG_RADIOTAP_HE) && + !(status->flag & RX_FLAG_SKIP_MONITOR)) { he = skb_push(msdu, sizeof(known)); memcpy(he, &known, sizeof(known)); status->flag |= RX_FLAG_RADIOTAP_HE; } + if (!(status->flag & RX_FLAG_ONLY_MONITOR)) + decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rxcb->rx_desc); + + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); + if (peer && peer->sta) + pubsta = peer->sta; + spin_unlock_bh(&ar->ab->base_lock); + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, - "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", + "rx skb %pK len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, - ieee80211_get_SA(hdr), - ath11k_print_get_tid(hdr, tid, sizeof(tid)), - is_multicast_ether_addr(ieee80211_get_DA(hdr)) ? - "mcast" : "ucast", - (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4, + peer ? peer->addr : NULL, + rxcb->tid, + is_mcbc ? "mcast" : "ucast", + rxcb->seq_no, (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", (status->encoding == RX_ENC_HT) ? "ht" : "", (status->encoding == RX_ENC_VHT) ? "vht" : "", @@ -2426,22 +2495,32 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ", msdu->data, msdu->len); + rx_status = IEEE80211_SKB_RXCB(msdu); + *rx_status = *status; + /* TODO: trace rx packet */ - ieee80211_rx_napi(ar->hw, NULL, msdu, napi); + /* PN for multicast packets are not validate in HW, + * so skip 802.3 rx path + * Also, fast_rx expectes the STA to be authorized, hence + * eapol packets are sent in slow path. + */ + if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol && + !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) + rx_status->flag |= RX_FLAG_8023; + + ieee80211_rx_napi(ar->hw, pubsta, msdu, napi); } static int ath11k_dp_rx_process_msdu(struct ath11k *ar, struct sk_buff *msdu, - struct sk_buff_head *msdu_list) + struct sk_buff_head *msdu_list, + struct ieee80211_rx_status *rx_status) { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; struct rx_attention *rx_attention; - 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; u8 *hdr_status; @@ -2458,6 +2537,12 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar, } rx_desc = (struct hal_rx_desc *)msdu->data; + if (ath11k_dp_rx_h_attn_msdu_len_err(ab, rx_desc)) { + ath11k_warn(ar->ab, "msdu len not valid\n"); + ret = -EIO; + goto free_out; + } + lrx_desc = (struct hal_rx_desc *)last_buf->data; rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc); if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) { @@ -2497,19 +2582,11 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar, } } - 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); + 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; + rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; - status = IEEE80211_SKB_RXCB(msdu); - *status = rx_status; return 0; free_out: @@ -2524,6 +2601,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab, struct ath11k_skb_rxcb *rxcb; struct sk_buff *msdu; struct ath11k *ar; + struct ieee80211_rx_status rx_status = {0}; u8 mac_id; int ret; @@ -2546,7 +2624,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab, continue; } - ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list); + ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status); if (ret) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); @@ -2554,7 +2632,7 @@ static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab, continue; } - ath11k_dp_rx_deliver_msdu(ar, napi, msdu); + ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); (*quota)--; } @@ -2636,10 +2714,14 @@ try_again: RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); rxcb->is_continuation = !!(desc.rx_msdu_info.info0 & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); - rxcb->mac_id = mac_id; + rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID, + desc.rx_mpdu_info.meta_data); + rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM, + desc.rx_mpdu_info.info0); rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM, desc.info0); + rxcb->mac_id = mac_id; __skb_queue_tail(&msdu_list, msdu); if (total_msdu_reaped >= quota && !rxcb->is_continuation) { @@ -2674,7 +2756,7 @@ try_again: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list, @@ -2867,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, int *budget, struct sk_buff_head *skb_list) { struct ath11k *ar; + const struct ath11k_hw_hal_params *hal_params; struct ath11k_pdev_dp *dp; struct dp_rxdma_ring *rx_ring; struct hal_srng *srng; @@ -2937,8 +3020,9 @@ move_next: &buf_id); if (!skb) { + hal_params = ab->hw_params.hal_params; ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -2948,7 +3032,8 @@ move_next: FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, HAL_RX_BUF_RBM_SW3_BM); + cookie, + ab->hw_params.hal_params->rx_buf_rbm); ath11k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -2969,6 +3054,8 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct ath11k_peer *peer; struct ath11k_sta *arsta; int num_buffs_reaped = 0; + u32 rx_buf_sz; + u16 log_type = 0; __skb_queue_head_init(&skb_list); @@ -2981,8 +3068,16 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, memset(&ppdu_info, 0, sizeof(ppdu_info)); ppdu_info.peer_id = HAL_INVALID_PEERID; - if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) - trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE); + if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) { + log_type = ATH11K_PKTLOG_TYPE_LITE_RX; + rx_buf_sz = DP_RX_BUFFER_SIZE_LITE; + } else if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) { + log_type = ATH11K_PKTLOG_TYPE_RX_STATBUF; + rx_buf_sz = DP_RX_BUFFER_SIZE; + } + + if (log_type) + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); hal_status = ath11k_hal_rx_parse_mon_status(ab, &ppdu_info, skb); @@ -3010,7 +3105,7 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, ath11k_dp_rx_update_peer_stats(arsta, &ppdu_info); if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) - trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE); + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); @@ -3310,7 +3405,7 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti paddr = dma_map_single(ab->dev, defrag_skb->data, defrag_skb->len + skb_tailroom(defrag_skb), - DMA_FROM_DEVICE); + DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, paddr)) return -ENOMEM; @@ -3327,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti 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); + ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, + ab->hw_params.hal_params->rx_buf_rbm); /* Fill mpdu details into reo entrace ring */ srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id]; @@ -3375,7 +3471,7 @@ err_free_idr: 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); + DMA_TO_DEVICE); return ret; } @@ -3704,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, &rbm); if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && - rbm != HAL_RX_BUF_RBM_SW3_BM) { + rbm != ab->hw_params.hal_params->rx_buf_rbm) { ab->soc_stats.invalid_rbm++; ath11k_warn(ab, "invalid return buffer manager %d\n", rbm); ath11k_dp_rx_link_desc_return(ab, desc, @@ -3760,7 +3856,7 @@ exit: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } return tot_n_bufs_reaped; @@ -3941,7 +4037,6 @@ static void ath11k_dp_rx_wbm_err(struct ath11k *ar, { struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); struct ieee80211_rx_status rxs = {0}; - struct ieee80211_rx_status *status; bool drop = true; switch (rxcb->err_rel_src) { @@ -3961,10 +4056,7 @@ static void ath11k_dp_rx_wbm_err(struct ath11k *ar, return; } - status = IEEE80211_SKB_RXCB(msdu); - *status = rxs; - - ath11k_dp_rx_deliver_msdu(ar, napi, msdu); + ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs); } int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, @@ -4060,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } rcu_read_lock(); @@ -4169,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget) if (num_buf_freed) ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed, - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); return budget - quota; } @@ -4740,7 +4832,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar, struct ieee80211_rx_status *rxs) { struct ath11k_base *ab = ar->ab; - struct sk_buff *msdu, *mpdu_buf, *prev_buf; + struct sk_buff *msdu, *prev_buf; u32 wifi_hdr_len; struct hal_rx_desc *rx_desc; char *hdr_desc; @@ -4748,8 +4840,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar, struct ieee80211_hdr_3addr *wh; struct rx_attention *rx_attention; - mpdu_buf = NULL; - if (!head_msdu) goto err_merge_fail; @@ -4832,12 +4922,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar, return head_msdu; err_merge_fail: - if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) { - ath11k_dbg(ab, ATH11K_DBG_DATA, - "err_merge_fail mpdu_buf %pK", mpdu_buf); - /* Free the head buffer */ - dev_kfree_skb_any(mpdu_buf); - } return NULL; } @@ -4848,7 +4932,7 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id, { struct ath11k_pdev_dp *dp = &ar->dp; struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp->rx_status, *status; + struct ieee80211_rx_status *rxs = &dp->rx_status; mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu, tail_msdu, rxs); @@ -4874,10 +4958,7 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id, } rxs->flag |= RX_FLAG_ONLY_MONITOR; - status = IEEE80211_SKB_RXCB(mon_skb); - *status = *rxs; - - ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb); + ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs); mon_skb = skb_next; } while (mon_skb); rxs->flag = 0; @@ -4899,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, { struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; + const struct ath11k_hw_hal_params *hal_params; void *ring_entry; void *mon_dst_srng; u32 ppdu_id; @@ -4962,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, if (rx_bufs_used) { rx_mon_stats->dest_ppdu_done++; + hal_params = ar->ab->hw_params.hal_params; + if (ar->ab->hw_params.rxdma1_enable) ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rxdma_mon_buf_ring, rx_bufs_used, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); else ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rx_refill_buf_ring, rx_bufs_used, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); } } @@ -5029,7 +5113,7 @@ int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id); int ret = 0; - if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) + if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) ret = ath11k_dp_mon_process_rx(ab, mac_id, napi, budget); else ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget); diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 8bba5234f81f..879fb2a9dc0c 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) } int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct sk_buff *skb) + struct ath11k_sta *arsta, struct sk_buff *skb) { struct ath11k_base *ab = ar->ab; struct ath11k_dp *dp = &ab->dp; @@ -115,11 +115,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, tcl_ring_sel: tcl_ring_retry = false; - /* For some chip, it can only use tcl0 to tx */ - if (ar->ab->hw_params.tcl_0_only) - ti.ring_id = 0; - else - ti.ring_id = ring_selector % DP_TCL_NUM_RING_MAX; + + ti.ring_id = ring_selector % ab->hw_params.max_tx_ring; ring_map |= BIT(ti.ring_id); @@ -131,7 +128,7 @@ tcl_ring_sel: spin_unlock_bh(&tx_ring->tx_idr_lock); if (ret < 0) { - if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) { + if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1)) { atomic_inc(&ab->soc_stats.tx_err.misc_fail); return -ENOSPC; } @@ -145,7 +142,15 @@ tcl_ring_sel: FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) | FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id); ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); - ti.meta_data_flags = arvif->tcl_metadata; + + if (ieee80211_has_a4(hdr->frame_control) && + is_multicast_ether_addr(hdr->addr3) && arsta && + arsta->use_4addr_set) { + ti.meta_data_flags = arsta->tcl_metadata; + ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); + } else { + ti.meta_data_flags = arvif->tcl_metadata; + } if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) { if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) { @@ -240,8 +245,8 @@ tcl_ring_sel: * checking this ring earlier for each pkt tx. * Restart ring selection if some rings are not checked yet. */ - if (ring_map != (BIT(DP_TCL_NUM_RING_MAX) - 1) && - !ar->ab->hw_params.tcl_0_only) { + if (ring_map != (BIT(ab->hw_params.max_tx_ring) - 1) && + ab->hw_params.max_tx_ring > 1) { tcl_ring_retry = true; ring_selector++; } @@ -614,6 +619,9 @@ int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, struct hal_srng *cmd_ring; int cmd_num; + if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) + return -ESHUTDOWN; + cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; cmd_num = ath11k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); @@ -1068,12 +1076,16 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset) for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; - if (!reset) + if (!reset) { tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; - else + } else { tlv_filter = ath11k_mac_mon_status_filter_default; + if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } + ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id, dp->mac_id + i, HAL_RXDMA_MONITOR_STATUS, diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h index f8a9f9c8e444..698b907b878d 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.h +++ b/drivers/net/wireless/ath/ath11k/dp_tx.h @@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status { int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct sk_buff *skb); + struct ath11k_sta *arsta, struct sk_buff *skb); void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id); int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, enum hal_reo_cmd_type type, diff --git a/drivers/net/wireless/ath/ath11k/hal_desc.h b/drivers/net/wireless/ath/ath11k/hal_desc.h index d54ec6aa6281..00b595b84939 100644 --- a/drivers/net/wireless/ath/ath11k/hal_desc.h +++ b/drivers/net/wireless/ath/ath11k/hal_desc.h @@ -496,6 +496,8 @@ struct hal_tlv_hdr { #define RX_MPDU_DESC_INFO0_DA_IDX_TIMEOUT BIT(29) #define RX_MPDU_DESC_INFO0_RAW_MPDU BIT(30) +#define RX_MPDU_DESC_META_DATA_PEER_ID GENMASK(15, 0) + struct rx_mpdu_desc { u32 info0; /* %RX_MPDU_DESC_INFO */ u32 meta_data; diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 325055ca41ab..329c404cfa80 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, struct hal_wbm_release_ring *wbm_desc = desc; enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; + enum hal_rx_buf_return_buf_manager ret_buf_mgr; type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, wbm_desc->info0); @@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, rel_src != HAL_WBM_REL_SRC_MODULE_REO) return -EINVAL; - if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, - wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { + ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, + wbm_desc->buf_addr_info.info1); + if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) { ab->soc_stats.invalid_rbm++; return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index d9596903b0a5..da35fcf5bc56 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -7,10 +7,11 @@ #include <linux/bitops.h> #include <linux/bitfield.h> -#include "hw.h" #include "core.h" #include "ce.h" #include "hif.h" +#include "hal.h" +#include "hw.h" /* Map from pdev index to hw mac index */ static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx) @@ -97,6 +98,7 @@ static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab, config->num_multicast_filter_entries = 0x20; config->num_wow_filters = 0x16; config->num_keep_alive_pattern = 0; + config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; } static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) @@ -197,6 +199,7 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab, config->peer_map_unmap_v2_support = 1; config->twt_ap_pdev_count = ab->num_radios; config->twt_ap_sta_count = 1000; + config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; } static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw, @@ -372,6 +375,17 @@ static void ath11k_hw_ipq8074_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); } +static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; +} + +static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.ipq8074.mpdu_start.addr2; +} + static struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) { @@ -543,6 +557,17 @@ static u8 *ath11k_hw_qcn9074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) return &desc->u.qcn9074.msdu_payload[0]; } +static bool ath11k_hw_ipq9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & + RX_MPDU_START_INFO11_MAC_ADDR2_VALID; +} + +static u8 *ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.qcn9074.mpdu_start.addr2; +} + static bool ath11k_hw_wcn6855_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU_WCN6855, @@ -703,6 +728,17 @@ static u8 *ath11k_hw_wcn6855_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) return &desc->u.wcn6855.msdu_payload[0]; } +static bool ath11k_hw_wcn6855_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn6855.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; +} + +static u8 *ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.wcn6855.mpdu_start.addr2; +} + static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab) { u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; @@ -799,6 +835,8 @@ const struct ath11k_hw_ops ipq8074_ops = { .rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_ipq8074_reo_setup, .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, }; const struct ath11k_hw_ops ipq6018_ops = { @@ -835,6 +873,8 @@ const struct ath11k_hw_ops ipq6018_ops = { .rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_ipq8074_reo_setup, .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, }; const struct ath11k_hw_ops qca6390_ops = { @@ -871,6 +911,8 @@ const struct ath11k_hw_ops qca6390_ops = { .rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_ipq8074_reo_setup, .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, }; const struct ath11k_hw_ops qcn9074_ops = { @@ -907,6 +949,8 @@ const struct ath11k_hw_ops qcn9074_ops = { .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_ipq8074_reo_setup, .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, }; const struct ath11k_hw_ops wcn6855_ops = { @@ -943,6 +987,8 @@ const struct ath11k_hw_ops wcn6855_ops = { .rx_desc_get_msdu_payload = ath11k_hw_wcn6855_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_wcn6855_reo_setup, .mpdu_info_get_peerid = ath11k_hw_wcn6855_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_wcn6855_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, }; #define ATH11K_TX_RING_MASK_0 0x1 @@ -2079,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = { .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_pcs_osc_dtct_config_base = 0x01e0c628, }; + +const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, +}; + +const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, +}; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 62f5978b3005..19223d36846e 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -6,6 +6,7 @@ #ifndef ATH11K_HW_H #define ATH11K_HW_H +#include "hal.h" #include "wmi.h" /* Target configuration defines */ @@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask { u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX]; }; +struct ath11k_hw_hal_params { + enum hal_rx_buf_return_buf_manager rx_buf_rbm; +}; + struct ath11k_hw_params { const char *name; u16 hw_rev; @@ -128,7 +133,7 @@ struct ath11k_hw_params { struct { const char *dir; size_t board_size; - size_t cal_size; + size_t cal_offset; } fw; const struct ath11k_hw_ops *hw_ops; @@ -152,8 +157,14 @@ struct ath11k_hw_params { bool rx_mac_buf_ring; bool vdev_start_delay; bool htt_peer_map_v2; - bool tcl_0_only; - u8 spectral_fft_sz; + + struct { + u8 fft_sz; + u8 fft_pad_sz; + u8 summary_pad_sz; + u8 fft_hdr_len; + u16 max_fft_bins; + } spectral; u16 interface_modes; bool supports_monitor; @@ -163,6 +174,8 @@ struct ath11k_hw_params { bool supports_suspend; u32 hal_desc_sz; bool fix_l1ss; + u8 max_tx_ring; + const struct ath11k_hw_hal_params *hal_params; }; struct ath11k_hw_ops { @@ -202,6 +215,8 @@ struct ath11k_hw_ops { u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); void (*reo_setup)(struct ath11k_base *ab); u16 (*mpdu_info_get_peerid)(u8 *tlv_data); + bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); + u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); }; extern const struct ath11k_hw_ops ipq8074_ops; @@ -214,6 +229,9 @@ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; +extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; +extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; + static inline int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw, int pdev_idx) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e9b3689331ec..1cc55602787b 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -150,6 +150,9 @@ static const struct ieee80211_channel ath11k_6ghz_channels[] = { CHAN6G(225, 7075, 0), CHAN6G(229, 7095, 0), CHAN6G(233, 7115, 0), + + /* new addition in IEEE Std 802.11ax-2021 */ + CHAN6G(2, 5935, 0), }; static struct ieee80211_rate ath11k_legacy_rates[] = { @@ -354,6 +357,18 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) return 1; } +static u32 +ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) +{ + int nss; + + for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--) + if (he_mcs_mask[nss]) + return nss + 1; + + return 1; +} + static u8 ath11k_parse_mpdudensity(u8 mpdudensity) { /* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": @@ -488,7 +503,8 @@ struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, for (i = 0; i < ab->num_radios; i++) { pdev = rcu_dereference(ab->pdevs_active[i]); - if (pdev && pdev->ar) { + if (pdev && pdev->ar && + (pdev->ar->allocated_vdev_map & (1LL << vdev_id))) { arvif = ath11k_mac_get_arvif(pdev->ar, vdev_id); if (arvif) return arvif; @@ -715,32 +731,386 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar) ar->num_stations = 0; } -static int ath11k_monitor_vdev_up(struct ath11k *ar, int vdev_id) +static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar) { - int ret = 0; + lockdep_assert_held(&ar->conf_mutex); + + if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + return -ESHUTDOWN; + + if (!wait_for_completion_timeout(&ar->vdev_setup_done, + ATH11K_VDEV_SETUP_TIMEOUT_HZ)) + return -ETIMEDOUT; + + return ar->last_wmi_vdev_start_status ? -EINVAL : 0; +} + +static void +ath11k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf, + void *data) +{ + struct cfg80211_chan_def **def = data; + + *def = &conf->def; +} + +static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id, + struct cfg80211_chan_def *chandef) +{ + struct ieee80211_channel *channel; + struct wmi_vdev_start_req_arg arg = {}; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + channel = chandef->chan; + + arg.vdev_id = vdev_id; + arg.channel.freq = channel->center_freq; + arg.channel.band_center_freq1 = chandef->center_freq1; + arg.channel.band_center_freq2 = chandef->center_freq2; + + arg.channel.mode = ath11k_phymodes[chandef->chan->band][chandef->width]; + arg.channel.chan_radar = !!(channel->flags & IEEE80211_CHAN_RADAR); + + arg.channel.min_power = 0; + arg.channel.max_power = channel->max_power * 2; + arg.channel.max_reg_power = channel->max_reg_power * 2; + arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; + + arg.pref_tx_streams = ar->num_tx_chains; + arg.pref_rx_streams = ar->num_rx_chains; + + arg.channel.passive = !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); + + reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); + + ret = ath11k_wmi_vdev_start(ar, &arg, false); + if (ret) { + ath11k_warn(ar->ab, "failed to request monitor vdev %i start: %d\n", + vdev_id, ret); + return ret; + } + + ret = ath11k_mac_vdev_setup_sync(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to synchronize setup for monitor vdev %i start: %d\n", + vdev_id, ret); + return ret; + } ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); if (ret) { ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n", vdev_id, ret); - return ret; + goto vdev_stop; } ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %i started\n", vdev_id); + return 0; + +vdev_stop: + reinit_completion(&ar->vdev_setup_done); + + ret = ath11k_wmi_vdev_stop(ar, vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to stop monitor vdev %i after start failure: %d\n", + vdev_id, ret); + return ret; + } + + ret = ath11k_mac_vdev_setup_sync(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to synchronize setup for vdev %i stop: %d\n", + vdev_id, ret); + return ret; + } + + return -EIO; } -static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed) +static int ath11k_mac_monitor_vdev_stop(struct ath11k *ar) { - /* mac80211 requires this op to be present and that's why - * there's an empty function, this can be extended when - * required. - */ + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->vdev_setup_done); + + ret = ath11k_wmi_vdev_stop(ar, ar->monitor_vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to request monitor vdev %i stop: %d\n", + ar->monitor_vdev_id, ret); + return ret; + } + + ret = ath11k_mac_vdev_setup_sync(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to synchronize monitor vdev %i stop: %d\n", + ar->monitor_vdev_id, ret); + return ret; + } + + ret = ath11k_wmi_vdev_down(ar, ar->monitor_vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to put down monitor vdev %i: %d\n", + ar->monitor_vdev_id, ret); + return ret; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %i stopped\n", + ar->monitor_vdev_id); + + return 0; +} + +static int ath11k_mac_monitor_vdev_create(struct ath11k *ar) +{ + struct ath11k_pdev *pdev = ar->pdev; + struct vdev_create_params param = {}; + int bit, ret; + u8 tmp_addr[6] = {0}; + u16 nss; + + lockdep_assert_held(&ar->conf_mutex); + + if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) + return 0; + + if (ar->ab->free_vdev_map == 0) { + ath11k_warn(ar->ab, "failed to find free vdev id for monitor vdev\n"); + return -ENOMEM; + } + + bit = __ffs64(ar->ab->free_vdev_map); + + ar->monitor_vdev_id = bit; + + param.if_id = ar->monitor_vdev_id; + param.type = WMI_VDEV_TYPE_MONITOR; + param.subtype = WMI_VDEV_SUBTYPE_NONE; + param.pdev_id = pdev->pdev_id; + + if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { + param.chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; + param.chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains; + } + if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) { + param.chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains; + param.chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains; + } + + ret = ath11k_wmi_vdev_create(ar, tmp_addr, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to request monitor vdev %i creation: %d\n", + ar->monitor_vdev_id, ret); + ar->monitor_vdev_id = -1; + return ret; + } + + nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1; + ret = ath11k_wmi_vdev_set_param_cmd(ar, ar->monitor_vdev_id, + WMI_VDEV_PARAM_NSS, nss); + if (ret) { + ath11k_warn(ar->ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n", + ar->monitor_vdev_id, ar->cfg_tx_chainmask, nss, ret); + goto err_vdev_del; + } + + ret = ath11k_mac_txpower_recalc(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to recalc txpower for monitor vdev %d: %d\n", + ar->monitor_vdev_id, ret); + goto err_vdev_del; + } + + ar->allocated_vdev_map |= 1LL << ar->monitor_vdev_id; + ar->ab->free_vdev_map &= ~(1LL << ar->monitor_vdev_id); + ar->num_created_vdevs++; + set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %d created\n", + ar->monitor_vdev_id); + + return 0; + +err_vdev_del: + ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id); + ar->monitor_vdev_id = -1; + return ret; +} + +static int ath11k_mac_monitor_vdev_delete(struct ath11k *ar) +{ + int ret; + unsigned long time_left; + + lockdep_assert_held(&ar->conf_mutex); + + if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) + return 0; + + reinit_completion(&ar->vdev_delete_done); + + ret = ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to request wmi monitor vdev %i removal: %d\n", + ar->monitor_vdev_id, ret); + return ret; + } + + time_left = wait_for_completion_timeout(&ar->vdev_delete_done, + ATH11K_VDEV_DELETE_TIMEOUT_HZ); + if (time_left == 0) { + ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n"); + } else { + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %d deleted\n", + ar->monitor_vdev_id); + + ar->allocated_vdev_map &= ~(1LL << ar->monitor_vdev_id); + ar->ab->free_vdev_map |= 1LL << (ar->monitor_vdev_id); + ar->num_created_vdevs--; + ar->monitor_vdev_id = -1; + clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); + } + + return ret; +} + +static int ath11k_mac_monitor_start(struct ath11k *ar) +{ + struct cfg80211_chan_def *chandef = NULL; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) + return 0; + + ieee80211_iter_chan_contexts_atomic(ar->hw, + ath11k_mac_get_any_chandef_iter, + &chandef); + if (!chandef) + return 0; + + ret = ath11k_mac_monitor_vdev_start(ar, ar->monitor_vdev_id, chandef); + if (ret) { + ath11k_warn(ar->ab, "failed to start monitor vdev: %d\n", ret); + ath11k_mac_monitor_vdev_delete(ar); + return ret; + } + + set_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); + + ar->num_started_vdevs++; + ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, false); + if (ret) { + ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during start: %d", + ret); + return ret; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor started\n"); return 0; } +static int ath11k_mac_monitor_stop(struct ath11k *ar) +{ + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + if (!test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) + return 0; + + ret = ath11k_mac_monitor_vdev_stop(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to stop monitor vdev: %d\n", ret); + return ret; + } + + clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); + ar->num_started_vdevs--; + + ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, true); + if (ret) { + ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during stop: %d", + ret); + return ret; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor stopped ret %d\n", ret); + + return 0; +} + +static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ath11k *ar = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + int ret = 0; + + mutex_lock(&ar->conf_mutex); + + if (changed & IEEE80211_CONF_CHANGE_MONITOR) { + if (conf->flags & IEEE80211_CONF_MONITOR) { + set_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags); + + if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, + &ar->monitor_flags)) + goto out; + + ret = ath11k_mac_monitor_vdev_create(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to create monitor vdev: %d", + ret); + goto out; + } + + ret = ath11k_mac_monitor_start(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to start monitor: %d", + ret); + goto err_mon_del; + } + } else { + clear_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags); + + if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, + &ar->monitor_flags)) + goto out; + + ret = ath11k_mac_monitor_stop(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to stop monitor: %d", + ret); + goto out; + } + + ret = ath11k_mac_monitor_vdev_delete(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to delete monitor vdev: %d", + ret); + goto out; + } + } + } + +out: + mutex_unlock(&ar->conf_mutex); + return ret; + +err_mon_del: + ath11k_mac_monitor_vdev_delete(ar); + mutex_unlock(&ar->conf_mutex); + return ret; +} + static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) { struct ath11k *ar = arvif->ar; @@ -1035,7 +1405,7 @@ ath11k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) } static bool -ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) +ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[]) { int nss; @@ -1093,6 +1463,14 @@ static void ath11k_peer_assoc_h_ht(struct ath11k *ar, arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG; } + /* As firmware handles this two flags (IEEE80211_HT_CAP_SGI_20 + * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, we reset + * both flags if guard interval is Default GI + */ + if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI) + arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) { if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) @@ -1207,6 +1585,34 @@ ath11k_peer_assoc_h_vht_limit(u16 tx_mcs_set, return tx_mcs_set; } +static u8 ath11k_get_nss_160mhz(struct ath11k *ar, + u8 max_nss) +{ + u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info; + u8 max_sup_nss = 0; + + switch (nss_ratio_info) { + case WMI_NSS_RATIO_1BY2_NSS: + max_sup_nss = max_nss >> 1; + break; + case WMI_NSS_RATIO_3BY4_NSS: + ath11k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n"); + break; + case WMI_NSS_RATIO_1_NSS: + max_sup_nss = max_nss; + break; + case WMI_NSS_RATIO_2_NSS: + ath11k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n"); + break; + default: + ath11k_warn(ar->ab, "invalid nss ratio received from firmware: %d\n", + nss_ratio_info); + break; + } + + return max_sup_nss; +} + static void ath11k_peer_assoc_h_vht(struct ath11k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -1216,10 +1622,12 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, struct ath11k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; enum nl80211_band band; - const u16 *vht_mcs_mask; + u16 *vht_mcs_mask; u8 ampdu_factor; u8 max_nss, vht_mcs; - int i; + int i, vht_nss, nss_idx; + bool user_rate_valid = true; + u32 rx_nss, tx_nss, nss_160; if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) return; @@ -1262,6 +1670,24 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, if (sta->bandwidth == IEEE80211_STA_RX_BW_160) arg->bw_160 = true; + vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask); + + if (vht_nss > sta->rx_nss) { + user_rate_valid = false; + for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { + if (vht_mcs_mask[nss_idx]) { + user_rate_valid = true; + break; + } + } + } + + if (!user_rate_valid) { + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac setting vht range mcs value to peer supported nss %d for peer %pM\n", + sta->rx_nss, sta->addr); + vht_mcs_mask[sta->rx_nss - 1] = vht_mcs_mask[vht_nss - 1]; + } + /* Calculate peer NSS capability from VHT capabilities if STA * supports VHT. */ @@ -1294,10 +1720,95 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, /* TODO: Check */ arg->tx_max_mcs_nss = 0xFF; - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", - sta->addr, arg->peer_max_mpdu, arg->peer_flags); + if (arg->peer_phymode == MODE_11AC_VHT160 || + arg->peer_phymode == MODE_11AC_VHT80_80) { + tx_nss = ath11k_get_nss_160mhz(ar, max_nss); + rx_nss = min(arg->peer_nss, tx_nss); + arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE; + + if (!rx_nss) { + ath11k_warn(ar->ab, "invalid max_nss\n"); + return; + } + + if (arg->peer_phymode == MODE_11AC_VHT160) + nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1); + else + nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1); + + arg->peer_bw_rxnss_override |= nss_160; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n", + sta->addr, arg->peer_max_mpdu, arg->peer_flags, + arg->peer_bw_rxnss_override); +} + +static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss) +{ + switch ((mcs_map >> (2 * nss)) & 0x3) { + case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1; + case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1; + case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1; + } + return 0; +} + +static u16 ath11k_peer_assoc_h_he_limit(u16 tx_mcs_set, + const u16 he_mcs_limit[NL80211_HE_NSS_MAX]) +{ + int idx_limit; + int nss; + u16 mcs_map; + u16 mcs; + + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) { + mcs_map = ath11k_mac_get_max_he_mcs_map(tx_mcs_set, nss) & + he_mcs_limit[nss]; + + if (mcs_map) + idx_limit = fls(mcs_map) - 1; + else + idx_limit = -1; + + switch (idx_limit) { + case 0 ... 7: + mcs = IEEE80211_HE_MCS_SUPPORT_0_7; + break; + case 8: + case 9: + mcs = IEEE80211_HE_MCS_SUPPORT_0_9; + break; + case 10: + case 11: + mcs = IEEE80211_HE_MCS_SUPPORT_0_11; + break; + default: + WARN_ON(1); + fallthrough; + case -1: + mcs = IEEE80211_HE_MCS_NOT_SUPPORTED; + break; + } - /* TODO: rxnss_override */ + tx_mcs_set &= ~(0x3 << (nss * 2)); + tx_mcs_set |= mcs << (nss * 2); + } + + return tx_mcs_set; +} + +static bool +ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) +{ + int nss; + + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) + if (he_mcs_mask[nss]) + return false; + + return true; } static void ath11k_peer_assoc_h_he(struct ath11k *ar, @@ -1305,13 +1816,30 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, struct ieee80211_sta *sta, struct peer_assoc_params *arg) { + struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct cfg80211_chan_def def; const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; u8 ampdu_factor; - u16 v; + enum nl80211_band band; + u16 *he_mcs_mask; + u8 max_nss, he_mcs; + u16 he_tx_mcs = 0, v = 0; + int i, he_nss, nss_idx; + bool user_rate_valid = true; + u32 rx_nss, tx_nss, nss_160; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) + return; if (!he_cap->has_he) return; + band = def.chan->band; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; + + if (ath11k_peer_assoc_h_he_masked(he_mcs_mask)) + return; + arg->he_flag = true; memcpy_and_pad(&arg->peer_he_cap_macinfo, @@ -1388,25 +1916,48 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ) arg->twt_requester = true; + he_nss = ath11k_mac_max_he_nss(he_mcs_mask); + + if (he_nss > sta->rx_nss) { + user_rate_valid = false; + for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { + if (he_mcs_mask[nss_idx]) { + user_rate_valid = true; + break; + } + } + } + + if (!user_rate_valid) { + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac setting he range mcs value to peer supported nss %d for peer %pM\n", + sta->rx_nss, sta->addr); + he_mcs_mask[sta->rx_nss - 1] = he_mcs_mask[he_nss - 1]; + } + switch (sta->bandwidth) { case IEEE80211_STA_RX_BW_160: if (he_cap->he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80); + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; arg->peer_he_mcs_count++; + he_tx_mcs = v; } v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; arg->peer_he_mcs_count++; + if (!he_tx_mcs) + he_tx_mcs = v; fallthrough; default: @@ -1414,11 +1965,102 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; arg->peer_he_mcs_count++; + if (!he_tx_mcs) + he_tx_mcs = v; break; } + + /* Calculate peer NSS capability from HE capabilities if STA + * supports HE. + */ + for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) { + he_mcs = he_tx_mcs >> (2 * i) & 3; + + /* In case of fixed rates, MCS Range in he_tx_mcs might have + * unsupported range, with he_mcs_mask set, so check either of them + * to find nss. + */ + if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED || + he_mcs_mask[i]) + max_nss = i + 1; + } + arg->peer_nss = min(sta->rx_nss, max_nss); + + if (arg->peer_phymode == MODE_11AX_HE160 || + arg->peer_phymode == MODE_11AX_HE80_80) { + tx_nss = ath11k_get_nss_160mhz(ar, max_nss); + rx_nss = min(arg->peer_nss, tx_nss); + arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE; + + if (!rx_nss) { + ath11k_warn(ar->ab, "invalid max_nss\n"); + return; + } + + if (arg->peer_phymode == MODE_11AX_HE160) + nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1); + else + nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1); + + arg->peer_bw_rxnss_override |= nss_160; + } + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n", + sta->addr, arg->peer_nss, + arg->peer_he_mcs_count, + arg->peer_bw_rxnss_override); +} + +static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct peer_assoc_params *arg) +{ + const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + struct cfg80211_chan_def def; + enum nl80211_band band; + u8 ampdu_factor; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) + return; + + band = def.chan->band; + + if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->he_6ghz_capa.capa) + return; + + if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + arg->bw_80 = true; + + if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + arg->bw_160 = true; + + arg->peer_he_caps_6ghz = le16_to_cpu(sta->he_6ghz_capa.capa); + arg->peer_mpdu_density = + ath11k_parse_mpdudensity(FIELD_GET(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, + arg->peer_he_caps_6ghz)); + + /* From IEEE Std 802.11ax-2021 - Section 10.12.2: An HE STA shall be capable of + * receiving A-MPDU where the A-MPDU pre-EOF padding length is up to the value + * indicated by the Maximum A-MPDU Length Exponent Extension field in the HE + * Capabilities element and the Maximum A-MPDU Length Exponent field in HE 6 GHz + * Band Capabilities element in the 6 GHz band. + * + * Here, we are extracting the Max A-MPDU Exponent Extension from HE caps and + * factor is the Maximum A-MPDU Length Exponent from HE 6 GHZ Band capability. + */ + ampdu_factor = FIELD_GET(IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK, + he_cap->he_cap_elem.mac_cap_info[3]) + + FIELD_GET(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, + arg->peer_he_caps_6ghz); + + arg->peer_max_mpdu = (1u << (IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR + + ampdu_factor)) - 1; } static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta, @@ -1427,11 +2069,16 @@ static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta, const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; int smps; - if (!ht_cap->ht_supported) + if (!ht_cap->ht_supported && !sta->he_6ghz_capa.capa) return; - smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; - smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; + if (ht_cap->ht_supported) { + smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; + smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; + } else { + smps = le16_get_bits(sta->he_6ghz_capa.capa, + IEEE80211_HE_6GHZ_CAP_SM_PS); + } switch (smps) { case WLAN_HT_CAP_SM_PS_STATIC: @@ -1621,6 +2268,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; + const u16 *he_mcs_mask; enum wmi_phy_mode phymode = MODE_UNKNOWN; if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) @@ -1629,10 +2277,12 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, band = def.chan->band; ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; switch (band) { case NL80211_BAND_2GHZ: - if (sta->he_cap.has_he) { + if (sta->he_cap.has_he && + !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { if (sta->bandwidth == IEEE80211_STA_RX_BW_80) phymode = MODE_11AX_HE80_2G; else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) @@ -1660,7 +2310,8 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, case NL80211_BAND_5GHZ: case NL80211_BAND_6GHZ: /* Check HE first */ - if (sta->he_cap.has_he) { + if (sta->he_cap.has_he && + !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { phymode = ath11k_mac_get_phymode_he(ar, sta); } else if (sta->vht_cap.vht_supported && !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { @@ -1702,11 +2353,12 @@ static void ath11k_peer_assoc_prepare(struct ath11k *ar, ath11k_peer_assoc_h_basic(ar, vif, sta, arg); ath11k_peer_assoc_h_crypto(ar, vif, sta, arg); ath11k_peer_assoc_h_rates(ar, vif, sta, arg); + ath11k_peer_assoc_h_phymode(ar, vif, sta, arg); ath11k_peer_assoc_h_ht(ar, vif, sta, arg); ath11k_peer_assoc_h_vht(ar, vif, sta, arg); ath11k_peer_assoc_h_he(ar, vif, sta, arg); + ath11k_peer_assoc_h_he_6ghz(ar, vif, sta, arg); ath11k_peer_assoc_h_qos(ar, vif, sta, arg); - ath11k_peer_assoc_h_phymode(ar, vif, sta, arg); ath11k_peer_assoc_h_smps(sta, arg); /* TODO: amsdu_disable req? */ @@ -1714,15 +2366,20 @@ static void ath11k_peer_assoc_prepare(struct ath11k *ar, static int ath11k_setup_peer_smps(struct ath11k *ar, struct ath11k_vif *arvif, const u8 *addr, - const struct ieee80211_sta_ht_cap *ht_cap) + const struct ieee80211_sta_ht_cap *ht_cap, + u16 he_6ghz_capa) { int smps; - if (!ht_cap->ht_supported) + if (!ht_cap->ht_supported && !he_6ghz_capa) return 0; - smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; - smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; + if (ht_cap->ht_supported) { + smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; + smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; + } else { + smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS, he_6ghz_capa); + } if (smps >= ARRAY_SIZE(ath11k_smps_map)) return -EINVAL; @@ -1775,7 +2432,8 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, } ret = ath11k_setup_peer_smps(ar, arvif, bss_conf->bssid, - &ap_sta->ht_cap); + &ap_sta->ht_cap, + le16_to_cpu(ap_sta->he_6ghz_capa.capa)); if (ret) { ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); @@ -1956,7 +2614,7 @@ static int ath11k_mac_config_obss_pd(struct ath11k *ar, /* Set and enable SRG/non-SRG OBSS PD Threshold */ param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD; - if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) { + if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) { ret = ath11k_wmi_pdev_set_param(ar, param_id, 0, pdev_id); if (ret) ath11k_warn(ar->ab, @@ -2383,18 +3041,21 @@ void __ath11k_mac_scan_finish(struct ath11k *ar) break; case ATH11K_SCAN_RUNNING: case ATH11K_SCAN_ABORTING: + if (ar->scan.is_roc && ar->scan.roc_notify) + ieee80211_remain_on_channel_expired(ar->hw); + fallthrough; + case ATH11K_SCAN_STARTING: if (!ar->scan.is_roc) { struct cfg80211_scan_info info = { - .aborted = (ar->scan.state == - ATH11K_SCAN_ABORTING), + .aborted = ((ar->scan.state == + ATH11K_SCAN_ABORTING) || + (ar->scan.state == + ATH11K_SCAN_STARTING)), }; ieee80211_scan_completed(ar->hw, &info); - } else if (ar->scan.roc_notify) { - ieee80211_remain_on_channel_expired(ar->hw); } - fallthrough; - case ATH11K_SCAN_STARTING: + ar->scan.state = ATH11K_SCAN_IDLE; ar->scan_channel = NULL; ar->scan.roc_freq = 0; @@ -2887,6 +3548,20 @@ ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar, } static int +ath11k_mac_bitrate_mask_num_he_rates(struct ath11k *ar, + enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + int num_rates = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) + num_rates += hweight16(mask->control[band].he_mcs[i]); + + return num_rates; +} + +static int ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, struct ieee80211_sta *sta, const struct cfg80211_bitrate_mask *mask, @@ -2914,6 +3589,10 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, return -EINVAL; } + /* Avoid updating invalid nss as fixed rate*/ + if (nss > sta->rx_nss) + return -EINVAL; + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates", sta->addr); @@ -2932,6 +3611,57 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, return ret; } +static int +ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif, + struct ieee80211_sta *sta, + const struct cfg80211_bitrate_mask *mask, + enum nl80211_band band) +{ + struct ath11k *ar = arvif->ar; + u8 he_rate, nss; + u32 rate_code; + int ret, i; + + lockdep_assert_held(&ar->conf_mutex); + + nss = 0; + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { + if (hweight16(mask->control[band].he_mcs[i]) == 1) { + nss = i + 1; + he_rate = ffs(mask->control[band].he_mcs[i]) - 1; + } + } + + if (!nss) { + ath11k_warn(ar->ab, "No single he fixed rate found to set for %pM", + sta->addr); + return -EINVAL; + } + + /* Avoid updating invalid nss as fixed rate */ + if (nss > sta->rx_nss) + return -EINVAL; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "mac setting fixed he rate for peer %pM, device will not switch to any other selected rates", + sta->addr); + + rate_code = ATH11K_HW_RATE_CODE(he_rate, nss - 1, + WMI_RATE_PREAMBLE_HE); + + ret = ath11k_wmi_set_peer_param(ar, sta->addr, + arvif->vdev_id, + WMI_PEER_PARAM_FIXED_RATE, + rate_code); + if (ret) + ath11k_warn(ar->ab, + "failed to update sta %pM fixed rate %d: %d\n", + sta->addr, rate_code, ret); + + return ret; +} + static int ath11k_station_assoc(struct ath11k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -2943,7 +3673,7 @@ static int ath11k_station_assoc(struct ath11k *ar, struct cfg80211_chan_def def; enum nl80211_band band; struct cfg80211_bitrate_mask *mask; - u8 num_vht_rates; + u8 num_vht_rates, num_he_rates; lockdep_assert_held(&ar->conf_mutex); @@ -2969,9 +3699,10 @@ static int ath11k_station_assoc(struct ath11k *ar, } num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask); + num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask); - /* If single VHT rate is configured (by set_bitrate_mask()), - * peer_assoc will disable VHT. This is now enabled by a peer specific + /* If single VHT/HE rate is configured (by set_bitrate_mask()), + * peer_assoc will disable VHT/HE. This is now enabled by a peer specific * fixed param. * Note that all other rates and NSS will be disabled for this peer. */ @@ -2980,6 +3711,11 @@ static int ath11k_station_assoc(struct ath11k *ar, band); if (ret) return ret; + } else if (sta->he_cap.has_he && num_he_rates == 1) { + ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, + band); + if (ret) + return ret; } /* Re-assoc is run only to update supported rates for given station. It @@ -2989,7 +3725,7 @@ static int ath11k_station_assoc(struct ath11k *ar, return 0; ret = ath11k_setup_peer_smps(ar, arvif, sta->addr, - &sta->ht_cap); + &sta->ht_cap, le16_to_cpu(sta->he_6ghz_capa.capa)); if (ret) { ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); @@ -3050,8 +3786,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; + const u16 *he_mcs_mask; u32 changed, bw, nss, smps; - int err, num_vht_rates; + int err, num_vht_rates, num_he_rates; const struct cfg80211_bitrate_mask *mask; struct peer_assoc_params peer_arg; @@ -3066,6 +3803,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) band = def.chan->band; ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; spin_lock_bh(&ar->data_lock); @@ -3081,8 +3819,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) mutex_lock(&ar->conf_mutex); nss = max_t(u32, 1, nss); - nss = min(nss, max(ath11k_mac_max_ht_nss(ht_mcs_mask), - ath11k_mac_max_vht_nss(vht_mcs_mask))); + nss = min(nss, max(max(ath11k_mac_max_ht_nss(ht_mcs_mask), + ath11k_mac_max_vht_nss(vht_mcs_mask)), + ath11k_mac_max_he_nss(he_mcs_mask))); if (changed & IEEE80211_RC_BW_CHANGED) { err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, @@ -3118,6 +3857,8 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) mask = &arvif->bitrate_mask; num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask); + num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, + mask); /* Peer_assoc_prepare will reject vht rates in * bitrate_mask if its not available in range format and @@ -3133,11 +3874,25 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) if (sta->vht_cap.vht_supported && num_vht_rates == 1) { ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band); + } else if (sta->he_cap.has_he && num_he_rates == 1) { + ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, + band); } else { - /* If the peer is non-VHT or no fixed VHT rate + /* If the peer is non-VHT/HE or no fixed VHT/HE rate * is provided in the new bitrate mask we set the - * other rates using peer_assoc command. + * other rates using peer_assoc command. Also clear + * the peer fixed rate settings as it has higher proprity + * than peer assoc */ + err = ath11k_wmi_set_peer_param(ar, sta->addr, + arvif->vdev_id, + WMI_PEER_PARAM_FIXED_RATE, + WMI_FIXED_RATE_NONE); + if (err) + ath11k_warn(ar->ab, + "failed to disable peer fixed rate for sta %pM: %d\n", + sta->addr, err); + ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true); @@ -3155,6 +3910,31 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) mutex_unlock(&ar->conf_mutex); } +static void ath11k_sta_set_4addr_wk(struct work_struct *wk) +{ + struct ath11k *ar; + struct ath11k_vif *arvif; + struct ath11k_sta *arsta; + struct ieee80211_sta *sta; + int ret = 0; + + arsta = container_of(wk, struct ath11k_sta, set_4addr_wk); + sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); + arvif = arsta->arvif; + ar = arvif->ar; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "setting USE_4ADDR for peer %pM\n", sta->addr); + + ret = ath11k_wmi_set_peer_param(ar, sta->addr, + arvif->vdev_id, + WMI_PEER_USE_4ADDR, 1); + + if (ret) + ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n", + sta->addr, ret); +} + static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, struct ieee80211_sta *sta) { @@ -3234,11 +4014,13 @@ static int ath11k_mac_station_add(struct ath11k *ar, } if (ieee80211_vif_is_mesh(vif)) { + ath11k_dbg(ab, ATH11K_DBG_MAC, + "setting USE_4ADDR for mesh STA %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, WMI_PEER_USE_4ADDR, 1); if (ret) { - ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n", + ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n", sta->addr, ret); goto free_tx_stats; } @@ -3291,8 +4073,10 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, /* cancel must be done outside the mutex to avoid deadlock */ if ((old_state == IEEE80211_STA_NONE && - new_state == IEEE80211_STA_NOTEXIST)) + new_state == IEEE80211_STA_NOTEXIST)) { cancel_work_sync(&arsta->update_wk); + cancel_work_sync(&arsta->set_4addr_wk); + } mutex_lock(&ar->conf_mutex); @@ -3301,6 +4085,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, memset(arsta, 0, sizeof(*arsta)); arsta->arvif = arvif; INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk); + INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk); ret = ath11k_mac_station_add(ar, vif, sta); if (ret) @@ -3395,6 +4180,19 @@ out: return ret; } +static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled) +{ + struct ath11k *ar = hw->priv; + struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; + + if (enabled && !arsta->use_4addr_set) { + ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); + arsta->use_4addr_set = true; + } +} + static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -3765,11 +4563,6 @@ ath11k_create_vht_cap(struct ath11k *ar, u32 rate_cap_tx_chainmask, ath11k_set_vht_txbf_cap(ar, &vht_cap.cap); - /* TODO: Enable back VHT160 mode once association issues are fixed */ - /* Disabling VHT160 and VHT80+80 modes */ - vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; - vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; - rxmcs_map = 0; txmcs_map = 0; for (i = 0; i < 8; i++) { @@ -3814,7 +4607,9 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar, rate_cap_rx_chainmask); } - if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) { + if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && + (ar->ab->hw_params.single_pdev_only || + !ar->supports_6ghz)) { band = &ar->mac.sbands[NL80211_BAND_5GHZ]; ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info; if (ht_cap_info) @@ -4313,6 +5108,7 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; + struct ath11k_sta *arsta = NULL; u32 info_flags = info->flags; bool is_prb_rsp; int ret; @@ -4338,7 +5134,10 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, return; } - ret = ath11k_dp_tx(ar, arvif, skb); + if (control->sta) + arsta = (struct ath11k_sta *)control->sta->drv_priv; + + ret = ath11k_dp_tx(ar, arvif, arsta, skb); if (ret) { ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->hw, skb); @@ -4639,7 +5438,8 @@ static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET || (vif->type != NL80211_IFTYPE_STATION && vif->type != NL80211_IFTYPE_AP)) - vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED | + IEEE80211_OFFLOAD_DECAP_ENABLED); if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) param_value = ATH11K_HW_TXRX_ETHERNET; @@ -4655,6 +5455,22 @@ static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, arvif->vdev_id, ret); vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; } + + param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE; + if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED) + param_value = ATH11K_HW_TXRX_ETHERNET; + else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) + param_value = ATH11K_HW_TXRX_RAW; + else + param_value = ATH11K_HW_TXRX_NATIVE_WIFI; + + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + param_id, param_value); + if (ret) { + ath11k_warn(ab, "failed to set vdev %d rx decap mode: %d\n", + arvif->vdev_id, ret); + vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; + } } static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, @@ -4683,8 +5499,8 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, } if (ar->num_created_vdevs > (TARGET_NUM_VDEVS - 1)) { - ath11k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", - TARGET_NUM_VDEVS); + ath11k_warn(ab, "failed to create vdev %u, reached max vdev limit %d\n", + ar->num_created_vdevs, TARGET_NUM_VDEVS); ret = -EBUSY; goto err; } @@ -4700,10 +5516,13 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) { arvif->bitrate_mask.control[i].legacy = 0xffffffff; + arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI; memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff, sizeof(arvif->bitrate_mask.control[i].ht_mcs)); memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff, sizeof(arvif->bitrate_mask.control[i].vht_mcs)); + memset(arvif->bitrate_mask.control[i].he_mcs, 0xff, + sizeof(arvif->bitrate_mask.control[i].he_mcs)); } bit = __ffs64(ab->free_vdev_map); @@ -4724,6 +5543,7 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; + ar->monitor_vdev_id = bit; break; default: WARN_ON(1); @@ -4825,6 +5645,9 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, goto err_peer_del; } break; + case WMI_VDEV_TYPE_MONITOR: + set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); + break; default: break; } @@ -4845,6 +5668,16 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, ath11k_dp_vdev_tx_attach(ar, arvif); + if (vif->type != NL80211_IFTYPE_MONITOR && + test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { + ret = ath11k_mac_monitor_vdev_create(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d", + ret); + goto err_peer_del; + } + } + mutex_unlock(&ar->conf_mutex); return 0; @@ -4942,6 +5775,18 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw, ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", vif->addr, arvif->vdev_id); + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); + ar->monitor_vdev_id = -1; + } else if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags) && + !test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) { + ret = ath11k_mac_monitor_vdev_delete(ar); + if (ret) + /* continue even if there's an error */ + ath11k_warn(ar->ab, "failed to delete vdev monitor during remove interface: %d", + ret); + } + err_vdev_del: spin_lock_bh(&ar->data_lock); list_del(&arvif->list); @@ -4952,7 +5797,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); - for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock); idr_for_each(&ab->dp.tx_ring[i].txbuf_idr, ath11k_mac_vif_unref, vif); @@ -4961,7 +5806,6 @@ err_vdev_del: /* Recalc txpower for remaining vdev */ ath11k_mac_txpower_recalc(ar); - clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); /* TODO: recal traffic pause state based on the available vdevs */ @@ -4984,8 +5828,6 @@ static void ath11k_mac_op_configure_filter(struct ieee80211_hw *hw, u64 multicast) { struct ath11k *ar = hw->priv; - bool reset_flag = false; - int ret = 0; mutex_lock(&ar->conf_mutex); @@ -4993,23 +5835,6 @@ static void ath11k_mac_op_configure_filter(struct ieee80211_hw *hw, *total_flags &= SUPPORTED_FILTERS; ar->filter_flags = *total_flags; - /* For monitor mode */ - reset_flag = !(ar->filter_flags & FIF_BCN_PRBRESP_PROMISC); - - ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, reset_flag); - if (!ret) { - if (!reset_flag) - set_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); - else - clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); - } else { - ath11k_warn(ar->ab, - "fail to set monitor filter: %d\n", ret); - } - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, - "changed_flags:0x%x, total_flags:0x%x, reset_flag:%d\n", - changed_flags, *total_flags, reset_flag); - mutex_unlock(&ar->conf_mutex); } @@ -5118,20 +5943,6 @@ static void ath11k_mac_op_remove_chanctx(struct ieee80211_hw *hw, mutex_unlock(&ar->conf_mutex); } -static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar) -{ - lockdep_assert_held(&ar->conf_mutex); - - if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) - return -ESHUTDOWN; - - if (!wait_for_completion_timeout(&ar->vdev_setup_done, - ATH11K_VDEV_SETUP_TIMEOUT_HZ)) - return -ETIMEDOUT; - - return ar->last_wmi_vdev_start_status ? -EINVAL : 0; -} - static int ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif, const struct cfg80211_chan_def *chandef, @@ -5214,7 +6025,9 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif, return ret; } - ar->num_started_vdevs++; + if (!restart) + ar->num_started_vdevs++; + ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM started, vdev_id %d\n", arvif->vif->addr, arvif->vdev_id); @@ -5342,12 +6155,16 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, struct ath11k_vif *arvif; int ret; int i; + bool monitor_vif = false; lockdep_assert_held(&ar->conf_mutex); for (i = 0; i < n_vifs; i++) { arvif = (void *)vifs[i].vif->drv_priv; + if (vifs[i].vif->type == NL80211_IFTYPE_MONITOR) + monitor_vif = true; + ath11k_dbg(ab, ATH11K_DBG_MAC, "mac chanctx switch vdev_id %i freq %u->%u width %d->%d\n", arvif->vdev_id, @@ -5368,6 +6185,8 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, arvif->vdev_id, ret); continue; } + + ar->num_started_vdevs--; } /* All relevant vdevs are downed and associated channel resources @@ -5405,6 +6224,24 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, continue; } } + + /* Restart the internal monitor vdev on new channel */ + if (!monitor_vif && + test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { + ret = ath11k_mac_monitor_stop(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to stop monitor during vif channel update: %d", + ret); + return; + } + + ret = ath11k_mac_monitor_start(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to start monitor during vif channel update: %d", + ret); + return; + } + } } static void @@ -5484,7 +6321,7 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, } if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { - ret = ath11k_monitor_vdev_up(ar, arvif->vdev_id); + ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr); if (ret) { ath11k_warn(ab, "failed put monitor up: %d\n", ret); return ret; @@ -5544,6 +6381,18 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, } } + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + ret = ath11k_mac_monitor_start(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d", + ret); + goto out; + } + + arvif->is_started = true; + goto out; + } + ret = ath11k_mac_vdev_start(arvif, &ctx->def); if (ret) { ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", @@ -5551,14 +6400,19 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, ctx->def.chan->center_freq, ret); goto out; } - if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { - ret = ath11k_monitor_vdev_up(ar, arvif->vdev_id); - if (ret) - goto out; - } arvif->is_started = true; + if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && + test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { + ret = ath11k_mac_monitor_start(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d", + ret); + goto out; + } + } + /* TODO: Setup ps and cts/rts protection */ ret = 0; @@ -5592,6 +6446,20 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, ath11k_peer_find_by_addr(ab, ar->mac_addr)) ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + ret = ath11k_mac_monitor_stop(ar); + if (ret) { + ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d", + ret); + mutex_unlock(&ar->conf_mutex); + return; + } + + arvif->is_started = false; + mutex_unlock(&ar->conf_mutex); + return; + } + ret = ath11k_mac_vdev_stop(arvif); if (ret) ath11k_warn(ab, "failed to stop vdev %i: %d\n", @@ -5603,6 +6471,16 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ath11k_wmi_vdev_down(ar, arvif->vdev_id); + if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && + ar->num_started_vdevs == 1 && + test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { + ret = ath11k_mac_monitor_stop(ar); + if (ret) + /* continue even if there's an error */ + ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d", + ret); + } + mutex_unlock(&ar->conf_mutex); } @@ -5720,9 +6598,26 @@ ath11k_mac_has_single_legacy_rate(struct ath11k *ar, if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask)) return false; + if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask)) + return false; + return num_rates == 1; } +static __le16 +ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap) +{ + if (he_cap->he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) + return he_cap->he_mcs_nss_supp.tx_mcs_80p80; + + if (he_cap->he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) + return he_cap->he_mcs_nss_supp.tx_mcs_160; + + return he_cap->he_mcs_nss_supp.tx_mcs_80; +} + static bool ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, enum nl80211_band band, @@ -5731,8 +6626,10 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, { struct ieee80211_supported_band *sband = &ar->mac.sbands[band]; u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map); + u16 he_mcs_map = 0; u8 ht_nss_mask = 0; u8 vht_nss_mask = 0; + u8 he_nss_mask = 0; int i; /* No need to consider legacy here. Basic rates are always present @@ -5759,7 +6656,20 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, return false; } - if (ht_nss_mask != vht_nss_mask) + he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap)); + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { + if (mask->control[band].he_mcs[i] == 0) + continue; + + if (mask->control[band].he_mcs[i] == + ath11k_mac_get_max_he_mcs_map(he_mcs_map, i)) + he_nss_mask |= BIT(i); + else + return false; + } + + if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask) return false; if (ht_nss_mask == 0) @@ -5806,42 +6716,125 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar, return 0; } -static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif, - u32 rate, u8 nss, u8 sgi, u8 ldpc) +static int +ath11k_mac_set_fixed_rate_gi_ltf(struct ath11k_vif *arvif, u8 he_gi, u8 he_ltf) { struct ath11k *ar = arvif->ar; - u32 vdev_param; int ret; - lockdep_assert_held(&ar->conf_mutex); + /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */ + if (he_gi && he_gi != 0xFF) + he_gi += 1; - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n", - arvif->vdev_id, rate, nss, sgi); + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + WMI_VDEV_PARAM_SGI, he_gi); + if (ret) { + ath11k_warn(ar->ab, "failed to set he gi %d: %d\n", + he_gi, ret); + return ret; + } + /* start from 1 */ + if (he_ltf != 0xFF) + he_ltf += 1; - vdev_param = WMI_VDEV_PARAM_FIXED_RATE; ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, rate); + WMI_VDEV_PARAM_HE_LTF, he_ltf); if (ret) { - ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", - rate, ret); + ath11k_warn(ar->ab, "failed to set he ltf %d: %d\n", + he_ltf, ret); return ret; } - vdev_param = WMI_VDEV_PARAM_NSS; + return 0; +} + +static int +ath11k_mac_set_auto_rate_gi_ltf(struct ath11k_vif *arvif, u16 he_gi, u8 he_ltf) +{ + struct ath11k *ar = arvif->ar; + int ret; + u32 he_ar_gi_ltf; + + if (he_gi != 0xFF) { + switch (he_gi) { + case NL80211_RATE_INFO_HE_GI_0_8: + he_gi = WMI_AUTORATE_800NS_GI; + break; + case NL80211_RATE_INFO_HE_GI_1_6: + he_gi = WMI_AUTORATE_1600NS_GI; + break; + case NL80211_RATE_INFO_HE_GI_3_2: + he_gi = WMI_AUTORATE_3200NS_GI; + break; + default: + ath11k_warn(ar->ab, "invalid he gi: %d\n", he_gi); + return -EINVAL; + } + } + + if (he_ltf != 0xFF) { + switch (he_ltf) { + case NL80211_RATE_INFO_HE_1XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_1X; + break; + case NL80211_RATE_INFO_HE_2XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_2X; + break; + case NL80211_RATE_INFO_HE_4XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_4X; + break; + default: + ath11k_warn(ar->ab, "invalid he ltf: %d\n", he_ltf); + return -EINVAL; + } + } + + he_ar_gi_ltf = he_gi | he_ltf; ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, nss); + WMI_VDEV_PARAM_AUTORATE_MISC_CFG, + he_ar_gi_ltf); if (ret) { - ath11k_warn(ar->ab, "failed to set nss param %d: %d\n", - nss, ret); + ath11k_warn(ar->ab, + "failed to set he autorate gi %u ltf %u: %d\n", + he_gi, he_ltf, ret); return ret; } - vdev_param = WMI_VDEV_PARAM_SGI; + return 0; +} + +static int ath11k_mac_set_rate_params(struct ath11k_vif *arvif, + u32 rate, u8 nss, u8 sgi, u8 ldpc, + u8 he_gi, u8 he_ltf, bool he_fixed_rate) +{ + struct ath11k *ar = arvif->ar; + u32 vdev_param; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", + arvif->vdev_id, rate, nss, sgi, ldpc, he_gi, + he_ltf, he_fixed_rate); + + if (!arvif->vif->bss_conf.he_support) { + vdev_param = WMI_VDEV_PARAM_FIXED_RATE; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + vdev_param, rate); + if (ret) { + ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", + rate, ret); + return ret; + } + } + + vdev_param = WMI_VDEV_PARAM_NSS; ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, sgi); + vdev_param, nss); if (ret) { - ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n", - sgi, ret); + ath11k_warn(ar->ab, "failed to set nss param %d: %d\n", + nss, ret); return ret; } @@ -5854,6 +6847,35 @@ static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif, return ret; } + if (arvif->vif->bss_conf.he_support) { + if (he_fixed_rate) { + ret = ath11k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, + he_ltf); + if (ret) { + ath11k_warn(ar->ab, "failed to set fixed rate gi ltf: %d\n", + ret); + return ret; + } + } else { + ret = ath11k_mac_set_auto_rate_gi_ltf(arvif, he_gi, + he_ltf); + if (ret) { + ath11k_warn(ar->ab, "failed to set auto rate gi ltf: %d\n", + ret); + return ret; + } + } + } else { + vdev_param = WMI_VDEV_PARAM_SGI; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + vdev_param, sgi); + if (ret) { + ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n", + sgi, ret); + return ret; + } + } + return 0; } @@ -5882,6 +6904,31 @@ ath11k_mac_vht_mcs_range_present(struct ath11k *ar, return true; } +static bool +ath11k_mac_he_mcs_range_present(struct ath11k *ar, + enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + int i; + u16 he_mcs; + + for (i = 0; i < NL80211_HE_NSS_MAX; i++) { + he_mcs = mask->control[band].he_mcs[i]; + + switch (he_mcs) { + case 0: + case BIT(8) - 1: + case BIT(10) - 1: + case BIT(12) - 1: + break; + default: + return false; + } + } + + return true; +} + static void ath11k_mac_set_bitrate_mask_iter(void *data, struct ieee80211_sta *sta) { @@ -5913,6 +6960,54 @@ static void ath11k_mac_disable_peer_fixed_rate(void *data, sta->addr, ret); } +static bool +ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + bool he_fixed_rate = false, vht_fixed_rate = false; + struct ath11k_peer *peer, *tmp; + const u16 *vht_mcs_mask, *he_mcs_mask; + u8 vht_nss, he_nss; + bool ret = true; + + vht_mcs_mask = mask->control[band].vht_mcs; + he_mcs_mask = mask->control[band].he_mcs; + + if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1) + vht_fixed_rate = true; + + if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1) + he_fixed_rate = true; + + if (!vht_fixed_rate && !he_fixed_rate) + return true; + + vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask); + he_nss = ath11k_mac_max_he_nss(he_mcs_mask); + + rcu_read_lock(); + spin_lock_bh(&ar->ab->base_lock); + list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) { + if (peer->sta) { + if (vht_fixed_rate && (!peer->sta->vht_cap.vht_supported || + peer->sta->rx_nss < vht_nss)) { + ret = false; + goto out; + } + if (he_fixed_rate && (!peer->sta->he_cap.has_he || + peer->sta->rx_nss < he_nss)) { + ret = false; + goto out; + } + } + } + +out: + spin_unlock_bh(&ar->ab->base_lock); + rcu_read_unlock(); + return ret; +} + static int ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -5924,6 +7019,9 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; + const u16 *he_mcs_mask; + u8 he_ltf = 0; + u8 he_gi = 0; u32 rate; u8 nss; u8 sgi; @@ -5931,6 +7029,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, int single_nss; int ret; int num_rates; + bool he_fixed_rate = false; if (ath11k_mac_vif_chan(vif, &def)) return -EPERM; @@ -5938,12 +7037,16 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, band = def.chan->band; ht_mcs_mask = mask->control[band].ht_mcs; vht_mcs_mask = mask->control[band].vht_mcs; + he_mcs_mask = mask->control[band].he_mcs; ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); sgi = mask->control[band].gi; if (sgi == NL80211_TXRATE_FORCE_LGI) return -EINVAL; + he_gi = mask->control[band].he_gi; + he_ltf = mask->control[band].he_ltf; + /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it * requires passing atleast one of used basic rates along with them. * Fixed rate setting across different preambles(legacy, HT, VHT) is @@ -5967,11 +7070,22 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, &single_nss)) { rate = WMI_FIXED_RATE_NONE; nss = single_nss; + mutex_lock(&ar->conf_mutex); + arvif->bitrate_mask = *mask; + ieee80211_iterate_stations_atomic(ar->hw, + ath11k_mac_set_bitrate_mask_iter, + arvif); + mutex_unlock(&ar->conf_mutex); } else { rate = WMI_FIXED_RATE_NONE; + + if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask)) + ath11k_warn(ar->ab, + "could not update fixed rate settings to all peers due to mcs/nss incompatibility\n"); nss = min_t(u32, ar->num_tx_chains, - max(ath11k_mac_max_ht_nss(ht_mcs_mask), - ath11k_mac_max_vht_nss(vht_mcs_mask))); + max(max(ath11k_mac_max_ht_nss(ht_mcs_mask), + ath11k_mac_max_vht_nss(vht_mcs_mask)), + ath11k_mac_max_he_nss(he_mcs_mask))); /* If multiple rates across different preambles are given * we can reconfigure this info with all peers using PEER_ASSOC @@ -6002,16 +7116,28 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, * RATEMASK CMD */ ath11k_warn(ar->ab, - "Setting more than one MCS Value in bitrate mask not supported\n"); + "setting %d mcs values in bitrate mask not supported\n", + num_rates); return -EINVAL; } + num_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, + mask); + if (num_rates == 1) + he_fixed_rate = true; + + if (!ath11k_mac_he_mcs_range_present(ar, band, mask) && + num_rates > 1) { + ath11k_warn(ar->ab, + "Setting more than one HE MCS Value in bitrate mask not supported\n"); + return -EINVAL; + } + + mutex_lock(&ar->conf_mutex); ieee80211_iterate_stations_atomic(ar->hw, ath11k_mac_disable_peer_fixed_rate, arvif); - mutex_lock(&ar->conf_mutex); - arvif->bitrate_mask = *mask; ieee80211_iterate_stations_atomic(ar->hw, ath11k_mac_set_bitrate_mask_iter, @@ -6022,9 +7148,10 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); - ret = ath11k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc); + ret = ath11k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, + he_ltf, he_fixed_rate); if (ret) { - ath11k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n", + ath11k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", arvif->vdev_id, ret); } @@ -6109,7 +7236,13 @@ static int ath11k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, if (!sband) sband = hw->wiphy->bands[NL80211_BAND_5GHZ]; + if (sband && idx >= sband->n_channels) { + idx -= sband->n_channels; + sband = NULL; + } + if (!sband) + sband = hw->wiphy->bands[NL80211_BAND_6GHZ]; if (!sband || idx >= sband->n_channels) { ret = -ENOENT; goto exit; @@ -6180,6 +7313,7 @@ static const struct ieee80211_ops ath11k_ops = { .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, .set_key = ath11k_mac_op_set_key, .sta_state = ath11k_mac_op_sta_state, + .sta_set_4addr = ath11k_mac_op_sta_set_4addr, .sta_set_txpwr = ath11k_mac_op_sta_set_txpwr, .sta_rc_update = ath11k_mac_op_sta_rc_update, .conf_tx = ath11k_mac_op_conf_tx, @@ -6240,7 +7374,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, u32 supported_bands) { struct ieee80211_supported_band *band; - struct ath11k_hal_reg_capabilities_ext *reg_cap; + struct ath11k_hal_reg_capabilities_ext *reg_cap, *temp_reg_cap; void *channels; u32 phy_id; @@ -6250,6 +7384,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, ATH11K_NUM_CHANS); reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx]; + temp_reg_cap = reg_cap; if (supported_bands & WMI_HOST_WLAN_2G_CAP) { channels = kmemdup(ath11k_2ghz_channels, @@ -6268,11 +7403,11 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, if (ar->ab->hw_params.single_pdev_only) { phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP); - reg_cap = &ar->ab->hal_reg_cap[phy_id]; + temp_reg_cap = &ar->ab->hal_reg_cap[phy_id]; } ath11k_mac_update_ch_list(ar, band, - reg_cap->low_2ghz_chan, - reg_cap->high_2ghz_chan); + temp_reg_cap->low_2ghz_chan, + temp_reg_cap->high_2ghz_chan); } if (supported_bands & WMI_HOST_WLAN_5G_CAP) { @@ -6292,9 +7427,15 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, band->n_bitrates = ath11k_a_rates_size; band->bitrates = ath11k_a_rates; ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band; + + if (ar->ab->hw_params.single_pdev_only) { + phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP); + temp_reg_cap = &ar->ab->hal_reg_cap[phy_id]; + } + ath11k_mac_update_ch_list(ar, band, - reg_cap->low_5ghz_chan, - reg_cap->high_5ghz_chan); + temp_reg_cap->low_5ghz_chan, + temp_reg_cap->high_5ghz_chan); } if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) { @@ -6317,12 +7458,12 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, if (ar->ab->hw_params.single_pdev_only) { phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP); - reg_cap = &ar->ab->hal_reg_cap[phy_id]; + temp_reg_cap = &ar->ab->hal_reg_cap[phy_id]; } ath11k_mac_update_ch_list(ar, band, - reg_cap->low_5ghz_chan, - reg_cap->high_5ghz_chan); + temp_reg_cap->low_5ghz_chan, + temp_reg_cap->high_5ghz_chan); } } @@ -6367,7 +7508,9 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | BIT(NL80211_CHAN_WIDTH_20) | BIT(NL80211_CHAN_WIDTH_40) | - BIT(NL80211_CHAN_WIDTH_80); + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_80P80) | + BIT(NL80211_CHAN_WIDTH_160); ar->hw->wiphy->iface_combinations = combinations; ar->hw->wiphy->n_iface_combinations = 1; @@ -6505,8 +7648,16 @@ static int __ath11k_mac_register(struct ath11k *ar) ieee80211_hw_set(ar->hw, QUEUE_CONTROL); ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); - ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); - if (ht_cap & WMI_HT_CAP_ENABLED) { + + if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) { + ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); + ieee80211_hw_set(ar->hw, SUPPORTS_RX_DECAP_OFFLOAD); + } + + if (cap->nss_ratio_enabled) + ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW); + + if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) { ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION); ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW); ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER); @@ -6521,7 +7672,7 @@ static int __ath11k_mac_register(struct ath11k *ar) * for each band for a dual band capable radio. It will be tricky to * handle it when the ht capability different for each band. */ - if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS) + if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS || ar->supports_6ghz) ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS; ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID; @@ -6590,7 +7741,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); /* Apply the regd received during initialization */ - ret = ath11k_regd_update(ar, true); + ret = ath11k_regd_update(ar); if (ret) { ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret); goto err_unregister_hw; @@ -6631,6 +7782,10 @@ int ath11k_mac_register(struct ath11k_base *ab) if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) return 0; + /* Initialize channel counters frequency value in hertz */ + ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ; + ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1; + for (i = 0; i < ab->num_radios; i++) { pdev = &ab->pdevs[i]; ar = pdev->ar; @@ -6641,18 +7796,14 @@ int ath11k_mac_register(struct ath11k_base *ab) ar->mac_addr[4] += i; } + idr_init(&ar->txmgmt_idr); + spin_lock_init(&ar->txmgmt_idr_lock); + ret = __ath11k_mac_register(ar); if (ret) goto err_cleanup; - - idr_init(&ar->txmgmt_idr); - spin_lock_init(&ar->txmgmt_idr_lock); } - /* Initialize channel counters frequency value in hertz */ - ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ; - ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1; - return 0; err_cleanup: @@ -6723,7 +7874,11 @@ int ath11k_mac_allocate(struct ath11k_base *ab) INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); - clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); + + clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); + + ar->monitor_vdev_id = -1; + clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); } return 0; diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 4bc59bdaf244..254ca4acc8e8 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -115,6 +115,9 @@ struct ath11k_generic_iter { #define WMI_MAX_SPATIAL_STREAM 3 #define ATH11K_CHAN_WIDTH_NUM 8 +#define ATH11K_BW_NSS_MAP_ENABLE BIT(31) +#define ATH11K_PEER_RX_NSS_160MHZ GENMASK(2, 0) +#define ATH11K_PEER_RX_NSS_80_80MHZ GENMASK(5, 3) #define ATH11K_OBSS_PD_MAX_THRESHOLD -82 #define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62 diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 5abb38cc3b55..3d353e7c9d5c 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -430,6 +430,8 @@ static void ath11k_pci_force_wake(struct ath11k_base *ab) static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on) { + mdelay(100); + if (power_on) { ath11k_pci_enable_ltssm(ab); ath11k_pci_clear_all_intrs(ab); @@ -439,9 +441,9 @@ static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on) } ath11k_mhi_clear_vector(ab); + ath11k_pci_clear_dbg_registers(ab); ath11k_pci_soc_global_reset(ab); ath11k_mhi_set_mhictrl_reset(ab); - ath11k_pci_clear_dbg_registers(ab); } int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector) @@ -853,7 +855,32 @@ static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab) } } -static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci) +static void ath11k_pci_msi_config(struct ath11k_pci *ab_pci, bool enable) +{ + struct pci_dev *dev = ab_pci->pdev; + u16 control; + + pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + + if (enable) + control |= PCI_MSI_FLAGS_ENABLE; + else + control &= ~PCI_MSI_FLAGS_ENABLE; + + pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); +} + +static void ath11k_pci_msi_enable(struct ath11k_pci *ab_pci) +{ + ath11k_pci_msi_config(ab_pci, true); +} + +static void ath11k_pci_msi_disable(struct ath11k_pci *ab_pci) +{ + ath11k_pci_msi_config(ab_pci, false); +} + +static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) { struct ath11k_base *ab = ab_pci->ab; const struct ath11k_msi_config *msi_config = ab_pci->msi_config; @@ -874,6 +901,7 @@ static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci) else return num_vectors; } + ath11k_pci_msi_disable(ab_pci); msi_desc = irq_get_msi_desc(ab_pci->pdev->irq); if (!msi_desc) { @@ -896,7 +924,7 @@ free_msi_vector: return ret; } -static void ath11k_pci_disable_msi(struct ath11k_pci *ab_pci) +static void ath11k_pci_free_msi(struct ath11k_pci *ab_pci) { pci_free_irq_vectors(ab_pci->pdev); } @@ -1017,6 +1045,8 @@ static int ath11k_pci_power_up(struct ath11k_base *ab) */ ath11k_pci_aspm_disable(ab_pci); + ath11k_pci_msi_enable(ab_pci); + ret = ath11k_mhi_start(ab_pci); if (ret) { ath11k_err(ab, "failed to start mhi: %d\n", ret); @@ -1037,6 +1067,9 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) ath11k_pci_aspm_restore(ab_pci); ath11k_pci_force_wake(ab_pci->ab); + + ath11k_pci_msi_disable(ab_pci); + ath11k_mhi_stop(ab_pci); clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); ath11k_pci_sw_reset(ab_pci->ab, false); @@ -1261,7 +1294,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; } - ret = ath11k_pci_enable_msi(ab_pci); + ret = ath11k_pci_alloc_msi(ab_pci); if (ret) { ath11k_err(ab, "failed to enable msi: %d\n", ret); goto err_pci_free_region; @@ -1315,7 +1348,7 @@ err_mhi_unregister: ath11k_mhi_unregister(ab_pci); err_pci_disable_msi: - ath11k_pci_disable_msi(ab_pci); + ath11k_pci_free_msi(ab_pci); err_pci_free_region: ath11k_pci_free_region(ab_pci); @@ -1346,7 +1379,7 @@ qmi_fail: ath11k_mhi_unregister(ab_pci); ath11k_pci_free_irq(ab); - ath11k_pci_disable_msi(ab_pci); + ath11k_pci_free_msi(ab_pci); ath11k_pci_free_region(ab_pci); ath11k_hal_srng_deinit(ab); diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index f49abefa9618..85471f8b3563 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, struct ieee80211_sta *sta, struct peer_create_params *param) { struct ath11k_peer *peer; + struct ath11k_sta *arsta; int ret; lockdep_assert_held(&ar->conf_mutex); @@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + if (sta) { + arsta = (struct ath11k_sta *)sta->drv_priv; + arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) | + FIELD_PREP(HTT_TCL_META_DATA_PEER_ID, + peer->peer_id); + + /* set HTT extension valid bit to 0 by default */ + arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; + } + ar->num_peers++; spin_unlock_bh(&ar->ab->base_lock); diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index b5e34d670715..fa73118de6db 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -951,6 +951,78 @@ static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { num_macs), }, { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + voltage_mv_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + voltage_mv), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + time_freq_hz_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + time_freq_hz), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + otp_version_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + otp_version), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + eeprom_read_timeout_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + eeprom_read_timeout), + }, + { .data_type = QMI_EOTI, .array_type = NO_ARRAY, .tlv_type = QMI_COMMON_TLV_TYPE, @@ -1770,7 +1842,7 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) chunk->vaddr = dma_alloc_coherent(ab->dev, chunk->size, &chunk->paddr, - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (!chunk->vaddr) { if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) { ath11k_dbg(ab, ATH11K_DBG_QMI, @@ -1846,8 +1918,8 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); - ret = qmi_txn_init(&ab->qmi.handle, &txn, - qmi_wlanfw_cap_resp_msg_v01_ei, &resp); + ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei, + &resp); if (ret < 0) goto out; @@ -1900,6 +1972,12 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id, sizeof(ab->qmi.target.fw_build_id)); + if (resp.eeprom_read_timeout_valid) { + ab->qmi.target.eeprom_caldata = + resp.eeprom_read_timeout; + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n"); + } + ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n", ab->qmi.target.chip_id, ab->qmi.target.chip_family, ab->qmi.target.board_id, ab->qmi.target.soc_id); @@ -1917,98 +1995,73 @@ out: return ret; } -static int -ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type, - struct qmi_wlanfw_bdf_download_req_msg_v01 *req, - void __iomem *bdf_addr) -{ - const struct firmware *fw_entry; - struct ath11k_board_data bd; - u32 fw_size; - int ret; - - switch (type) { - case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN: - memset(&bd, 0, sizeof(bd)); - - ret = ath11k_core_fetch_bdf(ab, &bd); - if (ret) { - ath11k_warn(ab, "failed to load board file: %d\n", ret); - return ret; - } - - fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len); - memcpy_toio(bdf_addr, bd.data, fw_size); - ath11k_core_free_bdf(ab, &bd); - break; - case ATH11K_QMI_FILE_TYPE_CALDATA: - fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); - if (IS_ERR(fw_entry)) { - ret = PTR_ERR(fw_entry); - ath11k_warn(ab, "failed to load %s: %d\n", - ATH11K_DEFAULT_CAL_FILE, ret); - return ret; - } - - fw_size = min_t(u32, ab->hw_params.fw.board_size, - fw_entry->size); - - memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET, - fw_entry->data, fw_size); - - release_firmware(fw_entry); - break; - default: - return -EINVAL; - } - - req->total_size = fw_size; - return 0; -} - -static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab) +static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, + const u8 *data, u32 len, u8 type) { struct qmi_wlanfw_bdf_download_req_msg_v01 *req; struct qmi_wlanfw_bdf_download_resp_msg_v01 resp; struct qmi_txn txn = {}; + const u8 *temp = data; void __iomem *bdf_addr = NULL; - int type, ret; + int ret; + u32 remaining = len; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; + memset(&resp, 0, sizeof(resp)); - bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE); - if (!bdf_addr) { - ath11k_warn(ab, "failed ioremap for board file\n"); - ret = -EIO; - goto out; + if (ab->bus_params.fixed_bdf_addr) { + bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size); + if (!bdf_addr) { + ath11k_warn(ab, "qmi ioremap error for bdf_addr\n"); + ret = -EIO; + goto err_free_req; + } } - for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) { + while (remaining) { req->valid = 1; req->file_id_valid = 1; req->file_id = ab->qmi.target.board_id; req->total_size_valid = 1; + req->total_size = remaining; req->seg_id_valid = 1; - req->seg_id = type; - req->data_valid = 0; - req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; - req->bdf_type = 0; - req->bdf_type_valid = 0; + req->data_valid = 1; + req->bdf_type = type; + req->bdf_type_valid = 1; req->end_valid = 1; - req->end = 1; + req->end = 0; - ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr); - if (ret < 0) - goto out_qmi_bdf; + if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) { + req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01; + } else { + req->data_len = remaining; + req->end = 1; + } + + if (ab->bus_params.fixed_bdf_addr || + type == ATH11K_QMI_FILE_TYPE_EEPROM) { + req->data_valid = 0; + req->end = 1; + req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; + } else { + memcpy(req->data, temp, req->data_len); + } + + if (ab->bus_params.fixed_bdf_addr) { + if (type == ATH11K_QMI_FILE_TYPE_CALDATA) + bdf_addr += ab->hw_params.fw.cal_offset; + + memcpy_toio(bdf_addr, temp, len); + } ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_bdf_download_resp_msg_v01_ei, &resp); if (ret < 0) - goto out_qmi_bdf; + goto err_iounmap; ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download req fixed addr type %d\n", type); @@ -2019,54 +2072,62 @@ static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab) qmi_wlanfw_bdf_download_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); - goto out_qmi_bdf; + goto err_iounmap; } ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); - if (ret < 0) - goto out_qmi_bdf; + if (ret < 0) { + ath11k_warn(ab, "failed to wait board file download request: %d\n", + ret); + goto err_iounmap; + } if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { ath11k_warn(ab, "board file download request failed: %d %d\n", resp.resp.result, resp.resp.error); ret = -EINVAL; - goto out_qmi_bdf; + goto err_iounmap; + } + + if (ab->bus_params.fixed_bdf_addr || + type == ATH11K_QMI_FILE_TYPE_EEPROM) { + remaining = 0; + } else { + remaining -= req->data_len; + temp += req->data_len; + req->seg_id++; + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n", + remaining); } } -out_qmi_bdf: - iounmap(bdf_addr); -out: +err_iounmap: + if (ab->bus_params.fixed_bdf_addr) + iounmap(bdf_addr); + +err_free_req: kfree(req); + return ret; } static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) { - struct qmi_wlanfw_bdf_download_req_msg_v01 *req; - struct qmi_wlanfw_bdf_download_resp_msg_v01 resp; + struct device *dev = ab->dev; + char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE]; + const struct firmware *fw_entry; struct ath11k_board_data bd; - unsigned int remaining; - struct qmi_txn txn = {}; - int ret; - const u8 *temp; - int bdf_type; - - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - memset(&resp, 0, sizeof(resp)); + u32 fw_size, file_type; + int ret = 0, bdf_type; + const u8 *tmp; memset(&bd, 0, sizeof(bd)); ret = ath11k_core_fetch_bdf(ab, &bd); if (ret) { - ath11k_warn(ab, "failed to fetch board file: %d\n", ret); + ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret); goto out; } - temp = bd.data; - remaining = bd.len; - if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0) bdf_type = ATH11K_QMI_BDF_TYPE_ELF; else @@ -2074,67 +2135,60 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type); - while (remaining) { - req->valid = 1; - req->file_id_valid = 1; - req->file_id = ab->qmi.target.board_id; - req->total_size_valid = 1; - req->total_size = bd.len; - req->seg_id_valid = 1; - req->data_valid = 1; - req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; - req->bdf_type = bdf_type; - req->bdf_type_valid = 1; - req->end_valid = 1; - req->end = 0; + fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len); - if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) { - req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01; - } else { - req->data_len = remaining; - req->end = 1; - } + ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type); + if (ret < 0) { + ath11k_warn(ab, "qmi failed to load bdf file\n"); + goto out; + } - memcpy(req->data, temp, req->data_len); + /* QCA6390 does not support cal data, skip it */ + if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF) + goto out; - ret = qmi_txn_init(&ab->qmi.handle, &txn, - qmi_wlanfw_bdf_download_resp_msg_v01_ei, - &resp); - if (ret < 0) - goto out_qmi_bdf; + if (ab->qmi.target.eeprom_caldata) { + file_type = ATH11K_QMI_FILE_TYPE_EEPROM; + tmp = filename; + fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; + } else { + file_type = ATH11K_QMI_FILE_TYPE_CALDATA; - ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n", - remaining); + /* cal-<bus>-<id>.bin */ + snprintf(filename, sizeof(filename), "cal-%s-%s.bin", + ath11k_bus_str(ab->hif.bus), dev_name(dev)); + fw_entry = ath11k_core_firmware_request(ab, filename); + if (!IS_ERR(fw_entry)) + goto success; - ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, - QMI_WLANFW_BDF_DOWNLOAD_REQ_V01, - QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN, - qmi_wlanfw_bdf_download_req_msg_v01_ei, req); - if (ret < 0) { - qmi_txn_cancel(&txn); - goto out_qmi_bdf; + fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); + if (IS_ERR(fw_entry)) { + ret = PTR_ERR(fw_entry); + ath11k_warn(ab, + "qmi failed to load CAL data file:%s\n", + filename); + goto out; } +success: + fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size); + tmp = fw_entry->data; + } - ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); - if (ret < 0) - goto out_qmi_bdf; - - if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { - ath11k_warn(ab, "bdf download request failed: %d %d\n", - resp.resp.result, resp.resp.error); - ret = resp.resp.result; - goto out_qmi_bdf; - } - remaining -= req->data_len; - temp += req->data_len; - req->seg_id++; + ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type); + if (ret < 0) { + ath11k_warn(ab, "qmi failed to load caldata\n"); + goto out_qmi_cal; } -out_qmi_bdf: - ath11k_core_free_bdf(ab, &bd); + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type); +out_qmi_cal: + if (!ab->qmi.target.eeprom_caldata) + release_firmware(fw_entry); out: - kfree(req); + ath11k_core_free_bdf(ab, &bd); + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n"); + return ret; } @@ -2519,10 +2573,7 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi) return ret; } - if (ab->bus_params.fixed_bdf_addr) - ret = ath11k_qmi_load_bdf_fixed_addr(ab); - else - ret = ath11k_qmi_load_bdf_qmi(ab); + ret = ath11k_qmi_load_bdf_qmi(ab); if (ret < 0) { ath11k_warn(ab, "failed to load board data file: %d\n", ret); return ret; @@ -2707,8 +2758,10 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) list_del(&event->list); spin_unlock(&qmi->event_lock); - if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) + if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) { + kfree(event); return; + } switch (event->type) { case ATH11K_QMI_EVENT_SERVER_ARRIVE: diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index 3d5930330703..3bb0f9ef7996 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -10,11 +10,9 @@ #include <linux/soc/qcom/qmi.h> #define ATH11K_HOST_VERSION_STRING "WIN" -#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000 +#define ATH11K_QMI_WLANFW_TIMEOUT_MS 10000 #define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE 64 #define ATH11K_QMI_CALDB_ADDRESS 0x4BA00000 -#define ATH11K_QMI_BDF_MAX_SIZE (256 * 1024) -#define ATH11K_QMI_CALDATA_OFFSET (128 * 1024) #define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128 #define ATH11K_QMI_WLFW_SERVICE_ID_V01 0x45 #define ATH11K_QMI_WLFW_SERVICE_VERS_V01 0x01 @@ -44,6 +42,7 @@ struct ath11k_base; enum ath11k_qmi_file_type { ATH11K_QMI_FILE_TYPE_BDF_GOLDEN, ATH11K_QMI_FILE_TYPE_CALDATA, + ATH11K_QMI_FILE_TYPE_EEPROM, ATH11K_QMI_MAX_FILE_TYPE, }; @@ -104,6 +103,7 @@ struct target_info { u32 board_id; u32 soc_id; u32 fw_version; + u32 eeprom_caldata; char fw_build_timestamp[ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1]; char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1]; char bdf_ext[ATH11K_QMI_BDF_EXT_STR_LENGTH]; @@ -135,7 +135,7 @@ struct ath11k_qmi { wait_queue_head_t cold_boot_waitq; }; -#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 189 +#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261 #define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034 #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 @@ -285,7 +285,7 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 { }; #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 -#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 207 +#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 #define QMI_WLANFW_CAP_REQ_V01 0x0024 #define QMI_WLANFW_CAP_RESP_V01 0x0024 @@ -366,6 +366,14 @@ struct qmi_wlanfw_cap_resp_msg_v01 { char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1]; u8 num_macs_valid; u8 num_macs; + u8 voltage_mv_valid; + u32 voltage_mv; + u8 time_freq_hz_valid; + u32 time_freq_hz; + u8 otp_version_valid; + u32 otp_version; + u8 eeprom_read_timeout_valid; + u32 eeprom_read_timeout; }; struct qmi_wlanfw_cap_req_msg_v01 { diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index e1a1df169034..a66b5bdd2167 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -97,7 +97,6 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) struct channel_param *ch; enum nl80211_band band; int num_channels = 0; - int params_len; int i, ret; bands = hw->wiphy->bands; @@ -117,10 +116,8 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) if (WARN_ON(!num_channels)) return -EINVAL; - params_len = sizeof(struct scan_chan_list_params) + - num_channels * sizeof(struct channel_param); - params = kzalloc(params_len, GFP_KERNEL); - + params = kzalloc(struct_size(params, ch_param, num_channels), + GFP_KERNEL); if (!params) return -ENOMEM; @@ -198,7 +195,7 @@ static void ath11k_copy_regd(struct ieee80211_regdomain *regd_orig, sizeof(struct ieee80211_reg_rule)); } -int ath11k_regd_update(struct ath11k *ar, bool init) +int ath11k_regd_update(struct ath11k *ar) { struct ieee80211_regdomain *regd, *regd_copy = NULL; int ret, regd_len, pdev_id; @@ -209,7 +206,10 @@ int ath11k_regd_update(struct ath11k *ar, bool init) spin_lock_bh(&ab->base_lock); - if (init) { + /* Prefer the latest regd update over default if it's available */ + if (ab->new_regd[pdev_id]) { + regd = ab->new_regd[pdev_id]; + } else { /* Apply the regd received during init through * WMI_REG_CHAN_LIST_CC event. In case of failure to * receive the regd, initialize with a default world @@ -222,8 +222,6 @@ int ath11k_regd_update(struct ath11k *ar, bool init) "failed to receive default regd during init\n"); regd = (struct ieee80211_regdomain *)&ath11k_world_regd; } - } else { - regd = ab->new_regd[pdev_id]; } if (!regd) { @@ -683,7 +681,7 @@ void ath11k_regd_update_work(struct work_struct *work) regd_update_work); int ret; - ret = ath11k_regd_update(ar, false); + ret = ath11k_regd_update(ar); if (ret) { /* Firmware has already moved to the new regd. We need * to maintain channel consistency across FW, Host driver diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h index 65d56d44796f..5fb9dc03a74e 100644 --- a/drivers/net/wireless/ath/ath11k/reg.h +++ b/drivers/net/wireless/ath/ath11k/reg.h @@ -31,6 +31,6 @@ void ath11k_regd_update_work(struct work_struct *work); struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, struct cur_regulatory_info *reg_info, bool intersect); -int ath11k_regd_update(struct ath11k *ar, bool init); +int ath11k_regd_update(struct ath11k *ar); int ath11k_reg_update_chan_list(struct ath11k *ar); #endif diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c index 1afe67759659..ac4da99b5577 100644 --- a/drivers/net/wireless/ath/ath11k/spectral.c +++ b/drivers/net/wireless/ath/ath11k/spectral.c @@ -11,22 +11,20 @@ #define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1 #define ATH11K_SPECTRAL_DWORD_SIZE 4 -/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes */ -#define ATH11K_SPECTRAL_BIN_SIZE 4 -#define ATH11K_SPECTRAL_ATH11K_MIN_BINS 64 -#define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32 -#define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256 +#define ATH11K_SPECTRAL_MIN_BINS 32 +#define ATH11K_SPECTRAL_MIN_IB_BINS (ATH11K_SPECTRAL_MIN_BINS >> 1) +#define ATH11K_SPECTRAL_MAX_IB_BINS(x) ((x)->hw_params.spectral.max_fft_bins >> 1) #define ATH11K_SPECTRAL_SCAN_COUNT_MAX 4095 /* Max channel computed by sum of 2g and 5g band channels */ #define ATH11K_SPECTRAL_TOTAL_CHANNEL 41 #define ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL 70 -#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE (sizeof(struct fft_sample_ath11k) + \ - ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS) +#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE(x) (sizeof(struct fft_sample_ath11k) + \ + ATH11K_SPECTRAL_MAX_IB_BINS(x)) #define ATH11K_SPECTRAL_TOTAL_SAMPLE (ATH11K_SPECTRAL_TOTAL_CHANNEL * \ ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL) -#define ATH11K_SPECTRAL_SUB_BUFF_SIZE ATH11K_SPECTRAL_PER_SAMPLE_SIZE +#define ATH11K_SPECTRAL_SUB_BUFF_SIZE(x) ATH11K_SPECTRAL_PER_SAMPLE_SIZE(x) #define ATH11K_SPECTRAL_NUM_SUB_BUF ATH11K_SPECTRAL_TOTAL_SAMPLE #define ATH11K_SPECTRAL_20MHZ 20 @@ -444,8 +442,8 @@ static ssize_t ath11k_write_file_spectral_bins(struct file *file, if (kstrtoul(buf, 0, &val)) return -EINVAL; - if (val < ATH11K_SPECTRAL_ATH11K_MIN_BINS || - val > SPECTRAL_ATH11K_MAX_NUM_BINS) + if (val < ATH11K_SPECTRAL_MIN_BINS || + val > ar->ab->hw_params.spectral.max_fft_bins) return -EINVAL; if (!is_power_of_2(val)) @@ -581,12 +579,12 @@ int ath11k_spectral_process_fft(struct ath11k *ar, struct spectral_tlv *tlv; int tlv_len, bin_len, num_bins; u16 length, freq; - u8 chan_width_mhz; + u8 chan_width_mhz, bin_sz; int ret; lockdep_assert_held(&ar->spectral.lock); - if (!ab->hw_params.spectral_fft_sz) { + if (!ab->hw_params.spectral.fft_sz) { ath11k_warn(ab, "invalid bin size type for hw rev %d\n", ab->hw_rev); return -EINVAL; @@ -596,7 +594,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar, tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header)); /* convert Dword into bytes */ tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE; - bin_len = tlv_len - (sizeof(*fft_report) - sizeof(*tlv)); + bin_len = tlv_len - ab->hw_params.spectral.fft_hdr_len; if (data_len < (bin_len + sizeof(*fft_report))) { ath11k_warn(ab, "mismatch in expected bin len %d and data len %d\n", @@ -604,12 +602,13 @@ int ath11k_spectral_process_fft(struct ath11k *ar, return -EINVAL; } - num_bins = bin_len / ATH11K_SPECTRAL_BIN_SIZE; + bin_sz = ab->hw_params.spectral.fft_sz + ab->hw_params.spectral.fft_pad_sz; + num_bins = bin_len / bin_sz; /* Only In-band bins are useful to user for visualize */ num_bins >>= 1; - if (num_bins < ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS || - num_bins > ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS || + if (num_bins < ATH11K_SPECTRAL_MIN_IB_BINS || + num_bins > ATH11K_SPECTRAL_MAX_IB_BINS(ab) || !is_power_of_2(num_bins)) { ath11k_warn(ab, "Invalid num of bins %d\n", num_bins); return -EINVAL; @@ -654,7 +653,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar, fft_sample->freq2 = __cpu_to_be16(freq); ath11k_spectral_parse_fft(fft_sample->data, fft_report->bins, num_bins, - ab->hw_params.spectral_fft_sz); + ab->hw_params.spectral.fft_sz); fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index, search.peak_mag, @@ -690,7 +689,7 @@ static int ath11k_spectral_process_data(struct ath11k *ar, goto unlock; } - sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS; + sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_MAX_IB_BINS(ab); fft_sample = kmalloc(sample_sz, GFP_ATOMIC); if (!fft_sample) { ret = -ENOBUFS; @@ -738,7 +737,8 @@ static int ath11k_spectral_process_data(struct ath11k *ar, * is 4 DWORD size (16 bytes). * Need to remove this workaround once HW bug fixed */ - tlv_len = sizeof(*summary) - sizeof(*tlv); + tlv_len = sizeof(*summary) - sizeof(*tlv) + + ab->hw_params.spectral.summary_pad_sz; if (tlv_len < (sizeof(*summary) - sizeof(*tlv))) { ath11k_warn(ab, "failed to parse spectral summary at bytes %d tlv_len:%d\n", @@ -901,7 +901,7 @@ static inline int ath11k_spectral_debug_register(struct ath11k *ar) ar->spectral.rfs_scan = relay_open("spectral_scan", ar->debug.debugfs_pdev, - ATH11K_SPECTRAL_SUB_BUFF_SIZE, + ATH11K_SPECTRAL_SUB_BUFF_SIZE(ar->ab), ATH11K_SPECTRAL_NUM_SUB_BUF, &rfs_scan_cb, NULL); if (!ar->spectral.rfs_scan) { @@ -962,7 +962,7 @@ int ath11k_spectral_init(struct ath11k_base *ab) ab->wmi_ab.svc_map)) return 0; - if (!ab->hw_params.spectral_fft_sz) + if (!ab->hw_params.spectral.fft_sz) return 0; for (i = 0; i < ab->num_radios; i++) { diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h index d2d2a3cb0826..25d18e9d5b0b 100644 --- a/drivers/net/wireless/ath/ath11k/trace.h +++ b/drivers/net/wireless/ath/ath11k/trace.h @@ -79,14 +79,15 @@ TRACE_EVENT(ath11k_htt_ppdu_stats, ); TRACE_EVENT(ath11k_htt_rxdesc, - TP_PROTO(struct ath11k *ar, const void *data, size_t len), + TP_PROTO(struct ath11k *ar, const void *data, size_t log_type, size_t len), - TP_ARGS(ar, data, len), + TP_ARGS(ar, data, log_type, len), TP_STRUCT__entry( __string(device, dev_name(ar->ab->dev)) __string(driver, dev_driver_string(ar->ab->dev)) __field(u16, len) + __field(u16, log_type) __dynamic_array(u8, rxdesc, len) ), @@ -94,14 +95,16 @@ TRACE_EVENT(ath11k_htt_rxdesc, __assign_str(device, dev_name(ar->ab->dev)); __assign_str(driver, dev_driver_string(ar->ab->dev)); __entry->len = len; + __entry->log_type = log_type; memcpy(__get_dynamic_array(rxdesc), data, len); ), TP_printk( - "%s %s rxdesc len %d", + "%s %s rxdesc len %d type %d", __get_str(driver), __get_str(device), - __entry->len + __entry->len, + __entry->log_type ) ); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 6c253eae9d06..5ae2ef4680d6 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -360,6 +360,10 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g; pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g; pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g; + pdev_cap->nss_ratio_enabled = + WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio); + pdev_cap->nss_ratio_info = + WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); } else { return -EINVAL; } @@ -403,18 +407,18 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, sizeof(struct ath11k_ppe_threshold)); - } - cap_band = &pdev_cap->band[NL80211_BAND_6GHZ]; - cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g; - cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g; - cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g; - cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext; - cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g; - memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g, - sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); - memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, - sizeof(struct ath11k_ppe_threshold)); + cap_band = &pdev_cap->band[NL80211_BAND_6GHZ]; + cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g; + cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g; + cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g; + cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext; + cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g; + memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g, + sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE); + memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g, + sizeof(struct ath11k_ppe_threshold)); + } return 0; } @@ -783,14 +787,26 @@ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id) static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan, struct wmi_vdev_start_req_arg *arg) { + u32 center_freq1 = arg->channel.band_center_freq1; + memset(chan, 0, sizeof(*chan)); chan->mhz = arg->channel.freq; chan->band_center_freq1 = arg->channel.band_center_freq1; - if (arg->channel.mode == MODE_11AC_VHT80_80) + + if (arg->channel.mode == MODE_11AX_HE160) { + if (arg->channel.freq > arg->channel.band_center_freq1) + chan->band_center_freq1 = center_freq1 + 40; + else + chan->band_center_freq1 = center_freq1 - 40; + + chan->band_center_freq2 = arg->channel.band_center_freq1; + + } else if (arg->channel.mode == MODE_11AC_VHT80_80) { chan->band_center_freq2 = arg->channel.band_center_freq2; - else + } else { chan->band_center_freq2 = 0; + } chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode); if (arg->channel.passive) @@ -868,6 +884,8 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg, } cmd->flags |= WMI_VDEV_START_LDPC_RX_ENABLED; + if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) + cmd->flags |= WMI_VDEV_START_HW_ENCRYPTION_DISABLED; ptr = skb->data + sizeof(*cmd); chan = ptr; @@ -1339,6 +1357,7 @@ int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar, WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST) | FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); cmd->req_type = type; + cmd->pdev_id = ar->pdev->pdev_id; ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "WMI bss chan info req type %d\n", type); @@ -1903,8 +1922,8 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, FIELD_PREP(WMI_TLV_LEN, sizeof(*he_mcs) - TLV_HDR_SIZE); - he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; - he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; + he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ptr += sizeof(*he_mcs); } @@ -2285,7 +2304,7 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar, u16 num_send_chans, num_sends = 0, max_chan_limit = 0; u32 *reg1, *reg2; - tchan_info = &chan_list->ch_param[0]; + tchan_info = chan_list->ch_param; while (chan_list->nallchans) { len = sizeof(*cmd) + TLV_HDR_SIZE; max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) / @@ -2352,6 +2371,8 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar, chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE; if (tchan_info->psc_channel) chan_info->info |= WMI_CHAN_INFO_PSC; + if (tchan_info->dfs_set) + chan_info->info |= WMI_CHAN_INFO_DFS; chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, tchan_info->phy_mode); @@ -3495,7 +3516,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size; wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters; wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id; - wmi_cfg->flag1 = tg_cfg->atf_config; + wmi_cfg->flag1 = tg_cfg->flag1; wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support; wmi_cfg->sched_params = tg_cfg->sched_params; wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; @@ -4046,8 +4067,8 @@ static int ath11k_wmi_tlv_mac_phy_caps_parse(struct ath11k_base *soc, len = min_t(u16, len, sizeof(struct wmi_mac_phy_capabilities)); if (!svc_rdy_ext->n_mac_phy_caps) { - svc_rdy_ext->mac_phy_caps = kzalloc((svc_rdy_ext->tot_phy_id) * len, - GFP_ATOMIC); + svc_rdy_ext->mac_phy_caps = kcalloc(svc_rdy_ext->tot_phy_id, + len, GFP_ATOMIC); if (!svc_rdy_ext->mac_phy_caps) return -ENOMEM; } @@ -4447,8 +4468,8 @@ static struct cur_reg_rule struct cur_reg_rule *reg_rule_ptr; u32 count; - reg_rule_ptr = kzalloc((num_reg_rules * sizeof(*reg_rule_ptr)), - GFP_ATOMIC); + reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), + GFP_ATOMIC); if (!reg_rule_ptr) return NULL; @@ -5234,9 +5255,11 @@ ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src, dst->hw_queued = src->hw_queued; dst->hw_reaped = src->hw_reaped; dst->underrun = src->underrun; + dst->hw_paused = src->hw_paused; dst->tx_abort = src->tx_abort; dst->mpdus_requeued = src->mpdus_requeued; dst->tx_ko = src->tx_ko; + dst->tx_xretry = src->tx_xretry; dst->data_rc = src->data_rc; dst->self_triggers = src->self_triggers; dst->sw_retry_failure = src->sw_retry_failure; @@ -5247,6 +5270,16 @@ ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src, dst->stateless_tid_alloc_failure = src->stateless_tid_alloc_failure; dst->phy_underrun = src->phy_underrun; dst->txop_ovf = src->txop_ovf; + dst->seq_posted = src->seq_posted; + dst->seq_failed_queueing = src->seq_failed_queueing; + dst->seq_completed = src->seq_completed; + dst->seq_restarted = src->seq_restarted; + dst->mu_seq_posted = src->mu_seq_posted; + dst->mpdus_sw_flush = src->mpdus_sw_flush; + dst->mpdus_hw_filter = src->mpdus_hw_filter; + dst->mpdus_truncated = src->mpdus_truncated; + dst->mpdus_ack_failed = src->mpdus_ack_failed; + dst->mpdus_expired = src->mpdus_expired; } static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src, @@ -5266,6 +5299,7 @@ static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src, dst->phy_errs = src->phy_errs; dst->phy_err_drop = src->phy_err_drop; dst->mpdu_errs = src->mpdu_errs; + dst->rx_ovfl_errs = src->rx_ovfl_errs; } static void @@ -5503,11 +5537,15 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev, len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "Num underruns", pdev->underrun); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", + "Num HW Paused", pdev->hw_paused); + len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "PPDUs cleaned", pdev->tx_abort); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "MPDUs requeued", pdev->mpdus_requeued); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "Excessive retries", pdev->tx_ko); + "PPDU OK", pdev->tx_ko); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Excessive retries", pdev->tx_xretry); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", "HW rate", pdev->data_rc); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", @@ -5531,6 +5569,26 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev *pdev, "PHY underrun", pdev->phy_underrun); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", "MPDU is more than txop limit", pdev->txop_ovf); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num sequences posted", pdev->seq_posted); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num seq failed queueing ", pdev->seq_failed_queueing); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num sequences completed ", pdev->seq_completed); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num sequences restarted ", pdev->seq_restarted); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MU sequences posted ", pdev->mu_seq_posted); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MPDUS SW flushed ", pdev->mpdus_sw_flush); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MPDUS HW filtered ", pdev->mpdus_hw_filter); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MPDUS truncated ", pdev->mpdus_truncated); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MPDUS ACK failed ", pdev->mpdus_ack_failed); + len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", + "Num of MPDUS expired ", pdev->mpdus_expired); *length = len; } @@ -5575,6 +5633,8 @@ ath11k_wmi_fw_pdev_rx_stats_fill(const struct ath11k_fw_stats_pdev *pdev, "PHY errors drops", pdev->phy_err_drop); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); + len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", + "Overflow errors", pdev->rx_ovfl_errs); *length = len; } @@ -5792,6 +5852,17 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk pdev_idx = reg_info->phy_id; + /* Avoid default reg rule updates sent during FW recovery if + * it is already available + */ + spin_lock(&ab->base_lock); + if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) && + ab->default_regd[pdev_idx]) { + spin_unlock(&ab->base_lock); + goto mem_free; + } + spin_unlock(&ab->base_lock); + if (pdev_idx >= ab->num_radios) { /* Process the event for phy0 only if single_pdev_only * is true. If pdev_idx is valid but not 0, discard the @@ -5829,10 +5900,10 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk } spin_lock(&ab->base_lock); - if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { - /* Once mac is registered, ar is valid and all CC events from - * fw is considered to be received due to user requests - * currently. + if (ab->default_regd[pdev_idx]) { + /* The initial rules from FW after WMI Init is to build + * the default regd. From then on, any rules updated for + * the pdev could be due to user reg changes. * Free previously built regd before assigning the newly * generated regd to ar. NULL pointer handling will be * taken care by kfree itself. @@ -5842,13 +5913,9 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk ab->new_regd[pdev_idx] = regd; ieee80211_queue_work(ar->hw, &ar->regd_update_work); } else { - /* Multiple events for the same *ar is not expected. But we - * can still clear any previously stored default_regd if we - * are receiving this event for the same radio by mistake. - * NULL pointer handling will be taken care by kfree itself. + /* This regd would be applied during mac registration and is + * held constant throughout for regd intersection purpose */ - kfree(ab->default_regd[pdev_idx]); - /* This regd would be applied during mac registration */ ab->default_regd[pdev_idx] = regd; } ab->dfs_region = reg_info->dfs_region; @@ -6119,8 +6186,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) if (rx_ev.status & WMI_RX_STATUS_ERR_MIC) status->flag |= RX_FLAG_MMIC_ERROR; - if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) { + if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ && + rx_ev.chan_freq <= ATH11K_MAX_6G_FREQ) { status->band = NL80211_BAND_6GHZ; + status->freq = rx_ev.chan_freq; } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { status->band = NL80211_BAND_2GHZ; } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) { @@ -6141,8 +6210,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) sband = &ar->mac.sbands[status->band]; - status->freq = ieee80211_channel_to_frequency(rx_ev.channel, - status->band); + if (status->band != NL80211_BAND_6GHZ) + status->freq = ieee80211_channel_to_frequency(rx_ev.channel, + status->band); + status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR; status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100); @@ -6220,8 +6291,9 @@ exit: rcu_read_unlock(); } -static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab, - u32 vdev_id) +static struct ath11k *ath11k_get_ar_on_scan_state(struct ath11k_base *ab, + u32 vdev_id, + enum ath11k_scan_state state) { int i; struct ath11k_pdev *pdev; @@ -6233,7 +6305,7 @@ static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab, ar = pdev->ar; spin_lock_bh(&ar->data_lock); - if (ar->scan.state == ATH11K_SCAN_ABORTING && + if (ar->scan.state == state && ar->scan.vdev_id == vdev_id) { spin_unlock_bh(&ar->data_lock); return ar; @@ -6263,10 +6335,15 @@ static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb) * aborting scan's vdev id matches this event info. */ if (scan_ev.event_type == WMI_SCAN_EVENT_COMPLETED && - scan_ev.reason == WMI_SCAN_REASON_CANCELLED) - ar = ath11k_get_ar_on_scan_abort(ab, scan_ev.vdev_id); - else + scan_ev.reason == WMI_SCAN_REASON_CANCELLED) { + ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id, + ATH11K_SCAN_ABORTING); + if (!ar) + ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id, + ATH11K_SCAN_RUNNING); + } else { ar = ath11k_mac_get_ar_by_vdev_id(ab, scan_ev.vdev_id); + } if (!ar) { ath11k_warn(ab, "Received scan event for unknown vdev"); @@ -6301,6 +6378,8 @@ static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb) ath11k_wmi_event_scan_start_failed(ar); break; case WMI_SCAN_EVENT_DEQUEUED: + __ath11k_mac_scan_finish(ar); + break; case WMI_SCAN_EVENT_PREEMPTED: case WMI_SCAN_EVENT_RESTARTED: case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT: @@ -7065,6 +7144,7 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_TWT_ENABLE_EVENTID: case WMI_TWT_DISABLE_EVENTID: case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID: + case WMI_PEER_CREATE_CONF_EVENTID: ath11k_dbg(ab, ATH11K_DBG_WMI, "ignoring unsupported event 0x%x\n", id); break; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index d35c47e0b19d..0584e68e7593 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -119,6 +119,22 @@ enum { WMI_HOST_WLAN_2G_5G_CAP = 0x3, }; +/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command. + * Used only for HE auto rate mode. + */ +enum { + /* HE LTF related configuration */ + WMI_HE_AUTORATE_LTF_1X = BIT(0), + WMI_HE_AUTORATE_LTF_2X = BIT(1), + WMI_HE_AUTORATE_LTF_4X = BIT(2), + + /* HE GI related configuration */ + WMI_AUTORATE_400NS_GI = BIT(8), + WMI_AUTORATE_800NS_GI = BIT(9), + WMI_AUTORATE_1600NS_GI = BIT(10), + WMI_AUTORATE_3200NS_GI = BIT(11), +}; + /* * wmi command groups. */ @@ -647,6 +663,9 @@ enum wmi_tlv_event_id { WMI_PEER_RESERVED9_EVENTID, WMI_PEER_RESERVED10_EVENTID, WMI_PEER_OPER_MODE_CHANGE_EVENTID, + WMI_PEER_TX_PN_RESPONSE_EVENTID, + WMI_PEER_CFR_CAPTURE_EVENTID, + WMI_PEER_CREATE_CONF_EVENTID, WMI_MGMT_RX_EVENTID = WMI_TLV_CMD(WMI_GRP_MGMT), WMI_HOST_SWBA_EVENTID, WMI_TBTTOFFSET_UPDATE_EVENTID, @@ -1044,7 +1063,9 @@ enum wmi_tlv_vdev_param { WMI_VDEV_PARAM_HE_RANGE_EXT, WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, + WMI_VDEV_PARAM_HE_LTF = 0x74, WMI_VDEV_PARAM_BA_MODE = 0x7e, + WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80, WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99, WMI_VDEV_PARAM_PROTOTYPE = 0x8000, @@ -2128,6 +2149,24 @@ enum wmi_direct_buffer_module { WMI_DIRECT_BUF_MAX }; +/* enum wmi_nss_ratio - NSS ratio received from FW during service ready ext + * event + * WMI_NSS_RATIO_1BY2_NSS -Max nss of 160MHz is equals to half of the max nss + * of 80MHz + * WMI_NSS_RATIO_3BY4_NSS - Max nss of 160MHz is equals to 3/4 of the max nss + * of 80MHz + * WMI_NSS_RATIO_1_NSS - Max nss of 160MHz is equals to the max nss of 80MHz + * WMI_NSS_RATIO_2_NSS - Max nss of 160MHz is equals to two times the max + * nss of 80MHz + */ + +enum wmi_nss_ratio { + WMI_NSS_RATIO_1BY2_NSS = 0x0, + WMI_NSS_RATIO_3BY4_NSS = 0x1, + WMI_NSS_RATIO_1_NSS = 0x2, + WMI_NSS_RATIO_2_NSS = 0x3, +}; + struct wmi_host_pdev_band_to_mac { u32 pdev_id; u32 start_freq; @@ -2244,6 +2283,8 @@ struct wmi_init_cmd { u32 num_host_mem_chunks; } __packed; +#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) + struct wmi_resource_config { u32 tlv_header; u32 num_vdevs; @@ -2370,6 +2411,12 @@ struct wmi_hw_mode_capabilities { } __packed; #define WMI_MAX_HECAP_PHY_SIZE (3) +#define WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS BIT(0) +#define WMI_NSS_RATIO_ENABLE_DISABLE_GET(_val) \ + FIELD_GET(WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS, _val) +#define WMI_NSS_RATIO_INFO_BITPOS GENMASK(4, 1) +#define WMI_NSS_RATIO_INFO_GET(_val) \ + FIELD_GET(WMI_NSS_RATIO_INFO_BITPOS, _val) struct wmi_mac_phy_capabilities { u32 hw_mode_id; @@ -2403,6 +2450,12 @@ struct wmi_mac_phy_capabilities { u32 he_cap_info_2g_ext; u32 he_cap_info_5g_ext; u32 he_cap_info_internal; + u32 wireless_modes; + u32 low_2ghz_chan_freq; + u32 high_2ghz_chan_freq; + u32 low_5ghz_chan_freq; + u32 high_5ghz_chan_freq; + u32 nss_ratio; } __packed; struct wmi_hal_reg_capabilities_ext { @@ -2527,6 +2580,7 @@ struct wmi_vdev_down_cmd { #define WMI_VDEV_START_HIDDEN_SSID BIT(0) #define WMI_VDEV_START_PMF_ENABLED BIT(1) #define WMI_VDEV_START_LDPC_RX_ENABLED BIT(3) +#define WMI_VDEV_START_HW_ENCRYPTION_DISABLED BIT(4) struct wmi_ssid { u32 ssid_len; @@ -2960,6 +3014,7 @@ struct wmi_pdev_bss_chan_info_req_cmd { u32 tlv_header; /* ref wmi_bss_chan_info_req_type */ u32 req_type; + u32 pdev_id; } __packed; struct wmi_ap_ps_peer_cmd { @@ -3608,7 +3663,7 @@ struct wmi_stop_scan_cmd { struct scan_chan_list_params { u32 pdev_id; u16 nallchans; - struct channel_param ch_param[1]; + struct channel_param ch_param[]; }; struct wmi_scan_chan_list_cmd { @@ -3917,7 +3972,11 @@ struct wmi_vht_rate_set { struct wmi_he_rate_set { u32 tlv_header; + + /* MCS at which the peer can receive */ u32 rx_mcs_set; + + /* MCS at which the peer can transmit */ u32 tx_mcs_set; } __packed; @@ -4056,7 +4115,6 @@ struct wmi_vdev_stopped_event { } __packed; struct wmi_pdev_bss_chan_info_event { - u32 pdev_id; u32 freq; /* Units in MHz */ u32 noise_floor; /* units are dBm */ /* rx clear - how often the channel was unused */ @@ -4074,6 +4132,7 @@ struct wmi_pdev_bss_chan_info_event { /*rx_cycle cnt for my bss in 64bits format */ u32 rx_bss_cycle_count_low; u32 rx_bss_cycle_count_high; + u32 pdev_id; } __packed; #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 @@ -4168,6 +4227,9 @@ struct wmi_pdev_stats_tx { /* Num underruns */ s32 underrun; + /* Num hw paused */ + u32 hw_paused; + /* Num PPDUs cleaned up in TX abort */ s32 tx_abort; @@ -4177,6 +4239,8 @@ struct wmi_pdev_stats_tx { /* excessive retries */ u32 tx_ko; + u32 tx_xretry; + /* data hw rate code */ u32 data_rc; @@ -4206,6 +4270,40 @@ struct wmi_pdev_stats_tx { /* MPDU is more than txop limit */ u32 txop_ovf; + + /* Num sequences posted */ + u32 seq_posted; + + /* Num sequences failed in queueing */ + u32 seq_failed_queueing; + + /* Num sequences completed */ + u32 seq_completed; + + /* Num sequences restarted */ + u32 seq_restarted; + + /* Num of MU sequences posted */ + u32 mu_seq_posted; + + /* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT + * (Reset,channel change) + */ + s32 mpdus_sw_flush; + + /* Num MPDUs filtered by HW, all filter condition (TTL expired) */ + s32 mpdus_hw_filter; + + /* Num MPDUs truncated by PDG (TXOP, TBTT, + * PPDU_duration based on rate, dyn_bw) + */ + s32 mpdus_truncated; + + /* Num MPDUs that was tried but didn't receive ACK or BA */ + s32 mpdus_ack_failed; + + /* Num MPDUs that was dropped du to expiry. */ + s32 mpdus_expired; } __packed; struct wmi_pdev_stats_rx { @@ -4240,6 +4338,9 @@ struct wmi_pdev_stats_rx { /* Number of mpdu errors - FCS, MIC, ENC etc. */ s32 mpdu_errs; + + /* Num overflow errors */ + s32 rx_ovfl_errs; } __packed; struct wmi_pdev_stats { @@ -5014,7 +5115,7 @@ struct target_resource_config { u32 vo_minfree; u32 rx_batchmode; u32 tt_support; - u32 atf_config; + u32 flag1; u32 iphdr_pad_config; u32 qwrap_config:16, alloc_frag_desc_for_data_pkt:16; |