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);