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:

committed by
Madan Koyyalamudi

parent
6ee7701aab
commit
1c6617edf5
@@ -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;
|
||||
|
Reference in New Issue
Block a user