xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/li/dp_li_rx.h (revision ccf6794c7efeda37a9772e5eb4d4dab2ab5af07a)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _DP_LI_RX_H_
20 #define _DP_LI_RX_H_
21 
22 #include <dp_types.h>
23 #include <dp_rx.h>
24 #include "dp_li.h"
25 
26 uint32_t dp_rx_process_li(struct dp_intr *int_ctx,
27 			  hal_ring_handle_t hal_ring_hdl, uint8_t reo_ring_num,
28 			  uint32_t quota);
29 
30 /**
31  * dp_rx_desc_pool_init_li() - Initialize Rx Descriptor pool(s)
32  * @soc: Handle to DP Soc structure
33  * @rx_desc_pool: Rx descriptor pool handler
34  * @pool_id: Rx descriptor pool ID
35  *
36  * Return: None
37  */
38 QDF_STATUS dp_rx_desc_pool_init_li(struct dp_soc *soc,
39 				   struct rx_desc_pool *rx_desc_pool,
40 				   uint32_t pool_id);
41 
42 /**
43  * dp_rx_desc_pool_deinit_li() - De-initialize Rx Descriptor pool(s)
44  * @soc: Handle to DP Soc structure
45  * @rx_desc_pool: Rx descriptor pool handler
46  * @pool_id: Rx descriptor pool ID
47  *
48  * Return: None
49  */
50 void dp_rx_desc_pool_deinit_li(struct dp_soc *soc,
51 			       struct rx_desc_pool *rx_desc_pool,
52 			       uint32_t pool_id);
53 
54 /**
55  * dp_wbm_get_rx_desc_from_hal_desc_li() - Get corresponding Rx Desc
56  *					address from WBM ring Desc
57  * @soc: Handle to DP Soc structure
58  * @ring_desc: ring descriptor structure pointer
59  * @r_rx_desc: pointer to a pointer of Rx Desc
60  *
61  * Return: QDF_STATUS_SUCCESS - succeeded, others - failed
62  */
63 QDF_STATUS dp_wbm_get_rx_desc_from_hal_desc_li(
64 					struct dp_soc *soc,
65 					void *ring_desc,
66 					struct dp_rx_desc **r_rx_desc);
67 
68 /**
69  * dp_rx_desc_cookie_2_va_li() - Convert RX Desc cookie ID to VA
70  * @soc:Handle to DP Soc structure
71  * @cookie: cookie used to lookup virtual address
72  *
73  * Return: Rx descriptor virtual address
74  */
75 static inline
76 struct dp_rx_desc *dp_rx_desc_cookie_2_va_li(struct dp_soc *soc,
77 					     uint32_t cookie)
78 {
79 	return dp_rx_cookie_2_va_rxdma_buf(soc, cookie);
80 }
81 
82 #define DP_PEER_METADATA_VDEV_ID_MASK	0x003f0000
83 #define DP_PEER_METADATA_VDEV_ID_SHIFT	16
84 #define DP_PEER_METADATA_OFFLOAD_MASK	0x01000000
85 #define DP_PEER_METADATA_OFFLOAD_SHIFT	24
86 
87 #define DP_PEER_METADATA_VDEV_ID_GET_LI(_peer_metadata)		\
88 	(((_peer_metadata) & DP_PEER_METADATA_VDEV_ID_MASK)	\
89 			>> DP_PEER_METADATA_VDEV_ID_SHIFT)
90 
91 #define DP_PEER_METADATA_OFFLOAD_GET_LI(_peer_metadata)		\
92 	(((_peer_metadata) & DP_PEER_METADATA_OFFLOAD_MASK)	\
93 			>> DP_PEER_METADATA_OFFLOAD_SHIFT)
94 
95 static inline uint16_t
96 dp_rx_peer_metadata_peer_id_get_li(struct dp_soc *soc, uint32_t peer_metadata)
97 {
98 	struct htt_rx_peer_metadata_v0 *metadata =
99 			(struct htt_rx_peer_metadata_v0 *)&peer_metadata;
100 
101 	return metadata->peer_id;
102 }
103 
104 #ifdef QCA_DP_RX_NBUF_AND_NBUF_DATA_PREFETCH
105 static inline
106 void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next)
107 {
108 	struct rx_pkt_tlvs *pkt_tlvs;
109 
110 	if (next) {
111 		/* prefetch skb->next and first few bytes of skb->cb */
112 		qdf_prefetch(next);
113 		/* skb->cb spread across 2 cache lines hence below prefetch */
114 		qdf_prefetch(&next->_skb_refdst);
115 		qdf_prefetch(&next->len);
116 		qdf_prefetch(&next->protocol);
117 		pkt_tlvs = (struct rx_pkt_tlvs *)next->data;
118 		/* sa_idx, da_idx, l3_pad in RX msdu_end TLV */
119 		qdf_prefetch(pkt_tlvs);
120 		/* msdu_done in RX attention TLV */
121 		qdf_prefetch(&pkt_tlvs->attn_tlv);
122 		/* fr_ds & to_ds in RX MPDU start TLV */
123 		if (qdf_nbuf_is_rx_chfrag_end(nbuf))
124 			qdf_prefetch(&pkt_tlvs->mpdu_start_tlv);
125 	}
126 }
127 #else
128 static inline
129 void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next)
130 {
131 }
132 #endif
133 
134 #ifdef QCA_DP_RX_HW_SW_NBUF_DESC_PREFETCH
135 /**
136  * dp_rx_cookie_2_va_rxdma_buf_prefetch() - function to prefetch the SW desc
137  * @soc: Handle to DP Soc structure
138  * @cookie: cookie used to lookup virtual address
139  *
140  * Return: prefetched Rx descriptor virtual address
141  */
142 static inline
143 void *dp_rx_cookie_2_va_rxdma_buf_prefetch(struct dp_soc *soc, uint32_t cookie)
144 {
145 	uint8_t pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(cookie);
146 	uint16_t index = DP_RX_DESC_COOKIE_INDEX_GET(cookie);
147 	struct rx_desc_pool *rx_desc_pool;
148 	void *prefetch_desc;
149 
150 	if (qdf_unlikely(pool_id >= MAX_RXDESC_POOLS))
151 		return NULL;
152 
153 	rx_desc_pool = &soc->rx_desc_buf[pool_id];
154 
155 	if (qdf_unlikely(index >= rx_desc_pool->pool_size))
156 		return NULL;
157 
158 	prefetch_desc = &soc->rx_desc_buf[pool_id].array[index].rx_desc;
159 	qdf_prefetch(prefetch_desc);
160 	return prefetch_desc;
161 }
162 
163 /**
164  * dp_rx_prefetch_hw_sw_nbuf_desc() - function to prefetch HW and SW desc
165  * @soc: Handle to HAL Soc structure
166  * @num_entries: valid number of HW descriptors
167  * @hal_ring_hdl: Destination ring pointer
168  * @last_prefetched_hw_desc: pointer to the last prefetched HW descriptor
169  * @last_prefetched_sw_desc: input & output param of last prefetch SW desc
170  *
171  * Return: None
172  */
173 static inline
174 void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
175 				    hal_soc_handle_t hal_soc,
176 				    uint32_t num_entries,
177 				    hal_ring_handle_t hal_ring_hdl,
178 				    hal_ring_desc_t *last_prefetched_hw_desc,
179 				    struct dp_rx_desc **last_prefetched_sw_desc)
180 {
181 	if (*last_prefetched_sw_desc) {
182 		qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf);
183 		qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf + 64);
184 	}
185 
186 	if (num_entries) {
187 		*last_prefetched_sw_desc = dp_rx_cookie_2_va_rxdma_buf_prefetch(soc, HAL_RX_REO_BUF_COOKIE_GET(*last_prefetched_hw_desc));
188 		*last_prefetched_hw_desc = hal_srng_dst_prefetch_next_cached_desc(hal_soc,
189 										  hal_ring_hdl,
190 										  (uint8_t *)*last_prefetched_hw_desc);
191 	}
192 }
193 #else
194 static inline
195 void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
196 				    hal_soc_handle_t hal_soc,
197 				    uint32_t quota,
198 				    hal_ring_handle_t hal_ring_hdl,
199 				    hal_ring_desc_t *last_prefetched_hw_desc,
200 				    struct dp_rx_desc **last_prefetched_sw_desc)
201 {
202 }
203 #endif
204 #endif
205