qcacmn: Enable support for HE radiotap headers

radiotap has updated HE (11ax) radiotap header extensions.
The change enables the support for those headers in the
driver.

CRs-Fixed: 2133532
Change-Id: I42c4f13e157ea981d6a276582553893921a70758
This commit is contained in:
Ravi Joshi 2017-10-26 16:37:00 -07:00 • committed by snandini
commit 54ee5e48db
2 changed files with 144 additions and 24 deletions

View file

@ -136,6 +136,8 @@
* @vht_flags: VHT flags, only present for VHT frames.
* @vht_flag_values1-5: Contains corresponding data for flags field
* @he_flags: HE (11ax) flags, only present in HE frames
* @he_mu_flags: HE-MU (11ax) flags, only present in HE frames
* @he_mu_other_flags: HE-MU-OTHER (11ax) flags, only present in HE frames
* @he_sig_A1_known: HE (11ax) sig A1 known field
* @he_sig_A2_known: HE (11ax) sig A2 known field
* @he_sig_b_common: HE (11ax) sig B common field
@ -158,6 +160,18 @@
* @first_data_seq_ctrl: Sequence ctrl field of first data frame
* @ast_index: AST table hash index
* @tid: QoS traffic tid number
* @he_per_user_1: HE per user info1
* @he_per_user_2: HE per user info2
* @he_per_user_position: HE per user position info
* @he_per_user_known: HE per user known info
* @he_flags1: HE flags
* @he_flags2: HE flags
* @he_RU[4]: HE RU assignment index
* @he_data1: HE property of received frame
* @he_data2: HE property of received frame
* @he_data3: HE property of received frame
* @he_data4: HE property of received frame
* @he_data5: HE property of received frame
*
*/
struct mon_rx_status {
@ -174,6 +188,8 @@ struct mon_rx_status {
uint16_t vht_flags;
uint16_t vht_flag_values6;
uint16_t he_flags;
uint16_t he_mu_flags;
uint16_t he_mu_other_flags;
uint16_t he_sig_A1_known;
uint16_t he_sig_A2_known;
uint16_t he_sig_b_common;
@ -204,6 +220,20 @@ struct mon_rx_status {
int16_t first_data_seq_ctrl;
uint32_t ast_index;
uint32_t tid;
/* New HE radiotap fields */
uint16_t he_per_user_1;
uint16_t he_per_user_2;
uint8_t he_per_user_position;
uint8_t he_per_user_known;
uint16_t he_flags1;
uint16_t he_flags2;
uint8_t he_RU[4];
uint16_t he_data1;
uint16_t he_data2;
uint16_t he_data3;
uint16_t he_data4;
uint16_t he_data5;
uint16_t he_data6;
};
/* Masks for HE SIG known fields in mon_rx_status structure */

View file

@ -3042,8 +3042,8 @@ static unsigned int qdf_nbuf_update_radiotap_vht_flags(
/**
* qdf_nbuf_update_radiotap_he_flags() - Update radiotap header from rx_status
* @rx_status: Pointer to rx_status.
* @nbuf: nbuf pointer to which radiotap has to be updated
* @headroom_sz: Available headroom size.
* @rtap_buf: buffer to which radiotap has to be updated
* @rtap_len: radiotap length
*
* API update high-efficiency (11ax) fields in the radiotap header
*
@ -3054,58 +3054,127 @@ qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status,
int8_t *rtap_buf, uint32_t rtap_len)
{
/*
* IEEE80211_RADIOTAP_HE u32, u32, u32, u32 u16, u16, u16, u16, u8[4]
* Enable all "known" radiotap flags for now
* IEEE80211_RADIOTAP_HE u16, u16, u16, u16, u16, u16
* Enable all "known" HE radiotap flags for now
*/
put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);
rtap_len += 2;
/* HE-MU-COMMON fields */
put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);
rtap_len += 2;
return rtap_len;
}
/**
* qdf_nbuf_update_radiotap_he_mu_flags() - update he-mu radiotap flags
* @rx_status: Pointer to rx_status.
* @rtap_buf: buffer to which radiotap has to be updated
* @rtap_len: radiotap length
*
* API update HE-MU fields in the radiotap header
*
* Return: length of rtap_len updated.
*/
static unsigned int
qdf_nbuf_update_radiotap_he_mu_flags(struct mon_rx_status *rx_status,
int8_t *rtap_buf, uint32_t rtap_len)
{
/*
* IEEE80211_RADIOTAP_HE_MU u16, u16, u8[4]
* Enable all "known" he-mu radiotap flags for now
*/
if (rx_status->he_sig_b_common_known &
QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0) {
rtap_buf[rtap_len] = rx_status->he_sig_b_common_RU[0];
rtap_buf[rtap_len] = rx_status->he_RU[0];
rtap_len += 1;
}
if (rx_status->he_sig_b_common_known &
QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1) {
rtap_buf[rtap_len] = rx_status->he_sig_b_common_RU[1];
rtap_buf[rtap_len] = rx_status->he_RU[1];
rtap_len += 1;
}
if (rx_status->he_sig_b_common_known &
QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2) {
rtap_buf[rtap_len] = rx_status->he_sig_b_common_RU[2];
rtap_buf[rtap_len] = rx_status->he_RU[2];
rtap_len += 1;
}
if (rx_status->he_sig_b_common_known &
QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3) {
rtap_buf[rtap_len] = rx_status->he_sig_b_common_RU[3];
rtap_buf[rtap_len] = rx_status->he_RU[3];
rtap_len += 1;
}
put_unaligned_le16(rx_status->he_sig_b_common, &rtap_buf[rtap_len]);
put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(
rx_status->he_sig_b_common_known, &rtap_buf[rtap_len]);
put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);
rtap_len += 2;
/* HE-MU-USER fields */
put_unaligned_le32(rx_status->he_sig_b_user, &rtap_buf[rtap_len]);
rtap_len += 4;
return rtap_len;
}
put_unaligned_le32(rx_status->he_sig_b_user_known, &rtap_buf[rtap_len]);
rtap_len += 4;
/**
* qdf_nbuf_update_radiotap_he_mu_other_flags() - update he_mu_other flags
* @rx_status: Pointer to rx_status.
* @rtap_buf: buffer to which radiotap has to be updated
* @rtap_len: radiotap length
*
* API update he-mu-other fields in the radiotap header
*
* Return: length of rtap_len updated.
*/
static unsigned int
qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status,
int8_t *rtap_buf, uint32_t rtap_len)
{
/*
* IEEE80211_RADIOTAP_HE-MU-OTHER u16, u16, u8, u8
* Enable all "known" he-mu-other radiotap flags for now
*/
put_unaligned_le16(rx_status->he_per_user_1, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_per_user_2, &rtap_buf[rtap_len]);
rtap_len += 2;
rtap_buf[rtap_len] = rx_status->he_per_user_position;
rtap_len += 1;
rtap_buf[rtap_len] = rx_status->he_per_user_known;
rtap_len += 1;
/* HE fields */
put_unaligned_le32(rx_status->he_sig_A1, &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le32(rx_status->he_sig_A2, &rtap_buf[rtap_len]);
rtap_len += 4;
put_unaligned_le16(rx_status->he_sig_A1_known, &rtap_buf[rtap_len]);
put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_sig_A2_known, &rtap_buf[rtap_len]);
put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);
rtap_len += 2;
put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);
rtap_len += 2;
return rtap_len;
@ -3122,6 +3191,8 @@ qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status,
#define RADIOTAP_HEADER_LEN (sizeof(struct ieee80211_radiotap_header) + 100)
#define IEEE80211_RADIOTAP_HE 22
#define IEEE80211_RADIOTAP_HE_MU 23
#define IEEE80211_RADIOTAP_HE_MU_OTHER 24
/**
* qdf_nbuf_update_radiotap() - Update radiotap header from rx_status
@ -3151,7 +3222,8 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
rtap_len += 1;
/* IEEE80211_RADIOTAP_RATE u8 500kb/s */
if (!rx_status->ht_flags && !rx_status->vht_flags) {
if (!rx_status->ht_flags && !rx_status->vht_flags &&
!rx_status->he_flags) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
rtap_buf[rtap_len] = rx_status->rate * RATE_MULTIPLIER;
} else
@ -3219,6 +3291,24 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
rtap_len);
}
if (rx_status->he_mu_flags) {
/* IEEE80211_RADIOTAP_HE-MU */
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE_MU);
rtap_len = qdf_nbuf_update_radiotap_he_mu_flags(rx_status,
rtap_buf,
rtap_len);
}
if (rx_status->he_mu_other_flags) {
/* IEEE80211_RADIOTAP_HE-MU-OTHER */
rthdr->it_present |=
cpu_to_le32(1 << IEEE80211_RADIOTAP_HE_MU_OTHER);
rtap_len =
qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status,
rtap_buf,
rtap_len);
}
rthdr->it_len = cpu_to_le16(rtap_len);
if (headroom_sz < rtap_len) {