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:
Jeevan Kukkalli
2022-06-22 20:37:18 +05:30
committed by Madan Koyyalamudi
parent fc7daffbd0
commit e0231b2771
5 changed files with 50 additions and 10 deletions

View File

@@ -380,6 +380,7 @@ enum cdp_mon_phyrx_abort_reason_code {
* @mon_rx_desc_invalid: rx_desc invalid count * @mon_rx_desc_invalid: rx_desc invalid count
* @mpdu_ppdu_id_mismatch_drop: mpdu's ppdu id did not match destination * @mpdu_ppdu_id_mismatch_drop: mpdu's ppdu id did not match destination
* ring ppdu id * ring ppdu id
* @mpdu_decap_type_invalid: mpdu decap type invalid count
* @rx_undecoded_count: Received undecoded frame count * @rx_undecoded_count: Received undecoded frame count
* @rx_undecoded_error: Rx undecoded errors * @rx_undecoded_error: Rx undecoded errors
* @rx_hdr_not_received: Rx HDR not received for MPDU * @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_rx_desc_invalid;
uint32_t mon_nbuf_sanity_err; uint32_t mon_nbuf_sanity_err;
uint32_t mpdu_ppdu_id_mismatch_drop; uint32_t mpdu_ppdu_id_mismatch_drop;
uint32_t mpdu_decap_type_invalid;
#ifdef QCA_UNDECODED_METADATA_SUPPORT #ifdef QCA_UNDECODED_METADATA_SUPPORT
uint32_t rx_undecoded_count; uint32_t rx_undecoded_count;
uint32_t rx_undecoded_error[CDP_PHYRX_ERR_MAX]; uint32_t rx_undecoded_error[CDP_PHYRX_ERR_MAX];

View File

@@ -37,6 +37,9 @@
#define DP_MON_MSDU_LOGGING 0 #define DP_MON_MSDU_LOGGING 0
#define DP_MON_MPDU_LOGGING 1 #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 */ /* monitor frame filter modes */
enum dp_mon_frm_filter_mode { enum dp_mon_frm_filter_mode {
/* mode filter pass */ /* mode filter pass */

View File

@@ -391,7 +391,7 @@ dp_rx_mon_process_ppdu_info(struct dp_pdev *pdev,
status = dp_lite_mon_rx_mpdu_process(pdev, ppdu_info, status = dp_lite_mon_rx_mpdu_process(pdev, ppdu_info,
mpdu, mpdu_idx, user); mpdu, mpdu_idx, user);
if (status != QDF_STATUS_SUCCESS) { if (status != QDF_STATUS_SUCCESS) {
qdf_nbuf_free(mpdu); dp_mon_free_parent_nbuf(mon_pdev, mpdu);
continue; continue;
} }
} else { } else {
@@ -401,8 +401,12 @@ dp_rx_mon_process_ppdu_info(struct dp_pdev *pdev,
continue; continue;
} }
dp_rx_mon_handle_full_mon(pdev, status = dp_rx_mon_handle_full_mon(pdev,
ppdu_info, mpdu); ppdu_info, mpdu);
if (status != QDF_STATUS_SUCCESS) {
dp_mon_free_parent_nbuf(mon_pdev, mpdu);
continue;
}
} else { } else {
dp_mon_free_parent_nbuf(mon_pdev, mpdu); dp_mon_free_parent_nbuf(mon_pdev, mpdu);
continue; continue;
@@ -519,7 +523,7 @@ dp_rx_mon_add_ppdu_info_to_wq(struct dp_pdev *pdev,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
void QDF_STATUS
dp_rx_mon_handle_full_mon(struct dp_pdev *pdev, dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
struct hal_rx_ppdu_info *ppdu_info, struct hal_rx_ppdu_info *ppdu_info,
qdf_nbuf_t mpdu) 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_trim_add_frag_size(mpdu,
qdf_nbuf_get_nr_frags(mpdu) - 1, qdf_nbuf_get_nr_frags(mpdu) - 1,
-HAL_RX_FCS_LEN, 0); -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; 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); 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[ppdu_info->user_id].mpdu_start_received = true;
ppdu_info->mpdu_info[user_id].first_rx_hdr_rcvd = 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 { } else {
if (ppdu_info->mpdu_info[user_id].decap_type == if (ppdu_info->mpdu_info[user_id].decap_type ==
HAL_HW_RX_DECAP_FORMAT_RAW) { 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; 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); tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf);
if (!tmp_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 */ /* update msdu metadata at last buffer of msdu in MPDU */
nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx]; nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx];
if (!nbuf) { 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); dp_mon_err(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx);
break; 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, dp_rx_mon_pf_tag_to_buf_headroom_2_0(nbuf, ppdu_info, pdev,
soc); soc);
/* reset msdu info for next msdu for same user */ /* 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, /* If flow classification is enabled,
* update cce_metadata and fse_metadata * 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]; mpdu_info = &ppdu_info->mpdu_info[user_id];
nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx]; nbuf = ppdu_info->mpdu_q[user_id][mpdu_idx];
if (!nbuf) { 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); dp_mon_err(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx);
break; 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->full_pkt = mpdu_info->full_pkt;
mpdu_meta->truncated = mpdu_info->truncated; mpdu_meta->truncated = mpdu_info->truncated;
num_frags = qdf_nbuf_get_nr_frags(nbuf);
ppdu_info->mpdu_q[user_id][mpdu_idx] = nbuf; ppdu_info->mpdu_q[user_id][mpdu_idx] = nbuf;
/* reset msdu info for next msdu for same user */ /* reset mpdu info for next mpdu for same user */
qdf_mem_zero(mpdu_info, sizeof(mpdu_info)); qdf_mem_zero(mpdu_info, sizeof(*mpdu_info));
ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false; ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false;
ppdu_info->mpdu_count[user_id]++; ppdu_info->mpdu_count[user_id]++;
} }

View File

@@ -171,8 +171,10 @@ static inline void dp_rx_mon_process_ppdu(void *context)
* @pdev: DP pdev * @pdev: DP pdev
* @ppdu_info: PPDU info * @ppdu_info: PPDU info
* @mpdu: mpdu buf * @mpdu: mpdu buf
*
* Return: SUCCESS or Failure
*/ */
void QDF_STATUS
dp_rx_mon_handle_full_mon(struct dp_pdev *pdev, dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
struct hal_rx_ppdu_info *ppdu_info, struct hal_rx_ppdu_info *ppdu_info,
qdf_nbuf_t mpdu); qdf_nbuf_t mpdu);

View File

@@ -872,6 +872,8 @@ dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
rx_mon_stats->dest_ppdu_drop); rx_mon_stats->dest_ppdu_drop);
DP_PRINT_STATS("mpdu_ppdu_id_mismatch_drop = %u", DP_PRINT_STATS("mpdu_ppdu_id_mismatch_drop = %u",
rx_mon_stats->mpdu_ppdu_id_mismatch_drop); 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 = stat_ring_ppdu_ids =
(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST); (uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
dest_ring_ppdu_ids = dest_ring_ppdu_ids =