qcacmn: WBM msdu continuation for SG in QCN9000
In QCN9000, wbm release ring has msdu continuation bit support for invld peer MPDUs. Host needs to form SG buffer for packets with msdu continuation bit set Change-Id: Ica03c78068d32d2c8dc609b9a50298b91dd48c0a
This commit is contained in:
@@ -813,11 +813,19 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1,
|
||||
qdf_nbuf_len(nbuf));
|
||||
|
||||
mpdu_done = dp_rx_chain_msdus(soc, nbuf, rx_tlv_hdr, pool_id);
|
||||
/* Trigger invalid peer handler wrapper */
|
||||
dp_rx_process_invalid_peer_wrapper(soc,
|
||||
pdev->invalid_peer_head_msdu,
|
||||
mpdu_done, pool_id);
|
||||
/* QCN9000 has the support enabled */
|
||||
if (qdf_unlikely(soc->wbm_release_desc_rx_sg_support)) {
|
||||
mpdu_done = true;
|
||||
/* Trigger invalid peer handler wrapper */
|
||||
dp_rx_process_invalid_peer_wrapper(soc,
|
||||
nbuf, mpdu_done, pool_id);
|
||||
} else {
|
||||
mpdu_done = dp_rx_chain_msdus(soc, nbuf, rx_tlv_hdr, pool_id);
|
||||
/* Trigger invalid peer handler wrapper */
|
||||
dp_rx_process_invalid_peer_wrapper(soc,
|
||||
pdev->invalid_peer_head_msdu,
|
||||
mpdu_done, pool_id);
|
||||
}
|
||||
|
||||
if (mpdu_done) {
|
||||
pdev->invalid_peer_head_msdu = NULL;
|
||||
@@ -1442,6 +1450,11 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
struct hal_wbm_err_desc_info wbm_err_info = { 0 };
|
||||
uint8_t pool_id;
|
||||
uint8_t tid = 0;
|
||||
uint8_t msdu_continuation = 0;
|
||||
bool first_msdu_in_sg = false;
|
||||
bool is_raw_mode = false;
|
||||
uint32_t msdu_len = 0;
|
||||
|
||||
|
||||
/* Debug -- Remove later */
|
||||
qdf_assert(soc && hal_ring_hdl);
|
||||
@@ -1463,9 +1476,30 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (qdf_likely(quota-- && (ring_desc =
|
||||
hal_srng_dst_get_next(hal_soc,
|
||||
hal_ring_hdl)))) {
|
||||
while (qdf_likely(quota)) {
|
||||
ring_desc = hal_srng_dst_get_next(hal_soc, hal_ring_hdl);
|
||||
|
||||
if (qdf_unlikely(!ring_desc)) {
|
||||
/* Check hw hp in case of SG support */
|
||||
if (qdf_unlikely(soc->wbm_release_desc_rx_sg_support)) {
|
||||
/*
|
||||
* Update the cached hp from hw hp
|
||||
* This is required for partially created
|
||||
* SG packets while quote is still left
|
||||
*/
|
||||
hal_srng_sync_cachedhp(hal_soc, hal_ring_hdl);
|
||||
ring_desc = hal_srng_dst_get_next(hal_soc, hal_ring_hdl);
|
||||
if (!ring_desc) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("No Rx Hw Desc for intermediate sg -- %pK"),
|
||||
hal_ring_hdl);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Come out of the loop in Non SG support cases */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX */
|
||||
buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc);
|
||||
@@ -1519,6 +1553,31 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
ring_desc, rx_desc);
|
||||
}
|
||||
|
||||
if (qdf_unlikely(soc->wbm_release_desc_rx_sg_support)) {
|
||||
/* SG is detected from continuation bit */
|
||||
msdu_continuation = hal_rx_wbm_err_msdu_continuation_get(hal_soc,
|
||||
ring_desc);
|
||||
if (msdu_continuation && !first_msdu_in_sg) {
|
||||
/* Update length from first buffer in SG */
|
||||
msdu_len = hal_rx_msdu_start_msdu_len_get(
|
||||
qdf_nbuf_data(rx_desc->nbuf));
|
||||
first_msdu_in_sg = true;
|
||||
QDF_NBUF_CB_RX_PKT_LEN(rx_desc->nbuf) = msdu_len;
|
||||
}
|
||||
|
||||
if (msdu_continuation) {
|
||||
/* MSDU continued packets */
|
||||
qdf_nbuf_set_rx_chfrag_cont(rx_desc->nbuf, 1);
|
||||
QDF_NBUF_CB_RX_PKT_LEN(rx_desc->nbuf) = msdu_len;
|
||||
} else {
|
||||
/* This is the terminal packet in SG */
|
||||
qdf_nbuf_set_rx_chfrag_start(rx_desc->nbuf, 1);
|
||||
qdf_nbuf_set_rx_chfrag_end(rx_desc->nbuf, 1);
|
||||
QDF_NBUF_CB_RX_PKT_LEN(rx_desc->nbuf) = msdu_len;
|
||||
first_msdu_in_sg = false;
|
||||
}
|
||||
}
|
||||
|
||||
nbuf = rx_desc->nbuf;
|
||||
qdf_nbuf_unmap_single(soc->osdev, nbuf, QDF_DMA_FROM_DEVICE);
|
||||
|
||||
@@ -1537,6 +1596,14 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id],
|
||||
&tail[rx_desc->pool_id],
|
||||
rx_desc);
|
||||
|
||||
/*
|
||||
* if continuation bit is set then we have MSDU spread
|
||||
* across multiple buffers, let us not decrement quota
|
||||
* till we reap all buffers of that MSDU.
|
||||
*/
|
||||
if (qdf_likely(!msdu_continuation))
|
||||
quota -= 1;
|
||||
}
|
||||
done:
|
||||
dp_srng_access_end(int_ctx, soc, hal_ring_hdl);
|
||||
@@ -1581,9 +1648,26 @@ done:
|
||||
|
||||
next = nbuf->next;
|
||||
|
||||
/*
|
||||
* Form the SG for msdu continued buffers
|
||||
* QCN9000 has this support
|
||||
*/
|
||||
if (qdf_nbuf_is_rx_chfrag_cont(nbuf)) {
|
||||
nbuf = dp_rx_sg_create(nbuf);
|
||||
next = nbuf->next;
|
||||
is_raw_mode = HAL_IS_DECAP_FORMAT_RAW(soc->hal_soc, qdf_nbuf_data(nbuf));
|
||||
if (!is_raw_mode) {
|
||||
/* Free the pacckets in case of 802.3 SG */
|
||||
qdf_nbuf_free(nbuf);
|
||||
dp_info_rl("scattered 802.3 msdu dropped");
|
||||
nbuf = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (wbm_err_info.wbm_err_src == HAL_RX_WBM_ERR_SRC_REO) {
|
||||
if (wbm_err_info.reo_psh_rsn
|
||||
== HAL_RX_WBM_REO_PSH_RSN_ERROR) {
|
||||
== HAL_RX_WBM_REO_PSH_RSN_ERROR) {
|
||||
|
||||
DP_STATS_INC(soc,
|
||||
rx.err.reo_error
|
||||
|
Reference in New Issue
Block a user