RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / otus / 80211core / queue.c
blob29be4bdb40a419a3ad7c4a1fd7a009cd39a9aaf3
1 /*
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.
16 /* */
17 /* Module Name : queue.c */
18 /* */
19 /* Abstract */
20 /* This module contains queue management functions. */
21 /* */
22 /* NOTES */
23 /* None */
24 /* */
25 /************************************************************************/
26 #include "cprecomp.h"
27 #include "queue.h"
30 struct zsQueue* zfQueueCreate(zdev_t* dev, u16_t size)
32 struct zsQueue* q;
34 q = (struct zsQueue*)zfwMemAllocate(dev, sizeof(struct zsQueue)
35 + (sizeof(struct zsQueueCell)*(size-1)));
36 if (q != NULL)
38 q->size = size;
39 q->sizeMask = size-1;
40 q->head = 0;
41 q->tail = 0;
43 return q;
46 void zfQueueDestroy(zdev_t* dev, struct zsQueue* q)
48 u16_t size = sizeof(struct zsQueue) + (sizeof(struct zsQueueCell)*(q->size-1));
50 zfQueueFlush(dev, q);
51 zfwMemFree(dev, q, size);
53 return;
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;
67 ret = ZM_SUCCESS;
70 return ret;
73 u16_t zfQueuePut(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick)
75 u16_t ret;
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);
84 return ret;
87 zbuf_t* zfQueueGet(zdev_t* dev, struct zsQueue* q)
89 zbuf_t* buf = NULL;
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);
102 return buf;
105 u16_t zfCompareDstwithBuf(zdev_t* dev, zbuf_t* buf, u8_t* addr)
107 u16_t i;
108 u8_t dst[6];
110 for (i=0; i<6; i++)
112 dst[i] = zmw_buf_readb(dev, buf, i);
113 if (dst[i] != addr[i])
115 return 1+i;
119 return 0;
123 zbuf_t* zfQueueGetWithMac(zdev_t* dev, struct zsQueue* q, u8_t* addr, u8_t* mb)
125 zbuf_t* buf;
126 zbuf_t* retBuf = NULL;
127 u16_t index, next;
128 zmw_declare_for_critical_section();
130 *mb = 0;
132 zmw_enter_critical_section(dev);
134 index = q->head;
136 while (1)
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)
145 retBuf = buf;
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))
155 *mb = 1;
158 index = next;
160 q->tail = (q->tail-1) & q->sizeMask;
162 zmw_leave_critical_section(dev);
163 return retBuf;
165 index = (index + 1) & q->sizeMask;
166 } //if (index != q->tail)
167 else
169 break;
173 zmw_leave_critical_section(dev);
175 return retBuf;
179 void zfQueueFlush(zdev_t* dev, struct zsQueue* q)
181 zbuf_t* buf;
183 while ((buf = zfQueueGet(dev, q)) != NULL)
185 zfwBufFree(dev, buf, 0);
188 return;
191 void zfQueueAge(zdev_t* dev, struct zsQueue* q, u32_t tick, u32_t msAge)
193 zbuf_t* buf;
194 u32_t buftick;
195 zmw_declare_for_critical_section();
197 while (1)
199 buf = NULL;
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);
214 if (buf != NULL)
216 zm_msg0_mm(ZM_LV_0, "Age frame in queue!");
217 zfwBufFree(dev, buf, 0);
219 else
221 break;
224 return;
228 u8_t zfQueueRemovewithIndex(zdev_t* dev, struct zsQueue* q, u16_t index, u8_t* addr)
230 u16_t next;
231 u8_t mb = 0;
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))
242 mb = 1;
245 index = next;
247 q->tail = (q->tail-1) & q->sizeMask;
249 return mb;
253 void zfQueueGenerateUapsdTim(zdev_t* dev, struct zsQueue* q,
254 u8_t* uniBitMap, u16_t* highestByte)
256 zbuf_t* psBuf;
257 u8_t dst[6];
258 u16_t id, aid, index, i;
259 u16_t bitPosition;
260 u16_t bytePosition;
261 zmw_get_wlan_dev(dev);
262 zmw_declare_for_critical_section();
264 zmw_enter_critical_section(dev);
266 index = q->head;
268 while (index != q->tail)
270 psBuf = q->cell[index].buf;
271 for (i=0; i<6; i++)
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)
282 aid = id + 1;
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;
294 else
296 /* Free garbage UAPSD frame */
297 zfQueueRemovewithIndex(dev, q, index, dst);
298 zfwBufFree(dev, psBuf, 0);
301 zmw_leave_critical_section(dev);
303 return;