~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/ath6kl/reorder/rcv_aggr.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 *
22
22
 */
23
23
 
24
 
#ifdef  ATH_AR6K_11N_SUPPORT
25
 
 
26
24
#include <a_config.h>
27
25
#include <athdefs.h>
28
 
#include <a_types.h>
29
26
#include <a_osapi.h>
30
27
#include <a_debug.h>
31
28
#include "pkt_log.h"
33
30
#include "aggr_rx_internal.h"
34
31
#include "wmi.h"
35
32
 
36
 
extern A_STATUS
 
33
extern int
37
34
wmi_dot3_2_dix(void *osbuf);
38
35
 
39
36
static void
40
 
aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf);
41
 
 
42
 
static void
43
 
aggr_timeout(A_ATH_TIMER arg);
44
 
 
45
 
static void
46
 
aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order);
47
 
 
48
 
static void
49
 
aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q);
 
37
aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);
 
38
 
 
39
static void
 
40
aggr_timeout(unsigned long arg);
 
41
 
 
42
static void
 
43
aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);
 
44
 
 
45
static void
 
46
aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q);
50
47
 
51
48
static void *
52
 
aggr_get_osbuf(AGGR_INFO *p_aggr);
 
49
aggr_get_osbuf(struct aggr_info *p_aggr);
53
50
 
54
51
void *
55
52
aggr_init(ALLOC_NETBUFS netbuf_allocator)
56
53
{
57
 
    AGGR_INFO   *p_aggr = NULL;
58
 
    RXTID *rxtid;
59
 
    A_UINT8 i;
60
 
    A_STATUS status = A_OK;
 
54
    struct aggr_info   *p_aggr = NULL;
 
55
    struct rxtid *rxtid;
 
56
    u8 i;
 
57
    int status = 0;
61
58
 
62
59
    A_PRINTF("In aggr_init..\n");
63
60
 
64
61
    do {
65
 
        p_aggr = A_MALLOC(sizeof(AGGR_INFO));
 
62
        p_aggr = A_MALLOC(sizeof(struct aggr_info));
66
63
        if(!p_aggr) {
67
64
            A_PRINTF("Failed to allocate memory for aggr_node\n");
68
65
            status = A_ERROR;
70
67
        }
71
68
 
72
69
        /* Init timer and data structures */
73
 
        A_MEMZERO(p_aggr, sizeof(AGGR_INFO));
 
70
        A_MEMZERO(p_aggr, sizeof(struct aggr_info));
74
71
        p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
75
72
        A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
76
 
        p_aggr->timerScheduled = FALSE;
 
73
        p_aggr->timerScheduled = false;
77
74
        A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
78
75
 
79
76
        p_aggr->netbuf_allocator = netbuf_allocator;
81
78
 
82
79
        for(i = 0; i < NUM_OF_TIDS; i++) {
83
80
            rxtid = AGGR_GET_RXTID(p_aggr, i);
84
 
            rxtid->aggr = FALSE;
85
 
            rxtid->progress = FALSE;
86
 
            rxtid->timerMon = FALSE;
 
81
            rxtid->aggr = false;
 
82
            rxtid->progress = false;
 
83
            rxtid->timerMon = false;
87
84
            A_NETBUF_QUEUE_INIT(&rxtid->q);
88
85
            A_MUTEX_INIT(&rxtid->lock);
89
86
        }
90
 
    }while(FALSE);
 
87
    }while(false);
91
88
 
92
89
    A_PRINTF("going out of aggr_init..status %s\n",
93
 
                    (status == A_OK) ? "OK":"Error");
 
90
                    (status == 0) ? "OK":"Error");
94
91
 
95
 
    if(status != A_OK) {
 
92
    if (status) {
96
93
        /* Cleanup */
97
94
        aggr_module_destroy(p_aggr);
98
95
    }
99
 
    return ((status == A_OK) ? p_aggr : NULL);
 
96
    return ((status == 0) ? p_aggr : NULL);
100
97
}
101
98
 
