xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/ampdu.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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