iwctl.c 50 KB

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