xref: /wlan-driver/qcacld-3.0/core/dp/txrx/ol_tx_desc.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
5*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
6*5113495bSYour Name  * above copyright notice and this permission notice appear in all
7*5113495bSYour Name  * copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
17*5113495bSYour Name  */
18*5113495bSYour Name 
19*5113495bSYour Name /**
20*5113495bSYour Name  * @file ol_tx_desc.h
21*5113495bSYour Name  * @brief API definitions for the tx descriptor module within the data SW.
22*5113495bSYour Name  */
23*5113495bSYour Name #ifndef _OL_TX_DESC__H_
24*5113495bSYour Name #define _OL_TX_DESC__H_
25*5113495bSYour Name 
26*5113495bSYour Name #include "queue.h"          /* TAILQ_HEAD */
27*5113495bSYour Name #include <qdf_nbuf.h>           /* qdf_nbuf_t */
28*5113495bSYour Name #include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
29*5113495bSYour Name #include <ol_txrx_internal.h>   /*TXRX_ASSERT2 */
30*5113495bSYour Name #include <ol_htt_tx_api.h>
31*5113495bSYour Name 
32*5113495bSYour Name #define DIV_BY_8	3
33*5113495bSYour Name #define DIV_BY_32	5
34*5113495bSYour Name #define MOD_BY_8	0x7
35*5113495bSYour Name #define MOD_BY_32	0x1F
36*5113495bSYour Name 
37*5113495bSYour Name struct ol_tx_desc_t *
38*5113495bSYour Name ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
39*5113495bSYour Name 			 struct ol_txrx_vdev_t *vdev,
40*5113495bSYour Name 			 struct ol_txrx_msdu_info_t *msdu_info);
41*5113495bSYour Name 
42*5113495bSYour Name 
43*5113495bSYour Name /**
44*5113495bSYour Name  * @brief Allocate and initialize a tx descriptor for a LL system.
45*5113495bSYour Name  * @details
46*5113495bSYour Name  *  Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor
47*5113495bSYour Name  *  for private use within the host data SW, and a HTT tx descriptor for
48*5113495bSYour Name  *  downloading tx meta-data to the target FW/HW.
49*5113495bSYour Name  *  Fill in the fields of this pair of tx descriptors based on the
50*5113495bSYour Name  *  information in the netbuf.
51*5113495bSYour Name  *  For LL, this includes filling in a fragmentation descriptor to
52*5113495bSYour Name  *  specify to the MAC HW where to find the tx frame's fragments.
53*5113495bSYour Name  *
54*5113495bSYour Name  * @param pdev - the data physical device sending the data
55*5113495bSYour Name  *      (for accessing the tx desc pool)
56*5113495bSYour Name  * @param vdev - the virtual device sending the data
57*5113495bSYour Name  *      (for specifying the transmitter address for multicast / broadcast data)
58*5113495bSYour Name  * @param netbuf - the tx frame
59*5113495bSYour Name  * @param msdu_info - tx meta-data
60*5113495bSYour Name  */
61*5113495bSYour Name struct ol_tx_desc_t *ol_tx_desc_ll(struct ol_txrx_pdev_t *pdev,
62*5113495bSYour Name 				   struct ol_txrx_vdev_t *vdev,
63*5113495bSYour Name 				   qdf_nbuf_t netbuf,
64*5113495bSYour Name 				   struct ol_txrx_msdu_info_t *msdu_info);
65*5113495bSYour Name 
66*5113495bSYour Name 
67*5113495bSYour Name /**
68*5113495bSYour Name  * @brief Allocate and initialize a tx descriptor for a HL system.
69*5113495bSYour Name  * @details
70*5113495bSYour Name  *  Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor
71*5113495bSYour Name  *  for private use within the host data SW, and a HTT tx descriptor for
72*5113495bSYour Name  *  downloading tx meta-data to the target FW/HW.
73*5113495bSYour Name  *  Fill in the fields of this pair of tx descriptors based on the
74*5113495bSYour Name  *  information in the netbuf.
75*5113495bSYour Name  *
76*5113495bSYour Name  * @param pdev - the data physical device sending the data
77*5113495bSYour Name  *      (for accessing the tx desc pool)
78*5113495bSYour Name  * @param vdev - the virtual device sending the data
79*5113495bSYour Name  *      (for specifying the transmitter address for multicast / broadcast data)
80*5113495bSYour Name  * @param netbuf - the tx frame
81*5113495bSYour Name  * @param msdu_info - tx meta-data
82*5113495bSYour Name  */
83*5113495bSYour Name struct ol_tx_desc_t *
84*5113495bSYour Name ol_tx_desc_hl(
85*5113495bSYour Name 		struct ol_txrx_pdev_t *pdev,
86*5113495bSYour Name 		struct ol_txrx_vdev_t *vdev,
87*5113495bSYour Name 		qdf_nbuf_t netbuf,
88*5113495bSYour Name 		struct ol_txrx_msdu_info_t *msdu_info);
89*5113495bSYour Name 
90*5113495bSYour Name 
91*5113495bSYour Name /**
92*5113495bSYour Name  * @brief Use a tx descriptor ID to find the corresponding descriptor object.
93*5113495bSYour Name  *
94*5113495bSYour Name  * @param pdev - the data physical device sending the data
95*5113495bSYour Name  * @param tx_desc_id - the ID of the descriptor in question
96*5113495bSYour Name  * @return the descriptor object that has the specified ID
97*5113495bSYour Name  */
ol_tx_desc_find(struct ol_txrx_pdev_t * pdev,uint16_t tx_desc_id)98*5113495bSYour Name static inline struct ol_tx_desc_t *ol_tx_desc_find(
99*5113495bSYour Name 			struct ol_txrx_pdev_t *pdev, uint16_t tx_desc_id)
100*5113495bSYour Name {
101*5113495bSYour Name 	void **td_base = (void **)pdev->tx_desc.desc_pages.cacheable_pages;
102*5113495bSYour Name 
103*5113495bSYour Name 	return &((union ol_tx_desc_list_elem_t *)
104*5113495bSYour Name 		(td_base[tx_desc_id >> pdev->tx_desc.page_divider] +
105*5113495bSYour Name 		(pdev->tx_desc.desc_reserved_size *
106*5113495bSYour Name 		(tx_desc_id & pdev->tx_desc.offset_filter))))->tx_desc;
107*5113495bSYour Name }
108*5113495bSYour Name 
109*5113495bSYour Name /**
110*5113495bSYour Name  * @brief Use a tx descriptor ID to find the corresponding descriptor object
111*5113495bSYour Name  *    and add sanity check.
112*5113495bSYour Name  *
113*5113495bSYour Name  * @param pdev - the data physical device sending the data
114*5113495bSYour Name  * @param tx_desc_id - the ID of the descriptor in question
115*5113495bSYour Name  * @return the descriptor object that has the specified ID,
116*5113495bSYour Name  *    if failure, will return NULL.
117*5113495bSYour Name  */
118*5113495bSYour Name 
119*5113495bSYour Name #ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
120*5113495bSYour Name static inline struct ol_tx_desc_t *
ol_tx_desc_find_check(struct ol_txrx_pdev_t * pdev,u_int16_t tx_desc_id)121*5113495bSYour Name ol_tx_desc_find_check(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id)
122*5113495bSYour Name {
123*5113495bSYour Name 	struct ol_tx_desc_t *tx_desc;
124*5113495bSYour Name 
125*5113495bSYour Name 	if (tx_desc_id >= pdev->tx_desc.pool_size)
126*5113495bSYour Name 		return NULL;
127*5113495bSYour Name 
128*5113495bSYour Name 	tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
129*5113495bSYour Name 
130*5113495bSYour Name 	if (tx_desc->pkt_type == ol_tx_frm_freed)
131*5113495bSYour Name 		return NULL;
132*5113495bSYour Name 
133*5113495bSYour Name 	return tx_desc;
134*5113495bSYour Name }
135*5113495bSYour Name 
136*5113495bSYour Name #else
137*5113495bSYour Name 
138*5113495bSYour Name static inline struct ol_tx_desc_t *
ol_tx_desc_find_check(struct ol_txrx_pdev_t * pdev,u_int16_t tx_desc_id)139*5113495bSYour Name ol_tx_desc_find_check(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id)
140*5113495bSYour Name {
141*5113495bSYour Name 	struct ol_tx_desc_t *tx_desc;
142*5113495bSYour Name 
143*5113495bSYour Name 	if (tx_desc_id >= pdev->tx_desc.pool_size)
144*5113495bSYour Name 		return NULL;
145*5113495bSYour Name 
146*5113495bSYour Name 	tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
147*5113495bSYour Name 
148*5113495bSYour Name 	/* check against invalid tx_desc_id */
149*5113495bSYour Name 	if (ol_cfg_is_high_latency(pdev->ctrl_pdev) && !tx_desc->vdev)
150*5113495bSYour Name 		return NULL;
151*5113495bSYour Name 
152*5113495bSYour Name 	return tx_desc;
153*5113495bSYour Name }
154*5113495bSYour Name #endif
155*5113495bSYour Name 
156*5113495bSYour Name /**
157*5113495bSYour Name  * @brief Free a list of tx descriptors and the tx frames they refer to.
158*5113495bSYour Name  * @details
159*5113495bSYour Name  *  Free a batch of "standard" tx descriptors and their tx frames.
160*5113495bSYour Name  *  Free each tx descriptor, by returning it to the freelist.
161*5113495bSYour Name  *  Unmap each netbuf, and free the netbufs as a batch.
162*5113495bSYour Name  *  Irregular tx frames like TSO or management frames that require
163*5113495bSYour Name  *  special handling are processed by the ol_tx_desc_frame_free_nonstd
164*5113495bSYour Name  *  function rather than this function.
165*5113495bSYour Name  *
166*5113495bSYour Name  * @param pdev - the data physical device that sent the data
167*5113495bSYour Name  * @param tx_descs - a list of SW tx descriptors for the tx frames
168*5113495bSYour Name  * @param had_error - bool indication of whether the transmission failed.
169*5113495bSYour Name  *            This is provided to callback functions that get notified of
170*5113495bSYour Name  *            the tx frame completion.
171*5113495bSYour Name  */
172*5113495bSYour Name void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev,
173*5113495bSYour Name 				ol_tx_desc_list *tx_descs, int had_error);
174*5113495bSYour Name 
175*5113495bSYour Name /**
176*5113495bSYour Name  * @brief Free a non-standard tx frame and its tx descriptor.
177*5113495bSYour Name  * @details
178*5113495bSYour Name  *  Check the tx frame type (e.g. TSO vs. management) to determine what
179*5113495bSYour Name  *  special steps, if any, need to be performed prior to freeing the
180*5113495bSYour Name  *  tx frame and its tx descriptor.
181*5113495bSYour Name  *  This function can also be used to free single standard tx frames.
182*5113495bSYour Name  *  After performing any special steps based on tx frame type, free the
183*5113495bSYour Name  *  tx descriptor, i.e. return it to the freelist, and unmap and
184*5113495bSYour Name  *  free the netbuf referenced by the tx descriptor.
185*5113495bSYour Name  *
186*5113495bSYour Name  * @param pdev - the data physical device that sent the data
187*5113495bSYour Name  * @param tx_desc - the SW tx descriptor for the tx frame that was sent
188*5113495bSYour Name  * @param had_error - bool indication of whether the transmission failed.
189*5113495bSYour Name  *            This is provided to callback functions that get notified of
190*5113495bSYour Name  *            the tx frame completion.
191*5113495bSYour Name  */
192*5113495bSYour Name void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev,
193*5113495bSYour Name 				  struct ol_tx_desc_t *tx_desc, int had_error);
194*5113495bSYour Name 
195*5113495bSYour Name /*
196*5113495bSYour Name  * @brief Determine the ID of a tx descriptor.
197*5113495bSYour Name  *
198*5113495bSYour Name  * @param pdev - the physical device that is sending the data
199*5113495bSYour Name  * @param tx_desc - the descriptor whose ID is being determined
200*5113495bSYour Name  * @return numeric ID that uniquely identifies the tx descriptor
201*5113495bSYour Name  */
202*5113495bSYour Name static inline uint16_t
ol_tx_desc_id(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)203*5113495bSYour Name ol_tx_desc_id(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
204*5113495bSYour Name {
205*5113495bSYour Name 	TXRX_ASSERT2(tx_desc->id < pdev->tx_desc.pool_size);
206*5113495bSYour Name 	return tx_desc->id;
207*5113495bSYour Name }
208*5113495bSYour Name 
209*5113495bSYour Name /*
210*5113495bSYour Name  * @brief Retrieves the beacon headr for the vdev
211*5113495bSYour Name  * @param pdev - opaque pointe to scn
212*5113495bSYour Name  * @param vdevid - vdev id
213*5113495bSYour Name  * @return void pointer to the beacon header for the given vdev
214*5113495bSYour Name  */
215*5113495bSYour Name 
216*5113495bSYour Name void *ol_ath_get_bcn_header(struct cdp_cfg *cfg_pdev, A_UINT32 vdev_id);
217*5113495bSYour Name 
218*5113495bSYour Name /*
219*5113495bSYour Name  * @brief Free a tx descriptor, without freeing the matching frame.
220*5113495bSYour Name  * @details
221*5113495bSYour Name  *  This function is using during the function call that submits tx frames
222*5113495bSYour Name  *  into the txrx layer, for cases where a tx descriptor is successfully
223*5113495bSYour Name  *  allocated, but for other reasons the frame could not be accepted.
224*5113495bSYour Name  *
225*5113495bSYour Name  * @param pdev - the data physical device that is sending the data
226*5113495bSYour Name  * @param tx_desc - the descriptor being freed
227*5113495bSYour Name  */
228*5113495bSYour Name void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc);
229*5113495bSYour Name 
230*5113495bSYour Name #if defined(FEATURE_TSO)
231*5113495bSYour Name struct qdf_tso_seg_elem_t *ol_tso_alloc_segment(struct ol_txrx_pdev_t *pdev);
232*5113495bSYour Name 
233*5113495bSYour Name void ol_tso_free_segment(struct ol_txrx_pdev_t *pdev,
234*5113495bSYour Name 	 struct qdf_tso_seg_elem_t *tso_seg);
235*5113495bSYour Name struct qdf_tso_num_seg_elem_t *ol_tso_num_seg_alloc(
236*5113495bSYour Name 				struct ol_txrx_pdev_t *pdev);
237*5113495bSYour Name void ol_tso_num_seg_free(struct ol_txrx_pdev_t *pdev,
238*5113495bSYour Name 	 struct qdf_tso_num_seg_elem_t *tso_num_seg);
239*5113495bSYour Name void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev,
240*5113495bSYour Name 				struct ol_txrx_msdu_info_t *msdu_info,
241*5113495bSYour Name 				bool is_tso_seg_mapping_done);
242*5113495bSYour Name 
243*5113495bSYour Name #else
244*5113495bSYour Name #define ol_tso_alloc_segment(pdev) /*no-op*/
245*5113495bSYour Name #define ol_tso_free_segment(pdev, tso_seg) /*no-op*/
246*5113495bSYour Name #define ol_tso_num_seg_alloc(pdev) /*no-op*/
247*5113495bSYour Name #define ol_tso_num_seg_free(pdev, tso_num_seg) /*no-op*/
248*5113495bSYour Name /*no-op*/
249*5113495bSYour Name #define ol_free_remaining_tso_segs(vdev, msdu_info, is_tso_seg_mapping_done)
250*5113495bSYour Name #endif
251*5113495bSYour Name 
252*5113495bSYour Name /**
253*5113495bSYour Name  * ol_tx_get_desc_global_pool() - get descriptor from global pool
254*5113495bSYour Name  * @pdev: pdev handler
255*5113495bSYour Name  *
256*5113495bSYour Name  * Caller needs to take lock and do sanity checks.
257*5113495bSYour Name  *
258*5113495bSYour Name  * Return: tx descriptor
259*5113495bSYour Name  */
260*5113495bSYour Name static inline
ol_tx_get_desc_global_pool(struct ol_txrx_pdev_t * pdev)261*5113495bSYour Name struct ol_tx_desc_t *ol_tx_get_desc_global_pool(struct ol_txrx_pdev_t *pdev)
262*5113495bSYour Name {
263*5113495bSYour Name 	struct ol_tx_desc_t *tx_desc = &pdev->tx_desc.freelist->tx_desc;
264*5113495bSYour Name 
265*5113495bSYour Name 	pdev->tx_desc.freelist = pdev->tx_desc.freelist->next;
266*5113495bSYour Name 	pdev->tx_desc.num_free--;
267*5113495bSYour Name 	return tx_desc;
268*5113495bSYour Name }
269*5113495bSYour Name 
270*5113495bSYour Name /**
271*5113495bSYour Name  * ol_tx_put_desc_global_pool() - put descriptor to global pool freelist
272*5113495bSYour Name  * @pdev: pdev handle
273*5113495bSYour Name  * @tx_desc: tx descriptor
274*5113495bSYour Name  *
275*5113495bSYour Name  * Caller needs to take lock and do sanity checks.
276*5113495bSYour Name  *
277*5113495bSYour Name  * Return: none
278*5113495bSYour Name  */
279*5113495bSYour Name static inline
ol_tx_put_desc_global_pool(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)280*5113495bSYour Name void ol_tx_put_desc_global_pool(struct ol_txrx_pdev_t *pdev,
281*5113495bSYour Name 			struct ol_tx_desc_t *tx_desc)
282*5113495bSYour Name {
283*5113495bSYour Name 	((union ol_tx_desc_list_elem_t *)tx_desc)->next =
284*5113495bSYour Name 					pdev->tx_desc.freelist;
285*5113495bSYour Name 	pdev->tx_desc.freelist =
286*5113495bSYour Name 			 (union ol_tx_desc_list_elem_t *)tx_desc;
287*5113495bSYour Name 	pdev->tx_desc.num_free++;
288*5113495bSYour Name }
289*5113495bSYour Name 
290*5113495bSYour Name 
291*5113495bSYour Name #ifdef QCA_LL_TX_FLOW_CONTROL_V2
292*5113495bSYour Name 
293*5113495bSYour Name #ifdef QCA_LL_TX_FLOW_CONTROL_RESIZE
294*5113495bSYour Name int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void);
295*5113495bSYour Name #else
296*5113495bSYour Name static inline
ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void)297*5113495bSYour Name int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void)
298*5113495bSYour Name {
299*5113495bSYour Name 	return 0;
300*5113495bSYour Name }
301*5113495bSYour Name #endif
302*5113495bSYour Name 
303*5113495bSYour Name int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool);
304*5113495bSYour Name /**
305*5113495bSYour Name  * ol_tx_get_desc_flow_pool() - get descriptor from flow pool
306*5113495bSYour Name  * @pool: flow pool
307*5113495bSYour Name  *
308*5113495bSYour Name  * Caller needs to take lock and do sanity checks.
309*5113495bSYour Name  *
310*5113495bSYour Name  * Return: tx descriptor
311*5113495bSYour Name  */
312*5113495bSYour Name static inline
ol_tx_get_desc_flow_pool(struct ol_tx_flow_pool_t * pool)313*5113495bSYour Name struct ol_tx_desc_t *ol_tx_get_desc_flow_pool(struct ol_tx_flow_pool_t *pool)
314*5113495bSYour Name {
315*5113495bSYour Name 	struct ol_tx_desc_t *tx_desc = &pool->freelist->tx_desc;
316*5113495bSYour Name 
317*5113495bSYour Name 	pool->freelist = pool->freelist->next;
318*5113495bSYour Name 	pool->avail_desc--;
319*5113495bSYour Name 	return tx_desc;
320*5113495bSYour Name }
321*5113495bSYour Name 
322*5113495bSYour Name /**
323*5113495bSYour Name  * ol_tx_put_desc_flow_pool() - put descriptor to flow pool freelist
324*5113495bSYour Name  * @pool: flow pool
325*5113495bSYour Name  * @tx_desc: tx descriptor
326*5113495bSYour Name  *
327*5113495bSYour Name  * Caller needs to take lock and do sanity checks.
328*5113495bSYour Name  *
329*5113495bSYour Name  * Return: none
330*5113495bSYour Name  */
331*5113495bSYour Name static inline
ol_tx_put_desc_flow_pool(struct ol_tx_flow_pool_t * pool,struct ol_tx_desc_t * tx_desc)332*5113495bSYour Name void ol_tx_put_desc_flow_pool(struct ol_tx_flow_pool_t *pool,
333*5113495bSYour Name 			struct ol_tx_desc_t *tx_desc)
334*5113495bSYour Name {
335*5113495bSYour Name 	tx_desc->pool = pool;
336*5113495bSYour Name 	((union ol_tx_desc_list_elem_t *)tx_desc)->next = pool->freelist;
337*5113495bSYour Name 	pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc;
338*5113495bSYour Name 	pool->avail_desc++;
339*5113495bSYour Name }
340*5113495bSYour Name 
341*5113495bSYour Name #else
ol_tx_free_invalid_flow_pool(void * pool)342*5113495bSYour Name static inline int ol_tx_free_invalid_flow_pool(void *pool)
343*5113495bSYour Name {
344*5113495bSYour Name 	return 0;
345*5113495bSYour Name }
346*5113495bSYour Name #endif
347*5113495bSYour Name 
348*5113495bSYour Name #ifdef DESC_DUP_DETECT_DEBUG
349*5113495bSYour Name /**
350*5113495bSYour Name  * ol_tx_desc_dup_detect_init() - initialize descriptor duplication logic
351*5113495bSYour Name  * @pdev: pdev handle
352*5113495bSYour Name  * @pool_size: global pool size
353*5113495bSYour Name  *
354*5113495bSYour Name  * Return: none
355*5113495bSYour Name  */
356*5113495bSYour Name static inline
ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t * pdev,uint16_t pool_size)357*5113495bSYour Name void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t pool_size)
358*5113495bSYour Name {
359*5113495bSYour Name 	uint16_t size = (pool_size >> DIV_BY_8) +
360*5113495bSYour Name 		sizeof(*pdev->tx_desc.free_list_bitmap);
361*5113495bSYour Name 	pdev->tx_desc.free_list_bitmap = qdf_mem_malloc(size);
362*5113495bSYour Name }
363*5113495bSYour Name 
364*5113495bSYour Name /**
365*5113495bSYour Name  * ol_tx_desc_dup_detect_deinit() - deinit descriptor duplication logic
366*5113495bSYour Name  * @pdev: pdev handle
367*5113495bSYour Name  *
368*5113495bSYour Name  * Return: none
369*5113495bSYour Name  */
370*5113495bSYour Name static inline
ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t * pdev)371*5113495bSYour Name void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
372*5113495bSYour Name {
373*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
374*5113495bSYour Name 		  "%s: pool_size %d num_free %d\n", __func__,
375*5113495bSYour Name 		pdev->tx_desc.pool_size, pdev->tx_desc.num_free);
376*5113495bSYour Name 	if (pdev->tx_desc.free_list_bitmap)
377*5113495bSYour Name 		qdf_mem_free(pdev->tx_desc.free_list_bitmap);
378*5113495bSYour Name }
379*5113495bSYour Name 
380*5113495bSYour Name /**
381*5113495bSYour Name  * ol_tx_desc_dup_detect_set() - set bit for msdu_id
382*5113495bSYour Name  * @pdev: pdev handle
383*5113495bSYour Name  * @tx_desc: tx descriptor
384*5113495bSYour Name  *
385*5113495bSYour Name  * Return: none
386*5113495bSYour Name  */
387*5113495bSYour Name static inline
ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)388*5113495bSYour Name void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
389*5113495bSYour Name 				struct ol_tx_desc_t *tx_desc)
390*5113495bSYour Name {
391*5113495bSYour Name 	uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
392*5113495bSYour Name 	bool test;
393*5113495bSYour Name 
394*5113495bSYour Name 	if (!pdev->tx_desc.free_list_bitmap)
395*5113495bSYour Name 		return;
396*5113495bSYour Name 
397*5113495bSYour Name 	if (qdf_unlikely(msdu_id > pdev->tx_desc.pool_size)) {
398*5113495bSYour Name 		qdf_print("msdu_id %d > pool_size %d",
399*5113495bSYour Name 			  msdu_id, pdev->tx_desc.pool_size);
400*5113495bSYour Name 		QDF_BUG(0);
401*5113495bSYour Name 	}
402*5113495bSYour Name 
403*5113495bSYour Name 	test = test_and_set_bit(msdu_id, pdev->tx_desc.free_list_bitmap);
404*5113495bSYour Name 	if (qdf_unlikely(test)) {
405*5113495bSYour Name 		uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
406*5113495bSYour Name 			((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
407*5113495bSYour Name 		qdf_print("duplicate msdu_id %d detected!!", msdu_id);
408*5113495bSYour Name 		qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
409*5113495bSYour Name 		(void *)pdev->tx_desc.free_list_bitmap, size);
410*5113495bSYour Name 		QDF_BUG(0);
411*5113495bSYour Name 	}
412*5113495bSYour Name }
413*5113495bSYour Name 
414*5113495bSYour Name /**
415*5113495bSYour Name  * ol_tx_desc_dup_detect_reset() - reset bit for msdu_id
416*5113495bSYour Name  * @pdev: pdev handle
417*5113495bSYour Name  * @tx_desc: tx descriptor
418*5113495bSYour Name  *
419*5113495bSYour Name  * Return: none
420*5113495bSYour Name  */
421*5113495bSYour Name static inline
ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)422*5113495bSYour Name void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
423*5113495bSYour Name 				 struct ol_tx_desc_t *tx_desc)
424*5113495bSYour Name {
425*5113495bSYour Name 	uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
426*5113495bSYour Name 	bool test;
427*5113495bSYour Name 
428*5113495bSYour Name 	if (!pdev->tx_desc.free_list_bitmap)
429*5113495bSYour Name 		return;
430*5113495bSYour Name 
431*5113495bSYour Name 	if (qdf_unlikely(msdu_id > pdev->tx_desc.pool_size)) {
432*5113495bSYour Name 		qdf_print("msdu_id %d > pool_size %d",
433*5113495bSYour Name 			  msdu_id, pdev->tx_desc.pool_size);
434*5113495bSYour Name 		QDF_BUG(0);
435*5113495bSYour Name 	}
436*5113495bSYour Name 
437*5113495bSYour Name 	test = !test_and_clear_bit(msdu_id, pdev->tx_desc.free_list_bitmap);
438*5113495bSYour Name 	if (qdf_unlikely(test)) {
439*5113495bSYour Name 		uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
440*5113495bSYour Name 			((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
441*5113495bSYour Name 		qdf_print("duplicate free msg received for msdu_id %d!!\n",
442*5113495bSYour Name 								 msdu_id);
443*5113495bSYour Name 		qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
444*5113495bSYour Name 		(void *)pdev->tx_desc.free_list_bitmap, size);
445*5113495bSYour Name 		QDF_BUG(0);
446*5113495bSYour Name 	}
447*5113495bSYour Name }
448*5113495bSYour Name #else
449*5113495bSYour Name static inline
ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t * pdev,uint16_t size)450*5113495bSYour Name void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t size)
451*5113495bSYour Name {
452*5113495bSYour Name }
453*5113495bSYour Name 
454*5113495bSYour Name static inline
ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t * pdev)455*5113495bSYour Name void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
456*5113495bSYour Name {
457*5113495bSYour Name }
458*5113495bSYour Name 
459*5113495bSYour Name static inline
ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)460*5113495bSYour Name void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
461*5113495bSYour Name 				struct ol_tx_desc_t *tx_desc)
462*5113495bSYour Name {
463*5113495bSYour Name }
464*5113495bSYour Name 
465*5113495bSYour Name static inline
ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t * pdev,struct ol_tx_desc_t * tx_desc)466*5113495bSYour Name void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
467*5113495bSYour Name 				 struct ol_tx_desc_t *tx_desc)
468*5113495bSYour Name {
469*5113495bSYour Name }
470*5113495bSYour Name #endif
471*5113495bSYour Name 
472*5113495bSYour Name enum extension_header_type
473*5113495bSYour Name ol_tx_get_ext_header_type(struct ol_txrx_vdev_t *vdev,
474*5113495bSYour Name 	qdf_nbuf_t netbuf);
475*5113495bSYour Name enum extension_header_type
476*5113495bSYour Name ol_tx_get_wisa_ext_type(qdf_nbuf_t netbuf);
477*5113495bSYour Name 
478*5113495bSYour Name 
479*5113495bSYour Name #endif /* _OL_TX_DESC__H_ */
480