qcacmn: Add support to parse and aggregate split TLVs
For KIWI, when operating monitor mode in 802.11BE, there can be certain header fields which can be received as split across multiple TLVs. Add support to aggregate such split TLVs and decode them after agregation. Change-Id: Ia00323a8f9fbe39306b1bbab4afefaa937befdae CRs-Fixed: 3092820
This commit is contained in:

committed by
Madan Koyyalamudi

parent
1c6617edf5
commit
dad3ff5afa
@@ -1524,6 +1524,121 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo,
|
||||
return HAL_TLV_STATUS_PPDU_NOT_DONE;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hal_rx_status_process_aggr_tlv(struct hal_soc *hal_soc,
|
||||
struct hal_rx_ppdu_info *ppdu_info)
|
||||
{
|
||||
uint32_t aggr_tlv_tag = ppdu_info->tlv_aggr.tlv_tag;
|
||||
|
||||
switch (aggr_tlv_tag) {
|
||||
case WIFIPHYRX_GENERIC_EHT_SIG_E:
|
||||
break;
|
||||
default:
|
||||
/* Aggregated TLV cannot be handled */
|
||||
qdf_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
ppdu_info->tlv_aggr.in_progress = 0;
|
||||
ppdu_info->tlv_aggr.cur_len = 0;
|
||||
|
||||
return HAL_TLV_STATUS_PPDU_NOT_DONE;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hal_rx_status_tlv_should_aggregate(struct hal_soc *hal_soc, uint32_t tlv_tag)
|
||||
{
|
||||
switch (tlv_tag) {
|
||||
case WIFIPHYRX_GENERIC_EHT_SIG_E:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_status_aggr_tlv(struct hal_soc *hal_soc, void *rx_tlv_hdr,
|
||||
struct hal_rx_ppdu_info *ppdu_info,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint32_t tlv_tag, user_id, tlv_len;
|
||||
void *rx_tlv;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV64_TYPE(rx_tlv_hdr);
|
||||
user_id = HAL_RX_GET_USER_TLV64_USERID(rx_tlv_hdr);
|
||||
tlv_len = HAL_RX_GET_USER_TLV64_LEN(rx_tlv_hdr);
|
||||
|
||||
rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV64_HDR_SIZE;
|
||||
|
||||
if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) {
|
||||
qdf_mem_copy(ppdu_info->tlv_aggr.buf +
|
||||
ppdu_info->tlv_aggr.cur_len,
|
||||
rx_tlv, tlv_len);
|
||||
ppdu_info->tlv_aggr.cur_len += tlv_len;
|
||||
} else {
|
||||
dp_err("Length of TLV exceeds max aggregation length");
|
||||
qdf_assert(0);
|
||||
}
|
||||
|
||||
return HAL_TLV_STATUS_PPDU_NOT_DONE;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_status_start_new_aggr_tlv(struct hal_soc *hal_soc, void *rx_tlv_hdr,
|
||||
struct hal_rx_ppdu_info *ppdu_info,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint32_t tlv_tag, user_id, tlv_len;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV64_TYPE(rx_tlv_hdr);
|
||||
user_id = HAL_RX_GET_USER_TLV64_USERID(rx_tlv_hdr);
|
||||
tlv_len = HAL_RX_GET_USER_TLV64_LEN(rx_tlv_hdr);
|
||||
|
||||
ppdu_info->tlv_aggr.in_progress = 1;
|
||||
ppdu_info->tlv_aggr.tlv_tag = tlv_tag;
|
||||
ppdu_info->tlv_aggr.cur_len = 0;
|
||||
|
||||
return hal_rx_status_aggr_tlv(hal_soc, rx_tlv_hdr, ppdu_info, nbuf);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_status_get_tlv_info_wrapper_be(void *rx_tlv_hdr, void *ppduinfo,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
|
||||
uint32_t tlv_tag, user_id, tlv_len;
|
||||
struct hal_rx_ppdu_info *ppdu_info =
|
||||
(struct hal_rx_ppdu_info *)ppduinfo;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV64_TYPE(rx_tlv_hdr);
|
||||
user_id = HAL_RX_GET_USER_TLV64_USERID(rx_tlv_hdr);
|
||||
tlv_len = HAL_RX_GET_USER_TLV64_LEN(rx_tlv_hdr);
|
||||
|
||||
/*
|
||||
* Handle the case where aggregation is in progress
|
||||
* or the current TLV is one of the TLVs which should be
|
||||
* aggregated
|
||||
*/
|
||||
if (ppdu_info->tlv_aggr.in_progress) {
|
||||
if (ppdu_info->tlv_aggr.tlv_tag == tlv_tag) {
|
||||
return hal_rx_status_aggr_tlv(hal, rx_tlv_hdr,
|
||||
ppdu_info, nbuf);
|
||||
} else {
|
||||
/* Finish aggregation of current TLV */
|
||||
hal_rx_status_process_aggr_tlv(hal, ppdu_info);
|
||||
}
|
||||
}
|
||||
|
||||
if (hal_rx_status_tlv_should_aggregate(hal, tlv_tag)) {
|
||||
return hal_rx_status_start_new_aggr_tlv(hal, rx_tlv_hdr,
|
||||
ppduinfo, nbuf);
|
||||
}
|
||||
|
||||
return hal_rx_status_get_tlv_info_generic_be(rx_tlv_hdr, ppduinfo,
|
||||
hal_soc_hdl, nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_tx_set_pcp_tid_map_generic_be() - Configure default PCP to TID map table
|
||||
* @soc: HAL SoC context
|
||||
|
Reference in New Issue
Block a user