qcacmn: Fix Radiotap headers in monitor mode
In monitor mode, code decodes legacy rates and bandwidth information for HT and VHT. Other changes include populating radiotap header with correct nss and mcs values for legacy, HT and VHT frames. Mapping of mcs rates in rx_msdu_start tlv and radiotap header info is done using Lithium data structure document. Change-Id: I5f20e5d89329738e3a6c076ee14457c003cab279 CRs-fixed: 2083027
This commit is contained in:
@@ -86,6 +86,23 @@
|
||||
#define HAL_RX_RECEPTION_TYPE_OFDMA 2
|
||||
#define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3
|
||||
|
||||
#define HAL_11B_RATE_0MCS 11
|
||||
#define HAL_11B_RATE_1MCS 5.5
|
||||
#define HAL_11B_RATE_2MCS 2
|
||||
#define HAL_11B_RATE_3MCS 1
|
||||
#define HAL_11B_RATE_4MCS 11
|
||||
#define HAL_11B_RATE_5MCS 5.5
|
||||
#define HAL_11B_RATE_6MCS 2
|
||||
|
||||
#define HAL_11A_RATE_0MCS 48
|
||||
#define HAL_11A_RATE_1MCS 24
|
||||
#define HAL_11A_RATE_2MCS 12
|
||||
#define HAL_11A_RATE_3MCS 6
|
||||
#define HAL_11A_RATE_4MCS 54
|
||||
#define HAL_11A_RATE_5MCS 36
|
||||
#define HAL_11A_RATE_6MCS 18
|
||||
#define HAL_11A_RATE_7MCS 9
|
||||
|
||||
enum {
|
||||
HAL_HW_RX_DECAP_FORMAT_RAW = 0,
|
||||
HAL_HW_RX_DECAP_FORMAT_NWIFI,
|
||||
@@ -351,7 +368,7 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
|
||||
struct rx_msdu_start *rx_msdu_start;
|
||||
struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
|
||||
uint32_t reg_value;
|
||||
|
||||
uint8_t nss = 0;
|
||||
static uint32_t sgi_hw_to_cdp[] = {
|
||||
CDP_SGI_0_8_US,
|
||||
CDP_SGI_0_4_US,
|
||||
@@ -373,12 +390,19 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
|
||||
|
||||
reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
|
||||
switch (reg_value) {
|
||||
case HAL_RX_PKT_TYPE_11N:
|
||||
rs->ht_flags = 1;
|
||||
rs->bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
|
||||
RECEIVE_BANDWIDTH);
|
||||
break;
|
||||
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;
|
||||
RECEIVE_BANDWIDTH);
|
||||
rs->vht_flag_values2 = reg_value;
|
||||
nss = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
|
||||
nss = nss + 1;
|
||||
rs->vht_flag_values3[0] = (rs->mcs << 4) | nss ;
|
||||
break;
|
||||
case HAL_RX_PKT_TYPE_11AX:
|
||||
rs->he_flags = 1;
|
||||
@@ -386,7 +410,6 @@ void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
|
||||
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 */
|
||||
@@ -436,6 +459,7 @@ 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, value;
|
||||
uint8_t group_id = 0;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
|
||||
user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv);
|
||||
@@ -526,15 +550,92 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
|
||||
1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case WIFIPHYRX_L_SIG_B_E:
|
||||
{
|
||||
uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
|
||||
HAL_RX_OFFSET(PHYRX_L_SIG_B_0,
|
||||
L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
|
||||
|
||||
value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
|
||||
switch (value) {
|
||||
case 1:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
|
||||
break;
|
||||
case 2:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
|
||||
break;
|
||||
case 3:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
|
||||
break;
|
||||
case 4:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
|
||||
break;
|
||||
case 5:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
|
||||
break;
|
||||
case 6:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
|
||||
break;
|
||||
case 7:
|
||||
ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WIFIPHYRX_L_SIG_A_E:
|
||||
{
|
||||
uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
|
||||
HAL_RX_OFFSET(PHYRX_L_SIG_A_0,
|
||||
L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
|
||||
|
||||
value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
|
||||
switch (value) {
|
||||
case 8:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
|
||||
break;
|
||||
case 9:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
|
||||
break;
|
||||
case 10:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
|
||||
break;
|
||||
case 11:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
|
||||
break;
|
||||
case 12:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
|
||||
break;
|
||||
case 13:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
|
||||
break;
|
||||
case 14:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
|
||||
break;
|
||||
case 15:
|
||||
ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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;
|
||||
group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
|
||||
ppdu_info->rx_status.vht_flag_values5 = group_id;
|
||||
break;
|
||||
}
|
||||
case WIFIPHYRX_HE_SIG_A_SU_E:
|
||||
|
@@ -70,6 +70,8 @@
|
||||
#include "phyrx_he_sig_b1_mu.h"
|
||||
#include "phyrx_he_sig_b2_mu.h"
|
||||
#include "phyrx_he_sig_b2_ofdma.h"
|
||||
#include "phyrx_l_sig_a.h"
|
||||
#include "phyrx_l_sig_b.h"
|
||||
#include "phyrx_vht_sig_a.h"
|
||||
#include "phyrx_ht_sig.h"
|
||||
#include "tx_msdu_extension.h"
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#endif /* FEATURE_TSO */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
|
||||
|
||||
#define qdf_nbuf_users_inc atomic_inc
|
||||
#define qdf_nbuf_users_dec atomic_dec
|
||||
#define qdf_nbuf_users_set atomic_set
|
||||
@@ -64,6 +65,19 @@
|
||||
#define qdf_nbuf_users_read refcount_read
|
||||
#endif /* KERNEL_VERSION(4, 13, 0) */
|
||||
|
||||
#define RATE_MULTIPLIER 2
|
||||
|
||||
#define IEEE80211_RADIOTAP_VHT_BW_20 0
|
||||
#define IEEE80211_RADIOTAP_VHT_BW_40 1
|
||||
#define IEEE80211_RADIOTAP_VHT_BW_80 2
|
||||
#define IEEE80211_RADIOTAP_VHT_BW_160 3
|
||||
|
||||
#define RADIOTAP_VHT_BW_20 0
|
||||
#define RADIOTAP_VHT_BW_40 1
|
||||
#define RADIOTAP_VHT_BW_80 4
|
||||
#define RADIOTAP_VHT_BW_160 11
|
||||
|
||||
|
||||
/* Packet Counter */
|
||||
static uint32_t nbuf_tx_mgmt[QDF_NBUF_TX_PKT_STATE_MAX];
|
||||
static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX];
|
||||
@@ -2674,8 +2688,20 @@ static unsigned int qdf_nbuf_update_radiotap_vht_flags(
|
||||
(rx_status->beamformed ?
|
||||
IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED : 0);
|
||||
rtap_len += 1;
|
||||
|
||||
rtap_buf[rtap_len] = (rx_status->vht_flag_values2);
|
||||
switch (rx_status->vht_flag_values2) {
|
||||
case IEEE80211_RADIOTAP_VHT_BW_20:
|
||||
rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20;
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_VHT_BW_40:
|
||||
rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40;
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_VHT_BW_80:
|
||||
rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80;
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_VHT_BW_160:
|
||||
rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160;
|
||||
break;
|
||||
}
|
||||
rtap_len += 1;
|
||||
rtap_buf[rtap_len] = (rx_status->vht_flag_values3[0]);
|
||||
rtap_len += 1;
|
||||
@@ -2810,7 +2836,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
|
||||
/* IEEE80211_RADIOTAP_RATE u8 500kb/s */
|
||||
if (!rx_status->ht_flags && !rx_status->vht_flags) {
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
|
||||
rtap_buf[rtap_len] = rx_status->rate;
|
||||
rtap_buf[rtap_len] = rx_status->rate * RATE_MULTIPLIER;
|
||||
} else
|
||||
rtap_buf[rtap_len] = 0;
|
||||
rtap_len += 1;
|
||||
@@ -2852,6 +2878,8 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
|
||||
rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_SGI;
|
||||
if (rx_status->bw)
|
||||
rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_40;
|
||||
else
|
||||
rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_20;
|
||||
rtap_len += 1;
|
||||
|
||||
rtap_buf[rtap_len] = rx_status->mcs;
|
||||
|
Reference in New Issue
Block a user