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