diff options
| author | Zhang Qian <zhangq@codeaurora.org> | 2019-04-11 16:32:12 +0800 |
|---|---|---|
| committer | Zhang Qian <zhangq@codeaurora.org> | 2019-04-24 13:43:03 +0800 |
| commit | 91fa1989060fac657ed782bfd168ba09f039fb7a (patch) | |
| tree | 14f249407271c27fa2cb208f4a4851dc8a93db60 | |
| parent | 11fdab25545b45ce9977d5d49618eaa7f93098ae (diff) | |
qcacld-2.0: Add RX stats indication to SA
Add RX stats indication to SA
Change-Id: I15badd684577a7ff6e7dcb3401e5e57ee63d1ca1
CRs-Fixed: 2407824
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_t2h.c | 29 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_rx.c | 139 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_htt_rx_api.h | 17 | ||||
| -rw-r--r-- | CORE/SERVICES/SA/smart_antenna_apis.h | 89 |
4 files changed, 251 insertions, 23 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index d6110c366db8..02b8b6a8e1f2 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1123,6 +1123,28 @@ htt_rx_ind_noise_floor_chain(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, return noise_floor; } +int htt_rx_ind_sig(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, + uint32_t *sig_a1, uint32_t *sig_a2, uint8_t *type) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) + (adf_nbuf_data(rx_ind_msg) + HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET); + + /* check if the RX_IND message contains valid rx PPDU start info */ + if (!HTT_RX_IND_START_VALID_GET(*msg_word)) { + *sig_a1 = -1; + *sig_a2 = -1; + *type = -1; + return -1; + } + + *sig_a1 = *(msg_word + 7); + *sig_a2 = *(msg_word + 8); + *type = HTT_RX_IND_PREAMBLE_TYPE_GET(*sig_a1); + return 0; +} + /** * htt_rx_ind_legacy_rate() - Return the data rate * @pdev: the HTT instance the rx data was received on @@ -1153,7 +1175,7 @@ htt_rx_ind_noise_floor_chain(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, * * Return the data rate provided in a rx indication message. */ -void +int htt_rx_ind_legacy_rate(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, uint8_t *legacy_rate, uint8_t *legacy_rate_sel) { @@ -1166,11 +1188,12 @@ htt_rx_ind_legacy_rate(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, if (!HTT_RX_IND_START_VALID_GET(*msg_word)) { *legacy_rate = -1; *legacy_rate_sel = -1; - return; + return -1; } *legacy_rate = HTT_RX_IND_LEGACY_RATE_GET(*msg_word); *legacy_rate_sel = HTT_RX_IND_LEGACY_RATE_SEL_GET(*msg_word); + return 0; } /** diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c index b6d2d5b219a2..fed172e93a5f 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -67,6 +67,8 @@ #include "vos_cnss.h" #endif +#include "if_smart_antenna.h" + #ifdef OSIF_NEED_RX_PEER_ID #define OL_RX_OSIF_DELIVER(vdev, peer, msdus) \ vdev->osif_rx(vdev->osif_dev, peer->local_id, msdus) @@ -338,6 +340,121 @@ ol_rx_mon_mac_header_handler( } } +#ifdef WLAN_SMART_ANTENNA_FEATURE +static inline void ol_fill_legacy_rate(uint8_t legacy_rate, + uint8_t legacy_rate_sel, + enum legacy_rate *rate) +{ + switch (legacy_rate) { + case 0x8: + *rate = legacy_rate_sel ? CCK_11M_LONG_PREAMBLE : OFDM_48M; + break; + case 0x9: + *rate = legacy_rate_sel ? CCK_5_5M_LONG_PREAMBLE : OFDM_24M; + break; + case 0xA: + *rate = legacy_rate_sel ? CCK_2M_LONG_PREAMBLE : OFDM_12M; + break; + case 0xB: + *rate = legacy_rate_sel ? CCK_1M_LONG_PREAMBLE : OFDM_6M; + break; + case 0xC: + *rate = legacy_rate_sel ? CCK_11M_SHORT_PREAMBLE : OFDM_54M; + break; + case 0xD: + *rate = legacy_rate_sel ? CCK_5_5M_SHORT_PREAMBLE : OFDM_36M; + break; + case 0xE: + *rate = legacy_rate_sel ? CCK_2M_SHORT_PREAMBLE : OFDM_18M; + break; + case 0xF: + *rate = OFDM_9M; + break; + default: + *rate = INVALID_LEGACY_RATE; + break; + } +} + +static void ol_pop_rx_stats(htt_pdev_handle htt_pdev, + adf_nbuf_t rx_ind_msg, + int pkt_num, + struct sa_rx_mpdu_stats *fb) +{ + uint8_t legacy_rate, legacy_rate_sel, preamble_type, subms; + uint32_t vht_sig1, vht_sig2, ms; + int i; + + if (!fb) + return; + + htt_rx_ind_sig(htt_pdev, rx_ind_msg, &vht_sig1, + &vht_sig2, &preamble_type); + fb->magic = (vht_sig2 & 0xff000000) >> 24; + if (preamble_type == 0x4) { + htt_rx_ind_legacy_rate(htt_pdev, rx_ind_msg, + &legacy_rate, &legacy_rate_sel); + fb->rate.type = LEGACY_RATE; + ol_fill_legacy_rate(legacy_rate, + legacy_rate_sel, &fb->rate.rate.legacy_rate); + } else if (preamble_type != -1) { + uint8_t bw = 0; + fb->rate.type = HT_VHT_RATE; + fb->rate.rate.mcs.mcs_index = vht_sig1 & 0x7f; + fb->rate.rate.mcs.nss = (vht_sig2 >> 8) &0x3; + bw |= ((vht_sig1 >> 7) & 0x1) ? + SMART_ANT_BW_40MHZ : SMART_ANT_BW_20MHZ; + if ((preamble_type == 0xC) || (preamble_type == 0xD)) + bw |= SMART_ANT_NODE_VHT; + else + bw |= SMART_ANT_NODE_HT; + fb->rate.rate.mcs.bw = bw; + } else { + /* Both legacy and VHT are invalid*/ + fb->rate.type = LEGACY_RATE; + fb->rate.rate.legacy_rate = INVALID_LEGACY_RATE; + } + fb->tid = htt_rx_ind_ext_tid(htt_pdev, rx_ind_msg); + fb->pkt_num = pkt_num; + for (i = 0; i < SA_MAX_CHAIN_NUM; i++) { + fb->rx_rssi[i] = htt_rx_ind_rssi_dbm_chain(htt_pdev, + rx_ind_msg, + i); + fb->rx_nf[i] = htt_rx_ind_noise_floor_chain(htt_pdev, + rx_ind_msg, + i); + } + htt_rx_ind_timestamp(htt_pdev, rx_ind_msg, &ms, &subms); + fb->timestamp_microsec = ms; + fb->timestamp_submicrosec = (uint32_t)subms; +} + +static struct sa_rx_stats_feedback *ol_rx_feedback_alloc(uint32_t mpdu_num) +{ + struct sa_rx_stats_feedback *fb; + fb = adf_os_mem_alloc(NULL, + sizeof(struct sa_rx_stats_feedback) + + mpdu_num * sizeof(struct sa_rx_mpdu_stats)); + + if (fb) + fb->mpdu_count = mpdu_num; + return fb; +} +#else +static inline void ol_pop_rx_stats(htt_pdev_handle htt_pdev, + adf_nbuf_t rx_ind_msg, + uint32_t pkt_num, + struct sa_rx_mpdu_stats *fb) +{ +} + +static inline +struct sa_rx_stats_feedback *ol_rx_feedback_alloc(uint32_t mpdu_num) +{ + return NULL; +} +#endif + void ol_rx_indication_handler( ol_txrx_pdev_handle pdev, @@ -357,6 +474,7 @@ ol_rx_indication_handler( uint16_t chan2; uint8_t phymode; a_bool_t ret; + struct sa_rx_stats_feedback *fb; htt_pdev = pdev->htt_pdev; peer = ol_txrx_peer_find_by_id(pdev, peer_id); @@ -430,6 +548,11 @@ ol_rx_indication_handler( pdev->htt_pdev->rx_ring.sw_rd_idx.msdu_payld; #endif + if (peer && num_mpdu_ranges) + fb = ol_rx_feedback_alloc(num_mpdu_ranges); + else + fb = NULL; + for (mpdu_range = 0; mpdu_range < num_mpdu_ranges; mpdu_range++) { enum htt_rx_status status; int i, num_mpdus; @@ -442,6 +565,9 @@ ol_rx_indication_handler( htt_rx_ind_mpdu_range_info( pdev->htt_pdev, rx_ind_msg, mpdu_range, &status, &num_mpdus); + if (fb) + ol_pop_rx_stats(htt_pdev, rx_ind_msg, + num_mpdus, &fb->mpdu_stats[mpdu_range]); if ((status == htt_rx_status_ok) && peer) { TXRX_STATS_ADD(pdev, priv.rx.normal.mpdus, num_mpdus); /* valid frame - deposit it into the rx reordering buffer */ @@ -476,7 +602,7 @@ ol_rx_indication_handler( #ifdef HTT_RX_RESTORE if (htt_pdev->rx_ring.rx_reset) { ol_rx_trigger_restore(htt_pdev, head_msdu, tail_msdu); - return; + goto exit; } #endif rx_mpdu_desc = @@ -600,7 +726,7 @@ ol_rx_indication_handler( #ifdef HTT_RX_RESTORE if (htt_pdev->rx_ring.rx_reset) { ol_rx_trigger_restore(htt_pdev, msdu, tail_msdu); - return; + goto exit; } #endif /* pull the MPDU desc off the desc queue */ @@ -671,6 +797,13 @@ ol_rx_indication_handler( if (pdev->rx.flags.defrag_timeout_check) { ol_rx_defrag_waitlist_flush(pdev); } +#ifdef HTT_RX_RESTORE +exit: +#endif + if (peer && fb) + smart_antenna_update_rx_stats(peer->mac_addr.raw, fb); + if (fb) + adf_os_mem_free(fb); } void diff --git a/CORE/SERVICES/COMMON/ol_htt_rx_api.h b/CORE/SERVICES/COMMON/ol_htt_rx_api.h index 8cf7a4548fb4..38aa4b7141ac 100644 --- a/CORE/SERVICES/COMMON/ol_htt_rx_api.h +++ b/CORE/SERVICES/COMMON/ol_htt_rx_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015, 2018-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -259,7 +259,20 @@ int8_t htt_rx_ind_noise_floor_chain(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, int8_t chain); -void +/** + * htt_rx_ind_sig() - Return SIG_A1 and SIG_A2 + * @pdev: the HTT instance the rx data was received on + * @rx_ind_msg: the netbuf containing the rx indication message + * @sig_a1: SIG_A1 + * @sig_a2: SIG_A2 + * @type: preamble type + * + * return: 0 success, -1, SIG_A and preamble type is not avalible. + */ +int htt_rx_ind_sig(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, + uint32_t *sig_a1, uint32_t *sig_a2, uint8_t *type); + +int htt_rx_ind_legacy_rate(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, uint8_t *legacy_rate, uint8_t *legacy_rate_sel); diff --git a/CORE/SERVICES/SA/smart_antenna_apis.h b/CORE/SERVICES/SA/smart_antenna_apis.h index a1e536728c2c..44bdeadf35ac 100644 --- a/CORE/SERVICES/SA/smart_antenna_apis.h +++ b/CORE/SERVICES/SA/smart_antenna_apis.h @@ -58,6 +58,29 @@ enum radio_id { }; /** + * enum legacy_rate + */ +enum legacy_rate { + CCK_1M_LONG_PREAMBLE = 0, + CCK_2M_LONG_PREAMBLE, + CCK_2M_SHORT_PREAMBLE, + CCK_5_5M_LONG_PREAMBLE, + CCK_5_5M_SHORT_PREAMBLE, + CCK_11M_LONG_PREAMBLE, + CCK_11M_SHORT_PREAMBLE, + OFDM_6M, + OFDM_9M, + OFDM_12M, + OFDM_18M, + OFDM_24M, + OFDM_36M, + OFDM_48M, + OFDM_54M, + INVALID_LEGACY_RATE = -1 +}; + + +/** * struct sa_config - Smart Antenna config info * @channel_num: SAP home channel number */ @@ -77,6 +100,14 @@ struct sa_rate_cap { uint8_t ratecount[MAX_RATE_COUNTERS]; }; +#define SMART_ANT_BW_5MHZ BIT(0) +#define SMART_ANT_BW_10MHZ BIT(1) +#define SMART_ANT_BW_20MHZ BIT(2) +#define SMART_ANT_BW_40MHZ BIT(3) +#define SMART_ANT_BW_80MHZ BIT(4) +#define SMART_ANT_NODE_HT BIT(8) +#define SMART_ANT_NODE_VHT BIT(9) + /** * struct sa_node_info - Detailed info about the connected peer * @mac_addr: MAC address of the connected peer @@ -89,13 +120,6 @@ struct sa_node_info { uint8_t channel_num; uint8_t nss; -#define SMART_ANT_BW_5MHZ BIT(0) -#define SMART_ANT_BW_10MHZ BIT(1) -#define SMART_ANT_BW_20MHZ BIT(2) -#define SMART_ANT_BW_40MHZ BIT(3) -#define SMART_ANT_BW_80MHZ BIT(4) -#define SMART_ANT_NODE_HT BIT(8) -#define SMART_ANT_NODE_VHT BIT(9) uint32_t node_caps; struct sa_rate_cap rate_cap; }; @@ -136,23 +160,58 @@ struct sa_tx_stats_feedback { }; /** - * struct sa_rx_stats_feedback - feedback for RX stats + * struct sa_rx_rate - RX rate + */ +struct sa_rx_rate { +#define LEGACY_RATE 0 +#define HT_VHT_RATE 1 + uint8_t type; + union { + enum legacy_rate legacy_rate; + struct { + uint8_t mcs_index; + uint8_t nss; + uint8_t bw; + } mcs; + } rate; +}; + +/** + * struct sa_rx_mpdu_stats - RX stats for MPDU * @magic: magic number for deferent antenna settings * @tid: TID - * @rx_rate: msb is flag for legacy rate or mcs index - * if msb=0, legacy rate is reported, units of 500 kb/s - * if msb=1, MCS index is reported. + * @mcs: mcs index + * only valid when legacy_rate == INVALID_LEGACY_RATE + * @legacy_rate: legay rate * @pkt_num: received packets nmber * @rx_rssi: percchain rssi - * @timestamp: timestap + * @rx_sn: perchain noise floor + * @timestamp_microsec: (output) the timestamp to microsecond resolution. + * -1 on error. + * @timestamp_submicrosec: the submicrosecond portion of the + * timestamp. -1 on error. */ -struct sa_rx_stats_feedback { +struct sa_rx_mpdu_stats { uint32_t magic; uint8_t tid; - uint16_t rx_rate; + uint8_t mcs; + struct sa_rx_rate rate; uint16_t pkt_num; uint8_t rx_rssi[SA_MAX_CHAIN_NUM]; - uint32_t timestamp; + uint8_t rx_nf[SA_MAX_CHAIN_NUM]; + uint32_t timestamp_microsec; + uint32_t timestamp_submicrosec; +}; + +/** + * struct sa_rx_stats_feedback - RX stats Feedback + * @mpdu_count: mpdu count in this feedback + * @mpdu_stats: MPDU stats buffer + */ +struct sa_rx_stats_feedback +{ + uint32_t mpdu_count; + struct sa_rx_mpdu_stats mpdu_stats[0]; }; /** |
