qcacmn: Monitor status ring handling

Changes to process PHY TLVs from monitor status ring and extract
information required for radiotap header.

Change-Id: I99d642e7506ea797b26dbfac89fd223d1a4c0a55
CRs-Fixed: 2048006
Bu işleme şunda yer alıyor:
Karunakar Dasineni
2017-03-26 22:44:39 -07:00
işlemeyi yapan: snandini
ebeveyn 1eb4e0ae5c
işleme 4055568bad
9 değiştirilmiş dosya ile 324 ekleme ve 153 silme

Dosyayı Görüntüle

@@ -32,6 +32,7 @@
HAL_RX_LSB(block, field))
#define HAL_RX_PHY_DATA_RADAR 0x01
#define HAL_SU_MU_CODING_LDPC 0x01
#define HAL_RX_FCS_LEN (4)
#define KEY_EXTIV 0x20
@@ -74,6 +75,17 @@
#define HAL_MAX_UL_MU_USERS 8
#define HAL_RX_PKT_TYPE_11A 0
#define HAL_RX_PKT_TYPE_11B 1
#define HAL_RX_PKT_TYPE_11N 2
#define HAL_RX_PKT_TYPE_11AC 3
#define HAL_RX_PKT_TYPE_11AX 4
#define HAL_RX_RECEPTION_TYPE_SU 0
#define HAL_RX_RECEPTION_TYPE_MU_MIMO 1
#define HAL_RX_RECEPTION_TYPE_OFDMA 2
#define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3
enum {
HAL_HW_RX_DECAP_FORMAT_RAW = 0,
HAL_HW_RX_DECAP_FORMAT_NWIFI,
@@ -154,6 +166,16 @@ uint32_t HAL_RX_MON_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr)
return HAL_RX_GET(rx_attn, RX_ATTENTION_0, PHY_PPDU_ID);
}
/* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */
static inline
uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr)
{
struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr;
struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end;
return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU);
}
#define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \
BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \
@@ -286,7 +308,7 @@ uint32 hal_get_rx_msdu_link_desc_size(void)
enum {
HAL_PKT_TYPE_OFDM = 0,
HAL_CDP_PKT_TYPE_CCK,
HAL_PKT_TYPE_CCK,
HAL_PKT_TYPE_HT,
HAL_PKT_TYPE_VHT,
HAL_PKT_TYPE_HE,
@@ -313,73 +335,60 @@ enum {
HAL_RX_TYPE_MU_OFDMA_MIMO,
};
/**
* hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status
*
* @ hw_desc_addr: Start address of Rx HW TLVs
* @ rs: Status for monitor mode
*
* Return: void
*/
static inline
void HAL_RX_MON_HW_DESC_GET_PPDU_START_STATUS(void *hw_desc_addr,
struct cdp_mon_status *rs)
void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
struct mon_rx_status *rs)
{
struct rx_msdu_start *rx_msdu_start;
struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
uint32_t rx_pream_type;
uint32_t rx_sgi;
uint32_t rx_type;
uint32_t rx_bw;
static uint32_t pkt_type_hw_to_cdp[] = {
CDP_PKT_TYPE_OFDM,
CDP_PKT_TYPE_CCK,
CDP_PKT_TYPE_HT,
CDP_PKT_TYPE_VHT,
CDP_PKT_TYPE_HE,
};
uint32_t reg_value;
static uint32_t sgi_hw_to_cdp[] = {
CDP_SGI_0_8_US,
CDP_SGI_0_4_US,
CDP_SGI_1_6_US,
CDP_SGI_3_2_US,
};
static uint32_t rx_type_hw_to_cdp[] = {
CDP_RX_TYPE_SU,
CDP_RX_TYPE_MU_MIMO,
CDP_RX_TYPE_MU_OFDMA,
CDP_RX_TYPE_MU_OFDMA_MIMO,
};
static uint32_t rx_bw_hw_to_cdp[] = {
CDP_FULL_RX_BW_20,
CDP_FULL_RX_BW_40,
CDP_FULL_RX_BW_80,
CDP_FULL_RX_BW_160,
};
static uint32_t sgi_hw_to_cdp[] = {
CDP_SGI_0_8_US,
CDP_SGI_0_4_US,
CDP_SGI_1_6_US,
CDP_SGI_3_2_US,
};
rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start;
rs->cdp_rs_tstamp.cdp_tsf = rx_msdu_start->ppdu_start_timestamp;
rx_pream_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
rs->cdp_rs_pream_type = pkt_type_hw_to_cdp[rx_pream_type];
rs->cdp_rs_user_rssi = HAL_RX_GET(rx_msdu_start,
rs->ant_signal_db = HAL_RX_GET(rx_msdu_start,
RX_MSDU_START_5, USER_RSSI);
rs->cdp_rs_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC);
rx_sgi = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI);
rs->cdp_rs_sgi = sgi_hw_to_cdp[rx_sgi];
rs->cdf_rs_rate_mcs = HAL_RX_GET(rx_msdu_start,
rs->mcs = HAL_RX_GET(rx_msdu_start,
RX_MSDU_START_5, RATE_MCS);
rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC);
rx_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI);
rs->sgi = sgi_hw_to_cdp[reg_value];
rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
rs->cdp_rs_reception_type = rx_type_hw_to_cdp[rx_type];
rx_bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEIVE_BANDWIDTH);
rs->cdp_rs_bw = rx_bw_hw_to_cdp[rx_bw];
rs->cdp_rs_nss = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
switch (reg_value) {
case HAL_RX_PKT_TYPE_11AC:
rs->vht_flags = 1;
reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
RECEIVE_BANDWIDTH);
rs->vht_flag_values2 = 0x01 << reg_value;
rs->vht_flag_values3[0] = rs->mcs << 4;
break;
case HAL_RX_PKT_TYPE_11AX:
rs->he_flags = 1;
break;
default:
break;
}
reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0;
/* TODO: rs->beamformed should be set for SU beamforming also */
}
struct hal_rx_ppdu_user_info {
@@ -394,6 +403,7 @@ struct hal_rx_ppdu_common_info {
struct hal_rx_ppdu_info {
struct hal_rx_ppdu_common_info com_info;
struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS];
struct mon_rx_status rx_status;
};
static inline uint32_t
@@ -404,9 +414,18 @@ hal_get_rx_status_buf_size(void) {
static inline uint8_t*
hal_rx_status_get_next_tlv(uint8_t *rx_tlv) {
uint32_t tlv_len;
uint32_t tlv_len, tlv_tag;
tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv);
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
/* The actual length of PPDU_END is the combined lenght of many PHY
* TLVs that follow. Skip the TLV header and
* rx_rxpcu_classification_overview that follows the header to get to
* next TLV.
*/
if (tlv_tag == WIFIRX_PPDU_END_E)
tlv_len = sizeof(struct rx_rxpcu_classification_overview);
return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len +
HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3)));
@@ -415,7 +434,7 @@ hal_rx_status_get_next_tlv(uint8_t *rx_tlv) {
static inline uint32_t
hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
{
uint32_t tlv_tag, user_id, tlv_len;
uint32_t tlv_tag, user_id, tlv_len, value;
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv);
@@ -432,6 +451,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
ppdu_info->com_info.ppdu_id =
HAL_RX_GET(rx_tlv, RX_PPDU_START_0,
PHY_PPDU_ID);
/* TODO: Ensure channel number is set in PHY meta data */
ppdu_info->rx_status.chan_freq =
HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
SW_PHY_META_DATA);
ppdu_info->com_info.ppdu_timestamp =
HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
PPDU_START_TIMESTAMP);
@@ -444,9 +467,16 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"[%s][%d] ppdu_end_e len=%d\n",
__func__, __LINE__, tlv_len);
/* This is followed by sub-TLVs of PPDU_END */
break;
case WIFIRXPCU_PPDU_END_INFO_E:
ppdu_info->rx_status.tsft =
HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1,
WB_TIMESTAMP_UPPER_32);
ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) |
HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0,
WB_TIMESTAMP_LOWER_32);
break;
case WIFIRX_PPDU_END_USER_STATS_E:
@@ -459,8 +489,147 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
return HAL_TLV_STATUS_PPDU_DONE;
case WIFIDUMMY_E:
return HAL_TLV_STATUS_DUMMY;
return HAL_TLV_STATUS_PPDU_DONE;
case WIFIPHYRX_HT_SIG_E:
{
uint8_t *ht_sig_info = (uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HT_SIG_0,
HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS);
value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1,
FEC_CODING);
ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
1 : 0;
break;
}
case WIFIPHYRX_VHT_SIG_A_E:
{
uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0,
VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
SU_MU_CODING);
ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
1 : 0;
break;
}
case WIFIPHYRX_HE_SIG_A_SU_E:
ppdu_info->rx_status.he_sig_A1 =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0,
HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_A1 |=
QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU;
/* TODO: Enabling all known bits. Check if this should be
* enabled selectively
*/
ppdu_info->rx_status.he_sig_A1_known =
QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL;
ppdu_info->rx_status.he_sig_A2 =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_1,
HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_A2_known =
QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL;
break;
case WIFIPHYRX_HE_SIG_A_MU_DL_E:
ppdu_info->rx_status.he_sig_A1 =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0,
HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_A1 |=
QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU;
ppdu_info->rx_status.he_sig_A1_known =
QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL;
ppdu_info->rx_status.he_sig_A2 =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_1,
HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_A2_known =
QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL;
break;
case WIFIPHYRX_HE_SIG_B1_MU_E:
{
uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv +
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0,
HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_b_common_RU[0] =
HAL_RX_GET(he_sig_b1_mu_info, HE_SIG_B1_MU_INFO_0,
RU_ALLOCATION);
ppdu_info->rx_status.he_sig_b_common_known =
QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
/* TODO: Check on the availability of other fields in
* sig_b_common
*/
break;
}
case WIFIPHYRX_HE_SIG_B2_MU_E:
ppdu_info->rx_status.he_sig_b_user =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0,
HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_b_user_known =
QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL;
break;
case WIFIPHYRX_HE_SIG_B2_OFDMA_E:
ppdu_info->rx_status.he_sig_b_user =
*((uint32_t *)((uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0,
HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS)));
ppdu_info->rx_status.he_sig_b_user_known =
QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL;
break;
case WIFIPHYRX_RSSI_LEGACY_E:
{
uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv +
HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3,
RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_PRI20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT40_LOW20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT40_HIGH20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT80_LOW20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value);
value = HAL_RX_GET(rssi_info_tlv,
RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"RSSI_EXT80_HIGH20_CHAIN0: %d\n", value);
break;
}
case 0:
return HAL_TLV_STATUS_PPDU_DONE;
@@ -468,6 +637,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
break;
}
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s TLV type: %d, TLV len:%d\n",
__func__, tlv_tag, tlv_len);
return HAL_TLV_STATUS_PPDU_NOT_DONE;
}

Dosyayı Görüntüle

@@ -64,7 +64,18 @@
#include "rx_ppdu_end_user_stats.h"
#include "rx_ppdu_end_user_stats_ext.h"
#include "rx_mpdu_desc_info.h"
#include "rxpcu_ppdu_end_info.h"
#include "phyrx_he_sig_a_su.h"
#include "phyrx_he_sig_a_mu_dl.h"
#include "phyrx_he_sig_b1_mu.h"
#include "phyrx_he_sig_b2_mu.h"
#include "phyrx_he_sig_b2_ofdma.h"
#include "phyrx_vht_sig_a.h"
#include "phyrx_ht_sig.h"
#include "tx_msdu_extension.h"
#include "receive_rssi_info.h"
#include "phyrx_pkt_end.h"
#include "phyrx_rssi_legacy.h"
#include "wcss_version.h"
#include "pld_common.h"
#include "rx_msdu_link.h"