Commit | Line | Data |
---|---|---|
5449c685 FB |
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 | * File: ioctl.c | |
20 | * | |
21 | * Purpose: private ioctl functions | |
22 | * | |
23 | * Author: Lyndon Chen | |
24 | * | |
25 | * Date: Auguest 20, 2003 | |
26 | * | |
27 | * Functions: | |
28 | * | |
29 | * Revision History: | |
30 | * | |
31 | */ | |
32 | ||
5449c685 | 33 | #include "ioctl.h" |
5449c685 | 34 | #include "iocmd.h" |
5449c685 | 35 | #include "mac.h" |
5449c685 | 36 | #include "card.h" |
5449c685 | 37 | #include "hostap.h" |
5449c685 | 38 | #include "wpactl.h" |
5449c685 | 39 | #include "rf.h" |
5449c685 FB |
40 | |
41 | /*--------------------- Static Definitions -------------------------*/ | |
42 | ||
43 | /*--------------------- Static Classes ----------------------------*/ | |
44 | ||
45 | /*--------------------- Static Variables --------------------------*/ | |
46 | //static int msglevel =MSG_LEVEL_DEBUG; | |
47 | static int msglevel =MSG_LEVEL_INFO; | |
48 | ||
5449c685 FB |
49 | #ifdef WPA_SM_Transtatus |
50 | SWPAResult wpa_Result; | |
51 | #endif | |
52 | ||
612822f5 | 53 | /*--------------------- Static Functions --------------------------*/ |
5449c685 FB |
54 | |
55 | /*--------------------- Export Variables --------------------------*/ | |
56 | ||
57 | int private_ioctl(PSDevice pDevice, struct ifreq *rq) { | |
58 | ||
59 | PSCmdRequest pReq = (PSCmdRequest)rq; | |
60 | PSMgmtObject pMgmt = pDevice->pMgmt; | |
61 | int result = 0; | |
62 | PWLAN_IE_SSID pItemSSID; | |
63 | SCmdBSSJoin sJoinCmd; | |
64 | SCmdZoneTypeSet sZoneTypeCmd; | |
65 | SCmdScan sScanCmd; | |
66 | SCmdStartAP sStartAPCmd; | |
67 | SCmdSetWEP sWEPCmd; | |
68 | SCmdValue sValue; | |
69 | SBSSIDList sList; | |
70 | SNodeList sNodeList; | |
71 | PSBSSIDList pList; | |
72 | PSNodeList pNodeList; | |
73 | UINT cbListCount; | |
74 | PKnownBSS pBSS; | |
75 | PKnownNodeDB pNode; | |
76 | UINT ii, jj; | |
77 | SCmdLinkStatus sLinkStatus; | |
78 | BYTE abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; | |
79 | BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
80 | DWORD dwKeyIndex= 0; | |
81 | BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; | |
82 | LONG ldBm; | |
83 | ||
5449c685 FB |
84 | pReq->wResult = 0; |
85 | ||
b46966ee | 86 | switch (pReq->wCmdCode) { |
5449c685 FB |
87 | |
88 | case WLAN_CMD_BSS_SCAN: | |
89 | ||
7e809a9b | 90 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n"); |
5449c685 FB |
91 | if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) { |
92 | result = -EFAULT; | |
93 | break; | |
94 | }; | |
95 | ||
96 | pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid; | |
97 | if (pItemSSID->len != 0) { | |
98 | memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); | |
99 | memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); | |
100 | } | |
101 | ||
102 | if (pDevice->bMACSuspend == TRUE) { | |
103 | if (pDevice->bRadioOff == TRUE) | |
104 | CARDbRadioPowerOn(pDevice); | |
105 | vMgrTimerInit(pDevice); | |
106 | MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); | |
107 | add_timer(&pMgmt->sTimerSecondCallback); | |
108 | pDevice->bMACSuspend = FALSE; | |
109 | } | |
110 | spin_lock_irq(&pDevice->lock); | |
111 | if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) | |
e64354c0 | 112 | BSSvClearBSSList((void *)pDevice, FALSE); |
5449c685 | 113 | else |
e64354c0 | 114 | BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); |
5449c685 FB |
115 | |
116 | if (pItemSSID->len != 0) | |
e64354c0 | 117 | bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); |
5449c685 | 118 | else |
e64354c0 | 119 | bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); |
5449c685 FB |
120 | spin_unlock_irq(&pDevice->lock); |
121 | break; | |
122 | ||
123 | case WLAN_CMD_ZONETYPE_SET: | |
124 | //mike add :cann't support. | |
125 | result=-EOPNOTSUPP; | |
126 | break; | |
127 | ||
128 | if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) { | |
129 | result = -EFAULT; | |
130 | break; | |
131 | }; | |
132 | ||
133 | if(sZoneTypeCmd.bWrite==TRUE) { | |
134 | //////write zonetype | |
135 | if(sZoneTypeCmd.ZoneType == ZoneType_USA) { | |
136 | //set to USA | |
137 | printk("set_ZoneType:USA\n"); | |
138 | } | |
139 | else if(sZoneTypeCmd.ZoneType == ZoneType_Japan) { | |
140 | //set to Japan | |
141 | printk("set_ZoneType:Japan\n"); | |
142 | } | |
143 | else if(sZoneTypeCmd.ZoneType == ZoneType_Europe) { | |
144 | //set to Europe | |
145 | printk("set_ZoneType:Europe\n"); | |
146 | } | |
147 | } | |
148 | else { | |
149 | ///////read zonetype | |
150 | BYTE zonetype=0; | |
151 | ||
152 | ||
153 | if(zonetype == 0x00) { //USA | |
154 | sZoneTypeCmd.ZoneType = ZoneType_USA; | |
155 | } | |
156 | else if(zonetype == 0x01) { //Japan | |
157 | sZoneTypeCmd.ZoneType = ZoneType_Japan; | |
158 | } | |
159 | else if(zonetype == 0x02) { //Europe | |
160 | sZoneTypeCmd.ZoneType = ZoneType_Europe; | |
161 | } | |
bbc9a991 | 162 | else { //Unknown ZoneType |
5449c685 FB |
163 | printk("Error:ZoneType[%x] Unknown ???\n",zonetype); |
164 | result = -EFAULT; | |
165 | break; | |
166 | } | |
167 | if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) { | |
168 | result = -EFAULT; | |
169 | break; | |
170 | }; | |
171 | } | |
172 | ||
173 | break; | |
174 | ||
175 | case WLAN_CMD_BSS_JOIN: | |
176 | ||
177 | if (pDevice->bMACSuspend == TRUE) { | |
178 | if (pDevice->bRadioOff == TRUE) | |
179 | CARDbRadioPowerOn(pDevice); | |
180 | vMgrTimerInit(pDevice); | |
181 | MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); | |
182 | add_timer(&pMgmt->sTimerSecondCallback); | |
183 | pDevice->bMACSuspend = FALSE; | |
184 | } | |
185 | ||
186 | if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { | |
187 | result = -EFAULT; | |
188 | break; | |
189 | }; | |
190 | ||
191 | pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid; | |
192 | memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); | |
193 | memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); | |
194 | if (sJoinCmd.wBSSType == ADHOC) { | |
195 | pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; | |
7e809a9b | 196 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n"); |
5449c685 FB |
197 | } |
198 | else { | |
199 | pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; | |
7e809a9b | 200 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n"); |
5449c685 FB |
201 | } |
202 | if (sJoinCmd.bPSEnable == TRUE) { | |
203 | pDevice->ePSMode = WMAC_POWER_FAST; | |
204 | // pDevice->ePSMode = WMAC_POWER_MAX; | |
205 | pMgmt->wListenInterval = 2; | |
7e809a9b | 206 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n"); |
5449c685 FB |
207 | } |
208 | else { | |
209 | pDevice->ePSMode = WMAC_POWER_CAM; | |
210 | pMgmt->wListenInterval = 1; | |
7e809a9b | 211 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n"); |
5449c685 FB |
212 | } |
213 | ||
214 | if (sJoinCmd.bShareKeyAuth == TRUE){ | |
215 | pMgmt->bShareKeyAlgorithm = TRUE; | |
7e809a9b | 216 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n"); |
5449c685 FB |
217 | } |
218 | else { | |
219 | pMgmt->bShareKeyAlgorithm = FALSE; | |
7e809a9b | 220 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n"); |
5449c685 FB |
221 | } |
222 | pDevice->uChannel = sJoinCmd.uChannel; | |
223 | netif_stop_queue(pDevice->dev); | |
224 | spin_lock_irq(&pDevice->lock); | |
225 | pMgmt->eCurrState = WMAC_STATE_IDLE; | |
e64354c0 CC |
226 | bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); |
227 | bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); | |
5449c685 FB |
228 | spin_unlock_irq(&pDevice->lock); |
229 | break; | |
230 | ||
231 | case WLAN_CMD_SET_WEP: | |
7e809a9b | 232 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key. \n"); |
5449c685 FB |
233 | memset(&sWEPCmd, 0 ,sizeof(SCmdSetWEP)); |
234 | if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) { | |
235 | result = -EFAULT; | |
236 | break; | |
237 | }; | |
238 | if (sWEPCmd.bEnableWep != TRUE) { | |
239 | pDevice->bEncryptionEnable = FALSE; | |
240 | pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; | |
241 | MACvDisableDefaultKey(pDevice->PortOffset); | |
7e809a9b | 242 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n"); |
5449c685 FB |
243 | break; |
244 | } | |
245 | ||
246 | for (ii = 0; ii < WLAN_WEP_NKEYS; ii ++) { | |
247 | if (sWEPCmd.bWepKeyAvailable[ii]) { | |
248 | if (ii == sWEPCmd.byKeyIndex) | |
249 | //2006-1123-02,<Modify> by EinsnLiu | |
250 | //Evaluate the "dwKeyIndex" error | |
251 | // dwKeyIndex |= (1 << 31); | |
252 | dwKeyIndex =ii|(1 << 31); | |
253 | else | |
254 | dwKeyIndex = ii; | |
255 | ||
256 | KeybSetDefaultKey(&(pDevice->sKey), | |
257 | dwKeyIndex, | |
258 | sWEPCmd.auWepKeyLength[ii], | |
259 | NULL, | |
260 | (PBYTE)&sWEPCmd.abyWepKey[ii][0], | |
261 | KEY_CTL_WEP, | |
262 | pDevice->PortOffset, | |
263 | pDevice->byLocalID); | |
264 | } | |
265 | } | |
266 | pDevice->byKeyIndex = sWEPCmd.byKeyIndex; | |
267 | pDevice->bTransmitKey = TRUE; | |
268 | pDevice->bEncryptionEnable = TRUE; | |
269 | pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; | |
270 | ||
271 | break; | |
272 | ||
273 | case WLAN_CMD_GET_LINK: | |
7e809a9b | 274 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status. \n"); |
5449c685 FB |
275 | |
276 | memset(sLinkStatus.abySSID, 0 , WLAN_SSID_MAXLEN + 1); | |
277 | ||
278 | if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) | |
279 | sLinkStatus.wBSSType = ADHOC; | |
280 | else | |
281 | sLinkStatus.wBSSType = INFRA; | |
282 | ||
283 | if (pMgmt->eCurrState == WMAC_STATE_JOINTED) | |
284 | sLinkStatus.byState = ADHOC_JOINTED; | |
285 | else | |
286 | sLinkStatus.byState = ADHOC_STARTED; | |
287 | ||
288 | sLinkStatus.uChannel = pMgmt->uCurrChannel; | |
289 | if (pDevice->bLinkPass == TRUE) { | |
290 | sLinkStatus.bLink = TRUE; | |
291 | pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; | |
292 | memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); | |
293 | memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); | |
294 | sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; | |
7e809a9b | 295 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n"); |
5449c685 FB |
296 | } |
297 | else { | |
298 | sLinkStatus.bLink = FALSE; | |
299 | } | |
300 | if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) { | |
301 | result = -EFAULT; | |
302 | break; | |
303 | }; | |
304 | ||
305 | break; | |
306 | ||
307 | case WLAN_CMD_GET_LISTLEN: | |
308 | cbListCount = 0; | |
309 | pBSS = &(pMgmt->sBSSList[0]); | |
310 | for (ii = 0; ii < MAX_BSS_NUM; ii++) { | |
311 | pBSS = &(pMgmt->sBSSList[ii]); | |
312 | if (!pBSS->bActive) | |
313 | continue; | |
314 | cbListCount++; | |
315 | }; | |
316 | sList.uItem = cbListCount; | |
317 | if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) { | |
318 | result = -EFAULT; | |
319 | break; | |
320 | }; | |
321 | pReq->wResult = 0; | |
322 | break; | |
323 | ||
324 | case WLAN_CMD_GET_LIST: | |
325 | if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) { | |
326 | result = -EFAULT; | |
327 | break; | |
328 | }; | |
329 | pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC); | |
330 | if (pList == NULL) { | |
331 | result = -ENOMEM; | |
332 | break; | |
333 | } | |
334 | pList->uItem = sList.uItem; | |
335 | pBSS = &(pMgmt->sBSSList[0]); | |
336 | for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { | |
337 | pBSS = &(pMgmt->sBSSList[jj]); | |
338 | if (pBSS->bActive) { | |
339 | pList->sBSSIDList[ii].uChannel = pBSS->uChannel; | |
340 | pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; | |
341 | pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; | |
342 | // pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; | |
343 | RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); | |
344 | pList->sBSSIDList[ii].uRSSI = (UINT)ldBm; | |
345 | memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); | |
346 | pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; | |
347 | memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1); | |
348 | memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len); | |
349 | if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { | |
350 | pList->sBSSIDList[ii].byNetType = INFRA; | |
351 | } | |
352 | else { | |
353 | pList->sBSSIDList[ii].byNetType = ADHOC; | |
354 | } | |
355 | if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { | |
356 | pList->sBSSIDList[ii].bWEPOn = TRUE; | |
357 | } | |
358 | else { | |
359 | pList->sBSSIDList[ii].bWEPOn = FALSE; | |
360 | } | |
361 | ii ++; | |
362 | if (ii >= pList->uItem) | |
363 | break; | |
364 | } | |
365 | } | |
366 | ||
367 | if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) { | |
368 | result = -EFAULT; | |
369 | break; | |
370 | }; | |
371 | kfree(pList); | |
372 | pReq->wResult = 0; | |
373 | break; | |
374 | ||
375 | case WLAN_CMD_GET_MIB: | |
376 | if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) { | |
377 | result = -EFAULT; | |
378 | break; | |
379 | }; | |
380 | break; | |
381 | ||
382 | case WLAN_CMD_GET_STAT: | |
383 | if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) { | |
384 | result = -EFAULT; | |
385 | break; | |
386 | }; | |
387 | break; | |
388 | case WLAN_CMD_STOP_MAC: | |
389 | ||
7e809a9b | 390 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n"); |
5449c685 FB |
391 | netif_stop_queue(pDevice->dev); |
392 | ||
393 | spin_lock_irq(&pDevice->lock); | |
394 | if (pDevice->bRadioOff == FALSE) { | |
395 | CARDbRadioPowerOff(pDevice); | |
396 | } | |
397 | pDevice->bLinkPass = FALSE; | |
398 | memset(pMgmt->abyCurrBSSID, 0, 6); | |
399 | pMgmt->eCurrState = WMAC_STATE_IDLE; | |
400 | del_timer(&pDevice->sTimerCommand); | |
401 | del_timer(&pMgmt->sTimerSecondCallback); | |
402 | pDevice->bCmdRunning = FALSE; | |
403 | pDevice->bMACSuspend = TRUE; | |
404 | MACvIntDisable(pDevice->PortOffset); | |
405 | spin_unlock_irq(&pDevice->lock); | |
406 | ||
407 | break; | |
408 | ||
409 | case WLAN_CMD_START_MAC: | |
410 | ||
7e809a9b | 411 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n"); |
5449c685 FB |
412 | |
413 | if (pDevice->bMACSuspend == TRUE) { | |
414 | if (pDevice->bRadioOff == TRUE) | |
415 | CARDbRadioPowerOn(pDevice); | |
416 | vMgrTimerInit(pDevice); | |
417 | MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); | |
418 | add_timer(&pMgmt->sTimerSecondCallback); | |
419 | pDevice->bMACSuspend = FALSE; | |
420 | } | |
421 | break; | |
422 | ||
423 | case WLAN_CMD_SET_HOSTAPD: | |
424 | ||
7e809a9b | 425 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n"); |
5449c685 FB |
426 | |
427 | if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { | |
428 | result = -EFAULT; | |
429 | break; | |
430 | }; | |
431 | if (sValue.dwValue == 1) { | |
ecf739e6 | 432 | if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0){ |
7e809a9b | 433 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n"); |
5449c685 FB |
434 | } |
435 | else { | |
436 | result = -EFAULT; | |
437 | break; | |
438 | } | |
439 | } | |
440 | else { | |
ecf739e6 | 441 | vt6655_hostap_set_hostapd(pDevice, 0, 1); |
7e809a9b | 442 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n"); |
5449c685 FB |
443 | } |
444 | ||
445 | break; | |
446 | ||
447 | case WLAN_CMD_SET_HOSTAPD_STA: | |
448 | ||
7e809a9b | 449 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n"); |
5449c685 FB |
450 | |
451 | break; | |
452 | case WLAN_CMD_SET_802_1X: | |
453 | ||
7e809a9b | 454 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n"); |
5449c685 FB |
455 | if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { |
456 | result = -EFAULT; | |
457 | break; | |
458 | }; | |
459 | ||
460 | if (sValue.dwValue == 1) { | |
461 | pDevice->bEnable8021x = TRUE; | |
7e809a9b | 462 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n"); |
5449c685 FB |
463 | } |
464 | else { | |
465 | pDevice->bEnable8021x = FALSE; | |
7e809a9b | 466 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n"); |
5449c685 FB |
467 | } |
468 | ||
469 | break; | |
470 | ||
471 | ||
472 | case WLAN_CMD_SET_HOST_WEP: | |
473 | ||
7e809a9b | 474 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n"); |
5449c685 FB |
475 | if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { |
476 | result = -EFAULT; | |
477 | break; | |
478 | }; | |
479 | ||
480 | if (sValue.dwValue == 1) { | |
481 | pDevice->bEnableHostWEP = TRUE; | |
7e809a9b | 482 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n"); |
5449c685 FB |
483 | } |
484 | else { | |
485 | pDevice->bEnableHostWEP = FALSE; | |
7e809a9b | 486 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n"); |
5449c685 FB |
487 | } |
488 | ||
489 | break; | |
490 | ||
491 | case WLAN_CMD_SET_WPA: | |
7e809a9b | 492 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n"); |
5449c685 FB |
493 | |
494 | if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { | |
495 | result = -EFAULT; | |
496 | break; | |
497 | }; | |
498 | if (sValue.dwValue == 1) { | |
7e809a9b | 499 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n"); |
078b078f | 500 | memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, ETH_ALEN); |
5449c685 FB |
501 | pDevice->bWPADEVUp = TRUE; |
502 | } | |
503 | else { | |
7e809a9b | 504 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n"); |
5449c685 FB |
505 | pDevice->bWPADEVUp = FALSE; |
506 | } | |
507 | ||
508 | break; | |
509 | ||
510 | case WLAN_CMD_AP_START: | |
511 | ||
7e809a9b | 512 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n"); |
5449c685 FB |
513 | if (pDevice->bRadioOff == TRUE) { |
514 | CARDbRadioPowerOn(pDevice); | |
515 | vMgrTimerInit(pDevice); | |
516 | MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); | |
517 | add_timer(&pMgmt->sTimerSecondCallback); | |
518 | } | |
519 | if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) { | |
520 | result = -EFAULT; | |
521 | break; | |
522 | }; | |
523 | ||
524 | if (sStartAPCmd.wBSSType == AP) { | |
525 | pMgmt->eConfigMode = WMAC_CONFIG_AP; | |
7e809a9b | 526 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n"); |
5449c685 FB |
527 | } |
528 | else { | |
7e809a9b | 529 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n"); |
5449c685 FB |
530 | result = -EFAULT; |
531 | break; | |
532 | } | |
533 | ||
534 | ||
535 | if (sStartAPCmd.wBBPType == PHY80211g) { | |
536 | pMgmt->byAPBBType = PHY_TYPE_11G; | |
537 | } | |
538 | else if (sStartAPCmd.wBBPType == PHY80211a) { | |
539 | pMgmt->byAPBBType = PHY_TYPE_11A; | |
540 | } | |
541 | else { | |
542 | pMgmt->byAPBBType = PHY_TYPE_11B; | |
543 | } | |
544 | ||
545 | pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid; | |
546 | memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); | |
547 | memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); | |
548 | ||
549 | if ((sStartAPCmd.uChannel > 0)&&(sStartAPCmd.uChannel <= 14)) | |
550 | pDevice->uChannel = sStartAPCmd.uChannel; | |
551 | ||
552 | if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000)) | |
553 | pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt; | |
554 | else | |
555 | pMgmt->wIBSSBeaconPeriod = 100; | |
556 | ||
557 | if (sStartAPCmd.bShareKeyAuth == TRUE){ | |
558 | pMgmt->bShareKeyAlgorithm = TRUE; | |
7e809a9b | 559 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n"); |
5449c685 FB |
560 | } |
561 | else { | |
562 | pMgmt->bShareKeyAlgorithm = FALSE; | |
7e809a9b | 563 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n"); |
5449c685 FB |
564 | } |
565 | memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6); | |
566 | ||
567 | if (sStartAPCmd.byBasicRate & BIT3) { | |
568 | pMgmt->abyIBSSSuppRates[2] |= BIT7; | |
569 | pMgmt->abyIBSSSuppRates[3] |= BIT7; | |
570 | pMgmt->abyIBSSSuppRates[4] |= BIT7; | |
571 | pMgmt->abyIBSSSuppRates[5] |= BIT7; | |
572 | }else if (sStartAPCmd.byBasicRate & BIT2) { | |
573 | pMgmt->abyIBSSSuppRates[2] |= BIT7; | |
574 | pMgmt->abyIBSSSuppRates[3] |= BIT7; | |
575 | pMgmt->abyIBSSSuppRates[4] |= BIT7; | |
576 | }else if (sStartAPCmd.byBasicRate & BIT1) { | |
577 | pMgmt->abyIBSSSuppRates[2] |= BIT7; | |
578 | pMgmt->abyIBSSSuppRates[3] |= BIT7; | |
579 | }else if (sStartAPCmd.byBasicRate & BIT1) { | |
580 | pMgmt->abyIBSSSuppRates[2] |= BIT7; | |
581 | }else { | |
582 | //default 1,2M | |
583 | pMgmt->abyIBSSSuppRates[2] |= BIT7; | |
584 | pMgmt->abyIBSSSuppRates[3] |= BIT7; | |
585 | } | |
586 | ||
7e809a9b | 587 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n", |
5449c685 FB |
588 | pMgmt->abyIBSSSuppRates[2], |
589 | pMgmt->abyIBSSSuppRates[3], | |
590 | pMgmt->abyIBSSSuppRates[4], | |
591 | pMgmt->abyIBSSSuppRates[5] | |
592 | ); | |
593 | ||
594 | netif_stop_queue(pDevice->dev); | |
595 | spin_lock_irq(&pDevice->lock); | |
e64354c0 | 596 | bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); |
5449c685 FB |
597 | spin_unlock_irq(&pDevice->lock); |
598 | break; | |
599 | ||
600 | case WLAN_CMD_GET_NODE_CNT: | |
601 | ||
602 | cbListCount = 0; | |
603 | pNode = &(pMgmt->sNodeDBTable[0]); | |
604 | for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { | |
605 | pNode = &(pMgmt->sNodeDBTable[ii]); | |
606 | if (!pNode->bActive) | |
607 | continue; | |
608 | cbListCount++; | |
609 | }; | |
610 | ||
611 | sNodeList.uItem = cbListCount; | |
612 | if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) { | |
613 | result = -EFAULT; | |
614 | break; | |
615 | }; | |
616 | pReq->wResult = 0; | |
617 | break; | |
618 | ||
619 | case WLAN_CMD_GET_NODE_LIST: | |
620 | ||
621 | if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) { | |
622 | result = -EFAULT; | |
623 | break; | |
624 | }; | |
625 | pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); | |
626 | if (pNodeList == NULL) { | |
627 | result = -ENOMEM; | |
628 | break; | |
629 | } | |
630 | pNodeList->uItem = sNodeList.uItem; | |
631 | pNode = &(pMgmt->sNodeDBTable[0]); | |
632 | for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) { | |
633 | pNode = &(pMgmt->sNodeDBTable[ii]); | |
634 | if (pNode->bActive) { | |
635 | pNodeList->sNodeList[jj].wAID = pNode->wAID; | |
636 | memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN); | |
637 | pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate; | |
638 | pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount; | |
639 | pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt; | |
640 | pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags; | |
641 | pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable; | |
642 | pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex; | |
643 | pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength; | |
644 | memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN); | |
7e809a9b | 645 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", |
5449c685 FB |
646 | pNodeList->sNodeList[jj].abyWepKey[0], |
647 | pNodeList->sNodeList[jj].abyWepKey[1], | |
648 | pNodeList->sNodeList[jj].abyWepKey[2], | |
649 | pNodeList->sNodeList[jj].abyWepKey[3], | |
650 | pNodeList->sNodeList[jj].abyWepKey[4] | |
651 | ); | |
652 | pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback; | |
653 | pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures; | |
654 | pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts; | |
655 | pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio; | |
656 | jj ++; | |
657 | if (jj >= pNodeList->uItem) | |
658 | break; | |
659 | } | |
660 | }; | |
661 | if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { | |
662 | result = -EFAULT; | |
663 | break; | |
664 | }; | |
665 | kfree(pNodeList); | |
666 | pReq->wResult = 0; | |
667 | break; | |
668 | ||
669 | #ifdef WPA_SM_Transtatus | |
670 | case 0xFF: | |
671 | memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname)); | |
672 | wpa_Result.proto = 0; | |
673 | wpa_Result.key_mgmt = 0; | |
674 | wpa_Result.eap_type = 0; | |
675 | wpa_Result.authenticated = FALSE; | |
612822f5 | 676 | pDevice->fWPA_Authened = FALSE; |
5449c685 FB |
677 | if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) { |
678 | result = -EFAULT; | |
679 | break; | |
680 | } | |
681 | ||
612822f5 | 682 | if(wpa_Result.authenticated==TRUE) { |
5449c685 FB |
683 | #ifdef SndEvt_ToAPI |
684 | { | |
685 | union iwreq_data wrqu; | |
686 | ||
687 | pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; | |
688 | ||
689 | memset(&wrqu, 0, sizeof(wrqu)); | |
690 | wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG; | |
691 | wrqu.data.length =pItemSSID->len; | |
692 | wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID); | |
693 | } | |
694 | #endif | |
bbc9a991 | 695 | pDevice->fWPA_Authened = TRUE; //is successful peer to wpa_Result.authenticated? |
5449c685 FB |
696 | } |
697 | ||
698 | //printk("get private wpa_supplicant announce WPA SM\n"); | |
699 | //printk("wpa-->ifname=%s\n",wpa_Result.ifname); | |
700 | //printk("wpa-->proto=%d\n",wpa_Result.proto); | |
701 | //printk("wpa-->key-mgmt=%d\n",wpa_Result.key_mgmt); | |
702 | //printk("wpa-->eap_type=%d\n",wpa_Result.eap_type); | |
703 | //printk("wpa-->authenticated is %s\n",(wpa_Result.authenticated==TRUE)?"TRUE":"FALSE"); | |
704 | ||
705 | pReq->wResult = 0; | |
706 | break; | |
707 | #endif | |
708 | ||
5449c685 | 709 | default: |
7e809a9b | 710 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n"); |
5449c685 FB |
711 | } |
712 | ||
713 | return result; | |
714 | } | |
715 | ||
716 | /* | |
6b35b7b3 | 717 | void |
5449c685 | 718 | vConfigWEPKey ( |
3a215e0f CC |
719 | PSDevice pDevice, |
720 | DWORD dwKeyIndex, | |
721 | PBYTE pbyKey, | |
722 | ULONG uKeyLength | |
5449c685 FB |
723 | ) |
724 | { | |
725 | int ii; | |
726 | ||
727 | ||
51b6d9c2 JL |
728 | memset(&pDevice->abyWepKey[dwKeyIndex][0], 0, WLAN_WEPMAX_KEYLEN); |
729 | memcpy(&pDevice->abyWepKey[dwKeyIndex][0], pbyKey, uKeyLength); | |
5449c685 FB |
730 | |
731 | pDevice->bWepKeyAvailable[dwKeyIndex] = TRUE; | |
732 | pDevice->auWepKeyLength[dwKeyIndex] = uKeyLength; | |
733 | ||
734 | MACvSetDefaultKeyEntry(pDevice->PortOffset, uKeyLength, dwKeyIndex, | |
735 | (PDWORD) &(pDevice->abyWepKey[dwKeyIndex][0]), pDevice->byLocalID); | |
736 | ||
737 | if (pDevice->eEncryptionStatus < Ndis802_11EncryptionNotSupported) { | |
738 | for(ii=0; ii<MAX_GROUP_KEY; ii++) { | |
739 | if ((pDevice->bWepKeyAvailable[ii] == TRUE) && | |
740 | (pDevice->auWepKeyLength[ii] == WLAN_WEP232_KEYLEN)) { | |
741 | pDevice->uCurrentWEPMode = TX_WEP_SW232; | |
742 | MACvDisableDefaultKey(pDevice->PortOffset); | |
743 | break; | |
744 | } | |
745 | } | |
746 | if ((ii == MAX_GROUP_KEY) && | |
747 | (pDevice->eEncryptionStatus < Ndis802_11EncryptionNotSupported)) { | |
748 | MACvEnableDefaultKey(pDevice->PortOffset, pDevice->byLocalID); | |
749 | } | |
750 | } | |
751 | } | |
752 | */ |