qcacmn: Add EHT radiotap header fields

Add the EHT radiotap header definition and
support to parse these fields.

Change-Id: If988753b497cc2feb79f358afea2674effd8270c
CRs-Fixed: 3092818
This commit is contained in:
Rakesh Pillai
2021-12-10 02:04:36 -08:00
committed by Madan Koyyalamudi
parent 6ee7701aab
commit 1c6617edf5
3 changed files with 325 additions and 27 deletions

View File

@@ -4813,6 +4813,102 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status,
return rtap_len;
}
/**
* qdf_nbuf_update_radiotap_usig_flags() - Update radiotap header with USIG data
* from rx_status
* @rx_status: Pointer to rx_status.
* @rtap_buf: buffer to which radiotap has to be updated
* @rtap_len: radiotap length
*
* API update Extra High Throughput (11be) fields in the radiotap header
*
* Return: length of rtap_len updated.
*/
static unsigned int
qdf_nbuf_update_radiotap_usig_flags(struct mon_rx_status *rx_status,
int8_t *rtap_buf, uint32_t rtap_len)
{
/*
* IEEE80211_RADIOTAP_USIG:
* u32, u32, u32
*/
rtap_len = qdf_align(rtap_len, 4);
put_unaligned_le32(rx_status->usig_common, &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->usig_value, &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->usig_mask, &rtap_buf[rtap_len]);
rtap_len += 4;
qdf_rl_debug("U-SIG data %x %x %x",
rx_status->usig_common, rx_status->usig_value,
rx_status->usig_mask);
return rtap_len;
}
/**
* qdf_nbuf_update_radiotap_eht_flags() - Update radiotap header with EHT data
* from rx_status
* @rx_status: Pointer to rx_status.
* @rtap_buf: buffer to which radiotap has to be updated
* @rtap_len: radiotap length
*
* API update Extra High Throughput (11be) fields in the radiotap header
*
* Return: length of rtap_len updated.
*/
static unsigned int
qdf_nbuf_update_radiotap_eht_flags(struct mon_rx_status *rx_status,
int8_t *rtap_buf, uint32_t rtap_len)
{
uint32_t user;
/*
* IEEE80211_RADIOTAP_EHT:
* u32, u32, u32, u32, u32, u32, u32, u16, [u32, u32, u32]
*/
rtap_len = qdf_align(rtap_len, 4);
put_unaligned_le32(rx_status->eht_known, &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[0], &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[1], &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[2], &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[3], &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[4], &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->eht_data[5], &rtap_buf[rtap_len]);
rtap_len += 4;
for (user = 0; user < rx_status->num_eht_user_info_valid; user++) {
put_unaligned_le32(rx_status->eht_user_info[user],
&rtap_buf[rtap_len]);
rtap_len += 4;
}
qdf_rl_debug("EHT data %x %x %x %x %x %x %x",
rx_status->eht_known, rx_status->eht_data[0],
rx_status->eht_data[1], rx_status->eht_data[2],
rx_status->eht_data[3], rx_status->eht_data[4],
rx_status->eht_data[5]);
return rtap_len;
}
#define IEEE80211_RADIOTAP_TX_STATUS 0
#define IEEE80211_RADIOTAP_RETRY_COUNT 1
#define IEEE80211_RADIOTAP_EXTENSION2 2
@@ -4879,25 +4975,32 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
uint8_t length = rtap_len;
struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath;
struct qdf_radiotap_ext2 *rtap_ext2;
uint32_t *rtap_ext = NULL;
struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status;
/* per user info */
qdf_le32_t *it_present;
uint32_t it_present_val;
bool radiotap_ext1_hdr_present = false;
it_present = &rthdr->it_present;
/* Adding Extended Header space */
if (rx_status->add_rtap_ext) {
if (rx_status->add_rtap_ext || rx_status->add_rtap_ext2 ||
rx_status->usig_flags || rx_status->eht_flags) {
rtap_hdr_len += RADIOTAP_HEADER_EXT_LEN;
rtap_len = rtap_hdr_len;
radiotap_ext1_hdr_present = true;
}
length = rtap_len;
/* IEEE80211_RADIOTAP_TSFT __le64 microseconds*/
rthdr->it_present = (1 << IEEE80211_RADIOTAP_TSFT);
it_present_val = (1 << IEEE80211_RADIOTAP_TSFT);
put_unaligned_le64(rx_status->tsft, &rtap_buf[rtap_len]);
rtap_len += 8;
/* IEEE80211_RADIOTAP_FLAGS u8 */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS);
it_present_val |= (1 << IEEE80211_RADIOTAP_FLAGS);
if (rx_status->rs_fcs_err)
rx_status->rtap_flags |= IEEE80211_RADIOTAP_F_BADFCS;
@@ -4908,14 +5011,14 @@ 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 &&
!rx_status->he_flags) {
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
it_present_val |= (1 << IEEE80211_RADIOTAP_RATE);
rtap_buf[rtap_len] = rx_status->rate;
} else
rtap_buf[rtap_len] = 0;
rtap_len += 1;
/* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
it_present_val |= (1 << IEEE80211_RADIOTAP_CHANNEL);
put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]);
rtap_len += 2;
/* Channel flags. */
@@ -4933,7 +5036,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from one milliwatt
* (dBm)
*/
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
/*
* rssi_comb is int dB, need to convert it to dBm.
* normalize value to noise floor of -96 dBm
@@ -4942,12 +5045,12 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
rtap_len += 1;
/* RX signal noise floor */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
rtap_buf[rtap_len] = (uint8_t)rx_status->chan_noise_floor;
rtap_len += 1;
/* IEEE80211_RADIOTAP_ANTENNA u8 antenna index */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA);
it_present_val |= (1 << IEEE80211_RADIOTAP_ANTENNA);
rtap_buf[rtap_len] = rx_status->nr_ant;
rtap_len += 1;
@@ -4959,7 +5062,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->ht_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_VHT u8, u8, u8 */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS);
it_present_val |= (1 << IEEE80211_RADIOTAP_MCS);
rtap_buf[rtap_len] = IEEE80211_RADIOTAP_MCS_HAVE_BW |
IEEE80211_RADIOTAP_MCS_HAVE_MCS |
IEEE80211_RADIOTAP_MCS_HAVE_GI;
@@ -4984,7 +5087,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->rs_flags & IEEE80211_AMPDU_FLAG) {
/* IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
it_present_val |= (1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
rtap_len = qdf_nbuf_update_radiotap_ampdu_flags(rx_status,
rtap_buf,
rtap_len);
@@ -4993,7 +5096,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->vht_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT);
it_present_val |= (1 << IEEE80211_RADIOTAP_VHT);
rtap_len = qdf_nbuf_update_radiotap_vht_flags(rx_status,
rtap_buf,
rtap_len);
@@ -5007,7 +5110,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->he_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_HE */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE);
it_present_val |= (1 << IEEE80211_RADIOTAP_HE);
rtap_len = qdf_nbuf_update_radiotap_he_flags(rx_status,
rtap_buf,
rtap_len);
@@ -5021,7 +5124,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->he_mu_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_HE-MU */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE_MU);
it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU);
rtap_len = qdf_nbuf_update_radiotap_he_mu_flags(rx_status,
rtap_buf,
rtap_len);
@@ -5035,7 +5138,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
if (rx_status->he_mu_other_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_HE-MU-OTHER */
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_HE_MU_OTHER);
it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU_OTHER);
rtap_len =
qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status,
rtap_buf,
@@ -5051,7 +5154,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
/*
* Radiotap Vendor Namespace
*/
rthdr->it_present |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
it_present_val |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
radiotap_vendor_ns_ath = (struct qdf_radiotap_vendor_ns_ath *)
(rtap_buf + rtap_len);
/*
@@ -5073,13 +5176,18 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
cpu_to_le32(rx_status->ppdu_timestamp);
rtap_len += sizeof(*radiotap_vendor_ns_ath);
/* Move to next it_present */
if (radiotap_ext1_hdr_present) {
it_present_val |= (1 << IEEE80211_RADIOTAP_EXT);
put_unaligned_le32(it_present_val, it_present);
it_present_val = 0;
it_present++;
}
/* Add Extension to Radiotap Header & corresponding data */
if (rx_status->add_rtap_ext) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT);
rtap_ext = (uint32_t *)&rthdr->it_present;
rtap_ext++;
*rtap_ext = cpu_to_le32(1 << IEEE80211_RADIOTAP_TX_STATUS);
*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RETRY_COUNT);
it_present_val |= (1 << IEEE80211_RADIOTAP_TX_STATUS);
it_present_val |= (1 << IEEE80211_RADIOTAP_RETRY_COUNT);
rtap_buf[rtap_len] = rx_status->tx_status;
rtap_len += 1;
@@ -5089,10 +5197,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
/* Add Extension2 to Radiotap Header */
if (rx_status->add_rtap_ext2) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT);
rtap_ext = (uint32_t *)&rthdr->it_present;
rtap_ext++;
*rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXTENSION2);
it_present_val |= (1 << IEEE80211_RADIOTAP_EXTENSION2);
rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len);
rtap_ext2->ppdu_id = rx_status->ppdu_id;
@@ -5118,13 +5223,42 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
rtap_len += sizeof(*rtap_ext2);
}
if (rx_status->usig_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_USIG */
it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_USIG);
rtap_len = qdf_nbuf_update_radiotap_usig_flags(rx_status,
rtap_buf,
rtap_len);
if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) {
qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN");
return 0;
}
}
if (rx_status->eht_flags) {
length = rtap_len;
/* IEEE80211_RADIOTAP_EHT */
it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_EHT);
rtap_len = qdf_nbuf_update_radiotap_eht_flags(rx_status,
rtap_buf,
rtap_len);
if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) {
qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN");
return 0;
}
}
put_unaligned_le32(it_present_val, it_present);
rthdr->it_len = cpu_to_le16(rtap_len);
rthdr->it_present = cpu_to_le32(rthdr->it_present);
if (headroom_sz < rtap_len) {
qdf_debug("DEBUG: Not enough space to update radiotap");
return 0;
}
qdf_nbuf_push_head(nbuf, rtap_len);
qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len);
return rtap_len;