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