xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/ampdu.c (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 #include <linux/version.h>
18 #include <ssv6200.h>
19 #include "dev.h"
20 #include "ap.h"
21 #include "sec.h"
22 #include "ssv_rc_common.h"
23 #include "ssv_ht_rc.h"
24 extern struct ieee80211_ops ssv6200_ops;
25 #define BA_WAIT_TIMEOUT (800)
26 #define AMPDU_BA_FRAME_LEN (68)
27 #define ampdu_skb_hdr(skb) ((struct ieee80211_hdr*)((u8*)((skb)->data)+AMPDU_DELIMITER_LEN))
28 #define ampdu_skb_ssn(skb) ((ampdu_skb_hdr(skb)->seq_ctrl)>>SSV_SEQ_NUM_SHIFT)
29 #define ampdu_hdr_ssn(hdr) ((hdr)->seq_ctrl>>SSV_SEQ_NUM_SHIFT)
30 #if 0
31 #define prn_aggr_dbg(fmt,...) \
32     do { \
33         printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
34     } while (0)
35 #else
36 #undef prn_aggr_dbg
37 #define prn_aggr_dbg(fmt,...)
38 #endif
39 #if 0
40 #define prn_aggr_err(fmt,...) \
41     do { \
42         printk(KERN_ERR fmt, ##__VA_ARGS__);\
43     } while (0)
44 #else
void_func(const char * fmt,...)45 static void void_func(const char *fmt, ...)
46 {
47 }
48 #define prn_aggr_err(fmt,...) \
49     do { \
50         void_func(KERN_ERR fmt, ##__VA_ARGS__);\
51     } while (0)
52 #endif
53 #define get_tid_aggr_len(agg_len,tid_data) \
54     ({ \
55         u32 agg_max_num = (tid_data)->agg_num_max; \
56         u32 to_agg_len = (agg_len); \
57         (agg_len >= agg_max_num) ? agg_max_num : to_agg_len; \
58     })
59 #define INDEX_PKT_BY_SSN(tid,ssn) \
60     ((tid)->aggr_pkts[(ssn) % SSV_AMPDU_BA_WINDOW_SIZE])
61 #define NEXT_PKT_SN(sn) \
62     ({ (sn + 1) % SSV_AMPDU_MAX_SSN; })
63 #define INC_PKT_SN(sn) \
64     ({ \
65         sn = NEXT_PKT_SN(sn); \
66         sn; \
67     })
68 #ifdef CONFIG_SSV6XXX_DEBUGFS
69 static ssize_t ampdu_tx_mib_dump(struct ssv_sta_priv_data *ssv_sta_priv,
70      char *mib_str, ssize_t length);
71 static int _dump_ba_skb(char *buf, int buf_size, struct sk_buff *ba_skb);
72 #endif
73 static struct sk_buff* _aggr_retry_mpdu (struct ssv_softc *sc,
74                                          struct AMPDU_TID_st *cur_AMPDU_TID,
75                                          struct sk_buff_head *retry_queue,
76                                          u32 max_aggr_len);
77 static int _dump_BA_notification (char *buf,
78                                   struct ampdu_ba_notify_data *ba_notification);
79 static struct sk_buff *_alloc_ampdu_skb (struct ssv_softc *sc,
80                                          struct AMPDU_TID_st *ampdu_tid,
81                                          u32 len);
82 static bool _sync_ampdu_pkt_arr (struct AMPDU_TID_st *ampdu_tid,
83                                  struct sk_buff *ampdu_skb, bool retry);
84 static void _put_mpdu_to_ampdu (struct sk_buff *ampdu,
85                                 struct sk_buff *mpdu);
86 static void _add_ampdu_txinfo (struct ssv_softc *sc, struct sk_buff *ampdu_skb);
87 static u32 _flush_early_ampdu_q (struct ssv_softc *sc,
88                                  struct AMPDU_TID_st *ampdu_tid);
89 static bool _is_skb_q_empty (struct ssv_softc *sc, struct sk_buff *skb);
90 static void _aggr_ampdu_tx_q (struct ieee80211_hw *hw,
91                               struct AMPDU_TID_st *ampdu_tid);
92 static void _queue_early_ampdu (struct ssv_softc *sc,
93                                 struct AMPDU_TID_st *ampdu_tid,
94                                 struct sk_buff *ampdu_skb);
95 static int _mark_skb_retry (struct SKB_info_st *skb_info, struct sk_buff *skb);
96 #ifdef CONFIG_DEBUG_SKB_TIMESTAMP
cal_duration_of_ampdu(struct sk_buff * ampdu_skb,int stage)97 unsigned int cal_duration_of_ampdu(struct sk_buff *ampdu_skb, int stage)
98 {
99  unsigned int timeout;
100     SKB_info *mpdu_skb_info;
101     u16 ssn = 0;
102     struct sk_buff *mpdu = NULL;
103     struct ampdu_hdr_st *ampdu_hdr = NULL;
104  ktime_t current_ktime;
105  ampdu_hdr = (struct ampdu_hdr_st *) ampdu_skb->head;
106  ssn = ampdu_hdr->ssn[0];
107  mpdu = INDEX_PKT_BY_SSN(ampdu_hdr->ampdu_tid, ssn);
108  if (mpdu == NULL)
109   return 0;
110  mpdu_skb_info = (SKB_info *) (mpdu->head);
111  current_ktime = ktime_get();
112  timeout = (unsigned int)ktime_to_ms(ktime_sub(current_ktime, mpdu_skb_info->timestamp));
113  if (timeout > SKB_DURATION_TIMEOUT_MS) {
114   if (stage == SKB_DURATION_STAGE_TO_SDIO)
115    printk("*a_to_sdio: %ums\n", timeout);
116   else if (stage == SKB_DURATION_STAGE_TX_ENQ)
117    printk("*a_to_txenqueue: %ums\n", timeout);
118   else
119    printk("*a_in_hwq: %ums\n", timeout);
120  }
121  return timeout;
122 }
123 #endif
_cal_ampdu_delm_half_crc(u8 value)124 static u8 _cal_ampdu_delm_half_crc (u8 value)
125 {
126     u32 c32 = value, v32 = value;
127     c32 ^= (v32 >> 1) | (v32 << 7);
128     c32 ^= (v32 >> 2);
129     if (v32 & 2)
130         c32 ^= (0xC0);
131     c32 ^= ((v32 << 4) & 0x30);
132     return (u8) c32;
133 }
_cal_ampdu_delm_crc(u8 * pointer)134 static u8 _cal_ampdu_delm_crc (u8 *pointer)
135 {
136     u8 crc = 0xCF;
137     crc ^= _cal_ampdu_delm_half_crc(*pointer++);
138     crc = _cal_ampdu_delm_half_crc(crc) ^ _cal_ampdu_delm_half_crc(*pointer);
139     return ~crc;
140 }
ssv6200_ampdu_add_delimiter_and_crc32(struct sk_buff * mpdu)141 static bool ssv6200_ampdu_add_delimiter_and_crc32 (struct sk_buff *mpdu)
142 {
143     p_AMPDU_DELIMITER delimiter_p;
144     struct ieee80211_hdr *mpdu_hdr;
145     int ret;
146     u32 orig_mpdu_len = mpdu->len;
147     u32 pad = (4 - (orig_mpdu_len % 4)) % 4;
148     mpdu_hdr = (struct ieee80211_hdr*) (mpdu->data);
149     mpdu_hdr->duration_id = AMPDU_TX_NAV_MCS_567;
150     ret = skb_padto(mpdu, mpdu->len + (AMPDU_FCS_LEN + pad));
151     if (ret)
152     {
153         printk(KERN_ERR "Failed to extand skb for aggregation.");
154         return false;
155     }
156     skb_put(mpdu, AMPDU_FCS_LEN + pad);
157     skb_push(mpdu, AMPDU_DELIMITER_LEN);
158     delimiter_p = (p_AMPDU_DELIMITER) mpdu->data;
159     delimiter_p->reserved = 0;
160     delimiter_p->length = orig_mpdu_len + AMPDU_FCS_LEN;
161     delimiter_p->signature = AMPDU_SIGNATURE;
162     delimiter_p->crc = _cal_ampdu_delm_crc((u8*) (delimiter_p));
163     return true;
164 }
ssv6200_ampdu_hw_init(struct ieee80211_hw * hw)165 static void ssv6200_ampdu_hw_init (struct ieee80211_hw *hw)
166 {
167     struct ssv_softc *sc = hw->priv;
168     u32 temp32;
169     SMAC_REG_READ(sc->sh, ADR_MTX_MISC_EN, &temp32);
170     temp32 |= (0x1 << MTX_AMPDU_CRC_AUTO_SFT);
171     SMAC_REG_WRITE(sc->sh, ADR_MTX_MISC_EN, temp32);
172     SMAC_REG_READ(sc->sh, ADR_MTX_MISC_EN, &temp32);
173 }
_sync_ampdu_pkt_arr(struct AMPDU_TID_st * ampdu_tid,struct sk_buff * ampdu,bool retry)174 bool _sync_ampdu_pkt_arr (struct AMPDU_TID_st *ampdu_tid, struct sk_buff *ampdu,
175                           bool retry)
176 {
177     struct sk_buff **pp_aggr_pkt;
178     struct sk_buff *p_aggr_pkt;
179     unsigned long flags;
180     struct ampdu_hdr_st *ampdu_hdr = (struct ampdu_hdr_st *) ampdu->head;
181     struct sk_buff *mpdu;
182     u32 first_ssn = SSV_ILLEGAL_SN;
183     u32 old_aggr_pkt_num;
184     u32 old_baw_head;
185     u32 sync_num = skb_queue_len(&ampdu_hdr->mpdu_q);
186     bool ret = true;
187     spin_lock_irqsave(&ampdu_tid->pkt_array_lock, flags);
188     old_baw_head = ampdu_tid->ssv_baw_head;
189     old_aggr_pkt_num = ampdu_tid->aggr_pkt_num;
190     ampdu_tid->mib.ampdu_mib_ampdu_counter += 1;
191     ampdu_tid->mib.ampdu_mib_dist[sync_num] += 1;
192     do
193     {
194         if (!retry)
195         {
196             ampdu_tid->mib.ampdu_mib_mpdu_counter += sync_num;
197             mpdu = skb_peek_tail(&ampdu_hdr->mpdu_q);
198             if (mpdu == NULL)
199             {
200                 ret = false;
201                 break;
202             }
203             else
204             {
205                 u32 ssn = ampdu_skb_ssn(mpdu);
206                 p_aggr_pkt = INDEX_PKT_BY_SSN(ampdu_tid, ssn);
207                 if (p_aggr_pkt != NULL)
208                 {
209                     char msg[256];
210                     u32 sn = ampdu_skb_ssn(mpdu);
211                     skb_queue_walk(&ampdu_hdr->mpdu_q, mpdu)
212                     {
213                         sn = ampdu_skb_ssn(mpdu);
214                         sprintf(msg, " %d", sn);
215                     }
216                     prn_aggr_err("ES %d -> %d (%s)\n",
217                                  ssn, ampdu_skb_ssn(p_aggr_pkt), msg);
218                     ret = false;
219                     break;
220                 }
221             }
222         }
223         else
224             ampdu_tid->mib.ampdu_mib_aggr_retry_counter += 1;
225         skb_queue_walk(&ampdu_hdr->mpdu_q, mpdu)
226         {
227             u32 ssn = ampdu_skb_ssn(mpdu);
228             SKB_info *mpdu_skb_info = (SKB_info *) (mpdu->head);
229             if (first_ssn == SSV_ILLEGAL_SN)
230                 first_ssn = ssn;
231             pp_aggr_pkt = &INDEX_PKT_BY_SSN(ampdu_tid, ssn);
232             p_aggr_pkt = *pp_aggr_pkt;
233             *pp_aggr_pkt = mpdu;
234             if (!retry)
235                 ampdu_tid->aggr_pkt_num++;
236             mpdu_skb_info->ampdu_tx_status = AMPDU_ST_AGGREGATED;
237             if (ampdu_tid->ssv_baw_head == SSV_ILLEGAL_SN)
238             {
239                 ampdu_tid->ssv_baw_head = ssn;
240             }
241             if ((p_aggr_pkt != NULL) && (mpdu != p_aggr_pkt))
242                 prn_aggr_err(
243                         "%d -> %d (H%d, N%d, Q%d)\n",
244                         ssn, ampdu_skb_ssn(p_aggr_pkt), old_baw_head, old_aggr_pkt_num, sync_num);
245         }
246     } while (0);
247     spin_unlock_irqrestore(&ampdu_tid->pkt_array_lock, flags);
248     #if 1
249     {
250     u32 page_count = (ampdu->len + SSV6200_ALLOC_RSVD);
251     if (page_count & HW_MMU_PAGE_MASK)
252         page_count = (page_count >> HW_MMU_PAGE_SHIFT) + 1;
253     else page_count = page_count >> HW_MMU_PAGE_SHIFT;
254     if (page_count > (SSV6200_PAGE_TX_THRESHOLD / 2))
255         printk(KERN_ERR "AMPDU requires pages %d(%d-%d-%d) exceeds resource limit %d.\n",
256                page_count, ampdu->len, ampdu_hdr->max_size, ampdu_hdr->size,
257                (SSV6200_PAGE_TX_THRESHOLD / 2));
258     }
259     #endif
260     return ret;
261 }
_aggr_retry_mpdu(struct ssv_softc * sc,struct AMPDU_TID_st * ampdu_tid,struct sk_buff_head * retry_queue,u32 max_aggr_len)262 struct sk_buff* _aggr_retry_mpdu (struct ssv_softc *sc,
263                                   struct AMPDU_TID_st *ampdu_tid,
264                                   struct sk_buff_head *retry_queue,
265                                   u32 max_aggr_len)
266 {
267     struct sk_buff *retry_mpdu;
268     struct sk_buff *new_ampdu_skb;
269     u32 num_retry_mpdu;
270     u32 temp_i;
271     u32 total_skb_size;
272     unsigned long flags;
273     u16 head_ssn = ampdu_tid->ssv_baw_head;
274     struct ampdu_hdr_st *ampdu_hdr;
275 #if 0
276     if (cur_AMPDU_TID->ssv_baw_head == SSV_ILLEGAL_SN)
277     {
278         struct sk_buff *skb = skb_peek(ampdu_skb_retry_queue);
279         prn_aggr_err("Rr %d\n", (skb == NULL) ? (-1) : ampdu_skb_ssn(skb));
280         return NULL;
281     }
282 #else
283     BUG_ON(head_ssn == SSV_ILLEGAL_SN);
284 #endif
285     num_retry_mpdu = skb_queue_len(retry_queue);
286     if (num_retry_mpdu == 0)
287         return NULL;
288     new_ampdu_skb = _alloc_ampdu_skb(sc, ampdu_tid, max_aggr_len);
289     if (new_ampdu_skb == 0)
290         return NULL;
291     ampdu_hdr = (struct ampdu_hdr_st *)new_ampdu_skb->head;
292     total_skb_size = 0;
293     spin_lock_irqsave(&retry_queue->lock, flags);
294     for (temp_i = 0; temp_i < ampdu_tid->agg_num_max; temp_i++)
295     {
296         struct ieee80211_hdr *mpdu_hdr;
297         u16 mpdu_sn;
298         u16 diff;
299         u32 new_total_skb_size;
300         retry_mpdu = skb_peek(retry_queue);
301         if (retry_mpdu == NULL)
302         {
303             break;
304         }
305         mpdu_hdr = ampdu_skb_hdr(retry_mpdu);
306         mpdu_sn = ampdu_hdr_ssn(mpdu_hdr);
307         diff = SSV_AMPDU_SN_a_minus_b(head_ssn, mpdu_sn);
308         if ((head_ssn != SSV_ILLEGAL_SN)
309             && (diff > 0)
310             && (diff <= ampdu_tid->ssv_baw_size))
311         {
312             struct SKB_info_st *skb_info;
313             prn_aggr_err("Z. release skb (s %d, h %d, d %d)\n",
314                          mpdu_sn, head_ssn, diff);
315             skb_info = (struct SKB_info_st *) (retry_mpdu->head);
316             skb_info->ampdu_tx_status = AMPDU_ST_DROPPED;
317             ampdu_tid->mib.ampdu_mib_discard_counter++;
318             continue;
319         }
320         new_total_skb_size = total_skb_size + retry_mpdu->len;
321         if (new_total_skb_size > ampdu_hdr->max_size)
322             break;
323         total_skb_size = new_total_skb_size;
324 #if 0
325             if (ampdu_skb_retry_queue != NULL)
326             prn_aggr_err("R %d\n", SerialNumber);
327 #endif
328         retry_mpdu = __skb_dequeue(retry_queue);
329         _put_mpdu_to_ampdu(new_ampdu_skb, retry_mpdu);
330         ampdu_tid->mib.ampdu_mib_retry_counter++;
331     }
332     ampdu_tid->mib.ampdu_mib_aggr_retry_counter += 1;
333     ampdu_tid->mib.ampdu_mib_dist[temp_i] += 1;
334     spin_unlock_irqrestore(&retry_queue->lock, flags);
335 #if 0
336     {
337     struct ampdu_hdr_st *ampdu_hdr = (struct ampdu_hdr_st *)new_ampdu_skb->head;
338     retry_mpdu = skb_peek(&ampdu_hdr->mpdu_q);
339     dev_alert(sc->dev, "rA %d - %d\n", ampdu_skb_ssn(retry_mpdu),
340               skb_queue_len(&ampdu_hdr->mpdu_q));
341     }
342 #endif
343     if (ampdu_hdr->mpdu_num == 0) {
344            dev_kfree_skb_any(new_ampdu_skb);
345            return NULL;
346        }
347     return new_ampdu_skb;
348 }
_add_ampdu_txinfo(struct ssv_softc * sc,struct sk_buff * ampdu_skb)349 static void _add_ampdu_txinfo (struct ssv_softc *sc, struct sk_buff *ampdu_skb)
350 {
351     struct ssv6200_tx_desc *tx_desc;
352     ssv6xxx_add_txinfo(sc, ampdu_skb);
353     tx_desc = (struct ssv6200_tx_desc *) ampdu_skb->data;
354     tx_desc->tx_report = 1;
355 #if 0
356     tx_desc->len = ampdu_skb->len;
357     tx_desc->c_type = M2_TXREQ;
358     tx_desc->f80211 = 1;
359     tx_desc->ht = 1;
360     tx_desc->qos = 1;
361     tx_desc->use_4addr = 0;
362     tx_desc->security = 0;
363     tx_desc->more_data = 0;
364     tx_desc->stype_b5b4 = 0;
365     tx_desc->extra_info = 0;
366     tx_desc->hdr_offset = sc->sh->cfg.txpb_offset;;
367     tx_desc->frag = 0;
368     tx_desc->unicast = 1;
369     tx_desc->hdr_len = 0;
370     tx_desc->RSVD_4 = 0;
371     tx_desc->tx_burst = 0;
372     tx_desc->ack_policy = 1;
373     tx_desc->aggregation = 1;
374     tx_desc->RSVD_1 = 0;
375     tx_desc->do_rts_cts = 0;
376     tx_desc->reason = 0;
377     tx_desc->payload_offset = tx_desc->hdr_offset + tx_desc->hdr_len;
378     tx_desc->RSVD_4 = 0;
379     tx_desc->RSVD_2 = 0;
380     tx_desc->fCmdIdx = 0;
381     tx_desc->wsid = 0;
382     tx_desc->txq_idx = 0;
383     tx_desc->TxF_ID = 0;
384     tx_desc->rts_cts_nav = 0;
385     tx_desc->frame_consume_time = 0;
386     tx_desc->crate_idx=0;
387     tx_desc->drate_idx = 22;
388     tx_desc->dl_length = 56;
389     tx_desc->RSVD_3 = 0;
390 #endif
391 #if 0
392     if(ampdu_skb != 0)
393     {
394         u32 temp_i;
395         u8* temp8_p = (u8*)ampdu_skb->data;
396         ampdu_db_log("print txinfo.\n");
397         for(temp_i=0; temp_i < 24; temp_i++)
398         {
399             ampdu_db_log_simple("%02x",*(u8*)(temp8_p + temp_i));
400             if(((temp_i+1) % 4) == 0)
401             {
402                 ampdu_db_log_simple("\n");
403             }
404         }
405         ampdu_db_log_simple("\n");
406     }
407 #endif
408 #if 0
409     if(ampdu_skb != 0)
410     {
411         u32 temp_i;
412         u8* temp8_p = (u8*)ampdu_skb->data;
413         ampdu_db_log("print all skb.\n");
414         for(temp_i=0; temp_i < ampdu_skb->len; temp_i++)
415         {
416             ampdu_db_log_simple("%02x",*(u8*)(temp8_p + temp_i));
417             if(((temp_i+1) % 4) == 0)
418             {
419                 ampdu_db_log_simple("\n");
420             }
421         }
422         ampdu_db_log_simple("\n");
423     }
424 #endif
425 }
_send_hci_skb(struct ssv_softc * sc,struct sk_buff * skb,u32 tx_flag)426 void _send_hci_skb (struct ssv_softc *sc, struct sk_buff *skb, u32 tx_flag)
427 {
428     struct ssv6200_tx_desc *tx_desc = (struct ssv6200_tx_desc *)skb->data;
429     int ret = AMPDU_HCI_SEND(sc->sh, skb, tx_desc->txq_idx, tx_flag);
430 #if 1
431     if ((tx_desc->txq_idx > 3) && (ret <= 0))
432     {
433         prn_aggr_err("BUG!! %d %d\n", tx_desc->txq_idx, ret);
434     }
435 #else
436     BUG_ON(tx_desc->txq_idx>3 && ret<=0);
437 #endif
438 }
ssv6200_ampdu_add_txinfo_and_send_HCI(struct ssv_softc * sc,struct sk_buff * ampdu_skb,u32 tx_flag)439 static void ssv6200_ampdu_add_txinfo_and_send_HCI (struct ssv_softc *sc,
440                                                    struct sk_buff *ampdu_skb,
441                                                    u32 tx_flag)
442 {
443     _add_ampdu_txinfo(sc, ampdu_skb);
444     _send_hci_skb(sc, ampdu_skb, tx_flag);
445 }
ssv6200_ampdu_send_retry(struct ieee80211_hw * hw,AMPDU_TID * cur_ampdu_tid,struct sk_buff_head * ampdu_skb_retry_queue_p,bool send_aggr_tx)446 static void ssv6200_ampdu_send_retry (
447         struct ieee80211_hw *hw, AMPDU_TID *cur_ampdu_tid,
448         struct sk_buff_head *ampdu_skb_retry_queue_p, bool send_aggr_tx)
449 {
450     struct ssv_softc *sc = hw->priv;
451     struct sk_buff *ampdu_retry_skb;
452     u32 ampdu_skb_retry_queue_len;
453     u32 max_agg_len;
454     u16 lowest_rate;
455     struct fw_rc_retry_params rates[SSV62XX_TX_MAX_RATES];
456     ampdu_skb_retry_queue_len = skb_queue_len(ampdu_skb_retry_queue_p);
457     if (ampdu_skb_retry_queue_len == 0)
458         return;
459     ampdu_retry_skb = skb_peek(ampdu_skb_retry_queue_p);
460     lowest_rate = ssv62xx_ht_rate_update(ampdu_retry_skb, sc, rates);
461     max_agg_len = ampdu_max_transmit_length[lowest_rate];
462     if (max_agg_len > 0)
463     {
464         u32 cur_ampdu_max_size = SSV_GET_MAX_AMPDU_SIZE(sc->sh);
465         if (max_agg_len >= cur_ampdu_max_size)
466             max_agg_len = cur_ampdu_max_size;
467         while (ampdu_skb_retry_queue_len > 0)
468         {
469             struct sk_buff *retry_mpdu = skb_peek(ampdu_skb_retry_queue_p);
470             SKB_info *mpdu_skb_info = (SKB_info *)(retry_mpdu->head);
471             mpdu_skb_info->lowest_rate = lowest_rate;
472             memcpy(mpdu_skb_info->rates, rates, sizeof(rates));
473             ampdu_retry_skb = _aggr_retry_mpdu(sc, cur_ampdu_tid, ampdu_skb_retry_queue_p,
474                                                max_agg_len);
475             if (ampdu_retry_skb != NULL)
476             {
477                 _sync_ampdu_pkt_arr(cur_ampdu_tid, ampdu_retry_skb, true);
478                 ssv6200_ampdu_add_txinfo_and_send_HCI(sc, ampdu_retry_skb,
479                                                       AMPDU_HCI_SEND_HEAD_WITHOUT_FLOWCTRL);
480             }
481             else
482             {
483                 prn_aggr_err("AMPDU retry failed.\n");
484                 return;
485             }
486             ampdu_skb_retry_queue_len = skb_queue_len(ampdu_skb_retry_queue_p);
487         }
488     }
489     else
490     {
491         struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
492         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(ampdu_retry_skb);
493         memcpy(rates, info->control.rates, sizeof(info->control.rates));
494         while ((ampdu_retry_skb = __skb_dequeue_tail(ampdu_skb_retry_queue_p)) != NULL)
495         {
496             struct ieee80211_tx_info *info = IEEE80211_SKB_CB(ampdu_retry_skb);
497             info->flags &= ~IEEE80211_TX_CTL_AMPDU;
498             memcpy(info->control.rates, rates, sizeof(info->control.rates));
499             ssv6xxx_update_txinfo(sc, ampdu_retry_skb);
500             _send_hci_skb(sc, ampdu_retry_skb, AMPDU_HCI_SEND_HEAD_WITHOUT_FLOWCTRL);
501         }
502     }
503 }
ssv6200_ampdu_init(struct ieee80211_hw * hw)504 void ssv6200_ampdu_init (struct ieee80211_hw *hw)
505 {
506     struct ssv_softc *sc = hw->priv;
507     ssv6200_ampdu_hw_init(hw);
508     sc->tx.ampdu_tx_group_id = 0;
509 #ifdef USE_ENCRYPT_WORK
510     INIT_WORK(&sc->ampdu_tx_encry_work, encry_work);
511     INIT_WORK(&sc->sync_hwkey_work, sync_hw_key_work);
512 #endif
513 }
ssv6200_ampdu_deinit(struct ieee80211_hw * hw)514 void ssv6200_ampdu_deinit (struct ieee80211_hw *hw)
515 {
516 }
ssv6200_ampdu_release_skb(struct sk_buff * skb,struct ieee80211_hw * hw)517 void ssv6200_ampdu_release_skb (struct sk_buff *skb, struct ieee80211_hw *hw)
518 {
519 #if LINUX_VERSION_CODE >= 0x030400
520     ieee80211_free_txskb(hw, skb);
521 #else
522     dev_kfree_skb_any(skb);
523 #endif
524 }
525 #ifdef CONFIG_SSV6XXX_DEBUGFS
526 struct mib_dump_data {
527     char *prt_buff;
528     size_t buff_size;
529     size_t prt_len;
530 };
531 #define AMPDU_TX_MIB_SUMMARY_BUF_SIZE (4096)
ampdu_tx_mib_summary_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)532 static ssize_t ampdu_tx_mib_summary_read (struct file *file,
533                                           char __user *user_buf, size_t count,
534                                           loff_t *ppos)
535 {
536     struct ssv_sta_priv_data *ssv_sta_priv =
537             (struct ssv_sta_priv_data *) file->private_data;
538     char *summary_buf = kzalloc(AMPDU_TX_MIB_SUMMARY_BUF_SIZE, GFP_KERNEL);
539     ssize_t summary_size;
540     ssize_t ret;
541     if (!summary_buf)
542         return -ENOMEM;
543     summary_size = ampdu_tx_mib_dump(ssv_sta_priv, summary_buf,
544                                      AMPDU_TX_MIB_SUMMARY_BUF_SIZE);
545     ret = simple_read_from_buffer(user_buf, count, ppos, summary_buf,
546                                   summary_size);
547     kfree(summary_buf);
548     return ret;
549 }
ampdu_tx_mib_summary_open(struct inode * inode,struct file * file)550 static int ampdu_tx_mib_summary_open (struct inode *inode, struct file *file)
551 {
552     file->private_data = inode->i_private;
553     return 0;
554 }
555 static const struct file_operations mib_summary_fops = { .read =
556         ampdu_tx_mib_summary_read, .open = ampdu_tx_mib_summary_open, };
ampdu_tx_tid_window_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)557 static ssize_t ampdu_tx_tid_window_read (struct file *file,
558                                           char __user *user_buf, size_t count,
559                                           loff_t *ppos)
560 {
561     struct AMPDU_TID_st *ampdu_tid = (struct AMPDU_TID_st *)file->private_data;
562     char *summary_buf = kzalloc(AMPDU_TX_MIB_SUMMARY_BUF_SIZE, GFP_KERNEL);
563     ssize_t ret;
564     char *prn_ptr = summary_buf;
565     int prt_size;
566     int buf_size = AMPDU_TX_MIB_SUMMARY_BUF_SIZE;
567     int i;
568     struct sk_buff *ba_skb, *tmp_ba_skb;
569     if (!summary_buf)
570         return -ENOMEM;
571     prt_size = snprintf(prn_ptr, buf_size, "\nWMM_TID %d:\n"
572                         "\tWindow:",
573                         ampdu_tid->tidno);
574     prn_ptr += prt_size;
575     buf_size -= prt_size;
576     for (i = 0; i < SSV_AMPDU_BA_WINDOW_SIZE; i++)
577     {
578         struct sk_buff *skb = ampdu_tid->aggr_pkts[i];
579         if ((i % 8) == 0)
580         {
581             prt_size = snprintf(prn_ptr, buf_size, "\n\t\t");
582             prn_ptr += prt_size;
583             buf_size -= prt_size;
584         }
585         if (skb == NULL)
586             prt_size = snprintf(prn_ptr, buf_size, " %s", "NULL ");
587         else
588         {
589             struct SKB_info_st *skb_info = (struct SKB_info_st *)(skb->head);
590             const char status_symbol[] = {'N',
591                                           'A',
592                                           'S',
593                                           'R',
594                                           'P',
595                                           'D'};
596             prt_size = snprintf(prn_ptr, buf_size, " %4d%c", ampdu_skb_ssn(skb),
597                                 ( (skb_info->ampdu_tx_status <= AMPDU_ST_DONE)
598                                  ? status_symbol[skb_info->ampdu_tx_status]
599                                  : 'X'));
600         }
601         prn_ptr += prt_size;
602         buf_size -= prt_size;
603     }
604     prt_size = snprintf(prn_ptr, buf_size, "\n\tEarly aggregated #: %d\n", ampdu_tid->early_aggr_skb_num);
605     prn_ptr += prt_size;
606     buf_size -= prt_size;
607     prt_size = snprintf(prn_ptr, buf_size, "\tBAW skb #: %d\n", ampdu_tid->aggr_pkt_num);
608     prn_ptr += prt_size;
609     buf_size -= prt_size;
610     prt_size = snprintf(prn_ptr, buf_size, "\tBAW head: %d\n", ampdu_tid->ssv_baw_head);
611     prn_ptr += prt_size;
612     buf_size -= prt_size;
613     prt_size = snprintf(prn_ptr, buf_size, "\tState: %d\n", ampdu_tid->state);
614     prn_ptr += prt_size;
615     buf_size -= prt_size;
616     prt_size = snprintf(prn_ptr, buf_size, "\tBA:\n");
617     prn_ptr += prt_size;
618     buf_size -= prt_size;
619     skb_queue_walk_safe(&ampdu_tid->ba_q, ba_skb, tmp_ba_skb)
620     {
621         prt_size = _dump_ba_skb(prn_ptr, buf_size, ba_skb);
622         prn_ptr += prt_size;
623         buf_size -= prt_size;
624     }
625     buf_size = AMPDU_TX_MIB_SUMMARY_BUF_SIZE - buf_size;
626     ret = simple_read_from_buffer(user_buf, count, ppos, summary_buf,
627                                   buf_size);
628     kfree(summary_buf);
629     return ret;
630 }
ampdu_tx_tid_window_open(struct inode * inode,struct file * file)631 static int ampdu_tx_tid_window_open (struct inode *inode, struct file *file)
632 {
633     file->private_data = inode->i_private;
634     return 0;
635 }
636 static const struct file_operations tid_window_fops = { .read =
637         ampdu_tx_tid_window_read, .open = ampdu_tx_tid_window_open, };
ampdu_tx_mib_reset_open(struct inode * inode,struct file * file)638 static int ampdu_tx_mib_reset_open (struct inode *inode, struct file *file)
639 {
640     file->private_data = inode->i_private;
641     return 0;
642 }
ampdu_tx_mib_reset_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)643 static ssize_t ampdu_tx_mib_reset_read (struct file *file,
644                                         char __user *user_buf, size_t count,
645                                         loff_t *ppos)
646 {
647     char *reset_buf = kzalloc(64, GFP_KERNEL);
648     ssize_t ret;
649     u32 reset_size;
650     if (!reset_buf)
651         return -ENOMEM;
652     reset_size = snprintf(reset_buf, 63, "%d", 0);
653     ret = simple_read_from_buffer(user_buf, count, ppos, reset_buf,
654                                   reset_size);
655     kfree(reset_buf);
656     return ret;
657 }
ampdu_tx_mib_reset_write(struct file * file,const char __user * buffer,size_t count,loff_t * pos)658 static ssize_t ampdu_tx_mib_reset_write (struct file *file,
659                                          const char __user *buffer,
660                                          size_t count,
661                                          loff_t *pos)
662 {
663     struct AMPDU_TID_st *ampdu_tid = (struct AMPDU_TID_st *)file->private_data;
664     memset(&ampdu_tid->mib, 0, sizeof(struct AMPDU_MIB_st));
665     return count;
666 }
667 static const struct file_operations mib_reset_fops
668     = { .read = ampdu_tx_mib_reset_read,
669         .open = ampdu_tx_mib_reset_open,
670         .write = ampdu_tx_mib_reset_write};
ssv6200_ampdu_tx_init_debugfs(struct ssv_softc * sc,struct ssv_sta_priv_data * ssv_sta_priv)671 static void ssv6200_ampdu_tx_init_debugfs (
672         struct ssv_softc *sc, struct ssv_sta_priv_data *ssv_sta_priv)
673 {
674     struct ssv_sta_info *sta_info = ssv_sta_priv->sta_info;
675     int i;
676     struct dentry *sta_debugfs_dir = sta_info->debugfs_dir;
677     dev_info(sc->dev, "Creating AMPDU TX debugfs.\n");
678     if (sta_debugfs_dir == NULL)
679     {
680         dev_err(sc->dev, "No STA debugfs.\n");
681         return;
682     }
683     debugfs_create_file("ampdu_tx_summary", 00444, sta_debugfs_dir,
684                         ssv_sta_priv, &mib_summary_fops);
685     debugfs_create_u32("total_BA", 00644, sta_debugfs_dir,
686                        &ssv_sta_priv->ampdu_mib_total_BA_counter);
687     for (i = 0; i < WMM_TID_NUM; i++)
688     {
689         char debugfs_name[20];
690         struct dentry *ampdu_tx_debugfs_dir;
691         int j;
692         struct AMPDU_TID_st *ampdu_tid = &ssv_sta_priv->ampdu_tid[i];
693         struct AMPDU_MIB_st *ampdu_mib = &ampdu_tid->mib;
694         snprintf(debugfs_name, sizeof(debugfs_name), "ampdu_tx_%d", i);
695         ampdu_tx_debugfs_dir = debugfs_create_dir(debugfs_name,
696                                                   sta_debugfs_dir);
697         if (ampdu_tx_debugfs_dir == NULL)
698         {
699             dev_err(sc->dev,
700                     "Failed to create debugfs for AMPDU TX TID %d: %s\n", i,
701                     debugfs_name);
702             continue;
703         }
704         ssv_sta_priv->ampdu_tid[i].debugfs_dir = ampdu_tx_debugfs_dir;
705         debugfs_create_file("baw_status", 00444, ampdu_tx_debugfs_dir,
706                             ampdu_tid, &tid_window_fops);
707         debugfs_create_file("reset", 00644, ampdu_tx_debugfs_dir,
708                             ampdu_tid, &mib_reset_fops);
709         debugfs_create_u32("total", 00444, ampdu_tx_debugfs_dir,
710                            &ampdu_mib->ampdu_mib_ampdu_counter);
711         debugfs_create_u32("retry", 00444, ampdu_tx_debugfs_dir,
712                            &ampdu_mib->ampdu_mib_retry_counter);
713         debugfs_create_u32("aggr_retry", 00444, ampdu_tx_debugfs_dir,
714                            &ampdu_mib->ampdu_mib_aggr_retry_counter);
715         debugfs_create_u32("BAR", 00444, ampdu_tx_debugfs_dir,
716                            &ampdu_mib->ampdu_mib_bar_counter);
717         debugfs_create_u32("Discarded", 00444, ampdu_tx_debugfs_dir,
718                            &ampdu_mib->ampdu_mib_discard_counter);
719         debugfs_create_u32("BA", 00444, ampdu_tx_debugfs_dir,
720                            &ampdu_mib->ampdu_mib_BA_counter);
721         debugfs_create_u32("Pass", 00444, ampdu_tx_debugfs_dir,
722                            &ampdu_mib->ampdu_mib_pass_counter);
723         for (j = 0; j <= SSV_AMPDU_aggr_num_max; j++)
724         {
725             char dist_dbg_name[10];
726             snprintf(dist_dbg_name, sizeof(dist_dbg_name), "aggr_%d", j);
727             debugfs_create_u32(dist_dbg_name, 00444, ampdu_tx_debugfs_dir,
728                                &ampdu_mib->ampdu_mib_dist[j]);
729         }
730         skb_queue_head_init(&ssv_sta_priv->ampdu_tid[i].ba_q);
731     }
732 }
733 #endif
ssv6200_ampdu_tx_add_sta(struct ieee80211_hw * hw,struct ieee80211_sta * sta)734 void ssv6200_ampdu_tx_add_sta (struct ieee80211_hw *hw,
735                                struct ieee80211_sta *sta)
736 {
737     struct ssv_sta_priv_data *ssv_sta_priv;
738     struct ssv_softc *sc;
739     u32 temp_i;
740     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
741     sc = (struct ssv_softc *) hw->priv;
742     for (temp_i = 0; temp_i < WMM_TID_NUM; temp_i++)
743     {
744         ssv_sta_priv->ampdu_tid[temp_i].sta = sta;
745         ssv_sta_priv->ampdu_tid[temp_i].state = AMPDU_STATE_STOP;
746         spin_lock_init(
747                 &ssv_sta_priv->ampdu_tid[temp_i].ampdu_skb_tx_queue_lock);
748         spin_lock_init(&ssv_sta_priv->ampdu_tid[temp_i].pkt_array_lock);
749     }
750 #ifdef CONFIG_SSV6XXX_DEBUGFS
751     ssv6200_ampdu_tx_init_debugfs(sc, ssv_sta_priv);
752 #endif
753 }
ssv6200_ampdu_tx_start(u16 tid,struct ieee80211_sta * sta,struct ieee80211_hw * hw,u16 * ssn)754 void ssv6200_ampdu_tx_start (u16 tid, struct ieee80211_sta *sta,
755                              struct ieee80211_hw *hw, u16 *ssn)
756 {
757     struct ssv_softc *sc = hw->priv;
758     struct ssv_sta_priv_data *ssv_sta_priv;
759     struct AMPDU_TID_st *ampdu_tid;
760     int i;
761     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
762     ampdu_tid = &ssv_sta_priv->ampdu_tid[tid];
763     ampdu_tid->ssv_baw_head = SSV_ILLEGAL_SN;
764 #if 0
765     if (list_empty(&sc->tx.ampdu_tx_que))
766     {
767         sc->ampdu_rekey_pause = AMPDU_REKEY_PAUSE_STOP;
768     }
769 #endif
770 #ifdef DEBUG_AMPDU_FLUSH
771     printk(KERN_ERR "Adding %02X-%02X-%02X-%02X-%02X-%02X TID %d (%p).\n",
772             sta->addr[0], sta->addr[1], sta->addr[2],
773             sta->addr[3], sta->addr[4], sta->addr[5],
774             ampdu_tid->tidno, ampdu_tid);
775     {
776         int j;
777         for (j = 0; j <= MAX_TID; j++)
778         {
779             if (sc->tid[j] == 0)
780                 break;
781         }
782         if (j == MAX_TID)
783         {
784             printk(KERN_ERR "No room for new TID.\n");
785         }
786         else
787             sc->tid[j] = ampdu_tid;
788 }
789 #endif
790     list_add_tail_rcu(&ampdu_tid->list, &sc->tx.ampdu_tx_que);
791     skb_queue_head_init(&ampdu_tid->ampdu_skb_tx_queue);
792 #ifdef ENABLE_INCREMENTAL_AGGREGATION
793     skb_queue_head_init(&ampdu_tid->early_aggr_ampdu_q);
794     ampdu_tid->early_aggr_skb_num = 0;
795 #endif
796     skb_queue_head_init(&ampdu_tid->ampdu_skb_wait_encry_queue);
797     skb_queue_head_init(&ampdu_tid->retry_queue);
798     skb_queue_head_init(&ampdu_tid->release_queue);
799     for (i = 0;
800             i < (sizeof(ampdu_tid->aggr_pkts) / sizeof(ampdu_tid->aggr_pkts[0]));
801             i++)
802         ampdu_tid->aggr_pkts[i] = 0;
803     ampdu_tid->aggr_pkt_num = 0;
804 #ifdef ENABLE_AGGREGATE_IN_TIME
805     ampdu_tid->cur_ampdu_pkt = _alloc_ampdu_skb(sc, ampdu_tid, 0);
806 #endif
807 #ifdef AMPDU_CHECK_SKB_SEQNO
808     ssv_sta_priv->ampdu_tid[tid].last_seqno = (-1);
809 #endif
810     ssv_sta_priv->ampdu_mib_total_BA_counter = 0;
811     memset(&ssv_sta_priv->ampdu_tid[tid].mib, 0, sizeof(struct AMPDU_MIB_st));
812     ssv_sta_priv->ampdu_tid[tid].state = AMPDU_STATE_START;
813     #ifdef CONFIG_SSV6XXX_DEBUGFS
814     skb_queue_head_init(&ssv_sta_priv->ampdu_tid[tid].ba_q);
815     #endif
816 }
ssv6200_ampdu_tx_operation(u16 tid,struct ieee80211_sta * sta,struct ieee80211_hw * hw,u8 buffer_size)817 void ssv6200_ampdu_tx_operation (u16 tid, struct ieee80211_sta *sta,
818                                  struct ieee80211_hw *hw, u8 buffer_size)
819 {
820     struct ssv_sta_priv_data *ssv_sta_priv;
821     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
822     ssv_sta_priv->ampdu_tid[tid].tidno = tid;
823     ssv_sta_priv->ampdu_tid[tid].sta = sta;
824     ssv_sta_priv->ampdu_tid[tid].agg_num_max = MAX_AGGR_NUM;
825 #if 1
826     if (buffer_size > IEEE80211_MAX_AMPDU_BUF)
827     {
828         buffer_size = IEEE80211_MAX_AMPDU_BUF;
829     }
830     printk("ssv6200_ampdu_tx_operation:buffer_size=%d\n", buffer_size);
831     ssv_sta_priv->ampdu_tid[tid].ssv_baw_size = SSV_AMPDU_WINDOW_SIZE;
832 #else
833     ssv_sta_priv->ampdu_tid[tid].ssv_baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
834     if(buffer_size > IEEE80211_MAX_AMPDU_BUF)
835     {
836         buffer_size = IEEE80211_MAX_AMPDU_BUF;
837     }
838     if(ssv_sta_priv->ampdu_tid[tid].ssv_baw_size > buffer_size)
839     {
840         ssv_sta_priv->ampdu_tid[tid].ssv_baw_size = buffer_size;
841     }
842 #endif
843     ssv_sta_priv->ampdu_tid[tid].state = AMPDU_STATE_OPERATION;
844 }
_clear_mpdu_q(struct ieee80211_hw * hw,struct sk_buff_head * q,bool aggregated_mpdu)845 static void _clear_mpdu_q (struct ieee80211_hw *hw, struct sk_buff_head *q,
846                            bool aggregated_mpdu)
847 {
848     struct sk_buff *skb;
849     while (1)
850     {
851         skb = skb_dequeue(q);
852         if (!skb)
853             break;
854         if (aggregated_mpdu)
855             skb_pull(skb, AMPDU_DELIMITER_LEN);
856         ieee80211_tx_status(hw, skb);
857     }
858 }
ssv6200_ampdu_tx_stop(u16 tid,struct ieee80211_sta * sta,struct ieee80211_hw * hw)859 void ssv6200_ampdu_tx_stop (u16 tid, struct ieee80211_sta *sta,
860                             struct ieee80211_hw *hw)
861 {
862     struct ssv_softc *sc = hw->priv;
863     struct ssv_sta_priv_data *ssv_sta_priv;
864     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
865     if (ssv_sta_priv->ampdu_tid[tid].state == AMPDU_STATE_STOP)
866         return;
867     ssv_sta_priv->ampdu_tid[tid].state = AMPDU_STATE_STOP;
868     printk("ssv6200_ampdu_tx_stop\n");
869     if (!list_empty(&sc->tx.ampdu_tx_que))
870     {
871 #ifdef DEBUG_AMPDU_FLUSH
872         {
873             int j;
874             struct AMPDU_TID_st *ampdu_tid = &ssv_sta_priv->ampdu_tid[tid];
875             for (j = 0; j <= MAX_TID; j++)
876             {
877                 if (sc->tid[j] == ampdu_tid)
878                     break;
879             }
880             if (j == MAX_TID)
881             {
882                 printk(KERN_ERR "No TID found when deleting it.\n");
883             }
884             else
885                 sc->tid[j] = NULL;
886             printk(KERN_ERR "Deleting %02X-%02X-%02X-%02X-%02X-%02X TID %d (%p).\n",
887                    sta->addr[0], sta->addr[1], sta->addr[2],
888                    sta->addr[3], sta->addr[4], sta->addr[5],
889                    ampdu_tid->tidno, ampdu_tid);
890         }
891 #endif
892         list_del_rcu(&ssv_sta_priv->ampdu_tid[tid].list);
893     }
894     printk("clear tx q len=%d\n",
895            skb_queue_len(&ssv_sta_priv->ampdu_tid[tid].ampdu_skb_tx_queue));
896     _clear_mpdu_q(sc->hw, &ssv_sta_priv->ampdu_tid[tid].ampdu_skb_tx_queue,
897                   true);
898     printk("clear retry q len=%d\n",
899            skb_queue_len(&ssv_sta_priv->ampdu_tid[tid].retry_queue));
900     _clear_mpdu_q(sc->hw, &ssv_sta_priv->ampdu_tid[tid].retry_queue, true);
901 #ifdef USE_ENCRYPT_WORK
902     printk("clear encrypt q len=%d\n",skb_queue_len(&ssv_sta_priv->ampdu_tid[tid].ampdu_skb_wait_encry_queue));
903     _clear_mpdu_q(sc->hw, &ssv_sta_priv->ampdu_tid[tid].ampdu_skb_wait_encry_queue, false);
904 #endif
905 #ifdef ENABLE_AGGREGATE_IN_TIME
906     if (ssv_sta_priv->ampdu_tid[tid].cur_ampdu_pkt != NULL)
907     {
908         dev_kfree_skb_any(ssv_sta_priv->ampdu_tid[tid].cur_ampdu_pkt);
909         ssv_sta_priv->ampdu_tid[tid].cur_ampdu_pkt = NULL;
910     }
911 #endif
912     ssv6200_tx_flow_control((void *) sc,
913                             sc->tx.hw_txqid[ssv_sta_priv->ampdu_tid[tid].ac],
914                             false, 1000);
915 }
ssv6200_ampdu_tx_state_stop_func(struct ssv_softc * sc,struct ieee80211_sta * sta,struct sk_buff * skb,struct AMPDU_TID_st * cur_AMPDU_TID)916 static void ssv6200_ampdu_tx_state_stop_func (
917         struct ssv_softc *sc, struct ieee80211_sta *sta, struct sk_buff *skb,
918         struct AMPDU_TID_st *cur_AMPDU_TID)
919 {
920     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
921     u8 *skb_qos_ctl = ieee80211_get_qos_ctl(hdr);
922     u8 tid_no = skb_qos_ctl[0] & 0xf;
923     if ((sta->ht_cap.ht_supported == true)
924         && (!!(sc->sh->cfg.hw_caps & SSV6200_HW_CAP_AMPDU_TX)))
925     {
926 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)
927         ieee80211_start_tx_ba_session(sc->hw, (u8*)(sta->addr), (u16)tid_no);
928 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)
929         ieee80211_start_tx_ba_session(sta, tid_no);
930 #else
931         ieee80211_start_tx_ba_session(sta, tid_no, 0);
932 #endif
933         ampdu_db_log("start ampdu_tx(rc) : tid_no = %d\n", tid_no);
934     }
935 }
ssv6200_ampdu_tx_state_operation_func(struct ssv_softc * sc,struct ieee80211_sta * sta,struct sk_buff * skb,struct AMPDU_TID_st * cur_AMPDU_TID)936 static void ssv6200_ampdu_tx_state_operation_func (
937         struct ssv_softc *sc, struct ieee80211_sta *sta, struct sk_buff *skb,
938         struct AMPDU_TID_st *cur_AMPDU_TID)
939 {
940 #if 0
941     else if (sc->ampdu_rekey_pause == AMPDU_REKEY_PAUSE_ONGOING)
942     {
943         pause_ampdu = true;
944         printk("!!!ampdu_rekey_pause\n");
945     }
946 #endif
947 }
ssv6200_ampdu_tx_update_state(void * priv,struct ieee80211_sta * sta,struct sk_buff * skb)948 void ssv6200_ampdu_tx_update_state (void *priv, struct ieee80211_sta *sta,
949                                     struct sk_buff *skb)
950 {
951     struct ssv_softc *sc = (struct ssv_softc *) priv;
952     struct ssv_sta_priv_data *ssv_sta_priv =
953             (struct ssv_sta_priv_data *) sta->drv_priv;
954     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
955     u8 *skb_qos_ctl;
956     u8 tid_no;
957     {
958         skb_qos_ctl = ieee80211_get_qos_ctl(hdr);
959         tid_no = skb_qos_ctl[0] & 0xf;
960         switch (ssv_sta_priv->ampdu_tid[tid_no].state)
961         {
962             case AMPDU_STATE_STOP:
963                 ssv6200_ampdu_tx_state_stop_func(
964                         sc, sta, skb, &(ssv_sta_priv->ampdu_tid[tid_no]));
965                 break;
966             case AMPDU_STATE_START:
967                 break;
968             case AMPDU_STATE_OPERATION:
969                 ssv6200_ampdu_tx_state_operation_func(
970                         sc, sta, skb, &(ssv_sta_priv->ampdu_tid[tid_no]));
971                 break;
972             default:
973                 break;
974         }
975     }
976 }
_put_mpdu_to_ampdu(struct sk_buff * ampdu,struct sk_buff * mpdu)977 void _put_mpdu_to_ampdu (struct sk_buff *ampdu, struct sk_buff *mpdu)
978 {
979     bool is_empty_ampdu = (ampdu->len == 0);
980     unsigned char *data_dest;
981     struct ampdu_hdr_st *ampdu_hdr = (struct ampdu_hdr_st *) ampdu->head;
982     BUG_ON(skb_tailroom(ampdu) < mpdu->len);
983     data_dest = skb_tail_pointer(ampdu);
984     skb_put(ampdu, mpdu->len);
985     if (is_empty_ampdu)
986     {
987         struct ieee80211_tx_info *ampdu_info = IEEE80211_SKB_CB(ampdu);
988         struct ieee80211_tx_info *mpdu_info = IEEE80211_SKB_CB(mpdu);
989         SKB_info *mpdu_skb_info = (SKB_info *)(mpdu->head);
990         u32 max_size_for_rate = ampdu_max_transmit_length[mpdu_skb_info->lowest_rate];
991         BUG_ON(max_size_for_rate == 0);
992         memcpy(ampdu_info, mpdu_info, sizeof(struct ieee80211_tx_info));
993         skb_set_queue_mapping(ampdu, skb_get_queue_mapping(mpdu));
994         ampdu_hdr->first_sn = ampdu_skb_ssn(mpdu);
995         ampdu_hdr->sta = ((struct SKB_info_st *)mpdu->head)->sta;
996         if (ampdu_hdr->max_size > max_size_for_rate)
997             ampdu_hdr->max_size = max_size_for_rate;
998         memcpy(ampdu_hdr->rates, mpdu_skb_info->rates, sizeof(ampdu_hdr->rates));
999     }
1000     memcpy(data_dest, mpdu->data, mpdu->len);
1001     __skb_queue_tail(&ampdu_hdr->mpdu_q, mpdu);
1002     ampdu_hdr->ssn[ampdu_hdr->mpdu_num++] = ampdu_skb_ssn(mpdu);
1003     ampdu_hdr->size += mpdu->len;
1004     BUG_ON(ampdu_hdr->size > ampdu_hdr->max_size);
1005 }
_flush_early_ampdu_q(struct ssv_softc * sc,struct AMPDU_TID_st * ampdu_tid)1006 u32 _flush_early_ampdu_q (struct ssv_softc *sc, struct AMPDU_TID_st *ampdu_tid)
1007 {
1008     u32 flushed_ampdu = 0;
1009     unsigned long flags;
1010     struct sk_buff_head *early_aggr_ampdu_q = &ampdu_tid->early_aggr_ampdu_q;
1011     spin_lock_irqsave(&early_aggr_ampdu_q->lock, flags);
1012     while (skb_queue_len(early_aggr_ampdu_q))
1013     {
1014         struct sk_buff *head_ampdu;
1015         struct ampdu_hdr_st *head_ampdu_hdr;
1016         u32 ampdu_aggr_num;
1017         head_ampdu = skb_peek(early_aggr_ampdu_q);
1018         head_ampdu_hdr = (struct ampdu_hdr_st *) head_ampdu->head;
1019         ampdu_aggr_num = skb_queue_len(&head_ampdu_hdr->mpdu_q);
1020         if ((SSV_AMPDU_BA_WINDOW_SIZE - ampdu_tid->aggr_pkt_num)
1021             < ampdu_aggr_num)
1022             break;
1023         if (_sync_ampdu_pkt_arr(ampdu_tid, head_ampdu, false))
1024         {
1025             head_ampdu = __skb_dequeue(early_aggr_ampdu_q);
1026             ampdu_tid->early_aggr_skb_num -= ampdu_aggr_num;
1027 #ifdef SSV_AMPDU_FLOW_CONTROL
1028             if (ampdu_tid->early_aggr_skb_num
1029                 <= SSV_AMPDU_FLOW_CONTROL_LOWER_BOUND)
1030             {
1031                 ssv6200_tx_flow_control((void *) sc,
1032                                         sc->tx.hw_txqid[ampdu_tid->ac], false, 1000);
1033             }
1034 #endif
1035             if ((skb_queue_len(early_aggr_ampdu_q) == 0)
1036                 && (ampdu_tid->early_aggr_skb_num > 0))
1037             {
1038                 printk(KERN_ERR "Empty early Q w. %d.\n", ampdu_tid->early_aggr_skb_num);
1039             }
1040             spin_unlock_irqrestore(&early_aggr_ampdu_q->lock, flags);
1041             _send_hci_skb(sc, head_ampdu,
1042                           AMPDU_HCI_SEND_TAIL_WITHOUT_FLOWCTRL);
1043             spin_lock_irqsave(&early_aggr_ampdu_q->lock, flags);
1044             flushed_ampdu++;
1045         }
1046         else
1047             break;
1048     }
1049     spin_unlock_irqrestore(&early_aggr_ampdu_q->lock, flags);
1050     return flushed_ampdu;
1051 }
1052 volatile int max_aggr_num = 24;
_aggr_ampdu_tx_q(struct ieee80211_hw * hw,struct AMPDU_TID_st * ampdu_tid)1053 void _aggr_ampdu_tx_q (struct ieee80211_hw *hw, struct AMPDU_TID_st *ampdu_tid)
1054 {
1055     struct ssv_softc *sc = hw->priv;
1056     struct sk_buff *ampdu_skb = ampdu_tid->cur_ampdu_pkt;
1057     while (skb_queue_len(&ampdu_tid->ampdu_skb_tx_queue))
1058     {
1059         u32 aggr_len;
1060         struct sk_buff *mpdu_skb;
1061         struct ampdu_hdr_st *ampdu_hdr;
1062         bool is_aggr_full = false;
1063         if (ampdu_skb == NULL)
1064         {
1065             ampdu_skb = _alloc_ampdu_skb(sc, ampdu_tid, 0);
1066             if (ampdu_skb == NULL)
1067                 break;
1068             ampdu_tid->cur_ampdu_pkt = ampdu_skb;
1069         }
1070         ampdu_hdr = (struct ampdu_hdr_st *) ampdu_skb->head;
1071         aggr_len = skb_queue_len(&ampdu_hdr->mpdu_q);
1072         do
1073         {
1074             struct sk_buff_head *tx_q = &ampdu_tid->ampdu_skb_tx_queue;
1075             unsigned long flags;
1076             spin_lock_irqsave(&tx_q->lock, flags);
1077             mpdu_skb = skb_peek(&ampdu_tid->ampdu_skb_tx_queue);
1078             if (mpdu_skb == NULL)
1079             {
1080                 spin_unlock_irqrestore(&tx_q->lock, flags);
1081                 break;
1082             }
1083             if ((mpdu_skb->len + ampdu_hdr->size) > ampdu_hdr->max_size)
1084             {
1085                 is_aggr_full = true;
1086                 spin_unlock_irqrestore(&tx_q->lock, flags);
1087                 break;
1088             }
1089             mpdu_skb = __skb_dequeue(&ampdu_tid->ampdu_skb_tx_queue);
1090             spin_unlock_irqrestore(&tx_q->lock, flags);
1091             _put_mpdu_to_ampdu(ampdu_skb, mpdu_skb);
1092         } while (++aggr_len < max_aggr_num );
1093         if ( (is_aggr_full || (aggr_len >= max_aggr_num))
1094             || ( (aggr_len > 0)
1095                 && (skb_queue_len(&ampdu_tid->early_aggr_ampdu_q) == 0)
1096                 && (ampdu_tid->ssv_baw_head == SSV_ILLEGAL_SN)
1097                 && _is_skb_q_empty(sc, ampdu_skb)))
1098         {
1099             _add_ampdu_txinfo(sc, ampdu_skb);
1100             _queue_early_ampdu(sc, ampdu_tid, ampdu_skb);
1101             ampdu_tid->cur_ampdu_pkt = ampdu_skb = NULL;
1102         }
1103         _flush_early_ampdu_q(sc, ampdu_tid);
1104     }
1105 }
_queue_early_ampdu(struct ssv_softc * sc,struct AMPDU_TID_st * ampdu_tid,struct sk_buff * ampdu_skb)1106 void _queue_early_ampdu (struct ssv_softc *sc, struct AMPDU_TID_st *ampdu_tid,
1107                          struct sk_buff *ampdu_skb)
1108 {
1109     unsigned long flags;
1110     struct ampdu_hdr_st *ampdu_hdr = (struct ampdu_hdr_st *) ampdu_skb->head;
1111     spin_lock_irqsave(&ampdu_tid->early_aggr_ampdu_q.lock, flags);
1112     __skb_queue_tail(&ampdu_tid->early_aggr_ampdu_q, ampdu_skb);
1113     ampdu_tid->early_aggr_skb_num += skb_queue_len(&ampdu_hdr->mpdu_q);
1114 #ifdef SSV_AMPDU_FLOW_CONTROL
1115     if (ampdu_tid->early_aggr_skb_num >= SSV_AMPDU_FLOW_CONTROL_UPPER_BOUND)
1116     {
1117         ssv6200_tx_flow_control((void *) sc, sc->tx.hw_txqid[ampdu_tid->ac],
1118                                 true, 1000);
1119     }
1120 #endif
1121     spin_unlock_irqrestore(&ampdu_tid->early_aggr_ampdu_q.lock, flags);
1122 }
_flush_mpdu(struct ssv_softc * sc,struct ieee80211_sta * sta)1123 void _flush_mpdu (struct ssv_softc *sc, struct ieee80211_sta *sta)
1124 {
1125     unsigned long flags;
1126     struct ssv_sta_priv_data *ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
1127     int i;
1128     for (i = 0; i < (sizeof(ssv_sta_priv->ampdu_tid) / sizeof(ssv_sta_priv->ampdu_tid[0])); i++)
1129     {
1130         struct AMPDU_TID_st *ampdu_tid = &ssv_sta_priv->ampdu_tid[i];
1131         struct sk_buff_head *early_aggr_ampdu_q;
1132         struct sk_buff *ampdu;
1133         struct ampdu_hdr_st *ampdu_hdr;
1134         struct sk_buff_head *mpdu_q;
1135         struct sk_buff *mpdu;
1136         if (ampdu_tid->state != AMPDU_STATE_OPERATION)
1137             continue;
1138         early_aggr_ampdu_q = &ampdu_tid->early_aggr_ampdu_q;
1139         spin_lock_irqsave(&early_aggr_ampdu_q->lock, flags);
1140         while ((ampdu = __skb_dequeue(early_aggr_ampdu_q)) != NULL)
1141         {
1142             ampdu_hdr = (struct ampdu_hdr_st *)ampdu->head;
1143             mpdu_q = &ampdu_hdr->mpdu_q;
1144             spin_unlock_irqrestore(&early_aggr_ampdu_q->lock, flags);
1145             while ((mpdu = __skb_dequeue(mpdu_q)) != NULL)
1146             {
1147                 _send_hci_skb(sc, mpdu, AMPDU_HCI_SEND_TAIL_WITHOUT_FLOWCTRL);
1148             }
1149             ssv6200_ampdu_release_skb(ampdu, sc->hw);
1150             spin_lock_irqsave(&early_aggr_ampdu_q->lock, flags);
1151         }
1152         if (ampdu_tid->cur_ampdu_pkt != NULL)
1153         {
1154             ampdu_hdr = (struct ampdu_hdr_st *)ampdu_tid->cur_ampdu_pkt->head;
1155             mpdu_q = &ampdu_hdr->mpdu_q;
1156             spin_unlock_irqrestore(&early_aggr_ampdu_q->lock, flags);
1157             while ((mpdu = __skb_dequeue(mpdu_q)) != NULL)
1158             {
1159                 _send_hci_skb(sc, mpdu, AMPDU_HCI_SEND_TAIL_WITHOUT_FLOWCTRL);
1160             }
1161             ssv6200_ampdu_release_skb(ampdu_tid->cur_ampdu_pkt, sc->hw);
1162             spin_lock_irqsave(&early_aggr_ampdu_q->lock, flags);
1163             ampdu_tid->cur_ampdu_pkt = NULL;
1164         }
1165         spin_unlock_irqrestore(&early_aggr_ampdu_q->lock, flags);
1166     }
1167 }
ssv6200_ampdu_tx_handler(struct ieee80211_hw * hw,struct sk_buff * skb)1168 bool ssv6200_ampdu_tx_handler (struct ieee80211_hw *hw, struct sk_buff *skb)
1169 {
1170     struct ssv_softc *sc = hw->priv;
1171     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1172 #ifdef REPORT_TX_STATUS_DIRECTLY
1173     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1174     struct sk_buff *tx_skb = skb;
1175     struct sk_buff *copy_skb = NULL;
1176 #endif
1177     struct SKB_info_st *mpdu_skb_info_p = (SKB_info *) (skb->head);
1178     struct ieee80211_sta *sta = mpdu_skb_info_p->sta;
1179     struct ssv_sta_priv_data *ssv_sta_priv =
1180             (struct ssv_sta_priv_data *) sta->drv_priv;
1181     u8 tidno;
1182     struct AMPDU_TID_st *ampdu_tid;
1183     if (sta == NULL)
1184     {
1185         WARN_ON(1);
1186         return false;
1187     }
1188     tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
1189     ampdu_db_log("tidno = %d\n", tidno);
1190     ampdu_tid = &ssv_sta_priv->ampdu_tid[tidno];
1191     if (ampdu_tid->state != AMPDU_STATE_OPERATION)
1192         return false;
1193 #ifdef AMPDU_CHECK_SKB_SEQNO
1194     {
1195         u32 skb_seqno = ((struct ieee80211_hdr*) (skb->data))->seq_ctrl
1196                         >> SSV_SEQ_NUM_SHIFT;
1197         u32 tid_seqno = ampdu_tid->last_seqno;
1198         if ((tid_seqno != (-1)) && (skb_seqno != NEXT_PKT_SN(tid_seqno)))
1199         {
1200             prn_aggr_err("Non continueous seq no: %d - %d\n", tid_seqno, skb_seqno);
1201             return false;
1202         }
1203         ampdu_tid->last_seqno = skb_seqno;
1204     }
1205 #endif
1206 #if 1
1207     mpdu_skb_info_p->lowest_rate = ssv62xx_ht_rate_update(skb, sc, mpdu_skb_info_p->rates);
1208     if (ampdu_max_transmit_length[mpdu_skb_info_p->lowest_rate] == 0)
1209     {
1210         _flush_mpdu(sc, sta);
1211         return false;
1212     }
1213 #endif
1214 #if 0
1215     if ((ampdu_tid->ssv_baw_head == SSV_ILLEGAL_SN)
1216         && (skb_queue_len(&ampdu_tid->ampdu_skb_tx_queue) == 0)
1217         && (skb_queue_len(&ampdu_tid->early_aggr_ampdu_q) == 0)
1218         && ((ampdu_tid->cur_ampdu_pkt == NULL)
1219             || (skb_queue_len(
1220                     &((struct ampdu_hdr_st *) (ampdu_tid->cur_ampdu_pkt->head))->mpdu_q)
1221                 == 0))
1222         && _is_skb_q_empty(sc, skb))
1223     {
1224         ampdu_tid->mib.ampdu_mib_pass_counter++;
1225 #if 0
1226         prn_aggr_err(
1227                 "pass %d\n",
1228                 ((struct ieee80211_hdr*)(skb->data))->seq_ctrl >> SSV_SEQ_NUM_SHIFT);
1229 #else
1230         if ((ssv_sta_priv->ampdu_tid[tidno].mib.ampdu_mib_pass_counter % 1024) == 0)
1231             prn_aggr_err("STA %d TID %d passed %d\n", ssv_sta_priv->sta_idx,
1232                          ampdu_tid->tidno,
1233                          ampdu_tid->mib.ampdu_mib_pass_counter);
1234 #endif
1235         return false;
1236     }
1237 #endif
1238     mpdu_skb_info_p = (SKB_info *) (skb->head);
1239     mpdu_skb_info_p->mpdu_retry_counter = 0;
1240     mpdu_skb_info_p->ampdu_tx_status = AMPDU_ST_NON_AMPDU;
1241     mpdu_skb_info_p->ampdu_tx_final_retry_count = 0;
1242     ssv_sta_priv->ampdu_tid[tidno].ac = skb_get_queue_mapping(skb);
1243 #if 0
1244 #ifndef CONFIG_SSV_SW_ENCRYPT_HW_DECRYPT
1245     if ((sc->ampdu_ccmp_encrypt == true))
1246     {
1247         skb_queue_tail(&ssv_sta_priv->ampdu_tid[tidno].ampdu_skb_wait_encry_queue, skb);
1248         if (sc->ampdu_encry_work_scheduled == false)
1249         {
1250             schedule_work(&sc->ampdu_tx_encry_work);
1251         }
1252     }
1253     else if (sc->algorithm != ME_NONE)
1254     {
1255         printk("None ccmp skb into AMPDU sc->algorithm = %d\n",sc->algorithm);
1256         info = IEEE80211_SKB_CB(skb);
1257         info->flags &= (~IEEE80211_TX_CTL_AMPDU);
1258         if(ssv6200_mpdu_send_HCI(sc->hw, skb))
1259         ieee80211_tx_status_irqsafe(sc->hw, skb);
1260     }
1261     else
1262 #endif
1263 #endif
1264 #ifdef REPORT_TX_STATUS_DIRECTLY
1265     info->flags |= IEEE80211_TX_STAT_ACK;
1266     copy_skb = skb_copy(tx_skb, GFP_ATOMIC);
1267     if (!copy_skb) {
1268          printk("create TX skb copy failed!\n");
1269         return false;
1270     }
1271     ieee80211_tx_status(sc->hw, tx_skb);
1272     skb = copy_skb;
1273 #endif
1274     {
1275         bool ret;
1276         ret = ssv6200_ampdu_add_delimiter_and_crc32(skb);
1277         if (ret == false)
1278         {
1279             ssv6200_ampdu_release_skb(skb, hw);
1280             return false;
1281         }
1282         skb_queue_tail(&ssv_sta_priv->ampdu_tid[tidno].ampdu_skb_tx_queue, skb);
1283         ssv_sta_priv->ampdu_tid[tidno].timestamp = jiffies;
1284     }
1285     _aggr_ampdu_tx_q(hw, &ssv_sta_priv->ampdu_tid[tidno]);
1286     return true;
1287 }
ssv6xxx_ampdu_flush(struct ieee80211_hw * hw)1288 u32 ssv6xxx_ampdu_flush (struct ieee80211_hw *hw)
1289 {
1290     struct ssv_softc *sc = hw->priv;
1291     struct AMPDU_TID_st *cur_AMPDU_TID;
1292     u32 flushed_ampdu = 0;
1293     u32 tid_idx = 0;
1294     if (!list_empty(&sc->tx.ampdu_tx_que))
1295     {
1296         list_for_each_entry_rcu(cur_AMPDU_TID, &sc->tx.ampdu_tx_que, list)
1297         {
1298             tid_idx++;
1299 #ifdef DEBUG_AMPDU_FLUSH
1300             {
1301                 int i = 0;
1302                 for (i = 0; i < MAX_TID; i++)
1303                     if (sc->tid[i] == cur_AMPDU_TID)
1304                         break;
1305                 if (i == MAX_TID)
1306                 {
1307                     printk(KERN_ERR "No matching TID (%d) found! %p\n", tid_idx, cur_AMPDU_TID);
1308                     continue;
1309                 }
1310             }
1311 #endif
1312             if (cur_AMPDU_TID->state != AMPDU_STATE_OPERATION)
1313             {
1314                 struct ieee80211_sta *sta = cur_AMPDU_TID->sta;
1315                 struct ssv_sta_priv_data *sta_priv = (struct ssv_sta_priv_data *)sta->drv_priv;
1316                 dev_dbg(sc->dev, "STA %d TID %d is @%d\n",
1317                         sta_priv->sta_idx, cur_AMPDU_TID->tidno,
1318                         cur_AMPDU_TID->state);
1319                 continue;
1320             }
1321             if ((cur_AMPDU_TID->state == AMPDU_STATE_OPERATION)
1322                 && (skb_queue_len(&cur_AMPDU_TID->early_aggr_ampdu_q) == 0)
1323                 && (cur_AMPDU_TID->cur_ampdu_pkt != NULL))
1324             {
1325                 struct ampdu_hdr_st *ampdu_hdr =
1326                         (struct ampdu_hdr_st *) (cur_AMPDU_TID->cur_ampdu_pkt->head);
1327                 u32 aggr_len = skb_queue_len(&ampdu_hdr->mpdu_q);
1328                 if (aggr_len)
1329                 {
1330                     struct sk_buff *ampdu_skb = cur_AMPDU_TID->cur_ampdu_pkt;
1331                     cur_AMPDU_TID->cur_ampdu_pkt = NULL;
1332                     _add_ampdu_txinfo(sc, ampdu_skb);
1333                     _queue_early_ampdu(sc, cur_AMPDU_TID, ampdu_skb);
1334                     #if 0
1335                     prn_aggr_err("A%c %d %d\n", sc->tx_q_empty ? 'e' : 't',
1336                                 ampdu_hdr->first_sn, aggr_len);
1337                     #endif
1338                 }
1339             }
1340             if (skb_queue_len(&cur_AMPDU_TID->early_aggr_ampdu_q) > 0)
1341                 flushed_ampdu += _flush_early_ampdu_q(sc, cur_AMPDU_TID);
1342         }
1343     }
1344     return flushed_ampdu;
1345 }
_dump_BA_notification(char * buf,struct ampdu_ba_notify_data * ba_notification)1346 int _dump_BA_notification (char *buf,
1347                             struct ampdu_ba_notify_data *ba_notification)
1348 {
1349     int i;
1350     char *orig_buf = buf;
1351     for (i = 0; i < MAX_AGGR_NUM; i++)
1352     {
1353         if (ba_notification->seq_no[i] == (u16) (-1))
1354             break;
1355         buf += sprintf(buf, " %d", ba_notification->seq_no[i]);
1356     }
1357     return ((size_t)buf - (size_t)orig_buf);
1358 }
_dump_ba_skb(char * buf,int buf_size,struct sk_buff * ba_skb)1359 int _dump_ba_skb (char *buf, int buf_size, struct sk_buff *ba_skb)
1360 {
1361     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) (ba_skb->data
1362                                                           + SSV6XXX_RX_DESC_LEN);
1363     AMPDU_BLOCKACK *BA_frame = (AMPDU_BLOCKACK *) hdr;
1364     u32 ssn = BA_frame->BA_ssn;
1365     struct ampdu_ba_notify_data *ba_notification =
1366             (struct ampdu_ba_notify_data *) (ba_skb->data + ba_skb->len
1367                                              - sizeof(struct ampdu_ba_notify_data));
1368     int prt_size;
1369     prt_size = snprintf(buf, buf_size, "\n\t\t%04d %08X %08X -",
1370                         ssn, BA_frame->BA_sn_bit_map[0], BA_frame->BA_sn_bit_map[1]);
1371     buf_size -= prt_size;
1372     buf += prt_size;
1373     prt_size = prt_size + _dump_BA_notification(buf, ba_notification);
1374     return prt_size;
1375 }
_ssn_to_bit_idx(u32 start_ssn,u32 mpdu_ssn,u32 * word_idx,u32 * bit_idx)1376 static bool _ssn_to_bit_idx (u32 start_ssn, u32 mpdu_ssn, u32 *word_idx,
1377                              u32 *bit_idx)
1378 {
1379     u32 ret_bit_idx, ret_word_idx = 0;
1380     s32 diff = mpdu_ssn - start_ssn;
1381     if (diff >= 0)
1382     {
1383         if (diff >= SSV_AMPDU_BA_WINDOW_SIZE)
1384         {
1385             return false;
1386         }
1387         ret_bit_idx = diff;
1388     }
1389     else
1390     {
1391         diff = -diff;
1392         if (diff <= (SSV_AMPDU_MAX_SSN - SSV_AMPDU_BA_WINDOW_SIZE))
1393         {
1394             *word_idx = 0;
1395             *bit_idx = 0;
1396             return false;
1397         }
1398         ret_bit_idx = SSV_AMPDU_MAX_SSN - diff;
1399     }
1400     if (ret_bit_idx >= 32)
1401     {
1402         ret_bit_idx -= 32;
1403         ret_word_idx = 1;
1404     }
1405     *bit_idx = ret_bit_idx;
1406     *word_idx = ret_word_idx;
1407     return true;
1408 }
_inc_bit_idx(u32 ssn_1st,u32 ssn_next,u32 * word_idx,u32 * bit_idx)1409 static bool _inc_bit_idx (u32 ssn_1st, u32 ssn_next, u32 *word_idx,
1410                           u32 *bit_idx)
1411 {
1412     u32 ret_word_idx = *word_idx, ret_bit_idx = *bit_idx;
1413     s32 diff = (s32) ssn_1st - (s32) ssn_next;
1414     if (diff > 0)
1415     {
1416         if (diff < (SSV_AMPDU_MAX_SSN - SSV_AMPDU_BA_WINDOW_SIZE))
1417         {
1418             prn_aggr_err("Irrational SN distance in AMPDU: %d %d.\n",
1419                          ssn_1st, ssn_next);
1420             return false;
1421         }
1422         diff = SSV_AMPDU_MAX_SSN - diff;
1423     }
1424     else
1425     {
1426         diff = -diff;
1427     }
1428     if (diff > SSV_AMPDU_MAX_SSN)
1429         prn_aggr_err("DF %d - %d = %d\n", ssn_1st, ssn_next, diff);
1430     ret_bit_idx += diff;
1431     if (ret_bit_idx >= 32)
1432     {
1433         ret_bit_idx -= 32;
1434         ret_word_idx++;
1435     }
1436     *word_idx = ret_word_idx;
1437     *bit_idx = ret_bit_idx;
1438     return true;
1439 }
_release_frames(struct AMPDU_TID_st * ampdu_tid)1440 static void _release_frames (struct AMPDU_TID_st *ampdu_tid)
1441 {
1442     u32 head_ssn, head_ssn_before, last_ssn;
1443     struct sk_buff **skb;
1444     struct SKB_info_st *skb_info;
1445     spin_lock_bh(&ampdu_tid->pkt_array_lock);
1446     head_ssn_before = ampdu_tid->ssv_baw_head;
1447 #if 1
1448     if (head_ssn_before >= SSV_AMPDU_MAX_SSN)
1449     {
1450         spin_unlock_bh(&ampdu_tid->pkt_array_lock);
1451         prn_aggr_err("l x.x %d\n", head_ssn_before);
1452         return;
1453     }
1454 #else
1455     BUG_ON(head_ssn_before >= SSV_AMPDU_MAX_SSN);
1456 #endif
1457     head_ssn = ampdu_tid->ssv_baw_head;
1458     last_ssn = head_ssn;
1459     do
1460     {
1461         skb = &INDEX_PKT_BY_SSN(ampdu_tid, head_ssn);
1462         if (*skb == NULL)
1463         {
1464             head_ssn = SSV_ILLEGAL_SN;
1465             {
1466                 int i;
1467                 char sn_str[66 * 5] = "";
1468                 char *str = sn_str;
1469                 for (i = 0; i < 64; i++)
1470                     if (ampdu_tid->aggr_pkts[i] != NULL)
1471                     {
1472                         str += sprintf(str, "%d ",
1473                                        ampdu_skb_ssn(ampdu_tid->aggr_pkts[i]));
1474                     }
1475                 *str = 0;
1476                 if (str == sn_str)
1477                 {
1478                 }
1479                 else
1480                     prn_aggr_err(
1481                             "ILL %d %d - %d (%s)\n",
1482                             head_ssn_before, last_ssn, ampdu_tid->aggr_pkt_num, sn_str);
1483             }
1484             break;
1485         }
1486         skb_info = (struct SKB_info_st *) ((*skb)->head);
1487         if ((skb_info->ampdu_tx_status == AMPDU_ST_DONE)
1488             || (skb_info->ampdu_tx_status == AMPDU_ST_DROPPED))
1489         {
1490             __skb_queue_tail(&ampdu_tid->release_queue, *skb);
1491             *skb = NULL;
1492             last_ssn = head_ssn;
1493             INC_PKT_SN(head_ssn);
1494             ampdu_tid->aggr_pkt_num--;
1495             if (skb_info->ampdu_tx_status == AMPDU_ST_DROPPED)
1496                 ampdu_tid->mib.ampdu_mib_discard_counter++;
1497         }
1498         else
1499         {
1500             break;
1501         }
1502     } while (1);
1503     ampdu_tid->ssv_baw_head = head_ssn;
1504 #if 0
1505     if (head_ssn == SSV_ILLEGAL_SN)
1506     {
1507         u32 i = head_ssn_before;
1508         do
1509         {
1510             skb = &INDEX_PKT_BY_SSN(ampdu_tid, i);
1511             if (*skb != NULL)
1512             prn_aggr_err("O.o %d: %d - %d\n", head_ssn_before, i, ampdu_skb_ssn(*skb));
1513             INC_PKT_SN(i);
1514         }while (i != head_ssn_before);
1515     }
1516 #endif
1517     spin_unlock_bh(&ampdu_tid->pkt_array_lock);
1518 #if 0
1519     if (head_ssn_before != head_ssn)
1520     {
1521         prn_aggr_err("H %d -> %d (%d - %d)\n", head_ssn_before, head_ssn,
1522                 ampdu_tid->aggr_pkt_num, skb_queue_len(&ampdu_tid->ampdu_skb_tx_queue));
1523     }
1524 #endif
1525 }
_collect_retry_frames(struct AMPDU_TID_st * ampdu_tid)1526 static int _collect_retry_frames (struct AMPDU_TID_st *ampdu_tid)
1527 {
1528     u16 ssn, head_ssn, end_ssn;
1529     int num_retry = 0;
1530     int timeout_check = 1;
1531     unsigned long check_jiffies = jiffies;
1532     head_ssn = ampdu_tid->ssv_baw_head;
1533     ssn = head_ssn;
1534     if (ssn == SSV_ILLEGAL_SN)
1535         return 0;
1536     end_ssn = (head_ssn + SSV_AMPDU_BA_WINDOW_SIZE) % SSV_AMPDU_MAX_SSN;
1537     do
1538     {
1539         struct sk_buff *skb = INDEX_PKT_BY_SSN(ampdu_tid, ssn);
1540         struct SKB_info_st *skb_info;
1541         int timeout_retry = 0;
1542         if (skb == NULL)
1543             break;
1544         skb_info = (SKB_info *) (skb->head);
1545         if ( timeout_check
1546             && (skb_info->ampdu_tx_status == AMPDU_ST_SENT))
1547         {
1548             unsigned long cur_jiffies = jiffies;
1549             unsigned long timeout_jiffies = skb_info->aggr_timestamp
1550                                             + msecs_to_jiffies(BA_WAIT_TIMEOUT);
1551             u32 delta_ms;
1552             if (time_before(cur_jiffies, timeout_jiffies))
1553             {
1554                 timeout_check = 0;
1555                 continue;
1556             }
1557             _mark_skb_retry(skb_info, skb);
1558             delta_ms = jiffies_to_msecs(cur_jiffies - skb_info->aggr_timestamp);
1559             prn_aggr_err("t S%d-T%d-%d (%u)\n",
1560                          ((struct ssv_sta_priv_data *)skb_info->sta->drv_priv)->sta_idx,
1561                          ampdu_tid->tidno, ssn,
1562                          delta_ms);
1563             if (delta_ms > 1000)
1564             {
1565                 prn_aggr_err("Last checktime %lu - %lu = %u\n",
1566                              check_jiffies, ampdu_tid->timestamp,
1567                              jiffies_to_msecs(check_jiffies - ampdu_tid->timestamp));
1568             }
1569             timeout_retry = 1;
1570         }
1571         if (skb_info->ampdu_tx_status == AMPDU_ST_RETRY)
1572         {
1573 #if 0
1574             if (!timeout_retry)
1575                 prn_aggr_dbg("r %d - %d\n", ssn, ampdu_skb_ssn(skb));
1576 #endif
1577             skb_queue_tail(&ampdu_tid->retry_queue, skb);
1578             ampdu_tid->mib.ampdu_mib_retry_counter++;
1579             num_retry++;
1580         }
1581         INC_PKT_SN(ssn);
1582     } while (ssn != end_ssn);
1583     ampdu_tid->timestamp = check_jiffies;
1584     return num_retry;
1585 }
_mark_skb_retry(struct SKB_info_st * skb_info,struct sk_buff * skb)1586 int _mark_skb_retry (struct SKB_info_st *skb_info, struct sk_buff *skb)
1587 {
1588     if (skb_info->mpdu_retry_counter < SSV_AMPDU_retry_counter_max)
1589     {
1590         if (skb_info->mpdu_retry_counter == 0)
1591         {
1592             struct ieee80211_hdr *skb_hdr = ampdu_skb_hdr(skb);
1593             skb_hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
1594         }
1595         skb_info->ampdu_tx_status = AMPDU_ST_RETRY;
1596         skb_info->mpdu_retry_counter++;
1597         return 1;
1598     }
1599     else
1600     {
1601         skb_info->ampdu_tx_status = AMPDU_ST_DROPPED;
1602         prn_aggr_err("p %d\n", ampdu_skb_ssn(skb));
1603         return 0;
1604     }
1605 }
_ba_map_walker(struct AMPDU_TID_st * ampdu_tid,u32 start_ssn,u32 sn_bit_map[2],struct ampdu_ba_notify_data * ba_notify_data,u32 * p_acked_num)1606 static u32 _ba_map_walker (struct AMPDU_TID_st *ampdu_tid, u32 start_ssn,
1607                            u32 sn_bit_map[2],
1608                            struct ampdu_ba_notify_data *ba_notify_data,
1609                            u32 *p_acked_num)
1610 {
1611     int i = 0;
1612     u32 ssn = ba_notify_data->seq_no[0];
1613     u32 word_idx = (-1), bit_idx = (-1);
1614     bool found = _ssn_to_bit_idx(start_ssn, ssn, &word_idx, &bit_idx);
1615     bool first_found = found;
1616     u32 aggr_num = 0;
1617     u32 acked_num = 0;
1618     if (found && (word_idx >= 2 || bit_idx >= 32))
1619         prn_aggr_err("idx error 1: %d %d %d %d\n",
1620                      start_ssn, ssn, word_idx, bit_idx);
1621     while ((i < MAX_AGGR_NUM) && (ssn < SSV_AMPDU_MAX_SSN))
1622     {
1623         u32 cur_ssn;
1624         struct sk_buff *skb = INDEX_PKT_BY_SSN(ampdu_tid, ssn);
1625         u32 skb_ssn = (skb == NULL) ? (-1) : ampdu_skb_ssn(skb);
1626         struct SKB_info_st *skb_info;
1627         aggr_num++;
1628         if (skb_ssn != ssn)
1629         {
1630             prn_aggr_err("Unmatched SSN packet: %d - %d - %d\n",
1631                          ssn, skb_ssn, start_ssn);
1632         }
1633         else
1634         {
1635             skb_info = (struct SKB_info_st *) (skb->head);
1636             if (found && (sn_bit_map[word_idx] & (1 << bit_idx)))
1637             {
1638                 if (skb_info->ampdu_tx_status != AMPDU_ST_SENT)
1639                 {
1640                     printk(KERN_ERR "BA marks a MPDU of status %d!\n",
1641                            skb_info->ampdu_tx_status);
1642                 }
1643                 skb_info->ampdu_tx_status = AMPDU_ST_DONE;
1644                 acked_num++;
1645             }
1646             else
1647             {
1648                 _mark_skb_retry(skb_info, skb);
1649             }
1650         }
1651         cur_ssn = ssn;
1652         if (++i >= MAX_AGGR_NUM)
1653             break;
1654         ssn = ba_notify_data->seq_no[i];
1655         if (ssn >= SSV_AMPDU_MAX_SSN)
1656             break;
1657         if (first_found)
1658         {
1659             u32 old_word_idx = word_idx, old_bit_idx = bit_idx;
1660             found = _inc_bit_idx(cur_ssn, ssn, &word_idx, &bit_idx);
1661             if (found && (word_idx >= 2 || bit_idx >= 32))
1662             {
1663                 prn_aggr_err(
1664                         "idx error 2: %d 0x%08X 0X%08X %d %d (%d %d) (%d %d)\n",
1665                         start_ssn, sn_bit_map[1], sn_bit_map[0], cur_ssn, ssn, word_idx, bit_idx, old_word_idx, old_bit_idx);
1666                 found = false;
1667             }
1668             else if (!found)
1669             {
1670                 char strbuf[256];
1671                 _dump_BA_notification(strbuf, ba_notify_data);
1672                 prn_aggr_err("SN out-of-order: %d\n%s\n", start_ssn, strbuf);
1673             }
1674         }
1675         else
1676         {
1677             found = _ssn_to_bit_idx(start_ssn, ssn, &word_idx, &bit_idx);
1678             first_found = found;
1679             if (found && (word_idx >= 2 || bit_idx >= 32))
1680                 prn_aggr_err("idx error 3: %d %d %d %d\n",
1681                              cur_ssn, ssn, word_idx, bit_idx);
1682         }
1683     }
1684     _release_frames(ampdu_tid);
1685     if (p_acked_num != NULL)
1686         *p_acked_num = acked_num;
1687     return aggr_num;
1688 }
_flush_release_queue(struct ieee80211_hw * hw,struct sk_buff_head * release_queue)1689 static void _flush_release_queue (struct ieee80211_hw *hw,
1690                                   struct sk_buff_head *release_queue)
1691 {
1692     do
1693     {
1694         struct sk_buff *ampdu_skb = __skb_dequeue(release_queue);
1695         struct ieee80211_tx_info *tx_info;
1696         struct SKB_info_st *skb_info;
1697         if (ampdu_skb == NULL)
1698             break;
1699         skb_info = (struct SKB_info_st *) (ampdu_skb->head);
1700         skb_pull(ampdu_skb, AMPDU_DELIMITER_LEN);
1701         tx_info = IEEE80211_SKB_CB(ampdu_skb);
1702         ieee80211_tx_info_clear_status(tx_info);
1703         tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1704         if (skb_info->ampdu_tx_status == AMPDU_ST_DONE)
1705             tx_info->flags |= IEEE80211_TX_STAT_ACK;
1706         tx_info->status.ampdu_len = 1;
1707         tx_info->status.ampdu_ack_len = 1;
1708 #ifdef REPORT_TX_STATUS_DIRECTLY
1709         dev_kfree_skb_any(ampdu_skb);
1710 #else
1711         #if defined(USE_THREAD_RX) && !defined(IRQ_PROC_TX_DATA)
1712         ieee80211_tx_status(hw, ampdu_skb);
1713         #else
1714         ieee80211_tx_status_irqsafe(hw, ampdu_skb);
1715         #endif
1716 #endif
1717     } while (1);
1718 }
1719 #if 0
1720 static u16 _get_BA_notification_hits(u16 ssn,u32 *bit_map,struct ampdu_ba_notify_data *ba_notification,u16 *max_continue_hits,u16 *aggr_num)
1721 {
1722     int i;
1723     u16 hits=0,continue_hits=0;
1724     u64 bitMap=0;
1725     if(bit_map)
1726     bitMap = ((u64)bit_map[1]<<32) | (u64)(bit_map[0]);
1727     for (i = 0; i < MAX_AGGR_NUM; i++)
1728     {
1729         if (ba_notification->seq_no[i] == (u16)(-1))
1730         break;
1731         if(ssn <= ba_notification->seq_no[i])
1732         {
1733             if((bitMap>>(ba_notification->seq_no[i]-ssn))&0x1)
1734             {
1735                 hits++;
1736                 continue_hits++;
1737                 if(*max_continue_hits<=continue_hits)
1738                 *max_continue_hits = continue_hits;
1739             }
1740             else
1741             {
1742                 continue_hits=0;
1743             }
1744         }
1745     }
1746     *aggr_num = i;
1747     return hits;
1748 }
1749 #endif
ssv6200_ampdu_no_BA_handler(struct ieee80211_hw * hw,struct sk_buff * skb)1750 void ssv6200_ampdu_no_BA_handler (struct ieee80211_hw *hw, struct sk_buff *skb)
1751 {
1752     struct cfg_host_event *host_event = (struct cfg_host_event *) skb->data;
1753     struct ampdu_ba_notify_data *ba_notification =
1754             (struct ampdu_ba_notify_data *) &host_event->dat[0];
1755     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) (ba_notification + 1);
1756     struct ssv_softc *sc = hw->priv;
1757     struct ieee80211_sta *sta = ssv6xxx_find_sta_by_addr(sc, hdr->addr1);
1758     u8 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
1759     struct ssv_sta_priv_data *ssv_sta_priv;
1760     char seq_str[256];
1761     struct AMPDU_TID_st *ampdu_tid;
1762     int i;
1763     u16 aggr_num = 0;
1764     struct firmware_rate_control_report_data *report_data;
1765     if (sta == NULL)
1766     {
1767         prn_aggr_err(
1768                 "NO BA for %d to unmatched STA %02X-%02X-%02X-%02X-%02X-%02X: %s\n",
1769                 tidno, hdr->addr1[0], hdr->addr1[1], hdr->addr1[2], hdr->addr1[3], hdr->addr1[4], hdr->addr1[5], seq_str);
1770         dev_kfree_skb_any(skb);
1771         return;
1772     }
1773     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
1774     _dump_BA_notification(seq_str, ba_notification);
1775     prn_aggr_err(
1776             "NO BA for %d to %02X-%02X-%02X-%02X-%02X-%02X: %s\n",
1777             tidno, sta->addr[0], sta->addr[1], sta->addr[2], sta->addr[3], sta->addr[4], sta->addr[5], seq_str);
1778     ampdu_tid = &ssv_sta_priv->ampdu_tid[tidno];
1779     if (ampdu_tid->state != AMPDU_STATE_OPERATION)
1780     {
1781         dev_kfree_skb_any(skb);
1782         return;
1783     }
1784     for (i = 0; i < MAX_AGGR_NUM; i++)
1785     {
1786         u32 ssn = ba_notification->seq_no[i];
1787         struct sk_buff *skb;
1788         u32 skb_ssn;
1789         struct SKB_info_st *skb_info;
1790         if (ssn >= (4096))
1791             break;
1792         aggr_num++;
1793         skb = INDEX_PKT_BY_SSN(ampdu_tid, ssn);
1794         skb_ssn = (skb == NULL) ? (-1) : ampdu_skb_ssn(skb);
1795         if (skb_ssn != ssn)
1796         {
1797             prn_aggr_err("Unmatched SSN packet: %d - %d\n", ssn, skb_ssn);
1798             continue;
1799         }
1800         skb_info = (struct SKB_info_st *) (skb->head);
1801         if (skb_info->ampdu_tx_status == AMPDU_ST_SENT)
1802         {
1803             if (skb_info->mpdu_retry_counter < SSV_AMPDU_retry_counter_max)
1804             {
1805                 if (skb_info->mpdu_retry_counter == 0)
1806                 {
1807                     struct ieee80211_hdr *skb_hdr = ampdu_skb_hdr(skb);
1808                     skb_hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
1809                 }
1810                 skb_info->ampdu_tx_status = AMPDU_ST_RETRY;
1811                 skb_info->mpdu_retry_counter++;
1812             }
1813             else
1814             {
1815                 skb_info->ampdu_tx_status = AMPDU_ST_DROPPED;
1816                 prn_aggr_err("p %d\n", skb_ssn);
1817             }
1818         }
1819         else
1820         {
1821             prn_aggr_err("S %d %d\n", skb_ssn, skb_info->ampdu_tx_status);
1822         }
1823     }
1824     _release_frames(ampdu_tid);
1825     host_event->h_event = SOC_EVT_RC_AMPDU_REPORT;
1826     report_data =
1827             (struct firmware_rate_control_report_data *) &host_event->dat[0];
1828     report_data->ampdu_len = aggr_num;
1829     report_data->ampdu_ack_len = 0;
1830     report_data->wsid = ssv_sta_priv->sta_info->hw_wsid;
1831 #if 0
1832     printk("AMPDU report NO BA!!wsid[%d]didx[%d]F[%d]R[%d]S[%d]\n",report_data->wsid,report_data->data_rate,report_data->mpduFrames,report_data->mpduFrameRetry,report_data->mpduFrameSuccess);
1833 #endif
1834     skb_queue_tail(&sc->rc_report_queue, skb);
1835     if (sc->rc_sample_sechedule == 0)
1836         queue_work(sc->rc_sample_workqueue, &sc->rc_sample_work);
1837 }
ssv6200_ampdu_BA_handler(struct ieee80211_hw * hw,struct sk_buff * skb)1838 void ssv6200_ampdu_BA_handler (struct ieee80211_hw *hw, struct sk_buff *skb)
1839 {
1840     struct ssv_softc *sc = hw->priv;
1841     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) (skb->data
1842                                                           + SSV6XXX_RX_DESC_LEN);
1843     AMPDU_BLOCKACK *BA_frame = (AMPDU_BLOCKACK *) hdr;
1844     struct ieee80211_sta *sta;
1845     struct ssv_sta_priv_data *ssv_sta_priv;
1846     struct ampdu_ba_notify_data *ba_notification;
1847     u32 ssn, aggr_num = 0, acked_num = 0;
1848     u8 tid_no;
1849     u32 sn_bit_map[2];
1850     struct firmware_rate_control_report_data *report_data;
1851     HDR_HostEvent *host_evt;
1852     sta = ssv6xxx_find_sta_by_rx_skb(sc, skb);
1853     if (sta == NULL)
1854     {
1855         if (skb->len > AMPDU_BA_FRAME_LEN)
1856         {
1857             char strbuf[256];
1858             struct ampdu_ba_notify_data *ba_notification =
1859                     (struct ampdu_ba_notify_data *) (skb->data + skb->len
1860                                                      - sizeof(struct ampdu_ba_notify_data));
1861             _dump_BA_notification(strbuf, ba_notification);
1862             prn_aggr_err("BA from not connected STA (%02X-%02X-%02X-%02X-%02X-%02X) (%s)\n",
1863                     BA_frame->ta_addr[0], BA_frame->ta_addr[1], BA_frame->ta_addr[2],
1864                     BA_frame->ta_addr[3], BA_frame->ta_addr[4], BA_frame->ta_addr[5], strbuf);
1865         }
1866         dev_kfree_skb_any(skb);
1867         return;
1868     }
1869     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
1870     ssn = BA_frame->BA_ssn;
1871     sn_bit_map[0] = BA_frame->BA_sn_bit_map[0];
1872     sn_bit_map[1] = BA_frame->BA_sn_bit_map[1];
1873     tid_no = BA_frame->tid_info;
1874     ssv_sta_priv->ampdu_mib_total_BA_counter++;
1875     if (ssv_sta_priv->ampdu_tid[tid_no].state == AMPDU_STATE_STOP)
1876     {
1877         prn_aggr_err("ssv6200_ampdu_BA_handler state == AMPDU_STATE_STOP.\n");
1878         dev_kfree_skb_any(skb);
1879         return;
1880     }
1881     ssv_sta_priv->ampdu_tid[tid_no].mib.ampdu_mib_BA_counter++;
1882     if (skb->len <= AMPDU_BA_FRAME_LEN)
1883     {
1884         prn_aggr_err("b %d\n", ssn);
1885         dev_kfree_skb_any(skb);
1886         return;
1887     }
1888     ba_notification =
1889             (struct ampdu_ba_notify_data *) (skb->data + skb->len
1890                                              - sizeof(struct ampdu_ba_notify_data));
1891 #if 0
1892     if (1)
1893     {
1894         char strbuf[256];
1895         _dump_BA_notification(strbuf, ba_notification);
1896         prn_aggr_err("B %d %08X %08X: %s\n", ssn, sn_bit_map[0], sn_bit_map[1], strbuf);
1897     }
1898 #endif
1899     aggr_num = _ba_map_walker(&(ssv_sta_priv->ampdu_tid[tid_no]), ssn,
1900                               sn_bit_map, ba_notification, &acked_num);
1901     #ifdef CONFIG_SSV6XXX_DEBUGFS
1902     if (ssv_sta_priv->ampdu_tid[tid_no].debugfs_dir)
1903     {
1904         struct sk_buff *dup_skb;
1905         if (skb_queue_len(&ssv_sta_priv->ampdu_tid[tid_no].ba_q) > 24)
1906         {
1907             struct sk_buff *ba_skb = skb_dequeue(&ssv_sta_priv->ampdu_tid[tid_no].ba_q);
1908             if (ba_skb)
1909                 dev_kfree_skb_any(ba_skb);
1910         }
1911         dup_skb = skb_clone(skb, GFP_ATOMIC);
1912         if (dup_skb)
1913             skb_queue_tail(&ssv_sta_priv->ampdu_tid[tid_no].ba_q, dup_skb);
1914     }
1915     #endif
1916     skb_trim(skb, skb->len - sizeof(struct ampdu_ba_notify_data));
1917 #if 0
1918     total_debug_count++;
1919     if (ba_notification_hits != ba_notification_aggr_num)
1920     printk("rate[%d] firmware retry [%d] agg nums[%d] hits[%d] continue_hits[%d] \n",ba_notification.data_rate,ba_notification.retry_count,ba_notification_aggr_num,ba_notification_hits,ba_notification_continue_hits);
1921     else
1922     {
1923         if (ba_notification.retry_count==0)
1924         total_perfect_debug_count++;
1925         else
1926         total_perfect_debug_count_but_firmware_retry++;
1927     }
1928     if ((total_debug_count % 2000) == 0)
1929     {
1930         printk("Percentage %d/2000\n",total_perfect_debug_count);
1931         printk("firmware retry [%d] no BA[%d]\n",total_perfect_debug_count_but_firmware_retry,no_ba_debug_count);
1932         total_debug_count = 0;
1933         total_perfect_debug_count_but_firmware_retry=0;
1934         total_perfect_debug_count = 0;
1935         no_ba_debug_count = 0;
1936     }
1937 #endif
1938     host_evt = (HDR_HostEvent *) skb->data;
1939     host_evt->h_event = SOC_EVT_RC_AMPDU_REPORT;
1940     report_data =
1941             (struct firmware_rate_control_report_data *) &host_evt->dat[0];
1942     memcpy(report_data, ba_notification,
1943            sizeof(struct firmware_rate_control_report_data));
1944     report_data->ampdu_len = aggr_num;
1945     report_data->ampdu_ack_len = acked_num;
1946 #ifdef RATE_CONTROL_HT_PERCENTAGE_TRACE
1947     if((acked_num) && (acked_num != aggr_num))
1948     {
1949         int i;
1950         for (i = 0; i < SSV62XX_TX_MAX_RATES ; i++) {
1951             if(report_data->rates[i].data_rate == -1)
1952                 break;
1953             if(report_data->rates[i].count == 0) {
1954                     printk("*********************************\n");
1955                     printk("       Illegal HT report         \n");
1956                     printk("*********************************\n");
1957             }
1958             printk("        i=[%d] rate[%d] count[%d]\n",i,report_data->rates[i].data_rate,report_data->rates[i].count);
1959         }
1960         printk("AMPDU percentage = %d%% \n",acked_num*100/aggr_num);
1961     }
1962     else if(acked_num == 0)
1963     {
1964         printk("AMPDU percentage = 0%% aggr_num=%d acked_num=%d\n",aggr_num,acked_num);
1965     }
1966 #endif
1967     skb_queue_tail(&sc->rc_report_queue, skb);
1968     if (sc->rc_sample_sechedule == 0)
1969         queue_work(sc->rc_sample_workqueue, &sc->rc_sample_work);
1970 }
_postprocess_BA(struct ssv_softc * sc,struct ssv_sta_info * sta_info,void * param)1971 static void _postprocess_BA (struct ssv_softc *sc, struct ssv_sta_info *sta_info, void *param)
1972 {
1973     int j;
1974     struct ssv_sta_priv_data *ssv_sta_priv;
1975     if ( (sta_info->sta == NULL)
1976         || ((sta_info->s_flags & STA_FLAG_VALID) == 0))
1977         return;
1978     ssv_sta_priv = (struct ssv_sta_priv_data *) sta_info->sta->drv_priv;
1979     for (j = 0; j < WMM_TID_NUM; j++)
1980     {
1981         AMPDU_TID *ampdu_tid = &ssv_sta_priv->ampdu_tid[j];
1982         if (ampdu_tid->state != AMPDU_STATE_OPERATION)
1983             continue;
1984         _collect_retry_frames(ampdu_tid);
1985         ssv6200_ampdu_send_retry(sc->hw, ampdu_tid, &ampdu_tid->retry_queue,
1986                                  true);
1987         _flush_early_ampdu_q(sc, ampdu_tid);
1988         _flush_release_queue(sc->hw, &ampdu_tid->release_queue);
1989     }
1990 }
ssv6xxx_ampdu_postprocess_BA(struct ieee80211_hw * hw)1991 void ssv6xxx_ampdu_postprocess_BA (struct ieee80211_hw *hw)
1992 {
1993     struct ssv_softc *sc = hw->priv;
1994     ssv6xxx_foreach_sta(sc, _postprocess_BA, NULL);
1995 }
ssv6200_hw_set_rx_ba_session(struct ssv_hw * sh,bool on,u8 * ta,u16 tid,u16 ssn,u8 buf_size)1996 static void ssv6200_hw_set_rx_ba_session (struct ssv_hw *sh, bool on, u8 *ta,
1997                                           u16 tid, u16 ssn, u8 buf_size)
1998 {
1999     if (on)
2000     {
2001         u32 u32ta;
2002         u32ta = 0;
2003         u32ta |= (ta[0] & 0xff) << (8 * 0);
2004         u32ta |= (ta[1] & 0xff) << (8 * 1);
2005         u32ta |= (ta[2] & 0xff) << (8 * 2);
2006         u32ta |= (ta[3] & 0xff) << (8 * 3);
2007         SMAC_REG_WRITE(sh, ADR_BA_TA_0, u32ta);
2008         u32ta = 0;
2009         u32ta |= (ta[4] & 0xff) << (8 * 0);
2010         u32ta |= (ta[5] & 0xff) << (8 * 1);
2011         SMAC_REG_WRITE(sh, ADR_BA_TA_1, u32ta);
2012         SMAC_REG_WRITE(sh, ADR_BA_TID, tid);
2013         SMAC_REG_WRITE(sh, ADR_BA_ST_SEQ, ssn);
2014         SMAC_REG_WRITE(sh, ADR_BA_SB0, 0);
2015         SMAC_REG_WRITE(sh, ADR_BA_SB1, 0);
2016         SMAC_REG_WRITE(sh, ADR_BA_CTRL, 0xb);
2017     }
2018     else
2019     {
2020         SMAC_REG_WRITE(sh, ADR_BA_CTRL, 0x0);
2021     }
2022 }
ssv6xxx_set_ampdu_rx_add_work(struct work_struct * work)2023 void ssv6xxx_set_ampdu_rx_add_work (struct work_struct *work)
2024 {
2025     struct ssv_softc
2026     *sc = container_of(work, struct ssv_softc, set_ampdu_rx_add_work);
2027     ssv6200_hw_set_rx_ba_session(sc->sh, true, sc->ba_ra_addr, sc->ba_tid,
2028                                  sc->ba_ssn, 64);
2029 }
ssv6xxx_set_ampdu_rx_del_work(struct work_struct * work)2030 void ssv6xxx_set_ampdu_rx_del_work (struct work_struct *work)
2031 {
2032     struct ssv_softc*sc = container_of(work, struct ssv_softc,
2033                                        set_ampdu_rx_del_work);
2034     u8 addr[6] = { 0 };
2035     ssv6200_hw_set_rx_ba_session(sc->sh, false, addr, 0, 0, 0);
2036 }
_reset_ampdu_mib(struct ssv_softc * sc,struct ssv_sta_info * sta_info,void * param)2037 static void _reset_ampdu_mib (struct ssv_softc *sc, struct ssv_sta_info *sta_info, void *param)
2038 {
2039     struct ieee80211_sta *sta = sta_info->sta;
2040     struct ssv_sta_priv_data *ssv_sta_priv;
2041     int i;
2042     ssv_sta_priv = (struct ssv_sta_priv_data *)sta->drv_priv;
2043     for (i = 0; i < WMM_TID_NUM; i++)
2044     {
2045         ssv_sta_priv->ampdu_tid[i].ampdu_mib_reset = 1;
2046     }
2047 }
ssv6xxx_ampdu_mib_reset(struct ieee80211_hw * hw)2048 void ssv6xxx_ampdu_mib_reset (struct ieee80211_hw *hw)
2049 {
2050     struct ssv_softc *sc = hw->priv;
2051     if (sc == NULL)
2052         return;
2053     ssv6xxx_foreach_sta(sc, _reset_ampdu_mib, NULL);
2054 }
2055 #ifdef CONFIG_SSV6XXX_DEBUGFS
ampdu_tx_mib_dump(struct ssv_sta_priv_data * ssv_sta_priv,char * mib_str,ssize_t length)2056 ssize_t ampdu_tx_mib_dump (struct ssv_sta_priv_data *ssv_sta_priv,
2057                            char *mib_str, ssize_t length)
2058 {
2059     ssize_t buf_size = length;
2060     ssize_t prt_size;
2061     int j;
2062     struct ssv_sta_info *ssv_sta = ssv_sta_priv->sta_info;
2063     if (ssv_sta->sta == NULL)
2064     {
2065         prt_size = snprintf(mib_str, buf_size, "\n    NULL STA.\n");
2066         mib_str += prt_size;
2067         buf_size -= prt_size;
2068         goto mib_dump_exit;
2069     }
2070     for (j = 0; j < WMM_TID_NUM; j++)
2071     {
2072         int k;
2073         struct AMPDU_TID_st *ampdu_tid = &ssv_sta_priv->ampdu_tid[j];
2074         struct AMPDU_MIB_st *ampdu_mib = &ampdu_tid->mib;
2075         prt_size = snprintf(mib_str, buf_size, "\n    WMM_TID %d@%d\n", j,
2076                             ampdu_tid->state);
2077         mib_str += prt_size;
2078         buf_size -= prt_size;
2079         if (ampdu_tid->state != AMPDU_STATE_OPERATION)
2080             continue;
2081         prt_size = snprintf(mib_str, buf_size, "        BA window size: %d\n",
2082                             ampdu_tid->ssv_baw_size);
2083         mib_str += prt_size;
2084         buf_size -= prt_size;
2085         prt_size = snprintf(mib_str, buf_size, "        BA window head: %d\n",
2086                             ampdu_tid->ssv_baw_head);
2087         mib_str += prt_size;
2088         buf_size -= prt_size;
2089         prt_size = snprintf(mib_str, buf_size,
2090                             "        Sending aggregated #: %d\n",
2091                             ampdu_tid->aggr_pkt_num);
2092         mib_str += prt_size;
2093         buf_size -= prt_size;
2094         prt_size = snprintf(
2095                 mib_str, buf_size, "        Waiting #: %d\n",
2096                 skb_queue_len(&ampdu_tid->ampdu_skb_tx_queue));
2097         mib_str += prt_size;
2098         buf_size -= prt_size;
2099         prt_size = snprintf(mib_str, buf_size, "        Early aggregated %d\n",
2100                             ampdu_tid->early_aggr_skb_num);
2101         mib_str += prt_size;
2102         buf_size -= prt_size;
2103         prt_size = snprintf(mib_str, buf_size,
2104                             "        MPDU: %d\n",
2105                             ampdu_mib->ampdu_mib_mpdu_counter);
2106         mib_str += prt_size;
2107         buf_size -= prt_size;
2108         prt_size = snprintf(mib_str, buf_size,
2109                             "        Passed: %d\n", ampdu_mib->ampdu_mib_pass_counter);
2110         mib_str += prt_size;
2111         buf_size -= prt_size;
2112         prt_size = snprintf(mib_str, buf_size,
2113                             "        Retry: %d\n",
2114                             ampdu_mib->ampdu_mib_retry_counter);
2115         mib_str += prt_size;
2116         buf_size -= prt_size;
2117         prt_size = snprintf(mib_str, buf_size,
2118                             "        AMPDU: %d\n",
2119                             ampdu_mib->ampdu_mib_ampdu_counter);
2120         mib_str += prt_size;
2121         buf_size -= prt_size;
2122         prt_size = snprintf(mib_str, buf_size,
2123                             "        Retry AMPDU: %d\n",
2124                             ampdu_mib->ampdu_mib_aggr_retry_counter);
2125         mib_str += prt_size;
2126         buf_size -= prt_size;
2127         prt_size = snprintf(mib_str, buf_size,
2128                             "        BAR count: %d\n",
2129                             ampdu_mib->ampdu_mib_bar_counter);
2130         mib_str += prt_size;
2131         buf_size -= prt_size;
2132         prt_size = snprintf(mib_str, buf_size,
2133                             "        Discard count: %d\n",
2134                             ampdu_mib->ampdu_mib_discard_counter);
2135         mib_str += prt_size;
2136         buf_size -= prt_size;
2137         prt_size = snprintf(mib_str, buf_size,
2138                             "        BA count: %d\n",
2139                             ampdu_mib->ampdu_mib_BA_counter);
2140         mib_str += prt_size;
2141         buf_size -= prt_size;
2142         prt_size = snprintf(mib_str, buf_size, "        Total BA count: %d\n",
2143                             ssv_sta_priv->ampdu_mib_total_BA_counter);
2144         mib_str += prt_size;
2145         buf_size -= prt_size;
2146         prt_size = snprintf(mib_str, buf_size, "        Aggr # count:\n");
2147         mib_str += prt_size;
2148         buf_size -= prt_size;
2149         for (k = 0; k <= SSV_AMPDU_aggr_num_max; k++)
2150         {
2151             prt_size = snprintf(mib_str, buf_size, "            %d: %d\n", k,
2152                                 ampdu_mib->ampdu_mib_dist[k]);
2153             mib_str += prt_size;
2154             buf_size -= prt_size;
2155         }
2156     }
2157 mib_dump_exit:
2158     return (length - buf_size);
2159 }
_dump_ampdu_mib(struct ssv_softc * sc,struct ssv_sta_info * sta_info,void * param)2160 static void _dump_ampdu_mib (struct ssv_softc *sc, struct ssv_sta_info *sta_info, void *param)
2161 {
2162     struct mib_dump_data *dump_data = (struct mib_dump_data *)param;
2163     struct ieee80211_sta *sta;
2164     struct ssv_sta_priv_data *ssv_sta_priv;
2165     ssize_t buf_size;
2166     ssize_t prt_size;
2167     char *mib_str = dump_data->prt_buff;
2168     if (param == NULL)
2169         return;
2170     buf_size = dump_data->buff_size - 1;
2171     sta = sta_info->sta;
2172     if ((sta == NULL) || ((sta_info->s_flags & STA_FLAG_VALID) == 0))
2173         return;
2174     prt_size = snprintf(mib_str, buf_size,
2175                         "STA: %02X-%02X-%02X-%02X-%02X-%02X:\n",
2176                         sta->addr[0], sta->addr[1], sta->addr[2],
2177                         sta->addr[3], sta->addr[4], sta->addr[5]);
2178     mib_str += prt_size;
2179     buf_size -= prt_size;
2180     ssv_sta_priv = (struct ssv_sta_priv_data *) sta->drv_priv;
2181     prt_size = ampdu_tx_mib_dump(ssv_sta_priv, mib_str, buf_size);
2182     mib_str += prt_size;
2183     buf_size -= prt_size;
2184     dump_data->prt_len = (dump_data->buff_size - 1 - buf_size);
2185     dump_data->prt_buff = mib_str;
2186     dump_data->buff_size = buf_size;
2187 }
ssv6xxx_ampdu_mib_dump(struct ieee80211_hw * hw,char * mib_str,ssize_t length)2188 ssize_t ssv6xxx_ampdu_mib_dump (struct ieee80211_hw *hw, char *mib_str,
2189                                 ssize_t length)
2190 {
2191     struct ssv_softc *sc = hw->priv;
2192     ssize_t buf_size = length - 1;
2193     struct mib_dump_data dump_data = {mib_str, buf_size, 0};
2194     if (sc == NULL)
2195         return 0;
2196     ssv6xxx_foreach_sta(sc, _dump_ampdu_mib, &dump_data);
2197     return dump_data.prt_len;
2198 }
2199 #endif
_alloc_ampdu_skb(struct ssv_softc * sc,struct AMPDU_TID_st * ampdu_tid,u32 len)2200 struct sk_buff *_alloc_ampdu_skb (struct ssv_softc *sc, struct AMPDU_TID_st *ampdu_tid, u32 len)
2201 {
2202     unsigned char *payload_addr;
2203     u32 headroom = sc->hw->extra_tx_headroom;
2204     u32 offset;
2205     u32 cur_max_ampdu_size = SSV_GET_MAX_AMPDU_SIZE(sc->sh);
2206     u32 extra_room = sc->sh->tx_desc_len * 2 + 48;
2207     u32 max_physical_len = (len && ((len + extra_room) < cur_max_ampdu_size))
2208                            ? (len + extra_room)
2209                            : cur_max_ampdu_size;
2210     u32 skb_len = max_physical_len + headroom + 3;
2211     struct sk_buff *ampdu_skb = __dev_alloc_skb(skb_len, GFP_KERNEL);
2212     struct ampdu_hdr_st *ampdu_hdr;
2213     if (ampdu_skb == NULL)
2214     {
2215         dev_err(sc->dev, "AMPDU allocation of size %d(%d) failed\n", len, skb_len);
2216         return NULL;
2217     }
2218     payload_addr = ampdu_skb->data + headroom - sc->sh->tx_desc_len;
2219     offset = ((size_t) payload_addr) % 4U;
2220     if (offset)
2221     {
2222         printk(KERN_ERR "Align AMPDU data %d\n", offset);
2223         skb_reserve(ampdu_skb, headroom + 4 - offset);
2224     }
2225     else
2226         skb_reserve(ampdu_skb, headroom);
2227     ampdu_hdr = (struct ampdu_hdr_st *) ampdu_skb->head;
2228     skb_queue_head_init(&ampdu_hdr->mpdu_q);
2229     ampdu_hdr->max_size = max_physical_len - extra_room;
2230     ampdu_hdr->size = 0;
2231     ampdu_hdr->ampdu_tid = ampdu_tid;
2232     memset(ampdu_hdr->ssn, 0xFF, sizeof(ampdu_hdr->ssn));
2233     ampdu_hdr->mpdu_num = 0;
2234     return ampdu_skb;
2235 }
_is_skb_q_empty(struct ssv_softc * sc,struct sk_buff * skb)2236 bool _is_skb_q_empty (struct ssv_softc *sc, struct sk_buff *skb)
2237 {
2238     u32 ac = skb_get_queue_mapping(skb);
2239     u32 hw_txqid = sc->tx.hw_txqid[ac];
2240     return AMPDU_HCI_Q_EMPTY(sc->sh, hw_txqid);
2241 }
_check_timeout(struct AMPDU_TID_st * ampdu_tid)2242 static u32 _check_timeout (struct AMPDU_TID_st *ampdu_tid)
2243 {
2244     u16 ssn, head_ssn, end_ssn;
2245     unsigned long check_jiffies = jiffies;
2246     u32 has_retry = 0;
2247     head_ssn = ampdu_tid->ssv_baw_head;
2248     ssn = head_ssn;
2249     if (ssn == SSV_ILLEGAL_SN)
2250         return 0;
2251     end_ssn = (head_ssn + SSV_AMPDU_BA_WINDOW_SIZE)% SSV_AMPDU_MAX_SSN;
2252     do {
2253         struct sk_buff *skb = INDEX_PKT_BY_SSN(ampdu_tid, ssn);
2254         struct SKB_info_st *skb_info;
2255         unsigned long cur_jiffies;
2256         unsigned long timeout_jiffies;
2257         u32 delta_ms;
2258         if (skb == NULL)
2259             break;
2260         skb_info = (SKB_info *) (skb->head);
2261         cur_jiffies = jiffies;
2262         timeout_jiffies = skb_info->aggr_timestamp + msecs_to_jiffies(BA_WAIT_TIMEOUT);
2263         if ( (skb_info->ampdu_tx_status != AMPDU_ST_SENT)
2264             || time_before(cur_jiffies, timeout_jiffies))
2265             break;
2266         delta_ms = jiffies_to_msecs(cur_jiffies - skb_info->aggr_timestamp);
2267         prn_aggr_err("rt S%d-T%d-%d (%u)\n",
2268                      ((struct ssv_sta_priv_data *)skb_info->sta->drv_priv)->sta_idx,
2269                      ampdu_tid->tidno, ssn,
2270                      delta_ms);
2271         if (delta_ms > 1000)
2272         {
2273             prn_aggr_err("Last checktime %lu - %lu = %u\n",
2274                          check_jiffies, ampdu_tid->timestamp,
2275                          jiffies_to_msecs(check_jiffies - ampdu_tid->timestamp));
2276         }
2277         has_retry += _mark_skb_retry(skb_info, skb);
2278         INC_PKT_SN(ssn);
2279     } while (ssn != end_ssn);
2280     ampdu_tid->timestamp = check_jiffies;
2281     return has_retry;
2282 }
ssv6xxx_ampdu_check_timeout(struct ieee80211_hw * hw)2283 void ssv6xxx_ampdu_check_timeout (struct ieee80211_hw *hw)
2284 {
2285     struct ssv_softc *sc = hw->priv;
2286     struct AMPDU_TID_st *cur_AMPDU_TID;
2287     if (!list_empty(&sc->tx.ampdu_tx_que))
2288     {
2289         list_for_each_entry_rcu(cur_AMPDU_TID, &sc->tx.ampdu_tx_que, list)
2290         {
2291             u32 has_retry;
2292             if (cur_AMPDU_TID->state != AMPDU_STATE_OPERATION)
2293                 continue;
2294             has_retry = _check_timeout(cur_AMPDU_TID);
2295             if (has_retry)
2296             {
2297                 _collect_retry_frames(cur_AMPDU_TID);
2298                 ssv6200_ampdu_send_retry(sc->hw, cur_AMPDU_TID, &cur_AMPDU_TID->retry_queue,
2299                                          true);
2300             }
2301         }
2302     }
2303 }
ssv6xxx_ampdu_sent(struct ieee80211_hw * hw,struct sk_buff * ampdu)2304 void ssv6xxx_ampdu_sent(struct ieee80211_hw *hw, struct sk_buff *ampdu)
2305 {
2306     struct ssv_softc *sc = hw->priv;
2307     struct ampdu_hdr_st *ampdu_hdr = (struct ampdu_hdr_st *) ampdu->head;
2308     struct sk_buff *mpdu;
2309     unsigned long cur_jiffies = jiffies;
2310     int i;
2311     SKB_info *mpdu_skb_info;
2312     u16 ssn;
2313     if (ampdu_hdr->ampdu_tid->state != AMPDU_STATE_OPERATION)
2314         return;
2315     spin_lock_bh(&ampdu_hdr->ampdu_tid->pkt_array_lock);
2316     for (i = 0; i < ampdu_hdr->mpdu_num; i++)
2317     {
2318         ssn = ampdu_hdr->ssn[i];
2319         mpdu = INDEX_PKT_BY_SSN(ampdu_hdr->ampdu_tid, ssn);
2320         if (mpdu == NULL)
2321         {
2322             dev_err(sc->dev, "T%d-%d is a NULL MPDU.\n",
2323                     ampdu_hdr->ampdu_tid->tidno, ssn);
2324             continue;
2325         }
2326         if (ampdu_skb_ssn(mpdu) != ssn)
2327         {
2328             dev_err(sc->dev, "T%d-%d does not match %d MPDU.\n",
2329                     ampdu_hdr->ampdu_tid->tidno, ssn, ampdu_skb_ssn(mpdu));
2330             continue;
2331         }
2332         mpdu_skb_info = (SKB_info *) (mpdu->head);
2333         mpdu_skb_info->aggr_timestamp = cur_jiffies;
2334         mpdu_skb_info->ampdu_tx_status = AMPDU_ST_SENT;
2335     }
2336     spin_unlock_bh(&ampdu_hdr->ampdu_tid->pkt_array_lock);
2337 }
2338