Linux Audio

Check our new training course

Loading...
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * This file is part of wl1271
  4 *
  5 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
  6 * Copyright (C) 2009 Nokia Corporation
  7 *
  8 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  9 */
 10
 11#ifndef __TX_H__
 12#define __TX_H__
 13
 14#define TX_HW_MGMT_PKT_LIFETIME_TU       2000
 15#define TX_HW_AP_MODE_PKT_LIFETIME_TU    8000
 16
 17#define TX_HW_ATTR_SAVE_RETRIES          BIT(0)
 18#define TX_HW_ATTR_HEADER_PAD            BIT(1)
 19#define TX_HW_ATTR_SESSION_COUNTER       (BIT(2) | BIT(3) | BIT(4))
 20#define TX_HW_ATTR_RATE_POLICY           (BIT(5) | BIT(6) | BIT(7) | \
 21					  BIT(8) | BIT(9))
 22#define TX_HW_ATTR_LAST_WORD_PAD         (BIT(10) | BIT(11))
 23#define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
 24#define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
 25#define TX_HW_ATTR_HOST_ENCRYPT          BIT(14)
 26#define TX_HW_ATTR_EAPOL_FRAME           BIT(15)
 27
 28#define TX_HW_ATTR_OFST_SAVE_RETRIES     0
 29#define TX_HW_ATTR_OFST_HEADER_PAD       1
 30#define TX_HW_ATTR_OFST_SESSION_COUNTER  2
 31#define TX_HW_ATTR_OFST_RATE_POLICY      5
 32#define TX_HW_ATTR_OFST_LAST_WORD_PAD    10
 33#define TX_HW_ATTR_OFST_TX_CMPLT_REQ     12
 34
 35#define TX_HW_RESULT_QUEUE_LEN           16
 36#define TX_HW_RESULT_QUEUE_LEN_MASK      0xf
 37
 38#define WL1271_TX_ALIGN_TO 4
 39#define WL1271_EXTRA_SPACE_TKIP 4
 40#define WL1271_EXTRA_SPACE_AES  8
 41#define WL1271_EXTRA_SPACE_MAX  8
 42
 43/* Used for management frames and dummy packets */
 44#define WL1271_TID_MGMT 7
 45
 46/* stop a ROC for pending authentication reply after this time (ms) */
 47#define WLCORE_PEND_AUTH_ROC_TIMEOUT     1000
 48
 49struct wl127x_tx_mem {
 50	/*
 51	 * Number of extra memory blocks to allocate for this packet
 52	 * in addition to the number of blocks derived from the packet
 53	 * length.
 54	 */
 55	u8 extra_blocks;
 56	/*
 57	 * Total number of memory blocks allocated by the host for
 58	 * this packet. Must be equal or greater than the actual
 59	 * blocks number allocated by HW.
 60	 */
 61	u8 total_mem_blocks;
 62} __packed;
 63
 64struct wl128x_tx_mem {
 65	/*
 66	 * Total number of memory blocks allocated by the host for
 67	 * this packet.
 68	 */
 69	u8 total_mem_blocks;
 70	/*
 71	 * Number of extra bytes, at the end of the frame. the host
 72	 * uses this padding to complete each frame to integer number
 73	 * of SDIO blocks.
 74	 */
 75	u8 extra_bytes;
 76} __packed;
 77
 78struct wl18xx_tx_mem {
 79	/*
 80	 * Total number of memory blocks allocated by the host for
 81	 * this packet.
 82	 */
 83	u8 total_mem_blocks;
 84
 85	/*
 86	 * control bits
 87	 */
 88	u8 ctrl;
 89} __packed;
 90
 91/*
 92 * On wl128x based devices, when TX packets are aggregated, each packet
 93 * size must be aligned to the SDIO block size. The maximum block size
 94 * is bounded by the type of the padded bytes field that is sent to the
 95 * FW. Currently the type is u8, so the maximum block size is 256 bytes.
 96 */
 97#define WL12XX_BUS_BLOCK_SIZE min(512u,	\
 98	    (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
 99
100struct wl1271_tx_hw_descr {
101	/* Length of packet in words, including descriptor+header+data */
102	__le16 length;
103	union {
104		struct wl127x_tx_mem wl127x_mem;
105		struct wl128x_tx_mem wl128x_mem;
106		struct wl18xx_tx_mem wl18xx_mem;
107	} __packed;
108	/* Device time (in us) when the packet arrived to the driver */
109	__le32 start_time;
110	/*
111	 * Max delay in TUs until transmission. The last device time the
112	 * packet can be transmitted is: start_time + (1024 * life_time)
113	 */
114	__le16 life_time;
115	/* Bitwise fields - see TX_ATTR... definitions above. */
116	__le16 tx_attr;
117	/* Packet identifier used also in the Tx-Result. */
118	u8 id;
119	/* The packet TID value (as User-Priority) */
120	u8 tid;
121	/* host link ID (HLID) */
122	u8 hlid;
123
124	union {
125		u8 wl12xx_reserved;
126
127		/*
128		 * bit 0   -> 0 = udp, 1 = tcp
129		 * bit 1:7 -> IP header offset
130		 */
131		u8 wl18xx_checksum_data;
132	} __packed;
133} __packed;
134
135enum wl1271_tx_hw_res_status {
136	TX_SUCCESS          = 0,
137	TX_HW_ERROR         = 1,
138	TX_DISABLED         = 2,
139	TX_RETRY_EXCEEDED   = 3,
140	TX_TIMEOUT          = 4,
141	TX_KEY_NOT_FOUND    = 5,
142	TX_PEER_NOT_FOUND   = 6,
143	TX_SESSION_MISMATCH = 7,
144	TX_LINK_NOT_VALID   = 8,
145};
146
147struct wl1271_tx_hw_res_descr {
148	/* Packet Identifier - same value used in the Tx descriptor.*/
149	u8 id;
150	/* The status of the transmission, indicating success or one of
151	   several possible reasons for failure. */
152	u8 status;
153	/* Total air access duration including all retrys and overheads.*/
154	__le16 medium_usage;
155	/* The time passed from host xfer to Tx-complete.*/
156	__le32 fw_handling_time;
157	/* Total media delay
158	   (from 1st EDCA AIFS counter until TX Complete). */
159	__le32 medium_delay;
160	/* LS-byte of last TKIP seq-num (saved per AC for recovery). */
161	u8 tx_security_sequence_number_lsb;
162	/* Retry count - number of transmissions without successful ACK.*/
163	u8 ack_failures;
164	/* The rate that succeeded getting ACK
165	   (Valid only if status=SUCCESS). */
166	u8 rate_class_index;
167	/* for 4-byte alignment. */
168	u8 spare;
169} __packed;
170
171struct wl1271_tx_hw_res_if {
172	__le32 tx_result_fw_counter;
173	__le32 tx_result_host_counter;
174	struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
175} __packed;
176
177enum wlcore_queue_stop_reason {
178	WLCORE_QUEUE_STOP_REASON_WATERMARK,
179	WLCORE_QUEUE_STOP_REASON_FW_RESTART,
180	WLCORE_QUEUE_STOP_REASON_FLUSH,
181	WLCORE_QUEUE_STOP_REASON_SPARE_BLK, /* 18xx specific */
182};
183
184static inline int wl1271_tx_get_queue(int queue)
185{
186	switch (queue) {
187	case 0:
188		return CONF_TX_AC_VO;
189	case 1:
190		return CONF_TX_AC_VI;
191	case 2:
192		return CONF_TX_AC_BE;
193	case 3:
194		return CONF_TX_AC_BK;
195	default:
196		return CONF_TX_AC_BE;
197	}
198}
199
200static inline
201int wlcore_tx_get_mac80211_queue(struct wl12xx_vif *wlvif, int queue)
202{
203	int mac_queue = wlvif->hw_queue_base;
204
205	switch (queue) {
206	case CONF_TX_AC_VO:
207		return mac_queue + 0;
208	case CONF_TX_AC_VI:
209		return mac_queue + 1;
210	case CONF_TX_AC_BE:
211		return mac_queue + 2;
212	case CONF_TX_AC_BK:
213		return mac_queue + 3;
214	default:
215		return mac_queue + 2;
216	}
217}
218
219static inline int wl1271_tx_total_queue_count(struct wl1271 *wl)
220{
221	int i, count = 0;
222
223	for (i = 0; i < NUM_TX_QUEUES; i++)
224		count += wl->tx_queue_count[i];
225
226	return count;
227}
228
229void wl1271_tx_work(struct work_struct *work);
230int wlcore_tx_work_locked(struct wl1271 *wl);
231int wlcore_tx_complete(struct wl1271 *wl);
232void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif);
233void wl12xx_tx_reset(struct wl1271 *wl);
234void wl1271_tx_flush(struct wl1271 *wl);
235u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum nl80211_band band);
236u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
237				enum nl80211_band rate_band);
238u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
239u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
240		      struct sk_buff *skb, struct ieee80211_sta *sta);
241void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
242void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
243bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
244void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
245unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
246					  unsigned int packet_length);
247void wl1271_free_tx_id(struct wl1271 *wl, int id);
248void wlcore_stop_queue_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
249			      u8 queue, enum wlcore_queue_stop_reason reason);
250void wlcore_stop_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
251		       enum wlcore_queue_stop_reason reason);
252void wlcore_wake_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
253		       enum wlcore_queue_stop_reason reason);
254void wlcore_stop_queues(struct wl1271 *wl,
255			enum wlcore_queue_stop_reason reason);
256void wlcore_wake_queues(struct wl1271 *wl,
257			enum wlcore_queue_stop_reason reason);
258bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
259				       struct wl12xx_vif *wlvif, u8 queue,
260				       enum wlcore_queue_stop_reason reason);
261bool
262wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
263					 struct wl12xx_vif *wlvif,
264					 u8 queue,
265					 enum wlcore_queue_stop_reason reason);
266bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
267				    u8 queue);
268
269/* from main.c */
270void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
271void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl);
272
273#endif