Commit | Line | Data |
---|---|---|
4bd43f50 LR |
1 | /* |
2 | * Copyright (c) 2007-2008 Atheros Communications Inc. | |
3 | * | |
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. | |
7 | * | |
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. | |
15 | */ | |
16 | ||
17 | #include "cprecomp.h" | |
18 | ||
19 | u8_t zfQueryOppositeRate(zdev_t* dev, u8_t dst_mac[6], u8_t frameType) | |
20 | { | |
21 | zmw_get_wlan_dev(dev); | |
22 | ||
23 | /* For AP's rate adaption */ | |
24 | if ( wd->wlanMode == ZM_MODE_AP ) | |
25 | { | |
26 | return 0; | |
27 | } | |
28 | ||
29 | /* For STA's rate adaption */ | |
30 | if ( (frameType & 0x0c) == ZM_WLAN_DATA_FRAME ) | |
31 | { | |
32 | if ( ZM_IS_MULTICAST(dst_mac) ) | |
33 | { | |
34 | return wd->sta.mTxRate; | |
35 | } | |
36 | else | |
37 | { | |
38 | return wd->sta.uTxRate; | |
39 | } | |
40 | } | |
41 | ||
42 | return wd->sta.mmTxRate; | |
43 | } | |
44 | ||
45 | void zfCopyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src, | |
46 | u16_t offset, u16_t length) | |
47 | { | |
48 | u16_t i; | |
49 | ||
50 | for(i=0; i<length;i++) | |
51 | { | |
52 | zmw_tx_buf_writeb(dev, buf, offset+i, src[i]); | |
53 | } | |
54 | } | |
55 | ||
56 | void zfCopyToRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src, | |
57 | u16_t offset, u16_t length) | |
58 | { | |
59 | u16_t i; | |
60 | ||
61 | for(i=0; i<length;i++) | |
62 | { | |
63 | zmw_rx_buf_writeb(dev, buf, offset+i, src[i]); | |
64 | } | |
65 | } | |
66 | ||
67 | void zfCopyFromIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst, | |
68 | u16_t offset, u16_t length) | |
69 | { | |
70 | u16_t i; | |
71 | ||
72 | for(i=0; i<length; i++) | |
73 | { | |
74 | dst[i] = zmw_tx_buf_readb(dev, buf, offset+i); | |
75 | } | |
76 | } | |
77 | ||
78 | void zfCopyFromRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst, | |
79 | u16_t offset, u16_t length) | |
80 | { | |
81 | u16_t i; | |
82 | ||
83 | for(i=0; i<length; i++) | |
84 | { | |
85 | dst[i] = zmw_rx_buf_readb(dev, buf, offset+i); | |
86 | } | |
87 | } | |
88 | ||
89 | #if 1 | |
90 | void zfMemoryCopy(u8_t* dst, u8_t* src, u16_t length) | |
91 | { | |
92 | zfwMemoryCopy(dst, src, length); | |
93 | } | |
94 | ||
95 | void zfMemoryMove(u8_t* dst, u8_t* src, u16_t length) | |
96 | { | |
97 | zfwMemoryMove(dst, src, length); | |
98 | } | |
99 | ||
100 | void zfZeroMemory(u8_t* va, u16_t length) | |
101 | { | |
102 | zfwZeroMemory(va, length); | |
103 | } | |
104 | ||
105 | u8_t zfMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length) | |
106 | { | |
107 | return zfwMemoryIsEqual(m1, m2, length); | |
108 | } | |
109 | #endif | |
110 | ||
111 | u8_t zfRxBufferEqualToStr(zdev_t* dev, zbuf_t* buf, | |
112 | const u8_t* str, u16_t offset, u16_t length) | |
113 | { | |
114 | u16_t i; | |
115 | u8_t ch; | |
116 | ||
117 | for(i=0; i<length; i++) | |
118 | { | |
119 | ch = zmw_rx_buf_readb(dev, buf, offset+i); | |
120 | if ( ch != str[i] ) | |
121 | { | |
122 | return FALSE; | |
123 | } | |
124 | } | |
125 | ||
126 | return TRUE; | |
127 | } | |
128 | ||
129 | void zfTxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src, | |
130 | u16_t dstOffset, u16_t srcOffset, u16_t length) | |
131 | { | |
132 | u16_t i; | |
133 | ||
134 | for(i=0; i<length; i++) | |
135 | { | |
136 | zmw_tx_buf_writeb(dev, dst, dstOffset+i, | |
137 | zmw_tx_buf_readb(dev, src, srcOffset+i)); | |
138 | } | |
139 | } | |
140 | ||
141 | void zfRxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src, | |
142 | u16_t dstOffset, u16_t srcOffset, u16_t length) | |
143 | { | |
144 | u16_t i; | |
145 | ||
146 | for(i=0; i<length; i++) | |
147 | { | |
148 | zmw_rx_buf_writeb(dev, dst, dstOffset+i, | |
149 | zmw_rx_buf_readb(dev, src, srcOffset+i)); | |
150 | } | |
151 | } | |
152 | ||
153 | ||
154 | void zfCollectHWTally(zdev_t*dev, u32_t* rsp, u8_t id) | |
155 | { | |
156 | zmw_get_wlan_dev(dev); | |
157 | ||
158 | zmw_declare_for_critical_section(); | |
159 | ||
160 | zmw_enter_critical_section(dev); | |
161 | ||
162 | if (id == 0) | |
163 | { | |
164 | wd->commTally.Hw_UnderrunCnt += (0xFFFF & rsp[1]); | |
165 | wd->commTally.Hw_TotalRxFrm += rsp[2]; | |
166 | wd->commTally.Hw_CRC32Cnt += rsp[3]; | |
167 | wd->commTally.Hw_CRC16Cnt += rsp[4]; | |
168 | #ifdef ZM_ENABLE_NATIVE_WIFI | |
169 | /* These code are here to satisfy Vista DTM */ | |
170 | wd->commTally.Hw_DecrypErr_UNI += ((rsp[5]>50) && (rsp[5]<60))?50:rsp[5]; | |
171 | #else | |
172 | wd->commTally.Hw_DecrypErr_UNI += rsp[5]; | |
173 | #endif | |
174 | wd->commTally.Hw_RxFIFOOverrun += rsp[6]; | |
175 | wd->commTally.Hw_DecrypErr_Mul += rsp[7]; | |
176 | wd->commTally.Hw_RetryCnt += rsp[8]; | |
177 | wd->commTally.Hw_TotalTxFrm += rsp[9]; | |
178 | wd->commTally.Hw_RxTimeOut +=rsp[10]; | |
179 | ||
180 | wd->commTally.Tx_MPDU += rsp[11]; | |
181 | wd->commTally.BA_Fail += rsp[12]; | |
182 | wd->commTally.Hw_Tx_AMPDU += rsp[13]; | |
183 | wd->commTally.Hw_Tx_MPDU += rsp[14]; | |
184 | wd->commTally.RateCtrlTxMPDU += rsp[11]; | |
185 | wd->commTally.RateCtrlBAFail += rsp[12]; | |
186 | } | |
187 | else | |
188 | { | |
189 | wd->commTally.Hw_RxMPDU += rsp[1]; | |
190 | wd->commTally.Hw_RxDropMPDU += rsp[2]; | |
191 | wd->commTally.Hw_RxDelMPDU += rsp[3]; | |
192 | ||
193 | wd->commTally.Hw_RxPhyMiscError += rsp[4]; | |
194 | wd->commTally.Hw_RxPhyXRError += rsp[5]; | |
195 | wd->commTally.Hw_RxPhyOFDMError += rsp[6]; | |
196 | wd->commTally.Hw_RxPhyCCKError += rsp[7]; | |
197 | wd->commTally.Hw_RxPhyHTError += rsp[8]; | |
198 | wd->commTally.Hw_RxPhyTotalCount += rsp[9]; | |
199 | } | |
200 | ||
201 | zmw_leave_critical_section(dev); | |
202 | ||
203 | if (id == 0) | |
204 | { | |
205 | zm_msg1_mm(ZM_LV_1, "rsplen =", rsp[0]); | |
206 | zm_msg1_mm(ZM_LV_1, "Hw_UnderrunCnt = ", (0xFFFF & rsp[1])); | |
207 | zm_msg1_mm(ZM_LV_1, "Hw_TotalRxFrm = ", rsp[2]); | |
208 | zm_msg1_mm(ZM_LV_1, "Hw_CRC32Cnt = ", rsp[3]); | |
209 | zm_msg1_mm(ZM_LV_1, "Hw_CRC16Cnt = ", rsp[4]); | |
210 | zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_UNI = ", rsp[5]); | |
211 | zm_msg1_mm(ZM_LV_1, "Hw_RxFIFOOverrun = ", rsp[6]); | |
212 | zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_Mul = ", rsp[7]); | |
213 | zm_msg1_mm(ZM_LV_1, "Hw_RetryCnt = ", rsp[8]); | |
214 | zm_msg1_mm(ZM_LV_1, "Hw_TotalTxFrm = ", rsp[9]); | |
215 | zm_msg1_mm(ZM_LV_1, "Hw_RxTimeOut = ", rsp[10]); | |
216 | zm_msg1_mm(ZM_LV_1, "Tx_MPDU = ", rsp[11]); | |
217 | zm_msg1_mm(ZM_LV_1, "BA_Fail = ", rsp[12]); | |
218 | zm_msg1_mm(ZM_LV_1, "Hw_Tx_AMPDU = ", rsp[13]); | |
219 | zm_msg1_mm(ZM_LV_1, "Hw_Tx_MPDU = ", rsp[14]); | |
220 | } | |
221 | else | |
222 | { | |
223 | zm_msg1_mm(ZM_LV_1, "rsplen = ", rsp[0]); | |
224 | zm_msg1_mm(ZM_LV_1, "Hw_RxMPDU = ", (0xFFFF & rsp[1])); | |
225 | zm_msg1_mm(ZM_LV_1, "Hw_RxDropMPDU = ", rsp[2]); | |
226 | zm_msg1_mm(ZM_LV_1, "Hw_RxDelMPDU = ", rsp[3]); | |
227 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyMiscError = ", rsp[4]); | |
228 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyXRError = ", rsp[5]); | |
229 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyOFDMError = ", rsp[6]); | |
230 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyCCKError = ", rsp[7]); | |
231 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyHTError = ", rsp[8]); | |
232 | zm_msg1_mm(ZM_LV_1, "Hw_RxPhyTotalCount = ", rsp[9]); | |
233 | } | |
234 | ||
235 | } | |
236 | ||
237 | /* Timer related functions */ | |
238 | void zfTimerInit(zdev_t* dev) | |
239 | { | |
240 | u8_t i; | |
241 | ||
242 | zmw_get_wlan_dev(dev); | |
243 | ||
244 | zm_debug_msg0(""); | |
245 | ||
246 | wd->timerList.freeCount = ZM_MAX_TIMER_COUNT; | |
247 | wd->timerList.head = &(wd->timerList.list[0]); | |
248 | wd->timerList.tail = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-1]); | |
249 | wd->timerList.head->pre = NULL; | |
250 | wd->timerList.head->next = &(wd->timerList.list[1]); | |
251 | wd->timerList.tail->pre = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-2]); | |
252 | wd->timerList.tail->next = NULL; | |
253 | ||
254 | for( i=1; i<(ZM_MAX_TIMER_COUNT-1); i++ ) | |
255 | { | |
256 | wd->timerList.list[i].pre = &(wd->timerList.list[i-1]); | |
257 | wd->timerList.list[i].next = &(wd->timerList.list[i+1]); | |
258 | } | |
259 | ||
260 | wd->bTimerReady = TRUE; | |
261 | } | |
262 | ||
263 | ||
264 | u16_t zfTimerSchedule(zdev_t* dev, u16_t event, u32_t tick) | |
265 | { | |
266 | struct zsTimerEntry *pFreeEntry; | |
267 | struct zsTimerEntry *pEntry; | |
268 | u8_t i, count; | |
269 | ||
270 | zmw_get_wlan_dev(dev); | |
271 | ||
272 | if ( wd->timerList.freeCount == 0 ) | |
273 | { | |
274 | zm_debug_msg0("no more timer"); | |
275 | return 1; | |
276 | } | |
277 | ||
278 | //zm_debug_msg2("event = ", event); | |
279 | //zm_debug_msg1("target tick = ", wd->tick + tick); | |
280 | ||
281 | count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; | |
282 | ||
283 | if ( count == 0 ) | |
284 | { | |
285 | wd->timerList.freeCount--; | |
286 | wd->timerList.head->event = event; | |
287 | wd->timerList.head->timer = wd->tick + tick; | |
288 | //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); | |
289 | ||
290 | return 0; | |
291 | } | |
292 | ||
293 | pFreeEntry = wd->timerList.tail; | |
294 | pFreeEntry->timer = wd->tick + tick; | |
295 | pFreeEntry->event = event; | |
296 | wd->timerList.tail = pFreeEntry->pre; | |
297 | pEntry = wd->timerList.head; | |
298 | ||
299 | for( i=0; i<count; i++ ) | |
300 | { | |
301 | // prevent from the case of tick overflow | |
302 | if ( ( pEntry->timer > pFreeEntry->timer )&& | |
303 | ((pEntry->timer - pFreeEntry->timer) < 1000000000) ) | |
304 | { | |
305 | if ( i != 0 ) | |
306 | { | |
307 | pFreeEntry->pre = pEntry->pre; | |
308 | pFreeEntry->pre->next = pFreeEntry; | |
309 | } | |
310 | else | |
311 | { | |
312 | pFreeEntry->pre = NULL; | |
313 | } | |
314 | ||
315 | pEntry->pre = pFreeEntry; | |
316 | pFreeEntry->next = pEntry; | |
317 | break; | |
318 | } | |
319 | ||
320 | pEntry = pEntry->next; | |
321 | } | |
322 | ||
323 | if ( i == 0 ) | |
324 | { | |
325 | wd->timerList.head = pFreeEntry; | |
326 | } | |
327 | ||
328 | if ( i == count ) | |
329 | { | |
330 | pFreeEntry->pre = pEntry->pre; | |
331 | pFreeEntry->pre->next = pFreeEntry; | |
332 | pEntry->pre = pFreeEntry; | |
333 | pFreeEntry->next = pEntry; | |
334 | } | |
335 | ||
336 | wd->timerList.freeCount--; | |
337 | //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); | |
338 | ||
339 | return 0; | |
340 | } | |
341 | ||
342 | u16_t zfTimerCancel(zdev_t* dev, u16_t event) | |
343 | { | |
344 | struct zsTimerEntry *pEntry; | |
345 | u8_t i, count; | |
346 | ||
347 | zmw_get_wlan_dev(dev); | |
348 | ||
349 | //zm_debug_msg2("event = ", event); | |
350 | //zm_debug_msg1("free timer count(b) = ", wd->timerList.freeCount); | |
351 | ||
352 | pEntry = wd->timerList.head; | |
353 | count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; | |
354 | ||
355 | for( i=0; i<count; i++ ) | |
356 | { | |
357 | if ( pEntry->event == event ) | |
358 | { | |
359 | if ( pEntry == wd->timerList.head ) | |
360 | { /* remove head entry */ | |
361 | wd->timerList.head = pEntry->next; | |
362 | wd->timerList.tail->next = pEntry; | |
363 | pEntry->pre = wd->timerList.tail; | |
364 | wd->timerList.tail = pEntry; | |
365 | pEntry = wd->timerList.head; | |
366 | } | |
367 | else | |
368 | { /* remove non-head entry */ | |
369 | pEntry->pre->next = pEntry->next; | |
370 | pEntry->next->pre = pEntry->pre; | |
371 | wd->timerList.tail->next = pEntry; | |
372 | pEntry->pre = wd->timerList.tail; | |
373 | wd->timerList.tail = pEntry; | |
374 | pEntry = pEntry->next; | |
375 | } | |
376 | ||
377 | wd->timerList.freeCount++; | |
378 | } | |
379 | else | |
380 | { | |
381 | pEntry = pEntry->next; | |
382 | } | |
383 | } | |
384 | ||
385 | //zm_debug_msg1("free timer count(a) = ", wd->timerList.freeCount); | |
386 | ||
387 | return 0; | |
388 | } | |
389 | ||
390 | void zfTimerClear(zdev_t* dev) | |
391 | { | |
392 | zmw_get_wlan_dev(dev); | |
393 | ||
394 | wd->timerList.freeCount = ZM_MAX_TIMER_COUNT; | |
395 | } | |
396 | ||
397 | u16_t zfTimerCheckAndHandle(zdev_t* dev) | |
398 | { | |
399 | struct zsTimerEntry *pEntry; | |
400 | struct zsTimerEntry *pTheLastEntry = NULL; | |
401 | u16_t event[ZM_MAX_TIMER_COUNT]; | |
402 | u8_t i, j=0, count; | |
403 | ||
404 | zmw_get_wlan_dev(dev); | |
405 | ||
406 | zmw_declare_for_critical_section(); | |
407 | ||
408 | if ( !wd->bTimerReady ) | |
409 | { | |
410 | return 0; | |
411 | } | |
412 | ||
413 | zmw_enter_critical_section(dev); | |
414 | ||
415 | pEntry = wd->timerList.head; | |
416 | count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; | |
417 | ||
418 | for( i=0; i<count; i++ ) | |
419 | { | |
420 | // prevent from the case of tick overflow | |
421 | if ( ( pEntry->timer > wd->tick )&& | |
422 | ((pEntry->timer - wd->tick) < 1000000000) ) | |
423 | { | |
424 | break; | |
425 | } | |
426 | ||
427 | event[j++] = pEntry->event; | |
428 | pTheLastEntry = pEntry; | |
429 | pEntry = pEntry->next; | |
430 | } | |
431 | ||
432 | if ( j > 0 ) | |
433 | { | |
434 | wd->timerList.tail->next = wd->timerList.head; | |
435 | wd->timerList.head->pre = wd->timerList.tail; | |
436 | wd->timerList.head = pEntry; | |
437 | wd->timerList.tail = pTheLastEntry; | |
438 | wd->timerList.freeCount += j; | |
439 | //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); | |
440 | } | |
441 | ||
442 | zmw_leave_critical_section(dev); | |
443 | ||
444 | zfProcessEvent(dev, event, j); | |
445 | ||
446 | return 0; | |
447 | } | |
448 | ||
449 | u32_t zfCoreSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, | |
450 | u16_t* mac, u32_t* key) | |
451 | { | |
452 | u32_t ret; | |
453 | ||
454 | zmw_get_wlan_dev(dev); | |
455 | zmw_declare_for_critical_section(); | |
456 | ||
457 | zmw_enter_critical_section(dev); | |
458 | wd->sta.flagKeyChanging++; | |
459 | zm_debug_msg1(" zfCoreSetKey++++ ", wd->sta.flagKeyChanging); | |
460 | zmw_leave_critical_section(dev); | |
461 | ||
462 | ret = zfHpSetKey(dev, user, keyId, type, mac, key); | |
463 | return ret; | |
464 | } | |
465 | ||
466 | void zfCoreSetKeyComplete(zdev_t* dev) | |
467 | { | |
468 | zmw_get_wlan_dev(dev); | |
469 | zmw_declare_for_critical_section(); | |
470 | ||
471 | #if 0 | |
472 | wd->sta.flagKeyChanging = 0; | |
473 | #else | |
474 | if(wd->sta.flagKeyChanging) | |
475 | { | |
476 | zmw_enter_critical_section(dev); | |
477 | wd->sta.flagKeyChanging--; | |
478 | zmw_leave_critical_section(dev); | |
479 | } | |
480 | #endif | |
481 | zm_debug_msg1(" zfCoreSetKeyComplete--- ", wd->sta.flagKeyChanging); | |
482 | ||
483 | zfPushVtxq(dev); | |
484 | } | |
485 | ||
486 | void zfCoreHalInitComplete(zdev_t* dev) | |
487 | { | |
488 | zmw_get_wlan_dev(dev); | |
489 | zmw_declare_for_critical_section(); | |
490 | ||
491 | zmw_enter_critical_section(dev); | |
492 | wd->halState = ZM_HAL_STATE_RUNNING; | |
493 | zmw_leave_critical_section(dev); | |
494 | ||
495 | zfPushVtxq(dev); | |
496 | } | |
497 | ||
498 | void zfCoreMacAddressNotify(zdev_t* dev, u8_t* addr) | |
499 | { | |
500 | zmw_get_wlan_dev(dev); | |
501 | ||
502 | wd->macAddr[0] = addr[0] | ((u16_t)addr[1]<<8); | |
503 | wd->macAddr[1] = addr[2] | ((u16_t)addr[3]<<8); | |
504 | wd->macAddr[2] = addr[4] | ((u16_t)addr[5]<<8); | |
505 | ||
506 | ||
507 | //zfHpSetMacAddress(dev, wd->macAddr, 0); | |
508 | if (wd->zfcbMacAddressNotify != NULL) | |
509 | { | |
510 | wd->zfcbMacAddressNotify(dev, addr); | |
511 | } | |
512 | } | |
513 | ||
514 | void zfCoreSetIsoName(zdev_t* dev, u8_t* isoName) | |
515 | { | |
516 | zmw_get_wlan_dev(dev); | |
517 | ||
518 | wd->ws.countryIsoName[0] = isoName[0]; | |
519 | wd->ws.countryIsoName[1] = isoName[1]; | |
520 | wd->ws.countryIsoName[2] = '\0'; | |
521 | } | |
522 | ||
523 | ||
524 | extern void zfScanMgrScanEventStart(zdev_t* dev); | |
525 | extern u8_t zfScanMgrScanEventTimeout(zdev_t* dev); | |
526 | extern void zfScanMgrScanEventRetry(zdev_t* dev); | |
527 | ||
528 | void zfProcessEvent(zdev_t* dev, u16_t* eventArray, u8_t eventCount) | |
529 | { | |
530 | u8_t i, j, bypass = FALSE; | |
531 | u16_t eventBypass[32]; | |
532 | u8_t eventBypassCount = 0; | |
533 | ||
534 | zmw_get_wlan_dev(dev); | |
535 | ||
536 | zmw_declare_for_critical_section(); | |
537 | ||
538 | zfZeroMemory((u8_t*) eventBypass, 64); | |
539 | ||
540 | for( i=0; i<eventCount; i++ ) | |
541 | { | |
542 | for( j=0; j<eventBypassCount; j++ ) | |
543 | { | |
544 | if ( eventBypass[j] == eventArray[i] ) | |
545 | { | |
546 | bypass = TRUE; | |
547 | break; | |
548 | } | |
549 | } | |
550 | ||
551 | if ( bypass ) | |
552 | { | |
553 | continue; | |
554 | } | |
555 | ||
556 | switch( eventArray[i] ) | |
557 | { | |
558 | case ZM_EVENT_SCAN: | |
559 | { | |
560 | zfScanMgrScanEventStart(dev); | |
561 | eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN; | |
562 | eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN; | |
563 | } | |
564 | break; | |
565 | ||
566 | case ZM_EVENT_TIMEOUT_SCAN: | |
567 | { | |
568 | u8_t res; | |
569 | ||
570 | res = zfScanMgrScanEventTimeout(dev); | |
571 | if ( res == 0 ) | |
572 | { | |
573 | eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN; | |
574 | } | |
575 | else if ( res == 1 ) | |
576 | { | |
577 | eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN; | |
578 | } | |
579 | } | |
580 | break; | |
581 | ||
582 | case ZM_EVENT_IBSS_MONITOR: | |
583 | { | |
584 | zfStaIbssMonitoring(dev, 0); | |
585 | } | |
586 | break; | |
587 | ||
588 | case ZM_EVENT_IN_SCAN: | |
589 | { | |
590 | zfScanMgrScanEventRetry(dev); | |
591 | } | |
592 | break; | |
593 | ||
594 | case ZM_EVENT_CM_TIMER: | |
595 | { | |
596 | zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_TIMER"); | |
597 | ||
598 | wd->sta.cmMicFailureCount = 0; | |
599 | } | |
600 | break; | |
601 | ||
602 | case ZM_EVENT_CM_DISCONNECT: | |
603 | { | |
604 | zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_DISCONNECT"); | |
605 | ||
606 | zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); | |
607 | ||
608 | zmw_enter_critical_section(dev); | |
609 | //zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER, | |
610 | // ZM_TICK_CM_BLOCK_TIMEOUT); | |
611 | ||
612 | /* Timer Resolution on WinXP is 15/16 ms */ | |
613 | /* Decrease Time offset for <XP> Counter Measure */ | |
614 | zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER, | |
615 | ZM_TICK_CM_BLOCK_TIMEOUT - ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET); | |
616 | ||
617 | zmw_leave_critical_section(dev); | |
618 | wd->sta.cmMicFailureCount = 0; | |
619 | //zfiWlanDisable(dev); | |
620 | zfHpResetKeyCache(dev); | |
621 | if (wd->zfcbConnectNotify != NULL) | |
622 | { | |
623 | wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISCONNECT_MIC_FAIL, | |
624 | wd->sta.bssid); | |
625 | } | |
626 | } | |
627 | break; | |
628 | ||
629 | case ZM_EVENT_CM_BLOCK_TIMER: | |
630 | { | |
631 | zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER"); | |
632 | ||
633 | //zmw_enter_critical_section(dev); | |
634 | wd->sta.cmDisallowSsidLength = 0; | |
635 | if ( wd->sta.bAutoReconnect ) | |
636 | { | |
637 | zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER:bAutoReconnect!=0"); | |
638 | zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); | |
639 | zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL); | |
640 | } | |
641 | //zmw_leave_critical_section(dev); | |
642 | } | |
643 | break; | |
644 | ||
645 | case ZM_EVENT_TIMEOUT_ADDBA: | |
646 | { | |
647 | if (!wd->addbaComplete && (wd->addbaCount < 5)) | |
648 | { | |
649 | zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0); | |
650 | wd->addbaCount++; | |
651 | zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100); | |
652 | } | |
653 | else | |
654 | { | |
655 | zfTimerCancel(dev, ZM_EVENT_TIMEOUT_ADDBA); | |
656 | } | |
657 | } | |
658 | break; | |
659 | ||
660 | #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION | |
661 | case ZM_EVENT_TIMEOUT_PERFORMANCE: | |
662 | { | |
663 | zfiPerformanceRefresh(dev); | |
664 | } | |
665 | break; | |
666 | #endif | |
667 | case ZM_EVENT_SKIP_COUNTERMEASURE: | |
668 | //enable the Countermeasure | |
669 | { | |
670 | zm_debug_msg0("Countermeasure : Enable MIC Check "); | |
671 | wd->TKIP_Group_KeyChanging = 0x0; | |
672 | } | |
673 | break; | |
674 | ||
675 | default: | |
676 | break; | |
677 | } | |
678 | } | |
679 | } | |
680 | ||
681 | void zfBssInfoCreate(zdev_t* dev) | |
682 | { | |
683 | u8_t i; | |
684 | ||
685 | zmw_get_wlan_dev(dev); | |
686 | ||
687 | zmw_declare_for_critical_section(); | |
688 | ||
689 | zmw_enter_critical_section(dev); | |
690 | ||
691 | wd->sta.bssList.bssCount = 0; | |
692 | wd->sta.bssList.head = NULL; | |
693 | wd->sta.bssList.tail = NULL; | |
694 | wd->sta.bssInfoArrayHead = 0; | |
695 | wd->sta.bssInfoArrayTail = 0; | |
696 | wd->sta.bssInfoFreeCount = ZM_MAX_BSS; | |
697 | ||
698 | for( i=0; i< ZM_MAX_BSS; i++ ) | |
699 | { | |
700 | //wd->sta.bssInfoArray[i] = &(wd->sta.bssInfoPool[i]); | |
701 | wd->sta.bssInfoArray[i] = zfwMemAllocate(dev, sizeof(struct zsBssInfo)); | |
702 | ||
703 | } | |
704 | ||
705 | zmw_leave_critical_section(dev); | |
706 | } | |
707 | ||
708 | void zfBssInfoDestroy(zdev_t* dev) | |
709 | { | |
710 | u8_t i; | |
711 | zmw_get_wlan_dev(dev); | |
712 | ||
713 | zfBssInfoRefresh(dev, 1); | |
714 | ||
715 | for( i=0; i< ZM_MAX_BSS; i++ ) | |
716 | { | |
717 | if (wd->sta.bssInfoArray[i] != NULL) | |
718 | { | |
719 | zfwMemFree(dev, wd->sta.bssInfoArray[i], sizeof(struct zsBssInfo)); | |
720 | } | |
721 | else | |
722 | { | |
723 | zm_assert(0); | |
724 | } | |
725 | } | |
726 | return; | |
727 | } | |
728 | ||
729 | struct zsBssInfo* zfBssInfoAllocate(zdev_t* dev) | |
730 | { | |
731 | struct zsBssInfo* pBssInfo; | |
732 | ||
733 | zmw_get_wlan_dev(dev); | |
734 | ||
735 | if (wd->sta.bssInfoFreeCount == 0) | |
736 | return NULL; | |
737 | ||
738 | pBssInfo = wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead]; | |
739 | wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead] = NULL; | |
740 | wd->sta.bssInfoArrayHead = (wd->sta.bssInfoArrayHead + 1) & (ZM_MAX_BSS - 1); | |
741 | wd->sta.bssInfoFreeCount--; | |
742 | ||
743 | zfZeroMemory((u8_t*)pBssInfo, sizeof(struct zsBssInfo)); | |
744 | ||
745 | return pBssInfo; | |
746 | } | |
747 | ||
748 | void zfBssInfoFree(zdev_t* dev, struct zsBssInfo* pBssInfo) | |
749 | { | |
750 | zmw_get_wlan_dev(dev); | |
751 | ||
752 | zm_assert(wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] == NULL); | |
753 | ||
754 | pBssInfo->signalStrength = pBssInfo->signalQuality = 0; | |
755 | pBssInfo->sortValue = 0; | |
756 | ||
757 | wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] = pBssInfo; | |
758 | wd->sta.bssInfoArrayTail = (wd->sta.bssInfoArrayTail + 1) & (ZM_MAX_BSS - 1); | |
759 | wd->sta.bssInfoFreeCount++; | |
760 | } | |
761 | ||
762 | void zfBssInfoReorderList(zdev_t* dev) | |
763 | { | |
764 | struct zsBssInfo* pBssInfo = NULL; | |
765 | struct zsBssInfo* pInsBssInfo = NULL; | |
766 | struct zsBssInfo* pNextBssInfo = NULL; | |
767 | struct zsBssInfo* pPreBssInfo = NULL; | |
768 | u8_t i = 0; | |
769 | ||
770 | zmw_get_wlan_dev(dev); | |
771 | ||
772 | zmw_declare_for_critical_section(); | |
773 | ||
774 | zmw_enter_critical_section(dev); | |
775 | ||
776 | if (wd->sta.bssList.bssCount > 1) | |
777 | { | |
778 | pInsBssInfo = wd->sta.bssList.head; | |
779 | wd->sta.bssList.tail = pInsBssInfo; | |
780 | pBssInfo = pInsBssInfo->next; | |
781 | pInsBssInfo->next = NULL; | |
782 | while (pBssInfo != NULL) | |
783 | { | |
784 | i = 0; | |
785 | while (1) | |
786 | { | |
787 | // if (pBssInfo->signalStrength >= pInsBssInfo->signalStrength) | |
788 | if( pBssInfo->sortValue >= pInsBssInfo->sortValue) | |
789 | { | |
790 | if (i==0) | |
791 | { | |
792 | //Insert BssInfo to head | |
793 | wd->sta.bssList.head = pBssInfo; | |
794 | pNextBssInfo = pBssInfo->next; | |
795 | pBssInfo->next = pInsBssInfo; | |
796 | break; | |
797 | } | |
798 | else | |
799 | { | |
800 | //Insert BssInfo to neither head nor tail | |
801 | pPreBssInfo->next = pBssInfo; | |
802 | pNextBssInfo = pBssInfo->next; | |
803 | pBssInfo->next = pInsBssInfo; | |
804 | break; | |
805 | } | |
806 | } | |
807 | else | |
808 | { | |
809 | if (pInsBssInfo->next != NULL) | |
810 | { | |
811 | //Signal strength smaller than current BssInfo, check next | |
812 | pPreBssInfo = pInsBssInfo; | |
813 | pInsBssInfo = pInsBssInfo->next; | |
814 | } | |
815 | else | |
816 | { | |
817 | //Insert BssInfo to tail | |
818 | pInsBssInfo->next = pBssInfo; | |
819 | pNextBssInfo = pBssInfo->next; | |
820 | wd->sta.bssList.tail = pBssInfo; | |
821 | pBssInfo->next = NULL; | |
822 | break; | |
823 | } | |
824 | } | |
825 | i++; | |
826 | } | |
827 | pBssInfo = pNextBssInfo; | |
828 | pInsBssInfo = wd->sta.bssList.head; | |
829 | } | |
830 | } //if (wd->sta.bssList.bssCount > 1) | |
831 | ||
832 | zmw_leave_critical_section(dev); | |
833 | } | |
834 | ||
835 | void zfBssInfoInsertToList(zdev_t* dev, struct zsBssInfo* pBssInfo) | |
836 | { | |
837 | zmw_get_wlan_dev(dev); | |
838 | ||
839 | zm_assert(pBssInfo); | |
840 | ||
841 | //zm_debug_msg2("pBssInfo = ", pBssInfo); | |
842 | ||
843 | if ( wd->sta.bssList.bssCount == 0 ) | |
844 | { | |
845 | wd->sta.bssList.head = pBssInfo; | |
846 | wd->sta.bssList.tail = pBssInfo; | |
847 | } | |
848 | else | |
849 | { | |
850 | wd->sta.bssList.tail->next = pBssInfo; | |
851 | wd->sta.bssList.tail = pBssInfo; | |
852 | } | |
853 | ||
854 | pBssInfo->next = NULL; | |
855 | wd->sta.bssList.bssCount++; | |
856 | ||
857 | //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount); | |
858 | } | |
859 | ||
860 | void zfBssInfoRemoveFromList(zdev_t* dev, struct zsBssInfo* pBssInfo) | |
861 | { | |
862 | struct zsBssInfo* pNowBssInfo; | |
863 | struct zsBssInfo* pPreBssInfo = NULL; | |
864 | u8_t i; | |
865 | ||
866 | zmw_get_wlan_dev(dev); | |
867 | ||
868 | zm_assert(pBssInfo); | |
869 | zm_assert(wd->sta.bssList.bssCount); | |
870 | ||
871 | //zm_debug_msg2("pBssInfo = ", pBssInfo); | |
872 | ||
873 | pNowBssInfo = wd->sta.bssList.head; | |
874 | ||
875 | for( i=0; i<wd->sta.bssList.bssCount; i++ ) | |
876 | { | |
877 | if ( pNowBssInfo == pBssInfo ) | |
878 | { | |
879 | if ( i == 0 ) | |
880 | { /* remove head */ | |
881 | wd->sta.bssList.head = pBssInfo->next; | |
882 | } | |
883 | else | |
884 | { | |
885 | pPreBssInfo->next = pBssInfo->next; | |
886 | } | |
887 | ||
888 | if ( i == (wd->sta.bssList.bssCount - 1) ) | |
889 | { /* remove tail */ | |
890 | wd->sta.bssList.tail = pPreBssInfo; | |
891 | } | |
892 | ||
893 | break; | |
894 | } | |
895 | ||
896 | pPreBssInfo = pNowBssInfo; | |
897 | pNowBssInfo = pNowBssInfo->next; | |
898 | } | |
899 | ||
900 | zm_assert(i != wd->sta.bssList.bssCount); | |
901 | wd->sta.bssList.bssCount--; | |
902 | ||
903 | //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount); | |
904 | } | |
905 | ||
906 | void zfBssInfoRefresh(zdev_t* dev, u16_t mode) | |
907 | { | |
908 | struct zsBssInfo* pBssInfo; | |
909 | struct zsBssInfo* pNextBssInfo; | |
910 | u8_t i, bssCount; | |
911 | ||
912 | zmw_get_wlan_dev(dev); | |
913 | ||
914 | pBssInfo = wd->sta.bssList.head; | |
915 | bssCount = wd->sta.bssList.bssCount; | |
916 | ||
917 | for( i=0; i<bssCount; i++ ) | |
918 | { | |
919 | if (mode == 1) | |
920 | { | |
921 | pNextBssInfo = pBssInfo->next; | |
922 | zfBssInfoRemoveFromList(dev, pBssInfo); | |
923 | zfBssInfoFree(dev, pBssInfo); | |
924 | pBssInfo = pNextBssInfo; | |
925 | } | |
926 | else | |
927 | { | |
928 | if ( pBssInfo->flag & ZM_BSS_INFO_VALID_BIT ) | |
929 | { /* this one must be kept */ | |
930 | pBssInfo->flag &= ~ZM_BSS_INFO_VALID_BIT; | |
931 | pBssInfo = pBssInfo->next; | |
932 | } | |
933 | else | |
934 | { | |
935 | #define ZM_BSS_CACHE_TIME_IN_MS 20000 | |
936 | if ((wd->tick - pBssInfo->tick) > (ZM_BSS_CACHE_TIME_IN_MS/ZM_MS_PER_TICK)) | |
937 | { | |
938 | pNextBssInfo = pBssInfo->next; | |
939 | zfBssInfoRemoveFromList(dev, pBssInfo); | |
940 | zfBssInfoFree(dev, pBssInfo); | |
941 | pBssInfo = pNextBssInfo; | |
942 | } | |
943 | else | |
944 | { | |
945 | pBssInfo = pBssInfo->next; | |
946 | } | |
947 | } | |
948 | } | |
949 | } //for( i=0; i<bssCount; i++ ) | |
950 | return; | |
951 | } | |
952 | ||
953 | void zfDumpSSID(u8_t length, u8_t *value) | |
954 | { | |
955 | u8_t buf[50]; | |
956 | u8_t tmpLength = length; | |
957 | ||
958 | if ( tmpLength > 49 ) | |
959 | { | |
960 | tmpLength = 49; | |
961 | } | |
962 | ||
963 | zfMemoryCopy(buf, value, tmpLength); | |
964 | buf[tmpLength] = '\0'; | |
965 | //printk("SSID: %s\n", buf); | |
966 | //zm_debug_msg_s("ssid = ", value); | |
967 | } | |
968 | ||
969 | void zfCoreReinit(zdev_t* dev) | |
970 | { | |
971 | zmw_get_wlan_dev(dev); | |
972 | ||
973 | wd->sta.flagKeyChanging = 0; | |
974 | wd->sta.flagFreqChanging = 0; | |
975 | } | |
976 | ||
977 | void zfGenerateRandomBSSID(zdev_t* dev, u8_t *MACAddr, u8_t *BSSID) | |
978 | { | |
979 | //ULONGLONG time; | |
980 | u32_t time; | |
981 | ||
982 | zmw_get_wlan_dev(dev); | |
983 | ||
984 | time = wd->tick; | |
985 | ||
986 | // | |
987 | // Initialize the random BSSID to be the same as MAC address. | |
988 | // | |
989 | ||
990 | // RtlCopyMemory(BSSID, MACAddr, sizeof(DOT11_MAC_ADDRESS)); | |
991 | zfMemoryCopy(BSSID, MACAddr, 6); | |
992 | ||
993 | // | |
994 | // Get the system time in 10 millisecond. | |
995 | // | |
996 | ||
997 | // NdisGetCurrentSystemTime((PLARGE_INTEGER)&time); | |
998 | // time /= 100000; | |
999 | ||
1000 | // | |
1001 | // Randomize the first 4 bytes of BSSID. | |
1002 | // | |
1003 | ||
1004 | BSSID[0] ^= (u8_t)(time & 0xff); | |
1005 | BSSID[0] &= ~0x01; // Turn off multicast bit | |
1006 | BSSID[0] |= 0x02; // Turn on local bit | |
1007 | ||
1008 | time >>= 8; | |
1009 | BSSID[1] ^= (u8_t)(time & 0xff); | |
1010 | ||
1011 | time >>= 8; | |
1012 | BSSID[2] ^= (u8_t)(time & 0xff); | |
1013 | ||
1014 | time >>= 8; | |
1015 | BSSID[3] ^= (u8_t)(time & 0xff); | |
1016 | } | |
1017 | ||
1018 | u8_t zfiWlanGetDestAddrFromBuf(zdev_t *dev, zbuf_t *buf, u16_t *macAddr) | |
1019 | { | |
1020 | #ifdef ZM_ENABLE_NATIVE_WIFI | |
1021 | zmw_get_wlan_dev(dev); | |
1022 | ||
1023 | if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) | |
1024 | { | |
1025 | /* DA */ | |
1026 | macAddr[0] = zmw_tx_buf_readh(dev, buf, 16); | |
1027 | macAddr[1] = zmw_tx_buf_readh(dev, buf, 18); | |
1028 | macAddr[2] = zmw_tx_buf_readh(dev, buf, 20); | |
1029 | } | |
1030 | else if ( wd->wlanMode == ZM_MODE_IBSS ) | |
1031 | { | |
1032 | /* DA */ | |
1033 | macAddr[0] = zmw_tx_buf_readh(dev, buf, 4); | |
1034 | macAddr[1] = zmw_tx_buf_readh(dev, buf, 6); | |
1035 | macAddr[2] = zmw_tx_buf_readh(dev, buf, 8); | |
1036 | } | |
1037 | else if ( wd->wlanMode == ZM_MODE_AP ) | |
1038 | { | |
1039 | /* DA */ | |
1040 | macAddr[0] = zmw_tx_buf_readh(dev, buf, 4); | |
1041 | macAddr[1] = zmw_tx_buf_readh(dev, buf, 6); | |
1042 | macAddr[2] = zmw_tx_buf_readh(dev, buf, 8); | |
1043 | } | |
1044 | else | |
1045 | { | |
1046 | return 1; | |
1047 | } | |
1048 | #else | |
1049 | /* DA */ | |
1050 | macAddr[0] = zmw_tx_buf_readh(dev, buf, 0); | |
1051 | macAddr[1] = zmw_tx_buf_readh(dev, buf, 2); | |
1052 | macAddr[2] = zmw_tx_buf_readh(dev, buf, 4); | |
1053 | #endif | |
1054 | ||
1055 | return 0; | |
1056 | } | |
1057 | ||
1058 | /* Leave an empty line below to remove warning message on some compiler */ | |
1059 | ||
1060 | u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode) | |
1061 | { | |
1062 | u8_t i, j; | |
1063 | u16_t returnChannel; | |
1064 | u16_t count_24G = 0, min24GIndex = 0; | |
1065 | u16_t count_5G = 0, min5GIndex = 0; | |
1066 | u16_t CombinationBssNumberIn24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1067 | u16_t BssNumberIn24G[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1068 | u16_t Array_24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1069 | u16_t BssNumberIn5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1070 | u16_t Array_5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1071 | struct zsBssInfo* pBssInfo; | |
1072 | ||
1073 | zmw_get_wlan_dev(dev); | |
1074 | ||
92363b52 JP |
1075 | pBssInfo = wd->sta.bssList.head; |
1076 | if (pBssInfo == NULL) | |
4bd43f50 LR |
1077 | { |
1078 | if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || | |
1079 | adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) | |
1080 | { | |
1081 | returnChannel = zfChGetFirst2GhzChannel(dev); | |
1082 | } | |
1083 | else | |
1084 | { | |
1085 | returnChannel = zfChGetFirst5GhzChannel(dev); | |
1086 | } | |
1087 | ||
1088 | return returnChannel; | |
1089 | } | |
1090 | ||
1091 | /* #1 Get Allowed Channel following Country Code ! */ | |
1092 | zmw_declare_for_critical_section(); | |
1093 | zmw_enter_critical_section(dev); | |
1094 | for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) | |
1095 | { | |
1096 | if (wd->regulationTable.allowChannel[i].channel < 3000) | |
1097 | { // 2.4GHz | |
1098 | Array_24G[count_24G] = wd->regulationTable.allowChannel[i].channel; | |
1099 | count_24G++; | |
1100 | } | |
1101 | else | |
1102 | { // 5GHz | |
1103 | count_5G++; | |
1104 | Array_5G[i] = wd->regulationTable.allowChannel[i].channel; | |
1105 | } | |
1106 | } | |
1107 | zmw_leave_critical_section(dev); | |
1108 | ||
1109 | while( pBssInfo != NULL ) | |
1110 | { | |
1111 | /* #2_1 Count BSS number in some specificed frequency in 2.4GHz band ! */ | |
1112 | if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || | |
1113 | adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) | |
1114 | { | |
1115 | for( i=0; i<=(count_24G+3); i++ ) | |
1116 | { | |
1117 | if( pBssInfo->frequency == Array_24G[i] ) | |
1118 | { // Array_24G[0] correspond to BssNumberIn24G[2] | |
1119 | BssNumberIn24G[pBssInfo->channel+1]++; | |
1120 | } | |
1121 | } | |
1122 | } | |
1123 | ||
1124 | /* #2_2 Count BSS number in some specificed frequency in 5GHz band ! */ | |
1125 | if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG ) | |
1126 | { | |
1127 | for( i=0; i<count_5G; i++ ) | |
1128 | { // 5GHz channel is not equal to array index | |
1129 | if( pBssInfo->frequency == Array_5G[i] ) | |
1130 | { // Array_5G[0] correspond to BssNumberIn5G[0] | |
1131 | BssNumberIn5G[i]++; | |
1132 | } | |
1133 | } | |
1134 | } | |
1135 | ||
1136 | pBssInfo = pBssInfo->next; | |
1137 | } | |
1138 | ||
1139 | #if 0 | |
1140 | for(i=0; i<=(count_24G+3); i++) | |
1141 | { | |
1142 | printk("2.4GHz Before combin, %d BSS network : %d", i, BssNumberIn24G[i]); | |
1143 | } | |
1144 | ||
1145 | for(i=0; i<count_5G; i++) | |
1146 | { | |
1147 | printk("5GHz Before combin, %d BSS network : %d", i, BssNumberIn5G[i]); | |
1148 | } | |
1149 | #endif | |
1150 | ||
1151 | if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || | |
1152 | adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) | |
1153 | { | |
1154 | /* #3_1 Count BSS number that influence the specificed frequency in 2.4GHz ! */ | |
1155 | for( j=0; j<count_24G; j++ ) | |
1156 | { | |
1157 | CombinationBssNumberIn24G[j] = BssNumberIn24G[j] + BssNumberIn24G[j+1] + | |
1158 | BssNumberIn24G[j+2] + BssNumberIn24G[j+3] + | |
1159 | BssNumberIn24G[j+4]; | |
1160 | //printk("After combine, the number of BSS network channel %d is %d", | |
1161 | // j , CombinationBssNumberIn24G[j]); | |
1162 | } | |
1163 | ||
1164 | /* #4_1 Find the less utilized frequency in 2.4GHz band ! */ | |
1165 | min24GIndex = zfFindMinimumUtilizationChannelIndex(dev, CombinationBssNumberIn24G, count_24G); | |
1166 | } | |
1167 | ||
1168 | /* #4_2 Find the less utilized frequency in 5GHz band ! */ | |
1169 | if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG ) | |
1170 | { | |
1171 | min5GIndex = zfFindMinimumUtilizationChannelIndex(dev, BssNumberIn5G, count_5G); | |
1172 | } | |
1173 | ||
1174 | if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || adhocMode == ZM_ADHOCBAND_BG ) | |
1175 | { | |
1176 | return Array_24G[min24GIndex]; | |
1177 | } | |
1178 | else if( adhocMode == ZM_ADHOCBAND_A ) | |
1179 | { | |
1180 | return Array_5G[min5GIndex]; | |
1181 | } | |
1182 | else if( adhocMode == ZM_ADHOCBAND_ABG ) | |
1183 | { | |
1184 | if ( CombinationBssNumberIn24G[min24GIndex] <= BssNumberIn5G[min5GIndex] ) | |
1185 | return Array_24G[min24GIndex]; | |
1186 | else | |
1187 | return Array_5G[min5GIndex]; | |
1188 | } | |
1189 | else | |
1190 | return 2412; | |
1191 | } | |
1192 | ||
1193 | u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t count) | |
1194 | { | |
1195 | u8_t i; | |
1196 | u16_t tempMinIndex, tempMinValue; | |
1197 | ||
4bd43f50 LR |
1198 | i = 1; |
1199 | tempMinIndex = 0; | |
1200 | tempMinValue = array[tempMinIndex]; | |
1201 | while( i< count ) | |
1202 | { | |
1203 | if( array[i] < tempMinValue ) | |
1204 | { | |
1205 | tempMinValue = array[i]; | |
1206 | tempMinIndex = i; | |
1207 | } | |
1208 | i++; | |
1209 | } | |
1210 | ||
1211 | return tempMinIndex; | |
1212 | } | |
1213 | ||
1214 | u8_t zfCompareWithBssid(zdev_t* dev, u16_t* bssid) | |
1215 | { | |
1216 | zmw_get_wlan_dev(dev); | |
1217 | ||
1218 | if ( zfMemoryIsEqual((u8_t*)bssid, (u8_t*)wd->sta.bssid, 6) ) | |
1219 | { | |
1220 | return 1; | |
1221 | } | |
1222 | else | |
1223 | { | |
1224 | return 0; | |
1225 | } | |
1226 | } |