GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / otus / 80211core / cmmsta.c
blobdf42d1859e79deb5e2e5b199f17c45ccffc19064
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.
17 #include "cprecomp.h"
18 #include "ratectrl.h"
19 #include "../hal/hpreg.h"
21 /* TODO : change global variable to constant */
22 u8_t zgWpaRadiusOui[] = { 0x00, 0x50, 0xf2, 0x01 };
23 u8_t zgWpaAesOui[] = { 0x00, 0x50, 0xf2, 0x04 };
24 u8_t zgWpa2RadiusOui[] = { 0x00, 0x0f, 0xac, 0x01 };
25 u8_t zgWpa2AesOui[] = { 0x00, 0x0f, 0xac, 0x04 };
27 const u16_t zcCwTlb[16] = { 0, 1, 3, 7, 15, 31, 63, 127,
28 255, 511, 1023, 2047, 4095, 4095, 4095, 4095};
30 void zfStaStartConnectCb(zdev_t* dev);
32 /************************************************************************/
33 /* */
34 /* FUNCTION DESCRIPTION zfStaPutApIntoBlockingList */
35 /* Put AP into blocking AP list. */
36 /* */
37 /* INPUTS */
38 /* dev : device pointer */
39 /* bssid : AP's BSSID */
40 /* weight : weight of AP */
41 /* */
42 /* OUTPUTS */
43 /* none */
44 /* */
45 /* AUTHOR */
46 /* Stephen Chen Atheros Communications, INC. 2006.12 */
47 /* */
48 /************************************************************************/
49 void zfStaPutApIntoBlockingList(zdev_t* dev, u8_t* bssid, u8_t weight)
51 u16_t i, j;
52 zmw_get_wlan_dev(dev);
53 zmw_declare_for_critical_section();
55 if (weight > 0)
57 zmw_enter_critical_section(dev);
58 /*Find same bssid entry first*/
59 for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
61 for (j=0; j<6; j++)
63 if(wd->sta.blockingApList[i].addr[j]!= bssid[j])
65 break;
69 if(j==6)
71 break;
74 /*This bssid doesn't have old record.Find an empty entry*/
75 if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
77 for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
79 if (wd->sta.blockingApList[i].weight == 0)
81 break;
86 /* If the list is full, pick one entry for replacement */
87 if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
89 i = bssid[5] & (ZM_MAX_BLOCKING_AP_LIST_SIZE-1);
92 /* Update AP address and weight */
93 for (j=0; j<6; j++)
95 wd->sta.blockingApList[i].addr[j] = bssid[j];
98 wd->sta.blockingApList[i].weight = weight;
99 zmw_leave_critical_section(dev);
102 return;
106 /************************************************************************/
107 /* */
108 /* FUNCTION DESCRIPTION zfStaIsApInBlockingList */
109 /* Is AP in blocking list. */
110 /* */
111 /* INPUTS */
112 /* dev : device pointer */
113 /* bssid : AP's BSSID */
114 /* */
115 /* OUTPUTS */
116 /* TRUE : AP in blocking list */
117 /* FALSE : AP not in blocking list */
118 /* */
119 /* AUTHOR */
120 /* Stephen Chen Atheros Communications, INC. 2006.12 */
121 /* */
122 /************************************************************************/
123 u16_t zfStaIsApInBlockingList(zdev_t* dev, u8_t* bssid)
125 u16_t i, j;
126 zmw_get_wlan_dev(dev);
127 //zmw_declare_for_critical_section();
129 //zmw_enter_critical_section(dev);
130 for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
132 if (wd->sta.blockingApList[i].weight != 0)
134 for (j=0; j<6; j++)
136 if (wd->sta.blockingApList[i].addr[j] != bssid[j])
138 break;
141 if (j == 6)
143 //zmw_leave_critical_section(dev);
144 return TRUE;
148 //zmw_leave_critical_section(dev);
149 return FALSE;
153 /************************************************************************/
154 /* */
155 /* FUNCTION DESCRIPTION zfStaRefreshBlockList */
156 /* Is AP in blocking list. */
157 /* */
158 /* INPUTS */
159 /* dev : device pointer */
160 /* flushFlag : flush whole blocking list */
161 /* */
162 /* OUTPUTS */
163 /* none */
164 /* */
165 /* AUTHOR */
166 /* Stephen Chen Atheros Communications, INC. 2006.12 */
167 /* */
168 /************************************************************************/
169 void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag)
171 u16_t i;
172 zmw_get_wlan_dev(dev);
173 zmw_declare_for_critical_section();
175 zmw_enter_critical_section(dev);
176 for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
178 if (wd->sta.blockingApList[i].weight != 0)
180 if (flushFlag != 0)
182 wd->sta.blockingApList[i].weight = 0;
184 else
186 wd->sta.blockingApList[i].weight--;
190 zmw_leave_critical_section(dev);
191 return;
195 /************************************************************************/
196 /* */
197 /* FUNCTION DESCRIPTION zfStaConnectFail */
198 /* Handle Connect failure. */
199 /* */
200 /* INPUTS */
201 /* dev : device pointer */
202 /* bssid : BSSID */
203 /* reason : reason of failure */
204 /* */
205 /* OUTPUTS */
206 /* none */
207 /* */
208 /* AUTHOR */
209 /* Stephen Chen Atheros Communications, INC. 2006.12 */
210 /* */
211 /************************************************************************/
212 void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight)
214 zmw_get_wlan_dev(dev);
216 /* Change internal state */
217 zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
219 /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
220 //zfHpSetTTSIFSTime(dev, 0x8);
222 /* Notify wrapper of connection status changes */
223 if (wd->zfcbConnectNotify != NULL)
225 wd->zfcbConnectNotify(dev, reason, bssid);
228 /* Put AP into internal blocking list */
229 zfStaPutApIntoBlockingList(dev, (u8_t *)bssid, weight);
231 /* Issue another SCAN */
232 if ( wd->sta.bAutoReconnect )
234 zm_debug_msg0("Start internal scan...");
235 zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
236 zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
240 u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev)
242 zmw_get_wlan_dev(dev);
244 return wd->sta.oppositeCount;
247 u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx)
249 u8_t oppositeCount;
250 u8_t i;
251 u8_t index = 0;
253 zmw_get_wlan_dev(dev);
255 zmw_declare_for_critical_section();
257 zmw_enter_critical_section(dev);
259 oppositeCount = wd->sta.oppositeCount;
260 if ( oppositeCount > numToIterate )
262 oppositeCount = numToIterate;
265 for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
267 if ( oppositeCount == 0 )
269 break;
272 if ( wd->sta.oppositeInfo[i].valid == 0 )
274 continue;
277 callback(dev, &wd->sta.oppositeInfo[i], ctx, index++);
278 oppositeCount--;
282 zmw_leave_critical_section(dev);
284 return index;
288 s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx)
290 int oppositeCount;
291 int i;
293 zmw_get_wlan_dev(dev);
295 oppositeCount = wd->sta.oppositeCount;
297 for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
299 if ( oppositeCount == 0 )
301 break;
304 if ( wd->sta.oppositeInfo[i].valid == 0 )
306 continue;
309 oppositeCount--;
310 if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
312 //wd->sta.oppositeInfo[i].aliveCounter++;
313 wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
315 /* it is already stored */
316 return 1;
320 // Check if there's still space for new comer
321 if ( wd->sta.oppositeCount == ZM_MAX_OPPOSITE_COUNT )
323 return -1;
326 // Find an unused slot for new peer station
327 for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
329 if ( wd->sta.oppositeInfo[i].valid == 0 )
331 break;
335 *pFoundIdx = i;
336 return 0;
339 s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx)
341 u32_t oppositeCount;
342 u32_t i;
344 zmw_get_wlan_dev(dev);
346 oppositeCount = wd->sta.oppositeCount;
348 for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
350 if ( oppositeCount == 0 )
352 break;
355 if ( wd->sta.oppositeInfo[i].valid == 0 )
357 continue;
360 oppositeCount--;
361 if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
363 *pFoundIdx = (u8_t)i;
365 return 0;
369 *pFoundIdx = 0;
370 return 1;
373 static void zfStaInitCommonOppositeInfo(zdev_t* dev, int i)
375 zmw_get_wlan_dev(dev);
377 /* set the default rate to the highest rate */
378 wd->sta.oppositeInfo[i].valid = 1;
379 wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
380 wd->sta.oppositeCount++;
382 #ifdef ZM_ENABLE_IBSS_WPA2PSK
383 /* Set parameters for new opposite peer station !!! */
384 wd->sta.oppositeInfo[i].camIdx = 0xff; // Not set key in this location
385 wd->sta.oppositeInfo[i].pkInstalled = 0;
386 wd->sta.oppositeInfo[i].wpaState = ZM_STA_WPA_STATE_INIT ; // No encryption
387 #endif
390 int zfStaSetOppositeInfoFromBSSInfo(zdev_t* dev, struct zsBssInfo* pBssInfo)
392 int i;
393 u8_t* dst;
394 u16_t sa[3];
395 int res;
396 u32_t oneTxStreamCap;
398 zmw_get_wlan_dev(dev);
400 zfMemoryCopy((u8_t*) sa, pBssInfo->macaddr, 6);
402 res = zfStaFindFreeOpposite(dev, sa, &i);
403 if ( res != 0 )
405 goto zlReturn;
408 dst = wd->sta.oppositeInfo[i].macAddr;
409 zfMemoryCopy(dst, (u8_t *)sa, 6);
411 oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
413 if (pBssInfo->extSupportedRates[1] != 0)
415 /* TODO : Handle 11n */
416 if (pBssInfo->frequency < 3000)
418 /* 2.4GHz */
419 if (pBssInfo->EnableHT == 1)
420 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
421 else
422 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, pBssInfo->SG40);
424 else
426 /* 5GHz */
427 if (pBssInfo->EnableHT == 1)
428 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
429 else
430 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
433 else
435 /* TODO : Handle 11n */
436 if (pBssInfo->frequency < 3000)
438 /* 2.4GHz */
439 if (pBssInfo->EnableHT == 1)
440 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
441 else
442 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, pBssInfo->SG40);
444 else
446 /* 5GHz */
447 if (pBssInfo->EnableHT == 1)
448 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
449 else
450 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
455 zfStaInitCommonOppositeInfo(dev, i);
456 zlReturn:
457 return 0;
460 int zfStaSetOppositeInfoFromRxBuf(zdev_t* dev, zbuf_t* buf)
462 int i;
463 u8_t* dst;
464 u16_t sa[3];
465 int res = 0;
466 u16_t offset;
467 u8_t bSupportExtRate;
468 u32_t rtsctsRate = 0xffffffff; /* CTS:OFDM 6M, RTS:OFDM 6M */
469 u32_t oneTxStreamCap;
471 zmw_get_wlan_dev(dev);
472 zmw_declare_for_critical_section();
474 sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
475 sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
476 sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
478 zmw_enter_critical_section(dev);
480 res = zfStaFindFreeOpposite(dev, sa, &i);
481 if ( res != 0 )
483 goto zlReturn;
486 dst = wd->sta.oppositeInfo[i].macAddr;
487 zfCopyFromRxBuffer(dev, buf, dst, ZM_WLAN_HEADER_A2_OFFSET, 6);
489 if ( (wd->sta.currentFrequency < 3000) && !(wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
491 bSupportExtRate = 0;
492 } else {
493 bSupportExtRate = 1;
496 if ( (bSupportExtRate == 1)
497 && (wd->sta.currentFrequency < 3000)
498 && (wd->wlanMode == ZM_MODE_IBSS)
499 && (wd->wfc.bIbssGMode == 0) )
501 bSupportExtRate = 0;
504 wd->sta.connection_11b = 0;
505 oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
507 if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff)
508 && (bSupportExtRate == 1) )
510 /* TODO : Handle 11n */
511 if (wd->sta.currentFrequency < 3000)
513 /* 2.4GHz */
514 if (wd->sta.EnableHT == 1)
516 //11ng
517 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
519 else
521 //11g
522 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, wd->sta.SG40);
524 rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
526 else
528 /* 5GHz */
529 if (wd->sta.EnableHT == 1)
531 //11na
532 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
534 else
536 //11a
537 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
539 rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
542 else
544 /* TODO : Handle 11n */
545 if (wd->sta.currentFrequency < 3000)
547 /* 2.4GHz */
548 if (wd->sta.EnableHT == 1)
550 //11ng
551 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
552 rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
554 else
556 //11b
557 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, wd->sta.SG40);
558 rtsctsRate = 0x0; /* CTS:CCK 1M, RTS:CCK 1M */
559 wd->sta.connection_11b = 1;
562 else
564 /* 5GHz */
565 if (wd->sta.EnableHT == 1)
567 //11na
568 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
570 else
572 //11a
573 zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
575 rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
579 zfStaInitCommonOppositeInfo(dev, i);
581 zlReturn:
582 zmw_leave_critical_section(dev);
584 if (rtsctsRate != 0xffffffff)
586 zfHpSetRTSCTSRate(dev, rtsctsRate);
588 return res;
591 void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf)
593 u16_t offset;
594 u8_t erp;
595 u8_t bssid[6];
597 zmw_get_wlan_dev(dev);
599 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&(zfStaIsConnected(dev)) )
601 ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
603 if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6))
605 offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
606 if (offset != 0xffff)
608 erp = zmw_rx_buf_readb(dev, buf, offset+2);
610 if ( erp & ZM_BIT_1 )
612 //zm_debug_msg0("protection mode on");
613 if (wd->sta.bProtectionMode == FALSE)
615 wd->sta.bProtectionMode = TRUE;
616 zfHpSetSlotTime(dev, 0);
619 else
621 //zm_debug_msg0("protection mode off");
622 if (wd->sta.bProtectionMode == TRUE)
624 wd->sta.bProtectionMode = FALSE;
625 zfHpSetSlotTime(dev, 1);
630 //Check the existence of Non-N AP
631 //Follow the check the "pBssInfo->EnableHT"
632 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
633 if (offset != 0xffff)
635 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
637 else
638 {wd->sta.NonNAPcount++;}
642 void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf)
644 u16_t tmp;
645 u16_t aifs[5];
646 u16_t cwmin[5];
647 u16_t cwmax[5];
648 u16_t txop[5];
649 u8_t acm;
650 u8_t ac;
651 u16_t len;
652 u16_t i;
653 u16_t offset;
654 u8_t rxWmeParameterSetCount;
656 zmw_get_wlan_dev(dev);
658 /* Update if WME parameter set count is changed */
659 /* If connect to WME AP */
660 if (wd->sta.wmeConnected != 0)
662 /* Find WME parameter element */
663 offset = zfFindWifiElement(dev, buf, 2, 1);
664 if (offset != 0xffff)
666 len = zmw_rx_buf_readb(dev, buf, offset+1);
667 if (len >= 7)
669 rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8);
670 if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount)
672 zm_msg0_mm(ZM_LV_0, "wmeParameterSetCount changed!");
673 wd->sta.wmeParameterSetCount = rxWmeParameterSetCount;
674 /* retrieve WME parameter and update TxQ parameters */
675 acm = 0xf;
676 for (i=0; i<4; i++)
678 if (len >= (8+(i*4)+4))
680 tmp=zmw_rx_buf_readb(dev, buf, offset+10+i*4);
681 ac = (tmp >> 5) & 0x3;
682 if ((tmp & 0x10) == 0)
684 acm &= (~(1<<ac));
686 aifs[ac] = ((tmp & 0xf) * 9) + 10;
687 tmp=zmw_rx_buf_readb(dev, buf, offset+11+i*4);
688 /* Convert to 2^n */
689 cwmin[ac] = zcCwTlb[(tmp & 0xf)];
690 cwmax[ac] = zcCwTlb[(tmp >> 4)];
691 txop[ac]=zmw_rx_buf_readh(dev, buf,
692 offset+12+i*4);
696 if ((acm & 0x4) != 0)
698 cwmin[2] = cwmin[0];
699 cwmax[2] = cwmax[0];
700 aifs[2] = aifs[0];
701 txop[2] = txop[0];
703 if ((acm & 0x8) != 0)
705 cwmin[3] = cwmin[2];
706 cwmax[3] = cwmax[2];
707 aifs[3] = aifs[2];
708 txop[3] = txop[2];
710 cwmin[4] = 3;
711 cwmax[4] = 7;
712 aifs[4] = 28;
714 if ((cwmin[2]+aifs[2]) > ((cwmin[0]+aifs[0])+1))
716 wd->sta.ac0PriorityHigherThanAc2 = 1;
718 else
720 wd->sta.ac0PriorityHigherThanAc2 = 0;
722 zfHpUpdateQosParameter(dev, cwmin, cwmax, aifs, txop);
726 } //if (wd->sta.wmeConnected != 0)
728 /* process 802.11h Dynamic Frequency Selection */
729 void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
731 //u8_t length, channel, is5G;
732 u16_t offset;
734 zmw_get_wlan_dev(dev);
737 Channel Switch Announcement Element Format
738 +------+----------+------+-------------------+------------------+--------------------+
739 |Format|Element ID|Length|Channel Switch Mode|New Channel Number|Channel Switch Count|
740 +------+----------+------+-------------------+------------------+--------------------+
741 |Bytes | 1 | 1 | 1 | 1 | 1 |
742 +------+----------+------+-------------------+------------------+--------------------+
743 |Value | 37 | 3 | 0 or 1 |unsigned integer |unsigned integer |
744 +------+----------+------+-------------------+------------------+--------------------+
747 /* get EID(Channel Switch Announcement) */
748 offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE);
749 if (offset == 0xffff)
751 //zm_debug_msg0("EID(Channel Switch Announcement) not found");
752 return;
754 else if ( zmw_rx_buf_readb(dev, buf, offset+1) == 0x3 )
756 zm_debug_msg0("EID(Channel Switch Announcement) found");
758 //length = zmw_rx_buf_readb(dev, buf, offset+1);
759 //zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
761 //Chanell Switch Mode set to 1, driver should disable transmit immediate
762 //we do this by poll CCA high
763 if (zmw_rx_buf_readb(dev, buf, offset+2) == 0x1 )
765 //use ZM_OID_INTERNAL_WRITE,ZM_CMD_RESET to notice firmware flush quene and stop dma,
766 //then restart rx dma but not tx dma
767 if (wd->sta.DFSDisableTx != TRUE)
769 /* TODO : zfHpResetTxRx would cause Rx hang */
770 //zfHpResetTxRx(dev);
771 wd->sta.DFSDisableTx = TRUE;
772 /* Trgger Rx DMA */
773 zfHpStartRecv(dev);
775 //Adapter->ZD80211HSetting.DisableTxBy80211H=TRUE;
776 //AcquireCtrOfPhyReg(Adapter);
777 //ZD1205_WRITE_REGISTER(Adapter,CR24, 0x0);
778 //ReleaseDoNotSleep(Adapter);
781 if (zmw_rx_buf_readb(dev, buf, offset+4) <= 0x2 )
783 //Channel Switch
784 //if Channel Switch Count = 0 , STA should change channel immediately.
785 //if Channel Switch Count > 0 , STA should change channel after TBTT*count
786 //But it won't be accurate to let driver calculate TBTT*count, and the value of
787 //Channel Switch Count will decrease by one each when continue receving beacon
788 //So we change channel here when we receive count <=2.
790 zfHpDeleteAllowChannel(dev, wd->sta.currentFrequency);
791 wd->frequency = zfChNumToFreq(dev, zmw_rx_buf_readb(dev, buf, offset+3), 0);
792 //zfHpAddAllowChannel(dev, wd->frequency);
793 zm_debug_msg1("CWY - jump to frequency = ", wd->frequency);
794 zfCoreSetFrequency(dev, wd->frequency);
795 wd->sta.DFSDisableTx = FALSE;
796 /* Increase rxBeaconCount to prevent beacon lost */
797 if (zfStaIsConnected(dev))
799 wd->sta.rxBeaconCount = 1 << 6; // 2 times of check would pass
801 //start tx dma to transmit packet
803 //if (zmw_rx_buf_readb(dev, buf, offset+3) != wd->frequency)
805 // //ZDDbgPrint(("Radar Detect by AP\n"));
806 // zfCoreSetFrequency();
807 // ProcessRadarDetectEvent(Adapter);
808 // Set_RF_Channel(Adapter, SwRfd->Rfd->RxBuffer[index+3], (UCHAR)Adapter->RF_Mode, 1);
809 // Adapter->CardSetting.Channel = SwRfd->Rfd->RxBuffer[index+3];
810 // Adapter->SaveChannel = Adapter->CardSetting.Channel;
811 // Adapter->UtilityChannel = Adapter->CardSetting.Channel;
817 /* TODO : process 802.11h Transmission Power Control */
818 void zfStaUpdateDot11HTPC(zdev_t* dev, zbuf_t* buf)
822 /* IBSS power-saving mode */
823 void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf)
825 u8_t i, frameCtrl;
827 zmw_get_wlan_dev(dev);
829 if ( !zfStaIsConnected(dev) )
831 return;
834 if ( wd->wlanMode != ZM_MODE_IBSS )
836 return ;
839 /* check BSSID */
840 if ( !zfRxBufferEqualToStr(dev, buf, (u8_t*) wd->sta.bssid,
841 ZM_WLAN_HEADER_A3_OFFSET, 6) )
843 return;
846 frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
848 /* check power management bit */
849 if ( frameCtrl & ZM_BIT_4 )
851 for(i=1; i<ZM_MAX_PS_STA; i++)
853 if ( !wd->sta.staPSList.entity[i].bUsed )
855 continue;
858 /* check source address */
859 if ( zfRxBufferEqualToStr(dev, buf,
860 wd->sta.staPSList.entity[i].macAddr,
861 ZM_WLAN_HEADER_A2_OFFSET, 6) )
863 return;
867 for(i=1; i<ZM_MAX_PS_STA; i++)
869 if ( !wd->sta.staPSList.entity[i].bUsed )
871 wd->sta.staPSList.entity[i].bUsed = TRUE;
872 wd->sta.staPSList.entity[i].bDataQueued = FALSE;
873 break;
877 if ( i == ZM_MAX_PS_STA )
879 /* STA list is full */
880 return;
883 zfCopyFromRxBuffer(dev, buf, wd->sta.staPSList.entity[i].macAddr,
884 ZM_WLAN_HEADER_A2_OFFSET, 6);
886 if ( wd->sta.staPSList.count == 0 )
888 // enable ATIM window
889 //zfEnableAtimWindow(dev);
892 wd->sta.staPSList.count++;
894 else if ( wd->sta.staPSList.count )
896 for(i=1; i<ZM_MAX_PS_STA; i++)
898 if ( wd->sta.staPSList.entity[i].bUsed )
900 if ( zfRxBufferEqualToStr(dev, buf,
901 wd->sta.staPSList.entity[i].macAddr,
902 ZM_WLAN_HEADER_A2_OFFSET, 6) )
904 wd->sta.staPSList.entity[i].bUsed = FALSE;
905 wd->sta.staPSList.count--;
907 if ( wd->sta.staPSList.entity[i].bDataQueued )
909 /* send queued data */
915 if ( wd->sta.staPSList.count == 0 )
917 /* disable ATIM window */
918 //zfDisableAtimWindow(dev);
924 /* IBSS power-saving mode */
925 u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf)
927 u8_t i;
928 u16_t da[3];
930 zmw_get_wlan_dev(dev);
932 if ( !zfStaIsConnected(dev) )
934 return 0;
937 if ( wd->wlanMode != ZM_MODE_IBSS )
939 return 0;
942 if ( wd->sta.staPSList.count == 0 && wd->sta.powerSaveMode <= ZM_STA_PS_NONE )
944 return 0;
947 /* DA */
948 #ifdef ZM_ENABLE_NATIVE_WIFI
949 da[0] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
950 da[1] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 2);
951 da[2] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 4);
952 #else
953 da[0] = zmw_tx_buf_readh(dev, buf, 0);
954 da[1] = zmw_tx_buf_readh(dev, buf, 2);
955 da[2] = zmw_tx_buf_readh(dev, buf, 4);
956 #endif
958 if ( ZM_IS_MULTICAST_OR_BROADCAST(da) )
960 wd->sta.staPSList.entity[0].bDataQueued = TRUE;
961 wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
962 return 1;
965 // Unicast packet...
967 for(i=1; i<ZM_MAX_PS_STA; i++)
969 if ( zfMemoryIsEqual(wd->sta.staPSList.entity[i].macAddr,
970 (u8_t*) da, 6) )
972 wd->sta.staPSList.entity[i].bDataQueued = TRUE;
973 wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
975 return 1;
980 return 0;
983 /* IBSS power-saving mode */
984 void zfStaIbssPSSend(zdev_t* dev)
986 u8_t i;
987 u16_t bcastAddr[3] = {0xffff, 0xffff, 0xffff};
989 zmw_get_wlan_dev(dev);
991 if ( !zfStaIsConnected(dev) )
993 return ;
996 if ( wd->wlanMode != ZM_MODE_IBSS )
998 return ;
1001 for(i=0; i<ZM_MAX_PS_STA; i++)
1003 if ( wd->sta.staPSList.entity[i].bDataQueued )
1005 if ( i == 0 )
1007 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1008 bcastAddr,
1009 0, 0, 0);
1011 else if ( wd->sta.staPSList.entity[i].bUsed )
1013 // Send ATIM to prevent the peer to go to sleep
1014 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1015 (u16_t*) wd->sta.staPSList.entity[i].macAddr,
1016 0, 0, 0);
1019 wd->sta.staPSList.entity[i].bDataQueued = FALSE;
1023 for(i=0; i<wd->sta.ibssPSDataCount; i++)
1025 zfTxSendEth(dev, wd->sta.ibssPSDataQueue[i], 0,
1026 ZM_EXTERNAL_ALLOC_BUF, 0);
1029 wd->sta.ibssPrevPSDataCount = wd->sta.ibssPSDataCount;
1030 wd->sta.ibssPSDataCount = 0;
1034 void zfStaReconnect(zdev_t* dev)
1036 zmw_get_wlan_dev(dev);
1037 zmw_declare_for_critical_section();
1039 if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE &&
1040 wd->wlanMode != ZM_MODE_IBSS )
1042 return;
1045 if ( (zfStaIsConnected(dev))||(zfStaIsConnecting(dev)) )
1047 return;
1050 if ( wd->sta.bChannelScan )
1052 return;
1055 /* Recover zero SSID length */
1056 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (wd->ws.ssidLen == 0))
1058 zm_debug_msg0("zfStaReconnect: NOT Support!! Set SSID to any BSS");
1059 /* ANY BSS */
1060 zmw_enter_critical_section(dev);
1061 wd->sta.ssid[0] = 0;
1062 wd->sta.ssidLen = 0;
1063 zmw_leave_critical_section(dev);
1066 // RAY: To ensure no TX pending before re-connecting
1067 zfFlushVtxq(dev);
1068 zfWlanEnable(dev);
1069 zfScanMgrScanAck(dev);
1072 void zfStaTimer100ms(zdev_t* dev)
1074 zmw_get_wlan_dev(dev);
1076 if ( (wd->tick % 10) == 0 )
1078 zfPushVtxq(dev);
1079 // zfPowerSavingMgrMain(dev);
1084 void zfStaCheckRxBeacon(zdev_t* dev)
1086 zmw_get_wlan_dev(dev);
1088 if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) && (zfStaIsConnected(dev)))
1090 if (wd->beaconInterval == 0)
1092 wd->beaconInterval = 100;
1094 if ( (wd->tick % ((wd->beaconInterval * 10) / ZM_MS_PER_TICK)) == 0 )
1096 /* Check rxBeaconCount */
1097 if (wd->sta.rxBeaconCount == 0)
1099 if (wd->sta.beaconMissState == 1)
1101 /*notify AP that we left*/
1102 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
1103 /* Beacon Lost */
1104 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS,
1105 wd->sta.bssid, 0);
1107 else
1109 wd->sta.beaconMissState = 1;
1110 /* Reset channel */
1111 zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40,
1112 wd->ExtOffset, NULL, 1);
1115 else
1117 wd->sta.beaconMissState = 0;
1119 wd->sta.rxBeaconCount = 0;
1126 void zfStaCheckConnectTimeout(zdev_t* dev)
1128 zmw_get_wlan_dev(dev);
1129 zmw_declare_for_critical_section();
1131 if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
1133 return;
1136 if ( !zfStaIsConnecting(dev) )
1138 return;
1141 zmw_enter_critical_section(dev);
1142 if ( (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN)||
1143 (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1)||
1144 (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2)||
1145 (wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE) )
1147 if ( (wd->tick - wd->sta.connectTimer) > ZM_INTERVAL_CONNECT_TIMEOUT )
1149 if ( wd->sta.connectByReasso )
1151 wd->sta.failCntOfReasso++;
1152 if ( wd->sta.failCntOfReasso > 2 )
1154 wd->sta.connectByReasso = FALSE;
1158 wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
1159 zm_debug_msg1("connect timeout, state = ", wd->sta.connectState);
1160 //zfiWlanDisable(dev);
1161 goto failed;
1165 zmw_leave_critical_section(dev);
1166 return;
1168 failed:
1169 zmw_leave_critical_section(dev);
1170 if(wd->sta.authMode == ZM_AUTH_MODE_AUTO)
1171 { // Fix some AP not send authentication failed message to sta and lead to connect timeout !
1172 wd->sta.connectTimeoutCount++;
1174 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT, wd->sta.bssid, 2);
1175 return;
1178 void zfMmStaTimeTick(zdev_t* dev)
1180 zmw_get_wlan_dev(dev);
1182 /* airopeek */
1183 if (wd->wlanMode != ZM_MODE_AP && !wd->swSniffer)
1185 if ( wd->tick & 1 )
1187 zfTimerCheckAndHandle(dev);
1190 zfStaCheckRxBeacon(dev);
1191 zfStaTimer100ms(dev);
1192 zfStaCheckConnectTimeout(dev);
1193 zfPowerSavingMgrMain(dev);
1196 #ifdef ZM_ENABLE_AGGREGATION
1198 * add by honda
1200 zfAggScanAndClear(dev, wd->tick);
1201 #endif
1204 void zfStaSendBeacon(zdev_t* dev)
1206 zbuf_t* buf;
1207 u16_t offset, seq;
1209 zmw_get_wlan_dev(dev);
1211 zmw_declare_for_critical_section();
1213 //zm_debug_msg0("\n");
1215 /* TBD : Maximum size of beacon */
1216 buf = zfwBufAllocate(dev, 1024);
1217 if (buf == NULL)
1219 zm_debug_msg0("Allocate beacon buffer failed");
1220 return;
1223 offset = 0;
1224 /* wlan header */
1225 /* Frame control */
1226 zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1227 offset+=2;
1228 /* Duration */
1229 zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1230 offset+=2;
1231 /* Address 1 */
1232 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1233 offset+=2;
1234 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1235 offset+=2;
1236 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1237 offset+=2;
1238 /* Address 2 */
1239 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1240 offset+=2;
1241 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1242 offset+=2;
1243 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]);
1244 offset+=2;
1245 /* Address 3 */
1246 zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]);
1247 offset+=2;
1248 zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]);
1249 offset+=2;
1250 zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]);
1251 offset+=2;
1253 /* Sequence number */
1254 zmw_enter_critical_section(dev);
1255 seq = ((wd->mmseq++)<<4);
1256 zmw_leave_critical_section(dev);
1257 zmw_tx_buf_writeh(dev, buf, offset, seq);
1258 offset+=2;
1260 /* 24-31 Time Stamp : hardware will fill this field */
1261 offset+=8;
1263 /* Beacon Interval */
1264 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1265 offset+=2;
1267 /* Capability */
1268 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]);
1269 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]);
1271 /* SSID */
1272 offset = zfStaAddIeSsid(dev, buf, offset);
1274 if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g
1277 /* Support Rate */
1278 offset = zfMmAddIeSupportRate(dev, buf, offset,
1279 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1281 /* DS parameter set */
1282 offset = zfMmAddIeDs(dev, buf, offset);
1284 offset = zfStaAddIeIbss(dev, buf, offset);
1286 if( wd->wfc.bIbssGMode
1287 && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode .
1289 /* ERP Information */
1290 wd->erpElement = 0;
1291 offset = zfMmAddIeErp(dev, buf, offset);
1294 /* TODO : country information */
1295 /* RSN */
1296 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1298 offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1301 if( wd->wfc.bIbssGMode
1302 && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode .
1304 /* Enable G Mode */
1305 /* Extended Supported Rates */
1306 offset = zfMmAddIeSupportRate(dev, buf, offset,
1307 ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
1310 else // 5GHz a
1312 /* Support Rate a Mode */
1313 offset = zfMmAddIeSupportRate(dev, buf, offset,
1314 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1316 /* DS parameter set */
1317 offset = zfMmAddIeDs(dev, buf, offset);
1319 offset = zfStaAddIeIbss(dev, buf, offset);
1321 /* TODO : country information */
1322 /* RSN */
1323 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1325 offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1329 if ( wd->wlanMode != ZM_MODE_IBSS )
1331 /* TODO : Need to check if it is ok */
1332 /* HT Capabilities Info */
1333 offset = zfMmAddHTCapability(dev, buf, offset);
1335 /* Extended HT Capabilities Info */
1336 offset = zfMmAddExtendedHTCapability(dev, buf, offset);
1339 if ( wd->sta.ibssAdditionalIESize )
1340 offset = zfStaAddIbssAdditionalIE(dev, buf, offset);
1342 /* 1212 : write to beacon fifo */
1343 /* 1221 : write to share memory */
1344 zfHpSendBeacon(dev, buf, offset);
1346 /* Free beacon buffer */
1347 //zfwBufFree(dev, buf, 0);
1350 void zfStaSignalStatistic(zdev_t* dev, u8_t SignalStrength, u8_t SignalQuality) //CWYang(+)
1352 zmw_get_wlan_dev(dev);
1354 /* Add Your Code to Do Works Like Moving Average Here */
1355 wd->SignalStrength = (wd->SignalStrength * 7 + SignalStrength * 3)/10;
1356 wd->SignalQuality = (wd->SignalQuality * 7 + SignalQuality * 3)/10;
1360 struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader)
1362 u8_t i;
1363 u8_t j;
1364 u8_t k;
1365 u8_t isMatched, length, channel;
1366 u16_t offset, frequency;
1367 struct zsBssInfo* pBssInfo;
1369 zmw_get_wlan_dev(dev);
1371 pBssInfo = wd->sta.bssList.head;
1372 if (pBssInfo == NULL)
1374 return NULL;
1377 for( i=0; i<wd->sta.bssList.bssCount; i++ )
1379 //zm_debug_msg2("check pBssInfo = ", pBssInfo);
1381 /* Check BSSID */
1382 for( j=0; j<6; j++ )
1384 if ( pBssInfo->bssid[j] != pProbeRspHeader->bssid[j] )
1386 break;
1390 /* Check SSID */
1391 if (j == 6)
1393 if (pProbeRspHeader->ssid[1] <= 32)
1395 /* compare length and ssid */
1396 isMatched = 1;
1397 if((pProbeRspHeader->ssid[1] != 0) && (pBssInfo->ssid[1] != 0))
1399 for( k=1; k<pProbeRspHeader->ssid[1] + 1; k++ )
1401 if ( pBssInfo->ssid[k] != pProbeRspHeader->ssid[k] )
1403 isMatched = 0;
1404 break;
1409 else
1411 isMatched = 0;
1414 else
1416 isMatched = 0;
1419 /* Check channel */
1420 /* Add check channel to solve the bug #31222 */
1421 if (isMatched) {
1422 offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS);
1423 if (offset != 0xffff) {
1424 length = zmw_rx_buf_readb(dev, buf, offset+1);
1425 if (length == 1) {
1426 channel = zmw_rx_buf_readb(dev, buf, offset+2);
1427 if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) {
1428 frequency = 0;
1429 } else {
1430 frequency = zfChNumToFreq(dev, channel, 0);;
1432 } else {
1433 frequency = 0;
1435 } else {
1436 frequency = wd->sta.currentFrequency;
1439 if (frequency != 0) {
1440 if ( ((frequency > 3000) && (pBssInfo->frequency > 3000))
1441 || ((frequency < 3000) && (pBssInfo->frequency < 3000)) ) {
1442 /* redundant */
1443 break;
1448 pBssInfo = pBssInfo->next;
1451 if ( i == wd->sta.bssList.bssCount )
1453 pBssInfo = NULL;
1456 return pBssInfo;
1459 u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf,
1460 struct zsWlanProbeRspFrameHeader *pProbeRspHeader,
1461 struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type)
1463 u8_t length, channel, is5G;
1464 u16_t i, offset;
1465 u8_t apQosInfo;
1466 u16_t eachIElength = 0;
1467 u16_t accumulateLen = 0;
1469 zmw_get_wlan_dev(dev);
1471 if ((type == 1) && ((pBssInfo->flag & ZM_BSS_INFO_VALID_BIT) != 0))
1473 goto zlUpdateRssi;
1476 /* get SSID */
1477 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
1478 if (offset == 0xffff)
1480 zm_debug_msg0("EID(SSID) not found");
1481 goto zlError;
1484 length = zmw_rx_buf_readb(dev, buf, offset+1);
1487 u8_t Show_Flag = 0;
1488 zfwGetShowZeroLengthSSID(dev, &Show_Flag);
1490 if(Show_Flag)
1492 if (length > ZM_MAX_SSID_LENGTH )
1494 zm_debug_msg0("EID(SSID) is invalid");
1495 goto zlError;
1498 else
1500 if ( length == 0 || length > ZM_MAX_SSID_LENGTH )
1502 zm_debug_msg0("EID(SSID) is invalid");
1503 goto zlError;
1508 zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2);
1510 /* get DS parameter */
1511 offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS);
1512 if (offset != 0xffff)
1514 length = zmw_rx_buf_readb(dev, buf, offset+1);
1515 if ( length != 1 )
1517 zm_msg0_mm(ZM_LV_0, "Abnormal DS Param Set IE");
1518 goto zlError;
1520 channel = zmw_rx_buf_readb(dev, buf, offset+2);
1522 if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0)
1524 goto zlError2;
1527 pBssInfo->frequency = zfChNumToFreq(dev, channel, 0); // auto check
1528 pBssInfo->channel = channel;
1532 else
1534 /* DS parameter not found */
1535 pBssInfo->frequency = wd->sta.currentFrequency;
1536 pBssInfo->channel = zfChFreqToNum(wd->sta.currentFrequency, &is5G);
1539 /* initialize security type */
1540 pBssInfo->securityType = ZM_SECURITY_TYPE_NONE;
1542 /* get macaddr */
1543 for( i=0; i<6; i++ )
1545 pBssInfo->macaddr[i] = pProbeRspHeader->sa[i];
1548 /* get bssid */
1549 for( i=0; i<6; i++ )
1551 pBssInfo->bssid[i] = pProbeRspHeader->bssid[i];
1554 /* get timestamp */
1555 for( i=0; i<8; i++ )
1557 pBssInfo->timeStamp[i] = pProbeRspHeader->timeStamp[i];
1560 /* get beacon interval */
1561 pBssInfo->beaconInterval[0] = pProbeRspHeader->beaconInterval[0];
1562 pBssInfo->beaconInterval[1] = pProbeRspHeader->beaconInterval[1];
1564 /* get capability */
1565 pBssInfo->capability[0] = pProbeRspHeader->capability[0];
1566 pBssInfo->capability[1] = pProbeRspHeader->capability[1];
1568 /* Copy frame body */
1569 offset = 36; // Copy from the start of variable IE
1570 pBssInfo->frameBodysize = zfwBufGetSize(dev, buf)-offset;
1571 if (pBssInfo->frameBodysize > (ZM_MAX_PROBE_FRAME_BODY_SIZE-1))
1573 pBssInfo->frameBodysize = ZM_MAX_PROBE_FRAME_BODY_SIZE-1;
1575 accumulateLen = 0;
1578 eachIElength = zmw_rx_buf_readb(dev, buf, offset + accumulateLen+1) + 2; //Len+(EID+Data)
1580 if ( (eachIElength >= 2)
1581 && ((accumulateLen + eachIElength) <= pBssInfo->frameBodysize) )
1583 zfCopyFromRxBuffer(dev, buf, pBssInfo->frameBody+accumulateLen, offset+accumulateLen, eachIElength);
1584 accumulateLen+=(u16_t)eachIElength;
1586 else
1588 zm_msg0_mm(ZM_LV_1, "probersp frameBodysize abnormal");
1589 break;
1592 while(accumulateLen < pBssInfo->frameBodysize);
1593 pBssInfo->frameBodysize = accumulateLen;
1595 /* get supported rates */
1596 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE);
1597 if (offset == 0xffff)
1599 zm_debug_msg0("EID(supported rates) not found");
1600 goto zlError;
1603 length = zmw_rx_buf_readb(dev, buf, offset+1);
1604 if ( length == 0 || length > ZM_MAX_SUPP_RATES_IE_SIZE)
1606 zm_msg0_mm(ZM_LV_0, "Supported rates IE length abnormal");
1607 goto zlError;
1609 zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
1613 /* get Country information */
1614 offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY);
1615 if (offset != 0xffff)
1617 length = zmw_rx_buf_readb(dev, buf, offset+1);
1618 if (length > ZM_MAX_COUNTRY_INFO_SIZE)
1620 length = ZM_MAX_COUNTRY_INFO_SIZE;
1622 zfCopyFromRxBuffer(dev, buf, pBssInfo->countryInfo, offset, length+2);
1623 /* check 802.11d support data */
1624 if (wd->sta.b802_11D)
1626 zfHpGetRegulationTablefromISO(dev, (u8_t *)&pBssInfo->countryInfo, 3);
1627 /* only set regulatory one time */
1628 wd->sta.b802_11D = 0;
1632 /* get ERP information */
1633 offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
1634 if (offset != 0xffff)
1636 pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
1639 /* get extended supported rates */
1640 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE);
1641 if (offset != 0xffff)
1643 length = zmw_rx_buf_readb(dev, buf, offset+1);
1644 if (length > ZM_MAX_SUPP_RATES_IE_SIZE)
1646 zm_msg0_mm(ZM_LV_0, "Extended rates IE length abnormal");
1647 goto zlError;
1649 zfCopyFromRxBuffer(dev, buf, pBssInfo->extSupportedRates, offset, length+2);
1651 else
1653 pBssInfo->extSupportedRates[0] = 0;
1654 pBssInfo->extSupportedRates[1] = 0;
1657 /* get WPA IE */
1658 offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE);
1659 if (offset != 0xffff)
1661 length = zmw_rx_buf_readb(dev, buf, offset+1);
1662 if (length > ZM_MAX_IE_SIZE)
1664 length = ZM_MAX_IE_SIZE;
1666 zfCopyFromRxBuffer(dev, buf, pBssInfo->wpaIe, offset, length+2);
1667 pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1669 else
1671 pBssInfo->wpaIe[1] = 0;
1674 /* get WPS IE */
1675 offset = zfFindWifiElement(dev, buf, 4, 0xff);
1676 if (offset != 0xffff)
1678 length = zmw_rx_buf_readb(dev, buf, offset+1);
1679 if (length > ZM_MAX_WPS_IE_SIZE )
1681 length = ZM_MAX_WPS_IE_SIZE;
1683 zfCopyFromRxBuffer(dev, buf, pBssInfo->wscIe, offset, length+2);
1685 else
1687 pBssInfo->wscIe[1] = 0;
1690 /* get SuperG IE */
1691 offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE);
1692 if (offset != 0xffff)
1694 pBssInfo->apCap |= ZM_SuperG_AP;
1697 /* get XR IE */
1698 offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE);
1699 if (offset != 0xffff)
1701 pBssInfo->apCap |= ZM_XR_AP;
1704 /* get RSN IE */
1705 offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE);
1706 if (offset != 0xffff)
1708 length = zmw_rx_buf_readb(dev, buf, offset+1);
1709 if (length > ZM_MAX_IE_SIZE)
1711 length = ZM_MAX_IE_SIZE;
1713 zfCopyFromRxBuffer(dev, buf, pBssInfo->rsnIe, offset, length+2);
1714 pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1716 else
1718 pBssInfo->rsnIe[1] = 0;
1720 #ifdef ZM_ENABLE_CENC
1721 /* get CENC IE */
1722 offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE);
1723 if (offset != 0xffff)
1725 length = zmw_rx_buf_readb(dev, buf, offset+1);
1726 if (length > ZM_MAX_IE_SIZE )
1728 length = ZM_MAX_IE_SIZE;
1730 zfCopyFromRxBuffer(dev, buf, pBssInfo->cencIe, offset, length+2);
1731 pBssInfo->securityType = ZM_SECURITY_TYPE_CENC;
1732 pBssInfo->capability[0] &= 0xffef;
1734 else
1736 pBssInfo->cencIe[1] = 0;
1738 #endif //ZM_ENABLE_CENC
1739 /* get WME Parameter IE, probe rsp may contain WME parameter element */
1740 //if ( wd->bQoSEnable )
1742 offset = zfFindWifiElement(dev, buf, 2, 1);
1743 if (offset != 0xffff)
1745 apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1746 pBssInfo->wmeSupport = 1 | apQosInfo;
1748 else if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff)
1750 apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1751 pBssInfo->wmeSupport = 1 | apQosInfo;
1753 else
1755 pBssInfo->wmeSupport = 0;
1758 //CWYang(+)
1759 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1760 if (offset != 0xffff)
1762 /* 11n AP */
1763 pBssInfo->EnableHT = 1;
1764 if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x02)
1766 pBssInfo->enableHT40 = 1;
1768 else
1770 pBssInfo->enableHT40 = 0;
1773 if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x40)
1775 pBssInfo->SG40 = 1;
1777 else
1779 pBssInfo->SG40 = 0;
1782 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
1784 /* 11n AP */
1785 pBssInfo->EnableHT = 1;
1786 pBssInfo->apCap |= ZM_All11N_AP;
1787 if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x02)
1789 pBssInfo->enableHT40 = 1;
1791 else
1793 pBssInfo->enableHT40 = 0;
1796 if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x40)
1798 pBssInfo->SG40 = 1;
1800 else
1802 pBssInfo->SG40 = 0;
1805 else
1807 pBssInfo->EnableHT = 0;
1809 /* HT information */
1810 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1811 if (offset != 0xffff)
1813 /* atheros pre n */
1814 pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03;
1816 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
1818 /* pre n 2.0 standard */
1819 pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+3) & 0x03;
1821 else
1823 pBssInfo->extChOffset = 0;
1826 if ( (pBssInfo->enableHT40 == 1)
1827 && ((pBssInfo->extChOffset != 1) && (pBssInfo->extChOffset != 3)) )
1829 pBssInfo->enableHT40 = 0;
1832 if (pBssInfo->enableHT40 == 1)
1834 if (zfHpIsAllowedChannel(dev, pBssInfo->frequency+((pBssInfo->extChOffset==1)?20:-20)) == 0)
1836 /* if extension channel is not an allowed channel, treat AP as non-HT mode */
1837 pBssInfo->EnableHT = 0;
1838 pBssInfo->enableHT40 = 0;
1839 pBssInfo->extChOffset = 0;
1843 /* get ATH Extended Capability */
1844 if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)&&
1845 ((offset = zfFindBrdcmMrvlRlnkExtCap(dev, buf)) == 0xffff))
1848 pBssInfo->athOwlAp = 1;
1850 else
1852 pBssInfo->athOwlAp = 0;
1855 /* get Broadcom Extended Capability */
1856 if ( (pBssInfo->EnableHT == 1) //((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)
1857 && ((offset = zfFindBroadcomExtCap(dev, buf)) != 0xffff) )
1859 pBssInfo->broadcomHTAp = 1;
1861 else
1863 pBssInfo->broadcomHTAp = 0;
1866 /* get Marvel Extended Capability */
1867 offset = zfFindMarvelExtCap(dev, buf);
1868 if (offset != 0xffff)
1870 pBssInfo->marvelAp = 1;
1872 else
1874 pBssInfo->marvelAp = 0;
1877 /* get ATIM window */
1878 offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS);
1879 if (offset != 0xffff )
1881 pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2);
1884 /* Fit for support mode */
1885 if (pBssInfo->frequency > 3000) {
1886 if (wd->supportMode & ZM_WIRELESS_MODE_5_N) {
1887 } else {
1888 if (wd->supportMode & ZM_WIRELESS_MODE_5_54) {
1889 /* support mode: a */
1890 /* delete n mode information */
1891 pBssInfo->EnableHT = 0;
1892 pBssInfo->enableHT40 = 0;
1893 pBssInfo->apCap &= (~ZM_All11N_AP);
1894 pBssInfo->extChOffset = 0;
1895 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1896 pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1897 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1898 pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1899 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1900 pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1901 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1902 pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1903 } else {
1904 /* support mode: none */
1905 goto zlError2;
1908 } else {
1909 if (wd->supportMode & ZM_WIRELESS_MODE_24_N) {
1910 } else {
1911 /* delete n mode information */
1912 pBssInfo->EnableHT = 0;
1913 pBssInfo->enableHT40 = 0;
1914 pBssInfo->apCap &= (~ZM_All11N_AP);
1915 pBssInfo->extChOffset = 0;
1916 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1917 pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1918 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1919 pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1920 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1921 pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1922 pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1923 pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1925 if (wd->supportMode & ZM_WIRELESS_MODE_24_54) {
1926 } else {
1927 if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1928 /* support mode: b */
1929 /* delete n mode information */
1930 if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates)
1931 || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) {
1932 goto zlError2;
1933 } else {
1934 zfGatherBMode(dev, pBssInfo->supportedRates,
1935 pBssInfo->extSupportedRates);
1936 pBssInfo->erp = 0;
1938 pBssInfo->frameBodysize = zfRemoveElement(dev,
1939 pBssInfo->frameBody, pBssInfo->frameBodysize,
1940 ZM_WLAN_EID_ERP);
1941 pBssInfo->frameBodysize = zfRemoveElement(dev,
1942 pBssInfo->frameBody, pBssInfo->frameBodysize,
1943 ZM_WLAN_EID_EXTENDED_RATE);
1945 pBssInfo->frameBodysize = zfUpdateElement(dev,
1946 pBssInfo->frameBody, pBssInfo->frameBodysize,
1947 pBssInfo->supportedRates);
1949 } else {
1950 /* support mode: none */
1951 goto zlError2;
1957 pBssInfo->flag |= ZM_BSS_INFO_VALID_BIT;
1959 zlUpdateRssi:
1960 /* Update Timer information */
1961 pBssInfo->tick = wd->tick;
1963 /* Update ERP information */
1964 offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
1965 if (offset != 0xffff)
1967 pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
1970 if( (s8_t)pBssInfo->signalStrength < (s8_t)AddInfo->Tail.Data.SignalStrength1 )
1972 /* Update signal strength */
1973 pBssInfo->signalStrength = (u8_t)AddInfo->Tail.Data.SignalStrength1;
1974 /* Update signal quality */
1975 pBssInfo->signalQuality = (u8_t)(AddInfo->Tail.Data.SignalStrength1 * 2);
1977 /* Update the sorting value */
1978 pBssInfo->sortValue = zfComputeBssInfoWeightValue(dev,
1979 (pBssInfo->supportedRates[6] + pBssInfo->extSupportedRates[0]),
1980 pBssInfo->EnableHT,
1981 pBssInfo->enableHT40,
1982 pBssInfo->signalStrength);
1985 return 0;
1987 zlError:
1989 return 1;
1991 zlError2:
1993 return 2;
1996 void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m)
1998 /* Parse TIM and send PS-POLL in power saving mode */
1999 struct zsWlanBeaconFrameHeader* pBeaconHeader;
2000 struct zsBssInfo* pBssInfo;
2001 u8_t pBuf[sizeof(struct zsWlanBeaconFrameHeader)];
2002 u8_t bssid[6];
2003 int res;
2005 zmw_get_wlan_dev(dev);
2007 zmw_declare_for_critical_section();
2009 /* sta routine jobs */
2010 zfStaProtErpMonitor(dev, buf); /* check protection mode */
2012 if (zfStaIsConnected(dev))
2014 ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
2016 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2018 if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6) )
2020 zfPowerSavingMgrProcessBeacon(dev, buf);
2021 zfStaUpdateWmeParameter(dev, buf);
2022 if (wd->sta.DFSEnable)
2023 zfStaUpdateDot11HDFS(dev, buf);
2024 if (wd->sta.TPCEnable)
2025 zfStaUpdateDot11HTPC(dev, buf);
2026 /* update signal strength and signal quality */
2027 zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2028 AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2029 wd->sta.rxBeaconCount++;
2032 else if ( wd->wlanMode == ZM_MODE_IBSS )
2034 if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A3_OFFSET, 6) )
2036 int res;
2037 struct zsPartnerNotifyEvent event;
2039 zm_debug_msg0("20070916 Receive opposite Beacon!");
2040 zmw_enter_critical_section(dev);
2041 wd->sta.ibssReceiveBeaconCount++;
2042 zmw_leave_critical_section(dev);
2044 res = zfStaSetOppositeInfoFromRxBuf(dev, buf);
2045 if ( res == 0 )
2047 // New peer station found. Notify the wrapper now
2048 zfInitPartnerNotifyEvent(dev, buf, &event);
2049 if (wd->zfcbIbssPartnerNotify != NULL)
2051 wd->zfcbIbssPartnerNotify(dev, 1, &event);
2054 /* update signal strength and signal quality */
2055 zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2056 AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2058 //else if ( wd->sta.ibssPartnerStatus == ZM_IBSS_PARTNER_LOST )
2059 // Why does this happen in IBSS?? The impact of Vista since
2060 // we need to tell it the BSSID
2064 /* return if not channel scan */
2065 if ( !wd->sta.bChannelScan )
2067 goto zlReturn;
2070 zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanBeaconFrameHeader));
2071 pBeaconHeader = (struct zsWlanBeaconFrameHeader*) pBuf;
2073 zmw_enter_critical_section(dev);
2075 //zm_debug_msg1("bss count = ", wd->sta.bssList.bssCount);
2077 pBssInfo = zfStaFindBssInfo(dev, buf, pBeaconHeader);
2079 if ( pBssInfo == NULL )
2081 /* Allocate a new entry if BSS not in the scan list */
2082 pBssInfo = zfBssInfoAllocate(dev);
2083 if (pBssInfo != NULL)
2085 res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 0);
2086 //zfDumpSSID(pBssInfo->ssid[1], &(pBssInfo->ssid[2]));
2087 if ( res != 0 )
2089 zfBssInfoFree(dev, pBssInfo);
2091 else
2093 zfBssInfoInsertToList(dev, pBssInfo);
2097 else
2099 res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 1);
2100 if (res == 2)
2102 zfBssInfoRemoveFromList(dev, pBssInfo);
2103 zfBssInfoFree(dev, pBssInfo);
2105 else if ( wd->wlanMode == ZM_MODE_IBSS )
2107 int idx;
2109 // It would reset the alive counter if the peer station is found!
2110 zfStaFindFreeOpposite(dev, (u16_t *)pBssInfo->macaddr, &idx);
2114 zmw_leave_critical_section(dev);
2116 zlReturn:
2118 return;
2122 void zfAuthFreqCompleteCb(zdev_t* dev)
2124 zmw_get_wlan_dev(dev);
2125 zmw_declare_for_critical_section();
2127 zmw_enter_critical_section(dev);
2129 if (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_COMPLETED)
2131 zm_debug_msg0("ZM_STA_CONN_STATE_ASSOCIATE");
2132 wd->sta.connectTimer = wd->tick;
2133 wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2136 zmw_leave_critical_section(dev);
2137 return;
2140 /************************************************************************/
2141 /* */
2142 /* FUNCTION DESCRIPTION zfProcessAuth */
2143 /* Process authenticate management frame. */
2144 /* */
2145 /* INPUTS */
2146 /* dev : device pointer */
2147 /* buf : auth frame buffer */
2148 /* */
2149 /* OUTPUTS */
2150 /* none */
2151 /* */
2152 /* AUTHOR */
2153 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
2154 /* */
2155 /************************************************************************/
2156 /* Note : AP allows one authenticating STA at a time, does not */
2157 /* support multiple authentication process. Make sure */
2158 /* authentication state machine will not be blocked due */
2159 /* to incompleted authentication handshake. */
2160 void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2162 struct zsWlanAuthFrameHeader* pAuthFrame;
2163 u8_t pBuf[sizeof(struct zsWlanAuthFrameHeader)];
2164 u32_t p1, p2;
2166 zmw_get_wlan_dev(dev);
2167 zmw_declare_for_critical_section();
2169 if ( !zfStaIsConnecting(dev) )
2171 return;
2174 pAuthFrame = (struct zsWlanAuthFrameHeader*) pBuf;
2175 zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAuthFrameHeader));
2177 if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN )
2179 if ( (zmw_le16_to_cpu(pAuthFrame->seq) == 2)&&
2180 (zmw_le16_to_cpu(pAuthFrame->algo) == 0)&&
2181 (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2184 zmw_enter_critical_section(dev);
2185 wd->sta.connectTimer = wd->tick;
2186 zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_COMPLETED");
2187 wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_COMPLETED;
2188 zmw_leave_critical_section(dev);
2190 //Set channel according to AP's configuration
2191 //Move to here because of Cisco 11n AP feature
2192 zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2193 wd->ExtOffset, zfAuthFreqCompleteCb);
2195 /* send association frame */
2196 if ( wd->sta.connectByReasso )
2198 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCREQ,
2199 wd->sta.bssid, 0, 0, 0);
2201 else
2203 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2204 wd->sta.bssid, 0, 0, 0);
2209 else
2211 zm_debug_msg1("authentication failed, status = ",
2212 pAuthFrame->status);
2214 if (wd->sta.authMode == ZM_AUTH_MODE_AUTO)
2216 wd->sta.bIsSharedKey = 1;
2217 zfStaStartConnect(dev, wd->sta.bIsSharedKey);
2219 else
2221 zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2222 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2226 else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1 )
2228 if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1) &&
2229 (zmw_le16_to_cpu(pAuthFrame->seq) == 2) &&
2230 (zmw_le16_to_cpu(pAuthFrame->status) == 0))
2231 //&& (pAuthFrame->challengeText[1] <= 255) )
2233 zfMemoryCopy(wd->sta.challengeText, pAuthFrame->challengeText,
2234 pAuthFrame->challengeText[1]+2);
2236 /* send the 3rd authentication frame */
2237 p1 = 0x30001;
2238 p2 = 0;
2239 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH,
2240 wd->sta.bssid, p1, p2, 0);
2242 zmw_enter_critical_section(dev);
2243 wd->sta.connectTimer = wd->tick;
2245 zm_debug_msg0("ZM_STA_SUB_STATE_AUTH_SHARE_2");
2246 wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_2;
2247 zmw_leave_critical_section(dev);
2249 else
2251 zm_debug_msg1("authentication failed, status = ",
2252 pAuthFrame->status);
2254 zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2255 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2258 else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2 )
2260 if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1)&&
2261 (zmw_le16_to_cpu(pAuthFrame->seq) == 4)&&
2262 (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2264 //Set channel according to AP's configuration
2265 //Move to here because of Cisco 11n AP feature
2266 zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2267 wd->ExtOffset, NULL);
2269 /* send association frame */
2270 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2271 wd->sta.bssid, 0, 0, 0);
2273 zmw_enter_critical_section(dev);
2274 wd->sta.connectTimer = wd->tick;
2276 zm_debug_msg0("ZM_STA_SUB_STATE_ASSOCIATE");
2277 wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2278 zmw_leave_critical_section(dev);
2280 else
2282 zm_debug_msg1("authentication failed, status = ",
2283 pAuthFrame->status);
2285 zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2286 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2289 else
2291 zm_debug_msg0("unknown case");
2295 void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2298 return;
2301 void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
2303 struct zsWlanAssoFrameHeader* pAssoFrame;
2304 u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)];
2305 u16_t offset;
2306 u32_t i;
2307 u32_t oneTxStreamCap;
2309 zmw_get_wlan_dev(dev);
2311 if ( !zfStaIsConnecting(dev) )
2313 return;
2316 pAssoFrame = (struct zsWlanAssoFrameHeader*) pBuf;
2317 zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAssoFrameHeader));
2319 if ( wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE )
2321 if ( pAssoFrame->status == 0 )
2323 zm_debug_msg0("ZM_STA_STATE_CONNECTED");
2325 if (wd->sta.EnableHT == 1)
2327 wd->sta.wmeConnected = 1;
2329 if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled
2331 /* Asoc rsp may contain WME parameter element */
2332 offset = zfFindWifiElement(dev, buf, 2, 1);
2333 if (offset != 0xffff)
2335 zm_debug_msg0("WME enable");
2336 wd->sta.wmeConnected = 1;
2337 if ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0)
2339 if ((zmw_rx_buf_readb(dev, buf, offset+8) & 0x80) != 0)
2341 zm_debug_msg0("UAPSD enable");
2342 wd->sta.qosInfo = wd->sta.wmeQosInfo;
2346 zfStaUpdateWmeParameter(dev, buf);
2351 //Store asoc response frame body, for VISTA only
2352 wd->sta.asocRspFrameBodySize = zfwBufGetSize(dev, buf)-24;
2353 if (wd->sta.asocRspFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
2355 wd->sta.asocRspFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
2357 for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2359 wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2362 zfStaStoreAsocRspIe(dev, buf);
2363 if (wd->sta.EnableHT &&
2364 ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) != 0) &&
2365 (wd->ExtOffset != 0))
2367 wd->sta.htCtrlBandwidth = 1;
2369 else
2371 wd->sta.htCtrlBandwidth = 0;
2374 //Set channel according to AP's configuration
2375 //zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2376 // wd->ExtOffset, NULL);
2378 if (wd->sta.EnableHT == 1)
2380 wd->addbaComplete = 0;
2382 if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 &&
2383 (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0)
2385 wd->addbaCount = 1;
2386 zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0);
2387 zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100);
2391 /* set RIFS support */
2392 if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode)
2394 wd->sta.HT2040 = 1;
2395 // zfHpSetRifs(dev, wd->sta.EnableHT, 1, (wd->sta.currentFrequency < 3000)? 1:0);
2398 wd->sta.aid = pAssoFrame->aid & 0x3fff;
2399 wd->sta.oppositeCount = 0; /* reset opposite count */
2400 zfStaSetOppositeInfoFromRxBuf(dev, buf);
2402 wd->sta.rxBeaconCount = 16;
2404 zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
2405 wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
2406 if (wd->zfcbConnectNotify != NULL)
2408 if (wd->sta.EnableHT != 0) /* 11n */
2410 oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
2411 if (wd->sta.htCtrlBandwidth == 1) /* HT40*/
2413 if(oneTxStreamCap) /* one Tx stream */
2415 if (wd->sta.SG40)
2417 wd->CurrentTxRateKbps = 150000;
2418 wd->CurrentRxRateKbps = 300000;
2420 else
2422 wd->CurrentTxRateKbps = 135000;
2423 wd->CurrentRxRateKbps = 270000;
2426 else /* Two Tx streams */
2428 if (wd->sta.SG40)
2430 wd->CurrentTxRateKbps = 300000;
2431 wd->CurrentRxRateKbps = 300000;
2433 else
2435 wd->CurrentTxRateKbps = 270000;
2436 wd->CurrentRxRateKbps = 270000;
2440 else /* HT20 */
2442 if(oneTxStreamCap) /* one Tx stream */
2444 wd->CurrentTxRateKbps = 650000;
2445 wd->CurrentRxRateKbps = 130000;
2447 else /* Two Tx streams */
2449 wd->CurrentTxRateKbps = 130000;
2450 wd->CurrentRxRateKbps = 130000;
2454 else /* 11abg */
2456 if (wd->sta.connection_11b != 0)
2458 wd->CurrentTxRateKbps = 11000;
2459 wd->CurrentRxRateKbps = 11000;
2461 else
2463 wd->CurrentTxRateKbps = 54000;
2464 wd->CurrentRxRateKbps = 54000;
2469 wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
2471 wd->sta.connectByReasso = TRUE;
2472 wd->sta.failCntOfReasso = 0;
2474 zfPowerSavingMgrConnectNotify(dev);
2476 /* Disable here because fixed rate is only for test, TBD. */
2477 //if (wd->sta.EnableHT)
2479 // wd->txMCS = 7; //Rate = 65Mbps
2480 // wd->txMT = 2; // Ht rate
2481 // wd->enableAggregation = 2; // Enable Aggregation
2484 else
2486 zm_debug_msg1("association failed, status = ",
2487 pAssoFrame->status);
2489 zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2490 wd->sta.connectByReasso = FALSE;
2491 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2497 void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf)
2499 u16_t offset;
2500 u32_t i;
2501 u16_t length;
2502 u8_t *htcap;
2503 u8_t asocBw40 = 0;
2504 u8_t asocExtOffset = 0;
2506 zmw_get_wlan_dev(dev);
2508 for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2510 wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2513 /* HT capabilities: 28 octets */
2514 if ( ((wd->sta.currentFrequency > 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_5_N))
2515 || ((wd->sta.currentFrequency < 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_24_N)) )
2517 /* not 11n AP */
2518 htcap = (u8_t *)&wd->sta.ie.HtCap;
2519 for (i=0; i<28; i++)
2521 htcap[i] = 0;
2523 wd->BandWidth40 = 0;
2524 wd->ExtOffset = 0;
2525 return;
2528 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
2529 if (offset != 0xffff)
2531 /* atheros pre n */
2532 zm_debug_msg0("atheros pre n");
2533 htcap = (u8_t *)&wd->sta.ie.HtCap;
2534 htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2535 htcap[1] = 26;
2536 for (i=1; i<=26; i++)
2538 htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2539 zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i+1]);
2542 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
2544 /* pre n 2.0 standard */
2545 zm_debug_msg0("pre n 2.0 standard");
2546 htcap = (u8_t *)&wd->sta.ie.HtCap;
2547 for (i=0; i<28; i++)
2549 htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2550 zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i]);
2553 else
2555 /* not 11n AP */
2556 htcap = (u8_t *)&wd->sta.ie.HtCap;
2557 for (i=0; i<28; i++)
2559 htcap[i] = 0;
2561 wd->BandWidth40 = 0;
2562 wd->ExtOffset = 0;
2563 return;
2566 asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1);
2568 /* HT information */
2569 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
2570 if (offset != 0xffff)
2572 /* atheros pre n */
2573 zm_debug_msg0("atheros pre n HTINFO");
2574 length = 22;
2575 htcap = (u8_t *)&wd->sta.ie.HtInfo;
2576 htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2577 htcap[1] = 22;
2578 for (i=1; i<=22; i++)
2580 htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2581 zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i+1]);
2584 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
2586 /* pre n 2.0 standard */
2587 zm_debug_msg0("pre n 2.0 standard HTINFO");
2588 length = zmw_rx_buf_readb(dev, buf, offset + 1);
2589 htcap = (u8_t *)&wd->sta.ie.HtInfo;
2590 for (i=0; i<24; i++)
2592 htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2593 zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i]);
2596 else
2598 zm_debug_msg0("no HTINFO");
2599 htcap = (u8_t *)&wd->sta.ie.HtInfo;
2600 for (i=0; i<24; i++)
2602 htcap[i] = 0;
2605 asocExtOffset = wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetBelow;
2607 if ((wd->sta.EnableHT == 1) && (asocBw40 == 1) && ((asocExtOffset == 1) || (asocExtOffset == 3)))
2609 wd->BandWidth40 = asocBw40;
2610 wd->ExtOffset = asocExtOffset;
2612 else
2614 wd->BandWidth40 = 0;
2615 wd->ExtOffset = 0;
2618 return;
2621 void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf)
2623 u16_t apMacAddr[3];
2625 zmw_get_wlan_dev(dev);
2626 zmw_declare_for_critical_section();
2628 /* STA : if SA=connected AP then disconnect with AP */
2629 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2631 apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2632 apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2633 apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2634 if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2636 if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2638 if ( zfStaIsConnected(dev) )
2640 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DEAUTH, wd->sta.bssid, 2);
2642 else if (zfStaIsConnecting(dev))
2644 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2646 else
2652 else if ( wd->wlanMode == ZM_MODE_IBSS )
2654 u16_t peerMacAddr[3];
2655 u8_t peerIdx;
2656 s8_t res;
2658 if ( zfStaIsConnected(dev) )
2660 peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
2661 peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
2662 peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
2664 zmw_enter_critical_section(dev);
2665 res = zfStaFindOppositeByMACAddr(dev, peerMacAddr, &peerIdx);
2666 if ( res == 0 )
2668 wd->sta.oppositeInfo[peerIdx].aliveCounter = 0;
2670 zmw_leave_critical_section(dev);
2675 void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf)
2677 u16_t apMacAddr[3];
2679 zmw_get_wlan_dev(dev);
2681 /* STA : if SA=connected AP then disconnect with AP */
2682 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2684 apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2685 apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2686 apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2688 if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2690 if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2692 if ( zfStaIsConnected(dev) )
2694 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DISASOC, wd->sta.bssid, 2);
2696 else
2698 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2707 /************************************************************************/
2708 /* */
2709 /* FUNCTION DESCRIPTION zfProcessProbeReq */
2710 /* Process probe request management frame. */
2711 /* */
2712 /* INPUTS */
2713 /* dev : device pointer */
2714 /* buf : auth frame buffer */
2715 /* */
2716 /* OUTPUTS */
2717 /* none */
2718 /* */
2719 /* AUTHOR */
2720 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
2721 /* */
2722 /************************************************************************/
2723 void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src)
2725 u16_t offset;
2726 u8_t len;
2727 u16_t i, j;
2728 u16_t sendFlag;
2730 zmw_get_wlan_dev(dev);
2732 /* check mode : AP/IBSS */
2733 if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS))
2735 zm_msg0_mm(ZM_LV_3, "Ignore probe req");
2736 return;
2739 /* check SSID */
2740 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
2741 if (offset == 0xffff)
2743 zm_msg0_mm(ZM_LV_3, "probe req SSID not found");
2744 return;
2747 len = zmw_rx_buf_readb(dev, buf, offset+1);
2749 for (i=0; i<ZM_MAX_AP_SUPPORT; i++)
2751 if ((wd->ap.apBitmap & (i<<i)) != 0)
2753 sendFlag = 0;
2754 /* boardcast SSID */
2755 if ((len == 0) && (wd->ap.hideSsid[i] == 0))
2757 sendFlag = 1;
2759 /* Not broadcast SSID */
2760 else if (wd->ap.ssidLen[i] == len)
2762 for (j=0; j<len; j++)
2764 if (zmw_rx_buf_readb(dev, buf, offset+1+j)
2765 != wd->ap.ssid[i][j])
2767 break;
2770 if (j == len)
2772 sendFlag = 1;
2775 if (sendFlag == 1)
2777 /* Send probe response */
2778 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, i, 0, 0);
2784 void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
2786 /* return if not channel scan */
2787 // Probe response is sent with unicast. Is this required?
2788 // IBSS would send probe request and the code below would prevent
2789 // the probe response from handling.
2791 zfProcessProbeRsp(dev, buf, AddInfo);
2794 void zfIBSSSetupBssDesc(zdev_t *dev)
2796 #ifdef ZM_ENABLE_IBSS_WPA2PSK
2797 u8_t i;
2798 #endif
2799 struct zsBssInfo *pBssInfo;
2800 u16_t offset = 0;
2802 zmw_get_wlan_dev(dev);
2804 pBssInfo = &wd->sta.ibssBssDesc;
2805 zfZeroMemory((u8_t *)pBssInfo, sizeof(struct zsBssInfo));
2807 pBssInfo->signalStrength = 100;
2809 zfMemoryCopy((u8_t *)pBssInfo->macaddr, (u8_t *)wd->macAddr,6);
2810 zfMemoryCopy((u8_t *)pBssInfo->bssid, (u8_t *)wd->sta.bssid, 6);
2812 pBssInfo->beaconInterval[0] = (u8_t)(wd->beaconInterval) ;
2813 pBssInfo->beaconInterval[1] = (u8_t)((wd->beaconInterval) >> 8) ;
2815 pBssInfo->capability[0] = wd->sta.capability[0];
2816 pBssInfo->capability[1] = wd->sta.capability[1];
2818 pBssInfo->ssid[0] = ZM_WLAN_EID_SSID;
2819 pBssInfo->ssid[1] = wd->sta.ssidLen;
2820 zfMemoryCopy((u8_t *)&pBssInfo->ssid[2], (u8_t *)wd->sta.ssid, wd->sta.ssidLen);
2821 zfMemoryCopy((u8_t *)&pBssInfo->frameBody[offset], (u8_t *)pBssInfo->ssid,
2822 wd->sta.ssidLen + 2);
2823 offset += wd->sta.ssidLen + 2;
2825 /* support rate */
2827 /* DS parameter set */
2828 pBssInfo->channel = zfChFreqToNum(wd->frequency, NULL);
2829 pBssInfo->frequency = wd->frequency;
2830 pBssInfo->atimWindow = wd->sta.atimWindow;
2832 #ifdef ZM_ENABLE_IBSS_WPA2PSK
2833 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
2835 u8_t rsn[64]=
2837 /* Element ID */
2838 0x30,
2839 /* Length */
2840 0x14,
2841 /* Version */
2842 0x01, 0x00,
2843 /* Group Cipher Suite, default=TKIP */
2844 0x00, 0x0f, 0xac, 0x04,
2845 /* Pairwise Cipher Suite Count */
2846 0x01, 0x00,
2847 /* Pairwise Cipher Suite, default=TKIP */
2848 0x00, 0x0f, 0xac, 0x02,
2849 /* Authentication and Key Management Suite Count */
2850 0x01, 0x00,
2851 /* Authentication type, default=PSK */
2852 0x00, 0x0f, 0xac, 0x02,
2853 /* RSN capability */
2854 0x00, 0x00
2857 /* Overwrite Group Cipher Suite by AP's setting */
2858 zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
2860 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
2862 /* Overwrite Pairwise Cipher Suite by AES */
2863 zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
2866 // RSN element id
2867 pBssInfo->frameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
2869 // RSN length
2870 pBssInfo->frameBody[offset++] = rsn[1] ;
2872 // RSN information
2873 for(i=0; i<rsn[1]; i++)
2875 pBssInfo->frameBody[offset++] = rsn[i+2] ;
2878 zfMemoryCopy(pBssInfo->rsnIe, rsn, rsn[1]+2);
2880 #endif
2883 void zfIbssConnectNetwork(zdev_t* dev)
2885 struct zsBssInfo* pBssInfo;
2886 struct zsBssInfo tmpBssInfo;
2887 u8_t macAddr[6], bssid[6], bssNotFound = TRUE;
2888 u16_t i, j=100;
2889 u16_t k;
2890 struct zsPartnerNotifyEvent event;
2891 u32_t channelFlags;
2892 u16_t oppositeWepStatus;
2894 zmw_get_wlan_dev(dev);
2896 zmw_declare_for_critical_section();
2898 /* change state to CONNECTING and stop the channel scanning */
2899 zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
2900 zfPowerSavingMgrWakeup(dev);
2902 /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
2903 zfUpdateDefaultQosParameter(dev, 0);
2905 wd->sta.bProtectionMode = FALSE;
2906 zfHpSetSlotTime(dev, 1);
2908 /* ESS bit off */
2909 wd->sta.capability[0] &= ~ZM_BIT_0;
2910 /* IBSS bit on */
2911 wd->sta.capability[0] |= ZM_BIT_1;
2912 /* not not use short slot time */
2913 wd->sta.capability[1] &= ~ZM_BIT_2;
2915 wd->sta.wmeConnected = 0;
2916 wd->sta.psMgr.tempWakeUp = 0;
2917 wd->sta.qosInfo = 0;
2918 wd->sta.EnableHT = 0;
2919 wd->BandWidth40 = 0;
2920 wd->ExtOffset = 0;
2922 if ( wd->sta.bssList.bssCount )
2924 //Reorder BssList by RSSI--CWYang(+)
2925 zfBssInfoReorderList(dev);
2927 zmw_enter_critical_section(dev);
2929 pBssInfo = wd->sta.bssList.head;
2931 for(i=0; i<wd->sta.bssList.bssCount; i++)
2933 // 20070806 #1 Privacy bit
2934 if ( pBssInfo->capability[0] & ZM_BIT_4 )
2935 { // Privacy Ibss network
2936 // zm_debug_msg0("Privacy bit on");
2937 oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
2939 if ( pBssInfo->rsnIe[1] != 0 )
2941 if ( (pBssInfo->rsnIe[7] == 0x01) || (pBssInfo->rsnIe[7] == 0x05) )
2942 { // WEP-40 & WEP-104
2943 // zm_debug_msg0("WEP40 or WEP104");
2944 oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
2946 else if ( pBssInfo->rsnIe[7] == 0x02 )
2947 { // TKIP
2948 // zm_debug_msg0("TKIP");
2949 oppositeWepStatus = ZM_ENCRYPTION_TKIP;
2951 else if ( pBssInfo->rsnIe[7] == 0x04 )
2952 { // AES
2953 // zm_debug_msg0("CCMP-AES");
2954 oppositeWepStatus = ZM_ENCRYPTION_AES;
2958 else
2960 // zm_debug_msg0("Privacy bit off");
2961 oppositeWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
2964 if ( (zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
2965 wd->sta.ssidLen))&&
2966 (wd->sta.ssidLen == pBssInfo->ssid[1])&&
2967 (oppositeWepStatus == wd->sta.wepStatus) )
2969 /* Check support mode */
2970 if (pBssInfo->frequency > 3000) {
2971 if ( (pBssInfo->EnableHT == 1)
2972 || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
2974 channelFlags = CHANNEL_A_HT;
2975 if (pBssInfo->enableHT40 == 1) {
2976 channelFlags |= CHANNEL_HT40;
2978 } else {
2979 channelFlags = CHANNEL_A;
2981 } else {
2982 if ( (pBssInfo->EnableHT == 1)
2983 || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
2985 channelFlags = CHANNEL_G_HT;
2986 if(pBssInfo->enableHT40 == 1) {
2987 channelFlags |= CHANNEL_HT40;
2989 } else {
2990 if (pBssInfo->extSupportedRates[1] == 0) {
2991 channelFlags = CHANNEL_B;
2992 } else {
2993 channelFlags = CHANNEL_G;
2998 if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
2999 || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3000 || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3001 || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3003 pBssInfo = pBssInfo->next;
3004 continue;
3007 /* Bypass DFS channel */
3008 if (zfHpIsDfsChannelNCS(dev, pBssInfo->frequency))
3010 zm_debug_msg0("Bypass DFS channel");
3011 continue;
3014 /* check IBSS bit */
3015 if ( pBssInfo->capability[0] & ZM_BIT_1 )
3017 /* may check timestamp here */
3018 j = i;
3019 break;
3023 pBssInfo = pBssInfo->next;
3026 if ((j < wd->sta.bssList.bssCount) && (pBssInfo != NULL))
3028 zfwMemoryCopy((u8_t*)&tmpBssInfo, (u8_t*)(pBssInfo), sizeof(struct zsBssInfo));
3029 pBssInfo = &tmpBssInfo;
3031 else
3033 pBssInfo = NULL;
3036 zmw_leave_critical_section(dev);
3038 //if ( j < wd->sta.bssList.bssCount )
3039 if (pBssInfo != NULL)
3041 int res;
3043 zm_debug_msg0("IBSS found");
3045 /* Found IBSS, reset bssNotFoundCount */
3046 zmw_enter_critical_section(dev);
3047 wd->sta.bssNotFoundCount = 0;
3048 zmw_leave_critical_section(dev);
3050 bssNotFound = FALSE;
3051 wd->sta.atimWindow = pBssInfo->atimWindow;
3052 wd->frequency = pBssInfo->frequency;
3053 //wd->sta.flagFreqChanging = 1;
3054 zfCoreSetFrequency(dev, wd->frequency);
3055 zfUpdateBssid(dev, pBssInfo->bssid);
3056 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3057 zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3058 zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3059 wd->beaconInterval = pBssInfo->beaconInterval[0] +
3060 (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3062 if (wd->beaconInterval == 0)
3064 wd->beaconInterval = 100;
3067 /* rsn information element */
3068 if ( pBssInfo->rsnIe[1] != 0 )
3070 zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3071 pBssInfo->rsnIe[1]+2);
3073 #ifdef ZM_ENABLE_IBSS_WPA2PSK
3074 /* If not use RSNA , run traditional */
3075 zmw_enter_critical_section(dev);
3076 wd->sta.ibssWpa2Psk = 1;
3077 zmw_leave_critical_section(dev);
3078 #endif
3080 else
3082 wd->sta.rsnIe[1] = 0;
3085 /* privacy bit */
3086 if ( pBssInfo->capability[0] & ZM_BIT_4 )
3088 wd->sta.capability[0] |= ZM_BIT_4;
3090 else
3092 wd->sta.capability[0] &= ~ZM_BIT_4;
3095 /* preamble type */
3096 wd->preambleTypeInUsed = wd->preambleType;
3097 if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3099 if (pBssInfo->capability[0] & ZM_BIT_5)
3101 wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3103 else
3105 wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3109 if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3111 wd->sta.capability[0] &= ~ZM_BIT_5;
3113 else
3115 wd->sta.capability[0] |= ZM_BIT_5;
3118 wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
3120 if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3122 wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3125 for (k=0; k<8; k++)
3127 wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
3129 wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
3130 wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
3131 wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
3132 wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
3133 //for (k=12; k<wd->sta.beaconFrameBodySize; k++)
3134 for (k=0; k<pBssInfo->frameBodysize; k++)
3136 wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
3139 zmw_enter_critical_section(dev);
3140 res = zfStaSetOppositeInfoFromBSSInfo(dev, pBssInfo);
3141 if ( res == 0 )
3143 zfMemoryCopy(event.bssid, (u8_t *)(pBssInfo->bssid), 6);
3144 zfMemoryCopy(event.peerMacAddr, (u8_t *)(pBssInfo->macaddr), 6);
3146 zmw_leave_critical_section(dev);
3148 //zfwIbssPartnerNotify(dev, 1, &event);
3149 goto connect_done;
3153 /* IBSS not found */
3154 if ( bssNotFound )
3156 #ifdef ZM_ENABLE_IBSS_WPA2PSK
3157 u16_t offset ;
3158 #endif
3159 if ( wd->sta.ibssJoinOnly )
3161 zm_debug_msg0("IBSS join only...retry...");
3162 goto retry_ibss;
3165 if(wd->sta.bssNotFoundCount<2)
3167 zmw_enter_critical_section(dev);
3168 zm_debug_msg1("IBSS not found, do sitesurvey!! bssNotFoundCount=", wd->sta.bssNotFoundCount);
3169 wd->sta.bssNotFoundCount++;
3170 zmw_leave_critical_section(dev);
3171 goto retry_ibss;
3173 else
3175 zmw_enter_critical_section(dev);
3176 /* Fail IBSS found, TODO create IBSS */
3177 wd->sta.bssNotFoundCount = 0;
3178 zmw_leave_critical_section(dev);
3182 if (zfHpIsDfsChannel(dev, wd->frequency))
3184 wd->frequency = zfHpFindFirstNonDfsChannel(dev, wd->frequency > 3000);
3187 if( wd->ws.autoSetFrequency == 0 )
3188 { /* Auto set frequency */
3189 zm_debug_msg1("Create Ad Hoc Network Band ", wd->ws.adhocMode);
3190 wd->frequency = zfFindCleanFrequency(dev, wd->ws.adhocMode);
3191 wd->ws.autoSetFrequency = 0xff;
3193 zm_debug_msg1("IBSS not found, created one in channel ", wd->frequency);
3195 wd->sta.ibssBssIsCreator = 1;
3197 //wd->sta.flagFreqChanging = 1;
3198 zfCoreSetFrequency(dev, wd->frequency);
3199 if (wd->sta.bDesiredBssid == TRUE)
3201 for (k=0; k<6; k++)
3203 bssid[k] = wd->sta.desiredBssid[k];
3206 else
3208 macAddr[0] = (wd->macAddr[0] & 0xff);
3209 macAddr[1] = (wd->macAddr[0] >> 8);
3210 macAddr[2] = (wd->macAddr[1] & 0xff);
3211 macAddr[3] = (wd->macAddr[1] >> 8);
3212 macAddr[4] = (wd->macAddr[2] & 0xff);
3213 macAddr[5] = (wd->macAddr[2] >> 8);
3214 zfGenerateRandomBSSID(dev, (u8_t *)wd->macAddr, (u8_t *)bssid);
3217 zfUpdateBssid(dev, bssid);
3218 //wd->sta.atimWindow = 0x0a;
3220 /* rate information */
3221 if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g
3223 if ( wd->wfc.bIbssGMode
3224 && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
3226 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3228 else
3230 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_B);
3232 } else {
3233 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3236 if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
3238 wd->sta.capability[0] &= ~ZM_BIT_4;
3240 else
3242 wd->sta.capability[0] |= ZM_BIT_4;
3245 wd->preambleTypeInUsed = wd->preambleType;
3246 if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3248 wd->sta.capability[0] &= ~ZM_BIT_5;
3250 else
3252 wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3253 wd->sta.capability[0] |= ZM_BIT_5;
3256 zfIBSSSetupBssDesc(dev);
3258 #ifdef ZM_ENABLE_IBSS_WPA2PSK
3260 // 20070411 Add WPA2PSK information to its IBSS network !!!
3261 offset = 0 ;
3263 /* timestamp */
3264 offset += 8 ;
3266 /* beacon interval */
3267 wd->sta.beaconFrameBody[offset++] = (u8_t)(wd->beaconInterval) ;
3268 wd->sta.beaconFrameBody[offset++] = (u8_t)((wd->beaconInterval) >> 8) ;
3270 /* capability information */
3271 wd->sta.beaconFrameBody[offset++] = wd->sta.capability[0] ;
3272 wd->sta.beaconFrameBody[offset++] = wd->sta.capability[1] ;
3274 /* RSN : important information influence the result of creating an IBSS network */
3275 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
3277 u8_t frameType = ZM_WLAN_FRAME_TYPE_AUTH ;
3278 u8_t rsn[64]=
3280 /* Element ID */
3281 0x30,
3282 /* Length */
3283 0x14,
3284 /* Version */
3285 0x01, 0x00,
3286 /* Group Cipher Suite, default=TKIP */
3287 0x00, 0x0f, 0xac, 0x04,
3288 /* Pairwise Cipher Suite Count */
3289 0x01, 0x00,
3290 /* Pairwise Cipher Suite, default=TKIP */
3291 0x00, 0x0f, 0xac, 0x02,
3292 /* Authentication and Key Management Suite Count */
3293 0x01, 0x00,
3294 /* Authentication type, default=PSK */
3295 0x00, 0x0f, 0xac, 0x02,
3296 /* RSN capability */
3297 0x00, 0x00
3300 /* Overwrite Group Cipher Suite by AP's setting */
3301 zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
3303 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3305 /* Overwrite Pairwise Cipher Suite by AES */
3306 zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
3309 // RSN element id
3310 wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
3312 // RSN length
3313 wd->sta.beaconFrameBody[offset++] = rsn[1] ;
3315 // RSN information
3316 for(i=0; i<rsn[1]; i++)
3317 wd->sta.beaconFrameBody[offset++] = rsn[i+2] ;
3319 zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
3321 #ifdef ZM_ENABLE_IBSS_WPA2PSK
3322 /* If not use RSNA , run traditional */
3323 zmw_enter_critical_section(dev);
3324 wd->sta.ibssWpa2Psk = 1;
3325 zmw_leave_critical_section(dev);
3326 #endif
3330 wd->sta.beaconFrameBodySize = offset ;
3332 if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3334 wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3337 // 20070416 Let Create IBSS network could enter the zfwIbssPartnerNotify function
3338 // bssNotFound = FALSE ;
3340 printk("The capability info 1 = %02x\n", wd->sta.capability[0]) ;
3341 printk("The capability info 2 = %02x\n", wd->sta.capability[1]) ;
3342 for(k=0; k<wd->sta.beaconFrameBodySize; k++)
3344 printk("%02x ", wd->sta.beaconFrameBody[k]) ;
3346 #endif
3348 //zmw_enter_critical_section(dev);
3349 //wd->sta.ibssPartnerStatus = ZM_IBSS_PARTNER_LOST;
3350 //zmw_leave_critical_section(dev);
3352 else
3354 wd->sta.ibssBssIsCreator = 0;
3357 connect_done:
3358 zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
3359 zfStaSendBeacon(dev); // Refresh Beacon content for ZD1211B HalPlus
3360 zfHpSetAtimWindow(dev, wd->sta.atimWindow);
3362 // Start the IBSS timer to monitor for new stations
3363 zmw_enter_critical_section(dev);
3364 zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
3365 zmw_leave_critical_section(dev);
3368 if (wd->zfcbConnectNotify != NULL)
3370 wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
3372 zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
3373 wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
3375 #ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
3376 if ( !bssNotFound )
3378 wd->sta.ibssDelayedInd = 1;
3379 zfMemoryCopy((u8_t *)&wd->sta.ibssDelayedIndEvent, (u8_t *)&event, sizeof(struct zsPartnerNotifyEvent));
3381 #else
3382 if ( !bssNotFound )
3384 if (wd->zfcbIbssPartnerNotify != NULL)
3386 wd->zfcbIbssPartnerNotify(dev, 1, &event);
3389 #endif
3391 return;
3393 retry_ibss:
3394 zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3395 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
3396 return;
3399 void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf)
3401 zmw_get_wlan_dev(dev);
3403 zm_debug_msg0("Receiving Atim window notification");
3405 wd->sta.recvAtim = 1;
3408 static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev,
3409 struct zsBssInfo* candidateBss)
3411 struct zsBssInfo* pBssInfo;
3412 struct zsBssInfo* pNowBssInfo=NULL;
3413 u16_t i;
3414 u16_t ret, apWepStatus;
3415 u32_t k;
3416 u32_t channelFlags;
3418 zmw_get_wlan_dev(dev);
3419 zmw_declare_for_critical_section();
3421 zmw_enter_critical_section(dev);
3423 pBssInfo = wd->sta.bssList.head;
3425 for(i=0; i<wd->sta.bssList.bssCount; i++)
3427 if ( pBssInfo->capability[0] & ZM_BIT_4 )
3429 apWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
3431 else
3433 apWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
3436 if ( ((zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
3437 wd->sta.ssidLen))&&
3438 (wd->sta.ssidLen == pBssInfo->ssid[1]))||
3439 ((wd->sta.ssidLen == 0)&&
3440 /* connect to any BSS: AP's ans STA's WEP status must match */
3441 (wd->sta.wepStatus == apWepStatus )&&
3442 (pBssInfo->securityType != ZM_SECURITY_TYPE_WPA) ))
3444 if ( wd->sta.ssidLen == 0 )
3446 zm_debug_msg0("ANY BSS found");
3449 if ( ((wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED && apWepStatus == ZM_ENCRYPTION_WEP_ENABLED) ||
3450 (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED &&
3451 (apWepStatus == ZM_ENCRYPTION_WEP_DISABLED && wd->sta.dropUnencryptedPkts == 1))) &&
3452 (wd->sta.authMode >= ZM_AUTH_MODE_OPEN && wd->sta.authMode <= ZM_AUTH_MODE_AUTO) )
3454 zm_debug_msg0("Privacy policy is inconsistent");
3455 pBssInfo = pBssInfo->next;
3456 continue;
3459 /* for WPA negative test */
3460 if ( !zfCheckAuthentication(dev, pBssInfo) )
3462 pBssInfo = pBssInfo->next;
3463 continue;
3466 /* Check bssid */
3467 if (wd->sta.bDesiredBssid == TRUE)
3469 for (k=0; k<6; k++)
3471 if (wd->sta.desiredBssid[k] != pBssInfo->bssid[k])
3473 zm_msg0_mm(ZM_LV_1, "desired bssid not matched 1");
3474 break;
3478 if (k != 6)
3480 zm_msg0_mm(ZM_LV_1, "desired bssid not matched 2");
3481 pBssInfo = pBssInfo->next;
3482 continue;
3486 /* Check support mode */
3487 if (pBssInfo->frequency > 3000) {
3488 if ( (pBssInfo->EnableHT == 1)
3489 || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3491 channelFlags = CHANNEL_A_HT;
3492 if (pBssInfo->enableHT40 == 1) {
3493 channelFlags |= CHANNEL_HT40;
3495 } else {
3496 channelFlags = CHANNEL_A;
3498 } else {
3499 if ( (pBssInfo->EnableHT == 1)
3500 || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3502 channelFlags = CHANNEL_G_HT;
3503 if(pBssInfo->enableHT40 == 1) {
3504 channelFlags |= CHANNEL_HT40;
3506 } else {
3507 if (pBssInfo->extSupportedRates[1] == 0) {
3508 channelFlags = CHANNEL_B;
3509 } else {
3510 channelFlags = CHANNEL_G;
3515 if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
3516 || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3517 || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3518 || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3520 pBssInfo = pBssInfo->next;
3521 continue;
3524 /* Skip if AP in blocking list */
3525 ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid);
3526 if (ret == TRUE)
3528 zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!");
3529 pNowBssInfo = pBssInfo;
3530 pBssInfo = pBssInfo->next;
3531 continue;
3534 if ( pBssInfo->capability[0] & ZM_BIT_0 ) // check if infra-BSS
3536 pNowBssInfo = pBssInfo;
3537 wd->sta.apWmeCapability = pBssInfo->wmeSupport;
3540 goto done;
3544 pBssInfo = pBssInfo->next;
3547 done:
3548 if (pNowBssInfo != NULL)
3550 zfwMemoryCopy((void*)candidateBss, (void*)pNowBssInfo, sizeof(struct zsBssInfo));
3551 pNowBssInfo = candidateBss;
3554 zmw_leave_critical_section(dev);
3556 return pNowBssInfo;
3560 void zfInfraConnectNetwork(zdev_t* dev)
3562 struct zsBssInfo* pBssInfo;
3563 struct zsBssInfo* pNowBssInfo=NULL;
3564 struct zsBssInfo candidateBss;
3565 //u16_t i, j=100, quality=10000;
3566 //u8_t ret=FALSE, apWepStatus;
3567 u8_t ret=FALSE;
3568 u16_t k;
3569 u8_t density = ZM_MPDU_DENSITY_NONE;
3571 zmw_get_wlan_dev(dev);
3572 zmw_declare_for_critical_section();
3574 /* Reset bssNotFoundCount for Ad-Hoc:IBSS */
3575 /* Need review : IbssConn -> InfraConn -> IbssConn etc, flag/counter reset? */
3576 zmw_enter_critical_section(dev);
3577 wd->sta.bssNotFoundCount = 0;
3578 zmw_leave_critical_section(dev);
3580 /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
3581 zfUpdateDefaultQosParameter(dev, 0);
3583 zfStaRefreshBlockList(dev, 0);
3585 /* change state to CONNECTING and stop the channel scanning */
3586 zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3587 zfPowerSavingMgrWakeup(dev);
3589 wd->sta.wmeConnected = 0;
3590 wd->sta.psMgr.tempWakeUp = 0;
3591 wd->sta.qosInfo = 0;
3592 zfQueueFlush(dev, wd->sta.uapsdQ);
3594 wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
3596 //Reorder BssList by RSSI--CWYang(+)
3597 zfBssInfoReorderList(dev);
3599 pNowBssInfo = zfInfraFindAPToConnect(dev, &candidateBss);
3601 if (wd->sta.SWEncryptEnable != 0)
3603 if (wd->sta.bSafeMode == 0)
3605 zfStaDisableSWEncryption(dev);//Quickly reboot
3608 if ( pNowBssInfo != NULL )
3610 //zm_assert(pNowBssInfo != NULL);
3612 pBssInfo = pNowBssInfo;
3613 wd->sta.ssidLen = pBssInfo->ssid[1];
3614 zfMemoryCopy(wd->sta.ssid, &(pBssInfo->ssid[2]), pBssInfo->ssid[1]);
3615 wd->frequency = pBssInfo->frequency;
3616 //wd->sta.flagFreqChanging = 1;
3618 //zfCoreSetFrequency(dev, wd->frequency);
3619 zfUpdateBssid(dev, pBssInfo->bssid);
3620 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3621 zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3622 zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3624 wd->beaconInterval = pBssInfo->beaconInterval[0] +
3625 (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3626 if (wd->beaconInterval == 0)
3628 wd->beaconInterval = 100;
3631 /* ESS bit on */
3632 wd->sta.capability[0] |= ZM_BIT_0;
3633 /* IBSS bit off */
3634 wd->sta.capability[0] &= ~ZM_BIT_1;
3636 /* 11n AP flag */
3637 wd->sta.EnableHT = pBssInfo->EnableHT;
3638 wd->sta.SG40 = pBssInfo->SG40;
3639 #ifdef ZM_ENABLE_CENC
3640 if ( pBssInfo->securityType == ZM_SECURITY_TYPE_CENC )
3642 wd->sta.wmeEnabled = 0; //Disable WMM in CENC
3643 cencInit(dev);
3644 cencSetCENCMode(dev, NdisCENC_PSK);
3645 wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3646 /* CENC */
3647 if ( pBssInfo->cencIe[1] != 0 )
3649 //wd->sta.wepStatus = ZM_ENCRYPTION_CENC;
3650 //wd->sta.encryMode = ZM_CENC;
3651 zfwCencHandleBeaconProbrespon(dev, (u8_t *)&pBssInfo->cencIe,
3652 (u8_t *)&pBssInfo->ssid, (u8_t *)&pBssInfo->macaddr);
3653 zfMemoryCopy(wd->sta.cencIe, pBssInfo->cencIe,
3654 pBssInfo->cencIe[1]+2);
3656 else
3658 wd->sta.cencIe[1] = 0;
3661 #endif //ZM_ENABLE_CENC
3662 if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
3664 wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3666 if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
3668 wd->sta.encryMode = ZM_TKIP;
3670 /* Turn on software encryption/decryption for TKIP */
3671 if (wd->sta.EnableHT == 1)
3673 zfStaEnableSWEncryption(dev, (ZM_SW_TKIP_ENCRY_EN|ZM_SW_TKIP_DECRY_EN));
3676 /* Do not support TKIP in 11n mode */
3677 //wd->sta.EnableHT = 0;
3678 //pBssInfo->enableHT40 = 0;
3680 else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3682 wd->sta.encryMode = ZM_AES;
3684 /* If AP supports HT mode */
3685 if (wd->sta.EnableHT)
3687 /* Set MPDU density to 8 us*/
3688 density = ZM_MPDU_DENSITY_8US;
3692 if ( pBssInfo->wpaIe[1] != 0 )
3694 zfMemoryCopy(wd->sta.wpaIe, pBssInfo->wpaIe,
3695 pBssInfo->wpaIe[1]+2);
3697 else
3699 wd->sta.wpaIe[1] = 0;
3702 if ( pBssInfo->rsnIe[1] != 0 )
3704 zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3705 pBssInfo->rsnIe[1]+2);
3707 else
3709 wd->sta.rsnIe[1] = 0;
3715 /* check preamble bit */
3716 wd->preambleTypeInUsed = wd->preambleType;
3717 if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3719 if (pBssInfo->capability[0] & ZM_BIT_5)
3721 wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3723 else
3725 wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3729 if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3731 wd->sta.capability[0] &= ~ZM_BIT_5;
3733 else
3735 wd->sta.capability[0] |= ZM_BIT_5;
3738 /* check 802.11n 40MHz Setting */
3739 if ((pBssInfo->enableHT40 == 1) &&
3740 ((pBssInfo->extChOffset == 1) || (pBssInfo->extChOffset == 3)))
3742 wd->BandWidth40 = pBssInfo->enableHT40;
3743 wd->ExtOffset = pBssInfo->extChOffset;
3745 else
3747 wd->BandWidth40 = 0;
3748 wd->ExtOffset = 0;
3751 /* check 802.11H support bit */
3753 /* check Owl Ap */
3754 if ( pBssInfo->athOwlAp & ZM_BIT_0 )
3756 /* In this function, FW retry will be enable, ZM_MAC_REG_RETRY_MAX
3757 will be set to 0.
3759 zfHpDisableHwRetry(dev);
3760 wd->sta.athOwlAp = 1;
3761 /* Set MPDU density to 8 us*/
3762 density = ZM_MPDU_DENSITY_8US;
3764 else
3766 /* In this function, FW retry will be disable, ZM_MAC_REG_RETRY_MAX
3767 will be set to 3.
3769 zfHpEnableHwRetry(dev);
3770 wd->sta.athOwlAp = 0;
3772 wd->reorder = 1;
3774 /* Set MPDU density */
3775 zfHpSetMPDUDensity(dev, density);
3777 /* check short slot time bit */
3778 if ( pBssInfo->capability[1] & ZM_BIT_2 )
3780 wd->sta.capability[1] |= ZM_BIT_2;
3783 if ( pBssInfo->erp & ZM_BIT_1 )
3785 //zm_debug_msg0("protection mode on");
3786 wd->sta.bProtectionMode = TRUE;
3787 zfHpSetSlotTime(dev, 0);
3789 else
3791 //zm_debug_msg0("protection mode off");
3792 wd->sta.bProtectionMode = FALSE;
3793 zfHpSetSlotTime(dev, 1);
3796 if (pBssInfo->marvelAp == 1)
3798 wd->sta.enableDrvBA = 0;
3800 * 8701 : NetGear 3500 (MARVELL)
3801 * Downlink issue : set slottime to 20.
3803 zfHpSetSlotTimeRegister(dev, 0);
3805 else
3807 wd->sta.enableDrvBA = 1;
3810 * This is not good for here do reset slot time.
3811 * I think it should reset when leave MARVELL ap
3812 * or enter disconnect state etc.
3814 zfHpSetSlotTimeRegister(dev, 1);
3817 //Store probe response frame body, for VISTA only
3818 wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
3819 if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3821 wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3823 for (k=0; k<8; k++)
3825 wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
3827 wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
3828 wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
3829 wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
3830 wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
3831 for (k=0; k<(wd->sta.beaconFrameBodySize - 12); k++)
3833 wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
3836 if ( ( pBssInfo->capability[0] & ZM_BIT_4 )&&
3837 (( wd->sta.authMode == ZM_AUTH_MODE_OPEN )||
3838 ( wd->sta.authMode == ZM_AUTH_MODE_SHARED_KEY)||
3839 (wd->sta.authMode == ZM_AUTH_MODE_AUTO)) )
3840 { /* privacy enabled */
3842 if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
3844 zm_debug_msg0("Adapter is no WEP, try to connect to WEP AP");
3845 ret = FALSE;
3848 /* Do not support WEP in 11n mode */
3849 if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED )
3851 /* Turn on software encryption/decryption for WEP */
3852 if (wd->sta.EnableHT == 1)
3854 zfStaEnableSWEncryption(dev, (ZM_SW_WEP_ENCRY_EN|ZM_SW_WEP_DECRY_EN));
3857 //wd->sta.EnableHT = 0;
3858 //wd->BandWidth40 = 0;
3859 //wd->ExtOffset = 0;
3862 wd->sta.capability[0] |= ZM_BIT_4;
3864 if ( wd->sta.authMode == ZM_AUTH_MODE_AUTO )
3865 { /* Try to use open and shared-key authehtication alternatively */
3866 if ( (wd->sta.connectTimeoutCount % 2) == 0 )
3867 wd->sta.bIsSharedKey = 0;
3868 else
3869 wd->sta.bIsSharedKey = 1;
3871 else if ( wd->sta.authMode != ZM_AUTH_MODE_SHARED_KEY )
3872 { /* open or auto */
3873 //zfStaStartConnect(dev, 0);
3874 wd->sta.bIsSharedKey = 0;
3876 else if ( wd->sta.authMode != ZM_AUTH_MODE_OPEN )
3877 { /* shared key */
3878 //zfStaStartConnect(dev, 1) ;
3879 wd->sta.bIsSharedKey = 1;
3882 else
3884 if ( (pBssInfo->securityType == ZM_SECURITY_TYPE_WPA)||
3885 (pBssInfo->capability[0] & ZM_BIT_4) )
3887 wd->sta.capability[0] |= ZM_BIT_4;
3888 /* initialize WPA related parameters */
3890 else
3892 wd->sta.capability[0] &= (~ZM_BIT_4);
3895 /* authentication with open system */
3896 //zfStaStartConnect(dev, 0);
3897 wd->sta.bIsSharedKey = 0;
3900 /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
3902 if ( (pBssInfo->broadcomHTAp == 1)
3903 && (wd->sta.SWEncryptEnable != 0) )
3905 zfHpSetTTSIFSTime(dev, 0xa);
3907 else
3909 zfHpSetTTSIFSTime(dev, 0x8);
3913 else
3915 zm_debug_msg0("Desired SSID not found");
3916 goto zlConnectFailed;
3920 zfCoreSetFrequencyV2(dev, wd->frequency, zfStaStartConnectCb);
3921 return;
3923 zlConnectFailed:
3924 zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
3925 return;
3928 u8_t zfCheckWPAAuth(zdev_t* dev, struct zsBssInfo* pBssInfo)
3930 u8_t ret=TRUE;
3931 u8_t pmkCount;
3932 u8_t i;
3933 u16_t encAlgoType = 0;
3935 zmw_get_wlan_dev(dev);
3937 if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
3939 encAlgoType = ZM_TKIP;
3941 else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3943 encAlgoType = ZM_AES;
3946 switch(wd->sta.authMode)
3948 case ZM_AUTH_MODE_WPA:
3949 case ZM_AUTH_MODE_WPAPSK:
3950 if ( pBssInfo->wpaIe[1] == 0 )
3952 ret = FALSE;
3953 break;
3956 pmkCount = pBssInfo->wpaIe[12];
3957 for(i=0; i < pmkCount; i++)
3959 if ( pBssInfo->wpaIe[17 + 4*i] == encAlgoType )
3961 ret = TRUE;
3962 goto done;
3966 ret = FALSE;
3967 break;
3969 case ZM_AUTH_MODE_WPA2:
3970 case ZM_AUTH_MODE_WPA2PSK:
3971 if ( pBssInfo->rsnIe[1] == 0 )
3973 ret = FALSE;
3974 break;
3977 pmkCount = pBssInfo->rsnIe[8];
3978 for(i=0; i < pmkCount; i++)
3980 if ( pBssInfo->rsnIe[13 + 4*i] == encAlgoType )
3982 ret = TRUE;
3983 goto done;
3987 ret = FALSE;
3988 break;
3991 done:
3992 return ret;
3995 u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo)
3997 u8_t ret=TRUE;
3998 u16_t encAlgoType;
3999 u16_t UnicastCipherNum;
4001 zmw_get_wlan_dev(dev);
4003 /* Connecting to ANY has been checked */
4004 if ( wd->sta.ssidLen == 0 )
4006 return ret;
4010 switch(wd->sta.authMode)
4011 //switch(wd->ws.authMode)//Quickly reboot
4013 case ZM_AUTH_MODE_WPA_AUTO:
4014 case ZM_AUTH_MODE_WPAPSK_AUTO:
4015 encAlgoType = 0;
4016 if(pBssInfo->rsnIe[1] != 0)
4018 UnicastCipherNum = (pBssInfo->rsnIe[8]) +
4019 (pBssInfo->rsnIe[9] << 8);
4021 /* If there is only one unicast cipher */
4022 if (UnicastCipherNum == 1)
4024 encAlgoType = pBssInfo->rsnIe[13];
4025 //encAlgoType = pBssInfo->rsnIe[7];
4027 else
4029 u16_t ii;
4030 u16_t desiredCipher = 0;
4031 u16_t IEOffSet = 13;
4033 /* Enumerate all the supported unicast cipher */
4034 for (ii = 0; ii < UnicastCipherNum; ii++)
4036 if (pBssInfo->rsnIe[IEOffSet+ii*4] > desiredCipher)
4038 desiredCipher = pBssInfo->rsnIe[IEOffSet+ii*4];
4042 encAlgoType = desiredCipher;
4045 if ( encAlgoType == 0x02 )
4047 wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4049 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4051 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4053 else //ZM_AUTH_MODE_WPAPSK_AUTO
4055 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4058 else if ( encAlgoType == 0x04 )
4060 wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4062 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4064 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4066 else //ZM_AUTH_MODE_WPAPSK_AUTO
4068 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4071 else
4073 ret = FALSE;
4076 else if(pBssInfo->wpaIe[1] != 0)
4078 UnicastCipherNum = (pBssInfo->wpaIe[12]) +
4079 (pBssInfo->wpaIe[13] << 8);
4081 /* If there is only one unicast cipher */
4082 if (UnicastCipherNum == 1)
4084 encAlgoType = pBssInfo->wpaIe[17];
4085 //encAlgoType = pBssInfo->wpaIe[11];
4087 else
4089 u16_t ii;
4090 u16_t desiredCipher = 0;
4091 u16_t IEOffSet = 17;
4093 /* Enumerate all the supported unicast cipher */
4094 for (ii = 0; ii < UnicastCipherNum; ii++)
4096 if (pBssInfo->wpaIe[IEOffSet+ii*4] > desiredCipher)
4098 desiredCipher = pBssInfo->wpaIe[IEOffSet+ii*4];
4102 encAlgoType = desiredCipher;
4105 if ( encAlgoType == 0x02 )
4107 wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4109 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4111 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4113 else //ZM_AUTH_MODE_WPAPSK_AUTO
4115 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4118 else if ( encAlgoType == 0x04 )
4120 wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4122 if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4124 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4126 else //ZM_AUTH_MODE_WPAPSK_AUTO
4128 wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4131 else
4133 ret = FALSE;
4138 else
4140 ret = FALSE;
4143 break;
4145 case ZM_AUTH_MODE_WPA:
4146 case ZM_AUTH_MODE_WPAPSK:
4147 case ZM_AUTH_MODE_WPA_NONE:
4148 case ZM_AUTH_MODE_WPA2:
4149 case ZM_AUTH_MODE_WPA2PSK:
4151 if ( pBssInfo->securityType != ZM_SECURITY_TYPE_WPA )
4153 ret = FALSE;
4156 ret = zfCheckWPAAuth(dev, pBssInfo);
4158 break;
4160 case ZM_AUTH_MODE_OPEN:
4161 case ZM_AUTH_MODE_SHARED_KEY:
4162 case ZM_AUTH_MODE_AUTO:
4164 if ( pBssInfo->wscIe[1] )
4166 // If the AP is a Jumpstart AP, it's ok!! Ray
4167 break;
4169 else if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
4171 ret = FALSE;
4174 break;
4176 default:
4177 break;
4180 return ret;
4183 u8_t zfStaIsConnected(zdev_t* dev)
4185 zmw_get_wlan_dev(dev);
4187 if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTED )
4189 return TRUE;
4192 return FALSE;
4195 u8_t zfStaIsConnecting(zdev_t* dev)
4197 zmw_get_wlan_dev(dev);
4199 if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTING )
4201 return TRUE;
4204 return FALSE;
4207 u8_t zfStaIsDisconnect(zdev_t* dev)
4209 zmw_get_wlan_dev(dev);
4211 if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT )
4213 return TRUE;
4216 return FALSE;
4219 u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState)
4221 u8_t ret = TRUE;
4223 zmw_get_wlan_dev(dev);
4225 zmw_declare_for_critical_section();
4227 //if ( newState == wd->sta.adapterState )
4229 // return FALSE;
4232 switch(newState)
4234 case ZM_STA_STATE_DISCONNECT:
4235 zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT);
4237 zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4239 break;
4240 case ZM_STA_STATE_CONNECTING:
4241 zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4243 break;
4244 case ZM_STA_STATE_CONNECTED:
4245 break;
4246 default:
4247 break;
4250 //if ( ret )
4252 zmw_enter_critical_section(dev);
4253 wd->sta.adapterState = newState;
4254 zmw_leave_critical_section(dev);
4256 zm_debug_msg1("change adapter state = ", newState);
4259 return ret;
4262 /************************************************************************/
4263 /* */
4264 /* FUNCTION DESCRIPTION zfStaMmAddIeSsid */
4265 /* Add information element SSID to buffer. */
4266 /* */
4267 /* INPUTS */
4268 /* dev : device pointer */
4269 /* buf : buffer to add information element */
4270 /* offset : add information element from this offset */
4271 /* */
4272 /* OUTPUTS */
4273 /* buffer offset after adding information element */
4274 /* */
4275 /* AUTHOR */
4276 /* Ji-Huang Lee ZyDAS Technology Corporation 2005.11 */
4277 /* */
4278 /************************************************************************/
4279 u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset)
4281 u16_t i;
4283 zmw_get_wlan_dev(dev);
4285 /* Element ID */
4286 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
4288 /* Element Length */
4289 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssidLen);
4291 /* Information : SSID */
4292 for (i=0; i<wd->sta.ssidLen; i++)
4294 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssid[i]);
4297 return offset;
4300 /************************************************************************/
4301 /* */
4302 /* FUNCTION DESCRIPTION zfStaMmAddIeWpa */
4303 /* Add information element SSID to buffer. */
4304 /* */
4305 /* INPUTS */
4306 /* dev : device pointer */
4307 /* buf : buffer to add information element */
4308 /* offset : add information element from this offset */
4309 /* */
4310 /* OUTPUTS */
4311 /* buffer offset after adding information element */
4312 /* */
4313 /* AUTHOR */
4314 /* Ji-Huang Lee ZyDAS Technology Corporation 2006.01 */
4315 /* */
4316 /************************************************************************/
4317 u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType)
4319 u32_t i;
4320 u8_t ssn[64]={
4321 /* Element ID */
4322 0xdd,
4323 /* Length */
4324 0x18,
4325 /* OUI type */
4326 0x00, 0x50, 0xf2, 0x01,
4327 /* Version */
4328 0x01, 0x00,
4329 /* Group Cipher Suite, default=TKIP */
4330 0x00, 0x50, 0xf2, 0x02,
4331 /* Pairwise Cipher Suite Count */
4332 0x01, 0x00,
4333 /* Pairwise Cipher Suite, default=TKIP */
4334 0x00, 0x50, 0xf2, 0x02,
4335 /* Authentication and Key Management Suite Count */
4336 0x01, 0x00,
4337 /* Authentication type, default=PSK */
4338 0x00, 0x50, 0xf2, 0x02,
4339 /* WPA capability */
4340 0x00, 0x00
4343 u8_t rsn[64]={
4344 /* Element ID */
4345 0x30,
4346 /* Length */
4347 0x14,
4348 /* Version */
4349 0x01, 0x00,
4350 /* Group Cipher Suite, default=TKIP */
4351 0x00, 0x0f, 0xac, 0x02,
4352 /* Pairwise Cipher Suite Count */
4353 0x01, 0x00,
4354 /* Pairwise Cipher Suite, default=TKIP */
4355 0x00, 0x0f, 0xac, 0x02,
4356 /* Authentication and Key Management Suite Count */
4357 0x01, 0x00,
4358 /* Authentication type, default=PSK */
4359 0x00, 0x0f, 0xac, 0x02,
4360 /* RSN capability */
4361 0x00, 0x00
4364 zmw_get_wlan_dev(dev);
4366 if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPAPSK )
4368 /* Overwrite Group Cipher Suite by AP's setting */
4369 zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4371 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4373 /* Overwrite Pairwise Cipher Suite by AES */
4374 zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4377 zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4378 zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4379 offset += (ssn[1]+2);
4381 else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA )
4383 /* Overwrite Group Cipher Suite by AP's setting */
4384 zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4385 /* Overwrite Key Management Suite by WPA-Radius */
4386 zfMemoryCopy(ssn+20, zgWpaRadiusOui, 4);
4388 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4390 /* Overwrite Pairwise Cipher Suite by AES */
4391 zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4394 zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4395 zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4396 offset += (ssn[1]+2);
4398 else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2PSK )
4400 /* Overwrite Group Cipher Suite by AP's setting */
4401 zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4403 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4405 /* Overwrite Pairwise Cipher Suite by AES */
4406 zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4409 if ( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ )
4411 for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4413 if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid,
4414 (u8_t*) wd->sta.bssid, 6) )
4416 /* matched */
4417 break;
4420 if ( i < wd->sta.pmkidInfo.bssidCount )
4422 // Fill PMKID Count in RSN information element
4423 rsn[22] = 0x01;
4424 rsn[23] = 0x00;
4426 // Fill PMKID in RSN information element
4427 zfMemoryCopy(rsn+24,
4428 wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4429 rsn[1] += 18;
4434 zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4435 zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4436 offset += (rsn[1]+2);
4438 else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2 )
4440 /* Overwrite Group Cipher Suite by AP's setting */
4441 zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4442 /* Overwrite Key Management Suite by WPA2-Radius */
4443 zfMemoryCopy(rsn+16, zgWpa2RadiusOui, 4);
4445 if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4447 /* Overwrite Pairwise Cipher Suite by AES */
4448 zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4451 if (( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ || ( frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ )))
4454 if (wd->sta.pmkidInfo.bssidCount != 0) {
4455 // Fill PMKID Count in RSN information element
4456 rsn[22] = 1;
4457 rsn[23] = 0;
4459 * The caller is respnsible to give us the relevant PMKID.
4460 * We'll only accept 1 PMKID for now.
4462 for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4464 if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, (u8_t*) wd->sta.bssid, 6) )
4466 zfMemoryCopy(rsn+24, wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4467 break;
4470 rsn[1] += 18;
4475 zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4476 zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4477 offset += (rsn[1]+2);
4480 return offset;
4483 /************************************************************************/
4484 /* */
4485 /* FUNCTION DESCRIPTION zfStaAddIeIbss */
4486 /* Add information element IBSS parameter to buffer. */
4487 /* */
4488 /* INPUTS */
4489 /* dev : device pointer */
4490 /* buf : buffer to add information element */
4491 /* offset : add information element from this offset */
4492 /* */
4493 /* OUTPUTS */
4494 /* buffer offset after adding information element */
4495 /* */
4496 /* AUTHOR */
4497 /* Ji-Huang Lee ZyDAS Technology Corporation 2005.12 */
4498 /* */
4499 /************************************************************************/
4500 u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset)
4502 zmw_get_wlan_dev(dev);
4504 /* Element ID */
4505 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_IBSS);
4507 /* Element Length */
4508 zmw_tx_buf_writeb(dev, buf, offset++, 2);
4510 /* ATIM window */
4511 zmw_tx_buf_writeh(dev, buf, offset, wd->sta.atimWindow);
4512 offset += 2;
4514 return offset;
4519 /************************************************************************/
4520 /* */
4521 /* FUNCTION DESCRIPTION zfStaAddIeWmeInfo */
4522 /* Add WME Information Element to buffer. */
4523 /* */
4524 /* INPUTS */
4525 /* dev : device pointer */
4526 /* buf : buffer to add information element */
4527 /* offset : add information element from this offset */
4528 /* */
4529 /* OUTPUTS */
4530 /* buffer offset after adding information element */
4531 /* */
4532 /* AUTHOR */
4533 /* Stephen Chen ZyDAS Technology Corporation 2006.6 */
4534 /* */
4535 /************************************************************************/
4536 u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo)
4538 /* Element ID */
4539 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
4541 /* Element Length */
4542 zmw_tx_buf_writeb(dev, buf, offset++, 7);
4544 /* OUI */
4545 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4546 zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
4547 zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
4548 zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
4549 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4550 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
4552 /* QoS Info */
4553 zmw_tx_buf_writeb(dev, buf, offset++, qosInfo);
4555 return offset;
4558 /************************************************************************/
4559 /* */
4560 /* FUNCTION DESCRIPTION zfStaAddIePowerCap */
4561 /* Add information element Power capability to buffer. */
4562 /* */
4563 /* INPUTS */
4564 /* dev : device pointer */
4565 /* buf : buffer to add information element */
4566 /* offset : add information element from this offset */
4567 /* */
4568 /* OUTPUTS */
4569 /* buffer offset after adding information element */
4570 /* */
4571 /* AUTHOR */
4572 /* Sharon 2007.12 */
4573 /* */
4574 /************************************************************************/
4575 u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset)
4577 u8_t MaxTxPower;
4578 u8_t MinTxPower;
4580 /* Element ID */
4581 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
4583 /* Element Length */
4584 zmw_tx_buf_writeb(dev, buf, offset++, 2);
4586 MinTxPower = (u8_t)(zfHpGetMinTxPower(dev)/2);
4587 MaxTxPower = (u8_t)(zfHpGetMaxTxPower(dev)/2);
4589 /* Min Transmit Power Cap */
4590 zmw_tx_buf_writeh(dev, buf, offset++, MinTxPower);
4592 /* Max Transmit Power Cap */
4593 zmw_tx_buf_writeh(dev, buf, offset++, MaxTxPower);
4595 return offset;
4597 /************************************************************************/
4598 /* */
4599 /* FUNCTION DESCRIPTION zfStaAddIeSupportCh */
4600 /* Add information element supported channels to buffer. */
4601 /* */
4602 /* INPUTS */
4603 /* dev : device pointer */
4604 /* buf : buffer to add information element */
4605 /* offset : add information element from this offset */
4606 /* */
4607 /* OUTPUTS */
4608 /* buffer offset after adding information element */
4609 /* */
4610 /* AUTHOR */
4611 /* Sharon 2007.12 */
4612 /* */
4613 /************************************************************************/
4614 u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset)
4617 u8_t i;
4618 u16_t count_24G = 0;
4619 u16_t count_5G = 0;
4620 u16_t channelNum;
4621 u8_t length;
4623 zmw_get_wlan_dev(dev);
4625 zmw_declare_for_critical_section();
4626 zmw_enter_critical_section(dev);
4628 for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
4630 if (wd->regulationTable.allowChannel[i].channel < 3000)
4631 { // 2.4Hz
4632 count_24G++;
4634 else
4635 { // 5GHz
4636 count_5G++;
4640 length = (u8_t)(count_5G * 2 + 2); //5G fill by pair, 2,4G (continuous channels) fill 2 bytes
4642 /* Element ID */
4643 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SUPPORTED_CHANNELS );
4645 /* Element Length */
4646 zmw_tx_buf_writeb(dev, buf, offset++, length);
4648 // 2.4GHz (continuous channels)
4649 /* First channel number */
4650 zmw_tx_buf_writeh(dev, buf, offset++, 1); //Start from channle 1
4651 /* Number of channels */
4652 zmw_tx_buf_writeh(dev, buf, offset++, count_24G);
4654 for (i = 0; i < wd->regulationTable.allowChannelCnt ; i++)
4656 if (wd->regulationTable.allowChannel[i].channel > 4000 && wd->regulationTable.allowChannel[i].channel < 5000)
4657 { // 5GHz 4000 -5000Mhz
4658 channelNum = (wd->regulationTable.allowChannel[i].channel-4000)/5;
4659 /* First channel number */
4660 zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4661 /* Number of channels */
4662 zmw_tx_buf_writeh(dev, buf, offset++, 1);
4664 else if (wd->regulationTable.allowChannel[i].channel >= 5000)
4665 { // 5GHz >5000Mhz
4666 channelNum = (wd->regulationTable.allowChannel[i].channel-5000)/5;
4667 /* First channel number */
4668 zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4669 /* Number of channels */
4670 zmw_tx_buf_writeh(dev, buf, offset++, 1);
4673 zmw_leave_critical_section(dev);
4675 return offset;
4678 void zfStaStartConnectCb(zdev_t* dev)
4680 zmw_get_wlan_dev(dev);
4682 zfStaStartConnect(dev, wd->sta.bIsSharedKey);
4685 void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey)
4687 u32_t p1, p2;
4688 u8_t newConnState;
4690 zmw_get_wlan_dev(dev);
4691 zmw_declare_for_critical_section();
4693 /* p1_low = algorithm number, p1_high = transaction sequence number */
4694 if ( bIsSharedKey )
4696 //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4697 newConnState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4698 zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_SHARE_1");
4699 p1 = ZM_AUTH_ALGO_SHARED_KEY;
4701 else
4703 //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_OPEN;
4704 newConnState = ZM_STA_CONN_STATE_AUTH_OPEN;
4705 zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_OPEN");
4706 if( wd->sta.leapEnabled )
4707 p1 = ZM_AUTH_ALGO_LEAP;
4708 else
4709 p1 = ZM_AUTH_ALGO_OPEN_SYSTEM;
4712 /* status code */
4713 p2 = 0x0;
4715 zmw_enter_critical_section(dev);
4716 wd->sta.connectTimer = wd->tick;
4717 wd->sta.connectState = newConnState;
4718 zmw_leave_critical_section(dev);
4720 /* send the 1st authentication frame */
4721 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, wd->sta.bssid, p1, p2, 0);
4723 return;
4726 void zfSendNullData(zdev_t* dev, u8_t type)
4728 zbuf_t* buf;
4729 //u16_t addrTblSize;
4730 //struct zsAddrTbl addrTbl;
4731 u16_t err;
4732 u16_t hlen;
4733 u16_t header[(34+8+1)/2];
4734 u16_t bcastAddr[3] = {0xffff,0xffff,0xffff};
4735 u16_t *dstAddr;
4737 zmw_get_wlan_dev(dev);
4739 buf = zfwBufAllocate(dev, 1024);
4740 if (buf == NULL)
4742 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4743 return;
4746 zfwBufSetSize(dev, buf, 0);
4748 //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4750 if ( wd->wlanMode == ZM_MODE_IBSS)
4752 dstAddr = bcastAddr;
4754 else
4756 dstAddr = wd->sta.bssid;
4759 if (wd->sta.wmeConnected != 0)
4761 /* If connect to a WMM AP, Send QoS Null data */
4762 hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, dstAddr, header, 0, buf, 0, 0);
4764 else
4766 hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_NULL, dstAddr, header, 0, buf, 0, 0);
4769 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
4771 header[4] |= 0x0100; //TODS bit
4774 if ( type == 1 )
4776 header[4] |= 0x1000;
4779 /* Get buffer DMA address */
4780 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
4781 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
4783 // goto zlError;
4786 /*increase unicast frame counter*/
4787 wd->commTally.txUnicastFrm++;
4789 err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4790 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4791 if (err != ZM_SUCCESS)
4793 goto zlError;
4797 return;
4799 zlError:
4801 zfwBufFree(dev, buf, 0);
4802 return;
4806 void zfSendPSPoll(zdev_t* dev)
4808 zbuf_t* buf;
4809 //u16_t addrTblSize;
4810 //struct zsAddrTbl addrTbl;
4811 u16_t err;
4812 u16_t hlen;
4813 u16_t header[(8+24+1)/2];
4815 zmw_get_wlan_dev(dev);
4817 buf = zfwBufAllocate(dev, 1024);
4818 if (buf == NULL)
4820 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4821 return;
4824 zfwBufSetSize(dev, buf, 0);
4826 //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4828 zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_PSPOLL, wd->sta.bssid, header, 0, buf, 0, 0);
4830 header[0] = 20;
4831 header[4] |= 0x1000;
4832 header[5] = wd->sta.aid | 0xc000; //Both bit-14 and bit-15 are 1
4833 hlen = 16 + 8;
4835 /* Get buffer DMA address */
4836 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
4837 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
4839 // goto zlError;
4842 err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4843 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4844 if (err != ZM_SUCCESS)
4846 goto zlError;
4849 return;
4851 zlError:
4853 zfwBufFree(dev, buf, 0);
4854 return;
4858 void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap)
4860 zbuf_t* buf;
4861 //u16_t addrTblSize;
4862 //struct zsAddrTbl addrTbl;
4863 u16_t err;
4864 u16_t hlen;
4865 u16_t header[(8+24+1)/2];
4866 u16_t i, offset = 0;
4868 zmw_get_wlan_dev(dev);
4870 buf = zfwBufAllocate(dev, 1024);
4871 if (buf == NULL)
4873 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4874 return;
4877 zfwBufSetSize(dev, buf, 12); // 28 = FC 2 + DU 2 + RA 6 + TA 6 + BAC 2 + SEQ 2 + BitMap 8
4878 // 12 = BAC 2 + SEQ 2 + BitMap 8
4880 //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4882 zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_BA, wd->sta.bssid, header, 0, buf, 0, 0);
4884 header[0] = 32; /* MAC header 16 + BA control 2 + BA info 10 + FCS 4*/
4885 header[1] = 0x4; /* No ACK */
4887 /* send by OFDM 6M */
4888 header[2] = (u16_t)(zcRateToPhyCtrl[4] & 0xffff);
4889 header[3] = (u16_t)(zcRateToPhyCtrl[4]>>16) & 0xffff;
4891 hlen = 16 + 8; /* MAC header 16 + control 8*/
4892 offset = 0;
4893 zmw_tx_buf_writeh(dev, buf, offset, 0x05); /*compressed bitmap on*/
4894 offset+=2;
4895 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
4896 offset+=2;
4898 for (i=0; i<8; i++) {
4899 zmw_tx_buf_writeb(dev, buf, offset, bitmap[i]);
4900 offset++;
4903 err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4904 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4905 if (err != ZM_SUCCESS)
4907 goto zlError;
4910 return;
4912 zlError:
4914 zfwBufFree(dev, buf, 0);
4915 return;
4919 void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl,
4920 u16_t* rcProbingFlag)
4922 u8_t addr[6], i;
4923 u8_t rate;
4924 zmw_get_wlan_dev(dev);
4925 zmw_declare_for_critical_section();
4927 ZM_MAC_WORD_TO_BYTE(macAddr, addr);
4928 *phyCtrl = 0;
4930 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
4932 zmw_enter_critical_section(dev);
4933 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[0].rcCell, rcProbingFlag);
4934 //#ifdef ZM_FB50
4935 //rate = 27;
4936 //#endif
4937 *phyCtrl = zcRateToPhyCtrl[rate];
4938 zmw_leave_critical_section(dev);
4940 else
4942 zmw_enter_critical_section(dev);
4943 for(i=0; i<wd->sta.oppositeCount; i++)
4945 if ( addr[0] && 0x01 == 1 ) // The default beacon transmitted rate is CCK and 1 Mbps , but the a mode should use
4946 // OFDM modulation and 6Mbps to transmit beacon.
4948 //rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
4949 rate = wd->sta.oppositeInfo[i].rcCell.operationRateSet[0];
4950 *phyCtrl = zcRateToPhyCtrl[rate];
4951 break;
4953 else if ( zfMemoryIsEqual(addr, wd->sta.oppositeInfo[i].macAddr, 6) )
4955 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
4956 *phyCtrl = zcRateToPhyCtrl[rate];
4957 break;
4960 zmw_leave_critical_section(dev);
4963 return;
4966 struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf)
4968 u8_t keyIndex;
4969 u8_t da0;
4971 zmw_get_wlan_dev(dev);
4973 /* if need not check MIC, return NULL */
4974 if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
4975 (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
4977 return NULL;
4980 da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
4982 if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
4983 keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
4984 else
4985 keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
4986 keyIndex = (keyIndex & 0xc0) >> 6;
4988 return (&wd->sta.rxMicKey[keyIndex]);
4991 struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf)
4993 zmw_get_wlan_dev(dev);
4995 /* if need not check MIC, return NULL */
4996 //if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
4997 // (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
4998 if ( (wd->sta.encryMode != ZM_TKIP) || (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5000 return NULL;
5003 return (&wd->sta.txMicKey);
5006 u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf)
5008 u8_t frameType, frameCtrl;
5009 u8_t da0;
5010 //u16_t sa[3];
5011 u16_t ret;
5012 //u8_t sa0;
5014 zmw_get_wlan_dev(dev);
5016 frameType = zmw_rx_buf_readb(dev, buf, 0);
5017 da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5018 //sa0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5020 if ( (!zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5022 return ZM_ERR_DATA_BEFORE_CONNECTED;
5026 if ( (zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5028 /* check BSSID */
5029 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
5031 /* Big Endian and Little Endian Compatibility */
5032 u16_t mac[3];
5033 mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5034 mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5035 mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5036 if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5037 ZM_WLAN_HEADER_A2_OFFSET, 6) )
5039 /*We will get lots of garbage data, especially in AES mode.*/
5040 /*To avoid sending too many deauthentication frames in STA mode, mark it.*/
5041 return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5044 else if ( wd->wlanMode == ZM_MODE_IBSS )
5046 /* Big Endian and Little Endian Compatibility */
5047 u16_t mac[3];
5048 mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5049 mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5050 mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5051 if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5052 ZM_WLAN_HEADER_A3_OFFSET, 6) )
5054 return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5058 frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
5060 /* check security bit */
5061 if ( wd->sta.dropUnencryptedPkts &&
5062 (wd->sta.wepStatus != ZM_ENCRYPTION_WEP_DISABLED )&&
5063 ( !(frameCtrl & ZM_BIT_6) ) )
5064 { /* security on, but got data without encryption */
5066 ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5067 if ( wd->sta.pStaRxSecurityCheckCb != NULL )
5069 ret = wd->sta.pStaRxSecurityCheckCb(dev, buf);
5071 else
5073 ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5075 if (ret == ZM_ERR_DATA_NOT_ENCRYPTED)
5077 wd->commTally.swRxDropUnencryptedCount++;
5079 return ret;
5083 return ZM_SUCCESS;
5086 void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf)
5088 u8_t da0;
5089 u8_t micNotify = 1;
5091 zmw_get_wlan_dev(dev);
5093 zmw_declare_for_critical_section();
5095 if ( wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK )
5097 return;
5100 zmw_enter_critical_section(dev);
5102 wd->sta.cmMicFailureCount++;
5104 if ( wd->sta.cmMicFailureCount == 1 )
5106 zm_debug_msg0("get the first MIC failure");
5107 //zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT);
5109 /* Timer Resolution on WinXP is 15/16 ms */
5110 /* Decrease Time offset for <XP> Counter Measure */
5111 zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT - ZM_TICK_CM_TIMEOUT_OFFSET);
5113 else if ( wd->sta.cmMicFailureCount == 2 )
5115 zm_debug_msg0("get the second MIC failure");
5116 /* reserve 2 second for OS to send MIC failure report to AP */
5117 wd->sta.cmDisallowSsidLength = wd->sta.ssidLen;
5118 zfMemoryCopy(wd->sta.cmDisallowSsid, wd->sta.ssid, wd->sta.ssidLen);
5119 //wd->sta.cmMicFailureCount = 0;
5120 zfTimerCancel(dev, ZM_EVENT_CM_TIMER);
5121 //zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT);
5123 /* Timer Resolution on WinXP is 15/16 ms */
5124 /* Decrease Time offset for <XP> Counter Measure */
5125 zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT - ZM_TICK_CM_DISCONNECT_OFFSET);
5127 else
5129 micNotify = 0;
5132 zmw_leave_critical_section(dev);
5134 if (micNotify == 1)
5136 da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5137 if ( da0 & 0x01 )
5139 if (wd->zfcbMicFailureNotify != NULL)
5141 wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_GROUP_ERROR);
5144 else
5146 if (wd->zfcbMicFailureNotify != NULL)
5148 wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_PAIRWISE_ERROR);
5155 u8_t zfStaBlockWlanScan(zdev_t* dev)
5157 u8_t ret=FALSE;
5159 zmw_get_wlan_dev(dev);
5161 if ( wd->sta.bChannelScan )
5163 return TRUE;
5166 return ret;
5169 void zfStaResetStatus(zdev_t* dev, u8_t bInit)
5171 u8_t i;
5173 zmw_get_wlan_dev(dev);
5175 zfHpDisableBeacon(dev);
5177 wd->dtim = 1;
5178 wd->sta.capability[0] = 0x01;
5179 wd->sta.capability[1] = 0x00;
5180 /* 802.11h */
5181 if (wd->sta.DFSEnable || wd->sta.TPCEnable)
5182 wd->sta.capability[1] |= ZM_BIT_0;
5184 /* release queued packets */
5185 for(i=0; i<wd->sta.ibssPSDataCount; i++)
5187 zfwBufFree(dev, wd->sta.ibssPSDataQueue[i], 0);
5190 for(i=0; i<wd->sta.staPSDataCount; i++)
5192 zfwBufFree(dev, wd->sta.staPSDataQueue[i], 0);
5195 wd->sta.ibssPSDataCount = 0;
5196 wd->sta.staPSDataCount = 0;
5197 zfZeroMemory((u8_t*) &wd->sta.staPSList, sizeof(struct zsStaPSList));
5199 wd->sta.wmeConnected = 0;
5200 wd->sta.psMgr.tempWakeUp = 0;
5201 wd->sta.qosInfo = 0;
5202 zfQueueFlush(dev, wd->sta.uapsdQ);
5204 return;
5208 void zfStaIbssMonitoring(zdev_t* dev, u8_t reset)
5210 u16_t i;
5211 u16_t oppositeCount;
5212 struct zsPartnerNotifyEvent event;
5214 zmw_get_wlan_dev(dev);
5216 zmw_declare_for_critical_section();
5218 //zm_debug_msg1("zfStaIbssMonitoring %d", wd->sta.oppositeCount);
5220 zmw_enter_critical_section(dev);
5222 if ( wd->sta.oppositeCount == 0 )
5224 goto done;
5227 if ( wd->sta.bChannelScan )
5229 goto done;
5232 oppositeCount = wd->sta.oppositeCount;
5234 for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
5236 if ( oppositeCount == 0 )
5238 break;
5241 if ( reset )
5243 wd->sta.oppositeInfo[i].valid = 0;
5246 if ( wd->sta.oppositeInfo[i].valid == 0 )
5248 continue;
5251 oppositeCount--;
5253 if ( wd->sta.oppositeInfo[i].aliveCounter )
5255 zm_debug_msg1("Setting alive to ", wd->sta.oppositeInfo[i].aliveCounter);
5257 zmw_leave_critical_section(dev);
5259 if ( wd->sta.oppositeInfo[i].aliveCounter != ZM_IBSS_PEER_ALIVE_COUNTER )
5261 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ,
5262 (u16_t*)wd->sta.oppositeInfo[i].macAddr, 1, 0, 0);
5265 zmw_enter_critical_section(dev);
5266 wd->sta.oppositeInfo[i].aliveCounter--;
5268 else
5270 zm_debug_msg0("zfStaIbssMonitoring remove the peer station");
5271 zfMemoryCopy(event.bssid, (u8_t *)(wd->sta.bssid), 6);
5272 zfMemoryCopy(event.peerMacAddr, wd->sta.oppositeInfo[i].macAddr, 6);
5274 wd->sta.oppositeInfo[i].valid = 0;
5275 wd->sta.oppositeCount--;
5276 if (wd->zfcbIbssPartnerNotify != NULL)
5278 zmw_leave_critical_section(dev);
5279 wd->zfcbIbssPartnerNotify(dev, 0, &event);
5280 zmw_enter_critical_section(dev);
5285 done:
5286 if ( reset == 0 )
5288 zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
5291 zmw_leave_critical_section(dev);
5294 void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event)
5296 u16_t *peerMacAddr;
5298 zmw_get_wlan_dev(dev);
5300 peerMacAddr = (u16_t *)event->peerMacAddr;
5302 zfMemoryCopy(event->bssid, (u8_t *)(wd->sta.bssid), 6);
5303 peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5304 peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 2);
5305 peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 4);
5308 void zfStaInitOppositeInfo(zdev_t* dev)
5310 int i;
5312 zmw_get_wlan_dev(dev);
5314 for(i=0; i<ZM_MAX_OPPOSITE_COUNT; i++)
5316 wd->sta.oppositeInfo[i].valid = 0;
5317 wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
5320 #ifdef ZM_ENABLE_CENC
5321 u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset)
5323 zmw_get_wlan_dev(dev);
5325 if (wd->sta.cencIe[1] != 0)
5327 zfCopyToIntTxBuffer(dev, buf, wd->sta.cencIe, offset, wd->sta.cencIe[1]+2);
5328 offset += (wd->sta.cencIe[1]+2);
5330 return offset;
5332 #endif //ZM_ENABLE_CENC
5333 u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf)
5335 u8_t category, actionDetails;
5336 zmw_get_wlan_dev(dev);
5338 category = zmw_rx_buf_readb(dev, buf, 24);
5339 actionDetails = zmw_rx_buf_readb(dev, buf, 25);
5340 switch (category)
5342 case 0: //Spectrum Management
5343 switch(actionDetails)
5345 case 0: //Measurement Request
5346 break;
5347 case 1: //Measurement Report
5348 //ProcessActionSpectrumFrame_MeasurementReport(Adapter,pActionBody+3);
5349 break;
5350 case 2: //TPC request
5351 //if (wd->sta.TPCEnable)
5352 // zfStaUpdateDot11HTPC(dev, buf);
5353 break;
5354 case 3: //TPC report
5355 //if (wd->sta.TPCEnable)
5356 // zfStaUpdateDot11HTPC(dev, buf);
5357 break;
5358 case 4: //Channel Switch Announcement
5359 if (wd->sta.DFSEnable)
5360 zfStaUpdateDot11HDFS(dev, buf);
5361 break;
5362 default:
5363 zm_debug_msg1("Action Frame contain not support action field ", actionDetails);
5364 break;
5366 break;
5367 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
5368 zfAggBlockAckActionFrame(dev, buf);
5369 break;
5370 case 17: //Qos Management
5371 break;
5374 return 0;
5377 /* Determine the time not send beacon , if more than some value ,
5378 re-write the beacon start address */
5379 void zfReWriteBeaconStartAddress(zdev_t* dev)
5381 zmw_get_wlan_dev(dev);
5383 zmw_declare_for_critical_section();
5385 zmw_enter_critical_section(dev);
5386 wd->tickIbssSendBeacon++; // Increase 1 per 10ms .
5387 zmw_leave_critical_section(dev);
5389 if ( wd->tickIbssSendBeacon == 40 )
5391 // DbgPrint("20070727");
5392 zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
5393 zmw_enter_critical_section(dev);
5394 wd->tickIbssSendBeacon = 0;
5395 zmw_leave_critical_section(dev);
5399 struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf)
5401 u8_t keyIndex;
5402 u8_t da0;
5404 zmw_get_wlan_dev(dev);
5406 /* if need not check MIC, return NULL */
5407 if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
5408 (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5410 return NULL;
5413 da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5415 if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
5416 keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
5417 else
5418 keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
5419 keyIndex = (keyIndex & 0xc0) >> 6;
5421 return (&wd->sta.rxSeed[keyIndex]);
5424 void zfStaEnableSWEncryption(zdev_t *dev, u8_t value)
5426 zmw_get_wlan_dev(dev);
5428 wd->sta.SWEncryptEnable = value;
5429 zfHpSWDecrypt(dev, 1);
5430 zfHpSWEncrypt(dev, 1);
5433 void zfStaDisableSWEncryption(zdev_t *dev)
5435 zmw_get_wlan_dev(dev);
5437 wd->sta.SWEncryptEnable = 0;
5438 zfHpSWDecrypt(dev, 0);
5439 zfHpSWEncrypt(dev, 0);
5442 u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength)
5444 u8_t weightOfB = 0;
5445 u8_t weightOfAGBelowThr = 0;
5446 u8_t weightOfAGUpThr = 15;
5447 u8_t weightOfN20BelowThr = 15;
5448 u8_t weightOfN20UpThr = 30;
5449 u8_t weightOfN40BelowThr = 16;
5450 u8_t weightOfN40UpThr = 32;
5452 if( isBMode == 0 )
5453 return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP !
5454 else
5456 if( isHT == 0 && isHT40 == 0 )
5457 { // a , g , b/g mode ! add the weight value 15 for this AP if it's signal strength is more than some value !
5458 if( signalStrength < 18 ) // -77 dBm
5459 return signalStrength + weightOfAGBelowThr;
5460 else
5461 return (signalStrength + weightOfAGUpThr);
5463 else if( isHT == 1 && isHT40 == 0 )
5464 { // 80211n mode use 20MHz
5465 if( signalStrength < 23 ) // -72 dBm
5466 return (signalStrength + weightOfN20BelowThr);
5467 else
5468 return (signalStrength + weightOfN20UpThr);
5470 else // isHT == 1 && isHT40 == 1
5471 { // 80211n mode use 40MHz
5472 if( signalStrength < 16 ) // -79 dBm
5473 return (signalStrength + weightOfN40BelowThr);
5474 else
5475 return (signalStrength + weightOfN40UpThr);
5480 u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset)
5482 u16_t i;
5484 zmw_get_wlan_dev(dev);
5486 for (i=0; i<wd->sta.ibssAdditionalIESize; i++)
5488 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ibssAdditionalIE[i]);
5491 return offset;