qcacmn: Add support to handle BAR frames in host
Due to recent FW changes not filtering out BAR frames, redirect these frames to REO exception ring and handle as normal data packets. Change-Id: I4540929fddab14de57a23f6364fc916a70057cbe CRs-Fixed: 2795499
Este commit está contenido en:
@@ -776,9 +776,9 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
}
|
||||
|
||||
static
|
||||
void dp_rx_wbm_err_handle_bar(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
void dp_rx_err_handle_bar(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint8_t *rx_tlv_hdr;
|
||||
unsigned char type, subtype;
|
||||
@@ -817,6 +817,76 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc,
|
||||
start_seq_num);
|
||||
}
|
||||
|
||||
static void
|
||||
dp_rx_bar_frame_handle(struct dp_soc *soc,
|
||||
hal_ring_desc_t ring_desc,
|
||||
struct dp_rx_desc *rx_desc,
|
||||
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
|
||||
uint8_t error)
|
||||
{
|
||||
qdf_nbuf_t nbuf;
|
||||
struct dp_pdev *pdev;
|
||||
struct dp_peer *peer;
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
uint16_t peer_id;
|
||||
uint8_t *rx_tlv_hdr;
|
||||
uint32_t tid;
|
||||
|
||||
nbuf = rx_desc->nbuf;
|
||||
rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id];
|
||||
dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf,
|
||||
rx_desc_pool->buf_size,
|
||||
false);
|
||||
qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
rx_desc->unmapped = 1;
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
peer_id =
|
||||
hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
|
||||
rx_tlv_hdr);
|
||||
peer = dp_peer_get_ref_by_id(soc, peer_id,
|
||||
DP_MOD_ID_RX_ERR);
|
||||
tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
|
||||
rx_tlv_hdr);
|
||||
pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id);
|
||||
|
||||
if (!peer)
|
||||
goto next;
|
||||
|
||||
dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT
|
||||
" peer_id = %d"
|
||||
" tid = %u"
|
||||
" SSN = %d"
|
||||
" error status = %d",
|
||||
QDF_MAC_ADDR_REF(peer->mac_addr.raw),
|
||||
peer->peer_id,
|
||||
tid,
|
||||
mpdu_desc_info->mpdu_seq,
|
||||
error);
|
||||
|
||||
switch (error) {
|
||||
case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
|
||||
/* fallthrough */
|
||||
case HAL_REO_ERR_BAR_FRAME_OOR:
|
||||
dp_rx_err_handle_bar(soc, peer, nbuf);
|
||||
DP_STATS_INC(soc,
|
||||
rx.err.reo_error[error], 1);
|
||||
break;
|
||||
default:
|
||||
DP_STATS_INC(soc, rx.bar_frame, 1);
|
||||
}
|
||||
|
||||
dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
|
||||
next:
|
||||
dp_rx_link_desc_return(soc, ring_desc,
|
||||
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
||||
dp_rx_add_to_free_desc_list(&pdev->free_list_head,
|
||||
&pdev->free_list_tail,
|
||||
rx_desc);
|
||||
qdf_nbuf_free(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_2k_jump_handle() - Function to handle 2k jump exception
|
||||
* on WBM ring
|
||||
@@ -1614,9 +1684,14 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
|
||||
error = HAL_RX_ERROR_STATUS_GET(ring_desc);
|
||||
|
||||
qdf_assert(error == HAL_REO_ERROR_DETECTED);
|
||||
|
||||
buf_type = HAL_RX_REO_BUF_TYPE_GET(ring_desc);
|
||||
|
||||
/* Get the MPDU DESC info */
|
||||
hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
|
||||
|
||||
if (mpdu_desc_info.msdu_count == 0)
|
||||
goto next_entry;
|
||||
|
||||
/*
|
||||
* For REO error ring, expect only MSDU LINK DESC
|
||||
*/
|
||||
@@ -1673,8 +1748,20 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
|
||||
mac_id = rx_desc->pool_id;
|
||||
|
||||
/* Get the MPDU DESC info */
|
||||
hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
|
||||
if (mpdu_desc_info.bar_frame) {
|
||||
qdf_assert_always(mpdu_desc_info.msdu_count == 1);
|
||||
|
||||
dp_rx_bar_frame_handle(soc,
|
||||
ring_desc,
|
||||
rx_desc,
|
||||
&mpdu_desc_info,
|
||||
error);
|
||||
|
||||
rx_bufs_reaped[mac_id] += 1;
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
dp_info("Got pkt with REO ERROR: %d", error);
|
||||
|
||||
if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_FRAGMENT) {
|
||||
/*
|
||||
@@ -1725,6 +1812,11 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expect REO errors to be handled after this point
|
||||
*/
|
||||
qdf_assert_always(error == HAL_REO_ERROR_DETECTED);
|
||||
|
||||
if (hal_rx_reo_is_pn_error(ring_desc)) {
|
||||
/* TOD0 */
|
||||
DP_STATS_INC(soc,
|
||||
@@ -1786,6 +1878,8 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
rx_bufs_reaped[mac_id] += count;
|
||||
goto next_entry;
|
||||
}
|
||||
/* Assert if unexpected error type */
|
||||
qdf_assert_always(0);
|
||||
next_entry:
|
||||
dp_rx_link_cookie_invalidate(ring_desc);
|
||||
hal_srng_dst_get_next(hal_soc, hal_ring_hdl);
|
||||
@@ -2151,9 +2245,9 @@ done:
|
||||
case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
|
||||
case HAL_REO_ERR_BAR_FRAME_OOR:
|
||||
if (peer)
|
||||
dp_rx_wbm_err_handle_bar(soc,
|
||||
peer,
|
||||
nbuf);
|
||||
dp_rx_err_handle_bar(soc,
|
||||
peer,
|
||||
nbuf);
|
||||
qdf_nbuf_free(nbuf);
|
||||
break;
|
||||
|
||||
|
Referencia en una nueva incidencia
Block a user