102
99
/* utility function to clear rx hold_q for a tid */
103
100
static void
104
 
aggr_delete_tid_state(AGGR_INFO *p_aggr, A_UINT8 tid)
 
101
aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
105
102
{
106
 
    RXTID *rxtid;
107
 
    RXTID_STATS *stats;
 
103
    struct rxtid *rxtid;
 
104
    struct rxtid_stats *stats;
108
105
 
109
106
    A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
110
107
 
115
112
        aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
116
113
    }
117
114
 
118
 
    rxtid->aggr = FALSE;
119
 
    rxtid->progress = FALSE;
120
 
    rxtid->timerMon = FALSE;
 
115
    rxtid->aggr = false;
 
116
    rxtid->progress = false;
 
117
    rxtid->timerMon = false;
121
118
    rxtid->win_sz = 0;
122
119
    rxtid->seq_next = 0;
123
120
    rxtid->hold_q_sz = 0;
124
121
 
125
122
    if(rxtid->hold_q) {
126
 
        A_FREE(rxtid->hold_q);
 
123
        kfree(rxtid->hold_q);
127
124
        rxtid->hold_q = NULL;
128
125
    }
129
126
 
130
 
    A_MEMZERO(stats, sizeof(RXTID_STATS));
 
127
    A_MEMZERO(stats, sizeof(struct rxtid_stats));
131
128
}
132
129
 
133
130
void
134
131
aggr_module_destroy(void *cntxt)
135
132
{
136
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
137
 
    RXTID *rxtid;
138
 
    A_UINT8 i, k;
 
133
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
134
    struct rxtid *rxtid;
 
135
    u8 i, k;
139
136
    A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
140
137
    A_ASSERT(p_aggr);
141
138
 
142
139
    if(p_aggr) {
143
140
        if(p_aggr->timerScheduled) {
144
141
            A_UNTIMEOUT(&p_aggr->timer);
145
 
            p_aggr->timerScheduled = FALSE;
 
142
            p_aggr->timerScheduled = false;
146
143
        }
147
144
 
148
145
        for(i = 0; i < NUM_OF_TIDS; i++) {
154
151
                        A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
155
152
                    }
156
153
                }
157
 
                A_FREE(rxtid->hold_q);
 
154
                kfree(rxtid->hold_q);
158
155
            }
159
156
            /* Free the dispatch q contents*/
160
157
            while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
168
165
        while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
169
166
            A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
170
167
        }
171
 
        A_FREE(p_aggr);
 
168
        kfree(p_aggr);
172
169
    }
173
170
    A_PRINTF("out aggr_module_destroy\n");
174
171
}
177
174
void
178
175
aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
179
176
{
180
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
 
177
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
181
178
 
182
179
    A_ASSERT(p_aggr && fn && dev);
183
180
 
187
184
 
188
185
 
189
186
void
190
 
aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no)
 
187
aggr_process_bar(void *cntxt, u8 tid, u16 seq_no)
191
188
{
192
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
193
 
    RXTID_STATS *stats;
 
189
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
190
    struct rxtid_stats *stats;
194
191
 
195
192
    A_ASSERT(p_aggr);
196
193
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
201
198
 
202
199
 
203
200
void
204
 
aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_sz)
 
201
aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz)
205
202
{
206
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
207
 
    RXTID *rxtid;
208
 
    RXTID_STATS *stats;
 
203
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
204
    struct rxtid *rxtid;
 
205
    struct rxtid_stats *stats;
209
206
 
210
207
    A_ASSERT(p_aggr);
211
208
    rxtid = AGGR_GET_RXTID(p_aggr, tid);
249
246
        A_ASSERT(0);
250
247
    }
251
248
 
252
 
    rxtid->aggr = TRUE;
 
249
    rxtid->aggr = true;
