qcacmn: Handle MPDU having more than QDF_NBUF_MAX_FRAGS MSDU

Handle case in mon dest ring buffer processing,
where one MPDU can have more than QDF_NBUF_MAX_FRAGS MSDU.

Change-Id: If09099814b7f701efbaa20b1406958ad97d64829
CRs-Fixed: 2788919
This commit is contained in:
Ankit Kumar
2020-10-02 15:40:25 +05:30
committed by snandini
부모 b481b85018
커밋 1f4a0ce9e6
2개의 변경된 파일401개의 추가작업 그리고 189개의 파일을 삭제

파일 보기

@@ -32,17 +32,18 @@
*/
#ifdef DP_RX_MON_MEM_FRAG
/*
*----------------------------------
*| Reserve | PF Tag | Radiotap hdr|
*| 64B | 64B | 128B |
*----------------------------------
* Reserved 64B is used to fill Protocol & Flow tag before writing into
* actual offset, data gets written to actual offset after updating
* radiotap HDR.
* -------------------------------------------------
* | Protocol & Flow TAG | Radiotap header|
* | | Length(128 B) |
* | ((4* QDF_NBUF_MAX_FRAGS) * 2) | |
* -------------------------------------------------
*/
#define DP_RX_MON_MAX_MONITOR_HEADER (256)
#else
#define DP_RX_MON_MAX_MONITOR_HEADER (512)
#define DP_RX_MON_MAX_RADIO_TAP_HDR (128)
#define DP_RX_MON_PF_TAG_LEN_PER_FRAG (4)
#define DP_RX_MON_TOT_PF_TAG_LEN \
((DP_RX_MON_PF_TAG_LEN_PER_FRAG) * (QDF_NBUF_MAX_FRAGS))
#define DP_RX_MON_MAX_MONITOR_HEADER \
((DP_RX_MON_TOT_PF_TAG_LEN * 2) + (DP_RX_MON_MAX_RADIO_TAP_HDR))
#endif
/* The maximum buffer length allocated for radiotap for monitor status buffer */
@@ -356,6 +357,41 @@ void dp_rx_mon_frag_adjust_frag_len(uint32_t *total_len, uint32_t *frag_len,
#define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \
NULL
/**
* dp_rx_mon_add_msdu_to_list_failure_handler() - Handler for nbuf buffer
* attach failure
*
* @rx_tlv_hdr: rx_tlv_hdr
* @pdev: struct dp_pdev *
* @last: skb pointing to last skb in chained list at any moment
* @head_msdu: parent skb in the chained list
* @tail_msdu: Last skb in the chained list
* @func_name: caller function name
*
* Return: void
*/
static inline void
dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr,
struct dp_pdev *pdev,
qdf_nbuf_t *last,
qdf_nbuf_t *head_msdu,
qdf_nbuf_t *tail_msdu,
const char *func_name)
{
DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1);
qdf_frag_free(rx_tlv_hdr);
if (head_msdu)
qdf_nbuf_list_free(*head_msdu);
dp_err("[%s] failed to allocate subsequent parent buffer to hold all frag\n",
func_name);
if (head_msdu)
*head_msdu = NULL;
if (last)
*last = NULL;
if (tail_msdu)
*tail_msdu = NULL;
}
/**
* dp_rx_mon_get_paddr_from_desc() - Get paddr from desc
*/
@@ -413,20 +449,28 @@ dp_rx_mon_buffer_unmap(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
static inline
QDF_STATUS dp_rx_mon_alloc_parent_buffer(qdf_nbuf_t *head_msdu)
{
/* Headroom should accommodate radiotap header
/*
* Headroom should accommodate radiotap header
* and protocol and flow tag for all frag
* Length reserved to accommodate Radiotap header
* is 128 bytes and length reserved for Protocol
* flow tag will vary based on QDF_NBUF_MAX_FRAGS.
*/
/* --------------------------------------
* | Protocol & Flow TAG | Radiotap header|
* | 64 B | Length(128 B) |
* --------------------------------------
/* -------------------------------------------------
* | Protocol & Flow TAG | Radiotap header|
* | | Length(128 B) |
* | ((4* QDF_NBUF_MAX_FRAGS) * 2) | |
* -------------------------------------------------
*/
*head_msdu = qdf_nbuf_alloc_no_recycler(DP_RX_MON_MAX_MONITOR_HEADER,
DP_RX_MON_MAX_MONITOR_HEADER, 4);
if (!(*head_msdu))
return QDF_STATUS_E_FAILURE;
qdf_mem_zero(qdf_nbuf_head(*head_msdu), qdf_nbuf_headroom(*head_msdu));
/* Set *head_msdu->next as NULL as all msdus are
* mapped via nr frags
*/
@@ -577,26 +621,85 @@ static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size)
* @l2_hdr_offset: l2 hdr padding
*/
static inline
void dp_rx_mon_add_msdu_to_list(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t *last, qdf_frag_t rx_desc_tlv,
uint32_t frag_len, uint32_t l2_hdr_offset)
QDF_STATUS dp_rx_mon_add_msdu_to_list(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t *last, qdf_frag_t rx_desc_tlv,
uint32_t frag_len,
uint32_t l2_hdr_offset)
{
qdf_nbuf_add_rx_frag(rx_desc_tlv, *head_msdu, SIZE_OF_MONITOR_TLV,
uint32_t num_frags;
qdf_nbuf_t msdu_curr;
/* Here head_msdu and *head_msdu must not be NULL */
if (qdf_unlikely(!head_msdu || !(*head_msdu))) {
dp_err("[%s] head_msdu || *head_msdu is Null while adding frag to skb\n",
__func__);
return QDF_STATUS_E_FAILURE;
}
/* In case of first desc of MPDU, assign curr msdu to *head_msdu */
if (!qdf_nbuf_get_nr_frags(*head_msdu))
msdu_curr = *head_msdu;
else
msdu_curr = *last;
/* Current msdu must not be NULL */
if (qdf_unlikely(!msdu_curr)) {
dp_err("[%s] Current msdu can't be Null while adding frag to skb\n",
__func__);
return QDF_STATUS_E_FAILURE;
}
num_frags = qdf_nbuf_get_nr_frags(msdu_curr);
if (num_frags < QDF_NBUF_MAX_FRAGS) {
qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr,
SIZE_OF_MONITOR_TLV,
frag_len + l2_hdr_offset,
RX_MONITOR_BUFFER_SIZE,
false);
if (*last != msdu_curr)
*last = msdu_curr;
return QDF_STATUS_SUCCESS;
}
/* Execution will reach here only if num_frags == QDF_NBUF_MAX_FRAGS */
msdu_curr = NULL;
if ((dp_rx_mon_alloc_parent_buffer(&msdu_curr))
!= QDF_STATUS_SUCCESS)
return QDF_STATUS_E_FAILURE;
qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr, SIZE_OF_MONITOR_TLV,
frag_len + l2_hdr_offset, RX_MONITOR_BUFFER_SIZE,
false);
/* Add allocated nbuf in the chain */
qdf_nbuf_set_next(*last, msdu_curr);
/* Assign current msdu to last to avoid traversal */
*last = msdu_curr;
return QDF_STATUS_SUCCESS;
}
/**
* dp_rx_mon_init_tail_msdu() - Initialize tail msdu
*
* @head_msdu: Parent buffer to hold MPDU data
* @msdu: Msdu to be updated in tail_msdu
* @last: last msdu
* @tail_msdu: Last msdu
*/
static inline
void dp_rx_mon_init_tail_msdu(qdf_nbuf_t msdu, qdf_nbuf_t last,
qdf_nbuf_t *tail_msdu)
void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t last, qdf_nbuf_t *tail_msdu)
{
if (!head_msdu || !(*head_msdu)) {
*tail_msdu = NULL;
return;
}
if (last)
qdf_nbuf_set_next(last, NULL);
*tail_msdu = last;
}
/**
@@ -605,22 +708,29 @@ void dp_rx_mon_init_tail_msdu(qdf_nbuf_t msdu, qdf_nbuf_t last,
* If feature is disabled, then removal happens in restitch logic.
*
* @head_msdu: Head msdu
* @tail_msdu: Tail msdu
*/
static inline
void dp_rx_mon_remove_raw_frame_fcs_len(qdf_nbuf_t *head_msdu)
void dp_rx_mon_remove_raw_frame_fcs_len(qdf_nbuf_t *head_msdu,
qdf_nbuf_t *tail_msdu)
{
qdf_frag_t addr;
if (qdf_unlikely(!head_msdu || !tail_msdu || !(*head_msdu)))
return;
/* If *head_msdu is valid, then *tail_msdu must be valid */
/* If head_msdu is valid, then it must have nr_frags */
/* If tail_msdu is valid, then it must have nr_frags */
/* Strip FCS_LEN for Raw frame */
if (head_msdu && *head_msdu) {
addr = qdf_nbuf_get_frag_addr(*head_msdu, 0);
addr -= SIZE_OF_MONITOR_TLV;
if (HAL_RX_DESC_GET_DECAP_FORMAT(addr) ==
HAL_HW_RX_DECAP_FORMAT_RAW) {
qdf_nbuf_trim_add_frag_size(*head_msdu,
qdf_nbuf_get_nr_frags(*head_msdu) - 1,
-HAL_RX_FCS_LEN, 0);
}
addr = qdf_nbuf_get_frag_addr(*head_msdu, 0);
addr -= SIZE_OF_MONITOR_TLV;
if (HAL_RX_DESC_GET_DECAP_FORMAT(addr) ==
HAL_HW_RX_DECAP_FORMAT_RAW) {
qdf_nbuf_trim_add_frag_size(*tail_msdu,
qdf_nbuf_get_nr_frags(*tail_msdu) - 1,
-HAL_RX_FCS_LEN, 0);
}
}
@@ -658,6 +768,16 @@ qdf_frag_t dp_rx_mon_get_nbuf_80211_hdr(qdf_nbuf_t nbuf)
#define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \
(rx_desc->nbuf)
static inline void
dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr,
struct dp_pdev *pdev,
qdf_nbuf_t *last,
qdf_nbuf_t *head_msdu,
qdf_nbuf_t *tail_msdu,
const char *func_name)
{
}
static inline
qdf_dma_addr_t dp_rx_mon_get_paddr_from_desc(struct dp_rx_desc *rx_desc)
{
@@ -738,9 +858,10 @@ static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size)
}
static inline
void dp_rx_mon_add_msdu_to_list(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t *last, qdf_frag_t rx_desc_tlv,
uint32_t frag_len, uint32_t l2_hdr_offset)
QDF_STATUS dp_rx_mon_add_msdu_to_list(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t *last, qdf_frag_t rx_desc_tlv,
uint32_t frag_len,
uint32_t l2_hdr_offset)
{
if (head_msdu && !*head_msdu) {
*head_msdu = msdu;
@@ -749,11 +870,12 @@ void dp_rx_mon_add_msdu_to_list(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_set_next(*last, msdu);
}
*last = msdu;
return QDF_STATUS_SUCCESS;
}
static inline
void dp_rx_mon_init_tail_msdu(qdf_nbuf_t msdu, qdf_nbuf_t last,
qdf_nbuf_t *tail_msdu)
void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
qdf_nbuf_t last, qdf_nbuf_t *tail_msdu)
{
if (last)
qdf_nbuf_set_next(last, NULL);
@@ -762,7 +884,8 @@ void dp_rx_mon_init_tail_msdu(qdf_nbuf_t msdu, qdf_nbuf_t last,
}
static inline
void dp_rx_mon_remove_raw_frame_fcs_len(qdf_nbuf_t *head_msdu)
void dp_rx_mon_remove_raw_frame_fcs_len(qdf_nbuf_t *head_msdu,
qdf_nbuf_t *tail_msdu)
{
}