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