xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/be/dp_be_rx.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #ifndef _DP_BE_RX_H_
21*5113495bSYour Name #define _DP_BE_RX_H_
22*5113495bSYour Name 
23*5113495bSYour Name #include <dp_types.h>
24*5113495bSYour Name #include "dp_be.h"
25*5113495bSYour Name #include "dp_peer.h"
26*5113495bSYour Name #include <dp_rx.h>
27*5113495bSYour Name #include "hal_be_rx.h"
28*5113495bSYour Name #include "hal_be_rx_tlv.h"
29*5113495bSYour Name 
30*5113495bSYour Name /*
31*5113495bSYour Name  * dp_be_intrabss_params
32*5113495bSYour Name  *
33*5113495bSYour Name  * @dest_soc: dest soc to forward the packet to
34*5113495bSYour Name  * @tx_vdev_id: vdev id retrieved from dest peer
35*5113495bSYour Name  */
36*5113495bSYour Name struct dp_be_intrabss_params {
37*5113495bSYour Name 	struct dp_soc *dest_soc;
38*5113495bSYour Name 	uint8_t tx_vdev_id;
39*5113495bSYour Name };
40*5113495bSYour Name 
41*5113495bSYour Name #ifndef QCA_HOST_MODE_WIFI_DISABLED
42*5113495bSYour Name 
43*5113495bSYour Name /**
44*5113495bSYour Name  * dp_rx_intrabss_fwd_be() - API for intrabss fwd. For EAPOL
45*5113495bSYour Name  *  pkt with DA not equal to vdev mac addr, fwd is not allowed.
46*5113495bSYour Name  * @soc: core txrx main context
47*5113495bSYour Name  * @ta_txrx_peer: source peer entry
48*5113495bSYour Name  * @rx_tlv_hdr: start address of rx tlvs
49*5113495bSYour Name  * @nbuf: nbuf that has to be intrabss forwarded
50*5113495bSYour Name  * @link_id: link id on which the packet is received
51*5113495bSYour Name  *
52*5113495bSYour Name  * Return: true if it is forwarded else false
53*5113495bSYour Name  */
54*5113495bSYour Name bool dp_rx_intrabss_fwd_be(struct dp_soc *soc,
55*5113495bSYour Name 			   struct dp_txrx_peer *ta_txrx_peer,
56*5113495bSYour Name 			   uint8_t *rx_tlv_hdr,
57*5113495bSYour Name 			   qdf_nbuf_t nbuf,
58*5113495bSYour Name 			   uint8_t link_id);
59*5113495bSYour Name #endif
60*5113495bSYour Name 
61*5113495bSYour Name /**
62*5113495bSYour Name  * dp_rx_intrabss_mcast_handler_be() - intrabss mcast handler
63*5113495bSYour Name  * @soc: core txrx main context
64*5113495bSYour Name  * @ta_txrx_peer: source txrx_peer entry
65*5113495bSYour Name  * @nbuf_copy: nbuf that has to be intrabss forwarded
66*5113495bSYour Name  * @tid_stats: tid_stats structure
67*5113495bSYour Name  * @link_id: link id on which the packet is received
68*5113495bSYour Name  *
69*5113495bSYour Name  * Return: true if it is forwarded else false
70*5113495bSYour Name  */
71*5113495bSYour Name bool
72*5113495bSYour Name dp_rx_intrabss_mcast_handler_be(struct dp_soc *soc,
73*5113495bSYour Name 				struct dp_txrx_peer *ta_txrx_peer,
74*5113495bSYour Name 				qdf_nbuf_t nbuf_copy,
75*5113495bSYour Name 				struct cdp_tid_rx_stats *tid_stats,
76*5113495bSYour Name 				uint8_t link_id);
77*5113495bSYour Name 
78*5113495bSYour Name void dp_rx_word_mask_subscribe_be(struct dp_soc *soc,
79*5113495bSYour Name 				  uint32_t *msg_word,
80*5113495bSYour Name 				  void *rx_filter);
81*5113495bSYour Name 
82*5113495bSYour Name /**
83*5113495bSYour Name  * dp_rx_process_be() - Brain of the Rx processing functionality
84*5113495bSYour Name  *		     Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
85*5113495bSYour Name  * @int_ctx: per interrupt context
86*5113495bSYour Name  * @hal_ring_hdl: opaque pointer to the HAL Rx Ring, which will be serviced
87*5113495bSYour Name  * @reo_ring_num: ring number (0, 1, 2 or 3) of the reo ring.
88*5113495bSYour Name  * @quota: No. of units (packets) that can be serviced in one shot.
89*5113495bSYour Name  *
90*5113495bSYour Name  * This function implements the core of Rx functionality. This is
91*5113495bSYour Name  * expected to handle only non-error frames.
92*5113495bSYour Name  *
93*5113495bSYour Name  * Return: uint32_t: No. of elements processed
94*5113495bSYour Name  */
95*5113495bSYour Name uint32_t dp_rx_process_be(struct dp_intr *int_ctx,
96*5113495bSYour Name 			  hal_ring_handle_t hal_ring_hdl, uint8_t reo_ring_num,
97*5113495bSYour Name 			  uint32_t quota);
98*5113495bSYour Name 
99*5113495bSYour Name /**
100*5113495bSYour Name  * dp_rx_desc_pool_init_be() - Initialize Rx Descriptor pool(s)
101*5113495bSYour Name  * @soc: Handle to DP Soc structure
102*5113495bSYour Name  * @rx_desc_pool: Rx descriptor pool handler
103*5113495bSYour Name  * @pool_id: Rx descriptor pool ID
104*5113495bSYour Name  *
105*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - succeeded, others - failed
106*5113495bSYour Name  */
107*5113495bSYour Name QDF_STATUS dp_rx_desc_pool_init_be(struct dp_soc *soc,
108*5113495bSYour Name 				   struct rx_desc_pool *rx_desc_pool,
109*5113495bSYour Name 				   uint32_t pool_id);
110*5113495bSYour Name 
111*5113495bSYour Name /**
112*5113495bSYour Name  * dp_rx_desc_pool_deinit_be() - De-initialize Rx Descriptor pool(s)
113*5113495bSYour Name  * @soc: Handle to DP Soc structure
114*5113495bSYour Name  * @rx_desc_pool: Rx descriptor pool handler
115*5113495bSYour Name  * @pool_id: Rx descriptor pool ID
116*5113495bSYour Name  *
117*5113495bSYour Name  * Return: None
118*5113495bSYour Name  */
119*5113495bSYour Name void dp_rx_desc_pool_deinit_be(struct dp_soc *soc,
120*5113495bSYour Name 			       struct rx_desc_pool *rx_desc_pool,
121*5113495bSYour Name 			       uint32_t pool_id);
122*5113495bSYour Name 
123*5113495bSYour Name /**
124*5113495bSYour Name  * dp_wbm_get_rx_desc_from_hal_desc_be() - Get corresponding Rx Desc
125*5113495bSYour Name  *					address from WBM ring Desc
126*5113495bSYour Name  * @soc: Handle to DP Soc structure
127*5113495bSYour Name  * @ring_desc: ring descriptor structure pointer
128*5113495bSYour Name  * @r_rx_desc: pointer to a pointer of Rx Desc
129*5113495bSYour Name  *
130*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - succeeded, others - failed
131*5113495bSYour Name  */
132*5113495bSYour Name QDF_STATUS dp_wbm_get_rx_desc_from_hal_desc_be(struct dp_soc *soc,
133*5113495bSYour Name 					       void *ring_desc,
134*5113495bSYour Name 					       struct dp_rx_desc **r_rx_desc);
135*5113495bSYour Name 
136*5113495bSYour Name /**
137*5113495bSYour Name  * dp_rx_desc_cookie_2_va_be() - Convert RX Desc cookie ID to VA
138*5113495bSYour Name  * @soc:Handle to DP Soc structure
139*5113495bSYour Name  * @cookie: cookie used to lookup virtual address
140*5113495bSYour Name  *
141*5113495bSYour Name  * Return: Rx descriptor virtual address
142*5113495bSYour Name  */
143*5113495bSYour Name struct dp_rx_desc *dp_rx_desc_cookie_2_va_be(struct dp_soc *soc,
144*5113495bSYour Name 					     uint32_t cookie);
145*5113495bSYour Name 
146*5113495bSYour Name #if !defined(DP_FEATURE_HW_COOKIE_CONVERSION) || \
147*5113495bSYour Name 		defined(DP_HW_COOKIE_CONVERT_EXCEPTION)
148*5113495bSYour Name /**
149*5113495bSYour Name  * dp_rx_desc_sw_cc_check() - check if RX desc VA is got correctly,
150*5113495bSYour Name  *			      if not, do SW cookie conversion.
151*5113495bSYour Name  * @soc:Handle to DP Soc structure
152*5113495bSYour Name  * @rx_buf_cookie: RX desc cookie ID
153*5113495bSYour Name  * @r_rx_desc: double pointer for RX desc
154*5113495bSYour Name  *
155*5113495bSYour Name  * Return: None
156*5113495bSYour Name  */
157*5113495bSYour Name static inline void
dp_rx_desc_sw_cc_check(struct dp_soc * soc,uint32_t rx_buf_cookie,struct dp_rx_desc ** r_rx_desc)158*5113495bSYour Name dp_rx_desc_sw_cc_check(struct dp_soc *soc,
159*5113495bSYour Name 		       uint32_t rx_buf_cookie,
160*5113495bSYour Name 		       struct dp_rx_desc **r_rx_desc)
161*5113495bSYour Name {
162*5113495bSYour Name 	if (qdf_unlikely(!(*r_rx_desc))) {
163*5113495bSYour Name 		*r_rx_desc = (struct dp_rx_desc *)
164*5113495bSYour Name 				dp_cc_desc_find(soc,
165*5113495bSYour Name 						rx_buf_cookie);
166*5113495bSYour Name 	}
167*5113495bSYour Name }
168*5113495bSYour Name #else
169*5113495bSYour Name static inline void
dp_rx_desc_sw_cc_check(struct dp_soc * soc,uint32_t rx_buf_cookie,struct dp_rx_desc ** r_rx_desc)170*5113495bSYour Name dp_rx_desc_sw_cc_check(struct dp_soc *soc,
171*5113495bSYour Name 		       uint32_t rx_buf_cookie,
172*5113495bSYour Name 		       struct dp_rx_desc **r_rx_desc)
173*5113495bSYour Name {
174*5113495bSYour Name }
175*5113495bSYour Name #endif /* DP_FEATURE_HW_COOKIE_CONVERSION && DP_HW_COOKIE_CONVERT_EXCEPTION */
176*5113495bSYour Name 
177*5113495bSYour Name struct dp_rx_desc *dp_rx_desc_ppeds_cookie_2_va(struct dp_soc *soc,
178*5113495bSYour Name 						unsigned long cookie);
179*5113495bSYour Name 
180*5113495bSYour Name #define DP_PEER_METADATA_OFFLOAD_GET_BE(_peer_metadata)		(0)
181*5113495bSYour Name 
182*5113495bSYour Name #define HTT_RX_PEER_META_DATA_FIELD_GET(_var, _field_s, _field_m) \
183*5113495bSYour Name 	(((_var) & (_field_m)) >> (_field_s))
184*5113495bSYour Name 
185*5113495bSYour Name #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
186*5113495bSYour Name static inline uint16_t
dp_rx_peer_metadata_peer_id_get_be(struct dp_soc * soc,uint32_t peer_metadata)187*5113495bSYour Name dp_rx_peer_metadata_peer_id_get_be(struct dp_soc *soc, uint32_t peer_metadata)
188*5113495bSYour Name {
189*5113495bSYour Name 	uint8_t ml_peer_valid;
190*5113495bSYour Name 	uint16_t peer_id;
191*5113495bSYour Name 
192*5113495bSYour Name 	peer_id = HTT_RX_PEER_META_DATA_FIELD_GET(peer_metadata,
193*5113495bSYour Name 						  soc->htt_peer_id_s,
194*5113495bSYour Name 						  soc->htt_peer_id_m);
195*5113495bSYour Name 	ml_peer_valid = HTT_RX_PEER_META_DATA_FIELD_GET(
196*5113495bSYour Name 						peer_metadata,
197*5113495bSYour Name 						soc->htt_mld_peer_valid_s,
198*5113495bSYour Name 						soc->htt_mld_peer_valid_m);
199*5113495bSYour Name 
200*5113495bSYour Name 	return (peer_id | (ml_peer_valid << soc->peer_id_shift));
201*5113495bSYour Name }
202*5113495bSYour Name #else
203*5113495bSYour Name /* Combine ml_peer_valid and peer_id field */
204*5113495bSYour Name #define DP_BE_PEER_METADATA_PEER_ID_MASK	0x00003fff
205*5113495bSYour Name #define DP_BE_PEER_METADATA_PEER_ID_SHIFT	0
206*5113495bSYour Name 
207*5113495bSYour Name static inline uint16_t
dp_rx_peer_metadata_peer_id_get_be(struct dp_soc * soc,uint32_t peer_metadata)208*5113495bSYour Name dp_rx_peer_metadata_peer_id_get_be(struct dp_soc *soc, uint32_t peer_metadata)
209*5113495bSYour Name {
210*5113495bSYour Name 	return ((peer_metadata & DP_BE_PEER_METADATA_PEER_ID_MASK) >>
211*5113495bSYour Name 		DP_BE_PEER_METADATA_PEER_ID_SHIFT);
212*5113495bSYour Name }
213*5113495bSYour Name #endif
214*5113495bSYour Name 
215*5113495bSYour Name static inline uint16_t
dp_rx_peer_metadata_vdev_id_get_be(struct dp_soc * soc,uint32_t peer_metadata)216*5113495bSYour Name dp_rx_peer_metadata_vdev_id_get_be(struct dp_soc *soc, uint32_t peer_metadata)
217*5113495bSYour Name {
218*5113495bSYour Name 
219*5113495bSYour Name 	return HTT_RX_PEER_META_DATA_FIELD_GET(peer_metadata,
220*5113495bSYour Name 					       soc->htt_vdev_id_s,
221*5113495bSYour Name 					       soc->htt_vdev_id_m);
222*5113495bSYour Name }
223*5113495bSYour Name 
224*5113495bSYour Name static inline uint8_t
dp_rx_peer_metadata_lmac_id_get_be(uint32_t peer_metadata)225*5113495bSYour Name dp_rx_peer_metadata_lmac_id_get_be(uint32_t peer_metadata)
226*5113495bSYour Name {
227*5113495bSYour Name 	return HTT_RX_PEER_META_DATA_V1_LMAC_ID_GET(peer_metadata);
228*5113495bSYour Name }
229*5113495bSYour Name 
230*5113495bSYour Name 
231*5113495bSYour Name #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
232*5113495bSYour Name /**
233*5113495bSYour Name  * dp_rx_nf_process() - Near Full state handler for RX rings.
234*5113495bSYour Name  * @int_ctx: interrupt context
235*5113495bSYour Name  * @hal_ring_hdl: Rx ring handle
236*5113495bSYour Name  * @reo_ring_num: RX ring number
237*5113495bSYour Name  * @quota: Quota of work to be done
238*5113495bSYour Name  *
239*5113495bSYour Name  * Return: work done in the handler
240*5113495bSYour Name  */
241*5113495bSYour Name uint32_t dp_rx_nf_process(struct dp_intr *int_ctx,
242*5113495bSYour Name 			  hal_ring_handle_t hal_ring_hdl,
243*5113495bSYour Name 			  uint8_t reo_ring_num,
244*5113495bSYour Name 			  uint32_t quota);
245*5113495bSYour Name #else
246*5113495bSYour Name static inline
dp_rx_nf_process(struct dp_intr * int_ctx,hal_ring_handle_t hal_ring_hdl,uint8_t reo_ring_num,uint32_t quota)247*5113495bSYour Name uint32_t dp_rx_nf_process(struct dp_intr *int_ctx,
248*5113495bSYour Name 			  hal_ring_handle_t hal_ring_hdl,
249*5113495bSYour Name 			  uint8_t reo_ring_num,
250*5113495bSYour Name 			  uint32_t quota)
251*5113495bSYour Name {
252*5113495bSYour Name 	return 0;
253*5113495bSYour Name }
254*5113495bSYour Name #endif /*WLAN_FEATURE_NEAR_FULL_IRQ */
255*5113495bSYour Name 
256*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
257*5113495bSYour Name struct dp_soc *
258*5113495bSYour Name dp_rx_replenish_soc_get(struct dp_soc *soc, uint8_t chip_id);
259*5113495bSYour Name 
260*5113495bSYour Name struct dp_soc *
261*5113495bSYour Name dp_soc_get_by_idle_bm_id(struct dp_soc *soc, uint8_t idle_bm_id);
262*5113495bSYour Name 
263*5113495bSYour Name uint8_t dp_soc_get_num_soc_be(struct dp_soc *soc);
264*5113495bSYour Name #else
265*5113495bSYour Name static inline struct dp_soc *
dp_rx_replenish_soc_get(struct dp_soc * soc,uint8_t chip_id)266*5113495bSYour Name dp_rx_replenish_soc_get(struct dp_soc *soc, uint8_t chip_id)
267*5113495bSYour Name {
268*5113495bSYour Name 	return soc;
269*5113495bSYour Name }
270*5113495bSYour Name 
271*5113495bSYour Name static inline uint8_t
dp_soc_get_num_soc_be(struct dp_soc * soc)272*5113495bSYour Name dp_soc_get_num_soc_be(struct dp_soc *soc)
273*5113495bSYour Name {
274*5113495bSYour Name 	return 1;
275*5113495bSYour Name }
276*5113495bSYour Name #endif
277*5113495bSYour Name 
278*5113495bSYour Name static inline QDF_STATUS
dp_peer_rx_reorder_q_setup_per_tid(struct dp_peer * peer,uint32_t tid_bitmap,uint32_t ba_window_size)279*5113495bSYour Name dp_peer_rx_reorder_q_setup_per_tid(struct dp_peer *peer,
280*5113495bSYour Name 				   uint32_t tid_bitmap,
281*5113495bSYour Name 				   uint32_t ba_window_size)
282*5113495bSYour Name {
283*5113495bSYour Name 	int tid;
284*5113495bSYour Name 	struct dp_rx_tid *rx_tid;
285*5113495bSYour Name 	struct dp_soc *soc = peer->vdev->pdev->soc;
286*5113495bSYour Name 
287*5113495bSYour Name 	if (!soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
288*5113495bSYour Name 		dp_peer_debug("%pK: rx_reorder_queue_setup NULL bitmap 0x%x",
289*5113495bSYour Name 			      soc, tid_bitmap);
290*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
291*5113495bSYour Name 	}
292*5113495bSYour Name 
293*5113495bSYour Name 	for (tid = 0; tid < DP_MAX_TIDS; tid++) {
294*5113495bSYour Name 		if (!(BIT(tid) & tid_bitmap))
295*5113495bSYour Name 			continue;
296*5113495bSYour Name 
297*5113495bSYour Name 		rx_tid = &peer->rx_tid[tid];
298*5113495bSYour Name 		if (!rx_tid->hw_qdesc_paddr) {
299*5113495bSYour Name 			tid_bitmap &= ~BIT(tid);
300*5113495bSYour Name 			continue;
301*5113495bSYour Name 		}
302*5113495bSYour Name 
303*5113495bSYour Name 		if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup(
304*5113495bSYour Name 		    soc->ctrl_psoc,
305*5113495bSYour Name 		    peer->vdev->pdev->pdev_id,
306*5113495bSYour Name 		    peer->vdev->vdev_id,
307*5113495bSYour Name 		    peer->mac_addr.raw,
308*5113495bSYour Name 		    rx_tid->hw_qdesc_paddr,
309*5113495bSYour Name 		    tid, tid,
310*5113495bSYour Name 		    1, ba_window_size)) {
311*5113495bSYour Name 			dp_peer_err("%pK: Fail to send reo q to FW. tid %d",
312*5113495bSYour Name 				    soc, tid);
313*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
314*5113495bSYour Name 		}
315*5113495bSYour Name 	}
316*5113495bSYour Name 
317*5113495bSYour Name 	if (!tid_bitmap) {
318*5113495bSYour Name 		dp_peer_err("tid_bitmap=0. All tids setup fail");
319*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
320*5113495bSYour Name 	}
321*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
322*5113495bSYour Name }
323*5113495bSYour Name 
324*5113495bSYour Name static inline QDF_STATUS
dp_peer_multi_tid_params_setup(struct dp_peer * peer,uint32_t tid_bitmap,uint32_t ba_window_size,struct multi_rx_reorder_queue_setup_params * tid_params)325*5113495bSYour Name dp_peer_multi_tid_params_setup(struct dp_peer *peer,
326*5113495bSYour Name 		uint32_t tid_bitmap,
327*5113495bSYour Name 		uint32_t ba_window_size,
328*5113495bSYour Name 		struct multi_rx_reorder_queue_setup_params *tid_params)
329*5113495bSYour Name {
330*5113495bSYour Name 	struct dp_rx_tid *rx_tid;
331*5113495bSYour Name 	int tid;
332*5113495bSYour Name 
333*5113495bSYour Name 	tid_params->peer_macaddr = peer->mac_addr.raw;
334*5113495bSYour Name 	tid_params->tid_bitmap = tid_bitmap;
335*5113495bSYour Name 	tid_params->vdev_id = peer->vdev->vdev_id;
336*5113495bSYour Name 
337*5113495bSYour Name 	for (tid = 0; tid < DP_MAX_TIDS; tid++) {
338*5113495bSYour Name 		if (!(BIT(tid) & tid_bitmap))
339*5113495bSYour Name 			continue;
340*5113495bSYour Name 
341*5113495bSYour Name 		rx_tid = &peer->rx_tid[tid];
342*5113495bSYour Name 		if (!rx_tid->hw_qdesc_paddr) {
343*5113495bSYour Name 			tid_params->tid_bitmap &= ~BIT(tid);
344*5113495bSYour Name 			continue;
345*5113495bSYour Name 		}
346*5113495bSYour Name 
347*5113495bSYour Name 		tid_params->tid_num++;
348*5113495bSYour Name 		tid_params->queue_params_list[tid].hw_qdesc_paddr =
349*5113495bSYour Name 			rx_tid->hw_qdesc_paddr;
350*5113495bSYour Name 		tid_params->queue_params_list[tid].queue_no = tid;
351*5113495bSYour Name 		tid_params->queue_params_list[tid].ba_window_size_valid = 1;
352*5113495bSYour Name 		tid_params->queue_params_list[tid].ba_window_size =
353*5113495bSYour Name 			ba_window_size;
354*5113495bSYour Name 	}
355*5113495bSYour Name 
356*5113495bSYour Name 	if (!tid_params->tid_bitmap) {
357*5113495bSYour Name 		dp_peer_err("tid_bitmap=0. All tids setup fail");
358*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
359*5113495bSYour Name 	}
360*5113495bSYour Name 
361*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
362*5113495bSYour Name }
363*5113495bSYour Name 
364*5113495bSYour Name static inline QDF_STATUS
dp_peer_rx_reorder_multi_q_setup(struct dp_peer * peer,uint32_t tid_bitmap,uint32_t ba_window_size)365*5113495bSYour Name dp_peer_rx_reorder_multi_q_setup(struct dp_peer *peer,
366*5113495bSYour Name 				 uint32_t tid_bitmap,
367*5113495bSYour Name 				 uint32_t ba_window_size)
368*5113495bSYour Name {
369*5113495bSYour Name 	QDF_STATUS status;
370*5113495bSYour Name 	struct dp_soc *soc = peer->vdev->pdev->soc;
371*5113495bSYour Name 	struct multi_rx_reorder_queue_setup_params tid_params = {0};
372*5113495bSYour Name 
373*5113495bSYour Name 	if (!soc->cdp_soc.ol_ops->peer_multi_rx_reorder_queue_setup) {
374*5113495bSYour Name 		dp_peer_debug("%pK: callback NULL", soc);
375*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
376*5113495bSYour Name 	}
377*5113495bSYour Name 
378*5113495bSYour Name 	status = dp_peer_multi_tid_params_setup(peer, tid_bitmap,
379*5113495bSYour Name 						ba_window_size,
380*5113495bSYour Name 						&tid_params);
381*5113495bSYour Name 	if (qdf_unlikely(QDF_IS_STATUS_ERROR(status)))
382*5113495bSYour Name 		return status;
383*5113495bSYour Name 
384*5113495bSYour Name 	if (soc->cdp_soc.ol_ops->peer_multi_rx_reorder_queue_setup(
385*5113495bSYour Name 	    soc->ctrl_psoc,
386*5113495bSYour Name 	    peer->vdev->pdev->pdev_id,
387*5113495bSYour Name 	    &tid_params)) {
388*5113495bSYour Name 		dp_peer_err("%pK: multi_reorder_q_setup fail. tid_bitmap 0x%x",
389*5113495bSYour Name 			    soc, tid_bitmap);
390*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
391*5113495bSYour Name 	}
392*5113495bSYour Name 
393*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
394*5113495bSYour Name }
395*5113495bSYour Name 
396*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
397*5113495bSYour Name /**
398*5113495bSYour Name  * dp_rx_mlo_igmp_handler() - Rx handler for Mcast packets
399*5113495bSYour Name  * @soc: Handle to DP Soc structure
400*5113495bSYour Name  * @vdev: DP vdev handle
401*5113495bSYour Name  * @peer: DP peer handle
402*5113495bSYour Name  * @nbuf: nbuf to be enqueued
403*5113495bSYour Name  * @link_id: link id on which the packet is received
404*5113495bSYour Name  *
405*5113495bSYour Name  * Return: true when packet sent to stack, false failure
406*5113495bSYour Name  */
407*5113495bSYour Name bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
408*5113495bSYour Name 			    struct dp_vdev *vdev,
409*5113495bSYour Name 			    struct dp_txrx_peer *peer,
410*5113495bSYour Name 			    qdf_nbuf_t nbuf,
411*5113495bSYour Name 			    uint8_t link_id);
412*5113495bSYour Name 
413*5113495bSYour Name /**
414*5113495bSYour Name  * dp_peer_rx_reorder_queue_setup_be() - Send reo queue
415*5113495bSYour Name  *        setup wmi cmd to FW per peer type
416*5113495bSYour Name  * @soc: DP Soc handle
417*5113495bSYour Name  * @peer: dp peer to operate on
418*5113495bSYour Name  * @tid_bitmap: TIDs to be set up
419*5113495bSYour Name  * @ba_window_size: BlockAck window size
420*5113495bSYour Name  *
421*5113495bSYour Name  * Return: 0 - success, others - failure
422*5113495bSYour Name  */
423*5113495bSYour Name static inline
dp_peer_rx_reorder_queue_setup_be(struct dp_soc * soc,struct dp_peer * peer,uint32_t tid_bitmap,uint32_t ba_window_size)424*5113495bSYour Name QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
425*5113495bSYour Name 					     struct dp_peer *peer,
426*5113495bSYour Name 					     uint32_t tid_bitmap,
427*5113495bSYour Name 					     uint32_t ba_window_size)
428*5113495bSYour Name {
429*5113495bSYour Name 	uint8_t i;
430*5113495bSYour Name 	struct dp_mld_link_peers link_peers_info;
431*5113495bSYour Name 	struct dp_peer *link_peer;
432*5113495bSYour Name 	struct dp_rx_tid *rx_tid;
433*5113495bSYour Name 	int tid;
434*5113495bSYour Name 	QDF_STATUS status;
435*5113495bSYour Name 
436*5113495bSYour Name 	if (hal_reo_shared_qaddr_is_enable(soc->hal_soc)) {
437*5113495bSYour Name 		/* Some BE targets dont require WMI and use shared
438*5113495bSYour Name 		 * table managed by host for storing Reo queue ref structs
439*5113495bSYour Name 		 */
440*5113495bSYour Name 		if (IS_MLO_DP_LINK_PEER(peer) ||
441*5113495bSYour Name 		    peer->peer_id == HTT_INVALID_PEER) {
442*5113495bSYour Name 			/* Return if this is for MLD link peer and table
443*5113495bSYour Name 			 * is not used in MLD link peer case as MLD peer's
444*5113495bSYour Name 			 * qref is written to LUT in peer setup or peer map.
445*5113495bSYour Name 			 * At this point peer setup for link peer is called
446*5113495bSYour Name 			 * before peer map, hence peer id is not assigned.
447*5113495bSYour Name 			 * This could happen if peer_setup is called before
448*5113495bSYour Name 			 * host receives HTT peer map. In this case return
449*5113495bSYour Name 			 * success with no op and let peer map handle
450*5113495bSYour Name 			 * writing the reo_qref to LUT.
451*5113495bSYour Name 			 */
452*5113495bSYour Name 			dp_peer_debug("Invalid peer id for dp_peer:%pK", peer);
453*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
454*5113495bSYour Name 		}
455*5113495bSYour Name 
456*5113495bSYour Name 		for (tid = 0; tid < DP_MAX_TIDS; tid++) {
457*5113495bSYour Name 			if (!((1 << tid) & tid_bitmap))
458*5113495bSYour Name 				continue;
459*5113495bSYour Name 
460*5113495bSYour Name 			rx_tid = &peer->rx_tid[tid];
461*5113495bSYour Name 			if (!rx_tid->hw_qdesc_paddr) {
462*5113495bSYour Name 				tid_bitmap &= ~BIT(tid);
463*5113495bSYour Name 				continue;
464*5113495bSYour Name 			}
465*5113495bSYour Name 
466*5113495bSYour Name 			hal_reo_shared_qaddr_write(soc->hal_soc,
467*5113495bSYour Name 						   peer->peer_id,
468*5113495bSYour Name 						   tid, peer->rx_tid[tid].
469*5113495bSYour Name 							hw_qdesc_paddr);
470*5113495bSYour Name 
471*5113495bSYour Name 			if (!tid_bitmap) {
472*5113495bSYour Name 				dp_peer_err("tid_bitmap=0. All tids setup fail");
473*5113495bSYour Name 				return QDF_STATUS_E_FAILURE;
474*5113495bSYour Name 			}
475*5113495bSYour Name 		}
476*5113495bSYour Name 
477*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
478*5113495bSYour Name 	}
479*5113495bSYour Name 
480*5113495bSYour Name 	/* when (!hal_reo_shared_qaddr_is_enable(soc->hal_soc)) is true: */
481*5113495bSYour Name 	if (IS_MLO_DP_MLD_PEER(peer)) {
482*5113495bSYour Name 		/* get link peers with reference */
483*5113495bSYour Name 		dp_get_link_peers_ref_from_mld_peer(soc, peer,
484*5113495bSYour Name 						    &link_peers_info,
485*5113495bSYour Name 						    DP_MOD_ID_CDP);
486*5113495bSYour Name 		/* send WMI cmd to each link peers */
487*5113495bSYour Name 		for (i = 0; i < link_peers_info.num_links; i++) {
488*5113495bSYour Name 			link_peer = link_peers_info.link_peers[i];
489*5113495bSYour Name 			if (soc->features.multi_rx_reorder_q_setup_support)
490*5113495bSYour Name 				status = dp_peer_rx_reorder_multi_q_setup(
491*5113495bSYour Name 					link_peer, tid_bitmap, ba_window_size);
492*5113495bSYour Name 			else
493*5113495bSYour Name 				status = dp_peer_rx_reorder_q_setup_per_tid(
494*5113495bSYour Name 							link_peer,
495*5113495bSYour Name 							tid_bitmap,
496*5113495bSYour Name 							ba_window_size);
497*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status)) {
498*5113495bSYour Name 				dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
499*5113495bSYour Name 				return status;
500*5113495bSYour Name 			}
501*5113495bSYour Name 		}
502*5113495bSYour Name 		/* release link peers reference */
503*5113495bSYour Name 		dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
504*5113495bSYour Name 	} else if (peer->peer_type == CDP_LINK_PEER_TYPE) {
505*5113495bSYour Name 		if (soc->features.multi_rx_reorder_q_setup_support)
506*5113495bSYour Name 			return dp_peer_rx_reorder_multi_q_setup(peer,
507*5113495bSYour Name 								tid_bitmap,
508*5113495bSYour Name 								ba_window_size);
509*5113495bSYour Name 		else
510*5113495bSYour Name 			return dp_peer_rx_reorder_q_setup_per_tid(peer,
511*5113495bSYour Name 							tid_bitmap,
512*5113495bSYour Name 							ba_window_size);
513*5113495bSYour Name 	} else {
514*5113495bSYour Name 		dp_peer_err("invalid peer type %d", peer->peer_type);
515*5113495bSYour Name 
516*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
517*5113495bSYour Name 	}
518*5113495bSYour Name 
519*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
520*5113495bSYour Name }
521*5113495bSYour Name #else
522*5113495bSYour Name static inline
dp_peer_rx_reorder_queue_setup_be(struct dp_soc * soc,struct dp_peer * peer,uint32_t tid_bitmap,uint32_t ba_window_size)523*5113495bSYour Name QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
524*5113495bSYour Name 					     struct dp_peer *peer,
525*5113495bSYour Name 					     uint32_t tid_bitmap,
526*5113495bSYour Name 					     uint32_t ba_window_size)
527*5113495bSYour Name {
528*5113495bSYour Name 	if (soc->features.multi_rx_reorder_q_setup_support)
529*5113495bSYour Name 		return dp_peer_rx_reorder_multi_q_setup(peer,
530*5113495bSYour Name 							tid_bitmap,
531*5113495bSYour Name 							ba_window_size);
532*5113495bSYour Name 	else
533*5113495bSYour Name 		return dp_peer_rx_reorder_q_setup_per_tid(peer,
534*5113495bSYour Name 							  tid_bitmap,
535*5113495bSYour Name 							  ba_window_size);
536*5113495bSYour Name }
537*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
538*5113495bSYour Name 
539*5113495bSYour Name #ifdef QCA_DP_RX_NBUF_AND_NBUF_DATA_PREFETCH
540*5113495bSYour Name static inline
dp_rx_prefetch_nbuf_data_be(qdf_nbuf_t nbuf,qdf_nbuf_t next)541*5113495bSYour Name void dp_rx_prefetch_nbuf_data_be(qdf_nbuf_t nbuf, qdf_nbuf_t next)
542*5113495bSYour Name {
543*5113495bSYour Name 	if (next) {
544*5113495bSYour Name 		/* prefetch skb->next and first few bytes of skb->cb */
545*5113495bSYour Name 		qdf_prefetch(next);
546*5113495bSYour Name 		/* skb->cb spread across 2 cache lines hence below prefetch */
547*5113495bSYour Name 		qdf_prefetch(&next->_skb_refdst);
548*5113495bSYour Name 		qdf_prefetch(&next->protocol);
549*5113495bSYour Name 		qdf_prefetch(&next->data);
550*5113495bSYour Name 		qdf_prefetch(next->data);
551*5113495bSYour Name 		qdf_prefetch(next->data + 64);
552*5113495bSYour Name 	}
553*5113495bSYour Name }
554*5113495bSYour Name #else
555*5113495bSYour Name static inline
dp_rx_prefetch_nbuf_data_be(qdf_nbuf_t nbuf,qdf_nbuf_t next)556*5113495bSYour Name void dp_rx_prefetch_nbuf_data_be(qdf_nbuf_t nbuf, qdf_nbuf_t next)
557*5113495bSYour Name {
558*5113495bSYour Name }
559*5113495bSYour Name #endif
560*5113495bSYour Name 
561*5113495bSYour Name #ifdef QCA_DP_RX_HW_SW_NBUF_DESC_PREFETCH
562*5113495bSYour Name /**
563*5113495bSYour Name  * dp_rx_va_prefetch() - function to prefetch the SW desc
564*5113495bSYour Name  * @last_prefetched_hw_desc: HW desc
565*5113495bSYour Name  *
566*5113495bSYour Name  * Return: prefetched Rx descriptor virtual address
567*5113495bSYour Name  */
568*5113495bSYour Name static inline
dp_rx_va_prefetch(void * last_prefetched_hw_desc)569*5113495bSYour Name void *dp_rx_va_prefetch(void *last_prefetched_hw_desc)
570*5113495bSYour Name {
571*5113495bSYour Name 	void *prefetch_desc;
572*5113495bSYour Name 
573*5113495bSYour Name 	prefetch_desc = (void *)hal_rx_get_reo_desc_va(last_prefetched_hw_desc);
574*5113495bSYour Name 	qdf_prefetch(prefetch_desc);
575*5113495bSYour Name 	return prefetch_desc;
576*5113495bSYour Name }
577*5113495bSYour Name 
578*5113495bSYour Name /**
579*5113495bSYour Name  * dp_rx_prefetch_hw_sw_nbuf_32_byte_desc() - function to prefetch HW and SW
580*5113495bSYour Name  *                                            descriptors
581*5113495bSYour Name  * @soc: DP soc context
582*5113495bSYour Name  * @hal_soc: Handle to HAL Soc structure
583*5113495bSYour Name  * @num_entries: valid number of HW descriptors
584*5113495bSYour Name  * @hal_ring_hdl: Destination ring pointer
585*5113495bSYour Name  * @last_prefetched_hw_desc: pointer to the last prefetched HW descriptor
586*5113495bSYour Name  * @last_prefetched_sw_desc: input & output param of last prefetch SW desc
587*5113495bSYour Name  *
588*5113495bSYour Name  * Return: None
589*5113495bSYour Name  */
590*5113495bSYour Name static inline void
dp_rx_prefetch_hw_sw_nbuf_32_byte_desc(struct dp_soc * soc,hal_soc_handle_t hal_soc,uint32_t num_entries,hal_ring_handle_t hal_ring_hdl,hal_ring_desc_t * last_prefetched_hw_desc,struct dp_rx_desc ** last_prefetched_sw_desc)591*5113495bSYour Name dp_rx_prefetch_hw_sw_nbuf_32_byte_desc(struct dp_soc *soc,
592*5113495bSYour Name 			       hal_soc_handle_t hal_soc,
593*5113495bSYour Name 			       uint32_t num_entries,
594*5113495bSYour Name 			       hal_ring_handle_t hal_ring_hdl,
595*5113495bSYour Name 			       hal_ring_desc_t *last_prefetched_hw_desc,
596*5113495bSYour Name 			       struct dp_rx_desc **last_prefetched_sw_desc)
597*5113495bSYour Name {
598*5113495bSYour Name 	if (*last_prefetched_sw_desc) {
599*5113495bSYour Name 		qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf);
600*5113495bSYour Name 		qdf_prefetch((uint8_t *)(*last_prefetched_sw_desc)->nbuf + 64);
601*5113495bSYour Name 	}
602*5113495bSYour Name 
603*5113495bSYour Name 	if (num_entries) {
604*5113495bSYour Name 		*last_prefetched_sw_desc =
605*5113495bSYour Name 			dp_rx_va_prefetch(*last_prefetched_hw_desc);
606*5113495bSYour Name 
607*5113495bSYour Name 		if ((uintptr_t)*last_prefetched_hw_desc & 0x3f)
608*5113495bSYour Name 			*last_prefetched_hw_desc =
609*5113495bSYour Name 				hal_srng_dst_prefetch_next_cached_desc(hal_soc,
610*5113495bSYour Name 					  hal_ring_hdl,
611*5113495bSYour Name 					  (uint8_t *)*last_prefetched_hw_desc);
612*5113495bSYour Name 		else
613*5113495bSYour Name 			*last_prefetched_hw_desc =
614*5113495bSYour Name 				hal_srng_dst_get_next_32_byte_desc(hal_soc,
615*5113495bSYour Name 				   hal_ring_hdl,
616*5113495bSYour Name 				   (uint8_t *)*last_prefetched_hw_desc);
617*5113495bSYour Name 	}
618*5113495bSYour Name }
619*5113495bSYour Name #else
620*5113495bSYour Name static inline void
dp_rx_prefetch_hw_sw_nbuf_32_byte_desc(struct dp_soc * soc,hal_soc_handle_t hal_soc,uint32_t num_entries,hal_ring_handle_t hal_ring_hdl,hal_ring_desc_t * last_prefetched_hw_desc,struct dp_rx_desc ** last_prefetched_sw_desc)621*5113495bSYour Name dp_rx_prefetch_hw_sw_nbuf_32_byte_desc(struct dp_soc *soc,
622*5113495bSYour Name 			       hal_soc_handle_t hal_soc,
623*5113495bSYour Name 			       uint32_t num_entries,
624*5113495bSYour Name 			       hal_ring_handle_t hal_ring_hdl,
625*5113495bSYour Name 			       hal_ring_desc_t *last_prefetched_hw_desc,
626*5113495bSYour Name 			       struct dp_rx_desc **last_prefetched_sw_desc)
627*5113495bSYour Name {
628*5113495bSYour Name }
629*5113495bSYour Name #endif
630*5113495bSYour Name #ifdef CONFIG_WORD_BASED_TLV
631*5113495bSYour Name /**
632*5113495bSYour Name  * dp_rx_get_reo_qdesc_addr_be(): API to get qdesc address of reo
633*5113495bSYour Name  * entrance ring desc
634*5113495bSYour Name  *
635*5113495bSYour Name  * @hal_soc: Handle to HAL Soc structure
636*5113495bSYour Name  * @dst_ring_desc: reo dest ring descriptor (used for Lithium DP)
637*5113495bSYour Name  * @buf: pointer to the start of RX PKT TLV headers
638*5113495bSYour Name  * @txrx_peer: pointer to txrx_peer
639*5113495bSYour Name  * @tid: tid value
640*5113495bSYour Name  *
641*5113495bSYour Name  * Return: qdesc address in reo destination ring buffer
642*5113495bSYour Name  */
643*5113495bSYour Name static inline
dp_rx_get_reo_qdesc_addr_be(hal_soc_handle_t hal_soc,uint8_t * dst_ring_desc,uint8_t * buf,struct dp_txrx_peer * txrx_peer,unsigned int tid)644*5113495bSYour Name uint64_t dp_rx_get_reo_qdesc_addr_be(hal_soc_handle_t hal_soc,
645*5113495bSYour Name 				     uint8_t *dst_ring_desc,
646*5113495bSYour Name 				     uint8_t *buf,
647*5113495bSYour Name 				     struct dp_txrx_peer *txrx_peer,
648*5113495bSYour Name 				     unsigned int tid)
649*5113495bSYour Name {
650*5113495bSYour Name 	struct dp_peer *peer = NULL;
651*5113495bSYour Name 	uint64_t qdesc_addr = 0;
652*5113495bSYour Name 
653*5113495bSYour Name 	if (hal_reo_shared_qaddr_is_enable(hal_soc)) {
654*5113495bSYour Name 		qdesc_addr = (uint64_t)txrx_peer->peer_id;
655*5113495bSYour Name 	} else {
656*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(txrx_peer->vdev->pdev->soc,
657*5113495bSYour Name 					     txrx_peer->peer_id,
658*5113495bSYour Name 					     DP_MOD_ID_CONFIG);
659*5113495bSYour Name 		if (!peer)
660*5113495bSYour Name 			return 0;
661*5113495bSYour Name 
662*5113495bSYour Name 		qdesc_addr = (uint64_t)peer->rx_tid[tid].hw_qdesc_paddr;
663*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
664*5113495bSYour Name 	}
665*5113495bSYour Name 	return qdesc_addr;
666*5113495bSYour Name }
667*5113495bSYour Name #else
668*5113495bSYour Name static inline
dp_rx_get_reo_qdesc_addr_be(hal_soc_handle_t hal_soc,uint8_t * dst_ring_desc,uint8_t * buf,struct dp_txrx_peer * txrx_peer,unsigned int tid)669*5113495bSYour Name uint64_t dp_rx_get_reo_qdesc_addr_be(hal_soc_handle_t hal_soc,
670*5113495bSYour Name 				     uint8_t *dst_ring_desc,
671*5113495bSYour Name 				     uint8_t *buf,
672*5113495bSYour Name 				     struct dp_txrx_peer *txrx_peer,
673*5113495bSYour Name 				     unsigned int tid)
674*5113495bSYour Name {
675*5113495bSYour Name 	return hal_rx_get_qdesc_addr(hal_soc, dst_ring_desc, buf);
676*5113495bSYour Name }
677*5113495bSYour Name #endif
678*5113495bSYour Name 
679*5113495bSYour Name /**
680*5113495bSYour Name  * dp_rx_wbm_err_reap_desc_be() - Function to reap and replenish
681*5113495bSYour Name  *                                WBM RX Error descriptors
682*5113495bSYour Name  *
683*5113495bSYour Name  * @int_ctx: pointer to DP interrupt context
684*5113495bSYour Name  * @soc: core DP main context
685*5113495bSYour Name  * @hal_ring_hdl: opaque pointer to the HAL Rx Error Ring, to be serviced
686*5113495bSYour Name  * @quota: No. of units (packets) that can be serviced in one shot.
687*5113495bSYour Name  * @rx_bufs_used: No. of descriptors reaped
688*5113495bSYour Name  *
689*5113495bSYour Name  * This function implements the core Rx functionality like reap and
690*5113495bSYour Name  * replenish the RX error ring Descriptors, and create a nbuf list
691*5113495bSYour Name  * out of it. It also reads wbm error information from descriptors
692*5113495bSYour Name  * and update the nbuf tlv area.
693*5113495bSYour Name  *
694*5113495bSYour Name  * Return: qdf_nbuf_t: head pointer to the nbuf list created
695*5113495bSYour Name  */
696*5113495bSYour Name qdf_nbuf_t
697*5113495bSYour Name dp_rx_wbm_err_reap_desc_be(struct dp_intr *int_ctx, struct dp_soc *soc,
698*5113495bSYour Name 			   hal_ring_handle_t hal_ring_hdl, uint32_t quota,
699*5113495bSYour Name 			   uint32_t *rx_bufs_used);
700*5113495bSYour Name 
701*5113495bSYour Name /**
702*5113495bSYour Name  * dp_rx_null_q_desc_handle_be() - Function to handle NULL Queue
703*5113495bSYour Name  *                                 descriptor violation on either a
704*5113495bSYour Name  *                                 REO or WBM ring
705*5113495bSYour Name  *
706*5113495bSYour Name  * @soc: core DP main context
707*5113495bSYour Name  * @nbuf: buffer pointer
708*5113495bSYour Name  * @rx_tlv_hdr: start of rx tlv header
709*5113495bSYour Name  * @pool_id: mac id
710*5113495bSYour Name  * @txrx_peer: txrx peer handle
711*5113495bSYour Name  * @is_reo_exception: flag to check if the error is from REO or WBM
712*5113495bSYour Name  * @link_id: link Id on which the packet is received
713*5113495bSYour Name  *
714*5113495bSYour Name  * This function handles NULL queue descriptor violations arising out
715*5113495bSYour Name  * a missing REO queue for a given peer or a given TID. This typically
716*5113495bSYour Name  * may happen if a packet is received on a QOS enabled TID before the
717*5113495bSYour Name  * ADDBA negotiation for that TID, when the TID queue is setup. Or
718*5113495bSYour Name  * it may also happen for MC/BC frames if they are not routed to the
719*5113495bSYour Name  * non-QOS TID queue, in the absence of any other default TID queue.
720*5113495bSYour Name  * This error can show up both in a REO destination or WBM release ring.
721*5113495bSYour Name  *
722*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS, if nbuf handled successfully. QDF status code
723*5113495bSYour Name  *         if nbuf could not be handled or dropped.
724*5113495bSYour Name  */
725*5113495bSYour Name QDF_STATUS
726*5113495bSYour Name dp_rx_null_q_desc_handle_be(struct dp_soc *soc, qdf_nbuf_t nbuf,
727*5113495bSYour Name 			    uint8_t *rx_tlv_hdr, uint8_t pool_id,
728*5113495bSYour Name 			    struct dp_txrx_peer *txrx_peer,
729*5113495bSYour Name 			    bool is_reo_exception, uint8_t link_id);
730*5113495bSYour Name 
731*5113495bSYour Name #if defined(DP_PKT_STATS_PER_LMAC) && defined(WLAN_FEATURE_11BE_MLO)
732*5113495bSYour Name static inline void
dp_rx_set_msdu_lmac_id(qdf_nbuf_t nbuf,uint32_t peer_mdata)733*5113495bSYour Name dp_rx_set_msdu_lmac_id(qdf_nbuf_t nbuf, uint32_t peer_mdata)
734*5113495bSYour Name {
735*5113495bSYour Name 	uint8_t lmac_id;
736*5113495bSYour Name 
737*5113495bSYour Name 	lmac_id = dp_rx_peer_metadata_lmac_id_get_be(peer_mdata);
738*5113495bSYour Name 	qdf_nbuf_set_lmac_id(nbuf, lmac_id);
739*5113495bSYour Name }
740*5113495bSYour Name #else
741*5113495bSYour Name static inline void
dp_rx_set_msdu_lmac_id(qdf_nbuf_t nbuf,uint32_t peer_mdata)742*5113495bSYour Name dp_rx_set_msdu_lmac_id(qdf_nbuf_t nbuf, uint32_t peer_mdata)
743*5113495bSYour Name {
744*5113495bSYour Name }
745*5113495bSYour Name #endif
746*5113495bSYour Name 
747*5113495bSYour Name #ifndef CONFIG_NBUF_AP_PLATFORM
748*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT)
749*5113495bSYour Name static inline uint8_t
dp_rx_peer_mdata_link_id_get_be(uint32_t peer_mdata)750*5113495bSYour Name dp_rx_peer_mdata_link_id_get_be(uint32_t peer_mdata)
751*5113495bSYour Name {
752*5113495bSYour Name 	uint8_t link_id;
753*5113495bSYour Name 
754*5113495bSYour Name 	link_id = HTT_RX_PEER_META_DATA_V1A_LOGICAL_LINK_ID_GET(peer_mdata) + 1;
755*5113495bSYour Name 	if (link_id > DP_MAX_MLO_LINKS)
756*5113495bSYour Name 		link_id = 0;
757*5113495bSYour Name 
758*5113495bSYour Name 	return link_id;
759*5113495bSYour Name }
760*5113495bSYour Name #else
761*5113495bSYour Name static inline uint8_t
dp_rx_peer_mdata_link_id_get_be(uint32_t peer_metadata)762*5113495bSYour Name dp_rx_peer_mdata_link_id_get_be(uint32_t peer_metadata)
763*5113495bSYour Name {
764*5113495bSYour Name 	return 0;
765*5113495bSYour Name }
766*5113495bSYour Name #endif /* DP_MLO_LINK_STATS_SUPPORT */
767*5113495bSYour Name 
768*5113495bSYour Name static inline void
dp_rx_set_mpdu_seq_number_be(qdf_nbuf_t nbuf,uint8_t * rx_tlv_hdr)769*5113495bSYour Name dp_rx_set_mpdu_seq_number_be(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
770*5113495bSYour Name {
771*5113495bSYour Name 	QDF_NBUF_CB_RX_MPDU_SEQ_NUM(nbuf) =
772*5113495bSYour Name 		hal_rx_mpdu_sequence_number_get_be(rx_tlv_hdr);
773*5113495bSYour Name }
774*5113495bSYour Name 
775*5113495bSYour Name static inline void
dp_rx_set_link_id_be(qdf_nbuf_t nbuf,uint32_t peer_mdata)776*5113495bSYour Name dp_rx_set_link_id_be(qdf_nbuf_t nbuf, uint32_t peer_mdata)
777*5113495bSYour Name {
778*5113495bSYour Name 	uint8_t logical_link_id;
779*5113495bSYour Name 
780*5113495bSYour Name 	logical_link_id = dp_rx_peer_mdata_link_id_get_be(peer_mdata);
781*5113495bSYour Name 	QDF_NBUF_CB_RX_LOGICAL_LINK_ID(nbuf) = logical_link_id;
782*5113495bSYour Name }
783*5113495bSYour Name 
784*5113495bSYour Name static inline uint16_t
dp_rx_get_peer_id_be(qdf_nbuf_t nbuf)785*5113495bSYour Name dp_rx_get_peer_id_be(qdf_nbuf_t nbuf)
786*5113495bSYour Name {
787*5113495bSYour Name 	return QDF_NBUF_CB_RX_PEER_ID(nbuf);
788*5113495bSYour Name }
789*5113495bSYour Name 
790*5113495bSYour Name static inline void
dp_rx_set_mpdu_msdu_desc_info_in_nbuf(qdf_nbuf_t nbuf,uint32_t mpdu_desc_info,uint32_t peer_mdata,uint32_t msdu_desc_info)791*5113495bSYour Name dp_rx_set_mpdu_msdu_desc_info_in_nbuf(qdf_nbuf_t nbuf,
792*5113495bSYour Name 				      uint32_t mpdu_desc_info,
793*5113495bSYour Name 				      uint32_t peer_mdata,
794*5113495bSYour Name 				      uint32_t msdu_desc_info)
795*5113495bSYour Name {
796*5113495bSYour Name }
797*5113495bSYour Name 
dp_rx_copy_desc_info_in_nbuf_cb(struct dp_soc * soc,hal_ring_desc_t ring_desc,qdf_nbuf_t nbuf,uint8_t reo_ring_num)798*5113495bSYour Name static inline uint8_t dp_rx_copy_desc_info_in_nbuf_cb(struct dp_soc *soc,
799*5113495bSYour Name 						      hal_ring_desc_t ring_desc,
800*5113495bSYour Name 						      qdf_nbuf_t nbuf,
801*5113495bSYour Name 						      uint8_t reo_ring_num)
802*5113495bSYour Name {
803*5113495bSYour Name 	struct hal_rx_mpdu_desc_info mpdu_desc_info;
804*5113495bSYour Name 	struct hal_rx_msdu_desc_info msdu_desc_info;
805*5113495bSYour Name 	uint8_t pkt_capture_offload = 0;
806*5113495bSYour Name 	uint32_t peer_mdata = 0;
807*5113495bSYour Name 
808*5113495bSYour Name 	qdf_mem_zero(&mpdu_desc_info, sizeof(mpdu_desc_info));
809*5113495bSYour Name 	qdf_mem_zero(&msdu_desc_info, sizeof(msdu_desc_info));
810*5113495bSYour Name 
811*5113495bSYour Name 	/* Get MPDU DESC info */
812*5113495bSYour Name 	hal_rx_mpdu_desc_info_get_be(ring_desc, &mpdu_desc_info);
813*5113495bSYour Name 
814*5113495bSYour Name 	/* Get MSDU DESC info */
815*5113495bSYour Name 	hal_rx_msdu_desc_info_get_be(ring_desc, &msdu_desc_info);
816*5113495bSYour Name 
817*5113495bSYour Name 	/* Set the end bit to identify the last buffer in MPDU */
818*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU)
819*5113495bSYour Name 		qdf_nbuf_set_rx_chfrag_end(nbuf, 1);
820*5113495bSYour Name 
821*5113495bSYour Name 	if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_RETRY_BIT)
822*5113495bSYour Name 		qdf_nbuf_set_rx_retry_flag(nbuf, 1);
823*5113495bSYour Name 
824*5113495bSYour Name 	if (qdf_unlikely(mpdu_desc_info.mpdu_flags & HAL_MPDU_F_RAW_AMPDU))
825*5113495bSYour Name 		qdf_nbuf_set_raw_frame(nbuf, 1);
826*5113495bSYour Name 
827*5113495bSYour Name 	peer_mdata = mpdu_desc_info.peer_meta_data;
828*5113495bSYour Name 	QDF_NBUF_CB_RX_PEER_ID(nbuf) =
829*5113495bSYour Name 		dp_rx_peer_metadata_peer_id_get_be(soc, peer_mdata);
830*5113495bSYour Name 	QDF_NBUF_CB_RX_VDEV_ID(nbuf) =
831*5113495bSYour Name 		dp_rx_peer_metadata_vdev_id_get_be(soc, peer_mdata);
832*5113495bSYour Name 	dp_rx_set_msdu_lmac_id(nbuf, peer_mdata);
833*5113495bSYour Name 	dp_rx_set_link_id_be(nbuf, peer_mdata);
834*5113495bSYour Name 
835*5113495bSYour Name 	/* to indicate whether this msdu is rx offload */
836*5113495bSYour Name 	pkt_capture_offload =
837*5113495bSYour Name 		DP_PEER_METADATA_OFFLOAD_GET_BE(peer_mdata);
838*5113495bSYour Name 
839*5113495bSYour Name 	/*
840*5113495bSYour Name 	 * save msdu flags first, last and continuation msdu in
841*5113495bSYour Name 	 * nbuf->cb, also save mcbc, is_da_valid, is_sa_valid and
842*5113495bSYour Name 	 * length to nbuf->cb. This ensures the info required for
843*5113495bSYour Name 	 * per pkt processing is always in the same cache line.
844*5113495bSYour Name 	 * This helps in improving throughput for smaller pkt
845*5113495bSYour Name 	 * sizes.
846*5113495bSYour Name 	 */
847*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_FIRST_MSDU_IN_MPDU)
848*5113495bSYour Name 		qdf_nbuf_set_rx_chfrag_start(nbuf, 1);
849*5113495bSYour Name 
850*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION)
851*5113495bSYour Name 		qdf_nbuf_set_rx_chfrag_cont(nbuf, 1);
852*5113495bSYour Name 
853*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_DA_IS_MCBC)
854*5113495bSYour Name 		qdf_nbuf_set_da_mcbc(nbuf, 1);
855*5113495bSYour Name 
856*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_DA_IS_VALID)
857*5113495bSYour Name 		qdf_nbuf_set_da_valid(nbuf, 1);
858*5113495bSYour Name 
859*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_SA_IS_VALID)
860*5113495bSYour Name 		qdf_nbuf_set_sa_valid(nbuf, 1);
861*5113495bSYour Name 
862*5113495bSYour Name 	if (msdu_desc_info.msdu_flags & HAL_MSDU_F_INTRA_BSS)
863*5113495bSYour Name 		qdf_nbuf_set_intra_bss(nbuf, 1);
864*5113495bSYour Name 
865*5113495bSYour Name 	if (qdf_likely(mpdu_desc_info.mpdu_flags &
866*5113495bSYour Name 		       HAL_MPDU_F_QOS_CONTROL_VALID))
867*5113495bSYour Name 		qdf_nbuf_set_tid_val(nbuf, mpdu_desc_info.tid);
868*5113495bSYour Name 
869*5113495bSYour Name 	/* set sw exception */
870*5113495bSYour Name 	qdf_nbuf_set_rx_reo_dest_ind_or_sw_excpt(
871*5113495bSYour Name 			nbuf,
872*5113495bSYour Name 			hal_rx_sw_exception_get_be(ring_desc));
873*5113495bSYour Name 
874*5113495bSYour Name 	QDF_NBUF_CB_RX_PKT_LEN(nbuf) = msdu_desc_info.msdu_len;
875*5113495bSYour Name 
876*5113495bSYour Name 	QDF_NBUF_CB_RX_CTX_ID(nbuf) = reo_ring_num;
877*5113495bSYour Name 
878*5113495bSYour Name 	return pkt_capture_offload;
879*5113495bSYour Name }
880*5113495bSYour Name 
hal_rx_get_l3_pad_bytes_be(qdf_nbuf_t nbuf,uint8_t * rx_tlv_hdr)881*5113495bSYour Name static inline uint8_t hal_rx_get_l3_pad_bytes_be(qdf_nbuf_t nbuf,
882*5113495bSYour Name 						 uint8_t *rx_tlv_hdr)
883*5113495bSYour Name {
884*5113495bSYour Name 	return HAL_RX_TLV_L3_HEADER_PADDING_GET(rx_tlv_hdr);
885*5113495bSYour Name }
886*5113495bSYour Name 
887*5113495bSYour Name static inline uint8_t
dp_rx_wbm_err_msdu_continuation_get(struct dp_soc * soc,hal_ring_desc_t ring_desc,qdf_nbuf_t nbuf)888*5113495bSYour Name dp_rx_wbm_err_msdu_continuation_get(struct dp_soc *soc,
889*5113495bSYour Name 				    hal_ring_desc_t ring_desc,
890*5113495bSYour Name 				    qdf_nbuf_t nbuf)
891*5113495bSYour Name {
892*5113495bSYour Name 	return hal_rx_wbm_err_msdu_continuation_get(soc->hal_soc,
893*5113495bSYour Name 						    ring_desc);
894*5113495bSYour Name }
895*5113495bSYour Name #else
896*5113495bSYour Name static inline void
dp_rx_set_link_id_be(qdf_nbuf_t nbuf,uint32_t peer_mdata)897*5113495bSYour Name dp_rx_set_link_id_be(qdf_nbuf_t nbuf, uint32_t peer_mdata)
898*5113495bSYour Name {
899*5113495bSYour Name }
900*5113495bSYour Name 
901*5113495bSYour Name static inline void
dp_rx_set_mpdu_seq_number_be(qdf_nbuf_t nbuf,uint8_t * rx_tlv_hdr)902*5113495bSYour Name dp_rx_set_mpdu_seq_number_be(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
903*5113495bSYour Name {
904*5113495bSYour Name }
905*5113495bSYour Name 
906*5113495bSYour Name static inline uint16_t
dp_rx_get_peer_id_be(qdf_nbuf_t nbuf)907*5113495bSYour Name dp_rx_get_peer_id_be(qdf_nbuf_t nbuf)
908*5113495bSYour Name {
909*5113495bSYour Name 	uint32_t peer_metadata = QDF_NBUF_CB_RX_MPDU_DESC_INFO_2(nbuf);
910*5113495bSYour Name 
911*5113495bSYour Name 	return ((peer_metadata & DP_BE_PEER_METADATA_PEER_ID_MASK) >>
912*5113495bSYour Name 		DP_BE_PEER_METADATA_PEER_ID_SHIFT);
913*5113495bSYour Name }
914*5113495bSYour Name 
915*5113495bSYour Name static inline void
dp_rx_set_mpdu_msdu_desc_info_in_nbuf(qdf_nbuf_t nbuf,uint32_t mpdu_desc_info,uint32_t peer_mdata,uint32_t msdu_desc_info)916*5113495bSYour Name dp_rx_set_mpdu_msdu_desc_info_in_nbuf(qdf_nbuf_t nbuf,
917*5113495bSYour Name 				      uint32_t mpdu_desc_info,
918*5113495bSYour Name 				      uint32_t peer_mdata,
919*5113495bSYour Name 				      uint32_t msdu_desc_info)
920*5113495bSYour Name {
921*5113495bSYour Name 	QDF_NBUF_CB_RX_MPDU_DESC_INFO_1(nbuf) = mpdu_desc_info;
922*5113495bSYour Name 	QDF_NBUF_CB_RX_MPDU_DESC_INFO_2(nbuf) = peer_mdata;
923*5113495bSYour Name 	QDF_NBUF_CB_RX_MSDU_DESC_INFO(nbuf) = msdu_desc_info;
924*5113495bSYour Name }
925*5113495bSYour Name 
dp_rx_copy_desc_info_in_nbuf_cb(struct dp_soc * soc,hal_ring_desc_t ring_desc,qdf_nbuf_t nbuf,uint8_t reo_ring_num)926*5113495bSYour Name static inline uint8_t dp_rx_copy_desc_info_in_nbuf_cb(struct dp_soc *soc,
927*5113495bSYour Name 						      hal_ring_desc_t ring_desc,
928*5113495bSYour Name 						      qdf_nbuf_t nbuf,
929*5113495bSYour Name 						      uint8_t reo_ring_num)
930*5113495bSYour Name {
931*5113495bSYour Name 	uint32_t mpdu_desc_info = 0;
932*5113495bSYour Name 	uint32_t msdu_desc_info = 0;
933*5113495bSYour Name 	uint32_t peer_mdata = 0;
934*5113495bSYour Name 
935*5113495bSYour Name 	/* get REO mpdu & msdu desc info */
936*5113495bSYour Name 	hal_rx_get_mpdu_msdu_desc_info_be(ring_desc,
937*5113495bSYour Name 					  &mpdu_desc_info,
938*5113495bSYour Name 					  &peer_mdata,
939*5113495bSYour Name 					  &msdu_desc_info);
940*5113495bSYour Name 
941*5113495bSYour Name 	dp_rx_set_mpdu_msdu_desc_info_in_nbuf(nbuf,
942*5113495bSYour Name 					      mpdu_desc_info,
943*5113495bSYour Name 					      peer_mdata,
944*5113495bSYour Name 					      msdu_desc_info);
945*5113495bSYour Name 
946*5113495bSYour Name 		return 0;
947*5113495bSYour Name }
948*5113495bSYour Name 
hal_rx_get_l3_pad_bytes_be(qdf_nbuf_t nbuf,uint8_t * rx_tlv_hdr)949*5113495bSYour Name static inline uint8_t hal_rx_get_l3_pad_bytes_be(qdf_nbuf_t nbuf,
950*5113495bSYour Name 						 uint8_t *rx_tlv_hdr)
951*5113495bSYour Name {
952*5113495bSYour Name 	return QDF_NBUF_CB_RX_L3_PAD_MSB(nbuf) ? 2 : 0;
953*5113495bSYour Name }
954*5113495bSYour Name 
955*5113495bSYour Name static inline uint8_t
dp_rx_wbm_err_msdu_continuation_get(struct dp_soc * soc,hal_ring_desc_t ring_desc,qdf_nbuf_t nbuf)956*5113495bSYour Name dp_rx_wbm_err_msdu_continuation_get(struct dp_soc *soc,
957*5113495bSYour Name 				    hal_ring_desc_t ring_desc,
958*5113495bSYour Name 				    qdf_nbuf_t nbuf)
959*5113495bSYour Name {
960*5113495bSYour Name 	return qdf_nbuf_is_rx_chfrag_cont(nbuf);
961*5113495bSYour Name }
962*5113495bSYour Name #endif /* CONFIG_NBUF_AP_PLATFORM */
963*5113495bSYour Name 
964*5113495bSYour Name /**
965*5113495bSYour Name  * dp_rx_wbm_err_copy_desc_info_in_nbuf(): API to copy WBM dest ring
966*5113495bSYour Name  * descriptor information in nbuf CB/TLV
967*5113495bSYour Name  *
968*5113495bSYour Name  * @soc: pointer to Soc structure
969*5113495bSYour Name  * @ring_desc: wbm dest ring descriptor
970*5113495bSYour Name  * @nbuf: nbuf to save descriptor information
971*5113495bSYour Name  * @pool_id: pool id part of wbm error info
972*5113495bSYour Name  *
973*5113495bSYour Name  * Return: wbm error information details
974*5113495bSYour Name  */
975*5113495bSYour Name static inline uint32_t
dp_rx_wbm_err_copy_desc_info_in_nbuf(struct dp_soc * soc,hal_ring_desc_t ring_desc,qdf_nbuf_t nbuf,uint8_t pool_id)976*5113495bSYour Name dp_rx_wbm_err_copy_desc_info_in_nbuf(struct dp_soc *soc,
977*5113495bSYour Name 				     hal_ring_desc_t ring_desc,
978*5113495bSYour Name 				     qdf_nbuf_t nbuf,
979*5113495bSYour Name 				     uint8_t pool_id)
980*5113495bSYour Name {
981*5113495bSYour Name 	uint32_t mpdu_desc_info = 0;
982*5113495bSYour Name 	uint32_t msdu_desc_info = 0;
983*5113495bSYour Name 	uint32_t peer_mdata = 0;
984*5113495bSYour Name 	union hal_wbm_err_info_u wbm_err = { 0 };
985*5113495bSYour Name 
986*5113495bSYour Name 	/* get WBM mpdu & msdu desc info */
987*5113495bSYour Name 	hal_rx_wbm_err_mpdu_msdu_info_get_be(ring_desc,
988*5113495bSYour Name 					     &wbm_err.info,
989*5113495bSYour Name 					     &mpdu_desc_info,
990*5113495bSYour Name 					     &msdu_desc_info,
991*5113495bSYour Name 					     &peer_mdata);
992*5113495bSYour Name 
993*5113495bSYour Name 	wbm_err.info_bit.pool_id = pool_id;
994*5113495bSYour Name 	dp_rx_set_mpdu_msdu_desc_info_in_nbuf(nbuf,
995*5113495bSYour Name 					      mpdu_desc_info,
996*5113495bSYour Name 					      peer_mdata,
997*5113495bSYour Name 					      msdu_desc_info);
998*5113495bSYour Name 	dp_rx_set_wbm_err_info_in_nbuf(soc, nbuf, wbm_err);
999*5113495bSYour Name 	return wbm_err.info;
1000*5113495bSYour Name }
1001*5113495bSYour Name 
1002*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
1003*5113495bSYour Name struct dp_soc *
1004*5113495bSYour Name dp_get_soc_by_chip_id_be(struct dp_soc *soc, uint8_t chip_id);
1005*5113495bSYour Name #else
1006*5113495bSYour Name static inline struct dp_soc *
dp_get_soc_by_chip_id_be(struct dp_soc * soc,uint8_t chip_id)1007*5113495bSYour Name dp_get_soc_by_chip_id_be(struct dp_soc *soc, uint8_t chip_id)
1008*5113495bSYour Name {
1009*5113495bSYour Name 	return soc;
1010*5113495bSYour Name }
1011*5113495bSYour Name #endif
1012*5113495bSYour Name #endif
1013