mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
qcacmn: Lithium LRO Support in the Data Path
Add support to extract LRO information provided by the hardware and utilize the support provided by QDF to perform LRO. Change-Id: I00a26573a450e9c32586b3d5fb656dbfe802cfac CRs-Fixed: 1107169
This commit is contained in:
parent
65bf2306f0
commit
0da3122669
5 changed files with 179 additions and 6 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include <qdf_types.h>
|
||||
#include <qdf_lock.h>
|
||||
#include <qdf_net_types.h>
|
||||
#include <qdf_lro.h>
|
||||
#include <hal_api.h>
|
||||
#include <hif.h>
|
||||
#include <htt.h>
|
||||
|
|
@ -284,7 +285,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||
for (ring = 0; ring < soc->num_reo_dest_rings; ring++) {
|
||||
if (rx_mask & (1 << ring)) {
|
||||
work_done =
|
||||
dp_rx_process(soc,
|
||||
dp_rx_process(int_ctx,
|
||||
soc->reo_dest_ring[ring].hal_srng,
|
||||
budget);
|
||||
budget -= work_done;
|
||||
|
|
@ -312,6 +313,8 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||
}
|
||||
}
|
||||
|
||||
qdf_lro_flush(int_ctx->lro_ctx);
|
||||
|
||||
budget_done:
|
||||
return dp_budget - budget;
|
||||
}
|
||||
|
|
@ -361,6 +364,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
|
|||
soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0x1;
|
||||
soc->intr_ctx[i].reo_status_ring_mask = 0x1;
|
||||
soc->intr_ctx[i].soc = soc;
|
||||
soc->intr_ctx[i].lro_ctx = qdf_lro_init();
|
||||
}
|
||||
|
||||
qdf_timer_init(soc->osdev, &soc->int_timer,
|
||||
|
|
@ -455,6 +459,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
|
|||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
soc->intr_ctx[i].lro_ctx = qdf_lro_init();
|
||||
}
|
||||
|
||||
hif_configure_ext_group_interrupts(soc->hif_handle);
|
||||
|
|
@ -477,6 +482,7 @@ static void dp_soc_interrupt_detach(void *txrx_soc)
|
|||
soc->intr_ctx[i].tx_ring_mask = 0;
|
||||
soc->intr_ctx[i].rx_ring_mask = 0;
|
||||
soc->intr_ctx[i].rx_mon_ring_mask = 0;
|
||||
qdf_lro_deinit(soc->intr_ctx[i].lro_ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1623,6 +1629,14 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev,
|
|||
|
||||
dp_lro_hash_setup(soc);
|
||||
|
||||
/* LRO */
|
||||
if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) &&
|
||||
wlan_op_mode_sta == vdev->opmode)
|
||||
vdev->lro_enable = true;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"LRO: vdev_id %d lro_enable %d", vdev_id, vdev->lro_enable);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Created vdev %p (%pM)", vdev, vdev->mac_addr.raw);
|
||||
DP_STATS_INIT(vdev);
|
||||
|
|
|
|||
|
|
@ -568,6 +568,66 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_rx_lro() - LRO related processing
|
||||
* @rx_tlv: TLV data extracted from the rx packet
|
||||
* @peer: destination peer of the msdu
|
||||
* @msdu: network buffer
|
||||
* @ctx: LRO context
|
||||
*
|
||||
* This function performs the LRO related processing of the msdu
|
||||
*
|
||||
* Return: true: LRO enabled false: LRO is not enabled
|
||||
*/
|
||||
#if defined(FEATURE_LRO)
|
||||
static bool dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer,
|
||||
qdf_nbuf_t msdu, qdf_lro_ctx_t ctx)
|
||||
{
|
||||
qdf_assert(rx_tlv);
|
||||
if (peer->vdev->lro_enable &&
|
||||
HAL_RX_TLV_GET_TCP_PROTO(rx_tlv)) {
|
||||
QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) =
|
||||
HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv) &&
|
||||
!HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv);
|
||||
|
||||
if (QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu)) {
|
||||
QDF_NBUF_CB_RX_LRO_CTX(msdu) = ctx;
|
||||
QDF_NBUF_CB_RX_TCP_ACK_NUM(msdu) =
|
||||
HAL_RX_TLV_GET_TCP_ACK(rx_tlv);
|
||||
QDF_NBUF_CB_RX_TCP_WIN(msdu) =
|
||||
HAL_RX_TLV_GET_TCP_WIN(rx_tlv);
|
||||
QDF_NBUF_CB_RX_TCP_SEQ_NUM(msdu) =
|
||||
HAL_RX_TLV_GET_TCP_SEQ(rx_tlv);
|
||||
QDF_NBUF_CB_RX_TCP_CHKSUM(msdu) =
|
||||
HAL_RX_TLV_GET_TCP_CHKSUM
|
||||
(rx_tlv);
|
||||
QDF_NBUF_CB_RX_FLOW_ID_TOEPLITZ(msdu) =
|
||||
HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ
|
||||
(rx_tlv);
|
||||
QDF_NBUF_CB_RX_TCP_OFFSET(msdu) =
|
||||
HAL_RX_TLV_GET_TCP_OFFSET
|
||||
(rx_tlv);
|
||||
QDF_NBUF_CB_RX_IPV6_PROTO(msdu) =
|
||||
HAL_RX_TLV_GET_IPV6(rx_tlv);
|
||||
|
||||
QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) =
|
||||
qdf_lro_update_info(ctx, msdu);
|
||||
}
|
||||
/* LRO 'enabled' packet, it may not be LRO 'eligible' */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* LRO not supported on this vdev or a non-TCP packet */
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static bool dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer,
|
||||
qdf_nbuf_t msdu, qdf_lro_ctx_t ctx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_rx_process() - Brain of the Rx processing functionality
|
||||
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
|
||||
|
|
@ -581,11 +641,11 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
|||
* Return: uint32_t: No. of elements processed
|
||||
*/
|
||||
uint32_t
|
||||
dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
||||
dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
|
||||
{
|
||||
void *hal_soc;
|
||||
void *ring_desc;
|
||||
struct dp_rx_desc *rx_desc;
|
||||
struct dp_rx_desc *rx_desc = NULL;
|
||||
qdf_nbuf_t nbuf;
|
||||
union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL };
|
||||
union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL };
|
||||
|
|
@ -611,6 +671,7 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
struct dp_pdev *pdev;
|
||||
struct dp_srng *dp_rxdma_srng;
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
struct dp_soc *soc = int_ctx->soc;
|
||||
|
||||
DP_HIST_INIT();
|
||||
/* Debug -- Remove later */
|
||||
|
|
@ -915,6 +976,10 @@ done:
|
|||
continue; /* Get next descriptor */
|
||||
|
||||
rx_bufs_used++;
|
||||
|
||||
if (!dp_rx_lro(rx_tlv_hdr, peer, nbuf, int_ctx->lro_ctx))
|
||||
QDF_NBUF_CB_RX_LRO_CTX(nbuf) = NULL;
|
||||
|
||||
DP_RX_LIST_APPEND(deliver_list_head,
|
||||
deliver_list_tail,
|
||||
nbuf);
|
||||
|
|
@ -951,8 +1016,8 @@ done:
|
|||
dp_rx_deliver_raw(vdev, deliver_list_head);
|
||||
else if (qdf_likely(vdev->osif_rx) && deliver_list_head)
|
||||
vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
|
||||
|
||||
}
|
||||
|
||||
return rx_bufs_used; /* Assume no scale factor for now */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ QDF_STATUS dp_rx_pdev_attach(struct dp_pdev *pdev);
|
|||
void dp_rx_pdev_detach(struct dp_pdev *pdev);
|
||||
|
||||
|
||||
uint32_t dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota);
|
||||
|
||||
uint32_t
|
||||
dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota);
|
||||
|
||||
uint32_t dp_rx_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <qdf_atomic.h>
|
||||
#include <qdf_util.h>
|
||||
#include <qdf_list.h>
|
||||
#include <qdf_lro.h>
|
||||
#include <queue.h>
|
||||
#include <htt_common.h>
|
||||
|
||||
|
|
@ -321,6 +322,7 @@ struct dp_intr {
|
|||
uint8_t reo_status_ring_mask; /* REO command response ring */
|
||||
struct dp_soc *soc; /* Reference to SoC structure ,
|
||||
to get DMA ring handles */
|
||||
qdf_lro_ctx_t lro_ctx;
|
||||
};
|
||||
|
||||
#define REO_DESC_FREELIST_SIZE 64
|
||||
|
|
@ -919,6 +921,7 @@ struct dp_vdev {
|
|||
|
||||
/* VDEV Stats */
|
||||
struct cdp_vdev_stats stats;
|
||||
bool lro_enable;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -614,6 +614,97 @@ hal_rx_mpdu_peer_meta_data_get(uint8_t *buf)
|
|||
RX_MSDU_END_9_L3_HEADER_PADDING_LSB))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LRO information needed from the TLVs
|
||||
*/
|
||||
#define HAL_RX_TLV_GET_LRO_ELIGIBLE(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_end_tlv.rx_msdu_end), \
|
||||
RX_MSDU_END_9_LRO_ELIGIBLE_OFFSET)), \
|
||||
RX_MSDU_END_9_LRO_ELIGIBLE_MASK, \
|
||||
RX_MSDU_END_9_LRO_ELIGIBLE_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_end_tlv.rx_msdu_end), \
|
||||
RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \
|
||||
RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \
|
||||
RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_ACK(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_end_tlv.rx_msdu_end), \
|
||||
RX_MSDU_END_8_TCP_ACK_NUMBER_OFFSET)), \
|
||||
RX_MSDU_END_8_TCP_ACK_NUMBER_MASK, \
|
||||
RX_MSDU_END_8_TCP_ACK_NUMBER_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_SEQ(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_end_tlv.rx_msdu_end), \
|
||||
RX_MSDU_END_7_TCP_SEQ_NUMBER_OFFSET)), \
|
||||
RX_MSDU_END_7_TCP_SEQ_NUMBER_MASK, \
|
||||
RX_MSDU_END_7_TCP_SEQ_NUMBER_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_WIN(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_end_tlv.rx_msdu_end), \
|
||||
RX_MSDU_END_9_WINDOW_SIZE_OFFSET)), \
|
||||
RX_MSDU_END_9_WINDOW_SIZE_MASK, \
|
||||
RX_MSDU_END_9_WINDOW_SIZE_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_PURE_ACK(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_2_TCP_ONLY_ACK_OFFSET)), \
|
||||
RX_MSDU_START_2_TCP_ONLY_ACK_MASK, \
|
||||
RX_MSDU_START_2_TCP_ONLY_ACK_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_PROTO(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_2_TCP_PROTO_OFFSET)), \
|
||||
RX_MSDU_START_2_TCP_PROTO_MASK, \
|
||||
RX_MSDU_START_2_TCP_PROTO_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_IPV6(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_2_IPV6_PROTO_OFFSET)), \
|
||||
RX_MSDU_START_2_IPV6_PROTO_MASK, \
|
||||
RX_MSDU_START_2_IPV6_PROTO_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_IP_OFFSET(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_1_L3_OFFSET_OFFSET)), \
|
||||
RX_MSDU_START_1_L3_OFFSET_MASK, \
|
||||
RX_MSDU_START_1_L3_OFFSET_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_TCP_OFFSET(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_1_L4_OFFSET_OFFSET)), \
|
||||
RX_MSDU_START_1_L4_OFFSET_MASK, \
|
||||
RX_MSDU_START_1_L4_OFFSET_LSB))
|
||||
|
||||
#define HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ(buf) \
|
||||
(_HAL_MS( \
|
||||
(*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\
|
||||
msdu_start_tlv.rx_msdu_start), \
|
||||
RX_MSDU_START_4_FLOW_ID_TOEPLITZ_OFFSET)), \
|
||||
RX_MSDU_START_4_FLOW_ID_TOEPLITZ_MASK, \
|
||||
RX_MSDU_START_4_FLOW_ID_TOEPLITZ_LSB))
|
||||
|
||||
/**
|
||||
* hal_rx_msdu_end_l3_hdr_padding_get(): API to get the
|
||||
* l3_header padding from rx_msdu_end TLV
|
||||
|
|
|
|||
Loading…
Reference in a new issue