1
0

qcacmn: Handle scattered msdu in OOR error scenario

In OOR error handling scenario, msdu is spread across
two nbufs. Due to this, there is a mismatch between
msdu count fetched from MPDU desc detatils and count
fetched from rx link descriptor.

Fix is to create frag list for the case where msdu
is spread across multiple nbufs.

Change-Id: I1d600a0988b373e68aad6ef815fb2d775763b7cb
CRs-Fixed: 2665963
Este cometimento está contido em:
Yeshwanth Sriram Guntuka
2020-04-21 22:23:01 +05:30
cometido por nshrivas
ascendente 4c6b5c6f69
cometimento 7dad533e6c
4 ficheiros modificados com 77 adições e 28 eliminações

Ver ficheiro

@@ -390,6 +390,7 @@ dp_rx_pn_error_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
* @soc: core txrx main context
* @nbuf: pointer to msdu skb
* @peer_id: dp peer ID
* @rx_tlv_hdr: start of rx tlv header
*
* This function process the msdu delivered from REO2TCL
* ring with error type OOR
@@ -399,7 +400,8 @@ dp_rx_pn_error_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
static void
dp_rx_oor_handle(struct dp_soc *soc,
qdf_nbuf_t nbuf,
uint16_t peer_id)
uint16_t peer_id,
uint8_t *rx_tlv_hdr)
{
uint32_t frame_mask = FRAME_MASK_IPV4_ARP | FRAME_MASK_IPV4_DHCP |
FRAME_MASK_IPV4_EAPOL | FRAME_MASK_IPV6_DHCP;
@@ -411,7 +413,8 @@ dp_rx_oor_handle(struct dp_soc *soc,
goto free_nbuf;
}
if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask)) {
if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask,
rx_tlv_hdr)) {
DP_STATS_INC(soc, rx.err.reo_err_oor_to_stack, 1);
dp_peer_unref_del_find_by_id(peer);
return;
@@ -449,7 +452,8 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc,
uint32_t rx_bufs_used = 0;
struct dp_pdev *pdev;
int i;
uint8_t *rx_tlv_hdr;
uint8_t *rx_tlv_hdr_first;
uint8_t *rx_tlv_hdr_last;
uint32_t tid = DP_MAX_TIDS;
uint16_t peer_id;
struct dp_rx_desc *rx_desc;
@@ -461,6 +465,9 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc,
struct buffer_addr_info next_link_desc_addr_info = { 0 };
/* First field in REO Dst ring Desc is buffer_addr_info */
void *buf_addr_info = ring_desc;
qdf_nbuf_t head_nbuf = NULL;
qdf_nbuf_t tail_nbuf = NULL;
uint16_t msdu_processed = 0;
peer_id = DP_PEER_METADATA_PEER_ID_GET(
mpdu_desc_info->peer_meta_data);
@@ -482,8 +489,25 @@ more_msdu_link_desc:
qdf_nbuf_unmap_single(soc->osdev,
nbuf, QDF_DMA_FROM_DEVICE);
rx_tlv_hdr = qdf_nbuf_data(nbuf);
QDF_NBUF_CB_RX_PKT_LEN(nbuf) = msdu_list.msdu_info[i].msdu_len;
rx_bufs_used++;
dp_rx_add_to_free_desc_list(&pdev->free_list_head,
&pdev->free_list_tail, rx_desc);
DP_RX_LIST_APPEND(head_nbuf, tail_nbuf, nbuf);
if (qdf_unlikely(msdu_list.msdu_info[i].msdu_flags &
HAL_MSDU_F_MSDU_CONTINUATION))
continue;
rx_tlv_hdr_first = qdf_nbuf_data(head_nbuf);
rx_tlv_hdr_last = qdf_nbuf_data(tail_nbuf);
if (qdf_unlikely(head_nbuf != tail_nbuf)) {
nbuf = dp_rx_sg_create(head_nbuf);
qdf_nbuf_set_is_frag(nbuf, 1);
DP_STATS_INC(soc, rx.err.reo_err_oor_sg_count, 1);
}
switch (err_code) {
case HAL_REO_ERR_REGULAR_FRAME_2K_JUMP:
@@ -492,28 +516,28 @@ more_msdu_link_desc:
* and use it for following msdu.
*/
if (hal_rx_msdu_end_first_msdu_get(soc->hal_soc,
rx_tlv_hdr))
rx_tlv_hdr_last))
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
rx_tlv_hdr);
rx_tlv_hdr_first);
dp_2k_jump_handle(soc, nbuf, rx_tlv_hdr,
dp_2k_jump_handle(soc, nbuf, rx_tlv_hdr_last,
peer_id, tid);
break;
case HAL_REO_ERR_REGULAR_FRAME_OOR:
dp_rx_oor_handle(soc, nbuf, peer_id);
dp_rx_oor_handle(soc, nbuf, peer_id, rx_tlv_hdr_last);
break;
default:
dp_err_rl("Non-support error code %d", err_code);
qdf_nbuf_free(nbuf);
}
dp_rx_add_to_free_desc_list(&pdev->free_list_head,
&pdev->free_list_tail, rx_desc);
rx_bufs_used++;
msdu_processed++;
head_nbuf = NULL;
tail_nbuf = NULL;
}
if (rx_bufs_used < mpdu_desc_info->msdu_count) {
if (msdu_processed < mpdu_desc_info->msdu_count) {
hal_rx_get_next_msdu_link_desc_buf_addr_info(
link_desc_va,
&next_link_desc_addr_info);
@@ -539,7 +563,7 @@ more_msdu_link_desc:
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
QDF_BUG(rx_bufs_used == mpdu_desc_info->msdu_count);
QDF_BUG(msdu_processed == mpdu_desc_info->msdu_count);
return rx_bufs_used;
}
@@ -755,7 +779,8 @@ dp_2k_jump_handle(struct dp_soc *soc,
}
nbuf_deliver:
if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask)) {
if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask,
rx_tlv_hdr)) {
DP_STATS_INC(soc, rx.err.rx_2k_jump_to_stack, 1);
dp_peer_unref_del_find_by_id(peer);
return;