253
250
}
254
251
 
255
252
void
256
 
aggr_recv_delba_req_evt(void *cntxt, A_UINT8 tid)
 
253
aggr_recv_delba_req_evt(void *cntxt, u8 tid)
257
254
{
258
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
259
 
    RXTID *rxtid;
 
255
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
256
    struct rxtid *rxtid;
260
257
 
261
258
    A_ASSERT(p_aggr);
262
259
    A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);
269
266
}
270
267
 
271
268
static void
272
 
aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order)
 
269
aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order)
273
270
{
274
 
    RXTID *rxtid;
275
 
    OSBUF_HOLD_Q *node;
276
 
    A_UINT16 idx, idx_end, seq_end;
277
 
    RXTID_STATS *stats;
 
271
    struct rxtid *rxtid;
 
272
    struct osbuf_hold_q *node;
 
273
    u16 idx, idx_end, seq_end;
 
274
    struct rxtid_stats *stats;
278
275
 
279
276
    A_ASSERT(p_aggr);
280
277
    rxtid = AGGR_GET_RXTID(p_aggr, tid);
334
331
}
335
332
 
336
333
static void *
337
 
aggr_get_osbuf(AGGR_INFO *p_aggr)
 
334
aggr_get_osbuf(struct aggr_info *p_aggr)
338
335
{
339
336
    void *buf = NULL;
340
337
 
356
353
 
357
354
 
358
355
static void
359
 
aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf)
 
