diff --git a/dp/wifi3.0/li/dp_li.h b/dp/wifi3.0/li/dp_li.h index 6ead45edcc..faf03a7641 100644 --- a/dp/wifi3.0/li/dp_li.h +++ b/dp/wifi3.0/li/dp_li.h @@ -20,6 +20,7 @@ #include #include +#include /* WBM2SW ring id for rx release */ #define WBM2SW_REL_ERR_RING_NUM 3 diff --git a/dp/wifi3.0/li/dp_li_rx.c b/dp/wifi3.0/li/dp_li_rx.c index 66465a19e2..17e1c2c3fc 100644 --- a/dp/wifi3.0/li/dp_li_rx.c +++ b/dp/wifi3.0/li/dp_li_rx.c @@ -455,6 +455,8 @@ done: nbuf = nbuf_head; while (nbuf) { next = nbuf->next; + dp_rx_prefetch_nbuf_data(nbuf, next); + if (qdf_unlikely(dp_rx_is_raw_frame_dropped(nbuf))) { nbuf = next; DP_STATS_INC(soc, rx.err.raw_frm_drop, 1); diff --git a/dp/wifi3.0/li/dp_li_rx.h b/dp/wifi3.0/li/dp_li_rx.h index bfef488c1d..1bfca19812 100644 --- a/dp/wifi3.0/li/dp_li_rx.h +++ b/dp/wifi3.0/li/dp_li_rx.h @@ -100,4 +100,34 @@ dp_rx_peer_metadata_peer_id_get_li(struct dp_soc *soc, uint32_t peer_metadata) return metadata->peer_id; } + +#ifdef QCA_DP_RX_NBUF_AND_NBUF_DATA_PREFETCH +static inline +void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next) +{ + struct rx_pkt_tlvs *pkt_tlvs; + + if (next) { + /* prefetch skb->next and first few bytes of skb->cb */ + qdf_prefetch(next); + /* skb->cb spread across 2 cache lines hence below prefetch */ + qdf_prefetch(&next->_skb_refdst); + qdf_prefetch(&next->len); + qdf_prefetch(&next->protocol); + pkt_tlvs = (struct rx_pkt_tlvs *)next->data; + /* sa_idx, da_idx, l3_pad in RX msdu_end TLV */ + qdf_prefetch(pkt_tlvs); + /* msdu_done in RX attention TLV */ + qdf_prefetch(&pkt_tlvs->attn_tlv); + /* fr_ds & to_ds in RX MPDU start TLV */ + if (qdf_nbuf_is_rx_chfrag_end(nbuf)) + qdf_prefetch(&pkt_tlvs->mpdu_start_tlv); + } +} +#else +static inline +void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next) +{ +} +#endif #endif