162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This file is part of wl1251 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 1998-2007 Texas Instruments Incorporated 662306a36Sopenharmony_ci * Copyright (C) 2008 Nokia Corporation 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __WL1251_TX_H__ 1062306a36Sopenharmony_ci#define __WL1251_TX_H__ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/bitops.h> 1362306a36Sopenharmony_ci#include "acx.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * TX PATH 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * The Tx path uses a double buffer and a tx_control structure, each located 2062306a36Sopenharmony_ci * at a fixed address in the device's memory. On startup, the host retrieves 2162306a36Sopenharmony_ci * the pointers to these addresses. A double buffer allows for continuous data 2262306a36Sopenharmony_ci * flow towards the device. The host keeps track of which buffer is available 2362306a36Sopenharmony_ci * and alternates between these two buffers on a per packet basis. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * The size of each of the two buffers is large enough to hold the longest 2662306a36Sopenharmony_ci * 802.3 packet - maximum size Ethernet packet + header + descriptor. 2762306a36Sopenharmony_ci * TX complete indication will be received a-synchronously in a TX done cyclic 2862306a36Sopenharmony_ci * buffer which is composed of 16 tx_result descriptors structures and is used 2962306a36Sopenharmony_ci * in a cyclic manner. 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * The TX (HOST) procedure is as follows: 3262306a36Sopenharmony_ci * 1. Read the Tx path status, that will give the data_out_count. 3362306a36Sopenharmony_ci * 2. goto 1, if not possible. 3462306a36Sopenharmony_ci * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double 3562306a36Sopenharmony_ci * buffer). 3662306a36Sopenharmony_ci * 3. Copy the packet (preceded by double_buffer_desc), if possible. 3762306a36Sopenharmony_ci * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double 3862306a36Sopenharmony_ci * buffer). 3962306a36Sopenharmony_ci * 4. increment data_in_count. 4062306a36Sopenharmony_ci * 5. Inform the firmware by generating a firmware internal interrupt. 4162306a36Sopenharmony_ci * 6. FW will increment data_out_count after it reads the buffer. 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * The TX Complete procedure: 4462306a36Sopenharmony_ci * 1. To get a TX complete indication the host enables the tx_complete flag in 4562306a36Sopenharmony_ci * the TX descriptor Structure. 4662306a36Sopenharmony_ci * 2. For each packet with a Tx Complete field set, the firmware adds the 4762306a36Sopenharmony_ci * transmit results to the cyclic buffer (txDoneRing) and sets both done_1 4862306a36Sopenharmony_ci * and done_2 to 1 to indicate driver ownership. 4962306a36Sopenharmony_ci * 3. The firmware sends a Tx Complete interrupt to the host to trigger the 5062306a36Sopenharmony_ci * host to process the new data. Note: interrupt will be send per packet if 5162306a36Sopenharmony_ci * TX complete indication was requested in tx_control or per crossing 5262306a36Sopenharmony_ci * aggregation threshold. 5362306a36Sopenharmony_ci * 4. After receiving the Tx Complete interrupt, the host reads the 5462306a36Sopenharmony_ci * TxDescriptorDone information in a cyclic manner and clears both done_1 5562306a36Sopenharmony_ci * and done_2 fields. 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define TX_COMPLETE_REQUIRED_BIT 0x80 6062306a36Sopenharmony_ci#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define WL1251_TX_ALIGN_TO 4 6362306a36Sopenharmony_ci#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \ 6462306a36Sopenharmony_ci ~(WL1251_TX_ALIGN_TO - 1)) 6562306a36Sopenharmony_ci#define WL1251_TKIP_IV_SPACE 4 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistruct tx_control { 6862306a36Sopenharmony_ci /* Rate Policy (class) index */ 6962306a36Sopenharmony_ci unsigned rate_policy:3; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* When set, no ack policy is expected */ 7262306a36Sopenharmony_ci unsigned ack_policy:1; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* 7562306a36Sopenharmony_ci * Packet type: 7662306a36Sopenharmony_ci * 0 -> 802.11 7762306a36Sopenharmony_ci * 1 -> 802.3 7862306a36Sopenharmony_ci * 2 -> IP 7962306a36Sopenharmony_ci * 3 -> raw codec 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci unsigned packet_type:2; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* If set, this is a QoS-Null or QoS-Data frame */ 8462306a36Sopenharmony_ci unsigned qos:1; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* 8762306a36Sopenharmony_ci * If set, the target triggers the tx complete INT 8862306a36Sopenharmony_ci * upon frame sending completion. 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_ci unsigned tx_complete:1; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* 2 bytes padding before packet header */ 9362306a36Sopenharmony_ci unsigned xfer_pad:1; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci unsigned reserved:7; 9662306a36Sopenharmony_ci} __packed; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistruct tx_double_buffer_desc { 10062306a36Sopenharmony_ci /* Length of payload, including headers. */ 10162306a36Sopenharmony_ci __le16 length; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* 10462306a36Sopenharmony_ci * A bit mask that specifies the initial rate to be used 10562306a36Sopenharmony_ci * Possible values are: 10662306a36Sopenharmony_ci * 0x0001 - 1Mbits 10762306a36Sopenharmony_ci * 0x0002 - 2Mbits 10862306a36Sopenharmony_ci * 0x0004 - 5.5Mbits 10962306a36Sopenharmony_ci * 0x0008 - 6Mbits 11062306a36Sopenharmony_ci * 0x0010 - 9Mbits 11162306a36Sopenharmony_ci * 0x0020 - 11Mbits 11262306a36Sopenharmony_ci * 0x0040 - 12Mbits 11362306a36Sopenharmony_ci * 0x0080 - 18Mbits 11462306a36Sopenharmony_ci * 0x0100 - 22Mbits 11562306a36Sopenharmony_ci * 0x0200 - 24Mbits 11662306a36Sopenharmony_ci * 0x0400 - 36Mbits 11762306a36Sopenharmony_ci * 0x0800 - 48Mbits 11862306a36Sopenharmony_ci * 0x1000 - 54Mbits 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci __le16 rate; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci /* Time in us that a packet can spend in the target */ 12362306a36Sopenharmony_ci __le32 expiry_time; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci /* index of the TX queue used for this packet */ 12662306a36Sopenharmony_ci u8 xmit_queue; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /* Used to identify a packet */ 12962306a36Sopenharmony_ci u8 id; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci struct tx_control control; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* 13462306a36Sopenharmony_ci * The FW should cut the packet into fragments 13562306a36Sopenharmony_ci * of this size. 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_ci __le16 frag_threshold; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* Numbers of HW queue blocks to be allocated */ 14062306a36Sopenharmony_ci u8 num_mem_blocks; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci u8 reserved; 14362306a36Sopenharmony_ci} __packed; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cienum { 14662306a36Sopenharmony_ci TX_SUCCESS = 0, 14762306a36Sopenharmony_ci TX_DMA_ERROR = BIT(7), 14862306a36Sopenharmony_ci TX_DISABLED = BIT(6), 14962306a36Sopenharmony_ci TX_RETRY_EXCEEDED = BIT(5), 15062306a36Sopenharmony_ci TX_TIMEOUT = BIT(4), 15162306a36Sopenharmony_ci TX_KEY_NOT_FOUND = BIT(3), 15262306a36Sopenharmony_ci TX_ENCRYPT_FAIL = BIT(2), 15362306a36Sopenharmony_ci TX_UNAVAILABLE_PRIORITY = BIT(1), 15462306a36Sopenharmony_ci}; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cistruct tx_result { 15762306a36Sopenharmony_ci /* 15862306a36Sopenharmony_ci * Ownership synchronization between the host and 15962306a36Sopenharmony_ci * the firmware. If done_1 and done_2 are cleared, 16062306a36Sopenharmony_ci * owned by the FW (no info ready). 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci u8 done_1; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* same as double_buffer_desc->id */ 16562306a36Sopenharmony_ci u8 id; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci /* 16862306a36Sopenharmony_ci * Total air access duration consumed by this 16962306a36Sopenharmony_ci * packet, including all retries and overheads. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_ci u16 medium_usage; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */ 17462306a36Sopenharmony_ci u32 medium_delay; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* Time between host xfer and tx complete */ 17762306a36Sopenharmony_ci u32 fw_hnadling_time; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* The LS-byte of the last TKIP sequence number. */ 18062306a36Sopenharmony_ci u8 lsb_seq_num; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* Retry count */ 18362306a36Sopenharmony_ci u8 ack_failures; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci /* At which rate we got a ACK */ 18662306a36Sopenharmony_ci u16 rate; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci u16 reserved; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci /* TX_* */ 19162306a36Sopenharmony_ci u8 status; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* See done_1 */ 19462306a36Sopenharmony_ci u8 done_2; 19562306a36Sopenharmony_ci} __packed; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic inline int wl1251_tx_get_queue(int queue) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci switch (queue) { 20062306a36Sopenharmony_ci case 0: 20162306a36Sopenharmony_ci return QOS_AC_VO; 20262306a36Sopenharmony_ci case 1: 20362306a36Sopenharmony_ci return QOS_AC_VI; 20462306a36Sopenharmony_ci case 2: 20562306a36Sopenharmony_ci return QOS_AC_BE; 20662306a36Sopenharmony_ci case 3: 20762306a36Sopenharmony_ci return QOS_AC_BK; 20862306a36Sopenharmony_ci default: 20962306a36Sopenharmony_ci return QOS_AC_BE; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_civoid wl1251_tx_work(struct work_struct *work); 21462306a36Sopenharmony_civoid wl1251_tx_complete(struct wl1251 *wl); 21562306a36Sopenharmony_civoid wl1251_tx_flush(struct wl1251 *wl); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci#endif 218