PageRenderTime 96ms CodeModel.GetById 42ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/staging/vt6656/iwctl.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 2087 lines | 1452 code | 287 blank | 348 comment | 280 complexity | 3f2070c41f58ea24375a8611f9b57bb2 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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: iwctl.c
  20. *
  21. * Purpose: wireless ext & ioctl functions
  22. *
  23. * Author: Lyndon Chen
  24. *
  25. * Date: July 5, 2006
  26. *
  27. * Functions:
  28. *
  29. * Revision History:
  30. *
  31. */
  32. #include "device.h"
  33. #include "ioctl.h"
  34. #include "iocmd.h"
  35. #include "mac.h"
  36. #include "card.h"
  37. #include "hostap.h"
  38. #include "power.h"
  39. #include "rf.h"
  40. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  41. #include "iowpa.h"
  42. #include "wpactl.h"
  43. #endif
  44. #include <net/iw_handler.h>
  45. /*--------------------- Static Definitions -------------------------*/
  46. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  47. #define SUPPORTED_WIRELESS_EXT 18
  48. #else
  49. #define SUPPORTED_WIRELESS_EXT 17
  50. #endif
  51. static const long frequency_list[] = {
  52. 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
  53. 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
  54. 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
  55. 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
  56. 5700, 5745, 5765, 5785, 5805, 5825
  57. };
  58. /*--------------------- Static Classes ----------------------------*/
  59. //static int msglevel =MSG_LEVEL_DEBUG;
  60. static int msglevel =MSG_LEVEL_INFO;
  61. /*--------------------- Static Variables --------------------------*/
  62. /*--------------------- Static Functions --------------------------*/
  63. /*--------------------- Export Variables --------------------------*/
  64. struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
  65. {
  66. PSDevice pDevice = netdev_priv(dev);
  67. long ldBm;
  68. pDevice->wstats.status = pDevice->eOPMode;
  69. if(pDevice->scStatistic.LinkQuality > 100)
  70. pDevice->scStatistic.LinkQuality = 100;
  71. pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
  72. RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
  73. pDevice->wstats.qual.level = ldBm;
  74. //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
  75. pDevice->wstats.qual.noise = 0;
  76. pDevice->wstats.qual.updated = 1;
  77. pDevice->wstats.discard.nwid = 0;
  78. pDevice->wstats.discard.code = 0;
  79. pDevice->wstats.discard.fragment = 0;
  80. pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
  81. pDevice->wstats.discard.misc = 0;
  82. pDevice->wstats.miss.beacon = 0;
  83. return &pDevice->wstats;
  84. }
  85. /*------------------------------------------------------------------*/
  86. static int iwctl_commit(struct net_device *dev,
  87. struct iw_request_info *info,
  88. void *wrq,
  89. char *extra)
  90. {
  91. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n");
  92. return 0;
  93. }
  94. /*
  95. * Wireless Handler : get protocol name
  96. */
  97. int iwctl_giwname(struct net_device *dev,
  98. struct iw_request_info *info,
  99. char *wrq,
  100. char *extra)
  101. {
  102. strcpy(wrq, "802.11-a/b/g");
  103. return 0;
  104. }
  105. int iwctl_giwnwid(struct net_device *dev,
  106. struct iw_request_info *info,
  107. struct iw_param *wrq,
  108. char *extra)
  109. {
  110. //wrq->value = 0x100;
  111. //wrq->disabled = 0;
  112. //wrq->fixed = 1;
  113. //return 0;
  114. return -EOPNOTSUPP;
  115. }
  116. /*
  117. * Wireless Handler : set scan
  118. */
  119. int iwctl_siwscan(struct net_device *dev,
  120. struct iw_request_info *info,
  121. struct iw_point *wrq,
  122. char *extra)
  123. {
  124. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  125. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  126. struct iw_scan_req *req = (struct iw_scan_req *)extra;
  127. BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
  128. PWLAN_IE_SSID pItemSSID=NULL;
  129. if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
  130. return -EINVAL;
  131. PRINT_K(" SIOCSIWSCAN \n");
  132. if (pMgmt->eScanState == WMAC_IS_SCANNING) {
  133. // In scanning..
  134. PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
  135. return -EAGAIN;
  136. }
  137. if(pDevice->byReAssocCount > 0) { //reject scan when re-associating!
  138. //send scan event to wpa_Supplicant
  139. union iwreq_data wrqu;
  140. PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
  141. memset(&wrqu, 0, sizeof(wrqu));
  142. wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
  143. return 0;
  144. }
  145. spin_lock_irq(&pDevice->lock);
  146. BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
  147. //mike add: active scan OR passive scan OR desire_ssid scan
  148. if(wrq->length == sizeof(struct iw_scan_req)) {
  149. if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan
  150. memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
  151. pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
  152. pItemSSID->byElementID = WLAN_EID_SSID;
  153. memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
  154. if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
  155. if(req->essid_len>0)
  156. pItemSSID->len = req->essid_len - 1;
  157. }
  158. else
  159. pItemSSID->len = req->essid_len;
  160. pMgmt->eScanType = WMAC_SCAN_PASSIVE;
  161. PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
  162. ((PWLAN_IE_SSID)abyScanSSID)->len);
  163. bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
  164. spin_unlock_irq(&pDevice->lock);
  165. return 0;
  166. }
  167. else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan
  168. pMgmt->eScanType = WMAC_SCAN_PASSIVE;
  169. }
  170. }
  171. else { //active scan
  172. pMgmt->eScanType = WMAC_SCAN_ACTIVE;
  173. }
  174. pMgmt->eScanType = WMAC_SCAN_PASSIVE;
  175. //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
  176. bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
  177. spin_unlock_irq(&pDevice->lock);
  178. return 0;
  179. }
  180. /*
  181. * Wireless Handler : get scan results
  182. */
  183. int iwctl_giwscan(struct net_device *dev,
  184. struct iw_request_info *info,
  185. struct iw_point *wrq,
  186. char *extra)
  187. {
  188. int ii, jj, kk;
  189. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  190. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  191. PKnownBSS pBSS;
  192. PWLAN_IE_SSID pItemSSID;
  193. PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
  194. char *current_ev = extra;
  195. char *end_buf = extra + IW_SCAN_MAX_DATA;
  196. char *current_val = NULL;
  197. struct iw_event iwe;
  198. long ldBm;
  199. char buf[MAX_WPA_IE_LEN * 2 + 30];
  200. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
  201. if (pMgmt->eScanState == WMAC_IS_SCANNING) {
  202. // In scanning..
  203. return -EAGAIN;
  204. }
  205. pBSS = &(pMgmt->sBSSList[0]);
  206. for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
  207. if (current_ev >= end_buf)
  208. break;
  209. pBSS = &(pMgmt->sBSSList[jj]);
  210. if (pBSS->bActive) {
  211. //ADD mac address
  212. memset(&iwe, 0, sizeof(iwe));
  213. iwe.cmd = SIOCGIWAP;
  214. iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
  215. memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
  216. current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
  217. //ADD ssid
  218. memset(&iwe, 0, sizeof(iwe));
  219. iwe.cmd = SIOCGIWESSID;
  220. pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
  221. iwe.u.data.length = pItemSSID->len;
  222. iwe.u.data.flags = 1;
  223. current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
  224. //ADD mode
  225. memset(&iwe, 0, sizeof(iwe));
  226. iwe.cmd = SIOCGIWMODE;
  227. if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
  228. iwe.u.mode = IW_MODE_INFRA;
  229. }
  230. else {
  231. iwe.u.mode = IW_MODE_ADHOC;
  232. }
  233. iwe.len = IW_EV_UINT_LEN;
  234. current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
  235. //ADD frequency
  236. pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
  237. pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
  238. memset(&iwe, 0, sizeof(iwe));
  239. iwe.cmd = SIOCGIWFREQ;
  240. iwe.u.freq.m = pBSS->uChannel;
  241. iwe.u.freq.e = 0;
  242. iwe.u.freq.i = 0;
  243. current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
  244. {
  245. int f = (int)pBSS->uChannel - 1;
  246. if(f < 0)f = 0;
  247. iwe.u.freq.m = frequency_list[f] * 100000;
  248. iwe.u.freq.e = 1;
  249. }
  250. current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
  251. //ADD quality
  252. memset(&iwe, 0, sizeof(iwe));
  253. iwe.cmd = IWEVQUAL;
  254. RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
  255. iwe.u.qual.level = ldBm;
  256. iwe.u.qual.noise = 0;
  257. if(-ldBm<50){
  258. iwe.u.qual.qual = 100;
  259. }else if(-ldBm > 90) {
  260. iwe.u.qual.qual = 0;
  261. }else {
  262. iwe.u.qual.qual=(40-(-ldBm-50))*100/40;
  263. }
  264. iwe.u.qual.updated=7;
  265. current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
  266. //ADD encryption
  267. memset(&iwe, 0, sizeof(iwe));
  268. iwe.cmd = SIOCGIWENCODE;
  269. iwe.u.data.length = 0;
  270. if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
  271. iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
  272. }else {
  273. iwe.u.data.flags = IW_ENCODE_DISABLED;
  274. }
  275. current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
  276. memset(&iwe, 0, sizeof(iwe));
  277. iwe.cmd = SIOCGIWRATE;
  278. iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
  279. current_val = current_ev + IW_EV_LCP_LEN;
  280. for (kk = 0 ; kk < 12 ; kk++) {
  281. if (pSuppRates->abyRates[kk] == 0)
  282. break;
  283. // Bit rate given in 500 kb/s units (+ 0x80)
  284. iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
  285. current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
  286. }
  287. for (kk = 0 ; kk < 8 ; kk++) {
  288. if (pExtSuppRates->abyRates[kk] == 0)
  289. break;
  290. // Bit rate given in 500 kb/s units (+ 0x80)
  291. iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
  292. current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
  293. }
  294. if((current_val - current_ev) > IW_EV_LCP_LEN)
  295. current_ev = current_val;
  296. memset(&iwe, 0, sizeof(iwe));
  297. iwe.cmd = IWEVCUSTOM;
  298. sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
  299. iwe.u.data.length = strlen(buf);
  300. current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
  301. if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
  302. memset(&iwe, 0, sizeof(iwe));
  303. iwe.cmd = IWEVGENIE;
  304. iwe.u.data.length = pBSS->wWPALen;
  305. current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE);
  306. }
  307. if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
  308. memset(&iwe, 0, sizeof(iwe));
  309. iwe.cmd = IWEVGENIE;
  310. iwe.u.data.length = pBSS->wRSNLen;
  311. current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
  312. }
  313. }
  314. }// for
  315. wrq->length = current_ev - extra;
  316. return 0;
  317. }
  318. /*
  319. * Wireless Handler : set frequence or channel
  320. */
  321. int iwctl_siwfreq(struct net_device *dev,
  322. struct iw_request_info *info,
  323. struct iw_freq *wrq,
  324. char *extra)
  325. {
  326. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  327. int rc = 0;
  328. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
  329. // If setting by frequency, convert to a channel
  330. if((wrq->e == 1) &&
  331. (wrq->m >= (int) 2.412e8) &&
  332. (wrq->m <= (int) 2.487e8)) {
  333. int f = wrq->m / 100000;
  334. int c = 0;
  335. while((c < 14) && (f != frequency_list[c]))
  336. c++;
  337. wrq->e = 0;
  338. wrq->m = c + 1;
  339. }
  340. // Setting by channel number
  341. if((wrq->m > 14) || (wrq->e > 0))
  342. rc = -EOPNOTSUPP;
  343. else {
  344. int channel = wrq->m;
  345. if((channel < 1) || (channel > 14)) {
  346. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
  347. rc = -EINVAL;
  348. } else {
  349. // Yes ! We can set it !!!
  350. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
  351. pDevice->uChannel = channel;
  352. }
  353. }
  354. return rc;
  355. }
  356. /*
  357. * Wireless Handler : get frequence or channel
  358. */
  359. int iwctl_giwfreq(struct net_device *dev,
  360. struct iw_request_info *info,
  361. struct iw_freq *wrq,
  362. char *extra)
  363. {
  364. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  365. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  366. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
  367. #ifdef WEXT_USECHANNELS
  368. wrq->m = (int)pMgmt->uCurrChannel;
  369. wrq->e = 0;
  370. #else
  371. {
  372. int f = (int)pMgmt->uCurrChannel - 1;
  373. if(f < 0)
  374. f = 0;
  375. wrq->m = frequency_list[f] * 100000;
  376. wrq->e = 1;
  377. }
  378. #endif
  379. return 0;
  380. }
  381. /*
  382. * Wireless Handler : set operation mode
  383. */
  384. int iwctl_siwmode(struct net_device *dev,
  385. struct iw_request_info *info,
  386. __u32 *wmode,
  387. char *extra)
  388. {
  389. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  390. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  391. int rc = 0;
  392. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
  393. if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
  394. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
  395. return rc;
  396. }
  397. switch(*wmode) {
  398. case IW_MODE_ADHOC:
  399. if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
  400. pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
  401. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  402. pDevice->bCommit = TRUE;
  403. }
  404. }
  405. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
  406. break;
  407. case IW_MODE_AUTO:
  408. case IW_MODE_INFRA:
  409. if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
  410. pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
  411. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  412. pDevice->bCommit = TRUE;
  413. }
  414. }
  415. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
  416. break;
  417. case IW_MODE_MASTER:
  418. pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
  419. rc = -EOPNOTSUPP;
  420. break;
  421. if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
  422. pMgmt->eConfigMode = WMAC_CONFIG_AP;
  423. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  424. pDevice->bCommit = TRUE;
  425. }
  426. }
  427. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
  428. break;
  429. case IW_MODE_REPEAT:
  430. pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
  431. rc = -EOPNOTSUPP;
  432. break;
  433. default:
  434. rc = -EINVAL;
  435. }
  436. return rc;
  437. }
  438. /*
  439. * Wireless Handler : get operation mode
  440. */
  441. int iwctl_giwmode(struct net_device *dev,
  442. struct iw_request_info *info,
  443. __u32 *wmode,
  444. char *extra)
  445. {
  446. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  447. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  448. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
  449. // If not managed, assume it's ad-hoc
  450. switch (pMgmt->eConfigMode) {
  451. case WMAC_CONFIG_ESS_STA:
  452. *wmode = IW_MODE_INFRA;
  453. break;
  454. case WMAC_CONFIG_IBSS_STA:
  455. *wmode = IW_MODE_ADHOC;
  456. break;
  457. case WMAC_CONFIG_AUTO:
  458. *wmode = IW_MODE_INFRA;
  459. break;
  460. case WMAC_CONFIG_AP:
  461. *wmode = IW_MODE_MASTER;
  462. break;
  463. default:
  464. *wmode = IW_MODE_ADHOC;
  465. }
  466. return 0;
  467. }
  468. /*
  469. * Wireless Handler : get capability range
  470. */
  471. int iwctl_giwrange(struct net_device *dev,
  472. struct iw_request_info *info,
  473. struct iw_point *wrq,
  474. char *extra)
  475. {
  476. struct iw_range *range = (struct iw_range *) extra;
  477. int i,k;
  478. BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
  479. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
  480. if (wrq->pointer) {
  481. wrq->length = sizeof(struct iw_range);
  482. memset(range, 0, sizeof(struct iw_range));
  483. range->min_nwid = 0x0000;
  484. range->max_nwid = 0x0000;
  485. range->num_channels = 14;
  486. // Should be based on cap_rid.country to give only
  487. // what the current card support
  488. k = 0;
  489. for (i = 0; i < 14; i++) {
  490. range->freq[k].i = i + 1; // List index
  491. range->freq[k].m = frequency_list[i] * 100000;
  492. range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
  493. }
  494. range->num_frequency = k;
  495. // Hum... Should put the right values there
  496. range->max_qual.qual = 100;
  497. range->max_qual.level = 0;
  498. range->max_qual.noise = 0;
  499. range->sensitivity = 255;
  500. for (i = 0 ; i < 13 ; i++) {
  501. range->bitrate[i] = abySupportedRates[i] * 500000;
  502. if(range->bitrate[i] == 0)
  503. break;
  504. }
  505. range->num_bitrates = i;
  506. // Set an indication of the max TCP throughput
  507. // in bit/s that we can expect using this interface.
  508. // May be use for QoS stuff... Jean II
  509. if(i > 2)
  510. range->throughput = 5 * 1000 * 1000;
  511. else
  512. range->throughput = 1.5 * 1000 * 1000;
  513. range->min_rts = 0;
  514. range->max_rts = 2312;
  515. range->min_frag = 256;
  516. range->max_frag = 2312;
  517. // the encoding capabilities
  518. range->num_encoding_sizes = 3;
  519. // 64(40) bits WEP
  520. range->encoding_size[0] = 5;
  521. // 128(104) bits WEP
  522. range->encoding_size[1] = 13;
  523. // 256 bits for WPA-PSK
  524. range->encoding_size[2] = 32;
  525. // 4 keys are allowed
  526. range->max_encoding_tokens = 4;
  527. range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
  528. IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
  529. range->min_pmp = 0;
  530. range->max_pmp = 1000000;// 1 secs
  531. range->min_pmt = 0;
  532. range->max_pmt = 1000000;// 1 secs
  533. range->pmp_flags = IW_POWER_PERIOD;
  534. range->pmt_flags = IW_POWER_TIMEOUT;
  535. range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
  536. // Transmit Power - values are in mW
  537. range->txpower[0] = 100;
  538. range->num_txpower = 1;
  539. range->txpower_capa = IW_TXPOW_MWATT;
  540. range->we_version_source = SUPPORTED_WIRELESS_EXT;
  541. range->we_version_compiled = WIRELESS_EXT;
  542. range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
  543. range->retry_flags = IW_RETRY_LIMIT;
  544. range->r_time_flags = IW_RETRY_LIFETIME;
  545. range->min_retry = 1;
  546. range->max_retry = 65535;
  547. range->min_r_time = 1024;
  548. range->max_r_time = 65535 * 1024;
  549. // Experimental measurements - boundary 11/5.5 Mb/s
  550. // Note : with or without the (local->rssi), results
  551. // are somewhat different. - Jean II
  552. range->avg_qual.qual = 6;
  553. range->avg_qual.level = 176; // -80 dBm
  554. range->avg_qual.noise = 0;
  555. }
  556. return 0;
  557. }
  558. /*
  559. * Wireless Handler : set ap mac address
  560. */
  561. int iwctl_siwap(struct net_device *dev,
  562. struct iw_request_info *info,
  563. struct sockaddr *wrq,
  564. char *extra)
  565. {
  566. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  567. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  568. int rc = 0;
  569. BYTE ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
  570. PRINT_K(" SIOCSIWAP \n");
  571. if (wrq->sa_family != ARPHRD_ETHER)
  572. rc = -EINVAL;
  573. else {
  574. memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
  575. //mike :add
  576. if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
  577. (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
  578. PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
  579. return rc;
  580. }
  581. //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
  582. // then ignore,because you don't known which one to be connect with??
  583. {
  584. unsigned int ii, uSameBssidNum = 0;
  585. for (ii = 0; ii < MAX_BSS_NUM; ii++) {
  586. if (pMgmt->sBSSList[ii].bActive &&
  587. !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
  588. pMgmt->abyDesireBSSID)) {
  589. uSameBssidNum++;
  590. }
  591. }
  592. if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
  593. PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
  594. return rc;
  595. }
  596. }
  597. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  598. pDevice->bCommit = TRUE;
  599. }
  600. }
  601. return rc;
  602. }
  603. /*
  604. * Wireless Handler : get ap mac address
  605. */
  606. int iwctl_giwap(struct net_device *dev,
  607. struct iw_request_info *info,
  608. struct sockaddr *wrq,
  609. char *extra)
  610. {
  611. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  612. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  613. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
  614. memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
  615. //20080123-02,<Modify> by Einsn Liu
  616. if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
  617. // if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
  618. memset(wrq->sa_data, 0, 6);
  619. if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
  620. memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
  621. }
  622. wrq->sa_family = ARPHRD_ETHER;
  623. return 0;
  624. }
  625. /*
  626. * Wireless Handler : get ap list
  627. */
  628. int iwctl_giwaplist(struct net_device *dev,
  629. struct iw_request_info *info,
  630. struct iw_point *wrq,
  631. char *extra)
  632. {
  633. int ii,jj, rc = 0;
  634. struct sockaddr sock[IW_MAX_AP];
  635. struct iw_quality qual[IW_MAX_AP];
  636. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  637. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  638. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
  639. // Only super-user can see AP list
  640. if (!capable(CAP_NET_ADMIN)) {
  641. rc = -EPERM;
  642. return rc;
  643. }
  644. if (wrq->pointer) {
  645. PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
  646. for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
  647. pBSS = &(pMgmt->sBSSList[ii]);
  648. if (!pBSS->bActive)
  649. continue;
  650. if ( jj >= IW_MAX_AP)
  651. break;
  652. memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
  653. sock[jj].sa_family = ARPHRD_ETHER;
  654. qual[jj].level = pBSS->uRSSI;
  655. qual[jj].qual = qual[jj].noise = 0;
  656. qual[jj].updated = 2;
  657. jj++;
  658. }
  659. wrq->flags = 1; // Should be define'd
  660. wrq->length = jj;
  661. memcpy(extra, sock, sizeof(struct sockaddr)*jj);
  662. memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
  663. }
  664. return rc;
  665. }
  666. /*
  667. * Wireless Handler : set essid
  668. */
  669. int iwctl_siwessid(struct net_device *dev,
  670. struct iw_request_info *info,
  671. struct iw_point *wrq,
  672. char *extra)
  673. {
  674. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  675. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  676. PWLAN_IE_SSID pItemSSID;
  677. if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
  678. return -EINVAL;
  679. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
  680. pDevice->fWPA_Authened = FALSE;
  681. // Check if we asked for `any'
  682. if(wrq->flags == 0) {
  683. // Just send an empty SSID list
  684. memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
  685. memset(pMgmt->abyDesireBSSID, 0xFF,6);
  686. PRINT_K("set essid to 'any' \n");
  687. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  688. //Unknown desired AP,so here need not associate??
  689. return 0;
  690. #endif
  691. } else {
  692. // Set the SSID
  693. memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
  694. pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
  695. pItemSSID->byElementID = WLAN_EID_SSID;
  696. memcpy(pItemSSID->abySSID, extra, wrq->length);
  697. if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
  698. if(wrq->length>0)
  699. pItemSSID->len = wrq->length - 1;
  700. }
  701. else
  702. pItemSSID->len = wrq->length;
  703. PRINT_K("set essid to %s \n",pItemSSID->abySSID);
  704. //mike:need clear desiredBSSID
  705. if(pItemSSID->len==0) {
  706. memset(pMgmt->abyDesireBSSID, 0xFF,6);
  707. return 0;
  708. }
  709. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  710. //Wext wil order another command of siwap to link with desired AP,
  711. //so here need not associate??
  712. if(pDevice->bWPASuppWextEnabled == TRUE) {
  713. /*******search if in hidden ssid mode ****/
  714. {
  715. PKnownBSS pCurr = NULL;
  716. BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
  717. unsigned int ii, uSameBssidNum = 0;
  718. memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
  719. pCurr = BSSpSearchBSSList(pDevice,
  720. NULL,
  721. abyTmpDesireSSID,
  722. pDevice->eConfigPHYMode
  723. );
  724. if (pCurr == NULL){
  725. PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
  726. vResetCommandTimer((void *) pDevice);
  727. pMgmt->eScanType = WMAC_SCAN_ACTIVE;
  728. bScheduleCommand((void *) pDevice,
  729. WLAN_CMD_BSSID_SCAN,
  730. pMgmt->abyDesireSSID);
  731. bScheduleCommand((void *) pDevice,
  732. WLAN_CMD_SSID,
  733. pMgmt->abyDesireSSID);
  734. }
  735. else { //mike:to find out if that desired SSID is a hidden-ssid AP ,
  736. // by means of judging if there are two same BSSID exist in list ?
  737. for (ii = 0; ii < MAX_BSS_NUM; ii++) {
  738. if (pMgmt->sBSSList[ii].bActive &&
  739. !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
  740. pCurr->abyBSSID)) {
  741. uSameBssidNum++;
  742. }
  743. }
  744. if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
  745. PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
  746. vResetCommandTimer((void *) pDevice);
  747. pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result!
  748. bScheduleCommand((void *) pDevice,
  749. WLAN_CMD_BSSID_SCAN,
  750. pMgmt->abyDesireSSID);
  751. bScheduleCommand((void *) pDevice,
  752. WLAN_CMD_SSID,
  753. pMgmt->abyDesireSSID);
  754. }
  755. }
  756. }
  757. return 0;
  758. }
  759. #endif
  760. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
  761. }
  762. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  763. pDevice->bCommit = TRUE;
  764. }
  765. return 0;
  766. }
  767. /*
  768. * Wireless Handler : get essid
  769. */
  770. int iwctl_giwessid(struct net_device *dev,
  771. struct iw_request_info *info,
  772. struct iw_point *wrq,
  773. char *extra)
  774. {
  775. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  776. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  777. PWLAN_IE_SSID pItemSSID;
  778. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
  779. // Note : if wrq->u.data.flags != 0, we should
  780. // get the relevant SSID from the SSID list...
  781. // Get the current SSID
  782. pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
  783. //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
  784. memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
  785. extra[pItemSSID->len] = '\0';
  786. wrq->length = pItemSSID->len;
  787. wrq->flags = 1; // active
  788. return 0;
  789. }
  790. /*
  791. * Wireless Handler : set data rate
  792. */
  793. int iwctl_siwrate(struct net_device *dev,
  794. struct iw_request_info *info,
  795. struct iw_param *wrq,
  796. char *extra)
  797. {
  798. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  799. int rc = 0;
  800. u8 brate = 0;
  801. int i;
  802. BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
  803. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
  804. if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
  805. rc = -EINVAL;
  806. return rc;
  807. }
  808. // First : get a valid bit rate value
  809. // Which type of value
  810. if((wrq->value < 13) &&
  811. (wrq->value >= 0)) {
  812. // Setting by rate index
  813. // Find value in the magic rate table
  814. brate = wrq->value;
  815. } else {
  816. // Setting by frequency value
  817. u8 normvalue = (u8) (wrq->value/500000);
  818. // Check if rate is valid
  819. for (i = 0 ; i < 13 ; i++) {
  820. if(normvalue == abySupportedRates[i]) {
  821. brate = i;
  822. break;
  823. }
  824. }
  825. }
  826. // -1 designed the max rate (mostly auto mode)
  827. if(wrq->value == -1) {
  828. // Get the highest available rate
  829. for (i = 0 ; i < 13 ; i++) {
  830. if(abySupportedRates[i] == 0)
  831. break;
  832. }
  833. if(i != 0)
  834. brate = i - 1;
  835. }
  836. // Check that it is valid
  837. // brate is index of abySupportedRates[]
  838. if(brate > 13 ) {
  839. rc = -EINVAL;
  840. return rc;
  841. }
  842. // Now, check if we want a fixed or auto value
  843. if(wrq->fixed != 0) {
  844. // Fixed mode
  845. // One rate, fixed
  846. pDevice->bFixRate = TRUE;
  847. if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
  848. pDevice->uConnectionRate = 3;
  849. }
  850. else {
  851. pDevice->uConnectionRate = brate;
  852. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
  853. }
  854. }
  855. else {
  856. pDevice->bFixRate = FALSE;
  857. pDevice->uConnectionRate = 13;
  858. }
  859. return rc;
  860. }
  861. /*
  862. * Wireless Handler : get data rate
  863. */
  864. int iwctl_giwrate(struct net_device *dev,
  865. struct iw_request_info *info,
  866. struct iw_param *wrq,
  867. char *extra)
  868. {
  869. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  870. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  871. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
  872. {
  873. BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
  874. int brate = 0;
  875. if (pDevice->uConnectionRate < 13) {
  876. brate = abySupportedRates[pDevice->uConnectionRate];
  877. }else {
  878. if (pDevice->byBBType == BB_TYPE_11B)
  879. brate = 0x16;
  880. if (pDevice->byBBType == BB_TYPE_11G)
  881. brate = 0x6C;
  882. if (pDevice->byBBType == BB_TYPE_11A)
  883. brate = 0x6C;
  884. }
  885. if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
  886. if (pDevice->byBBType == BB_TYPE_11B)
  887. brate = 0x16;
  888. if (pDevice->byBBType == BB_TYPE_11G)
  889. brate = 0x6C;
  890. if (pDevice->byBBType == BB_TYPE_11A)
  891. brate = 0x6C;
  892. }
  893. if (pDevice->uConnectionRate == 13)
  894. brate = abySupportedRates[pDevice->wCurrentRate];
  895. wrq->value = brate * 500000;
  896. // If more than one rate, set auto
  897. if (pDevice->bFixRate == TRUE)
  898. wrq->fixed = TRUE;
  899. }
  900. return 0;
  901. }
  902. /*
  903. * Wireless Handler : set rts threshold
  904. */
  905. int iwctl_siwrts(struct net_device *dev,
  906. struct iw_request_info *info,
  907. struct iw_param *wrq,
  908. char *extra)
  909. {
  910. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  911. int rc = 0;
  912. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
  913. {
  914. int rthr = wrq->value;
  915. if(wrq->disabled)
  916. rthr = 2312;
  917. if((rthr < 0) || (rthr > 2312)) {
  918. rc = -EINVAL;
  919. }else {
  920. pDevice->wRTSThreshold = rthr;
  921. }
  922. }
  923. return 0;
  924. }
  925. /*
  926. * Wireless Handler : get rts
  927. */
  928. int iwctl_giwrts(struct net_device *dev,
  929. struct iw_request_info *info,
  930. struct iw_param *wrq,
  931. char *extra)
  932. {
  933. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  934. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
  935. wrq->value = pDevice->wRTSThreshold;
  936. wrq->disabled = (wrq->value >= 2312);
  937. wrq->fixed = 1;
  938. return 0;
  939. }
  940. /*
  941. * Wireless Handler : set fragment threshold
  942. */
  943. int iwctl_siwfrag(struct net_device *dev,
  944. struct iw_request_info *info,
  945. struct iw_param *wrq,
  946. char *extra)
  947. {
  948. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  949. int rc = 0;
  950. int fthr = wrq->value;
  951. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
  952. if (wrq->disabled)
  953. fthr = 2312;
  954. if((fthr < 256) || (fthr > 2312)) {
  955. rc = -EINVAL;
  956. }else {
  957. fthr &= ~0x1; // Get an even value
  958. pDevice->wFragmentationThreshold = (u16)fthr;
  959. }
  960. return rc;
  961. }
  962. /*
  963. * Wireless Handler : get fragment threshold
  964. */
  965. int iwctl_giwfrag(struct net_device *dev,
  966. struct iw_request_info *info,
  967. struct iw_param *wrq,
  968. char *extra)
  969. {
  970. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  971. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
  972. wrq->value = pDevice->wFragmentationThreshold;
  973. wrq->disabled = (wrq->value >= 2312);
  974. wrq->fixed = 1;
  975. return 0;
  976. }
  977. /*
  978. * Wireless Handler : set retry threshold
  979. */
  980. int iwctl_siwretry(struct net_device *dev,
  981. struct iw_request_info *info,
  982. struct iw_param *wrq,
  983. char *extra)
  984. {
  985. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  986. int rc = 0;
  987. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
  988. if (wrq->disabled) {
  989. rc = -EINVAL;
  990. return rc;
  991. }
  992. if (wrq->flags & IW_RETRY_LIMIT) {
  993. if(wrq->flags & IW_RETRY_MAX)
  994. pDevice->byLongRetryLimit = wrq->value;
  995. else if (wrq->flags & IW_RETRY_MIN)
  996. pDevice->byShortRetryLimit = wrq->value;
  997. else {
  998. // No modifier : set both
  999. pDevice->byShortRetryLimit = wrq->value;
  1000. pDevice->byLongRetryLimit = wrq->value;
  1001. }
  1002. }
  1003. if (wrq->flags & IW_RETRY_LIFETIME) {
  1004. pDevice->wMaxTransmitMSDULifetime = wrq->value;
  1005. }
  1006. return rc;
  1007. }
  1008. /*
  1009. * Wireless Handler : get retry threshold
  1010. */
  1011. int iwctl_giwretry(struct net_device *dev,
  1012. struct iw_request_info *info,
  1013. struct iw_param *wrq,
  1014. char *extra)
  1015. {
  1016. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1017. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
  1018. wrq->disabled = 0; // Can't be disabled
  1019. // Note : by default, display the min retry number
  1020. if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
  1021. wrq->flags = IW_RETRY_LIFETIME;
  1022. wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
  1023. } else if((wrq->flags & IW_RETRY_MAX)) {
  1024. wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
  1025. wrq->value = (int)pDevice->byLongRetryLimit;
  1026. } else {
  1027. wrq->flags = IW_RETRY_LIMIT;
  1028. wrq->value = (int)pDevice->byShortRetryLimit;
  1029. if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
  1030. wrq->flags |= IW_RETRY_MIN;
  1031. }
  1032. return 0;
  1033. }
  1034. /*
  1035. * Wireless Handler : set encode mode
  1036. */
  1037. int iwctl_siwencode(struct net_device *dev,
  1038. struct iw_request_info *info,
  1039. struct iw_point *wrq,
  1040. char *extra)
  1041. {
  1042. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1043. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1044. DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
  1045. int ii,uu, rc = 0;
  1046. int index = (wrq->flags & IW_ENCODE_INDEX);
  1047. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
  1048. // Check the size of the key
  1049. if (wrq->length > WLAN_WEP232_KEYLEN) {
  1050. rc = -EINVAL;
  1051. return rc;
  1052. }
  1053. if (dwKeyIndex > WLAN_WEP_NKEYS) {
  1054. rc = -EINVAL;
  1055. return rc;
  1056. }
  1057. if (dwKeyIndex > 0)
  1058. dwKeyIndex--;
  1059. // Send the key to the card
  1060. if (wrq->length > 0) {
  1061. if (wrq->length == WLAN_WEP232_KEYLEN) {
  1062. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
  1063. }
  1064. else if (wrq->length == WLAN_WEP104_KEYLEN) {
  1065. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
  1066. }
  1067. else if (wrq->length == WLAN_WEP40_KEYLEN) {
  1068. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
  1069. }
  1070. memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
  1071. memcpy(pDevice->abyKey, extra, wrq->length);
  1072. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
  1073. for (ii = 0; ii < wrq->length; ii++) {
  1074. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
  1075. }
  1076. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  1077. spin_lock_irq(&pDevice->lock);
  1078. KeybSetDefaultKey( pDevice,
  1079. &(pDevice->sKey),
  1080. dwKeyIndex | (1 << 31),
  1081. wrq->length,
  1082. NULL,
  1083. pDevice->abyKey,
  1084. KEY_CTL_WEP
  1085. );
  1086. spin_unlock_irq(&pDevice->lock);
  1087. }
  1088. pDevice->byKeyIndex = (BYTE)dwKeyIndex;
  1089. pDevice->uKeyLength = wrq->length;
  1090. pDevice->bTransmitKey = TRUE;
  1091. pDevice->bEncryptionEnable = TRUE;
  1092. pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
  1093. // Do we want to just set the transmit key index ?
  1094. if ( index < 4 ) {
  1095. pDevice->byKeyIndex = index;
  1096. } else if (!(wrq->flags & IW_ENCODE_MODE)) {
  1097. rc = -EINVAL;
  1098. return rc;
  1099. }
  1100. }
  1101. // Read the flags
  1102. if(wrq->flags & IW_ENCODE_DISABLED){
  1103. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
  1104. pMgmt->bShareKeyAlgorithm = FALSE;
  1105. pDevice->bEncryptionEnable = FALSE;
  1106. pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
  1107. if (pDevice->flags & DEVICE_FLAGS_OPENED) {
  1108. spin_lock_irq(&pDevice->lock);
  1109. for (uu = 0; uu < MAX_KEY_TABLE; uu++)
  1110. MACvDisableKeyEntry(pDevice, uu);
  1111. spin_unlock_irq(&pDevice->lock);
  1112. }
  1113. }
  1114. if(wrq->flags & IW_ENCODE_RESTRICTED) {
  1115. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
  1116. pMgmt->bShareKeyAlgorithm = TRUE;
  1117. }
  1118. if(wrq->flags & IW_ENCODE_OPEN) {
  1119. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
  1120. pMgmt->bShareKeyAlgorithm = FALSE;
  1121. }
  1122. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  1123. memset(pMgmt->abyDesireBSSID, 0xFF,6);
  1124. #endif
  1125. return rc;
  1126. }
  1127. /*
  1128. * Wireless Handler : get encode mode
  1129. */
  1130. //2008-0409-06, <Mark> by Einsn Liu
  1131. /*
  1132. int iwctl_giwencode(struct net_device *dev,
  1133. struct iw_request_info *info,
  1134. struct iw_point *wrq,
  1135. char *extra)
  1136. {
  1137. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1138. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1139. int rc = 0;
  1140. char abyKey[WLAN_WEP232_KEYLEN];
  1141. unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
  1142. PSKeyItem pKey = NULL;
  1143. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
  1144. memset(abyKey, 0, sizeof(abyKey));
  1145. // Check encryption mode
  1146. wrq->flags = IW_ENCODE_NOKEY;
  1147. // Is WEP enabled ???
  1148. if (pDevice->bEncryptionEnable)
  1149. wrq->flags |= IW_ENCODE_ENABLED;
  1150. else
  1151. wrq->flags |= IW_ENCODE_DISABLED;
  1152. if (pMgmt->bShareKeyAlgorithm)
  1153. wrq->flags |= IW_ENCODE_RESTRICTED;
  1154. else
  1155. wrq->flags |= IW_ENCODE_OPEN;
  1156. if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
  1157. wrq->length = pKey->uKeyLength;
  1158. memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
  1159. }
  1160. else {
  1161. rc = -EINVAL;
  1162. return rc;
  1163. }
  1164. wrq->flags |= index;
  1165. // Copy the key to the user buffer
  1166. memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
  1167. return 0;
  1168. }
  1169. */
  1170. int iwctl_giwencode(struct net_device *dev,
  1171. struct iw_request_info *info,
  1172. struct iw_point *wrq,
  1173. char *extra)
  1174. {
  1175. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1176. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1177. char abyKey[WLAN_WEP232_KEYLEN];
  1178. unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
  1179. PSKeyItem pKey = NULL;
  1180. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
  1181. if (index > WLAN_WEP_NKEYS) {
  1182. return -EINVAL;
  1183. }
  1184. if(index<1){//get default key
  1185. if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
  1186. index=pDevice->byKeyIndex;
  1187. } else
  1188. index=0;
  1189. }else
  1190. index--;
  1191. memset(abyKey, 0, WLAN_WEP232_KEYLEN);
  1192. // Check encryption mode
  1193. wrq->flags = IW_ENCODE_NOKEY;
  1194. // Is WEP enabled ???
  1195. if (pDevice->bEncryptionEnable)
  1196. wrq->flags |= IW_ENCODE_ENABLED;
  1197. else
  1198. wrq->flags |= IW_ENCODE_DISABLED;
  1199. if (pMgmt->bShareKeyAlgorithm)
  1200. wrq->flags |= IW_ENCODE_RESTRICTED;
  1201. else
  1202. wrq->flags |= IW_ENCODE_OPEN;
  1203. wrq->length=0;
  1204. if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
  1205. pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key
  1206. if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
  1207. wrq->length = pKey->uKeyLength;
  1208. memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
  1209. memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
  1210. }
  1211. }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
  1212. wrq->length = pKey->uKeyLength;
  1213. memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
  1214. memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
  1215. }
  1216. wrq->flags |= index+1;
  1217. return 0;
  1218. }
  1219. /*
  1220. * Wireless Handler : set power mode
  1221. */
  1222. int iwctl_siwpower(struct net_device *dev,
  1223. struct iw_request_info *info,
  1224. struct iw_param *wrq,
  1225. char *extra)
  1226. {
  1227. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1228. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1229. int rc = 0;
  1230. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
  1231. if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
  1232. rc = -EINVAL;
  1233. return rc;
  1234. }
  1235. if (wrq->disabled) {
  1236. pDevice->ePSMode = WMAC_POWER_CAM;
  1237. PSvDisablePowerSaving(pDevice);
  1238. return rc;
  1239. }
  1240. if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
  1241. pDevice->ePSMode = WMAC_POWER_FAST;
  1242. PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
  1243. } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
  1244. pDevice->ePSMode = WMAC_POWER_FAST;
  1245. PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
  1246. }
  1247. switch (wrq->flags & IW_POWER_MODE) {
  1248. case IW_POWER_UNICAST_R:
  1249. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
  1250. rc = -EINVAL;
  1251. break;
  1252. case IW_POWER_ALL_R:
  1253. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
  1254. rc = -EINVAL;
  1255. case IW_POWER_ON:
  1256. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
  1257. break;
  1258. default:
  1259. rc = -EINVAL;
  1260. }
  1261. return rc;
  1262. }
  1263. /*
  1264. * Wireless Handler : get power mode
  1265. */
  1266. int iwctl_giwpower(struct net_device *dev,
  1267. struct iw_request_info *info,
  1268. struct iw_param *wrq,
  1269. char *extra)
  1270. {
  1271. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1272. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1273. int mode = pDevice->ePSMode;
  1274. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
  1275. if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
  1276. return 0;
  1277. if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
  1278. wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
  1279. wrq->flags = IW_POWER_TIMEOUT;
  1280. } else {
  1281. wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
  1282. wrq->flags = IW_POWER_PERIOD;
  1283. }
  1284. wrq->flags |= IW_POWER_ALL_R;
  1285. return 0;
  1286. }
  1287. /*
  1288. * Wireless Handler : get Sensitivity
  1289. */
  1290. int iwctl_giwsens(struct net_device *dev,
  1291. struct iw_request_info *info,
  1292. struct iw_param *wrq,
  1293. char *extra)
  1294. {
  1295. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1296. long ldBm;
  1297. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
  1298. if (pDevice->bLinkPass == TRUE) {
  1299. RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
  1300. wrq->value = ldBm;
  1301. }
  1302. else {
  1303. wrq->value = 0;
  1304. };
  1305. wrq->disabled = (wrq->value == 0);
  1306. wrq->fixed = 1;
  1307. return 0;
  1308. }
  1309. #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
  1310. int iwctl_siwauth(struct net_device *dev,
  1311. struct iw_request_info *info,
  1312. struct iw_param *wrq,
  1313. char *extra)
  1314. {
  1315. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1316. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1317. int ret=0;
  1318. static int wpa_version=0; //must be static to save the last value,einsn liu
  1319. static int pairwise=0;
  1320. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
  1321. switch (wrq->flags & IW_AUTH_INDEX) {
  1322. case IW_AUTH_WPA_VERSION:
  1323. wpa_version = wrq->value;
  1324. if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
  1325. PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
  1326. //pDevice->bWPADEVUp = FALSE;
  1327. }
  1328. else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
  1329. PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
  1330. }
  1331. else {
  1332. PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
  1333. }
  1334. //pDevice->bWPASuppWextEnabled =TRUE;
  1335. break;
  1336. case IW_AUTH_CIPHER_PAIRWISE:
  1337. pairwise = wrq->value;
  1338. PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
  1339. if(pairwise == IW_AUTH_CIPHER_CCMP){
  1340. pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
  1341. }else if(pairwise == IW_AUTH_CIPHER_TKIP){
  1342. pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
  1343. } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
  1344. pairwise == IW_AUTH_CIPHER_WEP104) {
  1345. pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
  1346. }else if(pairwise == IW_AUTH_CIPHER_NONE){
  1347. //do nothing,einsn liu
  1348. }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
  1349. break;
  1350. case IW_AUTH_CIPHER_GROUP:
  1351. PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
  1352. if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
  1353. break;
  1354. if(pairwise == IW_AUTH_CIPHER_NONE){
  1355. if(wrq->value == IW_AUTH_CIPHER_CCMP){
  1356. pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
  1357. }else {
  1358. pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
  1359. }
  1360. }
  1361. break;
  1362. case IW_AUTH_KEY_MGMT:
  1363. PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
  1364. if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
  1365. if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
  1366. pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
  1367. else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
  1368. }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
  1369. if(wrq->value == 0){
  1370. pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
  1371. }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
  1372. pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
  1373. else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
  1374. }
  1375. break;
  1376. case IW_AUTH_TKIP_COUNTERMEASURES:
  1377. break; /* FIXME */
  1378. case IW_AUTH_DROP_UNENCRYPTED:
  1379. break;
  1380. case IW_AUTH_80211_AUTH_ALG:
  1381. PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
  1382. if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
  1383. pMgmt->bShareKeyAlgorithm=FALSE;
  1384. }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
  1385. pMgmt->bShareKeyAlgorithm=TRUE;
  1386. }
  1387. break;
  1388. case IW_AUTH_WPA_ENABLED:
  1389. //pDevice->bWPADEVUp = !! wrq->value;
  1390. //if(pDevice->bWPADEVUp==TRUE)
  1391. // printk("iwctl_siwauth:set WPADEV to enable successful*******\n");
  1392. //else
  1393. // printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
  1394. break;
  1395. case IW_AUTH_RX_UNENCRYPTED_EAPOL:
  1396. break;
  1397. case IW_AUTH_ROAMING_CONTROL:
  1398. ret = -EOPNOTSUPP;
  1399. break;
  1400. case IW_AUTH_PRIVACY_INVOKED:
  1401. pDevice->bEncryptionEnable = !!wrq->value;
  1402. if(pDevice->bEncryptionEnable == FALSE){
  1403. wpa_version = 0;
  1404. pairwise = 0;
  1405. pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
  1406. pMgmt->bShareKeyAlgorithm = FALSE;
  1407. pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
  1408. //pDevice->bWPADEVUp = FALSE;
  1409. PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
  1410. }
  1411. break;
  1412. default:
  1413. ret = -EOPNOTSUPP;
  1414. break;
  1415. }
  1416. /*
  1417. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
  1418. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
  1419. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
  1420. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode = %d\n",pMgmt->eAuthenMode);
  1421. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
  1422. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
  1423. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
  1424. */
  1425. return ret;
  1426. }
  1427. int iwctl_giwauth(struct net_device *dev,
  1428. struct iw_request_info *info,
  1429. struct iw_param *wrq,
  1430. char *extra)
  1431. {
  1432. return -EOPNOTSUPP;
  1433. }
  1434. int iwctl_siwgenie(struct net_device *dev,
  1435. struct iw_request_info *info,
  1436. struct iw_point *wrq,
  1437. char *extra)
  1438. {
  1439. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1440. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1441. int ret=0;
  1442. if(wrq->length){
  1443. if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
  1444. ret = -EINVAL;
  1445. goto out;
  1446. }
  1447. if(wrq->length > MAX_WPA_IE_LEN){
  1448. ret = -ENOMEM;
  1449. goto out;
  1450. }
  1451. memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
  1452. if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
  1453. ret = -EFAULT;
  1454. goto out;
  1455. }
  1456. pMgmt->wWPAIELen = wrq->length;
  1457. }else {
  1458. memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
  1459. pMgmt->wWPAIELen = 0;
  1460. }
  1461. out://not completely ...not necessary in wpa_supplicant 0.5.8
  1462. return ret;
  1463. }
  1464. int iwctl_giwgenie(struct net_device *dev,
  1465. struct iw_request_info *info,
  1466. struct iw_point *wrq,
  1467. char *extra)
  1468. {
  1469. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1470. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1471. int ret=0;
  1472. int space = wrq->length;
  1473. wrq->length = 0;
  1474. if(pMgmt->wWPAIELen > 0){
  1475. wrq->length = pMgmt->wWPAIELen;
  1476. if(pMgmt->wWPAIELen <= space){
  1477. if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
  1478. ret = -EFAULT;
  1479. }
  1480. }else
  1481. ret = -E2BIG;
  1482. }
  1483. return ret;
  1484. }
  1485. int iwctl_siwencodeext(struct net_device *dev,
  1486. struct iw_request_info *info,
  1487. struct iw_point *wrq,
  1488. char *extra)
  1489. {
  1490. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1491. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1492. struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
  1493. struct viawget_wpa_param *param=NULL;
  1494. //original member
  1495. wpa_alg alg_name;
  1496. u8 addr[6];
  1497. int key_idx, set_tx=0;
  1498. u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
  1499. u8 key[64];
  1500. size_t seq_len=0,key_len=0;
  1501. //
  1502. // int ii;
  1503. u8 *buf;
  1504. size_t blen;
  1505. u8 key_array[64];
  1506. int ret=0;
  1507. PRINT_K("SIOCSIWENCODEEXT...... \n");
  1508. blen = sizeof(*param);
  1509. buf = kmalloc((int)blen, (int)GFP_KERNEL);
  1510. if (buf == NULL)
  1511. return -ENOMEM;
  1512. memset(buf, 0, blen);
  1513. param = (struct viawget_wpa_param *) buf;
  1514. //recover alg_name
  1515. switch (ext->alg) {
  1516. case IW_ENCODE_ALG_NONE:
  1517. alg_name = WPA_ALG_NONE;
  1518. break;
  1519. case IW_ENCODE_ALG_WEP:
  1520. alg_name = WPA_ALG_WEP;
  1521. break;
  1522. case IW_ENCODE_ALG_TKIP:
  1523. alg_name = WPA_ALG_TKIP;
  1524. break;
  1525. case IW_ENCODE_ALG_CCMP:
  1526. alg_name = WPA_ALG_CCMP;
  1527. break;
  1528. default:
  1529. PRINT_K("Unknown alg = %d\n",ext->alg);
  1530. ret= -ENOMEM;
  1531. goto error;
  1532. }
  1533. //recover addr
  1534. memcpy(addr, ext->addr.sa_data, ETH_ALEN);
  1535. //recover key_idx
  1536. key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
  1537. //recover set_tx
  1538. if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
  1539. set_tx = 1;
  1540. //recover seq,seq_len
  1541. if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
  1542. seq_len=IW_ENCODE_SEQ_MAX_SIZE;
  1543. memcpy(seq, ext->rx_seq, seq_len);
  1544. }
  1545. //recover key,key_len
  1546. if(ext->key_len) {
  1547. key_len=ext->key_len;
  1548. memcpy(key, &ext->key[0], key_len);
  1549. }
  1550. memset(key_array, 0, 64);
  1551. if ( key_len > 0) {
  1552. memcpy(key_array, key, key_len);
  1553. if (key_len == 32) {
  1554. // notice ! the oder
  1555. memcpy(&key_array[16], &key[24], 8);
  1556. memcpy(&key_array[24], &key[16], 8);
  1557. }
  1558. }
  1559. /**************Translate iw_encode_ext to viawget_wpa_param****************/
  1560. memcpy(param->addr, addr, ETH_ALEN);
  1561. param->u.wpa_key.alg_name = (int)alg_name;
  1562. param->u.wpa_key.set_tx = set_tx;
  1563. param->u.wpa_key.key_index = key_idx;
  1564. param->u.wpa_key.key_len = key_len;
  1565. param->u.wpa_key.key = (u8 *)key_array;
  1566. param->u.wpa_key.seq = (u8 *)seq;
  1567. param->u.wpa_key.seq_len = seq_len;
  1568. //****set if current action is Network Manager count??
  1569. //****this method is so foolish,but there is no other way???
  1570. if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
  1571. if(param->u.wpa_key.key_index ==0) {
  1572. pDevice->bwextstep0 = TRUE;
  1573. }
  1574. if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
  1575. pDevice->bwextstep0 = FALSE;
  1576. pDevice->bwextstep1 = TRUE;
  1577. }
  1578. if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
  1579. pDevice->bwextstep1 = FALSE;
  1580. pDevice->bwextstep2 = TRUE;
  1581. }
  1582. if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
  1583. pDevice->bwextstep2 = FALSE;
  1584. pDevice->bwextstep3 = TRUE;
  1585. }
  1586. }
  1587. if(pDevice->bwextstep3 == TRUE) {
  1588. PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
  1589. pDevice->bwextstep0 = FALSE;
  1590. pDevice->bwextstep1 = FALSE;
  1591. pDevice->bwextstep2 = FALSE;
  1592. pDevice->bwextstep3 = FALSE;
  1593. pDevice->bWPASuppWextEnabled = TRUE;
  1594. memset(pMgmt->abyDesireBSSID, 0xFF,6);
  1595. KeyvInitTable(pDevice,&pDevice->sKey);
  1596. }
  1597. //******
  1598. spin_lock_irq(&pDevice->lock);
  1599. ret = wpa_set_keys(pDevice, param, TRUE);
  1600. spin_unlock_irq(&pDevice->lock);
  1601. error:
  1602. kfree(param);
  1603. return ret;
  1604. }
  1605. int iwctl_giwencodeext(struct net_device *dev,
  1606. struct iw_request_info *info,
  1607. struct iw_point *wrq,
  1608. char *extra)
  1609. {
  1610. return -EOPNOTSUPP;
  1611. }
  1612. int iwctl_siwmlme(struct net_device *dev,
  1613. struct iw_request_info * info,
  1614. struct iw_point *wrq,
  1615. char *extra)
  1616. {
  1617. PSDevice pDevice = (PSDevice)netdev_priv(dev);
  1618. PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
  1619. struct iw_mlme *mlme = (struct iw_mlme *)extra;
  1620. //u16 reason = cpu_to_le16(mlme->reason_code);
  1621. int ret = 0;
  1622. if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
  1623. ret = -EINVAL;
  1624. return ret;
  1625. }
  1626. switch(mlme->cmd){
  1627. case IW_MLME_DEAUTH:
  1628. //this command seems to be not complete,please test it --einsnliu
  1629. //printk("iwctl_siwmlme--->send DEAUTH\n");
  1630. /* bScheduleCommand((void *) pDevice,
  1631. WLAN_CMD_DEAUTH,
  1632. (PBYTE)&reason); */
  1633. //break;
  1634. case IW_MLME_DISASSOC:
  1635. if(pDevice->bLinkPass == TRUE){
  1636. PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
  1637. bScheduleCommand((void *) pDevice,
  1638. WLAN_CMD_DISASSOCIATE,
  1639. NULL);
  1640. }
  1641. break;
  1642. default:
  1643. ret = -EOPNOTSUPP;
  1644. }
  1645. return ret;
  1646. }
  1647. #endif
  1648. /*------------------------------------------------------------------*/
  1649. /*
  1650. * Structures to export the Wireless Handlers
  1651. */
  1652. /*
  1653. static const iw_handler iwctl_handler[] =
  1654. {
  1655. (iw_handler) iwctl_commit, // SIOCSIWCOMMIT
  1656. (iw_handler) iwctl_giwname, // SIOCGIWNAME
  1657. (iw_handler) NULL, // SIOCSIWNWID
  1658. (iw_handler) NULL, // SIOCGIWNWID
  1659. (iw_handler) iwctl_siwfreq, // SIOCSIWFREQ
  1660. (iw_handler) iwctl_giwfreq, // SIOCGIWFREQ
  1661. (iw_handler) iwctl_siwmode, // SIOCSIWMODE
  1662. (iw_handler) iwctl_giwmode, // SIOCGIWMODE
  1663. (iw_handler) NULL, // SIOCSIWSENS
  1664. (iw_handler) iwctl_giwsens, // SIOCGIWSENS
  1665. (iw_handler) NULL, // SIOCSIWRANGE
  1666. (iw_handler) iwctl_giwrange, // SIOCGIWRANGE
  1667. (iw_handler) NULL, // SIOCSIWPRIV
  1668. (iw_handler) NULL, // SIOCGIWPRIV
  1669. (iw_handler) NULL, // SIOCSIWSTATS
  1670. (iw_handler) NULL, // SIOCGIWSTATS
  1671. (iw_handler) NULL, // SIOCSIWSPY
  1672. (iw_handler) NULL, // SIOCGIWSPY
  1673. (iw_handler) NULL, // -- hole --
  1674. (iw_handler) NULL, // -- hole --
  1675. (iw_handler) iwctl_siwap, // SIOCSIWAP
  1676. (iw_handler) iwctl_giwap, // SIOCGIWAP
  1677. (iw_handler) NULL, // -- hole -- 0x16
  1678. (iw_handler) iwctl_giwaplist, // SIOCGIWAPLIST
  1679. (iw_handler) iwctl_siwscan, // SIOCSIWSCAN
  1680. (iw_handler) iwctl_giwscan, // SIOCGIWSCAN
  1681. (iw_handler) iwctl_siwessid, // SIOCSIWESSID
  1682. (iw_handler) iwctl_giwessid, // SIOCGIWESSID
  1683. (iw_handler) NULL, // SIOCSIWNICKN
  1684. (iw_handler) NULL, // SIOCGIWNICKN
  1685. (iw_handler) NULL, // -- hole --
  1686. (iw_handler) NULL, // -- hole --
  1687. (iw_handler) iwctl_siwrate, // SIOCSIWRATE 0x20
  1688. (iw_handler) iwctl_giwrate, // SIOCGIWRATE
  1689. (iw_handler) iwctl_siwrts, // SIOCSIWRTS
  1690. (iw_handler) iwctl_giwrts, // SIOCGIWRTS
  1691. (iw_handler) iwctl_siwfrag, // SIOCSIWFRAG
  1692. (iw_handler) iwctl_giwfrag, // SIOCGIWFRAG
  1693. (iw_handler) NULL, // SIOCSIWTXPOW
  1694. (iw_handler) NULL, // SIOCGIWTXPOW
  1695. (iw_handler) iwctl_siwretry, // SIOCSIWRETRY
  1696. (iw_handler) iwctl_giwretry, // SIOCGIWRETRY
  1697. (iw_handler) iwctl_siwencode, // SIOCSIWENCODE
  1698. (iw_handler) iwctl_giwencode, // SIOCGIWENCODE
  1699. (iw_handler) iwctl_siwpower, // SIOCSIWPOWER
  1700. (iw_handler) iwctl_giwpower, // SIOCGIWPOWER
  1701. (iw_handler) NULL, // -- hole --
  1702. (iw_handler) NULL, // -- hole --
  1703. (iw_handler) iwctl_siwgenie, // SIOCSIWGENIE
  1704. (iw_handler) iwctl_giwgenie, // SIOCGIWGENIE
  1705. (iw_handler) iwctl_siwauth, // SIOCSIWAUTH
  1706. (iw_handler) iwctl_giwauth, // SIOCGIWAUTH
  1707. (iw_handler) iwctl_siwencodeext, // SIOCSIWENCODEEXT
  1708. (iw_handler) iwctl_giwencodeext, // SIOCGIWENCODEEXT
  1709. (iw_handler) NULL, // SIOCSIWPMKSA
  1710. (iw_handler) NULL, // -- hole --
  1711. };
  1712. */
  1713. static const iw_handler iwctl_handler[] =
  1714. {
  1715. (iw_handler) iwctl_commit, // SIOCSIWCOMMIT
  1716. (iw_handler) NULL, // SIOCGIWNAME
  1717. (iw_handler) NULL, // SIOCSIWNWID
  1718. (iw_handler) NULL, // SIOCGIWNWID
  1719. (iw_handler) NULL, // SIOCSIWFREQ
  1720. (iw_handler) NULL, // SIOCGIWFREQ
  1721. (iw_handler) NULL, // SIOCSIWMODE
  1722. (iw_handler) NULL, // SIOCGIWMODE
  1723. (iw_handler) NULL, // SIOCSIWSENS
  1724. (iw_handler) NULL, // SIOCGIWSENS
  1725. (iw_handler) NULL, // SIOCSIWRANGE
  1726. (iw_handler) iwctl_giwrange, // SIOCGIWRANGE
  1727. (iw_handler) NULL, // SIOCSIWPRIV
  1728. (iw_handler) NULL, // SIOCGIWPRIV
  1729. (iw_handler) NULL, // SIOCSIWSTATS
  1730. (iw_handler) NULL, // SIOCGIWSTATS
  1731. (iw_handler) NULL, // SIOCSIWSPY
  1732. (iw_handler) NULL, // SIOCGIWSPY
  1733. (iw_handler) NULL, // -- hole --
  1734. (iw_handler) NULL, // -- hole --
  1735. (iw_handler) NULL, // SIOCSIWAP
  1736. (iw_handler) NULL, // SIOCGIWAP
  1737. (iw_handler) NULL, // -- hole -- 0x16
  1738. (iw_handler) NULL, // SIOCGIWAPLIST
  1739. (iw_handler) iwctl_siwscan, // SIOCSIWSCAN
  1740. (iw_handler) iwctl_giwscan, // SIOCGIWSCAN
  1741. (iw_handler) NULL, // SIOCSIWESSID
  1742. (iw_handler) NULL, // SIOCGIWESSID
  1743. (iw_handler) NULL, // SIOCSIWNICKN
  1744. (iw_handler) NULL, // SIOCGIWNICKN
  1745. (iw_handler) NULL, // -- hole --
  1746. (iw_handler) NULL, // -- hole --
  1747. (iw_handler) NULL, // SIOCSIWRATE 0x20
  1748. (iw_handler) NULL, // SIOCGIWRATE
  1749. (iw_handler) NULL, // SIOCSIWRTS
  1750. (iw_handler) NULL, // SIOCGIWRTS
  1751. (iw_handler) NULL, // SIOCSIWFRAG
  1752. (iw_handler) NULL, // SIOCGIWFRAG
  1753. (iw_handler) NULL, // SIOCSIWTXPOW
  1754. (iw_handler) NULL, // SIOCGIWTXPOW
  1755. (iw_handler) NULL, // SIOCSIWRETRY
  1756. (iw_handler) NULL, // SIOCGIWRETRY
  1757. (iw_handler) NULL, // SIOCSIWENCODE
  1758. (iw_handler) NULL, // SIOCGIWENCODE
  1759. (iw_handler) NULL, // SIOCSIWPOWER
  1760. (iw_handler) NULL, // SIOCGIWPOWER
  1761. (iw_handler) NULL, // -- hole --
  1762. (iw_handler) NULL, // -- hole --
  1763. (iw_handler) NULL, // SIOCSIWGENIE
  1764. (iw_handler) NULL, // SIOCGIWGENIE
  1765. (iw_handler) NULL, // SIOCSIWAUTH
  1766. (iw_handler) NULL, // SIOCGIWAUTH
  1767. (iw_handler) NULL, // SIOCSIWENCODEEXT
  1768. (iw_handler) NULL, // SIOCGIWENCODEEXT
  1769. (iw_handler) NULL, // SIOCSIWPMKSA
  1770. (iw_handler) NULL, // -- hole --
  1771. };
  1772. static const iw_handler iwctl_private_handler[] =
  1773. {
  1774. NULL, // SIOCIWFIRSTPRIV
  1775. };
  1776. struct iw_priv_args iwctl_private_args[] = {
  1777. { IOCTL_CMD_SET,
  1778. IW_PRIV_TYPE_CHAR | 1024, 0,
  1779. "set"},
  1780. };
  1781. const struct iw_handler_def iwctl_handler_def =
  1782. {
  1783. .get_wireless_stats = &iwctl_get_wireless_stats,
  1784. .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler),
  1785. // .num_private = sizeof(iwctl_private_handler)/sizeof(iw_handler),
  1786. // .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
  1787. .num_private = 0,
  1788. .num_private_args = 0,
  1789. .standard = (iw_handler *) iwctl_handler,
  1790. // .private = (iw_handler *) iwctl_private_handler,
  1791. // .private_args = (struct iw_priv_args *)iwctl_private_args,
  1792. .private = NULL,
  1793. .private_args = NULL,
  1794. };