xref: /wlan-dirver/qcacld-3.0/core/dp/txrx/ol_tx.h (revision eff16d956b6c25bc860fac91ea57d737c47dd7a7)
1 /*
2  * Copyright (c) 2011-2018 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 <hif.h>
33 
34 #ifdef IPA_OFFLOAD
35 /**
36  * ol_tx_send_ipa_data_frame() - send IPA data frame
37  * @vdev: vdev
38  * @skb: skb
39  *
40  * Return: skb/ NULL is for success
41  */
42 qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb);
43 #endif
44 
45 #ifdef CONFIG_LL_DP_SUPPORT
46 struct ol_tx_desc_t *
47 ol_tx_prepare_ll(ol_txrx_vdev_handle vdev,
48 		 qdf_nbuf_t msdu,
49 		 struct ol_txrx_msdu_info_t *msdu_info);
50 #endif
51 
52 qdf_nbuf_t ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
53 #ifdef WLAN_FEATURE_FASTPATH
54 qdf_nbuf_t ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
55 
56 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
57 				     struct ol_txrx_pdev_t *pdev);
58 #else
59 static inline
60 void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
61 				     struct ol_txrx_pdev_t *pdev)
62 { }
63 
64 qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
65 #endif
66 
67 qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
68 
69 #ifdef CONFIG_HL_SUPPORT
70 #define OL_TX_SEND ol_tx_hl
71 #else
72 #define OL_TX_SEND OL_TX_LL
73 #endif
74 
75 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
76 #define OL_TX_LL ol_tx_ll_queue
77 #else
78 #define OL_TX_LL ol_tx_ll_wrapper
79 #endif
80 
81 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
82 void ol_tx_vdev_ll_pause_queue_send(void *context);
83 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev);
84 #else
85 static inline void ol_tx_vdev_ll_pause_queue_send(void *context)
86 {
87 }
88 static inline
89 void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev)
90 {
91 }
92 #endif
93 
94 static inline
95 int ol_txrx_tx_is_raw(enum ol_tx_spec tx_spec)
96 {
97 	return	tx_spec &
98 		(OL_TX_SPEC_RAW | OL_TX_SPEC_NO_AGGR | OL_TX_SPEC_NO_ENCRYPT);
99 }
100 
101 static inline
102 uint8_t ol_txrx_tx_raw_subtype(enum ol_tx_spec tx_spec)
103 {
104 	uint8_t sub_type = 0x1; /* 802.11 MAC header present */
105 
106 	if (tx_spec & OL_TX_SPEC_NO_AGGR)
107 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S;
108 	if (tx_spec & OL_TX_SPEC_NO_ENCRYPT)
109 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
110 	if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT)
111 		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
112 	return sub_type;
113 }
114 
115 /**
116  * ol_tx_hl() - transmit tx frames for a HL system.
117  * @vdev: the virtual device transmit the data
118  * @msdu_list: the tx frames to send
119  *
120  * Return: NULL if all MSDUs are accepted
121  */
122 qdf_nbuf_t
123 ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
124 
125 /**
126  * ol_tx_non_std() - Allow the control-path SW to send data frames
127  * @data_vdev: which vdev should transmit the tx data frames
128  * @tx_spec: what non-standard handling to apply to the tx data frames
129  * @msdu_list: NULL-terminated list of tx MSDUs
130  *
131  * Generally, all tx data frames come from the OS shim into the txrx layer.
132  * However, there are rare cases such as TDLS messaging where the UMAC
133  * control-path SW creates tx data frames.
134  *  This UMAC SW can call this function to provide the tx data frames to
135  *  the txrx layer.
136  *  The UMAC SW can request a callback for these data frames after their
137  *  transmission completes, by using the ol_txrx_data_tx_cb_set function
138  *  to register a tx completion callback, and by specifying
139  *  ol_tx_spec_no_free as the tx_spec arg when giving the frames to
140  *  ol_tx_non_std.
141  *  The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11),
142  *  as specified by ol_cfg_frame_type().
143  *
144  *  Return: null - success, skb - failure
145  */
146 #ifdef CONFIG_HL_SUPPORT
147 qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev,
148 			    enum ol_tx_spec tx_spec,
149 			    qdf_nbuf_t msdu_list);
150 
151 static inline qdf_nbuf_t
152 ol_tx_non_std(struct cdp_vdev *pvdev,
153 	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
154 {
155 	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
156 
157 	return ol_tx_non_std_hl(vdev, tx_spec, msdu_list);
158 }
159 #else
160 qdf_nbuf_t ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev,
161 			    enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list);
162 
163 static inline qdf_nbuf_t
164 ol_tx_non_std(struct cdp_vdev *pvdev,
165 	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
166 {
167 	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
168 
169 	return ol_tx_non_std_ll(vdev, tx_spec, msdu_list);
170 }
171 #endif
172 
173 void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err);
174 
175 /**
176  * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery
177  *	notifications for management frames.
178  * @ppdev: the data physical device object
179  * @type: the type of mgmt frame the callback is used for
180  * @download_cb: the callback for notification of delivery to the target
181  * @ota_ack_cb: the callback for notification of delivery to the peer
182  * @ctxt: context to use with the callback
183  *
184  * When the txrx SW receives notifications from the target that a tx frame
185  * has been delivered to its recipient, it will check if the tx frame
186  * is a management frame.  If so, the txrx SW will check the management
187  * frame type specified when the frame was submitted for transmission.
188  * If there is a callback function registered for the type of management
189  * frame in question, the txrx code will invoke the callback to inform
190  * the management + control SW that the mgmt frame was delivered.
191  * This function is used by the control SW to store a callback pointer
192  * for a given type of management frame.
193  */
194 void
195 ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type,
196 		       ol_txrx_mgmt_tx_cb download_cb,
197 		       ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt);
198 
199 /**
200  * ol_txrx_mgmt_send_ext() - Transmit a management frame
201  * @pvdev: virtual device transmitting the frame
202  * @tx_mgmt_frm: management frame to transmit
203  * @type: the type of management frame (determines what callback to use)
204  * @use_6mbps: specify whether management frame to transmit should
205  *	use 6 Mbps rather than 1 Mbps min rate(for 5GHz band or P2P)
206  * @chanfreq: channel to transmit the frame on
207  *
208  * Send the specified management frame from the specified virtual device.
209  * The type is used for determining whether to invoke a callback to inform
210  * the sender that the tx mgmt frame was delivered, and if so, which
211  * callback to use.
212  *
213  * Return: 0 - the frame is accepted for transmission
214  *         1 - the frame was not accepted
215  */
216 int
217 ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev,
218 		      qdf_nbuf_t tx_mgmt_frm,
219 		      uint8_t type, uint8_t use_6mbps, uint16_t chanfreq);
220 
221 qdf_nbuf_t
222 ol_tx_reinject(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu, uint16_t peer_id);
223 
224 #if defined(FEATURE_TSO)
225 void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
226 void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
227 void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
228 void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
229 uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev);
230 uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
231 			  qdf_nbuf_t msdu,
232 			  struct ol_txrx_msdu_info_t *msdu_info);
233 void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
234 			    struct qdf_tso_info_t  *tso_info, qdf_nbuf_t msdu,
235 			    uint32_t tso_msdu_idx);
236 #else
237 static inline uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev)
238 {
239 	return 0;
240 }
241 
242 static inline void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev,
243 	uint32_t num_seg)
244 {
245 }
246 
247 static inline void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
248 {
249 }
250 
251 static inline void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev,
252 	uint32_t num_seg)
253 {
254 }
255 
256 static inline void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
257 {
258 }
259 
260 static inline uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
261 					qdf_nbuf_t msdu,
262 					struct ol_txrx_msdu_info_t *msdu_info)
263 {
264 	return 0;
265 }
266 
267 static inline void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
268 					  struct qdf_tso_info_t  *tso_info,
269 					  qdf_nbuf_t msdu,
270 					  uint32_t tso_msdu_idx)
271 {
272 }
273 #endif
274 
275 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
276 bool ol_tx_desc_is_high_prio(qdf_nbuf_t msdu);
277 #endif
278 
279 #if defined(HELIUMPLUS)
280 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc);
281 #else
282 static inline
283 void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc)
284 {
285 }
286 #endif
287 
288 #endif /* _OL_TX__H_ */
289