xref: /wlan-driver/qcacld-3.0/core/dp/ol/inc/ol_htt_tx_api.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * @file ol_htt_tx_api.h
22  * @brief Specify the tx HTT API functions called by the host data SW.
23  * @details
24  *  This file declares the HTT API functions that are specifically
25  *  related to transmit processing.
26  *  In particular, the methods of the abstract HTT tx descriptor are
27  *  specified.
28  */
29 #ifndef _OL_HTT_TX_API__H_
30 #define _OL_HTT_TX_API__H_
31 
32 /* #include <osapi_linux.h>    / * uint16_t, etc. * / */
33 #include <osdep.h>              /* uint16_t, etc. */
34 #include <qdf_nbuf.h>           /* qdf_nbuf_t */
35 #include <ol_cfg.h>             /* wlan_frm_fmt */
36 
37 #include <htt.h>                /* needed by inline functions */
38 #include <qdf_net_types.h>
39 #include <ol_htt_api.h>         /* htt_pdev_handle */
40 #include <htt_types.h>
41 #include <qdf_trace.h>
42 #include <cds_api.h>
43 
44 #define HTT_INVALID_CHANNEL -1
45 
46 /* Remove these macros when they get added to htt.h. */
47 #ifndef HTT_TX_DESC_EXTENSION_GET
48 #define HTT_TX_DESC_EXTENSION_OFFSET_DWORD 0
49 #define HTT_TX_DESC_EXTENSION_M        0x10000000
50 #define HTT_TX_DESC_EXTENSION_S        28
51 
52 #define HTT_TX_DESC_EXTENSION_GET(_var) \
53 	(((_var) & HTT_TX_DESC_EXTENSION_M) >> HTT_TX_DESC_EXTENSION_S)
54 #define HTT_TX_DESC_EXTENSION_SET(_var, _val)				\
55 	do {								\
56 		HTT_CHECK_SET_VAL(HTT_TX_DESC_EXTENSION, _val);		\
57 		((_var) |= ((_val) << HTT_TX_DESC_EXTENSION_S));	\
58 	} while (0)
59 #endif
60 
61 /*================ meta-info about tx MSDUs =================================*/
62 
63 /*
64  * For simplicity, use the IEEE 802.11 frame type values.
65  */
66 enum htt_frm_type {
67 	htt_frm_type_mgmt = 0,
68 	htt_frm_type_ctrl = 1,
69 	htt_frm_type_data = 2
70 };
71 
72 /*
73  * For simplicity, use the IEEE 802.11 frame sub-type values.
74  */
75 enum htt_frm_subtype {
76 	htt_frm_subtype_mgmt_assoc_req = 0,
77 	htt_frm_subtype_mgmt_assoc_resp = 1,
78 	htt_frm_subtype_mgmt_reassoc_req = 2,
79 	htt_frm_subtype_mgmt_reassoc_resp = 3,
80 	htt_frm_subtype_mgmt_probe_req = 4,
81 	htt_frm_subtype_mgmt_probe_resp = 5,
82 	htt_frm_subtype_mgmt_timing_adv = 6,
83 	htt_frm_subtype_mgmt_beacon = 8,
84 	htt_frm_subtype_mgmt_atim = 9,
85 	htt_frm_subtype_mgmt_disassoc = 10,
86 	htt_frm_subtype_mgmt_auth = 11,
87 	htt_frm_subtype_mgmt_deauth = 12,
88 	htt_frm_subtype_mgmt_action = 13,
89 	htt_frm_subtype_mgmt_action_no_ack = 14,
90 
91 	htt_frm_subtype_data_data = 0,
92 	htt_frm_subtype_data_data_cf_ack = 1,
93 	htt_frm_subtype_data_data_cf_poll = 2,
94 	htt_frm_subtype_data_data_cf_ack_cf_poll = 3,
95 	htt_frm_subtype_data_null = 4,
96 	htt_frm_subtype_data_cf_ack = 5,
97 	htt_frm_subtype_data_cf_poll = 6,
98 	htt_frm_subtype_data_cf_ack_cf_poll = 7,
99 	htt_frm_subtype_data_QoS_data = 8,
100 	htt_frm_subtype_data_QoS_data_cf_ack = 9,
101 	htt_frm_subtype_data_QoS_data_cf_poll = 10,
102 	htt_frm_subtype_data_QoS_data_cf_ack_cf_poll = 11,
103 	htt_frm_subtype_data_QoS_null = 12,
104 	htt_frm_subtype_data_QoS_cf_poll = 14,
105 	htt_frm_subtype_data_QoS_cf_ack_cf_poll = 15,
106 };
107 
108 enum htt_ofdm_datarate {		/* Value    MBPS    Modulation  Coding*/
109 	htt_ofdm_datarate_6_mbps = 0,	/* 0        6       BPSK        1/2   */
110 	htt_ofdm_datarate_9_mbps = 1,	/* 1        9       BPSK        3/4   */
111 	htt_ofdm_datarate_12_mbps = 2,	/* 2        12      QPSK        1/2   */
112 	htt_ofdm_datarate_18_mbps = 3,	/* 3        18      QPSK        3/4   */
113 	htt_ofdm_datarate_24_mbps = 4,	/* 4        24      16-QAM      1/2   */
114 	htt_ofdm_datarate_36_mbps = 5,	/* 5        36      16-QAM      3/4   */
115 	htt_ofdm_datarate_48_mbps = 6,	/* 6        48      64-QAM      1/2   */
116 	htt_ofdm_datarate_54_mbps = 7,	/* 7        54      64-QAM      3/4   */
117 	htt_ofdm_datarate_max = 7,
118 };
119 
120 /**
121  * struct ocb_tx_ctrl_hdr_t - TX control header
122  * @version:		must be 1
123  * @length:		length of this structure
124  * @channel_freq:	channel on which to transmit the packet
125  * @valid_pwr:		bit 0: if set, tx pwr spec is valid
126  * @valid_datarate:	bit 1: if set, tx MCS mask spec is valid
127  * @valid_retries:	bit 2: if set, tx retries spec is valid
128  * @valid_chain_mask:	bit 3: if set, chain mask is valid
129  * @valid_expire_tsf:	bit 4: if set, tx expire TSF spec is valid
130  * @valid_tid:		bit 5: if set, TID is valid
131  * @reserved0_15_6:	bits 15:6 - unused, set to 0x0
132  * @all_flags:		union of all the flags
133  * @expire_tsf_lo:	TX expiry time (TSF) LSBs
134  * @expire_tsf_hi:	TX expiry time (TSF) MSBs
135  * @pwr:		Specify what power the tx frame needs to be transmitted
136  *			at. The power a signed (two's complement) value is in
137  *			units of 0.5 dBm. The value needs to be appropriately
138  *			sign-extended when extracting the value from the message
139  *			and storing it in a variable that is larger than A_INT8.
140  *			If the transmission uses multiple tx chains, this power
141  *			spec is the total transmit power, assuming incoherent
142  *			combination of per-chain power to produce the total
143  *			power.
144  * @datarate:		The desired modulation and coding scheme.
145  *			VALUE    DATA RATE   MODULATION  CODING RATE
146  *			@ 20 MHz
147  *			(MBPS)
148  *			0        6           BPSK        1/2
149  *			1        9           BPSK        3/4
150  *			2        12          QPSK        1/2
151  *			3        18          QPSK        3/4
152  *			4        24          16-QAM      1/2
153  *			5        36          16-QAM      3/4
154  *			6        48          64-QAM      1/2
155  *			7        54          64-QAM      3/4
156  * @retry_limit:	Specify the maximum number of transmissions, including
157  *			the initial transmission, to attempt before giving up if
158  *			no ack is received.
159  *			If the tx rate is specified, then all retries shall use
160  *			the same rate as the initial transmission.
161  *			If no tx rate is specified, the target can choose
162  *			whether to retain the original rate during the
163  *			retransmissions, or to fall back to a more robust rate.
164  * @chain_mask:		specify which chains to transmit from
165  * @ext_tid:		Extended Traffic ID (0-15)
166  * @reserved:		Ensure that the size of the structure is a multiple of
167  *			4. Must be 0.
168  *
169  * When sending an OCB packet, the user application has
170  * the option of including the following struct following an ethernet header
171  * with the proto field set to 0x8151. This struct includes various TX
172  * parameters including the TX power and MCS.
173  */
174 PREPACK struct ocb_tx_ctrl_hdr_t {
175 	uint16_t version;
176 	uint16_t length;
177 	uint16_t channel_freq;
178 
179 	union {
180 		struct {
181 			uint16_t
182 			valid_pwr:1,
183 			valid_datarate:1,
184 			valid_retries:1,
185 			valid_chain_mask:1,
186 			valid_expire_tsf:1,
187 			valid_tid:1,
188 			reserved0_15_6:10;
189 		};
190 		uint16_t all_flags;
191 	};
192 
193 	uint32_t expire_tsf_lo;
194 	uint32_t expire_tsf_hi;
195 	int8_t pwr;
196 	uint8_t datarate;
197 	uint8_t retry_limit;
198 	uint8_t chain_mask;
199 	uint8_t ext_tid;
200 	uint8_t reserved[3];
201 } POSTPACK;
202 
203 /**
204  * @brief tx MSDU meta-data that HTT may use to program the FW/HW tx descriptor
205  */
206 struct htt_msdu_info_t {
207 	/* the info sub-struct specifies the characteristics of the MSDU */
208 	struct {
209 		uint16_t ethertype;
210 #define HTT_INVALID_PEER_ID 0xffff
211 		uint16_t peer_id;
212 		uint8_t vdev_id;
213 		uint8_t ext_tid;
214 		/*
215 		 * l2_hdr_type - L2 format (802.3, native WiFi 802.11,
216 		 * or raw 802.11)
217 		 * Based on attach-time configuration, the tx frames provided
218 		 * by the OS to the tx data SW are expected to be either
219 		 * 802.3 format or the "native WiFi" variant of 802.11 format.
220 		 * Internally, the driver may also inject tx frames into the tx
221 		 * datapath, and these frames may be either 802.3 format or
222 		 * 802.11 "raw" format, with no further 802.11 encapsulation
223 		 * needed.
224 		 * The tx frames are tagged with their frame format, so target
225 		 * FW/HW will know how to interpret the packet's encapsulation
226 		 * headers when doing tx classification, and what form of 802.11
227 		 * header encapsulation is needed, if any.
228 		 */
229 		uint8_t l2_hdr_type;    /* enum htt_pkt_type */
230 		/*
231 		 * frame_type - is the tx frame management or data?
232 		 * Just to avoid confusion, the enum values for this frame type
233 		 * field use the 802.11 frame type values, although it is
234 		 * unexpected for control frames to be sent through the host
235 		 * data path.
236 		 */
237 		uint8_t frame_type;     /* enum htt_frm_type */
238 		/*
239 		 * frame subtype - this field specifies the sub-type of
240 		 * management frames
241 		 * Just to avoid confusion, the enum values for this frame
242 		 * subtype field use the 802.11 management frame subtype values.
243 		 */
244 		uint8_t frame_subtype;  /* enum htt_frm_subtype */
245 		uint8_t is_unicast;
246 
247 		/* dest_addr is not currently used.
248 		 * It could be used as an input to a Tx BD (Riva tx descriptor)
249 		 * signature computation.
250 		   uint8_t *dest_addr;
251 		 */
252 
253 		uint8_t l3_hdr_offset;  /* wrt qdf_nbuf_data(msdu), in bytes */
254 
255 		/* l4_hdr_offset is not currently used.
256 		 * It could be used to specify to a TCP/UDP checksum computation
257 		 * engine where the TCP/UDP header starts.
258 		 */
259 		/* uint8_t l4_hdr_offset; - wrt qdf_nbuf_data(msdu), in bytes */
260 	} info;
261 	/* the action sub-struct specifies how to process the MSDU */
262 	struct {
263 		/* mgmt frames: option to force 6 Mbps rate */
264 		uint8_t use_6mbps;
265 		uint8_t do_encrypt;
266 		uint8_t do_tx_complete;
267 		uint8_t tx_comp_req;
268 
269 		/*
270 		 * cksum_offload - Specify whether checksum offload is
271 		 * enabled or not
272 		 * Target FW uses this flag to turn on HW checksumming
273 		 * 0x0 - No checksum offload
274 		 * 0x1 - L3 header checksum only
275 		 * 0x2 - L4 checksum only
276 		 * 0x3 - L3 header checksum + L4 checksum
277 		 */
278 		qdf_nbuf_tx_cksum_t cksum_offload;
279 	} action;
280 };
281 
htt_msdu_info_dump(struct htt_msdu_info_t * msdu_info)282 static inline void htt_msdu_info_dump(struct htt_msdu_info_t *msdu_info)
283 {
284 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
285 		  "HTT MSDU info object (%pK)\n", msdu_info);
286 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
287 		  "  ethertype: %#x\n", msdu_info->info.ethertype);
288 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
289 		  "  peer_id: %d\n", msdu_info->info.peer_id);
290 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
291 		  "  vdev_id: %d\n", msdu_info->info.vdev_id);
292 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
293 		  "  ext_tid: %d\n", msdu_info->info.ext_tid);
294 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
295 		  "  l2_hdr_type: %d\n", msdu_info->info.l2_hdr_type);
296 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
297 		  "  frame_type: %d\n", msdu_info->info.frame_type);
298 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
299 		  "  frame_subtype: %d\n", msdu_info->info.frame_subtype);
300 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
301 		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
302 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
303 		  "  l3_hdr_offset: %u\n", msdu_info->info.l3_hdr_offset);
304 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
305 		  "  use 6 Mbps: %d\n", msdu_info->action.use_6mbps);
306 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
307 		  "  do_encrypt: %d\n", msdu_info->action.do_encrypt);
308 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
309 		  "  do_tx_complete: %d\n", msdu_info->action.do_tx_complete);
310 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
311 		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
312 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
313 		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
314 }
315 
316 /*================ tx completion message field access methods ===============*/
317 
318 /**
319  * @brief Look up the descriptor ID of the nth MSDU from a tx completion msg.
320  * @details
321  *  A tx completion message tells the host that the target is done
322  *  transmitting a series of MSDUs.  The message uses a descriptor ID
323  *  to identify each such MSDU.  This function/macro is used to
324  *  find the ID of one such MSDU referenced by the tx completion message.
325  *
326  * @param iterator - tx completion message context provided by HTT to the
327  *      tx completion message handler.  This abstract reference to the
328  *      HTT tx completion message's payload allows the data SW's tx
329  *      completion handler to not care about the format of the HTT
330  *      tx completion message.
331  * @param num - (zero-based) index to specify a single MSDU within the
332  *      series of MSDUs referenced by the tx completion message
333  * @return descriptor ID for the specified MSDU
334  */
335 uint16_t htt_tx_compl_desc_id(void *iterator, int num);
336 
337 /*========================= tx descriptor operations ========================*/
338 
339 /**
340  * @brief Allocate a HTT abstract tx descriptor.
341  * @details
342  *  Allocate a HTT abstract tx descriptor from a pool within "consistent"
343  *  memory, which is accessible by HIF and/or MAC DMA as well as by the
344  *  host CPU.
345  *  It is expected that the tx datapath will allocate HTT tx descriptors
346  *  and link them with datapath SW tx descriptors up front as the driver
347  *  is loaded.  Thereafter, the link from datapath SW tx descriptor to
348  *  HTT tx descriptor will be maintained until the driver is unloaded.
349  *
350  * @param htt_pdev - handle to the HTT instance making the allocation
351  * @param[OUT] paddr_lo - physical address of the HTT descriptor
352  * @return success -> descriptor handle, -OR- failure -> NULL
353  */
354 void *htt_tx_desc_alloc(htt_pdev_handle pdev, qdf_dma_addr_t *paddr,
355 			uint16_t index);
356 
357 /**
358  * @brief Free a HTT abstract tx descriptor.
359  *
360  * @param htt_pdev - handle to the HTT instance that made the allocation
361  * @param htt_tx_desc - the descriptor to free
362  */
363 void htt_tx_desc_free(htt_pdev_handle htt_pdev, void *htt_tx_desc);
364 
365 #if defined(HELIUMPLUS)
366 /**
367  * @brief Allocate TX frag descriptor
368  * @details
369  *  Allocate TX frag descriptor
370  *
371  * @param pdev - handle to the HTT instance that made the allocation
372  * @param index - tx descriptor index
373  * @param frag_paddr_lo - fragment descriptor physical address lower 32bits
374  * @param frag_ptr - fragment descriptor hlos pointe
375  * @return success 0
376  */
377 int htt_tx_frag_alloc(htt_pdev_handle pdev,
378 	u_int16_t index, qdf_dma_addr_t *frag_paddr, void **frag_ptr);
379 #else
htt_tx_frag_alloc(htt_pdev_handle pdev,u_int16_t index,qdf_dma_addr_t * frag_paddr,void ** frag_ptr)380 static inline int htt_tx_frag_alloc(htt_pdev_handle pdev,
381 	u_int16_t index, qdf_dma_addr_t *frag_paddr, void **frag_ptr)
382 {
383 	*frag_ptr = NULL;
384 	return 0;
385 }
386 #endif /* defined(HELIUMPLUS) */
387 
388 #if defined(CONFIG_HL_SUPPORT)
389 
390 /**
391  * @brief Discard all tx frames in the process of being downloaded.
392  * @details
393  * This function discards any tx frames queued in HTT or the layers
394  * under HTT.
395  * The download completion callback is invoked on these frames.
396  *
397  * @param htt_pdev - handle to the HTT instance
398  * @param[OUT] frag_paddr_lo - physical address of the fragment descriptor
399  *                             (MSDU Link Extension Descriptor)
400  */
htt_tx_pending_discard(htt_pdev_handle pdev)401 static inline void htt_tx_pending_discard(htt_pdev_handle pdev)
402 {
403 }
404 #else
405 
406 void htt_tx_pending_discard(htt_pdev_handle pdev);
407 #endif
408 
409 /**
410  * @brief Download a MSDU descriptor and (a portion of) the MSDU payload.
411  * @details
412  *  This function is used within LL systems to download a tx descriptor and
413  *  the initial portion of the tx MSDU payload, and within HL systems to
414  *  download the tx descriptor and the entire tx MSDU payload.
415  *  The HTT layer determines internally how much of the tx descriptor
416  *  actually needs to be downloaded. In particular, the HTT layer does not
417  *  download the fragmentation descriptor, and only for the LL case downloads
418  *  the physical address of the fragmentation descriptor.
419  *  In HL systems, the tx descriptor and the entire frame are downloaded.
420  *  In LL systems, only the tx descriptor and the header of the frame are
421  *  downloaded.  To determine how much of the tx frame to download, this
422  *  function assumes the tx frame is the default frame type, as specified
423  *  by ol_cfg_frame_type.  "Raw" frames need to be transmitted through the
424  *  alternate htt_tx_send_nonstd function.
425  *  The tx descriptor has already been attached to the qdf_nbuf object during
426  *  a preceding call to htt_tx_desc_init.
427  *
428  * @param htt_pdev - the handle of the physical device sending the tx data
429  * @param msdu - the frame being transmitted
430  * @param msdu_id - unique ID for the frame being transmitted
431  * @return 0 -> success, -OR- 1 -> failure
432  */
433 int
434 htt_tx_send_std(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu, uint16_t msdu_id);
435 
436 /**
437  * @brief Download a Batch Of Tx MSDUs
438  * @details
439  *     Each MSDU already has the MSDU ID stored in the headroom of the
440  *     netbuf data buffer, and has the HTT tx descriptor already attached
441  *     as a prefix fragment to the netbuf.
442  *
443  * @param htt_pdev - the handle of the physical device sending the tx data
444  * @param head_msdu - the MSDU Head for Tx batch being transmitted
445  * @param num_msdus - The total Number of MSDU's provided for batch tx
446  * @return null-terminated linked-list of unaccepted frames
447  */
448 qdf_nbuf_t
449 htt_tx_send_batch(htt_pdev_handle htt_pdev,
450 		  qdf_nbuf_t head_msdu, int num_msdus);
451 
452 /* The htt scheduler for queued packets in htt
453  * htt when unable to send to HTC because of lack of resource
454  * forms a nbuf queue which is flushed when tx completion event from
455  * target is received
456  */
457 
458 void htt_tx_sched(htt_pdev_handle pdev);
459 
460 /**
461  * @brief Same as htt_tx_send_std, but can handle raw frames.
462  */
463 int
464 htt_tx_send_nonstd(htt_pdev_handle htt_pdev,
465 		   qdf_nbuf_t msdu,
466 		   uint16_t msdu_id, enum htt_pkt_type pkt_type);
467 
468 /**
469  * htt_pkt_dl_len_get() Gets the HTT PKT download length.
470  * @pdev: pointer to struct htt_pdev_t
471  *
472  * Return: size of HTT packet download length.
473  */
474 int
475 htt_pkt_dl_len_get(struct htt_pdev_t *pdev);
476 
477 /* Used to set classify bit in HTT desc.*/
478 #define HTT_TX_CLASSIFY_BIT_S	4
479 
480 /**
481  * enum htt_ce_tx_pkt_type - enum of packet types to be set in CE
482  *			     descriptor
483  * @tx_pkt_type_raw: Value set for RAW frames
484  * @tx_pkt_type_native_wifi: Value set for NATIVE WIFI frames
485  * @tx_pkt_type_eth2: Value set for Ethernet II frames (mostly default)
486  * @tx_pkt_type_802_3: Value set for 802.3 / original ethernet frames
487  * @tx_pkt_type_mgmt: Value set for MGMT frames over HTT
488  *
489  */
490 enum htt_ce_tx_pkt_type {
491 	tx_pkt_type_raw = 0,
492 	tx_pkt_type_native_wifi = 1,
493 	tx_pkt_type_eth2 = 2,
494 	tx_pkt_type_802_3 = 3,
495 	tx_pkt_type_mgmt = 4
496 };
497 
498 /**
499  * enum extension_header_type - extension header type
500  * @EXT_HEADER_NOT_PRESENT: extension header not present
501  * @OCB_MODE_EXT_HEADER: Extension header for OCB mode
502  * @WISA_MODE_EXT_HEADER_6MBPS: WISA mode 6Mbps header
503  * @WISA_MODE_EXT_HEADER_24MBPS: WISA mode 24Mbps header
504  */
505 enum extension_header_type {
506 	EXT_HEADER_NOT_PRESENT,
507 	OCB_MODE_EXT_HEADER,
508 	WISA_MODE_EXT_HEADER_6MBPS,
509 	WISA_MODE_EXT_HEADER_24MBPS,
510 };
511 
512 extern const uint32_t htt_to_ce_pkt_type[];
513 
514 /**
515  * Provide a constant to specify the offset of the HTT portion of the
516  * HTT tx descriptor, to avoid having to export the descriptor definition.
517  * The htt module checks internally that this exported offset is consistent
518  * with the private tx descriptor definition.
519  *
520  * Similarly, export a definition of the HTT tx descriptor size, and then
521  * check internally that this exported constant matches the private tx
522  * descriptor definition.
523  */
524 #define HTT_TX_DESC_VADDR_OFFSET 8
525 
526 /**
527  * htt_tx_desc_init() - Initialize the per packet HTT Tx descriptor
528  * @pdev:		  The handle of the physical device sending the
529  *			  tx data
530  * @htt_tx_desc:	  Abstract handle to the tx descriptor
531  * @htt_tx_desc_paddr_lo: Physical address of the HTT tx descriptor
532  * @msdu_id:		  ID to tag the descriptor with.
533  *			  The FW sends this ID back to host as a cookie
534  *			  during Tx completion, which the host uses to
535  *			  identify the MSDU.
536  *			  This ID is an index into the OL Tx desc. array.
537  * @msdu:		  The MSDU that is being prepared for transmission
538  * @msdu_info:		  Tx MSDU meta-data
539  * @tso_info:		  Storage for TSO meta-data
540  * @ext_header_data:      extension header data
541  * @type:                 extension header type
542  *
543  * This function initializes the HTT tx descriptor.
544  * HTT Tx descriptor is a host-f/w interface structure, and meta-data
545  * accompanying every packet downloaded to f/w via the HTT interface.
546  *
547  * Return QDF_STATUS_SUCCESS for success, otherwise error.
548  */
549 QDF_STATUS
550 htt_tx_desc_init(htt_pdev_handle pdev,
551 		 void *htt_tx_desc,
552 		 qdf_dma_addr_t htt_tx_desc_paddr,
553 		 uint16_t msdu_id,
554 		 qdf_nbuf_t msdu, struct htt_msdu_info_t *msdu_info,
555 		 struct qdf_tso_info_t *tso_info,
556 		 void *ext_header_data,
557 		 enum extension_header_type type);
558 
559 /**
560  * @brief Set a flag to indicate that the MSDU in question was postponed.
561  * @details
562  *  In systems in which the host retains its tx frame until the target sends
563  *  a tx completion, the target has the option of discarding it's copy of
564  *  the tx descriptor (and frame, for HL) and sending a "postpone" message
565  *  to the host, to inform the host that it must eventually download the
566  *  tx descriptor (and frame, for HL).
567  *  Before the host downloads the postponed tx desc/frame again, it will use
568  *  this function to set a flag in the HTT tx descriptor indicating that this
569  *  is a re-send of a postponed frame, rather than a new frame.  The target
570  *  uses this flag to keep the correct order between re-sent and new tx frames.
571  *  This function is relevant for LL systems.
572  *
573  * @param pdev - the handle of the physical device sending the tx data
574  * @param desc - abstract handle to the tx descriptor
575  */
576 void htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc);
577 
578 /**
579  * @brief Set a flag to tell the target that more tx downloads are en route.
580  * @details
581  *  At times, particularly in response to a U-APSD trigger in a HL system, the
582  *  host will download multiple tx descriptors (+ frames, in HL) in a batch.
583  *  The host will use this function to set a "more" flag in the initial
584  *  and interior frames of the batch, to tell the target that more tx frame
585  *  downloads within the batch are imminent.
586  *
587  * @param pdev - the handle of the physical device sending the tx data
588  * @param desc - abstract handle to the tx descriptor
589  */
590 void htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc);
591 
592 /**
593  * @brief Specify the number of fragments in the fragmentation descriptor.
594  * @details
595  *  Specify the number of fragments within the MSDU, i.e. the number of
596  *  elements within the fragmentation descriptor.
597  *  For LL, this is used to terminate the list of fragments used by the
598  *  HW's tx MAC DMA.
599  *  For HL, this is used to terminate the list of fragments provided to
600  *  HTC for download.
601  *
602  * @param pdev - the handle of the physical device sending the tx data
603  * @param desc - abstract handle to the tx descriptor
604  * @param num_frags - the number of fragments comprising the MSDU
605  */
606 static inline
607 void
htt_tx_desc_num_frags(htt_pdev_handle pdev,void * desc,uint32_t num_frags)608 htt_tx_desc_num_frags(htt_pdev_handle pdev, void *desc, uint32_t num_frags)
609 {
610 	/*
611 	 * Set the element after the valid frag elems to 0x0,
612 	 * to terminate the list of fragments.
613 	 */
614 #if defined(HELIUMPLUS)
615 	if (HTT_WIFI_IP(pdev, 2, 0)) {
616 		struct msdu_ext_frag_desc *fdesc;
617 
618 		/** Skip TSO related 4 dwords WIFI2.0*/
619 		fdesc = (struct msdu_ext_frag_desc *)
620 			&(((struct msdu_ext_desc_t *)desc)->frags[0]);
621 		fdesc[num_frags].u.desc64 = 0;
622 	} else {
623 		/* This piece of code should never be executed on HELIUMPLUS */
624 		*((u_int32_t *)
625 		  (((char *) desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
626 	}
627 #else /* ! HELIUMPLUS */
628 	*((uint32_t *)
629 	  (((char *)desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
630 #endif /* HELIUMPLUS */
631 }
632 
633 /* checksum offload flags for hw */
634 #define IPV4_CSUM_EN     0x00010000
635 #define UDP_IPV4_CSUM_EN 0x00020000
636 #define UDP_IPV6_CSUM_EN 0x00040000
637 #define TCP_IPV4_CSUM_EN 0x00080000
638 #define TCP_IPV6_CSUM_EN 0x00100000
639 #define PARTIAL_CSUM_EN  0x00200000
640 
641 /**
642  * @brief Specify the location and size of a fragment of a tx MSDU.
643  * @details
644  *  In LL systems, the tx MAC DMA needs to know how the MSDU is constructed
645  *  from fragments.
646  *  In LL and HL systems, the HIF's download DMA to the target (LL: tx desc
647  *  + header of tx payload; HL: tx desc + entire tx payload) needs to know
648  *  where to find the fragments to download.
649  *  The tx data SW uses this function to specify the location and size of
650  *  each of the MSDU's fragments.
651  *
652  * @param pdev - the handle of the physical device sending the tx data
653  * @param desc - abstract handle to the HTT tx descriptor
654  * @param frag_num - which fragment is being specified (zero-based indexing)
655  * @param frag_phys_addr - DMA/physical address of the fragment
656  * @param frag_len - number of bytes within the fragment
657  */
658 static inline
659 void
htt_tx_desc_frag(htt_pdev_handle pdev,void * desc,int frag_num,qdf_dma_addr_t frag_phys_addr,uint16_t frag_len)660 htt_tx_desc_frag(htt_pdev_handle pdev,
661 		 void *desc,
662 		 int frag_num, qdf_dma_addr_t frag_phys_addr, uint16_t frag_len)
663 {
664 	uint32_t *word32;
665 #if defined(HELIUMPLUS)
666 	uint64_t  *word64;
667 
668 	if (HTT_WIFI_IP(pdev, 2, 0)) {
669 		word32 = (u_int32_t *)(desc);
670 		/* Initialize top 6 words of TSO flags per packet */
671 		*word32++ = 0;
672 		*word32++ = 0;
673 		*word32++ = 0;
674 		if (((struct txrx_pdev_cfg_t *)(pdev->ctrl_pdev))
675 		    ->ip_tcp_udp_checksum_offload)
676 			*word32 |= (IPV4_CSUM_EN | TCP_IPV4_CSUM_EN |
677 					TCP_IPV6_CSUM_EN | UDP_IPV4_CSUM_EN |
678 					UDP_IPV6_CSUM_EN);
679 		else
680 			*word32 = 0;
681 		word32++;
682 		*word32++ = 0;
683 		*word32++ = 0;
684 
685 		qdf_assert_always(word32 == (uint32_t *)
686 				&(((struct msdu_ext_desc_t *)desc)->frags[0]));
687 
688 		/* Each fragment consumes 2 DWORDS */
689 		word32 += (frag_num << 1);
690 		word64 = (uint64_t *)word32;
691 		*word64 = frag_phys_addr;
692 		/*
693 		 * The frag_phys address is 37 bits. So, the higher 16 bits will
694 		 * be for len
695 		 */
696 		word32++;
697 		*word32 &= 0x0000ffff;
698 		*word32 |= (frag_len << 16);
699 	} else {
700 		/* For Helium+, this block cannot exist */
701 		QDF_ASSERT(0);
702 	}
703 #else /* !defined(HELIUMPLUS) */
704 	{
705 		uint64_t u64  = (uint64_t)frag_phys_addr;
706 		uint32_t u32l = (u64 & 0xffffffff);
707 		uint32_t u32h = (uint32_t)((u64 >> 32) & 0x1f);
708 		uint64_t *word64;
709 
710 		word32 = (uint32_t *) (((char *)desc) +
711 			 HTT_TX_DESC_LEN + frag_num * 8);
712 		word64 = (uint64_t *)word32;
713 		*word32 = u32l;
714 		word32++;
715 		*word32 = (u32h << 16) | frag_len;
716 	}
717 #endif /* defined(HELIUMPLUS) */
718 }
719 
720 void htt_tx_desc_frags_table_set(htt_pdev_handle pdev,
721 				 void *desc,
722 				 qdf_dma_addr_t paddr,
723 				 qdf_dma_addr_t frag_desc_paddr,
724 				 int reset);
725 
726 /**
727  * @brief Specify the type and subtype of a tx frame.
728  *
729  * @param pdev - the handle of the physical device sending the tx data
730  * @param type - format of the MSDU (802.3, native WiFi, raw, or mgmt)
731  * @param sub_type - sub_type (relevant for raw frames)
732  */
733 static inline
734 void
htt_tx_desc_type(htt_pdev_handle pdev,void * htt_tx_desc,enum htt_pkt_type type,uint8_t sub_type)735 htt_tx_desc_type(htt_pdev_handle pdev,
736 		 void *htt_tx_desc, enum htt_pkt_type type, uint8_t sub_type)
737 {
738 	uint32_t *word0;
739 
740 	word0 = (uint32_t *) htt_tx_desc;
741 	/* clear old values */
742 	*word0 &= ~(HTT_TX_DESC_PKT_TYPE_M | HTT_TX_DESC_PKT_SUBTYPE_M);
743 	/* write new values */
744 	HTT_TX_DESC_PKT_TYPE_SET(*word0, type);
745 	HTT_TX_DESC_PKT_SUBTYPE_SET(*word0, sub_type);
746 }
747 
748 /***** TX MGMT DESC management APIs ****/
749 
750 /* Number of mgmt descriptors in the pool */
751 #define HTT_MAX_NUM_MGMT_DESCS 32
752 
753 /** htt_tx_mgmt_desc_pool_alloc
754  * @description - allocates the memory for mgmt frame descriptors
755  * @param  - htt pdev object
756  * @param  - num of descriptors to be allocated in the pool
757  */
758 void htt_tx_mgmt_desc_pool_alloc(struct htt_pdev_t *pdev, A_UINT32 num_elems);
759 
760 /** htt_tx_mgmt_desc_alloc
761  * @description - reserves a mgmt descriptor from the pool
762  * @param  - htt pdev object
763  * @param  - pointer to variable to hold the allocated desc id
764  * @param  - pointer to the mamangement from UMAC
765  * @return - pointer the allocated mgmt descriptor
766  */
767 qdf_nbuf_t
768 htt_tx_mgmt_desc_alloc(struct htt_pdev_t *pdev, A_UINT32 *desc_id,
769 		       qdf_nbuf_t mgmt_frm);
770 
771 /** htt_tx_mgmt_desc_free
772  * @description - releases the management descriptor back to the pool
773  * @param  - htt pdev object
774  * @param  - descriptor ID
775  */
776 void
777 htt_tx_mgmt_desc_free(struct htt_pdev_t *pdev, A_UINT8 desc_id,
778 		      A_UINT32 status);
779 
780 /** htt_tx_mgmt_desc_pool_free
781  * @description - releases all the resources allocated for mgmt desc pool
782  * @param  - htt pdev object
783  */
784 void htt_tx_mgmt_desc_pool_free(struct htt_pdev_t *pdev);
785 
786 /**
787  * @brief Provide a buffer to store a 802.11 header added by SW tx encap
788  *
789  * @param htt_tx_desc - which frame the 802.11 header is being added to
790  * @param new_l2_hdr_size - how large the buffer needs to be
791  */
792 #define htt_tx_desc_mpdu_header(htt_tx_desc, new_l2_hdr_size) /*NULL*/
793 /**
794  * @brief How many tx credits would be consumed by the specified tx frame.
795  *
796  * @param msdu - the tx frame in question
797  * @return number of credits used for this tx frame
798  */
799 #define htt_tx_msdu_credit(msdu) 1      /* 1 credit per buffer */
800 #ifdef HTT_DBG
801 void htt_tx_desc_display(void *tx_desc);
802 #else
803 #define htt_tx_desc_display(tx_desc)
804 #endif
805 
htt_tx_desc_set_peer_id(void * htt_tx_desc,uint16_t peer_id)806 static inline void htt_tx_desc_set_peer_id(void *htt_tx_desc, uint16_t peer_id)
807 {
808 	uint16_t *peer_id_field_ptr;
809 
810 	peer_id_field_ptr = (uint16_t *)
811 			    (htt_tx_desc +
812 			     HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES);
813 
814 	*peer_id_field_ptr = peer_id;
815 }
816 
817 static inline
htt_tx_desc_set_chanfreq(void * htt_tx_desc,uint16_t chanfreq)818 void htt_tx_desc_set_chanfreq(void *htt_tx_desc, uint16_t chanfreq)
819 {
820 	uint16_t *chanfreq_field_ptr;
821 
822 	/*
823 	 * The reason we dont use CHAN_FREQ_OFFSET_BYTES is because
824 	 * it uses DWORD as unit
825 	 *
826 	 * The reason we dont use the SET macro in htt.h is because
827 	 * htt_tx_desc is incomplete type
828 	 */
829 	chanfreq_field_ptr = (uint16_t *)
830 		(htt_tx_desc +
831 		 HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES
832 		 + sizeof(A_UINT16));
833 
834 	*chanfreq_field_ptr = chanfreq;
835 }
836 
837 #if defined(FEATURE_TSO) && defined(HELIUMPLUS)
838 void
839 htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc,
840 	 struct qdf_tso_info_t *tso_info);
841 #else
842 #define htt_tx_desc_fill_tso_info(pdev, desc, tso_info)
843 #endif
844 #endif /* _OL_HTT_TX_API__H_ */
845