Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(512)

Side by Side Diff: chromeos/drivers/ath6kl/reorder/rcv_aggr.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright (c) 2009 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as
9 // published by the Free Software Foundation;
10 //
11 // Software distributed under the License is distributed on an "AS
12 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 // implied. See the License for the specific language governing
14 // rights and limitations under the License.
15 //
16 //
17 *
18 */
19
20 #ifdef ATH_AR6K_11N_SUPPORT
21
22 #include <a_config.h>
23 #include <athdefs.h>
24 #include <a_types.h>
25 #include <a_osapi.h>
26 #include "pkt_log.h"
27 #include "aggr_recv_api.h"
28 #include "aggr_rx_internal.h"
29 #include "wmi.h"
30
31 extern A_STATUS
32 wmi_dot3_2_dix(void *osbuf);
33
34 static void
35 aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf);
36
37 static void
38 aggr_timeout(unsigned long arg);
39
40 static void
41 aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order);
42
43 static void
44 aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q);
45
46 static void *
47 aggr_get_osbuf(AGGR_INFO *p_aggr);
48
49 void *
50 aggr_init(ALLOC_NETBUFS netbuf_allocator)
51 {
52 AGGR_INFO *p_aggr = NULL;
53 RXTID *rxtid;
54 A_UINT8 i;
55 A_STATUS status = A_OK;
56
57 A_PRINTF("In aggr_init..\n");
58
59 do {
60 p_aggr = A_MALLOC(sizeof(AGGR_INFO));
61 if(!p_aggr) {
62 A_PRINTF("Failed to allocate memory for aggr_node\n");
63 status = A_ERROR;
64 break;
65 }
66
67 /* Init timer and data structures */
68 A_MEMZERO(p_aggr, sizeof(AGGR_INFO));
69 p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
70 A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
71 p_aggr->timerScheduled = FALSE;
72 A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
73
74 p_aggr->netbuf_allocator = netbuf_allocator;
75 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
76
77 for(i = 0; i < NUM_OF_TIDS; i++) {
78 rxtid = AGGR_GET_RXTID(p_aggr, i);
79 rxtid->aggr = FALSE;
80 rxtid->progress = FALSE;
81 rxtid->timerMon = FALSE;
82 A_NETBUF_QUEUE_INIT(&rxtid->q);
83 A_MUTEX_INIT(&rxtid->lock);
84 }
85 }while(FALSE);
86
87 A_PRINTF("going out of aggr_init..status %s\n",
88 (status == A_OK) ? "OK":"Error");
89
90 if(status != A_OK) {
91 /* Cleanup */
92 aggr_module_destroy(p_aggr);
93 }
94 return ((status == A_OK) ? p_aggr : NULL);
95 }
96
97 /* utility function to clear rx hold_q for a tid */
98 static void
99 aggr_delete_tid_state(AGGR_INFO *p_aggr, A_UINT8 tid)
100 {
101 RXTID *rxtid;
102 RXTID_STATS *stats;
103
104 A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
105
106 rxtid = AGGR_GET_RXTID(p_aggr, tid);
107 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
108
109 if(rxtid->aggr) {
110 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
111 }
112
113 rxtid->aggr = FALSE;
114 rxtid->progress = FALSE;
115 rxtid->timerMon = FALSE;
116 rxtid->win_sz = 0;
117 rxtid->seq_next = 0;
118 rxtid->hold_q_sz = 0;
119
120 if(rxtid->hold_q) {
121 A_FREE(rxtid->hold_q);
122 rxtid->hold_q = NULL;
123 }
124
125 A_MEMZERO(stats, sizeof(RXTID_STATS));
126 }
127
128 void
129 aggr_module_destroy(void *cntxt)
130 {
131 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
132 RXTID *rxtid;
133 A_UINT8 i, k;
134
135 A_PRINTF("%s(): aggr = %p\n",__func__, p_aggr);
136 A_ASSERT(p_aggr);
137
138 if(p_aggr) {
139 if(p_aggr->timerScheduled) {
140 A_UNTIMEOUT(&p_aggr->timer);
141 p_aggr->timerScheduled = FALSE;
142 }
143
144 for(i = 0; i < NUM_OF_TIDS; i++) {
145 rxtid = AGGR_GET_RXTID(p_aggr, i);
146 /* Free the hold q contents and hold_q*/
147 if(rxtid->hold_q) {
148 for(k = 0; k< rxtid->hold_q_sz; k++) {
149 if(rxtid->hold_q[k].osbuf) {
150 A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
151 }
152 }
153 A_FREE(rxtid->hold_q);
154 }
155 /* Free the dispatch q contents*/
156 while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
157 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
158 }
159 if (A_IS_MUTEX_VALID(&rxtid->lock)) {
160 A_MUTEX_DELETE(&rxtid->lock);
161 }
162 }
163 /* free the freeQ and its contents*/
164 while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
165 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
166 }
167 A_FREE(p_aggr);
168 }
169 A_PRINTF("out aggr_module_destroy\n");
170 }
171
172
173 void
174 aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
175 {
176 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
177
178 A_ASSERT(p_aggr && fn && dev);
179
180 p_aggr->rx_fn = fn;
181 p_aggr->dev = dev;
182 }
183
184
185 void
186 aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no)
187 {
188 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
189 RXTID_STATS *stats;
190
191 A_ASSERT(p_aggr);
192 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
193 stats->num_bar++;
194
195 aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
196 }
197
198
199 void
200 aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_s z)
201 {
202 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
203 RXTID *rxtid;
204 RXTID_STATS *stats;
205
206 A_ASSERT(p_aggr);
207 rxtid = AGGR_GET_RXTID(p_aggr, tid);
208 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
209
210 A_PRINTF("%s(): win_sz = %d aggr %d\n", __func__, win_sz, rxtid->aggr);
211
212 if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
213 A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
214 }
215
216 if(rxtid->aggr) {
217 /* Just go and deliver all the frames up from this
218 * queue, as if we got DELBA and re-initialize the queue
219 */
220 aggr_delete_tid_state(p_aggr, tid);
221 }
222
223 rxtid->seq_next = seq_no;
224 /* create these queues, only upon receiving of ADDBA for a
225 * tid, reducing memory requirement
226 */
227 rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
228 if((rxtid->hold_q == NULL)) {
229 A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
230 A_ASSERT(0);
231 }
232 A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));
233
234 /* Update rxtid for the window sz */
235 rxtid->win_sz = win_sz;
236 /* hold_q_sz inicates the depth of holding q - which is
237 * a factor of win_sz. Compute once, as it will be used often
238 */
239 rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
240 /* There should be no frames on q - even when second ADDBA comes in.
241 * If aggr was previously ON on this tid, we would have cleaned up
242 * the q
243 */
244 if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
245 A_PRINTF("ERROR: Frames still on queue ?\n");
246 A_ASSERT(0);
247 }
248
249 rxtid->aggr = TRUE;
250 }
251
252 void
253 aggr_recv_delba_req_evt(void *cntxt, A_UINT8 tid)
254 {
255 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
256 RXTID *rxtid;
257
258 A_ASSERT(p_aggr);
259 A_PRINTF("%s(): tid %d\n", __func__, tid);
260
261 rxtid = AGGR_GET_RXTID(p_aggr, tid);
262
263 if(rxtid->aggr) {
264 aggr_delete_tid_state(p_aggr, tid);
265 }
266 }
267
268 static void
269 aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order)
270 {
271 RXTID *rxtid;
272 OSBUF_HOLD_Q *node;
273 A_UINT16 idx, idx_end, seq_end;
274 RXTID_STATS *stats;
275
276 A_ASSERT(p_aggr);
277 rxtid = AGGR_GET_RXTID(p_aggr, tid);
278 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
279
280 /* idx is absolute location for first frame */
281 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
282
283 /* idx_end is typically the last possible frame in the window,
284 * but changes to 'the' seq_no, when BAR comes. If seq_no
285 * is non-zero, we will go up to that and stop.
286 * Note: last seq no in current window will occupy the same
287 * index position as index that is just previous to start.
288 * An imp point : if win_sz is 7, for seq_no space of 4095,
289 * then, there would be holes when sequence wrap around occurs.
290 * Target should judiciously choose the win_sz, based on
291 * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
292 * 2, 4, 8, 16 win_sz works fine).
293 * We must deque from "idx" to "idx_end", including both.
294 */
295 seq_end = (seq_no) ? seq_no : rxtid->seq_next;
296 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
297
298 /* Critical section begins */
299 A_MUTEX_LOCK(&rxtid->lock);
300 do {
301
302 node = &rxtid->hold_q[idx];
303
304 if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
305 break;
306
307 /* chain frames and deliver frames bcos:
308 * 1. either the frames are in order and window is contiguous, OR
309 * 2. we need to deque frames, irrespective of holes
310 */
311 if(node->osbuf) {
312 if(node->is_amsdu) {
313 aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
314 } else {
315 A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
316 }
317 node->osbuf = NULL;
318 } else {
319 stats->num_hole++;
320 }
321
322 /* window is moving */
323 rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
324 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
325 } while(idx != idx_end);
326 /* Critical section ends */
327 A_MUTEX_UNLOCK(&rxtid->lock);
328
329 stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
330 aggr_dispatch_frames(p_aggr, &rxtid->q);
331 }
332
333 static void *
334 aggr_get_osbuf(AGGR_INFO *p_aggr)
335 {
336 void *buf = NULL;
337
338 /* Starving for buffers? get more from OS
339 * check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
340 * re-allocate bufs if so
341 * allocate a free buf from freeQ
342 */
343 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
344 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
345 }
346
347 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
348 buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
349 }
350
351 return buf;
352 }
353
354
355 static void
356 aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf)
357 {
358 void *new_buf;
359 A_UINT16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
360 A_UINT8 *framep;
361
362 /* Frame format at this point:
363 * [DIX hdr | 802.3 | 802.3 | ... | 802.3]
364 *
365 * Strip the DIX header.
366 * Iterate through the osbuf and do:
367 * grab a free netbuf from freeQ
368 * find the start and end of a frame
369 * copy it to netbuf(Vista can do better here)
370 * convert all msdu's(802.3) frames to upper layer format - os routine
371 * -for now lets convert from 802.3 to dix
372 * enque this to dispatch q of tid
373 * repeat
374 * free the osbuf - to OS. It's been sliced.
375 */
376
377 mac_hdr_len = sizeof(ATH_MAC_HDR);
378 framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
379 amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;
380
381 while(amsdu_len > mac_hdr_len) {
382 /* Begin of a 802.3 frame */
383 payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
384 #define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
385 #define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
386 if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
387 A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8 023_len);
388 break;
389 }
390 frame_8023_len = payload_8023_len + mac_hdr_len;
391 new_buf = aggr_get_osbuf(p_aggr);
392 if(new_buf == NULL) {
393 A_PRINTF("No buffer available \n");
394 break;
395 }
396
397 A_MEMCPY(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
398 A_NETBUF_PUT(new_buf, frame_8023_len);
399 if (wmi_dot3_2_dix(new_buf) != A_OK) {
400 A_PRINTF("dot3_2_dix err..\n");
401 A_NETBUF_FREE(new_buf);
402 break;
403 }
404
405 A_NETBUF_ENQUEUE(&rxtid->q, new_buf);
406
407 /* Is this the last subframe within this aggregate ? */
408 if ((amsdu_len - frame_8023_len) == 0) {
409 break;
410 }
411
412 /* Add the length of A-MSDU subframe padding bytes -
413 * Round to nearest word.
414 */
415 frame_8023_len = ((frame_8023_len + 3) & ~3);
416
417 framep += frame_8023_len;
418 amsdu_len -= frame_8023_len;
419 }
420
421 A_NETBUF_FREE(*osbuf);
422 *osbuf = NULL;
423 }
424
425 void
426 aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu , void **osbuf)
427 {
428 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
429 RXTID *rxtid;
430 RXTID_STATS *stats;
431 A_UINT16 idx, st, cur, end;
432 A_UINT16 *log_idx;
433 OSBUF_HOLD_Q *node;
434 PACKET_LOG *log;
435
436 A_ASSERT(p_aggr);
437 A_ASSERT(tid < NUM_OF_TIDS);
438
439 rxtid = AGGR_GET_RXTID(p_aggr, tid);
440 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
441
442 stats->num_into_aggr++;
443
444 if(!rxtid->aggr) {
445 if(is_amsdu) {
446 aggr_slice_amsdu(p_aggr, rxtid, osbuf);
447 stats->num_amsdu++;
448 aggr_dispatch_frames(p_aggr, &rxtid->q);
449 }
450 return;
451 }
452
453 /* Check the incoming sequence no, if it's in the window */
454 st = rxtid->seq_next;
455 cur = seq_no;
456 end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
457 /* Log the pkt info for future analysis */
458 log = &p_aggr->pkt_log;
459 log_idx = &log->last_idx;
460 log->info[*log_idx].cur = cur;
461 log->info[*log_idx].st = st;
462 log->info[*log_idx].end = end;
463 *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);
464
465 if(((st < end) && (cur < st || cur > end)) ||
466 ((st > end) && (cur > end) && (cur < st))) {
467 /* the cur frame is outside the window. Since we know
468 * our target would not do this without reason it must
469 * be assumed that the window has moved for some valid reason.
470 * Therefore, we dequeue all frames and start fresh.
471 */
472 A_UINT16 extended_end;
473
474 extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
475
476 if(((end < extended_end) && (cur < end || cur > extended_end)) ||
477 ((end > extended_end) && (cur > extended_end) && (cur < end))) {
478 // dequeue all frames in queue and shift window to new frame
479 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
480 //set window start so that new frame is last frame in window
481 if(cur >= rxtid->hold_q_sz-1) {
482 rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
483 }else{
484 rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - c ur);
485 }
486 } else {
487 // dequeue only those frames that are outside the new shifted window
488 if(cur >= rxtid->hold_q_sz-1) {
489 st = cur - (rxtid->hold_q_sz-1);
490 }else{
491 st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
492 }
493
494 aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
495 }
496
497 stats->num_oow++;
498 }
499
500 idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
501
502 /*enque the frame, in hold_q */
503 node = &rxtid->hold_q[idx];
504
505 A_MUTEX_LOCK(&rxtid->lock);
506 if(node->osbuf) {
507 /* Is the cur frame duplicate or something beyond our
508 * window(hold_q -> which is 2x, already)?
509 * 1. Duplicate is easy - drop incoming frame.
510 * 2. Not falling in current sliding window.
511 * 2a. is the frame_seq_no preceding current tid_seq_no?
512 * -> drop the frame. perhaps sender did not get our ACK.
513 * this is taken care of above.
514 * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
515 * -> Taken care of it above, by moving window forward.
516 *
517 */
518 A_NETBUF_FREE(node->osbuf);
519 stats->num_dups++;
520 }
521
522 node->osbuf = *osbuf;
523 node->is_amsdu = is_amsdu;
524 node->seq_no = seq_no;
525 if(node->is_amsdu) {
526 stats->num_amsdu++;
527 } else {
528 stats->num_mpdu++;
529 }
530 A_MUTEX_UNLOCK(&rxtid->lock);
531
532 *osbuf = NULL;
533 aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
534
535 if(p_aggr->timerScheduled) {
536 rxtid->progress = TRUE;
537 }else{
538 for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
539 if(rxtid->hold_q[idx].osbuf) {
540 /* there is a frame in the queue and no timer so
541 * start a timer to ensure that the frame doesn't remain
542 * stuck forever. */
543 p_aggr->timerScheduled = TRUE;
544 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
545 rxtid->progress = FALSE;
546 rxtid->timerMon = TRUE;
547 break;
548 }
549 }
550 }
551 }
552
553 /*
554 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
555 * hold Q state. Examples include when a Connect event or disconnect event is
556 * received.
557 */
558 void
559 aggr_reset_state(void *cntxt)
560 {
561 A_UINT8 tid;
562 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
563
564 A_ASSERT(p_aggr);
565
566 for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
567 aggr_delete_tid_state(p_aggr, tid);
568 }
569 }
570
571
572 static void
573 aggr_timeout(unsigned long arg)
574 {
575 A_UINT16 i,j;
576 AGGR_INFO *p_aggr = (AGGR_INFO *)arg;
577 RXTID *rxtid;
578 RXTID_STATS *stats;
579 /*
580 * If the q for which the timer was originally started has
581 * not progressed then it is necessary to dequeue all the
582 * contained frames so that they are not held forever.
583 */
584 for(i = 0; i < NUM_OF_TIDS; i++) {
585 rxtid = AGGR_GET_RXTID(p_aggr, i);
586 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
587
588 if(rxtid->aggr == FALSE ||
589 rxtid->timerMon == FALSE ||
590 rxtid->progress == TRUE) {
591 continue;
592 }
593 // dequeue all frames in for this tid
594 stats->num_timeouts++;
595 A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxti d->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
596 aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
597 }
598
599 p_aggr->timerScheduled = FALSE;
600 // determine whether a new timer should be started.
601 for(i = 0; i < NUM_OF_TIDS; i++) {
602 rxtid = AGGR_GET_RXTID(p_aggr, i);
603
604 if(rxtid->aggr == TRUE && rxtid->hold_q) {
605 for(j = 0 ; j < rxtid->hold_q_sz ; j++)
606 {
607 if(rxtid->hold_q[j].osbuf)
608 {
609 p_aggr->timerScheduled = TRUE;
610 rxtid->timerMon = TRUE;
611 rxtid->progress = FALSE;
612 break;
613 }
614 }
615
616 if(j >= rxtid->hold_q_sz) {
617 rxtid->timerMon = FALSE;
618 }
619 }
620 }
621
622 if(p_aggr->timerScheduled) {
623 /* Rearm the timer*/
624 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
625 }
626
627 }
628
629 static void
630 aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q)
631 {
632 void *osbuf;
633
634 while((osbuf = A_NETBUF_DEQUEUE(q))) {
635 p_aggr->rx_fn(p_aggr->dev, osbuf);
636 }
637 }
638
639 void
640 aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
641 {
642 AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
643 RXTID *rxtid;
644 RXTID_STATS *stats;
645 A_UINT8 i;
646
647 *log_buf = &p_aggr->pkt_log;
648 A_PRINTF("\n\n================================================\n");
649 A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, h oles, bar, seq_next\n");
650 for(i = 0; i < NUM_OF_TIDS; i++) {
651 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
652 rxtid = AGGR_GET_RXTID(p_aggr, i);
653 A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_agg r, stats->num_dups,
654 stats->num_oow, stats->num_mpdu,
655 stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
656 stats->num_hole, stats->num_bar,
657 rxtid->seq_next);
658 }
659 A_PRINTF("================================================\n\n");
660
661 }
662
663 #endif /* ATH_AR6K_11N_SUPPORT */
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/reorder/makefile ('k') | chromeos/drivers/ath6kl/wlan/include/ieee80211.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698