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

vanhempi
fc7daffbd0
commit
e0231b2771
@@ -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];
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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]++;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 =
|
||||||
|
Viittaa uudesa ongelmassa
Block a user