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 if ((q = (struct zsQueue*)zfwMemAllocate(dev, sizeof(struct zsQueue)
35 + (sizeof(struct zsQueueCell)*(size-1)))) != NULL)
45 void zfQueueDestroy(zdev_t* dev, struct zsQueue* q)
47 u16_t size = sizeof(struct zsQueue) + (sizeof(struct zsQueueCell)*(q->size-1));
50 zfwMemFree(dev, q, size);
55 u16_t zfQueuePutNcs(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick)
57 u16_t ret = ZM_ERR_QUEUE_FULL;
59 zm_msg0_mm(ZM_LV_1, "zfQueuePutNcs()");
61 if (((q->tail+1)&q->sizeMask) != q->head)
63 q->cell[q->tail].buf = buf;
64 q->cell[q->tail].tick = tick;
65 q->tail = (q->tail+1) & q->sizeMask;
72 u16_t zfQueuePut(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick)
75 zmw_declare_for_critical_section();
77 zmw_enter_critical_section(dev);
79 ret = zfQueuePutNcs(dev, q, buf, tick);
81 zmw_leave_critical_section(dev);
86 zbuf_t* zfQueueGet(zdev_t* dev, struct zsQueue* q)
89 zmw_declare_for_critical_section();
91 zmw_enter_critical_section(dev);
93 if (q->head != q->tail)
95 buf = q->cell[q->head].buf;
96 q->head = (q->head+1) & q->sizeMask;
99 zmw_leave_critical_section(dev);
104 u16_t zfCompareDstwithBuf(zdev_t* dev, zbuf_t* buf, u8_t* addr)
111 dst[i] = zmw_buf_readb(dev, buf, i);
112 if (dst[i] != addr[i])
122 zbuf_t* zfQueueGetWithMac(zdev_t* dev, struct zsQueue* q, u8_t* addr, u8_t* mb)
125 zbuf_t* retBuf = NULL;
127 zmw_declare_for_critical_section();
131 zmw_enter_critical_section(dev);
137 if (index != q->tail)
139 buf = q->cell[index].buf;
141 //if buf's detination address == input addr
142 if (zfCompareDstwithBuf(dev, buf, addr) == 0)
145 //Get it, and trace the whole queue to calculate more bit
146 while ((next =((index+1)&q->sizeMask)) != q->tail)
148 q->cell[index].buf = q->cell[next].buf;
149 q->cell[index].tick = q->cell[next].tick;
151 if ((*mb == 0) && (zfCompareDstwithBuf(dev,
152 q->cell[next].buf, addr) == 0))
159 q->tail = (q->tail-1) & q->sizeMask;
161 zmw_leave_critical_section(dev);
164 index = (index + 1) & q->sizeMask;
165 } //if (index != q->tail)
172 zmw_leave_critical_section(dev);
178 void zfQueueFlush(zdev_t* dev, struct zsQueue* q)
182 while ((buf = zfQueueGet(dev, q)) != NULL)
184 zfwBufFree(dev, buf, 0);
190 void zfQueueAge(zdev_t* dev, struct zsQueue* q, u32_t tick, u32_t msAge)
194 zmw_declare_for_critical_section();
199 zmw_enter_critical_section(dev);
201 if (q->head != q->tail)
203 buftick = q->cell[q->head].tick;
204 if (((tick - buftick)*ZM_MS_PER_TICK) > msAge)
206 buf = q->cell[q->head].buf;
207 q->head = (q->head+1) & q->sizeMask;
211 zmw_leave_critical_section(dev);
215 zm_msg0_mm(ZM_LV_0, "Age frame in queue!");
216 zfwBufFree(dev, buf, 0);
227 u8_t zfQueueRemovewithIndex(zdev_t* dev, struct zsQueue* q, u16_t index, u8_t* addr)
232 //trace the whole queue to calculate more bit
233 while ((next =((index+1)&q->sizeMask)) != q->tail)
235 q->cell[index].buf = q->cell[next].buf;
236 q->cell[index].tick = q->cell[next].tick;
238 if ((mb == 0) && (zfCompareDstwithBuf(dev,
239 q->cell[next].buf, addr) == 0))
246 q->tail = (q->tail-1) & q->sizeMask;
252 void zfQueueGenerateUapsdTim(zdev_t* dev, struct zsQueue* q,
253 u8_t* uniBitMap, u16_t* highestByte)
257 u16_t id, aid, index, i;
260 zmw_get_wlan_dev(dev);
261 zmw_declare_for_critical_section();
263 zmw_enter_critical_section(dev);
267 while (index != q->tail)
269 psBuf = q->cell[index].buf;
272 dst[i] = zmw_buf_readb(dev, psBuf, i);
274 /* TODO : use u8_t* fot MAC address */
275 if (((id = zfApFindSta(dev, (u16_t*)dst)) != 0xffff)
276 && (wd->ap.staTable[id].psMode != 0))
278 /* Calculate PVB only when all AC are delivery-enabled */
279 if ((wd->ap.staTable[id].qosInfo & 0xf) == 0xf)
282 bitPosition = (1 << (aid & 0x7));
283 bytePosition = (aid >> 3);
284 uniBitMap[bytePosition] |= bitPosition;
286 if (bytePosition>*highestByte)
288 *highestByte = bytePosition;
291 index = (index+1) & q->sizeMask;
295 /* Free garbage UAPSD frame */
296 zfQueueRemovewithIndex(dev, q, index, dst);
297 zfwBufFree(dev, psBuf, 0);
300 zmw_leave_critical_section(dev);