2019-05-29 16:57:50 -07:00
/* SPDX-License-Identifier: GPL-2.0-only */
2009-08-06 16:25:28 +03:00
/*
* This file is part of wl1271
*
* Copyright ( C ) 1998 - 2009 Texas Instruments . All rights reserved .
* Copyright ( C ) 2009 Nokia Corporation
*
* Contact : Luciano Coelho < luciano . coelho @ nokia . com >
*/
2010-11-08 11:20:10 +00:00
# ifndef __TX_H__
# define __TX_H__
2009-08-06 16:25:28 +03:00
# define TX_HW_MGMT_PKT_LIFETIME_TU 2000
2010-10-16 18:53:48 +02:00
# define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
2009-08-06 16:25:28 +03:00
# define TX_HW_ATTR_SAVE_RETRIES BIT(0)
# define TX_HW_ATTR_HEADER_PAD BIT(1)
# define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4))
# define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \
BIT ( 8 ) | BIT ( 9 ) )
# define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
# define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
2011-03-06 16:32:14 +02:00
# define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)
2012-01-31 17:54:42 +02:00
# define TX_HW_ATTR_HOST_ENCRYPT BIT(14)
2014-02-10 13:47:26 +02:00
# define TX_HW_ATTR_EAPOL_FRAME BIT(15)
2011-03-06 16:32:14 +02:00
2009-08-06 16:25:28 +03:00
# define TX_HW_ATTR_OFST_SAVE_RETRIES 0
# define TX_HW_ATTR_OFST_HEADER_PAD 1
# define TX_HW_ATTR_OFST_SESSION_COUNTER 2
# define TX_HW_ATTR_OFST_RATE_POLICY 5
# define TX_HW_ATTR_OFST_LAST_WORD_PAD 10
# define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12
# define TX_HW_RESULT_QUEUE_LEN 16
# define TX_HW_RESULT_QUEUE_LEN_MASK 0xf
# define WL1271_TX_ALIGN_TO 4
2012-02-02 12:22:09 +02:00
# define WL1271_EXTRA_SPACE_TKIP 4
# define WL1271_EXTRA_SPACE_AES 8
# define WL1271_EXTRA_SPACE_MAX 8
2009-08-06 16:25:28 +03:00
2011-03-06 16:32:14 +02:00
/* Used for management frames and dummy packets */
# define WL1271_TID_MGMT 7
2013-09-17 18:41:20 +03:00
/* stop a ROC for pending authentication reply after this time (ms) */
# define WLCORE_PEND_AUTH_ROC_TIMEOUT 1000
2011-03-06 16:32:08 +02:00
struct wl127x_tx_mem {
/*
* Number of extra memory blocks to allocate for this packet
* in addition to the number of blocks derived from the packet
* length .
*/
u8 extra_blocks ;
/*
* Total number of memory blocks allocated by the host for
* this packet . Must be equal or greater than the actual
* blocks number allocated by HW .
*/
u8 total_mem_blocks ;
} __packed ;
struct wl128x_tx_mem {
/*
* Total number of memory blocks allocated by the host for
* this packet .
*/
u8 total_mem_blocks ;
/*
* Number of extra bytes , at the end of the frame . the host
* uses this padding to complete each frame to integer number
* of SDIO blocks .
*/
u8 extra_bytes ;
} __packed ;
2012-05-10 12:13:18 +03:00
struct wl18xx_tx_mem {
/*
* Total number of memory blocks allocated by the host for
* this packet .
*/
u8 total_mem_blocks ;
/*
2012-05-13 14:53:40 +03:00
* control bits
2012-05-10 12:13:18 +03:00
*/
2012-05-13 14:53:40 +03:00
u8 ctrl ;
2012-05-10 12:13:18 +03:00
} __packed ;
2011-03-31 10:06:58 +02:00
/*
* On wl128x based devices , when TX packets are aggregated , each packet
* size must be aligned to the SDIO block size . The maximum block size
* is bounded by the type of the padded bytes field that is sent to the
* FW . Currently the type is u8 , so the maximum block size is 256 bytes .
*/
# define WL12XX_BUS_BLOCK_SIZE min(512u, \
( 1u < < ( 8 * sizeof ( ( ( struct wl128x_tx_mem * ) 0 ) - > extra_bytes ) ) ) )
2009-08-06 16:25:28 +03:00
struct wl1271_tx_hw_descr {
/* Length of packet in words, including descriptor+header+data */
2009-10-15 10:33:29 +03:00
__le16 length ;
2011-03-06 16:32:08 +02:00
union {
struct wl127x_tx_mem wl127x_mem ;
struct wl128x_tx_mem wl128x_mem ;
2012-05-10 12:13:18 +03:00
struct wl18xx_tx_mem wl18xx_mem ;
2011-03-06 16:32:08 +02:00
} __packed ;
2009-08-06 16:25:28 +03:00
/* Device time (in us) when the packet arrived to the driver */
2009-10-15 10:33:29 +03:00
__le32 start_time ;
2011-03-06 16:32:08 +02:00
/*
* Max delay in TUs until transmission . The last device time the
* packet can be transmitted is : start_time + ( 1024 * life_time )
*/
2009-10-15 10:33:29 +03:00
__le16 life_time ;
2009-08-06 16:25:28 +03:00
/* Bitwise fields - see TX_ATTR... definitions above. */
2009-10-15 10:33:29 +03:00
__le16 tx_attr ;
2009-08-06 16:25:28 +03:00
/* Packet identifier used also in the Tx-Result. */
u8 id ;
/* The packet TID value (as User-Priority) */
u8 tid ;
2011-08-14 13:17:11 +03:00
/* host link ID (HLID) */
u8 hlid ;
2012-05-10 12:13:27 +03:00
union {
u8 wl12xx_reserved ;
/*
* bit 0 - > 0 = udp , 1 = tcp
* bit 1 : 7 - > IP header offset
*/
u8 wl18xx_checksum_data ;
} __packed ;
2010-06-02 18:10:09 +00:00
} __packed ;
2009-08-06 16:25:28 +03:00
enum wl1271_tx_hw_res_status {
TX_SUCCESS = 0 ,
TX_HW_ERROR = 1 ,
TX_DISABLED = 2 ,
TX_RETRY_EXCEEDED = 3 ,
TX_TIMEOUT = 4 ,
TX_KEY_NOT_FOUND = 5 ,
TX_PEER_NOT_FOUND = 6 ,
2011-08-14 13:17:11 +03:00
TX_SESSION_MISMATCH = 7 ,
TX_LINK_NOT_VALID = 8 ,
2009-08-06 16:25:28 +03:00
} ;
struct wl1271_tx_hw_res_descr {
/* Packet Identifier - same value used in the Tx descriptor.*/
u8 id ;
/* The status of the transmission, indicating success or one of
several possible reasons for failure . */
u8 status ;
/* Total air access duration including all retrys and overheads.*/
2009-10-15 10:33:29 +03:00
__le16 medium_usage ;
2009-08-06 16:25:28 +03:00
/* The time passed from host xfer to Tx-complete.*/
2009-10-15 10:33:29 +03:00
__le32 fw_handling_time ;
2009-08-06 16:25:28 +03:00
/* Total media delay
( from 1 st EDCA AIFS counter until TX Complete ) . */
2009-10-15 10:33:29 +03:00
__le32 medium_delay ;
2009-08-06 16:25:28 +03:00
/* LS-byte of last TKIP seq-num (saved per AC for recovery). */
2011-06-26 10:36:02 +03:00
u8 tx_security_sequence_number_lsb ;
2009-08-06 16:25:28 +03:00
/* Retry count - number of transmissions without successful ACK.*/
u8 ack_failures ;
/* The rate that succeeded getting ACK
( Valid only if status = SUCCESS ) . */
u8 rate_class_index ;
/* for 4-byte alignment. */
u8 spare ;
2010-06-02 18:10:09 +00:00
} __packed ;
2009-08-06 16:25:28 +03:00
struct wl1271_tx_hw_res_if {
2009-10-15 10:33:29 +03:00
__le32 tx_result_fw_counter ;
__le32 tx_result_host_counter ;
2009-08-06 16:25:28 +03:00
struct wl1271_tx_hw_res_descr tx_results_queue [ TX_HW_RESULT_QUEUE_LEN ] ;
2010-06-02 18:10:09 +00:00
} __packed ;
2009-08-06 16:25:28 +03:00
2012-05-18 07:46:38 +03:00
enum wlcore_queue_stop_reason {
WLCORE_QUEUE_STOP_REASON_WATERMARK ,
WLCORE_QUEUE_STOP_REASON_FW_RESTART ,
2012-05-18 07:46:39 +03:00
WLCORE_QUEUE_STOP_REASON_FLUSH ,
2012-05-18 07:46:40 +03:00
WLCORE_QUEUE_STOP_REASON_SPARE_BLK , /* 18xx specific */
2012-05-18 07:46:38 +03:00
} ;
2010-02-18 13:25:41 +02:00
static inline int wl1271_tx_get_queue ( int queue )
{
switch ( queue ) {
case 0 :
return CONF_TX_AC_VO ;
case 1 :
return CONF_TX_AC_VI ;
case 2 :
return CONF_TX_AC_BE ;
case 3 :
return CONF_TX_AC_BK ;
default :
return CONF_TX_AC_BE ;
}
}
2012-11-30 00:48:03 +02:00
static inline
int wlcore_tx_get_mac80211_queue ( struct wl12xx_vif * wlvif , int queue )
2011-06-24 13:03:37 +03:00
{
2012-11-30 00:48:03 +02:00
int mac_queue = wlvif - > hw_queue_base ;
2011-06-24 13:03:37 +03:00
switch ( queue ) {
case CONF_TX_AC_VO :
2012-11-30 00:48:03 +02:00
return mac_queue + 0 ;
2011-06-24 13:03:37 +03:00
case CONF_TX_AC_VI :
2012-11-30 00:48:03 +02:00
return mac_queue + 1 ;
2011-06-24 13:03:37 +03:00
case CONF_TX_AC_BE :
2012-11-30 00:48:03 +02:00
return mac_queue + 2 ;
2011-06-24 13:03:37 +03:00
case CONF_TX_AC_BK :
2012-11-30 00:48:03 +02:00
return mac_queue + 3 ;
2011-06-24 13:03:37 +03:00
default :
2012-11-30 00:48:03 +02:00
return mac_queue + 2 ;
2011-06-24 13:03:37 +03:00
}
}
2011-07-07 14:25:23 +03:00
static inline int wl1271_tx_total_queue_count ( struct wl1271 * wl )
{
int i , count = 0 ;
for ( i = 0 ; i < NUM_TX_QUEUES ; i + + )
count + = wl - > tx_queue_count [ i ] ;
return count ;
}
2009-08-06 16:25:28 +03:00
void wl1271_tx_work ( struct work_struct * work ) ;
2012-06-18 13:21:55 +03:00
int wlcore_tx_work_locked ( struct wl1271 * wl ) ;
2012-06-18 12:31:16 +03:00
int wlcore_tx_complete ( struct wl1271 * wl ) ;
2011-10-10 10:12:51 +02:00
void wl12xx_tx_reset_wlvif ( struct wl1271 * wl , struct wl12xx_vif * wlvif ) ;
2012-05-18 07:46:38 +03:00
void wl12xx_tx_reset ( struct wl1271 * wl ) ;
2009-08-06 16:25:28 +03:00
void wl1271_tx_flush ( struct wl1271 * wl ) ;
2016-04-12 15:56:15 +02:00
u8 wlcore_rate_to_idx ( struct wl1271 * wl , u8 rate , enum nl80211_band band ) ;
2011-09-19 13:51:42 +03:00
u32 wl1271_tx_enabled_rates_get ( struct wl1271 * wl , u32 rate_set ,
2016-04-12 15:56:15 +02:00
enum nl80211_band rate_band ) ;
2011-09-19 13:51:42 +03:00
u32 wl1271_tx_min_rate_get ( struct wl1271 * wl , u32 rate_set ) ;
2011-10-10 10:12:51 +02:00
u8 wl12xx_tx_get_hlid ( struct wl1271 * wl , struct wl12xx_vif * wlvif ,
2012-07-27 10:11:33 +03:00
struct sk_buff * skb , struct ieee80211_sta * sta ) ;
2011-02-23 00:22:26 +02:00
void wl1271_tx_reset_link_queues ( struct wl1271 * wl , u8 hlid ) ;
void wl1271_handle_tx_low_watermark ( struct wl1271 * wl ) ;
2011-08-25 12:43:12 +03:00
bool wl12xx_is_dummy_packet ( struct wl1271 * wl , struct sk_buff * skb ) ;
2011-10-10 10:12:59 +02:00
void wl12xx_rearm_rx_streaming ( struct wl1271 * wl , unsigned long * active_hlids ) ;
2011-12-12 11:41:44 +02:00
unsigned int wlcore_calc_packet_alignment ( struct wl1271 * wl ,
unsigned int packet_length ) ;
2012-05-10 12:13:25 +03:00
void wl1271_free_tx_id ( struct wl1271 * wl , int id ) ;
2012-11-30 00:48:03 +02:00
void wlcore_stop_queue_locked ( struct wl1271 * wl , struct wl12xx_vif * wlvif ,
u8 queue , enum wlcore_queue_stop_reason reason ) ;
void wlcore_stop_queue ( struct wl1271 * wl , struct wl12xx_vif * wlvif , u8 queue ,
2012-05-18 07:46:38 +03:00
enum wlcore_queue_stop_reason reason ) ;
2012-11-30 00:48:03 +02:00
void wlcore_wake_queue ( struct wl1271 * wl , struct wl12xx_vif * wlvif , u8 queue ,
2012-05-18 07:46:38 +03:00
enum wlcore_queue_stop_reason reason ) ;
void wlcore_stop_queues ( struct wl1271 * wl ,
enum wlcore_queue_stop_reason reason ) ;
void wlcore_wake_queues ( struct wl1271 * wl ,
enum wlcore_queue_stop_reason reason ) ;
2012-11-30 00:48:03 +02:00
bool wlcore_is_queue_stopped_by_reason ( struct wl1271 * wl ,
struct wl12xx_vif * wlvif , u8 queue ,
2012-05-18 07:46:38 +03:00
enum wlcore_queue_stop_reason reason ) ;
2012-11-28 11:42:44 +02:00
bool
wlcore_is_queue_stopped_by_reason_locked ( struct wl1271 * wl ,
struct wl12xx_vif * wlvif ,
u8 queue ,
enum wlcore_queue_stop_reason reason ) ;
bool wlcore_is_queue_stopped_locked ( struct wl1271 * wl , struct wl12xx_vif * wlvif ,
u8 queue ) ;
2009-08-06 16:25:28 +03:00
2011-08-25 12:43:17 +03:00
/* from main.c */
2011-10-05 11:56:05 +02:00
void wl1271_free_sta ( struct wl1271 * wl , struct wl12xx_vif * wlvif , u8 hlid ) ;
2012-03-03 22:18:00 +02:00
void wl12xx_rearm_tx_watchdog_locked ( struct wl1271 * wl ) ;
2011-08-25 12:43:17 +03:00
2009-08-06 16:25:28 +03:00
# endif