Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / staging / vt6656 / key.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: key.c
21  *
22  * Purpose: Implement functions for 802.11i Key management
23  *
24  * Author: Jerry Chen
25  *
26  * Date: May 29, 2003
27  *
28  * Functions:
29  *      KeyvInitTable - Init Key management table
30  *      KeybGetKey - Get Key from table
31  *      KeybSetKey - Set Key to table
32  *      KeybRemoveKey - Remove Key from table
33  *      KeybGetTransmitKey - Get Transmit Key from table
34  *
35  * Revision History:
36  *
37  */
38
39 #include "mac.h"
40 #include "tmacro.h"
41 #include "key.h"
42 #include "usbpipe.h"
43
44 static int          msglevel                =MSG_LEVEL_INFO;
45 //static int          msglevel                =MSG_LEVEL_DEBUG;
46
47 static void s_vCheckKeyTableValid(struct vnt_private *pDevice,
48         PSKeyManagement pTable)
49 {
50         int i;
51         u16 wLength = 0;
52         u8 pbyData[MAX_KEY_TABLE];
53
54     for (i=0;i<MAX_KEY_TABLE;i++) {
55         if ((pTable->KeyTable[i].bInUse == true) &&
56             (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
57             (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
58             (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
59             (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
60             (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
61             ) {
62
63             pTable->KeyTable[i].bInUse = false;
64             pTable->KeyTable[i].wKeyCtl = 0;
65             pTable->KeyTable[i].bSoftWEP = false;
66             pbyData[wLength++] = (u8) i;
67             //MACvDisableKeyEntry(pDevice, i);
68         }
69     }
70
71         if (wLength != 0)
72                 vnt_control_out(pDevice, MESSAGE_TYPE_CLRKEYENTRY,
73                         0, 0, wLength, pbyData);
74
75 }
76
77 /*
78  * Description: Init Key management table
79  *
80  * Parameters:
81  *  In:
82  *      pTable          - Pointer to Key table
83  *  Out:
84  *      none
85  *
86  * Return Value: none
87  *
88  */
89 void KeyvInitTable(struct vnt_private *pDevice, PSKeyManagement pTable)
90 {
91         int i, jj;
92         u8 pbyData[MAX_KEY_TABLE+1];
93
94     for (i=0;i<MAX_KEY_TABLE;i++) {
95         pTable->KeyTable[i].bInUse = false;
96         pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
97         pTable->KeyTable[i].PairwiseKey.pvKeyTable =
98           (void *)&pTable->KeyTable[i];
99         for (jj=0; jj < MAX_GROUP_KEY; jj++) {
100             pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
101             pTable->KeyTable[i].GroupKey[jj].pvKeyTable =
102               (void *) &(pTable->KeyTable[i]);
103         }
104         pTable->KeyTable[i].wKeyCtl = 0;
105         pTable->KeyTable[i].dwGTKeyIndex = 0;
106         pTable->KeyTable[i].bSoftWEP = false;
107         pbyData[i] = (u8) i;
108     }
109     pbyData[i] = (u8) i;
110
111         vnt_control_out(pDevice, MESSAGE_TYPE_CLRKEYENTRY,
112                         0, 0, 11, pbyData);
113
114     return;
115 }
116
117 /*
118  * Description: Get Key from table
119  *
120  * Parameters:
121  *  In:
122  *      pTable          - Pointer to Key table
123  *      pbyBSSID        - BSSID of Key
124  *      dwKeyIndex      - Key Index (0xFFFFFFFF means pairwise key)
125  *  Out:
126  *      pKey            - Key return
127  *
128  * Return Value: true if found otherwise false
129  *
130  */
131 int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
132         PSKeyItem *pKey)
133 {
134         int i;
135
136         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey()\n");
137
138     *pKey = NULL;
139     for (i=0;i<MAX_KEY_TABLE;i++) {
140         if ((pTable->KeyTable[i].bInUse == true) &&
141             ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
142             if (dwKeyIndex == 0xFFFFFFFF) {
143                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
144                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
145                     return (true);
146                 }
147                 else {
148                     return (false);
149                 }
150             } else if (dwKeyIndex < MAX_GROUP_KEY) {
151                 if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
152                     *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
153                     return (true);
154                 }
155                 else {
156                     return (false);
157                 }
158             }
159             else {
160                 return (false);
161             }
162         }
163     }
164     return (false);
165 }
166
167 /*
168  * Description: Set Key to table
169  *
170  * Parameters:
171  *  In:
172  *      pTable          - Pointer to Key table
173  *      pbyBSSID        - BSSID of Key
174  *      dwKeyIndex      - Key index (reference to NDIS DDK)
175  *      uKeyLength      - Key length
176  *      KeyRSC          - Key RSC
177  *      pbyKey          - Pointer to key
178  *  Out:
179  *      none
180  *
181  * Return Value: true if success otherwise false
182  *
183  */
184 int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable,
185         u8 *pbyBSSID, u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
186         u8 byKeyDecMode)
187 {
188         PSKeyItem   pKey;
189         int i, j, ii;
190         u32 uKeyIdx;
191
192         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
193                 "Enter KeybSetKey: %X\n", dwKeyIndex);
194
195     j = (MAX_KEY_TABLE-1);
196     for (i=0;i<(MAX_KEY_TABLE-1);i++) {
197         if ((pTable->KeyTable[i].bInUse == false) &&
198             (j == (MAX_KEY_TABLE-1))) {
199             // found empty table
200             j = i;
201         }
202         if ((pTable->KeyTable[i].bInUse == true) &&
203             ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
204             // found table already exist
205             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
206                 // Pairwise key
207                 pKey = &(pTable->KeyTable[i].PairwiseKey);
208                 pTable->KeyTable[i].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
209                 pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
210                 uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
211             } else {
212                 // Group key
213                 if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
214                     return (false);
215                 pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
216                 if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
217                     // Group transmit key
218                     pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
219                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
220                                 "Group transmit key(R)[%X]: %d\n",
221                                         pTable->KeyTable[i].dwGTKeyIndex, i);
222                 }
223                 pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
224                 pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
225                 pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
226                 uKeyIdx = (dwKeyIndex & 0x000000FF);
227             }
228             pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
229
230             pKey->bKeyValid = true;
231             pKey->uKeyLength = uKeyLength;
232             pKey->dwKeyIndex = dwKeyIndex;
233             pKey->byCipherSuite = byKeyDecMode;
234             memcpy(pKey->abyKey, pbyKey, uKeyLength);
235             if (byKeyDecMode == KEY_CTL_WEP) {
236                 if (uKeyLength == WLAN_WEP40_KEYLEN)
237                     pKey->abyKey[15] &= 0x7F;
238                 if (uKeyLength == WLAN_WEP104_KEYLEN)
239                     pKey->abyKey[15] |= 0x80;
240             }
241
242             MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx,
243                         pbyBSSID, pKey->abyKey);
244
245                 if ((dwKeyIndex & USE_KEYRSC) == 0)
246                         pKey->KeyRSC = 0; /* RSC set by NIC */
247                 else
248                         pKey->KeyRSC = *KeyRSC;
249
250             pKey->dwTSC47_16 = 0;
251             pKey->wTSC15_0 = 0;
252
253             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
254             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
255             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
256             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
257             for (ii = 0; ii < pKey->uKeyLength; ii++) {
258                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
259             }
260             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
261
262                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
263                         pKey->dwTSC47_16);
264                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ",
265                         pKey->wTSC15_0);
266                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
267                         pKey->dwKeyIndex);
268
269             return (true);
270         }
271     }
272     if (j < (MAX_KEY_TABLE-1)) {
273         memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN);
274         pTable->KeyTable[j].bInUse = true;
275         if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
276             // Pairwise key
277             pKey = &(pTable->KeyTable[j].PairwiseKey);
278             pTable->KeyTable[j].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
279             pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
280             uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
281         } else {
282             // Group key
283             if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
284                 return (false);
285             pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
286             if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
287                 // Group transmit key
288                 pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
289                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
290                         "Group transmit key(N)[%X]: %d\n",
291                                 pTable->KeyTable[j].dwGTKeyIndex, j);
292             }
293             pTable->KeyTable[j].wKeyCtl &= 0xFF0F;          // clear group key control filed
294             pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
295             pTable->KeyTable[j].wKeyCtl |= 0x0040;          // use group key for group address
296             uKeyIdx = (dwKeyIndex & 0x000000FF);
297         }
298         pTable->KeyTable[j].wKeyCtl |= 0x8000;              // enable on-fly
299
300         pKey->bKeyValid = true;
301         pKey->uKeyLength = uKeyLength;
302         pKey->dwKeyIndex = dwKeyIndex;
303         pKey->byCipherSuite = byKeyDecMode;
304         memcpy(pKey->abyKey, pbyKey, uKeyLength);
305         if (byKeyDecMode == KEY_CTL_WEP) {
306             if (uKeyLength == WLAN_WEP40_KEYLEN)
307                 pKey->abyKey[15] &= 0x7F;
308             if (uKeyLength == WLAN_WEP104_KEYLEN)
309                 pKey->abyKey[15] |= 0x80;
310         }
311
312         MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx,
313                                         pbyBSSID, pKey->abyKey);
314
315                 if ((dwKeyIndex & USE_KEYRSC) == 0)
316                         pKey->KeyRSC = 0; /* RSC set by NIC */
317                 else
318                         pKey->KeyRSC = *KeyRSC;
319
320         pKey->dwTSC47_16 = 0;
321         pKey->wTSC15_0 = 0;
322
323         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
324         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
325         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
326         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
327         for (ii = 0; ii < pKey->uKeyLength; ii++) {
328             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
329         }
330         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
331
332         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
333                 pKey->dwTSC47_16);
334         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
335         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
336                 pKey->dwKeyIndex);
337
338         return (true);
339     }
340     return (false);
341 }
342
343 /*
344  * Description: Remove Key from table
345  *
346  * Parameters:
347  *  In:
348  *      pTable          - Pointer to Key table
349  *      pbyBSSID        - BSSID of Key
350  *      dwKeyIndex      - Key Index (reference to NDIS DDK)
351  *  Out:
352  *      none
353  *
354  * Return Value: true if success otherwise false
355  *
356  */
357
358 int KeybRemoveKey(struct vnt_private *pDevice, PSKeyManagement pTable,
359         u8 *pbyBSSID, u32 dwKeyIndex)
360 {
361         int i;
362         int bReturnValue = false;
363
364     if (is_broadcast_ether_addr(pbyBSSID)) {
365         // delete all keys
366         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
367             for (i=0;i<MAX_KEY_TABLE;i++) {
368                 pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
369             }
370             bReturnValue =  true;
371         }
372         else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
373             for (i=0;i<MAX_KEY_TABLE;i++) {
374                 pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
375                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
376                     // remove Group transmit key
377                     pTable->KeyTable[i].dwGTKeyIndex = 0;
378                 }
379             }
380             bReturnValue = true;
381         }
382         else {
383             bReturnValue = false;
384         }
385
386     } else {
387         for (i=0;i<MAX_KEY_TABLE;i++) {
388             if ( (pTable->KeyTable[i].bInUse == true) &&
389                  ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
390
391                 if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
392                     pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
393                     bReturnValue = true;
394                     break;
395                 }
396                 else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
397                     pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
398                     if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
399                         // remove Group transmit key
400                         pTable->KeyTable[i].dwGTKeyIndex = 0;
401                     }
402                     bReturnValue = true;
403                     break;
404                 }
405                 else {
406                     bReturnValue = false;
407                     break;
408                 }
409             } //pTable->KeyTable[i].bInUse == true
410         }  //for
411         bReturnValue = true;
412     }
413
414     s_vCheckKeyTableValid(pDevice,pTable);
415     return bReturnValue;
416
417 }
418
419 /*
420  * Description: Remove Key from table
421  *
422  * Parameters:
423  *  In:
424  *      pTable          - Pointer to Key table
425  *      pbyBSSID        - BSSID of Key
426  *  Out:
427  *      none
428  *
429  * Return Value: true if success otherwise false
430  *
431  */
432 int KeybRemoveAllKey(struct vnt_private *pDevice, PSKeyManagement pTable,
433         u8 *pbyBSSID)
434 {
435         int i, u;
436
437     for (i=0;i<MAX_KEY_TABLE;i++) {
438         if ((pTable->KeyTable[i].bInUse == true) &&
439             ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
440             pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
441             for (u = 0; u < MAX_GROUP_KEY; u++)
442                 pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
443
444             pTable->KeyTable[i].dwGTKeyIndex = 0;
445             s_vCheckKeyTableValid(pDevice, pTable);
446             return (true);
447         }
448     }
449     return (false);
450 }
451
452 /*
453  * Description: Get Transmit Key from table
454  *
455  * Parameters:
456  *  In:
457  *      pTable          - Pointer to Key table
458  *      pbyBSSID        - BSSID of Key
459  *  Out:
460  *      pKey            - Key return
461  *
462  * Return Value: true if found otherwise false
463  *
464  */
465 int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
466         PSKeyItem *pKey)
467 {
468         int i, ii;
469
470         *pKey = NULL;
471
472     for (i = 0; i < MAX_KEY_TABLE; i++) {
473         if ((pTable->KeyTable[i].bInUse == true) &&
474             ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
475
476             if (dwKeyType == PAIRWISE_KEY) {
477
478                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
479                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
480
481                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
482                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
483                     for (ii = 0; ii < 6; ii++) {
484                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
485                     }
486                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
487
488                     return (true);
489                 }
490                 else {
491                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n");
492                     return (false);
493                 }
494             } // End of Type == PAIRWISE
495             else {
496                 if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
497                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
498                     return false;
499                 }
500                 if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
501                     *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
502
503                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
504                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
505                         for (ii = 0; ii < 6; ii++) {
506                             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
507                         }
508                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
509                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n",
510                                 pTable->KeyTable[i].dwGTKeyIndex);
511
512                     return (true);
513                 }
514                 else {
515                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n");
516                     return (false);
517                 }
518             } // End of Type = GROUP
519         } // BSSID match
520     }
521     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
522     for (ii = 0; ii < 6; ii++) {
523         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
524     }
525     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
526     return (false);
527 }
528
529 /*
530  * Description: Set Key to table
531  *
532  * Parameters:
533  *  In:
534  *      pTable          - Pointer to Key table
535  *      dwKeyIndex      - Key index (reference to NDIS DDK)
536  *      uKeyLength      - Key length
537  *      KeyRSC          - Key RSC
538  *      pbyKey          - Pointer to key
539  *  Out:
540  *      none
541  *
542  * Return Value: true if success otherwise false
543  *
544  */
545
546 int KeybSetDefaultKey(struct vnt_private *pDevice, PSKeyManagement pTable,
547         u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
548         u8 byKeyDecMode)
549 {
550         int ii;
551         PSKeyItem pKey;
552         u32 uKeyIdx;
553
554     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n",
555             (int) dwKeyIndex, (int) uKeyLength);
556
557     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
558         return (false);
559     } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
560         return (false);
561     }
562
563     if (uKeyLength > MAX_KEY_LEN)
564             return false;
565
566     pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
567     for (ii = 0; ii < ETH_ALEN; ii++)
568         pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
569
570     // Group key
571     pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
572     if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
573         // Group transmit key
574         pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
575                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
576                 "Group transmit key(R)[%X]: %d\n",
577                 pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex,
578                 MAX_KEY_TABLE-1);
579
580     }
581     pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00;          // clear all key control filed
582     pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
583     pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
584     pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044;          // use group key for all address
585     uKeyIdx = (dwKeyIndex & 0x000000FF);
586
587     if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
588         (byKeyDecMode == KEY_CTL_WEP)) {
589         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
590         pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
591     } else {
592         if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
593             pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
594     }
595
596     pKey->bKeyValid = true;
597     pKey->uKeyLength = uKeyLength;
598     pKey->dwKeyIndex = dwKeyIndex;
599     pKey->byCipherSuite = byKeyDecMode;
600     memcpy(pKey->abyKey, pbyKey, uKeyLength);
601     if (byKeyDecMode == KEY_CTL_WEP) {
602         if (uKeyLength == WLAN_WEP40_KEYLEN)
603             pKey->abyKey[15] &= 0x7F;
604         if (uKeyLength == WLAN_WEP104_KEYLEN)
605             pKey->abyKey[15] |= 0x80;
606     }
607
608         MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl,
609                 MAX_KEY_TABLE-1, uKeyIdx,
610                 pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, pKey->abyKey);
611
612                 if ((dwKeyIndex & USE_KEYRSC) == 0)
613                         pKey->KeyRSC = 0; /* RSC set by NIC */
614                 else
615                         pKey->KeyRSC = *KeyRSC;
616
617     pKey->dwTSC47_16 = 0;
618     pKey->wTSC15_0 = 0;
619
620     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
621     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
622     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
623     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
624     for (ii = 0; ii < pKey->uKeyLength; ii++) {
625         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
626     }
627     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
628
629         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n",
630                 pKey->dwTSC47_16);
631     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
632         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n",
633                 pKey->dwKeyIndex);
634
635     return (true);
636 }
637
638 /*
639  * Description: Set Key to table
640  *
641  * Parameters:
642  *  In:
643  *      pTable          - Pointer to Key table
644  *      dwKeyIndex      - Key index (reference to NDIS DDK)
645  *      uKeyLength      - Key length
646  *      KeyRSC          - Key RSC
647  *      pbyKey          - Pointer to key
648  *  Out:
649  *      none
650  *
651  * Return Value: true if success otherwise false
652  *
653  */
654
655 int KeybSetAllGroupKey(struct vnt_private *pDevice, PSKeyManagement pTable,
656         u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
657         u8 byKeyDecMode)
658 {
659         int i, ii;
660         PSKeyItem pKey;
661         u32 uKeyIdx;
662
663         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n",
664                 dwKeyIndex);
665
666     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
667         return (false);
668     } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
669         return (false);
670     }
671
672     for (i=0; i < MAX_KEY_TABLE-1; i++) {
673         if (pTable->KeyTable[i].bInUse == true) {
674             // found table already exist
675             // Group key
676             pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
677             if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
678                 // Group transmit key
679                 pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
680                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
681                         "Group transmit key(R)[%X]: %d\n",
682                         pTable->KeyTable[i].dwGTKeyIndex, i);
683
684             }
685             pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
686             pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
687             pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
688             uKeyIdx = (dwKeyIndex & 0x000000FF);
689
690             pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
691
692             pKey->bKeyValid = true;
693             pKey->uKeyLength = uKeyLength;
694             pKey->dwKeyIndex = dwKeyIndex;
695             pKey->byCipherSuite = byKeyDecMode;
696             memcpy(pKey->abyKey, pbyKey, uKeyLength);
697             if (byKeyDecMode == KEY_CTL_WEP) {
698                 if (uKeyLength == WLAN_WEP40_KEYLEN)
699                     pKey->abyKey[15] &= 0x7F;
700                 if (uKeyLength == WLAN_WEP104_KEYLEN)
701                     pKey->abyKey[15] |= 0x80;
702             }
703
704             MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx,
705                         pTable->KeyTable[i].abyBSSID, pKey->abyKey);
706
707                 if ((dwKeyIndex & USE_KEYRSC) == 0)
708                         pKey->KeyRSC = 0; /* RSC set by NIC */
709                 else
710                         pKey->KeyRSC = *KeyRSC;
711
712             pKey->dwTSC47_16 = 0;
713             pKey->wTSC15_0 = 0;
714
715             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
716             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
717             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
718             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
719             for (ii = 0; ii < pKey->uKeyLength; ii++) {
720                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
721             }
722             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
723
724             //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
725             //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
726             //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
727
728         } // (pTable->KeyTable[i].bInUse == true)
729     }
730     return (true);
731 }