2 * Copyright (c) 2007-2008 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Module Name : queue.c */
20 /* This module contains queue management functions. */
25 /************************************************************************/
30 struct zsQueue
* zfQueueCreate(zdev_t
* dev
, u16_t size
)
34 q
= (struct zsQueue
*)zfwMemAllocate(dev
, sizeof(struct zsQueue
)
35 + (sizeof(struct zsQueueCell
)*(size
-1)));
46 void zfQueueDestroy(zdev_t
* dev
, struct zsQueue
* q
)
48 u16_t size
= sizeof(struct zsQueue
) + (sizeof(struct zsQueueCell
)*(q
->size
-1));
51 zfwMemFree(dev
, q
, size
);
56 u16_t
zfQueuePutNcs(zdev_t
* dev
, struct zsQueue
* q
, zbuf_t
* buf
, u32_t tick
)
58 u16_t ret
= ZM_ERR_QUEUE_FULL
;
60 zm_msg0_mm(ZM_LV_1
, "zfQueuePutNcs()");
62 if (((q
->tail
+1)&q
->sizeMask
) != q
->head
)
64 q
->cell
[q
->tail
].buf
= buf
;
65 q
->cell
[q
->tail
].tick
= tick
;
66 q
->tail
= (q
->tail
+1) & q
->sizeMask
;
73 u16_t
zfQueuePut(zdev_t
* dev
, struct zsQueue
* q
, zbuf_t
* buf
, u32_t tick
)
76 zmw_declare_for_critical_section();
78 zmw_enter_critical_section(dev
);
80 ret
= zfQueuePutNcs(dev
, q
, buf
, tick
);
82 zmw_leave_critical_section(dev
);
87 zbuf_t
* zfQueueGet(zdev_t
* dev
, struct zsQueue
* q
)
90 zmw_declare_for_critical_section();
92 zmw_enter_critical_section(dev
);
94 if (q
->head
!= q
->tail
)
96 buf
= q
->cell
[q
->head
].buf
;
97 q
->head
= (q
->head
+1) & q
->sizeMask
;
100 zmw_leave_critical_section(dev
);
105 u16_t
zfCompareDstwithBuf(zdev_t
* dev
, zbuf_t
* buf
, u8_t
* addr
)
112 dst
[i
] = zmw_buf_readb(dev
, buf
, i
);
113 if (dst
[i
] != addr
[i
])
123 zbuf_t
* zfQueueGetWithMac(zdev_t
* dev
, struct zsQueue
* q
, u8_t
* addr
, u8_t
* mb
)
126 zbuf_t
* retBuf
= NULL
;
128 zmw_declare_for_critical_section();
132 zmw_enter_critical_section(dev
);
138 if (index
!= q
->tail
)
140 buf
= q
->cell
[index
].buf
;
142 //if buf's detination address == input addr
143 if (zfCompareDstwithBuf(dev
, buf
, addr
) == 0)
146 //Get it, and trace the whole queue to calculate more bit
147 while ((next
=((index
+1)&q
->sizeMask
)) != q
->tail
)
149 q
->cell
[index
].buf
= q
->cell
[next
].buf
;
150 q
->cell
[index
].tick
= q
->cell
[next
].tick
;
152 if ((*mb
== 0) && (zfCompareDstwithBuf(dev
,
153 q
->cell
[next
].buf
, addr
) == 0))
160 q
->tail
= (q
->tail
-1) & q
->sizeMask
;
162 zmw_leave_critical_section(dev
);
165 index
= (index
+ 1) & q
->sizeMask
;
166 } //if (index != q->tail)
173 zmw_leave_critical_section(dev
);
179 void zfQueueFlush(zdev_t
* dev
, struct zsQueue
* q
)
183 while ((buf
= zfQueueGet(dev
, q
)) != NULL
)
185 zfwBufFree(dev
, buf
, 0);
191 void zfQueueAge(zdev_t
* dev
, struct zsQueue
* q
, u32_t tick
, u32_t msAge
)
195 zmw_declare_for_critical_section();
200 zmw_enter_critical_section(dev
);
202 if (q
->head
!= q
->tail
)
204 buftick
= q
->cell
[q
->head
].tick
;
205 if (((tick
- buftick
)*ZM_MS_PER_TICK
) > msAge
)
207 buf
= q
->cell
[q
->head
].buf
;
208 q
->head
= (q
->head
+1) & q
->sizeMask
;
212 zmw_leave_critical_section(dev
);
216 zm_msg0_mm(ZM_LV_0
, "Age frame in queue!");
217 zfwBufFree(dev
, buf
, 0);
228 u8_t
zfQueueRemovewithIndex(zdev_t
* dev
, struct zsQueue
* q
, u16_t index
, u8_t
* addr
)
233 //trace the whole queue to calculate more bit
234 while ((next
=((index
+1)&q
->sizeMask
)) != q
->tail
)
236 q
->cell
[index
].buf
= q
->cell
[next
].buf
;
237 q
->cell
[index
].tick
= q
->cell
[next
].tick
;
239 if ((mb
== 0) && (zfCompareDstwithBuf(dev
,
240 q
->cell
[next
].buf
, addr
) == 0))
247 q
->tail
= (q
->tail
-1) & q
->sizeMask
;
253 void zfQueueGenerateUapsdTim(zdev_t
* dev
, struct zsQueue
* q
,
254 u8_t
* uniBitMap
, u16_t
* highestByte
)
258 u16_t id
, aid
, index
, i
;
261 zmw_get_wlan_dev(dev
);
262 zmw_declare_for_critical_section();
264 zmw_enter_critical_section(dev
);
268 while (index
!= q
->tail
)
270 psBuf
= q
->cell
[index
].buf
;
273 dst
[i
] = zmw_buf_readb(dev
, psBuf
, i
);
275 /* TODO : use u8_t* fot MAC address */
276 if (((id
= zfApFindSta(dev
, (u16_t
*)dst
)) != 0xffff)
277 && (wd
->ap
.staTable
[id
].psMode
!= 0))
279 /* Calculate PVB only when all AC are delivery-enabled */
280 if ((wd
->ap
.staTable
[id
].qosInfo
& 0xf) == 0xf)
283 bitPosition
= (1 << (aid
& 0x7));
284 bytePosition
= (aid
>> 3);
285 uniBitMap
[bytePosition
] |= bitPosition
;
287 if (bytePosition
>*highestByte
)
289 *highestByte
= bytePosition
;
292 index
= (index
+1) & q
->sizeMask
;
296 /* Free garbage UAPSD frame */
297 zfQueueRemovewithIndex(dev
, q
, index
, dst
);
298 zfwBufFree(dev
, psBuf
, 0);
301 zmw_leave_critical_section(dev
);