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:

cometido por
nshrivas

ascendente
4c6b5c6f69
cometimento
7dad533e6c
@@ -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;
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador