MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / usb / net / Zydas / zdpsmon.c
blobb4f97e5756b2c1c1ddf8bec1f2688397e74001c7
1 #ifndef __ZDPSMON_C__
2 #define __ZDPSMON_C__
4 #include "zd80211.h"
5 #include "zddebug.h"
7 #define GetEntry(pMac) (((pMac->mac[3]) ^ (pMac->mac[4]) ^ (pMac->mac[5])) & (MAX_AID-1))
9 Hash_t *FreeHashList;
10 Hash_t HashBuf[MAX_RECORD];
11 Hash_t *HashTbl[MAX_RECORD];
12 Hash_t *sstByAid[MAX_RECORD];
13 U32 freeHashCount;
15 extern void zd1205_config_dyn_key(u8 DynKeyMode, u8 *pkey, int idx);
16 Hash_t *HashInsert(MacAddr_t *pMac);
18 void CleanupHash(Hash_t *hash)
20 memset(hash->mac, 0, 6);
21 hash->asoc = STATION_STATE_DIS_ASOC;
22 hash->auth = STATION_STATE_NOT_AUTH;
23 hash->psm = PSMODE_STA_ACTIVE;
24 hash->encryMode = WEP_NOT_USED;
25 hash->ZydasMode = 0;
26 hash->pkInstalled = 0;
27 hash->AlreadyIn = 0;
28 hash->ContSuccFrames = 0;
29 hash->ttl = 0;
30 hash->bValid = FALSE;
31 hash->Preamble = 0;
32 hash->keyLength = 0;
33 hash->KeyId = 0;
34 memset(hash->wepIv, 0, 4);
35 memset(&hash->TxSeed, 0, sizeof(Seedvar));
36 memset(&hash->RxSeed, 0, sizeof(Seedvar));
37 memset(&hash->TxMicKey, 0, sizeof(MICvar));
38 memset(&hash->RxMicKey, 0, sizeof(MICvar));
39 hash->SuccessFrames = 0;
40 hash->FailedFrames = 0;
41 hash->bJustRiseRate = FALSE;
42 hash->RiseConditionCount = 0;
43 hash->DownConditionCount = 0;
44 hash->vapId = 0;
45 #if defined(OFDM)
46 hash->bErpSta = TRUE;
47 #else
48 hash->bErpSta = FALSE;
49 #endif
53 void CleanupKeyInfo(Hash_t *hash)
55 hash->encryMode = WEP_NOT_USED;
56 hash->pkInstalled = 0;
57 hash->keyLength = 0;
58 hash->KeyId = 0;
59 memset(hash->wepIv, 0, 4);
60 memset(&hash->TxSeed, 0, sizeof(Seedvar));
61 memset(&hash->RxSeed, 0, sizeof(Seedvar));
62 memset(&hash->TxMicKey, 0, sizeof(MICvar));
63 memset(&hash->RxMicKey, 0, sizeof(MICvar));
67 void initHashBuf(void)
69 int i;
71 freeHashCount = MAX_RECORD;
73 for (i=0; i<MAX_AID; i++){ //from 0 to 31
74 HashBuf[i].pNext = &HashBuf[i+1];
75 sstByAid[i] = &HashBuf[i];
76 HashBuf[i].aid = i;
77 CleanupHash(&HashBuf[i]);
80 //aid 32 is here
81 HashBuf[MAX_AID].pNext = NULL;
82 sstByAid[MAX_AID] = &HashBuf[MAX_AID];
83 HashBuf[MAX_AID].aid = MAX_AID;
84 CleanupHash(&HashBuf[MAX_AID]);
86 FreeHashList = &HashBuf[1]; //by pass aid = 0
88 //deal with aid = 0
89 HashBuf[0].pNext = NULL;
93 Hash_t *allocHashBuf(void)
95 Hash_t *hash = NULL;
96 U32 flags;
98 //HSDEBUG("*****allocHashBuf*****");
99 flags = pdot11Obj->EnterCS();
100 if (FreeHashList != NULL){
101 hash = FreeHashList;
102 FreeHashList = FreeHashList->pNext;
103 hash->pNext = NULL;
104 freeHashCount--;
106 pdot11Obj->ExitCS(flags);
107 return hash;
112 void freeHashBuf(Hash_t *hash)
114 U32 flags;
116 //HSDEBUG("*****freeHashBuf*****");
117 flags = pdot11Obj->EnterCS();
118 if (hash->AlreadyIn){
119 if (mCurrConnUser > 0)
120 mCurrConnUser--;
121 if (hash->bErpSta == FALSE && mNumBOnlySta > 0)
123 mNumBOnlySta--;
124 if (mNumBOnlySta==0)
126 pdot11Obj->ConfigFlag &= ~NON_ERP_PRESENT_SET;
127 mErp.buf[2] &= ~NON_ERP_PRESENT;
132 if (hash->psm == PSMODE_POWER_SAVE){
133 if (mPsStaCnt > 0)
134 mPsStaCnt--;
137 #if defined(AMAC)
138 HW_CAM_ClearRollTbl(pdot11Obj, hash->aid);
139 #endif
141 CleanupHash(hash);
142 hash->pNext = FreeHashList;
143 FreeHashList = hash;
144 freeHashCount++;
145 pdot11Obj->ExitCS(flags);
149 void InitHashTbl(void)
151 int i;
153 for (i=0; i<MAX_RECORD; i++){
154 HashTbl[i] = NULL;
159 Hash_t *HashSearch(MacAddr_t *pMac)
161 U8 entry;
162 Hash_t *hash = NULL;
163 U32 flags;
164 U16 loopCheck = 0;
166 if (mBssType == INFRASTRUCTURE_BSS){
167 if (memcmp(&mBssId, pMac, 6) != 0){
168 return NULL;
170 else
171 return sstByAid[0];
174 //HSDEBUG("HashSearch");
175 entry = GetEntry(pMac);
176 flags = pdot11Obj->EnterCS();
177 if (HashTbl[entry] == NULL) {
178 goto exit;
180 else{
181 hash = HashTbl[entry];
182 do {
183 //to prevent hash->pNext equals to its self
184 if(loopCheck++ > 100)
186 printk("infinite loop occurs in %s\n", __FUNCTION__);
187 loopCheck = 0;
188 break;
191 if (memcmp(hash->mac, (U8 *)pMac, 6) == 0){
192 //HSDEBUG("Search got one");
193 goto exit;
195 else
196 hash = hash->pNext;
198 }while(hash != NULL);
201 exit:
202 pdot11Obj->ExitCS(flags);
203 if (hash){
204 #if 0
205 printf("macaddr = %02x:%02x:%02x:%02x:%02x:%02x\n",
206 hash->mac[0], hash->mac[1], hash->mac[2],
207 hash->mac[3], hash->mac[4], hash->mac[5]);
208 printf("asoc = %x\n", hash->asoc);
209 printf("auth = %x\n", hash->auth);
210 printf("psm = %x\n", hash->psm);
211 printf("aid = %x\n", hash->aid);
212 printf("lsInterval = %x\n", hash->lsInterval);
213 #endif
215 else
216 ;//HSDEBUG("Search no one");
218 return hash;
226 Hash_t *HashInsert(MacAddr_t *pMac)
228 U8 entry;
229 Hash_t *hash;
230 U32 flags;
232 HSDEBUG("HashInsert");
234 if (mBssType == INFRASTRUCTURE_BSS){
235 hash = sstByAid[0];
236 memcpy(hash->mac, (U8 *)pMac, 6);
237 hash->ttl = HW_GetNow(pdot11Obj);
238 hash->bValid = TRUE;
239 return hash;
242 hash = allocHashBuf();
243 if (!hash){
244 HSDEBUG("No free one");
245 //Age Hash table
246 AgeHashTbl();
247 return NULL; // no free one
249 else{
250 entry = GetEntry(pMac);
251 HSDEBUG_V("entry", entry);
253 if (HashTbl[entry] == NULL){ //entry is null
254 HashTbl[entry] = hash;
255 HSDEBUG("Entry is null");
257 else{ //insert list head
258 flags = pdot11Obj->EnterCS();
259 hash->pNext = HashTbl[entry];
260 HashTbl[entry] = hash;
261 pdot11Obj->ExitCS(flags);
262 HSDEBUG("Insert to list head");
265 memcpy(hash->mac, (U8 *)pMac, 6);
266 hash->ttl = HW_GetNow(pdot11Obj);
267 hash->bValid = TRUE;
268 return hash;
273 BOOLEAN AgeHashTbl(void)
275 U32 now, ttl, idleTime;
276 U8 entry, firstLayer;
277 U16 loopCheck = 0;
279 int i;
280 MacAddr_t *pMac;
281 Hash_t *hash, *preHash = NULL;
282 BOOLEAN ret = FALSE;
284 HSDEBUG("*****AgeHashTbl*****");
285 now = HW_GetNow(pdot11Obj);
287 for (i=1; i<(MAX_AID+1); i++){
288 ttl = sstByAid[i]->ttl;
289 if (now > ttl)
290 idleTime = now - ttl;
291 else
292 idleTime = (0xffffffff - ttl) + now;
295 if (sstByAid[i]->bValid){
296 if (idleTime > IDLE_TIMEOUT ){
297 HSDEBUG("*****Age one*****");
298 HSDEBUG_V("aid", i);
299 HSDEBUG_V("now", now);
300 HSDEBUG_V("ttl", ttl);
301 HSDEBUG_V("idleTime", idleTime);
303 pMac = (MacAddr_t *)&sstByAid[i]->mac[0];
304 entry = GetEntry(pMac);
305 HSDEBUG_V("entry", entry);
306 hash = HashTbl[entry];
307 firstLayer = 1;
308 do {
309 // For AP only
310 if(loopCheck++ > 100)
312 printk("infinite loop occurs in %s\n", __FUNCTION__);
313 loopCheck = 0;
314 break;
317 if (hash == sstByAid[i]){
318 if (firstLayer == 1){
319 HSDEBUG("*****firstLayer*****");
320 if (hash->pNext != NULL)
321 HashTbl[entry] = hash->pNext;
322 else
323 HashTbl[entry] = NULL;
325 else{
326 HSDEBUG("*****Not firstLayer*****");
327 preHash->pNext = hash->pNext;
329 zd_CmdProcess(CMD_DISASOC, &hash->mac[0], ZD_INACTIVITY);
330 freeHashBuf(hash);
331 break;
333 else{
334 preHash = hash;
335 hash = hash->pNext;
336 firstLayer = 0;
338 }while(hash != NULL);
339 ret = TRUE;
341 else {
342 if (sstByAid[i]->ZydasMode == 1)
343 mZyDasModeClient = TRUE;
345 if (sstByAid[i]->bErpSta == FALSE && mMacMode != PURE_A_MODE){
346 pdot11Obj->ConfigFlag |= NON_ERP_PRESENT_SET;
347 pdot11Obj->ConfigFlag |= ENABLE_PROTECTION_SET;
348 if (sstByAid[i]->Preamble == 0){ //long preamble
349 pdot11Obj->ConfigFlag |= BARKER_PREAMBLE_SET;
357 //HSDEBUG_V("ret", ret);
358 return ret;
362 void ResetPSMonitor(void)
364 ZDEBUG("ResetPSMonitor");
365 initHashBuf();
366 InitHashTbl();
367 mPsStaCnt = 0;
371 Hash_t *RxInfoIndicate(MacAddr_t *sta, PsMode psm, U8 rate)
373 Hash_t *pHash;
375 ZDEBUG("RxInfoIndicate");
377 //if (isGroup(sta))
378 //return NULL;
380 pHash = HashSearch(sta);
381 if (!pHash){
382 if (mBssType == PSEUDO_IBSS){
383 pHash = HashInsert(sta);
384 if (!pHash)
385 return NULL;
386 else{
387 pHash->asoc = STATION_STATE_ASOC;
388 zd1205_dump_data(" HashInsert macAddr = ", (U8 *)&pHash->mac[0], 6);
389 goto updateInfo;
392 else
393 return NULL;
395 else{
396 PsMode oldPsm = pHash->psm;
397 StationState asoc = pHash->asoc;
399 updateInfo:
400 if (rate > pHash->MaxRate)
401 pHash->MaxRate = rate;
403 pHash->RxRate = rate;
404 pHash->ttl = HW_GetNow(pdot11Obj);
406 if (mBssType == AP_BSS){
407 if (psm == PSMODE_STA_ACTIVE){
408 if (oldPsm == PSMODE_POWER_SAVE){
409 StaWakeup(sta);
410 if (asoc == STATION_STATE_ASOC){
411 if (mPsStaCnt >0){
412 mPsStaCnt--;
417 else {
418 if (oldPsm == PSMODE_STA_ACTIVE){
419 if (asoc == STATION_STATE_ASOC){
420 if (mPsStaCnt < MAX_AID){
421 mPsStaCnt++;
425 else if (oldPsm == PSMODE_POWER_SAVE){
426 if (asoc == STATION_STATE_ASOC){
427 if (mPsStaCnt == 0)
428 mPsStaCnt++;
434 pHash->psm = psm;
437 return pHash;
441 void RxInfoUpdate(Hash_t *pHash, PsMode psm, U8 rate)
443 PsMode oldPsm = pHash->psm;
444 StationState asoc = pHash->asoc;
446 if (rate > pHash->MaxRate)
447 pHash->MaxRate = rate;
449 pHash->RxRate = rate;
450 pHash->ttl = HW_GetNow(pdot11Obj);
452 if (psm == PSMODE_STA_ACTIVE){
453 if (oldPsm == PSMODE_POWER_SAVE){
454 StaWakeup((MacAddr_t *)pHash->mac);
455 if (asoc == STATION_STATE_ASOC){
456 if (mPsStaCnt >0){
457 mPsStaCnt--;
462 else {
463 if (oldPsm == PSMODE_STA_ACTIVE){
464 if (asoc == STATION_STATE_ASOC){
465 if (mPsStaCnt < MAX_AID){
466 mPsStaCnt++;
470 else if (oldPsm == PSMODE_POWER_SAVE){
471 if (asoc == STATION_STATE_ASOC){
472 if (mPsStaCnt == 0)
473 mPsStaCnt++;
480 pHash->psm = psm;
484 BOOLEAN UpdateStaStatus(MacAddr_t *sta, StationState staSte, U8 vapId)
486 Hash_t *pHash;
487 U16 loopCheck = 0;
489 ZDEBUG("UpdateStaStatus");
491 if (mBssType == AP_BSS){
492 pHash = HashSearch(sta);
493 if (pHash)
494 goto UpdateStatus;
495 else{
496 if ((STATION_STATE_AUTH_OPEN == staSte) || (STATION_STATE_AUTH_KEY == staSte)){
497 if ((mCurrConnUser + 1) > mLimitedUser){
498 //AgeHashTbl();
499 return FALSE;
501 else{
502 pHash = HashInsert(sta);
503 if (!pHash)
504 return FALSE;
507 else
508 return FALSE;
511 else if (mBssType == INFRASTRUCTURE_BSS){
512 if ((STATION_STATE_AUTH_OPEN == staSte) || (STATION_STATE_AUTH_KEY == staSte)){
513 CleanupHash(sstByAid[0]);
514 pHash = HashInsert(sta);
515 } else {
516 pHash = sstByAid[0]; //use aid = 0 to store AP's info
519 else if (mBssType == INDEPENDENT_BSS){
520 pHash = HashSearch(sta);
521 if (pHash)
522 goto UpdateStatus;
523 else {
524 pHash = HashInsert(sta);
525 if (!pHash)
526 return FALSE;
527 else
528 zd1205_dump_data(" HashInsert macAddr = ", (U8 *)&pHash->mac[0], 6);
531 else
532 return FALSE;
534 UpdateStatus:
535 switch(staSte){
536 case STATION_STATE_AUTH_OPEN:
537 case STATION_STATE_AUTH_KEY:
538 pHash->auth = staSte;
539 break;
541 case STATION_STATE_ASOC:
542 if (mBssType == AP_BSS){
543 if (((mCurrConnUser + 1) > mLimitedUser) && (!pHash->AlreadyIn)){
544 return FALSE;
547 if (pHash->psm == PSMODE_POWER_SAVE){
548 if (mPsStaCnt > 0){
549 mPsStaCnt--;
554 pHash->asoc = STATION_STATE_ASOC;
555 /*if (!pHash->AlreadyIn){
556 pHash->AlreadyIn = 1;
557 mCurrConnUser++;
559 }else{
560 pHash->asoc = STATION_STATE_ASOC;
563 if (mBssType != INDEPENDENT_BSS)
564 CleanupKeyInfo(pHash);
566 memcpy(&pdot11Obj->CurrSsid[0], (U8 *)&mSsid, mSsid.buf[1]+2);
567 break;
569 case STATION_STATE_NOT_AUTH:
570 case STATION_STATE_DIS_ASOC:
571 if (mBssType == AP_BSS){
572 if (pHash->asoc == STATION_STATE_ASOC){
573 if (pHash->psm == PSMODE_POWER_SAVE){
574 FlushQ(pPsQ[pHash->aid]);
575 if (mPsStaCnt > 0){
576 mPsStaCnt--;
577 if (mPsStaCnt == 0){
578 FlushQ(pAwakeQ);
579 FlushQ(pPsQ[0]);
583 /*if (pHash->AlreadyIn){
584 pHash->AlreadyIn = 0;
585 mCurrConnUser--;
586 }*/
590 pHash->auth = STATION_STATE_NOT_AUTH;
591 pHash->asoc = STATION_STATE_DIS_ASOC;
592 CleanupKeyInfo(pHash);
593 //for Rx-Retry filter
594 HW_CAM_ClearRollTbl(pdot11Obj, pHash->aid);
596 MacAddr_t *pMac;
597 Hash_t *sta_info;
598 U8 entry;
599 pMac = (MacAddr_t *) pHash->mac;
600 entry = GetEntry(pMac);
601 sta_info=HashTbl[entry];
602 if (sta_info)
604 if (memcmp(sta_info->mac, pHash->mac, 6)==0)
606 HashTbl[entry]=sta_info->pNext;
607 freeHashBuf(pHash);
609 else
611 while (sta_info->pNext != NULL && memcmp(sta_info->pNext->mac, pHash->mac, 6) != 0)
613 // To prevent self-link
614 if(loopCheck++ > 100)
616 printk("infinite loop occurs in %s\n", __FUNCTION__);
617 loopCheck = 0;
618 break;
621 sta_info = sta_info->pNext;
623 if (sta_info->pNext != NULL)
625 Hash_t *sta_info1;
626 sta_info1 = sta_info->pNext;
627 sta_info->pNext = sta_info->pNext->pNext;
628 freeHashBuf(sta_info1);
630 else
632 printk(KERN_DEBUG "Could not remove STA:" MACSTR "\n", MAC2STR(pHash->mac));
638 break;
642 return TRUE;
646 void SsInquiry(MacAddr_t *sta, StationState *sst, StationState *asst)
648 ZDEBUG("SsInquiry");
649 if (isGroup(sta)){
650 *asst = STATION_STATE_NOT_AUTH;
651 *sst = STATION_STATE_DIS_ASOC;
653 else{
654 Hash_t *pHash;
655 pHash = HashSearch(sta);
657 if (!pHash){
658 *asst = STATION_STATE_NOT_AUTH;
659 *sst = STATION_STATE_DIS_ASOC;
661 else{
662 *asst = pHash->auth;
663 if ((*asst == STATION_STATE_AUTH_OPEN) || (*asst == STATION_STATE_AUTH_KEY))
664 *sst = pHash->asoc;
665 else
666 *sst = STATION_STATE_DIS_ASOC;
673 U16 AIdLookup(MacAddr_t *sta)
675 Hash_t *pHash;
677 ZDEBUG("AIdLookup");
678 pHash = HashSearch(sta);
679 if (!pHash)
680 return (U16)0;
681 else
682 return pHash->aid;
686 void AssocInfoUpdate(MacAddr_t *sta, U8 MaxRate, U8 lsInterval, U8 ZydasMode, U8 Preamble, BOOLEAN bErpSta, U8 Burst, U8 AMSDU, U8 AMSDU_LEN, U8 vapId)
689 Hash_t *pHash;
691 ZDEBUG("AssocInfoUpdate");
692 if (isGroup(sta))
693 return;
695 pHash = HashSearch(sta);
696 if (!pHash)
697 return;
698 else{
699 pHash->MaxRate = MaxRate;
700 pHash->CurrTxRate = MaxRate;
701 pHash->lsInterval = lsInterval;
702 pHash->ZydasMode = ZydasMode;
703 pHash->Preamble = Preamble;
704 pHash->bErpSta = bErpSta;
705 pHash->vapId = vapId;
706 #if ZDCONF_LP_SUPPORT == 1
707 pHash->Turbo_Burst = Burst;
708 pHash->Turbo_AMSDU = AMSDU;
709 pHash->Turbo_AMSDU_LEN = AMSDU_LEN;
710 #endif
715 int zd_SetKeyInfo(U8 *addr, U8 encryMode, U8 keyLength, U8 key_id, U8 *pKeyContent)
717 Hash_t *pHash;
718 MacAddr_t *sta = (MacAddr_t *)addr;
720 U8 bcAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
721 U8 ZeroAddr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
722 U16 aid;
723 U8 change_enc = 0;
724 U8 bTxKey = key_id & BIT_7;
725 U8 bClrRollTable = key_id & BIT_6;
726 U8 KeyId = key_id & 0xF;
728 switch (encryMode)
730 case WEP64:
731 keyLength = 5;
732 break;
733 case WEP128:
734 keyLength = 13;
735 break;
736 case WEP256:
737 keyLength = 29;
738 break;
739 case TKIP:
740 keyLength = 32;
741 break;
742 case AES:
743 keyLength = 16;
744 break;
745 default:
746 return 0;
748 if (isGroup(sta))
750 change_enc = 1;
751 if (keyLength == 0)
752 { // No entry chance.
753 WPADEBUG("Clear Group key RollTbl (aid0)\n");
754 HW_CAM_ClearRollTbl(pdot11Obj, 0);//Clear group key.(aid0)
755 return 0;
757 if (mWpaBcKeyLen == keyLength && mGkInstalled == 1)
758 change_enc = 0; // Nonfirst time group key update.
759 mWpaBcKeyLen = keyLength;
760 mBcKeyId = KeyId;
761 mGkInstalled = 1;
763 if (encryMode == WEP64 || encryMode == WEP128 || encryMode == WEP256)
765 if (mOperationMode != CAM_AP_VAP)
767 if (0)
769 HW_ConfigDynaKey(pdot11Obj, 32, &bcAddr[0], pKeyContent, keyLength, encryMode, change_enc);
771 else if (bTxKey)
773 if (bClrRollTable)
774 HW_CAM_ResetRollTbl(pdot11Obj);// Reset all.
775 mKeyId = KeyId;
777 // Also set default key for Multicast case to avoid Tx-underrun.
778 HW_CAM_Write(pdot11Obj, DEFAULT_ENCRY_TYPE, encryMode);
779 HW_ConfigStatKey(pdot11Obj, pKeyContent, keyLength, STA_KEY_START_ADDR+(KeyId * 8));
781 else
782 HW_ConfigDynaKey(pdot11Obj, CAM_VAP_START_AID, (U8 *)&dot11MacAddress, pKeyContent, keyLength, encryMode,change_enc);
784 return 0;
786 else if (encryMode == TKIP)
788 if (mWpaBcKeyLen == 32)
790 if (mOperationMode != CAM_AP_VAP)
792 //Tmep key(16), Tx Mic Key(8), Rx Mic Key(8)
793 HW_ConfigDynaKey(pdot11Obj, 32, &bcAddr[0], pKeyContent, keyLength, encryMode, change_enc);
794 // Also set default key for Multicast case to avoid Tx-underrun.
795 //if ((mDebugFlag & BIT_1)==0)
797 HW_CAM_Write(pdot11Obj, DEFAULT_ENCRY_TYPE, encryMode);
798 HW_ConfigStatKey(pdot11Obj, pKeyContent, keyLength, STA_KEY_START_ADDR+(KeyId * 8));
801 else
803 HW_ConfigDynaKey(pdot11Obj, CAM_VAP_START_AID, (U8 *)&dot11MacAddress, pKeyContent, keyLength, encryMode, change_enc);
805 if (mBssType == INFRASTRUCTURE_BSS)
806 MICsetKey(&pKeyContent[24], &mBcMicKey); //Tx Mic key
807 else
808 MICsetKey(&pKeyContent[16], &mBcMicKey);// For Infra-STA mode.
810 return 0;
812 else if (encryMode == AES)
814 if (mWpaBcKeyLen == 16)
816 if (mOperationMode != CAM_AP_VAP)
818 HW_ConfigDynaKey(pdot11Obj, 32, &bcAddr[0], pKeyContent, keyLength, encryMode, change_enc);
819 // Also set default key for Multicast case to avoid Tx-underrun.
820 HW_CAM_Write(pdot11Obj, DEFAULT_ENCRY_TYPE, encryMode);
821 HW_ConfigStatKey(pdot11Obj, pKeyContent, keyLength, STA_KEY_START_ADDR+(KeyId * 8));
823 else
825 HW_ConfigDynaKey(pdot11Obj, CAM_VAP_START_AID, (U8 *)&dot11MacAddress, pKeyContent, keyLength, encryMode, change_enc);
828 return 0;
830 else{
831 return -1;
833 }// End of Group key setting.
835 // Start of Pairwise key setting.
836 pHash = HashSearch(sta);
837 if (!pHash)
839 if (!memcmp(&sta->mac[0], ZeroAddr, 6))
841 int i;
842 HW_CAM_ResetRollTbl(pdot11Obj);
843 if (mGkInstalled)
845 HW_CAM_UpdateRollTbl(pdot11Obj,0);//ReEnable group key.
847 if (mBssType != INFRASTRUCTURE_BSS)
848 {//AP mode.
849 WPADEBUG("clear all tx key\n");
850 for (i=0; i<MAX_RECORD; i++)
851 HashBuf[i].pkInstalled=0;
853 else
854 {// STA mode.
855 WPADEBUG("clear key of aid %d\n",sstByAid[0]->aid);
856 sstByAid[0]->pkInstalled=0;
859 return -1;
861 else{
862 pHash->keyLength = keyLength;
863 if (pHash->encryMode != encryMode)
864 change_enc = 1;
865 pHash->encryMode = encryMode;
866 aid = pHash->aid;
868 if (encryMode != NO_WEP)
869 WPADEBUG("********* Set key%s for aid:%d\n",DbgStrEncryType[encryMode & 7],aid);
870 else
871 WPADEBUG("********* Clear key for aid:%d\n",aid);
872 if (encryMode == NO_WEP)
873 {// Clear pairwise key
874 pHash->pkInstalled = 0;
875 if (mBssType == INFRASTRUCTURE_BSS)
876 HW_CAM_ClearRollTbl(pdot11Obj, 8);
877 else
878 HW_CAM_ClearRollTbl(pdot11Obj, aid);
880 else if (encryMode == TKIP)
882 if (mBssType == INFRASTRUCTURE_BSS)
884 // zd1205_dump_data("key:", (u8*)pKeyContent, 32);
885 HW_ConfigDynaKey(pdot11Obj, 8, addr, pKeyContent, 32, encryMode, change_enc);
887 else
888 HW_ConfigDynaKey(pdot11Obj, aid, addr, pKeyContent, 32, encryMode, change_enc);
890 MICsetKey(&pKeyContent[16], &pHash->TxMicKey);
891 MICsetKey(&pKeyContent[24], &pHash->RxMicKey);
892 pHash->KeyId = KeyId;
893 pHash->pkInstalled = 1;
895 else //if (encryMode == AES)
897 if (mBssType == INFRASTRUCTURE_BSS)
899 WPADEBUG("********* setAESkey\n");
900 HW_ConfigDynaKey(pdot11Obj, 8, addr, pKeyContent, keyLength, encryMode, change_enc);
902 else
903 HW_ConfigDynaKey(pdot11Obj, aid, addr, pKeyContent, keyLength, encryMode, change_enc);
904 pHash->KeyId = KeyId;
905 pHash->pkInstalled = 1;
907 return 0;
912 BOOLEAN zd_GetKeyInfo(U8 *addr, U8 *encryMode, U8 *keyLength, U8 *pKeyContent)
914 Hash_t *pHash;
915 MacAddr_t *sta = (MacAddr_t *)addr;
917 ZDEBUG("zd_GetKeyInfo");
918 if (isGroup(sta)){
919 return FALSE;
922 pHash = HashSearch(sta);
923 if (!pHash){
924 *encryMode = 0;
925 *keyLength = 0;
926 return FALSE;
928 else{
929 *encryMode = pHash->encryMode;
930 *keyLength = pHash->keyLength;
931 memcpy(pKeyContent, &pHash->keyContent[0], pHash->keyLength);
932 return TRUE;
937 * zd_SetKeyContext - Set Key context to CAM (used for WPA/WPA2)
938 * @addr: MAC address of AP we associated with
939 * @encryMode: Encryption mode
940 * @keyLength: Length of key context
941 * @keyId: Key index
942 * @pKeyContent: Context of key
944 #if 0
946 int zd_SetKeyContext(U8 *addr, U8 encryMode, U8 keyLength, U8 KeyId, U8 *pKeyContent)
948 Hash_t *pHash;
950 if (isGroup(addr)) {
951 mWpaBcKeyLen = keyLength;
952 mWpaBcKeyId = KeyId;
954 if (encryMode == DYN_KEY_TKIP) {
955 if (keyLength == 32) {
956 zd1205_config_dyn_key(encryMode, pKeyContent, KeyId);
957 MICsetKey(&pKeyContent[24], &mBcMicKey);
960 mGkInstalled = 1;
961 return 0;
963 else if (encryMode == DYN_KEY_AES) {
964 printk(KERN_ERR "***** set group key ID: %d\n",KeyId);
965 zd1205_config_dyn_key(encryMode, pKeyContent, KeyId);
966 mGkInstalled = 1;
967 return 0;
969 else {
970 WPADEBUG("zd_SetKeyContext: encryMode: %d not support\n", encryMode);
971 return -1;
976 pHash = HashSearch((MacAddr_t*)addr);
978 if(!pHash) {
979 WPADEBUG("Can't find AP's MAC address in the hash table\n");
980 return -1;
982 else {
983 pHash->encryMode = encryMode;
985 if (encryMode == DYN_KEY_TKIP) {
986 zd1205_config_dyn_key(encryMode, pKeyContent, KeyId);
988 MICsetKey(&pKeyContent[16], &pHash->TxMicKey);
989 MICsetKey(&pKeyContent[24], &pHash->RxMicKey);
990 pHash->KeyId = KeyId;
991 pHash->pkInstalled = 1;
993 else if (encryMode == DYN_KEY_AES) {
994 zd1205_config_dyn_key(encryMode, pKeyContent, KeyId);
995 pHash->KeyId = KeyId;
996 pHash->pkInstalled = 1;
999 else {
1000 WPADEBUG("zd_SetKeyContext: encryMode: %d not support\n", encryMode);
1004 return 0;
1006 #endif
1008 #if defined(PHY_1202)
1009 int zd_GetKeyInfo_ext(U8 *addr, U8 *encryMode, U8 *keyLength, U8 *pKeyContent, U16 iv16, U32 iv32)
1011 Hash_t *pHash;
1012 MacAddr_t *sta = (MacAddr_t *)addr;
1014 ZDEBUG("zd_GetKeyInfo_ext");
1015 if (isGroup(sta)){
1016 return -1;
1019 if (mDynKeyMode != DYN_KEY_TKIP)
1020 return -1;
1022 pHash = HashSearch(sta);
1023 if (!pHash){
1024 *encryMode = 0;
1025 *keyLength = 0;
1026 return -1;
1028 else{
1029 if (pHash->pkInstalled == 0)
1030 return -2;
1032 if ((iv16 == pHash->RxSeed.IV16) && (iv32 == pHash->RxSeed.IV32)){
1033 // iv out of sequence
1034 //FPRINT_V("iv16", iv16);
1035 //FPRINT_V("iv32", iv32);
1036 //return -3;
1039 *encryMode = pHash->encryMode;
1040 *keyLength = pHash->keyLength;
1041 //do key mixing
1042 Tkip_phase1_key_mix(iv32, &pHash->RxSeed);
1043 Tkip_phase2_key_mix(iv16, &pHash->RxSeed);
1044 Tkip_getseeds(iv16, pKeyContent, &pHash->RxSeed);
1045 pHash->RxSeed.IV16 = iv16;
1046 pHash->RxSeed.IV32 = iv32;
1047 return pHash->aid;
1052 int zd_SetTsc(U8 *addr, U8 KeyId, U8 direction, U32 tscHigh, U16 tscLow)
1054 Hash_t *pHash;
1055 MacAddr_t *sta = (MacAddr_t *)addr;
1057 ZDEBUG("zd_SetTsc");
1058 if (isGroup(sta)){
1059 return -1;
1062 pHash = HashSearch(sta);
1063 if (!pHash)
1064 return -1;
1065 else{
1066 pHash->KeyId = KeyId;
1067 if (direction == 0){ //Tx
1068 pHash->TxSeed.IV16 = tscLow;
1069 pHash->TxSeed.IV32 = tscHigh;
1071 else if (direction == 1){ //Rx
1072 pHash->RxSeed.IV16 = tscLow;
1073 pHash->RxSeed.IV32 = tscHigh;
1075 return 0;
1080 int zd_GetTsc(U8 *addr, U8 KeyId, U8 direction, U32 *tscHigh, U16 *tscLow)
1082 Hash_t *pHash;
1083 MacAddr_t *sta = (MacAddr_t *)addr;
1085 ZDEBUG("zd_GetTsc");
1086 if (isGroup(sta)){
1087 return -1;
1090 pHash = HashSearch(sta);
1091 if (!pHash)
1092 return -1;
1093 else{
1094 if (direction == 0){ //Tx
1095 *tscLow = pHash->TxSeed.IV16;
1096 *tscHigh = pHash->TxSeed.IV32;
1098 else if (direction == 1){ //Rx
1099 *tscLow = pHash->RxSeed.IV16;
1100 *tscHigh = pHash->RxSeed.IV32;
1102 return 0;
1105 #endif
1108 BOOLEAN zd_CheckIvSeq(U8 aid, U16 iv16, U32 iv32)
1110 Hash_t *pHash = NULL;
1111 U16 oldIv16;
1112 U32 oldIv32;
1115 ZDEBUG("zd_CheckIvSeq");
1117 if (mDynKeyMode != DYN_KEY_TKIP){
1118 FPRINT("Not in DYN_KEY_TKIP mode");
1119 return FALSE;
1122 pHash = sstByAid[aid];
1123 if (!pHash){
1124 FPRINT("zd_CheckIvSeq failed");
1125 return FALSE;
1127 else{
1128 if (pHash->pkInstalled == 0){
1129 FPRINT("pkInstalled == 0");
1130 return FALSE;
1133 oldIv16 = pHash->RxSeed.IV16;
1134 oldIv32 = pHash->RxSeed.IV32;
1136 #if 1
1137 if ((oldIv16 == iv16) && (oldIv32 == iv32)){
1138 // iv out of sequence
1139 FPRINT("iv out of sequence");
1140 FPRINT_V("iv16", iv16);
1141 FPRINT_V("iv32", iv32);
1142 return FALSE;
1145 #else //If fifo overrun, this will failed
1146 if (iv32 == oldIv32){
1147 if (iv16 != oldIv16+1){
1148 // iv out of sequence
1149 FPRINT("iv out of sequence");
1150 FPRINT_V("iv16", iv16);
1151 FPRINT_V("iv32", iv32);
1152 return FALSE;
1155 else {
1156 if ((iv16 != 0) || (oldIv16 != 0xffff)){
1157 // iv out of sequence
1158 FPRINT("iv out of sequence");
1159 FPRINT_V("iv16", iv16);
1160 FPRINT_V("iv32", iv32);
1161 return FALSE;
1164 #endif
1166 pHash->RxSeed.IV16 = iv16;
1167 pHash->RxSeed.IV32 = iv32;
1168 return TRUE;
1173 #endif