356
aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf)
360
357
{
361
358
    void *new_buf;
362
 
    A_UINT16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
363
 
    A_UINT8 *framep;
 
359
    u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
 
360
    u8 *framep;
364
361
 
365
362
    /* Frame format at this point:
366
363
     *  [DIX hdr | 802.3 | 802.3 | ... | 802.3]
397
394
            break;
398
395
        }
399
396
 
400
 
        A_MEMCPY(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
 
397
        memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
401
398
        A_NETBUF_PUT(new_buf, frame_8023_len);
402
 
        if (wmi_dot3_2_dix(new_buf) != A_OK) {
 
399
        if (wmi_dot3_2_dix(new_buf) != 0) {
403
400
            A_PRINTF("dot3_2_dix err..\n");
404
401
            A_NETBUF_FREE(new_buf);
405
402
            break;
426
423
}
427
424
 
428
425
void
429
 
aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf)
 
426
aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf)
430
427
{
431
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
432
 
    RXTID *rxtid;
433
 
    RXTID_STATS *stats;
434
 
    A_UINT16 idx, st, cur, end;
435
 
    A_UINT16 *log_idx;
436
 
    OSBUF_HOLD_Q *node;
 
428
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
429
    struct rxtid *rxtid;
 
430
    struct rxtid_stats *stats;
 
431
    u16 idx, st, cur, end;
 
432
    u16 *log_idx;
 
433
    struct osbuf_hold_q *node;
437
434
    PACKET_LOG *log;
438
435
 
439
436
    A_ASSERT(p_aggr);
472
469
         * be assumed that the window has moved for some valid reason.
473
470
         * Therefore, we dequeue all frames and start fresh.
474
471
         */
475
 
        A_UINT16 extended_end;
 
472
        u16 extended_end;
476
473
 
477
474
        extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
478
475
 
536
533
    aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
537
534
 
538
535
    if(p_aggr->timerScheduled) {
539
 
        rxtid->progress = TRUE;
 
536
        rxtid->progress = true;
540
537
    }else{
541
538
        for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
542
539
            if(rxtid->hold_q[idx].osbuf) {
543
540
                /* there is a frame in the queue and no timer so
544
541
                 * start a timer to ensure that the frame doesn't remain
545
542
                 * stuck forever. */
546
 
                p_aggr->timerScheduled = TRUE;
 
543
                p_aggr->timerScheduled = true;
547
544
                A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
548
 
                rxtid->progress = FALSE;
549
 
                rxtid->timerMon = TRUE;
 
545
                rxtid->progress = false;
 
546
                rxtid->timerMon = true;
550
547
                break;
551
548
            }
552
549
        }
561
558
void
562
559
aggr_reset_state(void *cntxt)
563
560
{
564
 
    A_UINT8 tid;
565
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
 
561
    u8 tid;
 
562
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
566
563
 
567
564
    A_ASSERT(p_aggr);
568
565
 
573
570
 
574
571
 
575
572
static void
576
 
aggr_timeout(A_ATH_TIMER arg)
 
573
aggr_timeout(unsigned long arg)
577
574
{
578
 
    A_UINT8 i,j;
579
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)arg;
580
 
    RXTID   *rxtid;
581
 
    RXTID_STATS *stats;
 
575
    u8 i,j;
 
576
    struct aggr_info *p_aggr = (struct aggr_info *)arg;
 
577
    struct rxtid   *rxtid;
 
578
    struct rxtid_stats *stats;
582
579
    /*
583
580
     * If the q for which the timer was originally started has
584
581
     * not progressed then it is necessary to dequeue all the
588
585
        rxtid = AGGR_GET_RXTID(p_aggr, i);
589
586
        stats = AGGR_GET_RXTID_STATS(p_aggr, i);
590
587
 
591
 
        if(rxtid->aggr == FALSE ||
592
 
           rxtid->timerMon == FALSE ||
593
 
           rxtid->progress == TRUE) {
 
588
        if(rxtid->aggr == false ||
 
589
           rxtid->timerMon == false ||
 
590
           rxtid->progress == true) {
594
591
            continue;
595
592
        }
596
593
        // dequeue all frames in for this tid
599
596
        aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
600
597
    }
601
598
 
602
 
    p_aggr->timerScheduled = FALSE;
 
599
    p_aggr->timerScheduled = false;
603
600
    // determine whether a new timer should be started.
604
601
    for(i = 0; i < NUM_OF_TIDS; i++) {
605
602
        rxtid = AGGR_GET_RXTID(p_aggr, i);
606
603
 
607
 
        if(rxtid->aggr == TRUE && rxtid->hold_q) {
 
604
        if(rxtid->aggr == true && rxtid->hold_q) {
608
605
            for(j = 0 ; j < rxtid->hold_q_sz ; j++)
609
606
            {
610
607
                if(rxtid->hold_q[j].osbuf)
611
608
                {
612
 
                    p_aggr->timerScheduled = TRUE;
613
 
                    rxtid->timerMon = TRUE;
614
 
                    rxtid->progress = FALSE;
 
609
                    p_aggr->timerScheduled = true;
 
610
                    rxtid->timerMon = true;
 
611
                    rxtid->progress = false;
615
612
                    break;
616
613
                }
617
614
            }
618
615
 
619
616
            if(j >= rxtid->hold_q_sz) {
620
 
                rxtid->timerMon = FALSE;
 
617
                rxtid->timerMon = false;
621
618
            }
622
619
        }
623
620
    }
630
627
}
631
628
 
632
629
static void
633
 
aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q)
 
630
aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q)
634
631
{
635
632
    void *osbuf;
636
633
 
642
639
void
643
640
aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
644
641
{
645
 
    AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
646
 
    RXTID   *rxtid;
647
 
    RXTID_STATS *stats;
648
 
    A_UINT8 i;
 
642
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
 
643
    struct rxtid   *rxtid;
 
644
    struct rxtid_stats *stats;
 
645
    u8 i;
649
646
 
650
647
    *log_buf = &p_aggr->pkt_log;
651
648
    A_PRINTF("\n\n================================================\n");
662
659
    A_PRINTF("================================================\n\n");
663
660
 
664
661
}
665
 
 
666
 
#endif  /* ATH_AR6K_11N_SUPPORT */