1 /* 2 * Copyright (c) 2015 South Silicon Valley Microelectronics Inc. 3 * Copyright (c) 2015 iComm Corporation 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * See the GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #ifndef _AMPDU_H_ 18 #define _AMPDU_H_ 19 #include <linux/version.h> 20 #include <ssv6200_common.h> 21 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) 22 #include "linux_2_6_35.h" 23 #endif 24 #define Enable_ampdu_debug_log (0) 25 #define Enable_AMPDU_Live_Time (0) 26 #define Enable_HW_AUTO_CRC_32 (1) 27 #define Enable_AMPDU_Rx (1) 28 #define Enable_AMPDU_Tx (1) 29 #define Enable_AMPDU_FW_Retry (1) 30 #define Enable_AMPDU_delay_work (1) 31 #define USE_FLUSH_RETRY 32 #define USE_AMPDU_TX_STATUS_ARRAY 33 #define SSV_AMPDU_FLOW_CONTROL 34 #define AMPDU_CHECK_SKB_SEQNO 35 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) 36 #define REPORT_TX_STATUS_DIRECTLY 37 #endif 38 #define SSV_AMPDU_aggr_num_max MAX_AGGR_NUM 39 #define SSV_AMPDU_seq_num_max (4096) 40 #define SSV_AMPDU_retry_counter_max (3) 41 #define SSV_AMPDU_tx_group_id_max (64) 42 #define SSV_AMPDU_MAX_SSN (4096) 43 #define SSV_AMPDU_BA_WINDOW_SIZE (64) 44 #define SSV_AMPDU_WINDOW_SIZE (64) 45 #define SSV_GET_MAX_AMPDU_SIZE(sh) (((sh)->tx_page_available/(sh)->ampdu_divider) << HW_MMU_PAGE_SHIFT) 46 #define SSV_AMPDU_FLOW_CONTROL_UPPER_BOUND (64) 47 #define SSV_AMPDU_FLOW_CONTROL_LOWER_BOUND (48) 48 #define SSV_AMPDU_timer_period (50) 49 #define SSV_AMPDU_TX_TIME_THRESHOLD (50) 50 #define SSV_AMPDU_MPDU_LIVE_TIME (SSV_AMPDU_retry_counter_max*8) 51 #define SSV_AMPDU_BA_TIME (50) 52 #define SSV_ILLEGAL_SN (0xffff) 53 #define AMPDU_BUFFER_SIZE (32*1024) 54 #define AMPDU_SIGNATURE (0x4E) 55 #define AMPDU_DELIMITER_LEN (4) 56 #define AMPDU_FCS_LEN (4) 57 #define AMPDU_RESERVED_LEN (3) 58 #define AMPDU_TX_NAV_MCS_567 (48) 59 #define SSV_SEQ_NUM_SHIFT (4) 60 #define SSV_RETRY_BIT_SHIFT (11) 61 #define IEEE80211_SEQ_SEQ_SHIFT (4) 62 #define IEEE80211_AMPDU_BA_LEN (34) 63 #define SSV6200_AMPDU_TRIGGER_INDEX 0 64 #define SSV_SN_STATUS_Release (0xaa) 65 #define SSV_SN_STATUS_Retry (0xbb) 66 #define SSV_SN_STATUS_Wait_BA (0xcc) 67 #define SSV_SN_STATUS_Discard (0xdd) 68 #define AMPDU_HCI_SEND_TAIL_WITH_FLOWCTRL (0) 69 #define AMPDU_HCI_SEND_HEAD_WITH_FLOWCTRL (1) 70 #define AMPDU_HCI_SEND_TAIL_WITHOUT_FLOWCTRL (2) 71 #define AMPDU_HCI_SEND_HEAD_WITHOUT_FLOWCTRL (3) 72 #define SSV_BAR_CTRL_ACK_POLICY_NORMAL (0x0000) 73 #define SSV_BAR_CTRL_CBMTID_COMPRESSED_BA (0x0004) 74 #define SSV_BAR_CTRL_TID_INFO_SHIFT (12) 75 #define AMPDU_STATE_START BIT(0) 76 #define AMPDU_STATE_OPERATION BIT(1) 77 #define AMPDU_STATE_STOP BIT(2) 78 typedef enum{ 79 AMPDU_REKEY_PAUSE_STOP=0, 80 AMPDU_REKEY_PAUSE_START, 81 AMPDU_REKEY_PAUSE_ONGOING, 82 AMPDU_REKEY_PAUSE_DEFER, 83 AMPDU_REKEY_PAUSE_HWKEY_SYNC, 84 }AMPDU_REKEY_PAUSE_STATE; 85 #define SSV_a_minus_b_in_c(a,b,c) (((a)>=(b))?((a)-(b)):((c)-(b)+(a))) 86 #define SSV_AMPDU_SN_a_minus_b(a,b) (SSV_a_minus_b_in_c((a), (b), SSV_AMPDU_seq_num_max)) 87 #define AMPDU_HCI_SEND(_sh,_sk,_q,_flag) (_sh)->hci.hci_ops->hci_tx((_sk), (_q), (_flag)) 88 #define AMPDU_HCI_Q_EMPTY(_sh,_q) (_sh)->hci.hci_ops->hci_txq_empty((_q)) 89 struct ampdu_hdr_st 90 { 91 u32 first_sn; 92 struct sk_buff_head mpdu_q; 93 u32 max_size; 94 u32 size; 95 struct AMPDU_TID_st *ampdu_tid; 96 u16 ssn[MAX_AGGR_NUM]; 97 u16 mpdu_num; 98 struct fw_rc_retry_params rates[SSV62XX_TX_MAX_RATES]; 99 struct ieee80211_sta *sta; 100 }; 101 enum AMPDU_TX_STATUS_E { 102 AMPDU_ST_NON_AMPDU, 103 AMPDU_ST_AGGREGATED, 104 AMPDU_ST_SENT, 105 AMPDU_ST_RETRY, 106 AMPDU_ST_DROPPED, 107 AMPDU_ST_DONE, 108 }; 109 typedef struct AMPDU_MIB_st 110 { 111 u32 ampdu_mib_mpdu_counter; 112 u32 ampdu_mib_retry_counter; 113 u32 ampdu_mib_ampdu_counter; 114 u32 ampdu_mib_aggr_retry_counter; 115 u32 ampdu_mib_bar_counter; 116 u32 ampdu_mib_discard_counter; 117 u32 ampdu_mib_total_BA_counter; 118 u32 ampdu_mib_BA_counter; 119 u32 ampdu_mib_pass_counter; 120 u32 ampdu_mib_dist[SSV_AMPDU_aggr_num_max + 1]; 121 } AMPDU_MIB; 122 typedef struct AMPDU_TID_st 123 { 124 struct list_head list; 125 volatile unsigned long timestamp; 126 u32 tidno; 127 u16 ac; 128 struct ieee80211_sta *sta; 129 u16 ssv_baw_size; 130 u8 agg_num_max; 131 u8 state; 132 #ifdef AMPDU_CHECK_SKB_SEQNO 133 u32 last_seqno; 134 #endif 135 struct sk_buff_head ampdu_skb_tx_queue; 136 spinlock_t ampdu_skb_tx_queue_lock; 137 struct sk_buff_head retry_queue; 138 struct sk_buff_head release_queue; 139 struct sk_buff *aggr_pkts[SSV_AMPDU_BA_WINDOW_SIZE]; 140 volatile u32 aggr_pkt_num; 141 volatile u16 ssv_baw_head; 142 spinlock_t pkt_array_lock; 143 #ifdef ENABLE_AGGREGATE_IN_TIME 144 struct sk_buff *cur_ampdu_pkt; 145 struct sk_buff_head early_aggr_ampdu_q; 146 u32 early_aggr_skb_num; 147 #endif 148 struct sk_buff_head ampdu_skb_wait_encry_queue; 149 u32 ampdu_mib_reset; 150 struct AMPDU_MIB_st mib; 151 #ifdef CONFIG_SSV6XXX_DEBUGFS 152 struct dentry *debugfs_dir; 153 struct sk_buff_head ba_q; 154 #endif 155 } AMPDU_TID, *p_AMPDU_TID; 156 typedef struct AMPDU_DELIMITER_st 157 { 158 u16 reserved:4; 159 u16 length:12; 160 u8 crc; 161 u8 signature; 162 } AMPDU_DELIMITER, *p_AMPDU_DELIMITER; 163 typedef struct AMPDU_BLOCKACK_st 164 { 165 u16 frame_control; 166 u16 duration; 167 u8 ra_addr[ETH_ALEN]; 168 u8 ta_addr[ETH_ALEN]; 169 u16 BA_ack_ploicy:1; 170 u16 multi_tid:1; 171 u16 compress_bitmap:1; 172 u16 reserved:9; 173 u16 tid_info:4; 174 u16 BA_fragment_sn:4; 175 u16 BA_ssn:12; 176 u32 BA_sn_bit_map[2]; 177 } AMPDU_BLOCKACK, *p_AMPDU_BLOCKACK; 178 struct ssv_bar { 179 unsigned short frame_control; 180 unsigned short duration; 181 unsigned char ra[6]; 182 unsigned char ta[6]; 183 unsigned short control; 184 unsigned short start_seq_num; 185 } __packed; 186 #if Enable_ampdu_debug_log 187 #define ampdu_db_log(format, args...) printk("~~~ampdu [%s:%d] "format, __FUNCTION__, __LINE__, ##args) 188 #define ampdu_db_log_simple(format, args...) printk(format, ##args) 189 #else 190 #define ampdu_db_log(...) do {} while (0) 191 #define ampdu_db_log_simple(...) do {} while (0) 192 #endif 193 #if Enable_AMPDU_delay_work 194 void ssv6200_ampdu_delayed_work_callback_func(struct work_struct *work); 195 #else 196 void ssv6200_ampdu_timer_callback_func(unsigned long data); 197 #endif 198 void ssv6200_ampdu_init(struct ieee80211_hw *hw); 199 void ssv6200_ampdu_deinit(struct ieee80211_hw *hw); 200 void ssv6200_ampdu_release_skb(struct sk_buff *skb, struct ieee80211_hw *hw); 201 void ssv6200_ampdu_tx_start(u16 tid, struct ieee80211_sta *sta, struct ieee80211_hw *hw, u16 *ssn); 202 void ssv6200_ampdu_tx_operation(u16 tid, struct ieee80211_sta *sta, struct ieee80211_hw *hw, u8 buffer_size); 203 void ssv6200_ampdu_tx_stop(u16 tid, struct ieee80211_sta *sta, struct ieee80211_hw *hw); 204 bool ssv6200_ampdu_tx_handler(struct ieee80211_hw *hw, struct sk_buff *skb); 205 u32 ssv6xxx_ampdu_flush(struct ieee80211_hw *hw); 206 void ssv6200_ampdu_timeout_tx (struct ieee80211_hw *hw); 207 struct cfg_host_event; 208 void ssv6200_ampdu_no_BA_handler(struct ieee80211_hw *hw, struct sk_buff *skb); 209 void ssv6200_ampdu_BA_handler(struct ieee80211_hw *hw, struct sk_buff *skb); 210 void ssv6200_ampdu_tx_update_state(void *priv, struct ieee80211_sta *sta, struct sk_buff *skb); 211 void ssv6200_ampdu_tx_add_sta(struct ieee80211_hw *hw, struct ieee80211_sta *sta); 212 void ssv6xxx_ampdu_postprocess_BA (struct ieee80211_hw *hw); 213 void ssv6xxx_ampdu_check_timeout (struct ieee80211_hw *hw); 214 void ssv6xxx_ampdu_sent (struct ieee80211_hw *hw, struct sk_buff *ampdu); 215 extern void ssv6xxx_set_ampdu_rx_add_work(struct work_struct *work); 216 extern void ssv6xxx_set_ampdu_rx_del_work(struct work_struct *work); 217 void ssv6xxx_mib_reset (struct ieee80211_hw *hw); 218 ssize_t ssv6xxx_mib_dump (struct ieee80211_hw *hw, char *mib_str, ssize_t length); 219 #if 0 220 void tx_work(struct work_struct *work); 221 void retry_work(struct work_struct *work); 222 #endif 223 void encry_work(struct work_struct *work); 224 void sync_hw_key_work(struct work_struct *work); 225 #endif 226