18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * This file is part of wl1251 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 1998-2007 Texas Instruments Incorporated 68c2ecf20Sopenharmony_ci * Copyright (C) 2008 Nokia Corporation 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifndef __WL1251_TX_H__ 108c2ecf20Sopenharmony_ci#define __WL1251_TX_H__ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/bitops.h> 138c2ecf20Sopenharmony_ci#include "acx.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * TX PATH 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * The Tx path uses a double buffer and a tx_control structure, each located 208c2ecf20Sopenharmony_ci * at a fixed address in the device's memory. On startup, the host retrieves 218c2ecf20Sopenharmony_ci * the pointers to these addresses. A double buffer allows for continuous data 228c2ecf20Sopenharmony_ci * flow towards the device. The host keeps track of which buffer is available 238c2ecf20Sopenharmony_ci * and alternates between these two buffers on a per packet basis. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * The size of each of the two buffers is large enough to hold the longest 268c2ecf20Sopenharmony_ci * 802.3 packet - maximum size Ethernet packet + header + descriptor. 278c2ecf20Sopenharmony_ci * TX complete indication will be received a-synchronously in a TX done cyclic 288c2ecf20Sopenharmony_ci * buffer which is composed of 16 tx_result descriptors structures and is used 298c2ecf20Sopenharmony_ci * in a cyclic manner. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * The TX (HOST) procedure is as follows: 328c2ecf20Sopenharmony_ci * 1. Read the Tx path status, that will give the data_out_count. 338c2ecf20Sopenharmony_ci * 2. goto 1, if not possible. 348c2ecf20Sopenharmony_ci * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double 358c2ecf20Sopenharmony_ci * buffer). 368c2ecf20Sopenharmony_ci * 3. Copy the packet (preceded by double_buffer_desc), if possible. 378c2ecf20Sopenharmony_ci * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double 388c2ecf20Sopenharmony_ci * buffer). 398c2ecf20Sopenharmony_ci * 4. increment data_in_count. 408c2ecf20Sopenharmony_ci * 5. Inform the firmware by generating a firmware internal interrupt. 418c2ecf20Sopenharmony_ci * 6. FW will increment data_out_count after it reads the buffer. 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * The TX Complete procedure: 448c2ecf20Sopenharmony_ci * 1. To get a TX complete indication the host enables the tx_complete flag in 458c2ecf20Sopenharmony_ci * the TX descriptor Structure. 468c2ecf20Sopenharmony_ci * 2. For each packet with a Tx Complete field set, the firmware adds the 478c2ecf20Sopenharmony_ci * transmit results to the cyclic buffer (txDoneRing) and sets both done_1 488c2ecf20Sopenharmony_ci * and done_2 to 1 to indicate driver ownership. 498c2ecf20Sopenharmony_ci * 3. The firmware sends a Tx Complete interrupt to the host to trigger the 508c2ecf20Sopenharmony_ci * host to process the new data. Note: interrupt will be send per packet if 518c2ecf20Sopenharmony_ci * TX complete indication was requested in tx_control or per crossing 528c2ecf20Sopenharmony_ci * aggregation threshold. 538c2ecf20Sopenharmony_ci * 4. After receiving the Tx Complete interrupt, the host reads the 548c2ecf20Sopenharmony_ci * TxDescriptorDone information in a cyclic manner and clears both done_1 558c2ecf20Sopenharmony_ci * and done_2 fields. 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define TX_COMPLETE_REQUIRED_BIT 0x80 608c2ecf20Sopenharmony_ci#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define WL1251_TX_ALIGN_TO 4 638c2ecf20Sopenharmony_ci#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \ 648c2ecf20Sopenharmony_ci ~(WL1251_TX_ALIGN_TO - 1)) 658c2ecf20Sopenharmony_ci#define WL1251_TKIP_IV_SPACE 4 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistruct tx_control { 688c2ecf20Sopenharmony_ci /* Rate Policy (class) index */ 698c2ecf20Sopenharmony_ci unsigned rate_policy:3; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* When set, no ack policy is expected */ 728c2ecf20Sopenharmony_ci unsigned ack_policy:1; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* 758c2ecf20Sopenharmony_ci * Packet type: 768c2ecf20Sopenharmony_ci * 0 -> 802.11 778c2ecf20Sopenharmony_ci * 1 -> 802.3 788c2ecf20Sopenharmony_ci * 2 -> IP 798c2ecf20Sopenharmony_ci * 3 -> raw codec 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci unsigned packet_type:2; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* If set, this is a QoS-Null or QoS-Data frame */ 848c2ecf20Sopenharmony_ci unsigned qos:1; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* 878c2ecf20Sopenharmony_ci * If set, the target triggers the tx complete INT 888c2ecf20Sopenharmony_ci * upon frame sending completion. 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci unsigned tx_complete:1; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci /* 2 bytes padding before packet header */ 938c2ecf20Sopenharmony_ci unsigned xfer_pad:1; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci unsigned reserved:7; 968c2ecf20Sopenharmony_ci} __packed; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistruct tx_double_buffer_desc { 1008c2ecf20Sopenharmony_ci /* Length of payload, including headers. */ 1018c2ecf20Sopenharmony_ci __le16 length; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* 1048c2ecf20Sopenharmony_ci * A bit mask that specifies the initial rate to be used 1058c2ecf20Sopenharmony_ci * Possible values are: 1068c2ecf20Sopenharmony_ci * 0x0001 - 1Mbits 1078c2ecf20Sopenharmony_ci * 0x0002 - 2Mbits 1088c2ecf20Sopenharmony_ci * 0x0004 - 5.5Mbits 1098c2ecf20Sopenharmony_ci * 0x0008 - 6Mbits 1108c2ecf20Sopenharmony_ci * 0x0010 - 9Mbits 1118c2ecf20Sopenharmony_ci * 0x0020 - 11Mbits 1128c2ecf20Sopenharmony_ci * 0x0040 - 12Mbits 1138c2ecf20Sopenharmony_ci * 0x0080 - 18Mbits 1148c2ecf20Sopenharmony_ci * 0x0100 - 22Mbits 1158c2ecf20Sopenharmony_ci * 0x0200 - 24Mbits 1168c2ecf20Sopenharmony_ci * 0x0400 - 36Mbits 1178c2ecf20Sopenharmony_ci * 0x0800 - 48Mbits 1188c2ecf20Sopenharmony_ci * 0x1000 - 54Mbits 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci __le16 rate; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci /* Time in us that a packet can spend in the target */ 1238c2ecf20Sopenharmony_ci __le32 expiry_time; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* index of the TX queue used for this packet */ 1268c2ecf20Sopenharmony_ci u8 xmit_queue; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* Used to identify a packet */ 1298c2ecf20Sopenharmony_ci u8 id; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci struct tx_control control; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* 1348c2ecf20Sopenharmony_ci * The FW should cut the packet into fragments 1358c2ecf20Sopenharmony_ci * of this size. 1368c2ecf20Sopenharmony_ci */ 1378c2ecf20Sopenharmony_ci __le16 frag_threshold; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci /* Numbers of HW queue blocks to be allocated */ 1408c2ecf20Sopenharmony_ci u8 num_mem_blocks; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci u8 reserved; 1438c2ecf20Sopenharmony_ci} __packed; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cienum { 1468c2ecf20Sopenharmony_ci TX_SUCCESS = 0, 1478c2ecf20Sopenharmony_ci TX_DMA_ERROR = BIT(7), 1488c2ecf20Sopenharmony_ci TX_DISABLED = BIT(6), 1498c2ecf20Sopenharmony_ci TX_RETRY_EXCEEDED = BIT(5), 1508c2ecf20Sopenharmony_ci TX_TIMEOUT = BIT(4), 1518c2ecf20Sopenharmony_ci TX_KEY_NOT_FOUND = BIT(3), 1528c2ecf20Sopenharmony_ci TX_ENCRYPT_FAIL = BIT(2), 1538c2ecf20Sopenharmony_ci TX_UNAVAILABLE_PRIORITY = BIT(1), 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistruct tx_result { 1578c2ecf20Sopenharmony_ci /* 1588c2ecf20Sopenharmony_ci * Ownership synchronization between the host and 1598c2ecf20Sopenharmony_ci * the firmware. If done_1 and done_2 are cleared, 1608c2ecf20Sopenharmony_ci * owned by the FW (no info ready). 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci u8 done_1; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* same as double_buffer_desc->id */ 1658c2ecf20Sopenharmony_ci u8 id; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* 1688c2ecf20Sopenharmony_ci * Total air access duration consumed by this 1698c2ecf20Sopenharmony_ci * packet, including all retries and overheads. 1708c2ecf20Sopenharmony_ci */ 1718c2ecf20Sopenharmony_ci u16 medium_usage; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */ 1748c2ecf20Sopenharmony_ci u32 medium_delay; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* Time between host xfer and tx complete */ 1778c2ecf20Sopenharmony_ci u32 fw_hnadling_time; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci /* The LS-byte of the last TKIP sequence number. */ 1808c2ecf20Sopenharmony_ci u8 lsb_seq_num; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci /* Retry count */ 1838c2ecf20Sopenharmony_ci u8 ack_failures; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* At which rate we got a ACK */ 1868c2ecf20Sopenharmony_ci u16 rate; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci u16 reserved; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci /* TX_* */ 1918c2ecf20Sopenharmony_ci u8 status; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci /* See done_1 */ 1948c2ecf20Sopenharmony_ci u8 done_2; 1958c2ecf20Sopenharmony_ci} __packed; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic inline int wl1251_tx_get_queue(int queue) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci switch (queue) { 2008c2ecf20Sopenharmony_ci case 0: 2018c2ecf20Sopenharmony_ci return QOS_AC_VO; 2028c2ecf20Sopenharmony_ci case 1: 2038c2ecf20Sopenharmony_ci return QOS_AC_VI; 2048c2ecf20Sopenharmony_ci case 2: 2058c2ecf20Sopenharmony_ci return QOS_AC_BE; 2068c2ecf20Sopenharmony_ci case 3: 2078c2ecf20Sopenharmony_ci return QOS_AC_BK; 2088c2ecf20Sopenharmony_ci default: 2098c2ecf20Sopenharmony_ci return QOS_AC_BE; 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_civoid wl1251_tx_work(struct work_struct *work); 2148c2ecf20Sopenharmony_civoid wl1251_tx_complete(struct wl1251 *wl); 2158c2ecf20Sopenharmony_civoid wl1251_tx_flush(struct wl1251 *wl); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci#endif 218