Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ioctl.c
Go to the documentation of this file.
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 
33 #include "ioctl.h"
34 #include "iocmd.h"
35 #include "mac.h"
36 #include "card.h"
37 #include "hostap.h"
38 #include "wpactl.h"
39 #include "control.h"
40 #include "rndis.h"
41 #include "rf.h"
42 
44 static int msglevel = MSG_LEVEL_INFO;
45 
46 int private_ioctl(PSDevice pDevice, struct ifreq *rq)
47 {
48 
49  PSCmdRequest pReq = (PSCmdRequest)rq;
50  PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
51  int result = 0;
52  PWLAN_IE_SSID pItemSSID;
53  SCmdBSSJoin sJoinCmd;
54  SCmdZoneTypeSet sZoneTypeCmd;
55  SCmdScan sScanCmd;
56  SCmdStartAP sStartAPCmd;
57  SCmdSetWEP sWEPCmd;
58  SCmdValue sValue;
59  SBSSIDList sList;
60  SNodeList sNodeList;
61  PSBSSIDList pList;
62  PSNodeList pNodeList;
63  unsigned int cbListCount;
64  PKnownBSS pBSS;
65  PKnownNodeDB pNode;
66  unsigned int ii, jj;
67  SCmdLinkStatus sLinkStatus;
68  BYTE abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
69  BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
70  DWORD dwKeyIndex = 0;
71  BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
72  signed long ldBm;
73 
74  pReq->wResult = 0;
75 
76  switch (pReq->wCmdCode) {
77  case WLAN_CMD_BSS_SCAN:
78  if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
79  result = -EFAULT;
80  break;
81  }
82 
83  pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
84  if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
85  return -EINVAL;
86  if (pItemSSID->len != 0) {
87  memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
88  memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
89  }
90  spin_lock_irq(&pDevice->lock);
91 
92  if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
93  BSSvClearBSSList(pDevice, FALSE);
94  else
95  BSSvClearBSSList(pDevice, pDevice->bLinkPass);
96 
97  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n");
98 
99  if (pItemSSID->len != 0)
101  abyScanSSID);
102  else
104 
105  spin_unlock_irq(&pDevice->lock);
106  break;
107 
109  result = -EOPNOTSUPP;
110  break;
111 
112  if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
113  result = -EFAULT;
114  break;
115  }
116 
117  if (sZoneTypeCmd.bWrite == TRUE) {
118  /* write zonetype */
119  if (sZoneTypeCmd.ZoneType == ZoneType_USA) {
120  /* set to USA */
121  printk("set_ZoneType:USA\n");
122  } else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) {
123  /* set to Japan */
124  printk("set_ZoneType:Japan\n");
125  } else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) {
126  /* set to Europe */
127  printk("set_ZoneType:Europe\n");
128  }
129  } else {
130  /* read zonetype */
131  BYTE zonetype = 0;
132 
133  if (zonetype == 0x00) { /* USA */
134  sZoneTypeCmd.ZoneType = ZoneType_USA;
135  } else if (zonetype == 0x01) { /* Japan */
136  sZoneTypeCmd.ZoneType = ZoneType_Japan;
137  } else if (zonetype == 0x02) { /* Europe */
138  sZoneTypeCmd.ZoneType = ZoneType_Europe;
139  } else { /* Unknown ZoneType */
140  printk("Error:ZoneType[%x] Unknown ???\n", zonetype);
141  result = -EFAULT;
142  break;
143  }
144 
145  if (copy_to_user(pReq->data, &sZoneTypeCmd,
146  sizeof(SCmdZoneTypeSet))) {
147  result = -EFAULT;
148  break;
149  }
150  }
151  break;
152 
153  case WLAN_CMD_BSS_JOIN:
154  if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
155  result = -EFAULT;
156  break;
157  }
158 
159  pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
160  if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
161  return -EINVAL;
163  memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
164  if (sJoinCmd.wBSSType == ADHOC) {
166  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
167  } else {
169  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
170  }
171  if (sJoinCmd.bPSEnable == TRUE) {
172  pDevice->ePSMode = WMAC_POWER_FAST;
173  pMgmt->wListenInterval = 2;
174  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
175  } else {
176  pDevice->ePSMode = WMAC_POWER_CAM;
177  pMgmt->wListenInterval = 1;
178  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off\n");
179  }
180 
181  if (sJoinCmd.bShareKeyAuth == TRUE) {
182  pMgmt->bShareKeyAlgorithm = TRUE;
183  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n");
184  } else {
185  pMgmt->bShareKeyAlgorithm = FALSE;
186  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n");
187  }
188 
189  pDevice->uChannel = sJoinCmd.uChannel;
190  netif_stop_queue(pDevice->dev);
191  spin_lock_irq(&pDevice->lock);
192  pMgmt->eCurrState = WMAC_STATE_IDLE;
194  pMgmt->abyDesireSSID);
196  spin_unlock_irq(&pDevice->lock);
197  break;
198 
199  case WLAN_CMD_SET_WEP:
200  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key.\n");
201  memset(&sWEPCmd, 0, sizeof(SCmdSetWEP));
202  if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
203  result = -EFAULT;
204  break;
205  }
206  if (sWEPCmd.bEnableWep != TRUE) {
207  int uu;
208 
209  pDevice->bEncryptionEnable = FALSE;
211  spin_lock_irq(&pDevice->lock);
212  for (uu = 0; uu < MAX_KEY_TABLE; uu++)
213  MACvDisableKeyEntry(pDevice, uu);
214  spin_unlock_irq(&pDevice->lock);
215  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable.\n");
216  break;
217  }
218 
219  for (ii = 0; ii < WLAN_WEP_NKEYS; ii++) {
220  if (sWEPCmd.bWepKeyAvailable[ii]) {
221  if (ii == sWEPCmd.byKeyIndex)
222  dwKeyIndex = ii | (1 << 31);
223  else
224  dwKeyIndex = ii;
225  spin_lock_irq(&pDevice->lock);
226  KeybSetDefaultKey(pDevice, &(pDevice->sKey),
227  dwKeyIndex,
228  sWEPCmd.auWepKeyLength[ii],
229  NULL,
230  (PBYTE)&sWEPCmd.abyWepKey[ii][0],
231  KEY_CTL_WEP);
232  spin_unlock_irq(&pDevice->lock);
233  }
234  }
235  pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
236  pDevice->bTransmitKey = TRUE;
237  pDevice->bEncryptionEnable = TRUE;
239  break;
240 
241  case WLAN_CMD_GET_LINK:
242  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status.\n");
243 
244  memset(sLinkStatus.abySSID, 0, WLAN_SSID_MAXLEN + 1);
245 
246  if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
247  sLinkStatus.wBSSType = ADHOC;
248  else
249  sLinkStatus.wBSSType = INFRA;
250 
251  if (pMgmt->eCurrState == WMAC_STATE_JOINTED)
252  sLinkStatus.byState = ADHOC_JOINTED;
253  else
254  sLinkStatus.byState = ADHOC_STARTED;
255 
256  sLinkStatus.uChannel = pMgmt->uCurrChannel;
257  if (pDevice->bLinkPass == TRUE) {
258  sLinkStatus.bLink = TRUE;
259  pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
260  memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
261  memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
262  sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate;
263  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Link Success!\n");
264  } else {
265  sLinkStatus.bLink = FALSE;
266  sLinkStatus.uLinkRate = 0;
267  }
268  if (copy_to_user(pReq->data, &sLinkStatus,
269  sizeof(SCmdLinkStatus))) {
270  result = -EFAULT;
271  break;
272  }
273  break;
274 
276  cbListCount = 0;
277  pBSS = &(pMgmt->sBSSList[0]);
278  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
279  pBSS = &(pMgmt->sBSSList[ii]);
280  if (!pBSS->bActive)
281  continue;
282  cbListCount++;
283  }
284  sList.uItem = cbListCount;
285  if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
286  result = -EFAULT;
287  break;
288  }
289  pReq->wResult = 0;
290  break;
291 
292  case WLAN_CMD_GET_LIST:
293  if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
294  result = -EFAULT;
295  break;
296  }
297  if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) {
298  result = -EINVAL;
299  break;
300  }
301  pList = kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), GFP_ATOMIC);
302  if (pList == NULL) {
303  result = -ENOMEM;
304  break;
305  }
306  pList->uItem = sList.uItem;
307  pBSS = &(pMgmt->sBSSList[0]);
308  for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
309  pBSS = &(pMgmt->sBSSList[jj]);
310  if (pBSS->bActive) {
311  pList->sBSSIDList[ii].uChannel = pBSS->uChannel;
312  pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval;
313  pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo;
314  RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
315  pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm;
316  /* pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; */
317  memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN);
318  pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
319  memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
320  memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len);
321  if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
322  pList->sBSSIDList[ii].byNetType = INFRA;
323  } else {
324  pList->sBSSIDList[ii].byNetType = ADHOC;
325  }
326  if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
327  pList->sBSSIDList[ii].bWEPOn = TRUE;
328  } else {
329  pList->sBSSIDList[ii].bWEPOn = FALSE;
330  }
331  ii++;
332  if (ii >= pList->uItem)
333  break;
334  }
335  }
336 
337  if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
338  result = -EFAULT;
339  break;
340  }
341  kfree(pList);
342  pReq->wResult = 0;
343  break;
344 
345  case WLAN_CMD_GET_MIB:
346  if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
347  result = -EFAULT;
348  break;
349  }
350  break;
351 
352  case WLAN_CMD_GET_STAT:
353  if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
354  result = -EFAULT;
355  break;
356  }
357  break;
358 
359  case WLAN_CMD_STOP_MAC:
360  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
361  /* Todo xxxxxx */
362  netif_stop_queue(pDevice->dev);
363  spin_lock_irq(&pDevice->lock);
364  if (pDevice->bRadioOff == FALSE) {
365  CARDbRadioPowerOff(pDevice);
366  }
367  pDevice->bLinkPass = FALSE;
369  memset(pMgmt->abyCurrBSSID, 0, 6);
370  pMgmt->eCurrState = WMAC_STATE_IDLE;
371  /* del_timer(&pDevice->sTimerCommand); */
372  /* del_timer(&pMgmt->sTimerSecondCallback); */
373  pDevice->bCmdRunning = FALSE;
374  spin_unlock_irq(&pDevice->lock);
375  break;
376 
377  case WLAN_CMD_START_MAC:
378  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
379  /* Todo xxxxxxx */
380  if (pDevice->bRadioOff == TRUE)
381  CARDbRadioPowerOn(pDevice);
382  break;
383 
385  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
386 
387  if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
388  result = -EFAULT;
389  break;
390  }
391  if (sValue.dwValue == 1) {
392  if (vt6656_hostap_set_hostapd(pDevice, 1, 1) == 0) {
393  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
394  } else {
395  result = -EFAULT;
396  break;
397  }
398  } else {
399  vt6656_hostap_set_hostapd(pDevice, 0, 1);
400  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
401  }
402  break;
403 
405  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
406  break;
407 
408  case WLAN_CMD_SET_802_1X:
409  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
410  if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
411  result = -EFAULT;
412  break;
413  }
414 
415  if (sValue.dwValue == 1) {
416  pDevice->bEnable8021x = TRUE;
417  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
418  } else {
419  pDevice->bEnable8021x = FALSE;
420  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
421  }
422  break;
423 
425  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
426  if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
427  result = -EFAULT;
428  break;
429  }
430 
431  if (sValue.dwValue == 1) {
432  pDevice->bEnableHostWEP = TRUE;
433  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
434  } else {
435  pDevice->bEnableHostWEP = FALSE;
436  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
437  }
438  break;
439 
440  case WLAN_CMD_SET_WPA:
441  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
442 
443  if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
444  result = -EFAULT;
445  break;
446  }
447  if (sValue.dwValue == 1) {
448  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
449  memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr,
450  ETH_ALEN);
451  pDevice->bWPADEVUp = TRUE;
452  } else {
453  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
454  pDevice->bWPADEVUp = FALSE;
455  }
456  break;
457 
458  case WLAN_CMD_AP_START:
459  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
460  if (pDevice->bRadioOff == TRUE) {
461  CARDbRadioPowerOn(pDevice);
463  }
464  if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
465  result = -EFAULT;
466  break;
467  }
468 
469  if (sStartAPCmd.wBSSType == AP) {
470  pMgmt->eConfigMode = WMAC_CONFIG_AP;
471  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
472  } else {
473  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
474  result = -EFAULT;
475  break;
476  }
477 
478  if (sStartAPCmd.wBBPType == PHY80211g) {
479  pMgmt->byAPBBType = PHY_TYPE_11G;
480  } else if (sStartAPCmd.wBBPType == PHY80211a) {
481  pMgmt->byAPBBType = PHY_TYPE_11A;
482  } else {
483  pMgmt->byAPBBType = PHY_TYPE_11B;
484  }
485 
486  pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid;
487  if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
488  return -EINVAL;
490  memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
491 
492  if ((sStartAPCmd.uChannel > 0) && (sStartAPCmd.uChannel <= 14))
493  pDevice->uChannel = sStartAPCmd.uChannel;
494 
495  if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000))
496  pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt;
497  else
498  pMgmt->wIBSSBeaconPeriod = 100;
499 
500  if (sStartAPCmd.bShareKeyAuth == TRUE) {
501  pMgmt->bShareKeyAlgorithm = TRUE;
502  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n");
503  } else {
504  pMgmt->bShareKeyAlgorithm = FALSE;
505  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n");
506  }
507  memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
508 
509  if (sStartAPCmd.byBasicRate & BIT3) {
510  pMgmt->abyIBSSSuppRates[2] |= BIT7;
511  pMgmt->abyIBSSSuppRates[3] |= BIT7;
512  pMgmt->abyIBSSSuppRates[4] |= BIT7;
513  pMgmt->abyIBSSSuppRates[5] |= BIT7;
514  } else if (sStartAPCmd.byBasicRate & BIT2) {
515  pMgmt->abyIBSSSuppRates[2] |= BIT7;
516  pMgmt->abyIBSSSuppRates[3] |= BIT7;
517  pMgmt->abyIBSSSuppRates[4] |= BIT7;
518  } else if (sStartAPCmd.byBasicRate & BIT1) {
519  pMgmt->abyIBSSSuppRates[2] |= BIT7;
520  pMgmt->abyIBSSSuppRates[3] |= BIT7;
521  } else if (sStartAPCmd.byBasicRate & BIT1) {
522  pMgmt->abyIBSSSuppRates[2] |= BIT7;
523  } else {
524  /* default 1,2M */
525  pMgmt->abyIBSSSuppRates[2] |= BIT7;
526  pMgmt->abyIBSSSuppRates[3] |= BIT7;
527  }
528 
529  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n",
530  4, pMgmt->abyIBSSSuppRates + 2);
531 
532  netif_stop_queue(pDevice->dev);
533  spin_lock_irq(&pDevice->lock);
535  spin_unlock_irq(&pDevice->lock);
536  break;
537 
539  cbListCount = 0;
540  pNode = &(pMgmt->sNodeDBTable[0]);
541  for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
542  pNode = &(pMgmt->sNodeDBTable[ii]);
543  if (!pNode->bActive)
544  continue;
545  cbListCount++;
546  }
547 
548  sNodeList.uItem = cbListCount;
549  if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
550  result = -EFAULT;
551  break;
552  }
553  pReq->wResult = 0;
554  break;
555 
557  if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
558  result = -EFAULT;
559  break;
560  }
561  if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) {
562  result = -ENOMEM;
563  break;
564  }
565  pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), GFP_ATOMIC);
566  if (pNodeList == NULL) {
567  result = -ENOMEM;
568  break;
569  }
570  pNodeList->uItem = sNodeList.uItem;
571  pNode = &(pMgmt->sNodeDBTable[0]);
572  for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) {
573  pNode = &(pMgmt->sNodeDBTable[ii]);
574  if (pNode->bActive) {
575  pNodeList->sNodeList[jj].wAID = pNode->wAID;
576  memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN);
577  pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate;
578  pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount;
579  pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt;
580  pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags;
581  pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable;
582  pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
583  pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
584  memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN);
585  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
586  pNodeList->sNodeList[jj].abyWepKey[0],
587  pNodeList->sNodeList[jj].abyWepKey[1],
588  pNodeList->sNodeList[jj].abyWepKey[2],
589  pNodeList->sNodeList[jj].abyWepKey[3],
590  pNodeList->sNodeList[jj].abyWepKey[4]);
591  pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback;
592  pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures;
593  pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts;
594  pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio;
595  jj++;
596  if (jj >= pNodeList->uItem)
597  break;
598  }
599  }
600  if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
601  kfree(pNodeList);
602  result = -EFAULT;
603  break;
604  }
605  kfree(pNodeList);
606  pReq->wResult = 0;
607  break;
608 
609  case 0xFF:
610  memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
611  wpa_Result.proto = 0;
612  wpa_Result.key_mgmt = 0;
613  wpa_Result.eap_type = 0;
614  wpa_Result.authenticated = FALSE;
615  pDevice->fWPA_Authened = FALSE;
616  if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
617  result = -EFAULT;
618  break;
619  }
620  /* for some AP's maybe a good authentication */
621  if (wpa_Result.key_mgmt == 0x20)
622  pMgmt->Cisco_cckm = 1;
623  else
624  pMgmt->Cisco_cckm = 0;
625 
626  if (wpa_Result.authenticated == TRUE) {
627  {
628  union iwreq_data wrqu;
629 
630  pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
631  memset(&wrqu, 0, sizeof(wrqu));
632  wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG;
633  wrqu.data.length = pItemSSID->len;
634  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
635  }
636 
637  pDevice->fWPA_Authened = TRUE; /* is successful peer to wpa_Result.authenticated? */
638  }
639 
640  pReq->wResult = 0;
641  break;
642 
643  default:
644  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not supported..\n");
645  }
646 
647  return result;
648 }