xref: /wlan-dirver/qcacld-3.0/core/dp/txrx/ol_tx.h (revision 63d7e2a202b3cd37d6c1c20a39582b297a267b6b)
1 /*
2  * Copyright (c) 2011-2020 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 /**
20  * @file ol_tx.h
21  * @brief Internal definitions for the high-level tx module.
22  */
23 #ifndef _OL_TX__H_
24 #define _OL_TX__H_
25 
26 #include <qdf_nbuf.h>           /* qdf_nbuf_t */
27 #include <qdf_lock.h>
28 #include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
29 #include <cdp_txrx_misc.h>      /* ol_tx_spec */
30 #include <cdp_txrx_handle.h>
31 #include <ol_txrx_types.h>      /* ol_tx_desc_t, ol_txrx_msdu_info_t */
32 #include <ol_txrx.h>
33 #include <hif.h>
34 
35 #ifdef IPA_OFFLOAD
36 /**
37  * ol_tx_send_ipa_data_frame() - send IPA data frame
38  * @soc_hdl: datapath soc handle
39  * @vdev: virtual interface id
40  * @skb: skb
41  *
42  * Return: skb/ NULL is for success
43  */
44 qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
45 				     qdf_nbuf_t skb);
46 #endif
47 
48 #ifdef CONFIG_LL_DP_SUPPORT
49 struct ol_tx_desc_t *
50 ol_tx_prepare_ll(ol_txrx_vdev_handle vdev,
51 		 qdf_nbuf_t msdu,
52 		 struct ol_txrx_msdu_info_t *msdu_info);
53 #endif
54 
55 qdf_nbuf_t ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
56 #ifdef WLAN_FEATURE_FASTPATH
57 qdf_nbuf_t ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
58 
59 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
60 				     struct ol_txrx_pdev_t *pdev);
61 #else
62 static inline
63 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
64 				     struct ol_txrx_pdev_t *pdev)
65 { }
66 
67 qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
68 #endif
69 
70 qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
71 
72 #ifdef CONFIG_HL_SUPPORT
73 #define OL_TX_SEND ol_tx_hl
74 #else
75 #define OL_TX_SEND OL_TX_LL
76 #endif
77 
78 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
79 #define OL_TX_LL ol_tx_ll_queue
80 #else
81 #define OL_TX_LL ol_tx_ll_wrapper
82 #endif
83 
84 #ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
85 void ol_tx_hl_vdev_bundle_timer(void *context);
86 
87 void ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t *vdev);
88 qdf_nbuf_t
89 ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t *pdev);
90 #else
91 static inline
92 void ol_tx_hl_vdev_bundle_timer(void *context)
93 {
94 }
95 
96 static inline
97 void ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t *vdev)
98 {
99 }
100 
101 static inline
102 qdf_nbuf_t
103 ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t *pdev)
104 {
105 	return NULL;
106 }
107 #endif
108 
109 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
110 void ol_tx_vdev_ll_pause_queue_send(void *context);
111 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev);
112 #else
113 static inline void ol_tx_vdev_ll_pause_queue_send(void *context)
114 {
115 }
116 static inline
117 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev)
118 {
119 }
120 #endif
121 
122 /**
123  * ol_tx_comp_hw_to_qdf_status(): map ol hw to qdf status
124  * @status: hw status
125  *
126  * Return: qdf tx rx status
127  */
128 static inline enum qdf_dp_tx_rx_status
129 ol_tx_comp_hw_to_qdf_status(uint16_t status)
130 {
131 	switch (status) {
132 	case HTT_TX_COMPL_IND_STAT_OK:
133 		return QDF_TX_RX_STATUS_OK;
134 	case HTT_TX_COMPL_IND_STAT_DISCARD:
135 	case HTT_TX_COMPL_IND_STAT_DROP:
136 		return QDF_TX_RX_STATUS_FW_DISCARD;
137 	case HTT_TX_COMPL_IND_STAT_NO_ACK:
138 		return QDF_TX_RX_STATUS_NO_ACK;
139 	default:
140 		return QDF_TX_RX_STATUS_DEFAULT;
141 	}
142 }
143 
144 static inline
145 int ol_txrx_tx_is_raw(enum ol_tx_spec tx_spec)
146 {
147 	return	tx_spec &
148 		(OL_TX_SPEC_RAW | OL_TX_SPEC_NO_AGGR | OL_TX_SPEC_NO_ENCRYPT);
149 }
150 
151 static inline
152 uint8_t ol_txrx_tx_raw_subtype(enum ol_tx_spec tx_spec)
153 {
154 	uint8_t sub_type = 0x1; /* 802.11 MAC header present */
155 
156 	if (tx_spec & OL_TX_SPEC_NO_AGGR)
157 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S;
158 	if (tx_spec & OL_TX_SPEC_NO_ENCRYPT)
159 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
160 	if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT)
161 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
162 	return sub_type;
163 }
164 
165 /**
166  * ol_tx_hl() - transmit tx frames for a HL system.
167  * @vdev: the virtual device transmit the data
168  * @msdu_list: the tx frames to send
169  *
170  * Return: NULL if all MSDUs are accepted
171  */
172 qdf_nbuf_t
173 ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
174 
175 /**
176  * ol_tx_non_std() - Allow the control-path SW to send data frames
177  * @soc_hdl: Datapath soc handle
178  * @vdev_id: id of vdev
179  * @tx_spec: what non-standard handling to apply to the tx data frames
180  * @msdu_list: NULL-terminated list of tx MSDUs
181  *
182  * Generally, all tx data frames come from the OS shim into the txrx layer.
183  * However, there are rare cases such as TDLS messaging where the UMAC
184  * control-path SW creates tx data frames.
185  *  This UMAC SW can call this function to provide the tx data frames to
186  *  the txrx layer.
187  *  The UMAC SW can request a callback for these data frames after their
188  *  transmission completes, by using the ol_txrx_data_tx_cb_set function
189  *  to register a tx completion callback, and by specifying
190  *  ol_tx_spec_no_free as the tx_spec arg when giving the frames to
191  *  ol_tx_non_std.
192  *  The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11),
193  *  as specified by ol_cfg_frame_type().
194  *
195  *  Return: null - success, skb - failure
196  */
197 #ifdef CONFIG_HL_SUPPORT
198 qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev,
199 			    enum ol_tx_spec tx_spec,
200 			    qdf_nbuf_t msdu_list);
201 
202 static inline qdf_nbuf_t
203 ol_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
204 	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
205 {
206 	struct ol_txrx_vdev_t *vdev;
207 
208 	vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
209 
210 	if (!vdev)
211 		return msdu_list;
212 	else
213 		return ol_tx_non_std_hl(vdev, tx_spec, msdu_list);
214 }
215 #else
216 qdf_nbuf_t ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev,
217 			    enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list);
218 
219 static inline qdf_nbuf_t
220 ol_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
221 	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
222 {
223 	struct ol_txrx_vdev_t *vdev;
224 
225 	vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
226 
227 	if (!vdev)
228 		return msdu_list;
229 	else
230 		return ol_tx_non_std_ll(vdev, tx_spec, msdu_list);
231 }
232 #endif
233 
234 void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err);
235 
236 /**
237  * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery
238  *	notifications for management frames.
239  * @soc: Datapath soc handle
240  * @pdev_id: Physical device instance id
241  * @type: the type of mgmt frame the callback is used for
242  * @download_cb: the callback for notification of delivery to the target
243  * @ota_ack_cb: the callback for notification of delivery to the peer
244  * @ctxt: context to use with the callback
245  *
246  * When the txrx SW receives notifications from the target that a tx frame
247  * has been delivered to its recipient, it will check if the tx frame
248  * is a management frame.  If so, the txrx SW will check the management
249  * frame type specified when the frame was submitted for transmission.
250  * If there is a callback function registered for the type of management
251  * frame in question, the txrx code will invoke the callback to inform
252  * the management + control SW that the mgmt frame was delivered.
253  * This function is used by the control SW to store a callback pointer
254  * for a given type of management frame.
255  */
256 QDF_STATUS
257 ol_txrx_mgmt_tx_cb_set(struct cdp_soc_t *soc, uint8_t pdev_id, uint8_t type,
258 		       ol_txrx_mgmt_tx_cb download_cb,
259 		       ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt);
260 
261 /**
262  * ol_txrx_mgmt_send_ext() - Transmit a management frame
263  * @soc: Datapath soc handle
264  * @vdev_id: virtual interface id
265  * @tx_mgmt_frm: management frame to transmit
266  * @type: the type of management frame (determines what callback to use)
267  * @use_6mbps: specify whether management frame to transmit should
268  *	use 6 Mbps rather than 1 Mbps min rate(for 5GHz band or P2P)
269  * @chanfreq: channel to transmit the frame on
270  *
271  * Send the specified management frame from the specified virtual device.
272  * The type is used for determining whether to invoke a callback to inform
273  * the sender that the tx mgmt frame was delivered, and if so, which
274  * callback to use.
275  *
276  * Return: 0 - the frame is accepted for transmission
277  *         1 - the frame was not accepted
278  */
279 int
280 ol_txrx_mgmt_send_ext(struct cdp_soc_t *soc, uint8_t vdev_id,
281 		      qdf_nbuf_t tx_mgmt_frm,
282 		      uint8_t type, uint8_t use_6mbps, uint16_t chanfreq);
283 
284 qdf_nbuf_t
285 ol_tx_reinject(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu, uint16_t peer_id);
286 
287 #if defined(FEATURE_TSO)
288 void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
289 void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
290 void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
291 void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
292 uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev);
293 uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
294 			  qdf_nbuf_t msdu,
295 			  struct ol_txrx_msdu_info_t *msdu_info);
296 void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
297 			    struct qdf_tso_info_t  *tso_info, qdf_nbuf_t msdu,
298 			    uint32_t tso_msdu_idx);
299 #else
300 static inline uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev)
301 {
302 	return 0;
303 }
304 
305 static inline void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev,
306 	uint32_t num_seg)
307 {
308 }
309 
310 static inline void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
311 {
312 }
313 
314 static inline void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev,
315 	uint32_t num_seg)
316 {
317 }
318 
319 static inline void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
320 {
321 }
322 
323 static inline uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
324 					qdf_nbuf_t msdu,
325 					struct ol_txrx_msdu_info_t *msdu_info)
326 {
327 	return 0;
328 }
329 
330 static inline void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
331 					  struct qdf_tso_info_t  *tso_info,
332 					  qdf_nbuf_t msdu,
333 					  uint32_t tso_msdu_idx)
334 {
335 }
336 #endif
337 
338 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
339 bool ol_tx_desc_is_high_prio(qdf_nbuf_t msdu);
340 #endif
341 
342 #if defined(HELIUMPLUS)
343 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc);
344 #else
345 static inline
346 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc)
347 {
348 }
349 #endif
350 
351 #endif /* _OL_TX__H_ */
352