qcacmn: Handle invalid decap type during rx mon tlv processing
- Handle scenario where decap type may be invalid when buff address tlv is received. - Add check for min number of frags during restitch process. - Minor fixes during rx mon tlv processing. Change-Id: I0120d97e297701362183189e29c1d5df91affdc1 CRs-Fixed: 3216050
This commit is contained in:

committed by
Madan Koyyalamudi

parent
fc7daffbd0
commit
e0231b2771
@@ -380,6 +380,7 @@ enum cdp_mon_phyrx_abort_reason_code {
|
||||
* @mon_rx_desc_invalid: rx_desc invalid count
|
||||
* @mpdu_ppdu_id_mismatch_drop: mpdu's ppdu id did not match destination
|
||||
* ring ppdu id
|
||||
* @mpdu_decap_type_invalid: mpdu decap type invalid count
|
||||
* @rx_undecoded_count: Received undecoded frame count
|
||||
* @rx_undecoded_error: Rx undecoded errors
|
||||
* @rx_hdr_not_received: Rx HDR not received for MPDU
|
||||
@@ -425,6 +426,7 @@ struct cdp_pdev_mon_stats {
|
||||
uint32_t mon_rx_desc_invalid;
|
||||
uint32_t mon_nbuf_sanity_err;
|
||||
uint32_t mpdu_ppdu_id_mismatch_drop;
|
||||
uint32_t mpdu_decap_type_invalid;
|
||||
#ifdef QCA_UNDECODED_METADATA_SUPPORT
|
||||
uint32_t rx_undecoded_count;
|
||||
uint32_t rx_undecoded_error[CDP_PHYRX_ERR_MAX];
|
||||
|
@@ -37,6 +37,9 @@
|
||||
#define DP_MON_MSDU_LOGGING 0
|
||||
#define DP_MON_MPDU_LOGGING 1
|
||||
|
||||
#define DP_MON_DECAP_FORMAT_INVALID 0xff
|
||||
#define DP_MON_MIN_FRAGS_FOR_RESTITCH 2
|
||||
|
||||
/* monitor frame filter modes */
|
||||
enum dp_mon_frm_filter_mode {
|
||||
/* mode filter pass */
|
||||
|
@@ -391,7 +391,7 @@ dp_rx_mon_process_ppdu_info(struct dp_pdev *pdev,
|
||||
status = dp_lite_mon_rx_mpdu_process(pdev, ppdu_info,
|
||||
mpdu, mpdu_idx, user);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
qdf_nbuf_free(mpdu);
|
||||
dp_mon_free_parent_nbuf(mon_pdev, mpdu);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@@ -401,8 +401,12 @@ dp_rx_mon_process_ppdu_info(struct dp_pdev *pdev,
|
||||
continue;
|
||||
}
|
||||
|
||||
dp_rx_mon_handle_full_mon(pdev,
|
||||
status = dp_rx_mon_handle_full_mon(pdev,
|
||||
ppdu_info, mpdu);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_mon_free_parent_nbuf(mon_pdev, mpdu);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
dp_mon_free_parent_nbuf(mon_pdev, mpdu);
|
||||
continue;
|
||||
@@ -519,7 +523,7 @@ dp_rx_mon_add_ppdu_info_to_wq(struct dp_pdev *pdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
QDF_STATUS
|
||||
dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
|
||||
struct hal_rx_ppdu_info *ppdu_info,
|
||||
qdf_nbuf_t mpdu)
|
||||
@@ -557,7 +561,13 @@ dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
|
||||
qdf_nbuf_trim_add_frag_size(mpdu,
|
||||
qdf_nbuf_get_nr_frags(mpdu) - 1,
|
||||
-HAL_RX_FCS_LEN, 0);
|
||||
return;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
num_frags = qdf_nbuf_get_nr_frags(mpdu);
|
||||
if (qdf_unlikely(num_frags < DP_MON_MIN_FRAGS_FOR_RESTITCH)) {
|
||||
dp_mon_debug("not enough frags(%d) for restitch", num_frags);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
l2_hdr_offset = DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
|
||||
@@ -824,6 +834,8 @@ dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
|
||||
msdu_cur = qdf_nbuf_queue_next(msdu_cur);
|
||||
}
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -978,6 +990,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
}
|
||||
ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true;
|
||||
ppdu_info->mpdu_info[user_id].first_rx_hdr_rcvd = true;
|
||||
/* initialize decap type to invalid, this will be set to appropriate
|
||||
* value once the mpdu start tlv is received
|
||||
*/
|
||||
ppdu_info->mpdu_info[user_id].decap_type = DP_MON_DECAP_FORMAT_INVALID;
|
||||
} else {
|
||||
if (ppdu_info->mpdu_info[user_id].decap_type ==
|
||||
HAL_HW_RX_DECAP_FORMAT_RAW) {
|
||||
@@ -1056,6 +1072,18 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
return num_buf_reaped;
|
||||
}
|
||||
|
||||
if (mpdu_info->decap_type == DP_MON_DECAP_FORMAT_INVALID) {
|
||||
/* decap type is invalid, drop the frame */
|
||||
mon_pdev->rx_mon_stats.mpdu_decap_type_invalid++;
|
||||
DP_STATS_INC(mon_soc, frag_free, 1);
|
||||
mon_pdev->rx_mon_stats.parent_buf_free++;
|
||||
qdf_frag_free(addr);
|
||||
qdf_nbuf_free(nbuf);
|
||||
/* we have freed the nbuf mark the q entry null */
|
||||
ppdu_info->mpdu_q[user_id][mpdu_idx] = NULL;
|
||||
return num_buf_reaped;
|
||||
}
|
||||
|
||||
tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf);
|
||||
|
||||
if (!tmp_nbuf) {
|
||||
@@ -1132,6 +1160,8 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
/* update msdu metadata at last buffer of msdu in MPDU */
|
||||
nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx];
|
||||
if (!nbuf) {
|
||||
/* reset msdu info for next msdu for same user */
|
||||
qdf_mem_zero(msdu_info, sizeof(*msdu_info));
|
||||
dp_mon_err(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx);
|
||||
break;
|
||||
}
|
||||
@@ -1157,7 +1187,7 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
dp_rx_mon_pf_tag_to_buf_headroom_2_0(nbuf, ppdu_info, pdev,
|
||||
soc);
|
||||
/* reset msdu info for next msdu for same user */
|
||||
qdf_mem_zero(msdu_info, sizeof(msdu_info));
|
||||
qdf_mem_zero(msdu_info, sizeof(*msdu_info));
|
||||
|
||||
/* If flow classification is enabled,
|
||||
* update cce_metadata and fse_metadata
|
||||
@@ -1185,6 +1215,8 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
mpdu_info = &ppdu_info->mpdu_info[user_id];
|
||||
nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx];
|
||||
if (!nbuf) {
|
||||
/* reset mpdu info for next mpdu for same user */
|
||||
qdf_mem_zero(mpdu_info, sizeof(*mpdu_info));
|
||||
dp_mon_err(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx);
|
||||
break;
|
||||
}
|
||||
@@ -1197,10 +1229,9 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
|
||||
mpdu_meta->full_pkt = mpdu_info->full_pkt;
|
||||
mpdu_meta->truncated = mpdu_info->truncated;
|
||||
|
||||
num_frags = qdf_nbuf_get_nr_frags(nbuf);
|
||||
ppdu_info->mpdu_q[user_id][mpdu_idx] = nbuf;
|
||||
/* reset msdu info for next msdu for same user */
|
||||
qdf_mem_zero(mpdu_info, sizeof(mpdu_info));
|
||||
/* reset mpdu info for next mpdu for same user */
|
||||
qdf_mem_zero(mpdu_info, sizeof(*mpdu_info));
|
||||
ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false;
|
||||
ppdu_info->mpdu_count[user_id]++;
|
||||
}
|
||||
|
@@ -171,8 +171,10 @@ static inline void dp_rx_mon_process_ppdu(void *context)
|
||||
* @pdev: DP pdev
|
||||
* @ppdu_info: PPDU info
|
||||
* @mpdu: mpdu buf
|
||||
*
|
||||
* Return: SUCCESS or Failure
|
||||
*/
|
||||
void
|
||||
QDF_STATUS
|
||||
dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
|
||||
struct hal_rx_ppdu_info *ppdu_info,
|
||||
qdf_nbuf_t mpdu);
|
||||
|
@@ -872,6 +872,8 @@ dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
|
||||
rx_mon_stats->dest_ppdu_drop);
|
||||
DP_PRINT_STATS("mpdu_ppdu_id_mismatch_drop = %u",
|
||||
rx_mon_stats->mpdu_ppdu_id_mismatch_drop);
|
||||
DP_PRINT_STATS("mpdu_decap_type_invalid = %u",
|
||||
rx_mon_stats->mpdu_decap_type_invalid);
|
||||
stat_ring_ppdu_ids =
|
||||
(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
|
||||
dest_ring_ppdu_ids =
|
||||
|
Reference in New Issue
Block a user