1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef _DP_LI_RX_H_ 21 #define _DP_LI_RX_H_ 22 23 #include <dp_types.h> 24 #include <dp_rx.h> 25 #include "dp_li.h" 26 27 /** 28 * dp_rx_process_li() - Brain of the Rx processing functionality 29 * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) 30 * @int_ctx: per interrupt context 31 * @hal_ring_hdl: opaque pointer to the HAL Rx Ring, which will be serviced 32 * @reo_ring_num: ring number (0, 1, 2 or 3) of the reo ring. 33 * @quota: No. of units (packets) that can be serviced in one shot. 34 * 35 * This function implements the core of Rx functionality. This is 36 * expected to handle only non-error frames. 37 * 38 * Return: uint32_t: No. of elements processed 39 */ 40 uint32_t dp_rx_process_li(struct dp_intr *int_ctx, 41 hal_ring_handle_t hal_ring_hdl, uint8_t reo_ring_num, 42 uint32_t quota); 43 44 /** 45 * dp_rx_chain_msdus_li() - Function to chain all msdus of a mpdu 46 * to pdev invalid peer list 47 * 48 * @soc: core DP main context 49 * @nbuf: Buffer pointer 50 * @rx_tlv_hdr: start of rx tlv header 51 * @mac_id: mac id 52 * 53 * Return: bool: true for last msdu of mpdu 54 */ 55 bool dp_rx_chain_msdus_li(struct dp_soc *soc, qdf_nbuf_t nbuf, 56 uint8_t *rx_tlv_hdr, uint8_t mac_id); 57 58 /** 59 * dp_rx_desc_pool_init_li() - Initialize Rx Descriptor pool(s) 60 * @soc: Handle to DP Soc structure 61 * @rx_desc_pool: Rx descriptor pool handler 62 * @pool_id: Rx descriptor pool ID 63 * 64 * Return: None 65 */ 66 QDF_STATUS dp_rx_desc_pool_init_li(struct dp_soc *soc, 67 struct rx_desc_pool *rx_desc_pool, 68 uint32_t pool_id); 69 70 /** 71 * dp_rx_desc_pool_deinit_li() - De-initialize Rx Descriptor pool(s) 72 * @soc: Handle to DP Soc structure 73 * @rx_desc_pool: Rx descriptor pool handler 74 * @pool_id: Rx descriptor pool ID 75 * 76 * Return: None 77 */ 78 void dp_rx_desc_pool_deinit_li(struct dp_soc *soc, 79 struct rx_desc_pool *rx_desc_pool, 80 uint32_t pool_id); 81 82 /** 83 * dp_wbm_get_rx_desc_from_hal_desc_li() - Get corresponding Rx Desc 84 * address from WBM ring Desc 85 * @soc: Handle to DP Soc structure 86 * @ring_desc: ring descriptor structure pointer 87 * @r_rx_desc: pointer to a pointer of Rx Desc 88 * 89 * Return: QDF_STATUS_SUCCESS - succeeded, others - failed 90 */ 91 QDF_STATUS dp_wbm_get_rx_desc_from_hal_desc_li( 92 struct dp_soc *soc, 93 void *ring_desc, 94 struct dp_rx_desc **r_rx_desc); 95 /** 96 * dp_rx_get_reo_qdesc_addr_li(): API to get qdesc address of reo 97 * entrance ring desc 98 * 99 * @hal_soc: Handle to HAL Soc structure 100 * @dst_ring_desc: reo dest ring descriptor (used for Lithium DP) 101 * @buf: pointer to the start of RX PKT TLV headers 102 * @txrx_peer: pointer to txrx_peer 103 * @tid: tid value 104 * 105 * Return: qdesc address in reo destination ring buffer 106 */ 107 static inline 108 uint64_t dp_rx_get_reo_qdesc_addr_li(hal_soc_handle_t hal_soc, 109 uint8_t *dst_ring_desc, 110 uint8_t *buf, 111 struct dp_txrx_peer *txrx_peer, 112 unsigned int tid) 113 { 114 return hal_rx_get_qdesc_addr(hal_soc, dst_ring_desc, buf); 115 } 116 117 /** 118 * dp_rx_desc_cookie_2_va_li() - Convert RX Desc cookie ID to VA 119 * @soc:Handle to DP Soc structure 120 * @cookie: cookie used to lookup virtual address 121 * 122 * Return: Rx descriptor virtual address 123 */ 124 static inline 125 struct dp_rx_desc *dp_rx_desc_cookie_2_va_li(struct dp_soc *soc, 126 uint32_t cookie) 127 { 128 return dp_rx_cookie_2_va_rxdma_buf(soc, cookie); 129 } 130 131 #define DP_PEER_METADATA_VDEV_ID_MASK 0x003f0000 132 #define DP_PEER_METADATA_VDEV_ID_SHIFT 16 133 #define DP_PEER_METADATA_OFFLOAD_MASK 0x01000000 134 #define DP_PEER_METADATA_OFFLOAD_SHIFT 24 135 136 #define DP_PEER_METADATA_VDEV_ID_GET_LI(_peer_metadata) \ 137 (((_peer_metadata) & DP_PEER_METADATA_VDEV_ID_MASK) \ 138 >> DP_PEER_METADATA_VDEV_ID_SHIFT) 139 140 #define DP_PEER_METADATA_OFFLOAD_GET_LI(_peer_metadata) \ 141 (((_peer_metadata) & DP_PEER_METADATA_OFFLOAD_MASK) \ 142 >> DP_PEER_METADATA_OFFLOAD_SHIFT) 143 144 static inline uint16_t 145 dp_rx_peer_metadata_peer_id_get_li(struct dp_soc *soc, uint32_t peer_metadata) 146 { 147 struct htt_rx_peer_metadata_v0 *metadata = 148 (struct htt_rx_peer_metadata_v0 *)&peer_metadata; 149 150 return metadata->peer_id; 151 } 152 153 bool 154 dp_rx_intrabss_handle_nawds_li(struct dp_soc *soc, struct dp_txrx_peer *ta_peer, 155 qdf_nbuf_t nbuf_copy, 156 struct cdp_tid_rx_stats *tid_stats); 157 #ifdef QCA_DP_RX_NBUF_AND_NBUF_DATA_PREFETCH 158 static inline 159 void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next) 160 { 161 struct rx_pkt_tlvs *pkt_tlvs; 162 163 if (next) { 164 /* prefetch skb->next and first few bytes of skb->cb */ 165 qdf_prefetch(next); 166 /* skb->cb spread across 2 cache lines hence below prefetch */ 167 qdf_prefetch(&next->_skb_refdst); 168 qdf_prefetch(&next->len); 169 qdf_prefetch(&next->protocol); 170 pkt_tlvs = (struct rx_pkt_tlvs *)next->data; 171 /* sa_idx, da_idx, l3_pad in RX msdu_end TLV */ 172 qdf_prefetch(pkt_tlvs); 173 /* msdu_done in RX attention TLV */ 174 qdf_prefetch(&pkt_tlvs->attn_tlv); 175 /* fr_ds & to_ds in RX MPDU start TLV */ 176 if (qdf_nbuf_is_rx_chfrag_end(nbuf)) 177 qdf_prefetch(&pkt_tlvs->mpdu_start_tlv); 178 } 179 } 180 #else 181 static inline 182 void dp_rx_prefetch_nbuf_data(qdf_nbuf_t nbuf, qdf_nbuf_t next) 183 { 184 } 185 #endif 186 187 #ifdef QCA_DP_RX_HW_SW_NBUF_DESC_PREFETCH 188 /** 189 * dp_rx_cookie_2_va_rxdma_buf_prefetch() - function to prefetch the SW desc 190 * @soc: Handle to DP Soc structure 191 * @cookie: cookie used to lookup virtual address 192 * 193 * Return: prefetched Rx descriptor virtual address 194 */ 195 static inline 196 void *dp_rx_cookie_2_va_rxdma_buf_prefetch(struct dp_soc *soc, uint32_t cookie) 197 { 198 uint8_t pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(cookie); 199 uint16_t index = DP_RX_DESC_COOKIE_INDEX_GET(cookie); 200 struct rx_desc_pool *rx_desc_pool; 201 void *prefetch_desc; 202 203 if (qdf_unlikely(pool_id >= MAX_RXDESC_POOLS)) 204 return NULL; 205 206 rx_desc_pool = &soc->rx_desc_buf[pool_id]; 207 208 if (qdf_unlikely(index >= rx_desc_pool->pool_size)) 209 return NULL; 210 211 prefetch_desc = &soc->rx_desc_buf[pool_id].array[index].rx_desc; 212 qdf_prefetch(prefetch_desc); 213 return prefetch_desc; 214 } 215 216 /** 217 * dp_rx_prefetch_hw_sw_nbuf_desc() - function to prefetch HW and SW desc 218 * @soc: Handle to DP Soc structure 219 * @hal_soc: Handle to HAL Soc structure 220 * @num_entries: valid number of HW descriptors 221 * @hal_ring_hdl: Destination ring pointer 222 * @last_prefetched_hw_desc: pointer to the last prefetched HW descriptor 223 * @last_prefetched_sw_desc: input & output param of last prefetch SW desc 224 * 225 * Return: None 226 */ 227 static inline 228 void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc, 229 hal_soc_handle_t hal_soc, 230 uint32_t num_entries, 231 hal_ring_handle_t hal_ring_hdl, 232 hal_ring_desc_t *last_prefetched_hw_desc, 233 struct dp_rx_desc **last_prefetched_sw_desc) 234 { 235 if (*last_prefetched_sw_desc) { 236 qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf); 237 qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf + 64); 238 } 239 240 if (num_entries) { 241 *last_prefetched_sw_desc = dp_rx_cookie_2_va_rxdma_buf_prefetch(soc, HAL_RX_REO_BUF_COOKIE_GET(*last_prefetched_hw_desc)); 242 *last_prefetched_hw_desc = hal_srng_dst_prefetch_next_cached_desc(hal_soc, 243 hal_ring_hdl, 244 (uint8_t *)*last_prefetched_hw_desc); 245 } 246 } 247 #else 248 static inline 249 void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc, 250 hal_soc_handle_t hal_soc, 251 uint32_t quota, 252 hal_ring_handle_t hal_ring_hdl, 253 hal_ring_desc_t *last_prefetched_hw_desc, 254 struct dp_rx_desc **last_prefetched_sw_desc) 255 { 256 } 257 #endif 258 259 static inline 260 QDF_STATUS dp_peer_rx_reorder_queue_setup_li(struct dp_soc *soc, 261 struct dp_peer *peer, 262 int tid, 263 uint32_t ba_window_size) 264 { 265 struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; 266 267 if (!rx_tid->hw_qdesc_paddr) 268 return QDF_STATUS_E_INVAL; 269 270 if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) { 271 if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup( 272 soc->ctrl_psoc, 273 peer->vdev->pdev->pdev_id, 274 peer->vdev->vdev_id, 275 peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid, 276 1, ba_window_size)) { 277 dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n", 278 soc, tid); 279 return QDF_STATUS_E_FAILURE; 280 } 281 } 282 283 return QDF_STATUS_SUCCESS; 284 } 285 #endif 286