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