diff options
author | David S. Miller <davem@davemloft.net> | 2021-10-07 13:42:40 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-10-07 13:42:40 +0100 |
commit | 44cc24b04bed578e32a4334cacf95799335b3274 (patch) | |
tree | 9dd2349702c3046ebcd7f36ff20cdd5fbde9d6f1 /drivers/net/wireless/ath | |
parent | 5a98dcf59abf68a7949bf1ff95765b946c1a4595 (diff) | |
parent | b3fcf9c5faaa2b09544f2cdd1eaae81c7a822f92 (diff) | |
download | linux-44cc24b04bed578e32a4334cacf95799335b3274.tar.bz2 |
Merge tag 'wireless-drivers-next-2021-10-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
wireless-drivers-next patches for v5.16
First set of patches for v5.16. ath11k getting most of new features
this time. Other drivers also have few new features, and of course the
usual set of fixes and cleanups all over.
Major changes:
rtw88
* support adaptivity for ETSI/JP DFS region
* 8821c: support RFE type4 wifi NIC
brcmfmac
* DMI nvram filename quirk for Cyberbook T116 tablet
ath9k
* load calibration data and pci init values via nvmem subsystem
ath11k
* include channel rx and tx time in survey dump statistics
* support for setting fixed Wi-Fi 6 rates from user space
* support for 80P80 and 160 MHz bandwidths
* spectral scan support for QCN9074
* support for calibration data files per radio
* support for calibration data via eeprom
* support for rx decapsulation offload (data frames in 802.3 format)
* support channel 2 in 6 GHz band
ath10k
* include frame time stamp in beacon and probe response frames
wcn36xx
* enable Idle Mode Power Save (IMPS) to reduce power consumption during idle
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath')
41 files changed, 4897 insertions, 2670 deletions
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 49cc4b7ed516..0e9bad33fac8 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1772,9 +1772,8 @@ static const struct usb_device_id ar5523_id_table[] = { AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */ AR5523_DEVICE_UG(0x083a, 0x4506), /* SMC / EZ Connect SMCWUSBT-G2 */ - AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1 */ + AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1, TEW444UBEU*/ AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */ - AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / TEW444UBEU */ AR5523_DEVICE_UG(0x1435, 0x0826), /* Wistronneweb / AR5523_1 */ AR5523_DEVICE_UX(0x1435, 0x0828), /* Wistronneweb / AR5523_2 */ AR5523_DEVICE_UG(0x0cde, 0x0012), /* Zcom / AR5523 */ diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c272b290fa73..7ca68c81d9b6 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -993,8 +993,12 @@ static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif) ath10k_mac_vif_beacon_free(arvif); if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; } } @@ -5576,10 +5580,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_ADHOC || vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_AP) { - arvif->beacon_buf = dma_alloc_coherent(ar->dev, - IEEE80211_MAX_FRAME_LEN, - &arvif->beacon_paddr, - GFP_ATOMIC); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { + arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN, + GFP_KERNEL); + arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf; + } else { + arvif->beacon_buf = + dma_alloc_coherent(ar->dev, + IEEE80211_MAX_FRAME_LEN, + &arvif->beacon_paddr, + GFP_ATOMIC); + } if (!arvif->beacon_buf) { ret = -ENOMEM; ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", @@ -5794,8 +5805,12 @@ err_vdev_delete: err: if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; } diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index b746052737e0..eb705214f3f0 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -1363,8 +1363,11 @@ static void ath10k_rx_indication_async_work(struct work_struct *work) ep->ep_ops.ep_rx_complete(ar, skb); } - if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) { + local_bh_disable(); napi_schedule(&ar->napi); + local_bh_enable(); + } } static int ath10k_sdio_read_rtc_state(struct ath10k_sdio *ar_sdio, unsigned char *state) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b8a4bbfe10b8..7c1c2658cb5f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2610,6 +2610,10 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) if (ieee80211_is_beacon(hdr->frame_control)) ath10k_mac_handle_beacon(ar, skb); + if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) + status->boottime_ns = ktime_get_boottime_ns(); + ath10k_dbg(ar, ATH10K_DBG_MGMT, "event mgmt rx skb %pK len %d ftype %02x stype %02x\n", skb, skb->len, diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 969bf1a590d9..2328e594a96a 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, @@ -59,7 +59,17 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .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) | @@ -78,7 +88,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, @@ -100,7 +110,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .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) | @@ -119,7 +136,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, @@ -141,7 +158,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .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), @@ -159,7 +183,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, @@ -180,6 +204,15 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .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), @@ -197,7 +230,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, @@ -219,7 +252,14 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .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), 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..17f0bbbac7ae 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -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.h b/drivers/net/wireless/ath/ath11k/dp.h index ee768ccce46e..d6267bfa0264 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -195,6 +195,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 +1593,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..75f6d55dca46 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); @@ -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) { @@ -2969,6 +3051,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 +3065,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 +3102,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 +3402,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; @@ -3375,7 +3467,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; } @@ -3941,7 +4033,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 +4052,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, @@ -4848,7 +4936,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 +4962,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; @@ -5029,7 +5114,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..70d2cf010a68 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; @@ -145,7 +145,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) { @@ -614,6 +622,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 +1079,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/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index d9596903b0a5..7a343db1dde8 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -97,6 +97,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 +198,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 +374,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 +556,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 +727,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 +834,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 +872,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 +910,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 +948,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 +986,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 diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 62f5978b3005..1535075eed03 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -128,7 +128,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; @@ -153,7 +153,14 @@ struct ath11k_hw_params { 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; @@ -202,6 +209,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; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e9b3689331ec..31f0cfba5bf5 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 = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS, + le16_to_cpu(sta->he_6ghz_capa.capa)); + } 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); @@ -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 incompaitiblity\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..7b3bce0ba76e 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) 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..8c615bc788ca 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,61 @@ 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 = bd.len; + 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 +2574,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 +2759,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..2d0acfb748cf 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) / @@ -3495,7 +3514,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; @@ -5234,9 +5253,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 +5268,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 +5297,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 +5535,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 +5567,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 +5631,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 +5850,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 +5898,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 +5911,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 +6184,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 +6208,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 +6289,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 +6303,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 +6333,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 +6376,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 +7142,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; diff --git a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c index 56d1a7764b9f..708c8969b503 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c +++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c @@ -19,9 +19,14 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/ath9k_platform.h> +#include <linux/nvmem-consumer.h> +#include <linux/workqueue.h> struct owl_ctx { + struct pci_dev *pdev; struct completion eeprom_load; + struct work_struct work; + struct nvmem_cell *cell; }; #define EEPROM_FILENAME_LEN 100 @@ -42,6 +47,12 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data, u32 bar0; bool swap_needed = false; + /* also note that we are doing *u16 operations on the file */ + if (cal_len > 4096 || cal_len < 0x200 || (cal_len & 1) == 1) { + dev_err(&pdev->dev, "eeprom has an invalid size.\n"); + return -EINVAL; + } + if (*cal_data != AR5416_EEPROM_MAGIC) { if (*cal_data != swab16(AR5416_EEPROM_MAGIC)) { dev_err(&pdev->dev, "invalid calibration data\n"); @@ -99,38 +110,31 @@ static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data, return 0; } -static void owl_fw_cb(const struct firmware *fw, void *context) +static void owl_rescan(struct pci_dev *pdev) { - struct pci_dev *pdev = (struct pci_dev *)context; - struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev); - struct pci_bus *bus; - - complete(&ctx->eeprom_load); - - if (!fw) { - dev_err(&pdev->dev, "no eeprom data received.\n"); - goto release; - } - - /* also note that we are doing *u16 operations on the file */ - if (fw->size > 4096 || fw->size < 0x200 || (fw->size & 1) == 1) { - dev_err(&pdev->dev, "eeprom file has an invalid size.\n"); - goto release; - } - - if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size)) - goto release; + struct pci_bus *bus = pdev->bus; pci_lock_rescan_remove(); - bus = pdev->bus; pci_stop_and_remove_bus_device(pdev); /* the device should come back with the proper * ProductId. But we have to initiate a rescan. */ pci_rescan_bus(bus); pci_unlock_rescan_remove(); +} + +static void owl_fw_cb(const struct firmware *fw, void *context) +{ + struct owl_ctx *ctx = (struct owl_ctx *)context; + + complete(&ctx->eeprom_load); -release: + if (fw) { + ath9k_pci_fixup(ctx->pdev, (const u16 *)fw->data, fw->size); + owl_rescan(ctx->pdev); + } else { + dev_err(&ctx->pdev->dev, "no eeprom data received.\n"); + } release_firmware(fw); } @@ -152,6 +156,43 @@ static const char *owl_get_eeprom_name(struct pci_dev *pdev) return eeprom_name; } +static void owl_nvmem_work(struct work_struct *work) +{ + struct owl_ctx *ctx = container_of(work, struct owl_ctx, work); + void *buf; + size_t len; + + complete(&ctx->eeprom_load); + + buf = nvmem_cell_read(ctx->cell, &len); + if (!IS_ERR(buf)) { + ath9k_pci_fixup(ctx->pdev, buf, len); + kfree(buf); + owl_rescan(ctx->pdev); + } else { + dev_err(&ctx->pdev->dev, "no nvmem data received.\n"); + } +} + +static int owl_nvmem_probe(struct owl_ctx *ctx) +{ + int err; + + ctx->cell = devm_nvmem_cell_get(&ctx->pdev->dev, "calibration"); + if (IS_ERR(ctx->cell)) { + err = PTR_ERR(ctx->cell); + if (err == -ENOENT || err == -EOPNOTSUPP) + return 1; /* not present, try firmware_request */ + + return err; + } + + INIT_WORK(&ctx->work, owl_nvmem_work); + schedule_work(&ctx->work); + + return 0; +} + static int owl_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -164,21 +205,27 @@ static int owl_probe(struct pci_dev *pdev, pcim_pin_device(pdev); - eeprom_name = owl_get_eeprom_name(pdev); - if (!eeprom_name) { - dev_err(&pdev->dev, "no eeprom filename found.\n"); - return -ENODEV; - } - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; init_completion(&ctx->eeprom_load); + ctx->pdev = pdev; pci_set_drvdata(pdev, ctx); + + err = owl_nvmem_probe(ctx); + if (err <= 0) + return err; + + eeprom_name = owl_get_eeprom_name(pdev); + if (!eeprom_name) { + dev_err(&pdev->dev, "no eeprom filename found.\n"); + return -ENODEV; + } + err = request_firmware_nowait(THIS_MODULE, true, eeprom_name, - &pdev->dev, GFP_KERNEL, pdev, owl_fw_cb); + &pdev->dev, GFP_KERNEL, ctx, owl_fw_cb); if (err) dev_err(&pdev->dev, "failed to request caldata (%d).\n", err); diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index c22d457dbc54..e6b3cd49ea18 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -135,13 +135,23 @@ static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob, offset, data); } +static bool ath9k_hw_nvram_read_nvmem(struct ath_hw *ah, off_t offset, + u16 *data) +{ + return ath9k_hw_nvram_read_array(ah->nvmem_blob, + ah->nvmem_blob_len / sizeof(u16), + offset, data); +} + bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_platform_data *pdata = ah->dev->platform_data; bool ret; - if (ah->eeprom_blob) + if (ah->nvmem_blob) + ret = ath9k_hw_nvram_read_nvmem(ah, off, data); + else if (ah->eeprom_blob) ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data); else if (pdata && !pdata->use_eeprom) ret = ath9k_hw_nvram_read_pdata(pdata, off, data); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b7b65b1c90e8..096a206f49ed 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -977,6 +977,8 @@ struct ath_hw { bool disable_5ghz; const struct firmware *eeprom_blob; + u16 *nvmem_blob; /* devres managed */ + size_t nvmem_blob_len; struct ath_dynack dynack; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e9a36dd7144f..1568730fc01e 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_net.h> +#include <linux/nvmem-consumer.h> #include <linux/relay.h> #include <linux/dmi.h> #include <net/ieee80211_radiotap.h> @@ -568,6 +569,57 @@ static void ath9k_eeprom_release(struct ath_softc *sc) release_firmware(sc->sc_ah->eeprom_blob); } +static int ath9k_nvmem_request_eeprom(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct nvmem_cell *cell; + void *buf; + size_t len; + int err; + + cell = devm_nvmem_cell_get(sc->dev, "calibration"); + if (IS_ERR(cell)) { + err = PTR_ERR(cell); + + /* nvmem cell might not be defined, or the nvmem + * subsystem isn't included. In this case, follow + * the established "just return 0;" convention of + * ath9k_init_platform to say: + * "All good. Nothing to see here. Please go on." + */ + if (err == -ENOENT || err == -EOPNOTSUPP) + return 0; + + return err; + } + + buf = nvmem_cell_read(cell, &len); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + /* run basic sanity checks on the returned nvram cell length. + * That length has to be a multiple of a "u16" (i.e.: & 1). + * Furthermore, it has to be more than "let's say" 512 bytes + * but less than the maximum of AR9300_EEPROM_SIZE (16kb). + */ + if ((len & 1) == 1 || len < 512 || len >= AR9300_EEPROM_SIZE) { + kfree(buf); + return -EINVAL; + } + + /* devres manages the calibration values release on shutdown */ + ah->nvmem_blob = (u16 *)devm_kmemdup(sc->dev, buf, len, GFP_KERNEL); + kfree(buf); + if (IS_ERR(ah->nvmem_blob)) + return PTR_ERR(ah->nvmem_blob); + + ah->nvmem_blob_len = len; + ah->ah_flags &= ~AH_USE_EEPROM; + ah->ah_flags |= AH_NO_EEP_SWAP; + + return 0; +} + static int ath9k_init_platform(struct ath_softc *sc) { struct ath9k_platform_data *pdata = sc->dev->platform_data; @@ -704,6 +756,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, if (ret) return ret; + ret = ath9k_nvmem_request_eeprom(sc); + if (ret) + return ret; + if (ath9k_led_active_high != -1) ah->config.led_active_high = ath9k_led_active_high == 1; diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h index 9c2e5458e425..e14f374f97d4 100644 --- a/drivers/net/wireless/ath/spectral_common.h +++ b/drivers/net/wireless/ath/spectral_common.h @@ -24,7 +24,6 @@ * could be acquired so far. */ #define SPECTRAL_ATH10K_MAX_NUM_BINS 256 -#define SPECTRAL_ATH11K_MAX_NUM_BINS 512 /* FFT sample format given to userspace via debugfs. * diff --git a/drivers/net/wireless/ath/wcn36xx/debug.c b/drivers/net/wireless/ath/wcn36xx/debug.c index 389b5e7129a6..6af306ae41ad 100644 --- a/drivers/net/wireless/ath/wcn36xx/debug.c +++ b/drivers/net/wireless/ath/wcn36xx/debug.c @@ -120,7 +120,7 @@ static ssize_t write_file_dump(struct file *file, if (begin == NULL) break; - if (kstrtou32(begin, 0, &arg[i]) != 0) + if (kstrtos32(begin, 0, &arg[i]) != 0) break; } diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 455143c4164e..5f1f2480459a 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -3384,11 +3384,11 @@ struct tl_hal_flush_ac_rsp_msg { struct wcn36xx_hal_enter_imps_req_msg { struct wcn36xx_hal_msg_header header; -}; +} __packed; -struct wcn36xx_hal_exit_imps_req { +struct wcn36xx_hal_exit_imps_req_msg { struct wcn36xx_hal_msg_header header; -}; +} __packed; struct wcn36xx_hal_enter_bmps_req_msg { struct wcn36xx_hal_msg_header header; diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index ec913ec991f3..263af65a889a 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -432,6 +432,13 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS); + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + if (hw->conf.flags & IEEE80211_CONF_IDLE) + wcn36xx_smd_enter_imps(wcn); + else + wcn36xx_smd_exit_imps(wcn); + } + mutex_unlock(&wcn->conf_mutex); return 0; @@ -569,12 +576,14 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) { sta_priv->is_data_encrypted = true; /* Reconfigure bss with encrypt_type */ - if (NL80211_IFTYPE_STATION == vif->type) + if (NL80211_IFTYPE_STATION == vif->type) { wcn36xx_smd_config_bss(wcn, vif, sta, sta->addr, true); + wcn36xx_smd_config_sta(wcn, vif, sta); + } wcn36xx_smd_set_stakey(wcn, vif_priv->encrypt_type, diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 57fa857b290b..3979171c92dd 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2184,6 +2184,59 @@ out: return ret; } +int wcn36xx_smd_enter_imps(struct wcn36xx *wcn) +{ + struct wcn36xx_hal_enter_imps_req_msg msg_body; + int ret; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_ENTER_IMPS_REQ); + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_enter_imps failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_enter_imps response failed err=%d\n", ret); + goto out; + } + + wcn36xx_dbg(WCN36XX_DBG_HAL, "Entered idle mode\n"); +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + +int wcn36xx_smd_exit_imps(struct wcn36xx *wcn) +{ + struct wcn36xx_hal_exit_imps_req_msg msg_body; + int ret; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_EXIT_IMPS_REQ); + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_exit_imps failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_exit_imps response failed err=%d\n", ret); + goto out; + } + wcn36xx_dbg(WCN36XX_DBG_HAL, "Exited idle mode\n"); +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + int wcn36xx_smd_set_power_params(struct wcn36xx *wcn, bool ignore_dtim) { struct wcn36xx_hal_set_power_params_req_msg msg_body; @@ -2623,30 +2676,52 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn, size_t len) { struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; - struct wcn36xx_vif *tmp; + struct wcn36xx_vif *vif_priv; + struct ieee80211_vif *vif; + struct ieee80211_bss_conf *bss_conf; struct ieee80211_sta *sta; + bool found = false; if (len != sizeof(*rsp)) { wcn36xx_warn("Corrupted delete sta indication\n"); return -EIO; } - wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n", - rsp->addr2, rsp->sta_id); + wcn36xx_dbg(WCN36XX_DBG_HAL, + "delete station indication %pM index %d reason %d\n", + rsp->addr2, rsp->sta_id, rsp->reason_code); - list_for_each_entry(tmp, &wcn->vif_list, list) { + list_for_each_entry(vif_priv, &wcn->vif_list, list) { rcu_read_lock(); - sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2); - if (sta) - ieee80211_report_low_ack(sta, 0); + vif = wcn36xx_priv_to_vif(vif_priv); + + if (vif->type == NL80211_IFTYPE_STATION) { + /* We could call ieee80211_find_sta too, but checking + * bss_conf is clearer. + */ + bss_conf = &vif->bss_conf; + if (vif_priv->sta_assoc && + !memcmp(bss_conf->bssid, rsp->addr2, ETH_ALEN)) { + found = true; + wcn36xx_dbg(WCN36XX_DBG_HAL, + "connection loss bss_index %d\n", + vif_priv->bss_index); + ieee80211_connection_loss(vif); + } + } else { + sta = ieee80211_find_sta(vif, rsp->addr2); + if (sta) { + found = true; + ieee80211_report_low_ack(sta, 0); + } + } + rcu_read_unlock(); - if (sta) + if (found) return 0; } - wcn36xx_warn("STA with addr %pM and index %d not found\n", - rsp->addr2, - rsp->sta_id); + wcn36xx_warn("BSS or STA with addr %pM not found\n", rsp->addr2); return -ENOENT; } @@ -3060,6 +3135,8 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_GTK_OFFLOAD_RSP: case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP: case WCN36XX_HAL_HOST_RESUME_RSP: + case WCN36XX_HAL_ENTER_IMPS_RSP: + case WCN36XX_HAL_EXIT_IMPS_RSP: memcpy(wcn->hal_buf, buf, len); wcn->hal_rsp_len = len; complete(&wcn->hal_rsp_compl); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index d8bded03945d..5f98c1d01ae4 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -163,4 +163,7 @@ int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn); int wcn36xx_smd_host_resume(struct wcn36xx *wcn); +int wcn36xx_smd_enter_imps(struct wcn36xx *wcn); +int wcn36xx_smd_exit_imps(struct wcn36xx *wcn); + #endif /* _SMD_H_ */ |