OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / core / rtw_wapi.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #ifdef CONFIG_WAPI_SUPPORT
16
17 #include <linux/unistd.h>
18 #include <linux/etherdevice.h>
19 #include <drv_types.h>
20 #include <rtw_wapi.h>
21
22
23 u32 wapi_debug_component =
24         /*                              WAPI_INIT       |
25          *                              WAPI_API        |
26          *                              WAPI_TX |
27          *                              WAPI_RX | */
28         WAPI_ERR ; /* always open err flags on */
29
30 void WapiFreeAllStaInfo(_adapter *padapter)
31 {
32         PRT_WAPI_T                              pWapiInfo;
33         PRT_WAPI_STA_INFO               pWapiStaInfo;
34         PRT_WAPI_BKID                   pWapiBkid;
35
36         WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
37         pWapiInfo = &padapter->wapiInfo;
38
39         /* Pust to Idle List */
40         rtw_wapi_return_all_sta_info(padapter);
41
42         /* Sta Info List */
43         while (!list_empty(&(pWapiInfo->wapiSTAIdleList))) {
44                 pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
45                 list_del_init(&pWapiStaInfo->list);
46         }
47
48         /* BKID List */
49         while (!list_empty(&(pWapiInfo->wapiBKIDIdleList))) {
50                 pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
51                 list_del_init(&pWapiBkid->list);
52         }
53         WAPI_TRACE(WAPI_INIT, "<=========== %s\n", __FUNCTION__);
54         return;
55 }
56
57 void WapiSetIE(_adapter *padapter)
58 {
59         PRT_WAPI_T              pWapiInfo = &(padapter->wapiInfo);
60         /* PRT_WAPI_BKID        pWapiBkid; */
61         u16             protocolVer = 1;
62         u16             akmCnt = 1;
63         u16             suiteCnt = 1;
64         u16             capability = 0;
65         u8              OUI[3];
66
67         OUI[0] = 0x00;
68         OUI[1] = 0x14;
69         OUI[2] = 0x72;
70
71         pWapiInfo->wapiIELength = 0;
72         /* protocol version */
73         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, &protocolVer, 2);
74         pWapiInfo->wapiIELength += 2;
75         /* akm */
76         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, &akmCnt, 2);
77         pWapiInfo->wapiIELength += 2;
78
79         if (pWapiInfo->bWapiPSK) {
80                 memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, OUI, 3);
81                 pWapiInfo->wapiIELength += 3;
82                 pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x2;
83                 pWapiInfo->wapiIELength += 1;
84         } else {
85                 memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, OUI, 3);
86                 pWapiInfo->wapiIELength += 3;
87                 pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
88                 pWapiInfo->wapiIELength += 1;
89         }
90
91         /* usk */
92         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, &suiteCnt, 2);
93         pWapiInfo->wapiIELength += 2;
94         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, OUI, 3);
95         pWapiInfo->wapiIELength += 3;
96         pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
97         pWapiInfo->wapiIELength += 1;
98
99         /* msk */
100         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, OUI, 3);
101         pWapiInfo->wapiIELength += 3;
102         pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
103         pWapiInfo->wapiIELength += 1;
104
105         /* Capbility */
106         memcpy(pWapiInfo->wapiIE + pWapiInfo->wapiIELength, &capability, 2);
107         pWapiInfo->wapiIELength += 2;
108 }
109
110
111 /*  PN1 > PN2, return 1,
112  *  else return 0.
113  */
114 u32 WapiComparePN(u8 *PN1, u8 *PN2)
115 {
116         char i;
117
118         if ((NULL == PN1) || (NULL == PN2))
119                 return 1;
120
121         /* overflow case */
122         if ((PN2[15] - PN1[15]) & 0x80)
123                 return 1;
124
125         for (i = 16; i > 0; i--) {
126                 if (PN1[i - 1] == PN2[i - 1])
127                         continue;
128                 else if (PN1[i - 1] > PN2[i - 1])
129                         return 1;
130                 else
131                         return 0;
132         }
133
134         return 0;
135 }
136
137 u8
138 WapiGetEntryForCamWrite(_adapter *padapter, u8 *pMacAddr, u8 KID, BOOLEAN IsMsk)
139 {
140         PRT_WAPI_T              pWapiInfo = NULL;
141         /* PRT_WAPI_CAM_ENTRY   pEntry=NULL; */
142         u8 i = 0;
143         u8 ret = 0xff;
144
145         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
146
147         pWapiInfo =  &padapter->wapiInfo;
148
149         /* exist? */
150         for (i = 0; i < WAPI_CAM_ENTRY_NUM; i++) {
151                 if (pWapiInfo->wapiCamEntry[i].IsUsed
152                     && (_rtw_memcmp(pMacAddr, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
153                     && pWapiInfo->wapiCamEntry[i].keyidx == KID
154                     && pWapiInfo->wapiCamEntry[i].type == IsMsk) {
155                         ret = pWapiInfo->wapiCamEntry[i].entry_idx; /* cover it */
156                         break;
157                 }
158         }
159
160         if (i == WAPI_CAM_ENTRY_NUM) { /* not found */
161                 for (i = 0; i < WAPI_CAM_ENTRY_NUM; i++) {
162                         if (pWapiInfo->wapiCamEntry[i].IsUsed == 0) {
163                                 pWapiInfo->wapiCamEntry[i].IsUsed = 1;
164                                 pWapiInfo->wapiCamEntry[i].type = IsMsk;
165                                 pWapiInfo->wapiCamEntry[i].keyidx = KID;
166                                 _rtw_memcpy(pWapiInfo->wapiCamEntry[i].PeerMacAddr, pMacAddr, ETH_ALEN);
167                                 ret = pWapiInfo->wapiCamEntry[i].entry_idx;
168                                 break;
169                         }
170                 }
171         }
172
173         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
174         return ret;
175
176         /*
177                 if(RTIsListEmpty(&pWapiInfo->wapiCamIdleList)) {
178                         return 0;
179                 }
180
181                 pEntry = (PRT_WAPI_CAM_ENTRY)RTRemoveHeadList(&pWapiInfo->wapiCamIdleList);
182                 RTInsertTailList(&pWapiInfo->wapiCamUsedList, &pEntry->list);
183
184
185                 return pEntry->entry_idx;*/
186 }
187
188 u8 WapiGetEntryForCamClear(_adapter *padapter, u8 *pPeerMac, u8 keyid, u8 IsMsk)
189 {
190         PRT_WAPI_T              pWapiInfo = NULL;
191         u8              i = 0;
192
193         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
194
195         pWapiInfo =  &padapter->wapiInfo;
196
197         for (i = 0; i < WAPI_CAM_ENTRY_NUM; i++) {
198                 if (pWapiInfo->wapiCamEntry[i].IsUsed
199                     && (_rtw_memcmp(pPeerMac, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
200                     && pWapiInfo->wapiCamEntry[i].keyidx == keyid
201                     && pWapiInfo->wapiCamEntry[i].type == IsMsk) {
202                         pWapiInfo->wapiCamEntry[i].IsUsed = 0;
203                         pWapiInfo->wapiCamEntry[i].keyidx = 2;
204                         _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr, 0, ETH_ALEN);
205
206                         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
207                         return pWapiInfo->wapiCamEntry[i].entry_idx;
208                 }
209         }
210
211         WAPI_TRACE(WAPI_API, "<====WapiGetReturnCamEntry(), No this cam entry.\n");
212         return 0xff;
213         /*
214                 if(RTIsListEmpty(&pWapiInfo->wapiCamUsedList)) {
215                         return FALSE;
216                 }
217
218                 pList = &pWapiInfo->wapiCamUsedList;
219                 while(pList->Flink != &pWapiInfo->wapiCamUsedList)
220                 {
221                         pEntry = (PRT_WAPI_CAM_ENTRY)pList->Flink;
222                         if(PlatformCompareMemory(pPeerMac,pEntry->PeerMacAddr, ETHER_ADDRLEN)== 0
223                                 && keyid == pEntry->keyidx)
224                         {
225                                 RTRemoveEntryList(pList);
226                                 RTInsertHeadList(&pWapiInfo->wapiCamIdleList, pList);
227                                 return pEntry->entry_idx;
228                         }
229                         pList = pList->Flink;
230                 }
231
232                 return 0;
233         */
234 }
235
236 void
237 WapiResetAllCamEntry(_adapter *padapter)
238 {
239         PRT_WAPI_T              pWapiInfo;
240         int                             i;
241
242         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
243
244         pWapiInfo =  &padapter->wapiInfo;
245
246         for (i = 0; i < WAPI_CAM_ENTRY_NUM; i++) {
247                 _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr, 0, ETH_ALEN);
248                 pWapiInfo->wapiCamEntry[i].IsUsed = 0;
249                 pWapiInfo->wapiCamEntry[i].keyidx = 2; /* invalid */
250                 pWapiInfo->wapiCamEntry[i].entry_idx = 4 + i * 2;
251         }
252
253         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
254
255         return;
256 }
257
258 u8 WapiWriteOneCamEntry(
259         _adapter        *padapter,
260         u8                      *pMacAddr,
261         u8                      KeyId,
262         u8                      EntryId,
263         u8                      EncAlg,
264         u8                      bGroupKey,
265         u8                      *pKey
266 )
267 {
268         u8 retVal = 0;
269         u16 usConfig = 0;
270
271         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
272
273         if (EntryId >= 32) {
274                 WAPI_TRACE(WAPI_ERR, "<=== CamAddOneEntry(): ulKeyId exceed!\n");
275                 return retVal;
276         }
277
278         usConfig = usConfig | (0x01 << 15) | ((u16)(EncAlg) << 2) | (KeyId);
279
280         if (EncAlg == _SMS4_) {
281                 if (bGroupKey == 1)
282                         usConfig |= (0x01 << 6);
283                 if ((EntryId % 2) == 1) /* ==0 sec key; == 1mic key */
284                         usConfig |= (0x01 << 5);
285         }
286
287         write_cam(padapter, EntryId, usConfig, pMacAddr, pKey);
288
289         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
290         return 1;
291 }
292
293 void rtw_wapi_init(_adapter *padapter)
294 {
295         PRT_WAPI_T              pWapiInfo;
296         int                             i;
297
298         WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
299         RT_ASSERT_RET(padapter);
300
301         if (!padapter->WapiSupport) {
302                 WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
303                 return;
304         }
305
306         pWapiInfo =  &padapter->wapiInfo;
307         pWapiInfo->bWapiEnable = false;
308
309         /* Init BKID List */
310         INIT_LIST_HEAD(&pWapiInfo->wapiBKIDIdleList);
311         INIT_LIST_HEAD(&pWapiInfo->wapiBKIDStoreList);
312         for (i = 0; i < WAPI_MAX_BKID_NUM; i++)
313                 list_add_tail(&pWapiInfo->wapiBKID[i].list, &pWapiInfo->wapiBKIDIdleList);
314
315         /* Init STA List */
316         INIT_LIST_HEAD(&pWapiInfo->wapiSTAIdleList);
317         INIT_LIST_HEAD(&pWapiInfo->wapiSTAUsedList);
318         for (i = 0; i < WAPI_MAX_STAINFO_NUM; i++)
319                 list_add_tail(&pWapiInfo->wapiSta[i].list, &pWapiInfo->wapiSTAIdleList);
320
321         for (i = 0; i < WAPI_CAM_ENTRY_NUM; i++) {
322                 pWapiInfo->wapiCamEntry[i].IsUsed = 0;
323                 pWapiInfo->wapiCamEntry[i].keyidx = 2; /* invalid */
324                 pWapiInfo->wapiCamEntry[i].entry_idx = 4 + i * 2;
325         }
326
327         WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
328 }
329
330 void rtw_wapi_free(_adapter *padapter)
331 {
332         WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
333         RT_ASSERT_RET(padapter);
334
335         if (!padapter->WapiSupport) {
336                 WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
337                 return;
338         }
339
340         WapiFreeAllStaInfo(padapter);
341
342         WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
343 }
344
345 void rtw_wapi_disable_tx(_adapter *padapter)
346 {
347         WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
348         RT_ASSERT_RET(padapter);
349
350         if (!padapter->WapiSupport) {
351                 WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
352                 return;
353         }
354
355         padapter->wapiInfo.wapiTxMsk.bTxEnable = false;
356         padapter->wapiInfo.wapiTxMsk.bSet = false;
357
358         WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
359 }
360
361 u8 rtw_wapi_is_wai_packet(_adapter *padapter, u8 *pkt_data)
362 {
363         PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
364         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
365         struct security_priv   *psecuritypriv = &padapter->securitypriv;
366         PRT_WAPI_STA_INFO pWapiSta = NULL;
367         u8 WaiPkt = 0, *pTaddr, bFind = false;
368         u8 Offset_TypeWAI = 0 ; /* (mac header len + llc length) */
369
370         WAPI_TRACE(WAPI_TX | WAPI_RX, "===========> %s\n", __FUNCTION__);
371
372         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
373                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
374                 return 0;
375         }
376
377         Offset_TypeWAI = 24 + 6 ;
378
379         /* YJ,add,091103. Data frame may also have skb->data[30]=0x88 and skb->data[31]=0xb4. */
380         if ((pkt_data[1] & 0x40) != 0) {
381                 /* RTW_INFO("data is privacy\n"); */
382                 return 0;
383         }
384
385         pTaddr = get_addr2_ptr(pkt_data);
386         if (list_empty(&pWapiInfo->wapiSTAUsedList))
387                 bFind = false;
388         else {
389                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
390                         if (_rtw_memcmp(pTaddr, pWapiSta->PeerMacAddr, 6) == _TRUE) {
391                                 bFind = true;
392                                 break;
393                         }
394                 }
395         }
396
397         WAPI_TRACE(WAPI_TX | WAPI_RX, "%s: bFind=%d pTaddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(pTaddr));
398
399         if (pkt_data[0] == WIFI_QOS_DATA_TYPE)
400                 Offset_TypeWAI += 2;
401
402         /* 88b4? */
403         if ((pkt_data[Offset_TypeWAI] == 0x88) && (pkt_data[Offset_TypeWAI + 1] == 0xb4)) {
404                 WaiPkt = pkt_data[Offset_TypeWAI + 5];
405
406                 psecuritypriv->hw_decrypted = _TRUE;
407         } else
408                 WAPI_TRACE(WAPI_TX | WAPI_RX, "%s(): non wai packet\n", __FUNCTION__);
409
410         WAPI_TRACE(WAPI_TX | WAPI_RX, "%s(): Recvd WAI frame. IsWAIPkt(%d)\n", __FUNCTION__, WaiPkt);
411
412         return  WaiPkt;
413 }
414
415
416 void rtw_wapi_update_info(_adapter *padapter, union recv_frame *precv_frame)
417 {
418         PRT_WAPI_T     pWapiInfo = &(padapter->wapiInfo);
419         struct recv_frame_hdr *precv_hdr;
420         u8      *ptr;
421         u8      *pTA;
422         u8      *pRecvPN;
423
424
425         WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
426
427         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
428                 WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
429                 return;
430         }
431
432         precv_hdr = &precv_frame->u.hdr;
433         ptr = precv_hdr->rx_data;
434
435         if (precv_hdr->attrib.qos == 1)
436                 precv_hdr->UserPriority = GetTid(ptr);
437         else
438                 precv_hdr->UserPriority = 0;
439
440         pTA = get_addr2_ptr(ptr);
441         _rtw_memcpy((u8 *)precv_hdr->WapiSrcAddr, pTA, 6);
442         pRecvPN = ptr + precv_hdr->attrib.hdrlen + 2;
443         _rtw_memcpy((u8 *)precv_hdr->WapiTempPN, pRecvPN, 16);
444
445         WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
446 }
447
448 /****************************************************************************
449 TRUE-----------------Drop
450 FALSE---------------- handle
451 add to support WAPI to N-mode
452 *****************************************************************************/
453 u8 rtw_wapi_check_for_drop(
454         _adapter *padapter,
455         union recv_frame *precv_frame,
456         u8 *ehdr_ops
457 )
458 {
459         PRT_WAPI_T     pWapiInfo = &(padapter->wapiInfo);
460         u8                      *pLastRecvPN = NULL;
461         u8                      bFind = false;
462         PRT_WAPI_STA_INFO       pWapiSta = NULL;
463         u8                      bDrop = false;
464         struct recv_frame_hdr *precv_hdr = &precv_frame->u.hdr;
465         u8                                      WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
466         u8                                      WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
467         u8                                      *ptr = ehdr_ops;
468         int                                     i;
469
470         WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
471
472         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
473                 WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
474                 return false;
475         }
476
477         if (precv_hdr->bIsWaiPacket != 0) {
478                 if (precv_hdr->bIsWaiPacket == 0x8) {
479
480                         RTW_INFO("rtw_wapi_check_for_drop: dump packet\n");
481                         for (i = 0; i < 50; i++) {
482                                 RTW_INFO("%02X  ", ptr[i]);
483                                 if ((i + 1) % 8 == 0)
484                                         RTW_INFO("\n");
485                         }
486                         RTW_INFO("\n rtw_wapi_check_for_drop: dump packet\n");
487
488                         for (i = 0; i < 16; i++) {
489                                 if (ptr[i + 27] != 0)
490                                         break;
491                         }
492
493                         if (i == 16) {
494                                 WAPI_TRACE(WAPI_RX, "rtw_wapi_check_for_drop: drop with zero BKID\n");
495                                 return true;
496                         } else
497                                 return false;
498                 } else
499                         return false;
500         }
501
502         if (list_empty(&pWapiInfo->wapiSTAUsedList))
503                 bFind = false;
504         else {
505                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
506                         if (_rtw_memcmp(precv_hdr->WapiSrcAddr, pWapiSta->PeerMacAddr, ETH_ALEN) == _TRUE) {
507                                 bFind = true;
508                                 break;
509                         }
510                 }
511         }
512         WAPI_TRACE(WAPI_RX, "%s: bFind=%d prxb->WapiSrcAddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(precv_hdr->WapiSrcAddr));
513
514         if (bFind) {
515                 if (IS_MCAST(precv_hdr->attrib.ra)) {
516                         WAPI_TRACE(WAPI_RX, "rtw_wapi_check_for_drop: multicast case\n");
517                         pLastRecvPN = pWapiSta->lastRxMulticastPN;
518                 } else {
519                         WAPI_TRACE(WAPI_RX, "rtw_wapi_check_for_drop: unicast case\n");
520                         switch (precv_hdr->UserPriority) {
521                         case 0:
522                         case 3:
523                                 pLastRecvPN = pWapiSta->lastRxUnicastPNBEQueue;
524                                 break;
525                         case 1:
526                         case 2:
527                                 pLastRecvPN = pWapiSta->lastRxUnicastPNBKQueue;
528                                 break;
529                         case 4:
530                         case 5:
531                                 pLastRecvPN = pWapiSta->lastRxUnicastPNVIQueue;
532                                 break;
533                         case 6:
534                         case 7:
535                                 pLastRecvPN = pWapiSta->lastRxUnicastPNVOQueue;
536                                 break;
537                         default:
538                                 WAPI_TRACE(WAPI_ERR, "%s: Unknown TID\n", __FUNCTION__);
539                                 break;
540                         }
541                 }
542
543                 if (!WapiComparePN(precv_hdr->WapiTempPN, pLastRecvPN)) {
544                         WAPI_TRACE(WAPI_RX, "%s: Equal PN!!\n", __FUNCTION__);
545                         if (IS_MCAST(precv_hdr->attrib.ra))
546                                 _rtw_memcpy(pLastRecvPN, WapiAEMultiCastPNInitialValueSrc, 16);
547                         else
548                                 _rtw_memcpy(pLastRecvPN, WapiAEPNInitialValueSrc, 16);
549                         bDrop = true;
550                 } else
551                         _rtw_memcpy(pLastRecvPN, precv_hdr->WapiTempPN, 16);
552         }
553
554         WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
555         return bDrop;
556 }
557
558 void rtw_build_probe_resp_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
559 {
560         PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
561         u8 WapiIELength = 0;
562
563         WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
564
565         if ((!padapter->WapiSupport)  || (!pWapiInfo->bWapiEnable)) {
566                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
567                 return;
568         }
569
570         WapiSetIE(padapter);
571         WapiIELength = pWapiInfo->wapiIELength;
572         pframe[0] = _WAPI_IE_;
573         pframe[1] = WapiIELength;
574         _rtw_memcpy(pframe + 2, pWapiInfo->wapiIE, WapiIELength);
575         pframe += WapiIELength + 2;
576         pattrib->pktlen += WapiIELength + 2;
577
578         WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
579 }
580
581 void rtw_build_beacon_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
582 {
583         PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
584         u8 WapiIELength = 0;
585         WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
586
587         if ((!padapter->WapiSupport)  || (!pWapiInfo->bWapiEnable)) {
588                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
589                 return;
590         }
591
592         WapiSetIE(padapter);
593         WapiIELength = pWapiInfo->wapiIELength;
594         pframe[0] = _WAPI_IE_;
595         pframe[1] = WapiIELength;
596         _rtw_memcpy(pframe + 2, pWapiInfo->wapiIE, WapiIELength);
597         pframe += WapiIELength + 2;
598         pattrib->pktlen += WapiIELength + 2;
599
600         WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
601 }
602
603 void rtw_build_assoc_req_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
604 {
605         PRT_WAPI_BKID           pWapiBKID;
606         u16                                     bkidNum;
607         PRT_WAPI_T                      pWapiInfo = &(padapter->wapiInfo);
608         u8                                      WapiIELength = 0;
609
610         WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
611
612         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
613                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
614                 return;
615         }
616
617         WapiSetIE(padapter);
618         WapiIELength = pWapiInfo->wapiIELength;
619         bkidNum = 0;
620         if (!list_empty(&(pWapiInfo->wapiBKIDStoreList))) {
621                 list_for_each_entry(pWapiBKID, &pWapiInfo->wapiBKIDStoreList, list) {
622                         bkidNum++;
623                         _rtw_memcpy(pWapiInfo->wapiIE + WapiIELength + 2, pWapiBKID->bkid, 16);
624                         WapiIELength += 16;
625                 }
626         }
627         _rtw_memcpy(pWapiInfo->wapiIE + WapiIELength, &bkidNum, 2);
628         WapiIELength += 2;
629
630         pframe[0] = _WAPI_IE_;
631         pframe[1] = WapiIELength;
632         _rtw_memcpy(pframe + 2, pWapiInfo->wapiIE, WapiIELength);
633         pframe += WapiIELength + 2;
634         pattrib->pktlen += WapiIELength + 2;
635         WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
636 }
637
638 void rtw_wapi_on_assoc_ok(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
639 {
640         PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
641         PRT_WAPI_STA_INFO pWapiSta;
642         u8 WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
643         /* u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; */
644         u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
645
646         WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
647
648         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
649                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
650                 return;
651         }
652
653         pWapiSta = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
654         list_del_init(&pWapiSta->list);
655         list_add_tail(&pWapiSta->list, &pWapiInfo->wapiSTAUsedList);
656         _rtw_memcpy(pWapiSta->PeerMacAddr, padapter->mlmeextpriv.mlmext_info.network.MacAddress, 6);
657         _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
658         _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
659
660         /* For chenk PN error with Qos Data after s3: add by ylb 20111114 */
661         _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiAEPNInitialValueSrc, 16);
662         _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiAEPNInitialValueSrc, 16);
663         _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiAEPNInitialValueSrc, 16);
664         _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiAEPNInitialValueSrc, 16);
665
666         WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
667 }
668
669
670 void rtw_wapi_return_one_sta_info(_adapter *padapter, u8 *MacAddr)
671 {
672         PRT_WAPI_T                              pWapiInfo;
673         PRT_WAPI_STA_INFO               pWapiStaInfo = NULL;
674         PRT_WAPI_BKID                   pWapiBkid = NULL;
675         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
676
677         pWapiInfo = &padapter->wapiInfo;
678
679         WAPI_TRACE(WAPI_API, "==========> %s\n", __FUNCTION__);
680
681         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
682                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
683                 return;
684         }
685
686         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
687                 while (!list_empty(&(pWapiInfo->wapiBKIDStoreList))) {
688                         pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
689                         list_del_init(&pWapiBkid->list);
690                         _rtw_memset(pWapiBkid->bkid, 0, 16);
691                         list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
692                 }
693         }
694
695
696         WAPI_TRACE(WAPI_API, " %s: after clear bkid\n", __FUNCTION__);
697
698
699         /* Remove STA info */
700         if (list_empty(&(pWapiInfo->wapiSTAUsedList))) {
701                 WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is null\n", __FUNCTION__);
702                 return;
703         } else {
704
705                 WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is not null\n", __FUNCTION__);
706 #if 0
707                 pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry((pWapiInfo->wapiSTAUsedList.next), RT_WAPI_STA_INFO, list);
708
709                 list_for_each_entry(pWapiStaInfo, &(pWapiInfo->wapiSTAUsedList), list) {
710
711                         RTW_INFO("MAC Addr %02x-%02x-%02x-%02x-%02x-%02x\n", MacAddr[0], MacAddr[1], MacAddr[2], MacAddr[3], MacAddr[4], MacAddr[5]);
712
713
714                         RTW_INFO("peer Addr %02x-%02x-%02x-%02x-%02x-%02x\n", pWapiStaInfo->PeerMacAddr[0], pWapiStaInfo->PeerMacAddr[1], pWapiStaInfo->PeerMacAddr[2], pWapiStaInfo->PeerMacAddr[3],
715                                 pWapiStaInfo->PeerMacAddr[4], pWapiStaInfo->PeerMacAddr[5]);
716
717                         if (pWapiStaInfo == NULL) {
718                                 WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo == NULL Case\n", __FUNCTION__);
719                                 return;
720                         }
721
722                         if (pWapiStaInfo->PeerMacAddr == NULL) {
723                                 WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo->PeerMacAddr == NULL Case\n", __FUNCTION__);
724                                 return;
725                         }
726
727                         if (MacAddr == NULL) {
728                                 WAPI_TRACE(WAPI_API, " %s: MacAddr == NULL Case\n", __FUNCTION__);
729                                 return;
730                         }
731
732                         if (_rtw_memcmp(pWapiStaInfo->PeerMacAddr, MacAddr, ETH_ALEN) == _TRUE) {
733                                 pWapiStaInfo->bAuthenticateInProgress = false;
734                                 pWapiStaInfo->bSetkeyOk = false;
735                                 _rtw_memset(pWapiStaInfo->PeerMacAddr, 0, ETH_ALEN);
736                                 list_del_init(&pWapiStaInfo->list);
737                                 list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
738                                 break;
739                         }
740
741                 }
742 #endif
743
744                 while (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
745                         pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
746
747                         RTW_INFO("peer Addr %02x-%02x-%02x-%02x-%02x-%02x\n", pWapiStaInfo->PeerMacAddr[0], pWapiStaInfo->PeerMacAddr[1], pWapiStaInfo->PeerMacAddr[2], pWapiStaInfo->PeerMacAddr[3],
748                                 pWapiStaInfo->PeerMacAddr[4], pWapiStaInfo->PeerMacAddr[5]);
749
750                         list_del_init(&pWapiStaInfo->list);
751                         memset(pWapiStaInfo->PeerMacAddr, 0, ETH_ALEN);
752                         pWapiStaInfo->bSetkeyOk = 0;
753                         list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
754                 }
755
756         }
757
758         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
759         return;
760 }
761
762 void rtw_wapi_return_all_sta_info(_adapter *padapter)
763 {
764         PRT_WAPI_T                              pWapiInfo;
765         PRT_WAPI_STA_INFO               pWapiStaInfo;
766         PRT_WAPI_BKID                   pWapiBkid;
767         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
768
769         pWapiInfo = &padapter->wapiInfo;
770
771         if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) {
772                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
773                 return;
774         }
775
776         /* Sta Info List */
777         while (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
778                 pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
779                 list_del_init(&pWapiStaInfo->list);
780                 memset(pWapiStaInfo->PeerMacAddr, 0, ETH_ALEN);
781                 pWapiStaInfo->bSetkeyOk = 0;
782                 list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
783         }
784
785         /* BKID List */
786         while (!list_empty(&(pWapiInfo->wapiBKIDStoreList))) {
787                 pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
788                 list_del_init(&pWapiBkid->list);
789                 memset(pWapiBkid->bkid, 0, 16);
790                 list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
791         }
792         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
793 }
794
795 void rtw_wapi_clear_cam_entry(_adapter *padapter, u8 *pMacAddr)
796 {
797         u8 UcIndex = 0;
798
799         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
800
801         if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
802                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
803                 return;
804         }
805
806         UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 0);
807         if (UcIndex != 0xff) {
808                 /* CAM_mark_invalid(Adapter, UcIndex); */
809                 CAM_empty_entry(padapter, UcIndex);
810         }
811
812         UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 0);
813         if (UcIndex != 0xff) {
814                 /* CAM_mark_invalid(Adapter, UcIndex); */
815                 CAM_empty_entry(padapter, UcIndex);
816         }
817
818         UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 1);
819         if (UcIndex != 0xff) {
820                 /* CAM_mark_invalid(Adapter, UcIndex); */
821                 CAM_empty_entry(padapter, UcIndex);
822         }
823
824         UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 1);
825         if (UcIndex != 0xff) {
826                 /* CAM_mark_invalid(padapter, UcIndex); */
827                 CAM_empty_entry(padapter, UcIndex);
828         }
829
830         WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
831 }
832
833 void rtw_wapi_clear_all_cam_entry(_adapter *padapter)
834 {
835         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
836
837         if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
838                 WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
839                 return;
840         }
841
842         invalidate_cam_all(padapter); /* is this ok? */
843         WapiResetAllCamEntry(padapter);
844
845         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
846 }
847
848 void rtw_wapi_set_key(_adapter *padapter, RT_WAPI_KEY *pWapiKey, RT_WAPI_STA_INFO *pWapiSta, u8 bGroupKey, u8 bUseDefaultKey)
849 {
850         PRT_WAPI_T              pWapiInfo =  &padapter->wapiInfo;
851         u8                              *pMacAddr = pWapiSta->PeerMacAddr;
852         u32 EntryId = 0;
853         BOOLEAN IsPairWise = false ;
854         u8 EncAlgo;
855
856         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
857
858         if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
859                 WAPI_TRACE(WAPI_API, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
860                 return;
861         }
862
863         EncAlgo = _SMS4_;
864
865         /* For Tx bc/mc pkt,use defualt key entry */
866         if (bUseDefaultKey) {
867                 /* when WAPI update key, keyid will be 0 or 1 by turns. */
868                 if (pWapiKey->keyId == 0)
869                         EntryId = 0;
870                 else
871                         EntryId = 2;
872         } else {
873                 /* tx/rx unicast pkt, or rx broadcast, find the key entry by peer's MacAddr */
874                 EntryId = WapiGetEntryForCamWrite(padapter, pMacAddr, pWapiKey->keyId, bGroupKey);
875         }
876
877         if (EntryId == 0xff) {
878                 WAPI_TRACE(WAPI_API, "===>No entry for WAPI setkey! !!\n");
879                 return;
880         }
881
882         /* EntryId is also used to diff Sec key and Mic key */
883         /* Sec Key */
884         WapiWriteOneCamEntry(padapter,
885                              pMacAddr,
886                              pWapiKey->keyId, /* keyid */
887                              EntryId,   /* entry */
888                              EncAlgo, /* type */
889                              bGroupKey, /* pairwise or group key */
890                              pWapiKey->dataKey);
891         /* MIC key */
892         WapiWriteOneCamEntry(padapter,
893                              pMacAddr,
894                              pWapiKey->keyId, /* keyid */
895                              EntryId + 1,       /* entry */
896                              EncAlgo, /* type */
897                              bGroupKey, /* pairwise or group key */
898                              pWapiKey->micKey);
899
900         WAPI_TRACE(WAPI_API, "Set Wapi Key :KeyId:%d,EntryId:%d,PairwiseKey:%d.\n", pWapiKey->keyId, EntryId, !bGroupKey);
901         WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
902
903 }
904
905 #if 0
906 /* YJ,test,091013 */
907 void wapi_test_set_key(struct _adapter *padapter, u8 *buf)
908 {
909         /*Data: keyType(1) + bTxEnable(1) + bAuthenticator(1) + bUpdate(1) + PeerAddr(6) + DataKey(16) + MicKey(16) + KeyId(1)*/
910         PRT_WAPI_T                      pWapiInfo = &padapter->wapiInfo;
911         PRT_WAPI_BKID           pWapiBkid;
912         PRT_WAPI_STA_INFO       pWapiSta;
913         u8                                      data[43];
914         bool                                    bTxEnable;
915         bool                                    bUpdate;
916         bool                                    bAuthenticator;
917         u8                                      PeerAddr[6];
918         u8                                      WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
919         u8                                      WapiASUEPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
920         u8                                      WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
921
922         WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
923
924         if (!padapter->WapiSupport)
925                 return;
926
927         copy_from_user(data, buf, 43);
928         bTxEnable = data[1];
929         bAuthenticator = data[2];
930         bUpdate = data[3];
931         memcpy(PeerAddr, data + 4, 6);
932
933         if (data[0] == 0x3) {
934                 if (!list_empty(&(pWapiInfo->wapiBKIDIdleList))) {
935                         pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
936                         list_del_init(&pWapiBkid->list);
937                         memcpy(pWapiBkid->bkid, data + 10, 16);
938                         WAPI_DATA(WAPI_INIT, "SetKey - BKID", pWapiBkid->bkid, 16);
939                         list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDStoreList);
940                 }
941         } else {
942                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
943                         if (!memcmp(pWapiSta->PeerMacAddr, PeerAddr, 6)) {
944                                 pWapiSta->bAuthenticatorInUpdata = false;
945                                 switch (data[0]) {
946                                 case 1:              /* usk */
947                                         if (bAuthenticator) {       /* authenticator */
948                                                 memcpy(pWapiSta->lastTxUnicastPN, WapiAEPNInitialValueSrc, 16);
949                                                 if (!bUpdate) {    /* first */
950                                                         WAPI_TRACE(WAPI_INIT, "AE fisrt set usk\n");
951                                                         pWapiSta->wapiUsk.bSet = true;
952                                                         memcpy(pWapiSta->wapiUsk.dataKey, data + 10, 16);
953                                                         memcpy(pWapiSta->wapiUsk.micKey, data + 26, 16);
954                                                         pWapiSta->wapiUsk.keyId = *(data + 42);
955                                                         pWapiSta->wapiUsk.bTxEnable = true;
956                                                         WAPI_DATA(WAPI_INIT, "SetKey - AE USK Data Key", pWapiSta->wapiUsk.dataKey, 16);
957                                                         WAPI_DATA(WAPI_INIT, "SetKey - AE USK Mic Key", pWapiSta->wapiUsk.micKey, 16);
958                                                 } else {           /* update */
959                                                         WAPI_TRACE(WAPI_INIT, "AE update usk\n");
960                                                         pWapiSta->wapiUskUpdate.bSet = true;
961                                                         pWapiSta->bAuthenticatorInUpdata = true;
962                                                         memcpy(pWapiSta->wapiUskUpdate.dataKey, data + 10, 16);
963                                                         memcpy(pWapiSta->wapiUskUpdate.micKey, data + 26, 16);
964                                                         memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiASUEPNInitialValueSrc, 16);
965                                                         memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiASUEPNInitialValueSrc, 16);
966                                                         memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiASUEPNInitialValueSrc, 16);
967                                                         memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiASUEPNInitialValueSrc, 16);
968                                                         memcpy(pWapiSta->lastRxUnicastPN, WapiASUEPNInitialValueSrc, 16);
969                                                         pWapiSta->wapiUskUpdate.keyId = *(data + 42);
970                                                         pWapiSta->wapiUskUpdate.bTxEnable = true;
971                                                 }
972                                         } else {
973                                                 if (!bUpdate) {
974                                                         WAPI_TRACE(WAPI_INIT, "ASUE fisrt set usk\n");
975                                                         if (bTxEnable) {
976                                                                 pWapiSta->wapiUsk.bTxEnable = true;
977                                                                 memcpy(pWapiSta->lastTxUnicastPN, WapiASUEPNInitialValueSrc, 16);
978                                                         } else {
979                                                                 pWapiSta->wapiUsk.bSet = true;
980                                                                 memcpy(pWapiSta->wapiUsk.dataKey, data + 10, 16);
981                                                                 memcpy(pWapiSta->wapiUsk.micKey, data + 26, 16);
982                                                                 pWapiSta->wapiUsk.keyId = *(data + 42);
983                                                                 pWapiSta->wapiUsk.bTxEnable = false;
984                                                         }
985                                                 } else {
986                                                         WAPI_TRACE(WAPI_INIT, "ASUE update usk\n");
987                                                         if (bTxEnable) {
988                                                                 pWapiSta->wapiUskUpdate.bTxEnable = true;
989                                                                 if (pWapiSta->wapiUskUpdate.bSet) {
990                                                                         memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16);
991                                                                         memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16);
992                                                                         pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId;
993                                                                         memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiASUEPNInitialValueSrc, 16);
994                                                                         memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiASUEPNInitialValueSrc, 16);
995                                                                         memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiASUEPNInitialValueSrc, 16);
996                                                                         memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiASUEPNInitialValueSrc, 16);
997                                                                         memcpy(pWapiSta->lastRxUnicastPN, WapiASUEPNInitialValueSrc, 16);
998                                                                         pWapiSta->wapiUskUpdate.bTxEnable = false;
999                                                                         pWapiSta->wapiUskUpdate.bSet = false;
1000                                                                 }
1001                                                                 memcpy(pWapiSta->lastTxUnicastPN, WapiASUEPNInitialValueSrc, 16);
1002                                                         } else {
1003                                                                 pWapiSta->wapiUskUpdate.bSet = true;
1004                                                                 memcpy(pWapiSta->wapiUskUpdate.dataKey, data + 10, 16);
1005                                                                 memcpy(pWapiSta->wapiUskUpdate.micKey, data + 26, 16);
1006                                                                 pWapiSta->wapiUskUpdate.keyId = *(data + 42);
1007                                                                 pWapiSta->wapiUskUpdate.bTxEnable = false;
1008                                                         }
1009                                                 }
1010                                         }
1011                                         break;
1012                                 case 2:         /* msk */
1013                                         if (bAuthenticator) {        /* authenticator */
1014                                                 pWapiInfo->wapiTxMsk.bSet = true;
1015                                                 memcpy(pWapiInfo->wapiTxMsk.dataKey, data + 10, 16);
1016                                                 memcpy(pWapiInfo->wapiTxMsk.micKey, data + 26, 16);
1017                                                 pWapiInfo->wapiTxMsk.keyId = *(data + 42);
1018                                                 pWapiInfo->wapiTxMsk.bTxEnable = true;
1019                                                 memcpy(pWapiInfo->lastTxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1020
1021                                                 if (!bUpdate) {    /* first */
1022                                                         WAPI_TRACE(WAPI_INIT, "AE fisrt set msk\n");
1023                                                         if (!pWapiSta->bSetkeyOk)
1024                                                                 pWapiSta->bSetkeyOk = true;
1025                                                         pWapiInfo->bFirstAuthentiateInProgress = false;
1026                                                 } else                /* update */
1027                                                         WAPI_TRACE(WAPI_INIT, "AE update msk\n");
1028
1029                                                 WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Data Key", pWapiInfo->wapiTxMsk.dataKey, 16);
1030                                                 WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Mic Key", pWapiInfo->wapiTxMsk.micKey, 16);
1031                                         } else {
1032                                                 if (!bUpdate) {
1033                                                         WAPI_TRACE(WAPI_INIT, "ASUE fisrt set msk\n");
1034                                                         pWapiSta->wapiMsk.bSet = true;
1035                                                         memcpy(pWapiSta->wapiMsk.dataKey, data + 10, 16);
1036                                                         memcpy(pWapiSta->wapiMsk.micKey, data + 26, 16);
1037                                                         pWapiSta->wapiMsk.keyId = *(data + 42);
1038                                                         pWapiSta->wapiMsk.bTxEnable = false;
1039                                                         if (!pWapiSta->bSetkeyOk)
1040                                                                 pWapiSta->bSetkeyOk = true;
1041                                                         pWapiInfo->bFirstAuthentiateInProgress = false;
1042                                                         WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Data Key", pWapiSta->wapiMsk.dataKey, 16);
1043                                                         WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Mic Key", pWapiSta->wapiMsk.micKey, 16);
1044                                                 } else {
1045                                                         WAPI_TRACE(WAPI_INIT, "ASUE update msk\n");
1046                                                         pWapiSta->wapiMskUpdate.bSet = true;
1047                                                         memcpy(pWapiSta->wapiMskUpdate.dataKey, data + 10, 16);
1048                                                         memcpy(pWapiSta->wapiMskUpdate.micKey, data + 26, 16);
1049                                                         pWapiSta->wapiMskUpdate.keyId = *(data + 42);
1050                                                         pWapiSta->wapiMskUpdate.bTxEnable = false;
1051                                                 }
1052                                         }
1053                                         break;
1054                                 default:
1055                                         WAPI_TRACE(WAPI_ERR, "Unknown Flag\n");
1056                                         break;
1057                                 }
1058                         }
1059                 }
1060         }
1061         WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
1062 }
1063
1064
1065 void wapi_test_init(struct _adapter *padapter)
1066 {
1067         u8 keybuf[100];
1068         u8 mac_addr[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x72, 0x04, 0x70};
1069         u8 UskDataKey[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
1070         u8 UskMicKey[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
1071         u8 UskId = 0;
1072         u8 MskDataKey[16] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f};
1073         u8 MskMicKey[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
1074         u8 MskId = 0;
1075
1076         WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
1077
1078         /* Enable Wapi */
1079         WAPI_TRACE(WAPI_INIT, "%s: Enable wapi!!!!\n", __FUNCTION__);
1080         padapter->wapiInfo.bWapiEnable = true;
1081         padapter->pairwise_key_type = KEY_TYPE_SMS4;
1082         ieee->group_key_type = KEY_TYPE_SMS4;
1083         padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
1084         padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
1085
1086         /* set usk */
1087         WAPI_TRACE(WAPI_INIT, "%s: Set USK!!!!\n", __FUNCTION__);
1088         memset(keybuf, 0, 100);
1089         keybuf[0] = 1;                           /* set usk */
1090         keybuf[1] = 1;                          /* enable tx */
1091         keybuf[2] = 1;                          /* AE */
1092         keybuf[3] = 0;                          /* not update */
1093
1094         memcpy(keybuf + 4, mac_addr, ETH_ALEN);
1095         memcpy(keybuf + 10, UskDataKey, 16);
1096         memcpy(keybuf + 26, UskMicKey, 16);
1097         keybuf[42] = UskId;
1098         wapi_test_set_key(padapter, keybuf);
1099
1100         memset(keybuf, 0, 100);
1101         keybuf[0] = 1;                           /* set usk */
1102         keybuf[1] = 1;                          /* enable tx */
1103         keybuf[2] = 0;                          /* AE */
1104         keybuf[3] = 0;                          /* not update */
1105
1106         memcpy(keybuf + 4, mac_addr, ETH_ALEN);
1107         memcpy(keybuf + 10, UskDataKey, 16);
1108         memcpy(keybuf + 26, UskMicKey, 16);
1109         keybuf[42] = UskId;
1110         wapi_test_set_key(padapter, keybuf);
1111
1112         /* set msk */
1113         WAPI_TRACE(WAPI_INIT, "%s: Set MSK!!!!\n", __FUNCTION__);
1114         memset(keybuf, 0, 100);
1115         keybuf[0] = 2;                                /* set msk */
1116         keybuf[1] = 1;                               /* Enable TX */
1117         keybuf[2] = 1;                          /* AE */
1118         keybuf[3] = 0;                              /* not update */
1119         memcpy(keybuf + 4, mac_addr, ETH_ALEN);
1120         memcpy(keybuf + 10, MskDataKey, 16);
1121         memcpy(keybuf + 26, MskMicKey, 16);
1122         keybuf[42] = MskId;
1123         wapi_test_set_key(padapter, keybuf);
1124
1125         memset(keybuf, 0, 100);
1126         keybuf[0] = 2;                                /* set msk */
1127         keybuf[1] = 1;                               /* Enable TX */
1128         keybuf[2] = 0;                          /* AE */
1129         keybuf[3] = 0;                              /* not update */
1130         memcpy(keybuf + 4, mac_addr, ETH_ALEN);
1131         memcpy(keybuf + 10, MskDataKey, 16);
1132         memcpy(keybuf + 26, MskMicKey, 16);
1133         keybuf[42] = MskId;
1134         wapi_test_set_key(padapter, keybuf);
1135         WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
1136 }
1137 #endif
1138
1139 void rtw_wapi_get_iv(_adapter *padapter, u8 *pRA, u8 *IV)
1140 {
1141         PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
1142         PRT_WAPI_T         pWapiInfo = &padapter->wapiInfo;
1143         bool    bPNOverflow = false;
1144         bool    bFindMatchPeer = false;
1145         PRT_WAPI_STA_INFO  pWapiSta = NULL;
1146
1147         pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)IV;
1148
1149         WAPI_DATA(WAPI_RX, "wapi_get_iv: pra", pRA, 6);
1150
1151         if (IS_MCAST(pRA)) {
1152                 if (!pWapiInfo->wapiTxMsk.bTxEnable) {
1153                         WAPI_TRACE(WAPI_ERR, "%s: bTxEnable = 0!!\n", __FUNCTION__);
1154                         return;
1155                 }
1156
1157                 if (pWapiInfo->wapiTxMsk.keyId <= 1) {
1158                         pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
1159                         pWapiExt->Reserved = 0;
1160                         bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
1161                         memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
1162                 }
1163         } else {
1164                 if (list_empty(&pWapiInfo->wapiSTAUsedList)) {
1165                         WAPI_TRACE(WAPI_RX, "rtw_wapi_get_iv: list is empty\n");
1166                         _rtw_memset(IV, 10, 18);
1167                         return;
1168                 } else {
1169                         list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1170                                 WAPI_DATA(WAPI_RX, "rtw_wapi_get_iv: peermacaddr ", pWapiSta->PeerMacAddr, 6);
1171                                 if (_rtw_memcmp((u8 *)pWapiSta->PeerMacAddr, pRA, 6) == _TRUE) {
1172                                         bFindMatchPeer = true;
1173                                         break;
1174                                 }
1175                         }
1176
1177                         WAPI_TRACE(WAPI_RX, "bFindMatchPeer: %d\n", bFindMatchPeer);
1178                         WAPI_DATA(WAPI_RX, "Addr", pRA, 6);
1179
1180                         if (bFindMatchPeer) {
1181                                 if ((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable))
1182                                         return;
1183
1184                                 if (pWapiSta->wapiUsk.keyId <= 1) {
1185                                         if (pWapiSta->wapiUskUpdate.bTxEnable)
1186                                                 pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
1187                                         else
1188                                                 pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
1189
1190                                         pWapiExt->Reserved = 0;
1191                                         bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
1192                                         _rtw_memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
1193
1194                                 }
1195                         }
1196                 }
1197
1198         }
1199
1200 }
1201
1202 bool rtw_wapi_drop_for_key_absent(_adapter *padapter, u8 *pRA)
1203 {
1204         PRT_WAPI_T         pWapiInfo = &padapter->wapiInfo;
1205         bool                            bFindMatchPeer = false;
1206         bool                            bDrop = false;
1207         PRT_WAPI_STA_INFO  pWapiSta = NULL;
1208         struct security_priv            *psecuritypriv = &padapter->securitypriv;
1209
1210         WAPI_DATA(WAPI_RX, "rtw_wapi_drop_for_key_absent: ra ", pRA, 6);
1211
1212         if (psecuritypriv->dot11PrivacyAlgrthm == _SMS4_) {
1213                 if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
1214                         return true;
1215
1216                 if (IS_MCAST(pRA)) {
1217                         if (!pWapiInfo->wapiTxMsk.bTxEnable) {
1218                                 bDrop = true;
1219                                 WAPI_TRACE(WAPI_RX, "rtw_wapi_drop_for_key_absent: multicast key is absent\n");
1220                                 return bDrop;
1221                         }
1222                 } else {
1223                         if (!list_empty(&pWapiInfo->wapiSTAUsedList)) {
1224                                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1225                                         WAPI_DATA(WAPI_RX, "rtw_wapi_drop_for_key_absent: pWapiSta->PeerMacAddr ", pWapiSta->PeerMacAddr, 6);
1226                                         if (_rtw_memcmp(pRA, pWapiSta->PeerMacAddr, 6) == _TRUE) {
1227                                                 bFindMatchPeer = true;
1228                                                 break;
1229                                         }
1230                                 }
1231                                 if (bFindMatchPeer)     {
1232                                         if (!pWapiSta->wapiUsk.bTxEnable) {
1233                                                 bDrop = true;
1234                                                 WAPI_TRACE(WAPI_RX, "rtw_wapi_drop_for_key_absent: unicast key is absent\n");
1235                                                 return bDrop;
1236                                         }
1237                                 } else {
1238                                         bDrop = true;
1239                                         WAPI_TRACE(WAPI_RX, "rtw_wapi_drop_for_key_absent: no peer find\n");
1240                                         return bDrop;
1241                                 }
1242
1243                         } else {
1244                                 bDrop = true;
1245                                 WAPI_TRACE(WAPI_RX, "rtw_wapi_drop_for_key_absent: no sta  exist\n");
1246                                 return bDrop;
1247                         }
1248                 }
1249         } else
1250                 return bDrop;
1251
1252         return bDrop;
1253 }
1254
1255 void rtw_wapi_set_set_encryption(_adapter *padapter, struct ieee_param *param)
1256 {
1257         struct security_priv *psecuritypriv = &padapter->securitypriv;
1258         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1259         PRT_WAPI_T                      pWapiInfo = &padapter->wapiInfo;
1260         PRT_WAPI_STA_INFO       pWapiSta;
1261         u8                                      WapiASUEPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1262         u8                                      WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1263         u8                                      WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1264
1265         if (param->u.crypt.set_tx == 1) {
1266                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1267                         if (_rtw_memcmp(pWapiSta->PeerMacAddr, param->sta_addr, 6)) {
1268                                 _rtw_memcpy(pWapiSta->lastTxUnicastPN, WapiASUEPNInitialValueSrc, 16);
1269
1270                                 pWapiSta->wapiUsk.bSet = true;
1271                                 _rtw_memcpy(pWapiSta->wapiUsk.dataKey, param->u.crypt.key, 16);
1272                                 _rtw_memcpy(pWapiSta->wapiUsk.micKey, param->u.crypt.key + 16, 16);
1273                                 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1274                                 pWapiSta->wapiUsk.bTxEnable = true;
1275
1276                                 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiAEPNInitialValueSrc, 16);
1277                                 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiAEPNInitialValueSrc, 16);
1278                                 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiAEPNInitialValueSrc, 16);
1279                                 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiAEPNInitialValueSrc, 16);
1280                                 _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
1281                                 pWapiSta->wapiUskUpdate.bTxEnable = false;
1282                                 pWapiSta->wapiUskUpdate.bSet = false;
1283
1284                                 if (psecuritypriv->sw_encrypt == false || psecuritypriv->sw_decrypt == false) {
1285                                         /* set unicast key for ASUE */
1286                                         rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1287                                 }
1288                         }
1289                 }
1290         } else {
1291                 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1292                         if (_rtw_memcmp(pWapiSta->PeerMacAddr, get_bssid(pmlmepriv), 6)) {
1293                                 pWapiSta->wapiMsk.bSet = true;
1294                                 _rtw_memcpy(pWapiSta->wapiMsk.dataKey, param->u.crypt.key, 16);
1295                                 _rtw_memcpy(pWapiSta->wapiMsk.micKey, param->u.crypt.key + 16, 16);
1296                                 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1297                                 pWapiSta->wapiMsk.bTxEnable = false;
1298                                 if (!pWapiSta->bSetkeyOk)
1299                                         pWapiSta->bSetkeyOk = true;
1300                                 pWapiSta->bAuthenticateInProgress = false;
1301
1302                                 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1303
1304                                 if (psecuritypriv->sw_decrypt == false) {
1305                                         /* set rx broadcast key for ASUE */
1306                                         rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1307                                 }
1308                         }
1309                 }
1310         }
1311 }
1312 #endif