rndis_wlan.c 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769
  1. /*
  2. * Driver for RNDIS based wireless USB devices.
  3. *
  4. * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
  5. * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * Portions of this file are based on NDISwrapper project,
  22. * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
  23. * http://ndiswrapper.sourceforge.net/
  24. */
  25. // #define DEBUG // error path messages, extra info
  26. // #define VERBOSE // more; success messages
  27. #include <linux/module.h>
  28. #include <linux/init.h>
  29. #include <linux/netdevice.h>
  30. #include <linux/etherdevice.h>
  31. #include <linux/ethtool.h>
  32. #include <linux/workqueue.h>
  33. #include <linux/mutex.h>
  34. #include <linux/mii.h>
  35. #include <linux/usb.h>
  36. #include <linux/usb/cdc.h>
  37. #include <linux/wireless.h>
  38. #include <linux/ieee80211.h>
  39. #include <linux/if_arp.h>
  40. #include <linux/ctype.h>
  41. #include <linux/spinlock.h>
  42. #include <net/iw_handler.h>
  43. #include <net/wireless.h>
  44. #include <net/cfg80211.h>
  45. #include <linux/usb/usbnet.h>
  46. #include <linux/usb/rndis_host.h>
  47. /* NOTE: All these are settings for Broadcom chipset */
  48. static char modparam_country[4] = "EU";
  49. module_param_string(country, modparam_country, 4, 0444);
  50. MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU");
  51. static int modparam_frameburst = 1;
  52. module_param_named(frameburst, modparam_frameburst, int, 0444);
  53. MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)");
  54. static int modparam_afterburner = 0;
  55. module_param_named(afterburner, modparam_afterburner, int, 0444);
  56. MODULE_PARM_DESC(afterburner,
  57. "enable afterburner aka '125 High Speed Mode' (default: off)");
  58. static int modparam_power_save = 0;
  59. module_param_named(power_save, modparam_power_save, int, 0444);
  60. MODULE_PARM_DESC(power_save,
  61. "set power save mode: 0=off, 1=on, 2=fast (default: off)");
  62. static int modparam_power_output = 3;
  63. module_param_named(power_output, modparam_power_output, int, 0444);
  64. MODULE_PARM_DESC(power_output,
  65. "set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)");
  66. static int modparam_roamtrigger = -70;
  67. module_param_named(roamtrigger, modparam_roamtrigger, int, 0444);
  68. MODULE_PARM_DESC(roamtrigger,
  69. "set roaming dBm trigger: -80=optimize for distance, "
  70. "-60=bandwidth (default: -70)");
  71. static int modparam_roamdelta = 1;
  72. module_param_named(roamdelta, modparam_roamdelta, int, 0444);
  73. MODULE_PARM_DESC(roamdelta,
  74. "set roaming tendency: 0=aggressive, 1=moderate, "
  75. "2=conservative (default: moderate)");
  76. static int modparam_workaround_interval = 500;
  77. module_param_named(workaround_interval, modparam_workaround_interval,
  78. int, 0444);
  79. MODULE_PARM_DESC(workaround_interval,
  80. "set stall workaround interval in msecs (default: 500)");
  81. /* various RNDIS OID defs */
  82. #define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107)
  83. #define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b)
  84. #define OID_GEN_XMIT_OK cpu_to_le32(0x00020101)
  85. #define OID_GEN_RCV_OK cpu_to_le32(0x00020102)
  86. #define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103)
  87. #define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104)
  88. #define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105)
  89. #define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101)
  90. #define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102)
  91. #define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103)
  92. #define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104)
  93. #define OID_802_11_BSSID cpu_to_le32(0x0d010101)
  94. #define OID_802_11_SSID cpu_to_le32(0x0d010102)
  95. #define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108)
  96. #define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113)
  97. #define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114)
  98. #define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115)
  99. #define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118)
  100. #define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119)
  101. #define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a)
  102. #define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b)
  103. #define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
  104. #define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
  105. #define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
  106. #define OID_802_11_PMKID cpu_to_le32(0x0d010123)
  107. #define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
  108. #define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
  109. #define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205)
  110. #define OID_802_11_RSSI cpu_to_le32(0x0d010206)
  111. #define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207)
  112. #define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209)
  113. #define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
  114. #define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
  115. #define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
  116. #define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
  117. /* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
  118. #define WL_NOISE -96 /* typical noise level in dBm */
  119. #define WL_SIGMAX -32 /* typical maximum signal level in dBm */
  120. /* Assume that Broadcom 4320 (only chipset at time of writing known to be
  121. * based on wireless rndis) has default txpower of 13dBm.
  122. * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
  123. * 13dBm == 19.9mW
  124. */
  125. #define BCM4320_DEFAULT_TXPOWER 20
  126. /* codes for "status" field of completion messages */
  127. #define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011)
  128. #define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
  129. /* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
  130. * slightly modified for datatype endianess, etc
  131. */
  132. #define NDIS_802_11_LENGTH_SSID 32
  133. #define NDIS_802_11_LENGTH_RATES 8
  134. #define NDIS_802_11_LENGTH_RATES_EX 16
  135. enum ndis_80211_net_type {
  136. ndis_80211_type_freq_hop,
  137. ndis_80211_type_direct_seq,
  138. ndis_80211_type_ofdm_a,
  139. ndis_80211_type_ofdm_g
  140. };
  141. enum ndis_80211_net_infra {
  142. ndis_80211_infra_adhoc,
  143. ndis_80211_infra_infra,
  144. ndis_80211_infra_auto_unknown
  145. };
  146. enum ndis_80211_auth_mode {
  147. ndis_80211_auth_open,
  148. ndis_80211_auth_shared,
  149. ndis_80211_auth_auto_switch,
  150. ndis_80211_auth_wpa,
  151. ndis_80211_auth_wpa_psk,
  152. ndis_80211_auth_wpa_none,
  153. ndis_80211_auth_wpa2,
  154. ndis_80211_auth_wpa2_psk
  155. };
  156. enum ndis_80211_encr_status {
  157. ndis_80211_encr_wep_enabled,
  158. ndis_80211_encr_disabled,
  159. ndis_80211_encr_wep_key_absent,
  160. ndis_80211_encr_not_supported,
  161. ndis_80211_encr_tkip_enabled,
  162. ndis_80211_encr_tkip_key_absent,
  163. ndis_80211_encr_ccmp_enabled,
  164. ndis_80211_encr_ccmp_key_absent
  165. };
  166. enum ndis_80211_priv_filter {
  167. ndis_80211_priv_accept_all,
  168. ndis_80211_priv_8021x_wep
  169. };
  170. struct ndis_80211_ssid {
  171. __le32 length;
  172. u8 essid[NDIS_802_11_LENGTH_SSID];
  173. } __attribute__((packed));
  174. struct ndis_80211_conf_freq_hop {
  175. __le32 length;
  176. __le32 hop_pattern;
  177. __le32 hop_set;
  178. __le32 dwell_time;
  179. } __attribute__((packed));
  180. struct ndis_80211_conf {
  181. __le32 length;
  182. __le32 beacon_period;
  183. __le32 atim_window;
  184. __le32 ds_config;
  185. struct ndis_80211_conf_freq_hop fh_config;
  186. } __attribute__((packed));
  187. struct ndis_80211_bssid_ex {
  188. __le32 length;
  189. u8 mac[6];
  190. u8 padding[2];
  191. struct ndis_80211_ssid ssid;
  192. __le32 privacy;
  193. __le32 rssi;
  194. __le32 net_type;
  195. struct ndis_80211_conf config;
  196. __le32 net_infra;
  197. u8 rates[NDIS_802_11_LENGTH_RATES_EX];
  198. __le32 ie_length;
  199. u8 ies[0];
  200. } __attribute__((packed));
  201. struct ndis_80211_bssid_list_ex {
  202. __le32 num_items;
  203. struct ndis_80211_bssid_ex bssid[0];
  204. } __attribute__((packed));
  205. struct ndis_80211_fixed_ies {
  206. u8 timestamp[8];
  207. __le16 beacon_interval;
  208. __le16 capabilities;
  209. } __attribute__((packed));
  210. struct ndis_80211_wep_key {
  211. __le32 size;
  212. __le32 index;
  213. __le32 length;
  214. u8 material[32];
  215. } __attribute__((packed));
  216. struct ndis_80211_key {
  217. __le32 size;
  218. __le32 index;
  219. __le32 length;
  220. u8 bssid[6];
  221. u8 padding[6];
  222. u8 rsc[8];
  223. u8 material[32];
  224. } __attribute__((packed));
  225. struct ndis_80211_remove_key {
  226. __le32 size;
  227. __le32 index;
  228. u8 bssid[6];
  229. } __attribute__((packed));
  230. struct ndis_config_param {
  231. __le32 name_offs;
  232. __le32 name_length;
  233. __le32 type;
  234. __le32 value_offs;
  235. __le32 value_length;
  236. } __attribute__((packed));
  237. struct ndis_80211_assoc_info {
  238. __le32 length;
  239. __le16 req_ies;
  240. struct req_ie {
  241. __le16 capa;
  242. __le16 listen_interval;
  243. u8 cur_ap_address[6];
  244. } req_ie;
  245. __le32 req_ie_length;
  246. __le32 offset_req_ies;
  247. __le16 resp_ies;
  248. struct resp_ie {
  249. __le16 capa;
  250. __le16 status_code;
  251. __le16 assoc_id;
  252. } resp_ie;
  253. __le32 resp_ie_length;
  254. __le32 offset_resp_ies;
  255. } __attribute__((packed));
  256. /* these have to match what is in wpa_supplicant */
  257. enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
  258. enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
  259. CIPHER_WEP104 };
  260. enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
  261. KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
  262. /*
  263. * private data
  264. */
  265. #define NET_TYPE_11FB 0
  266. #define CAP_MODE_80211A 1
  267. #define CAP_MODE_80211B 2
  268. #define CAP_MODE_80211G 4
  269. #define CAP_MODE_MASK 7
  270. #define CAP_SUPPORT_TXPOWER 8
  271. #define WORK_LINK_UP (1<<0)
  272. #define WORK_LINK_DOWN (1<<1)
  273. #define WORK_SET_MULTICAST_LIST (1<<2)
  274. #define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
  275. static const struct ieee80211_channel rndis_channels[] = {
  276. { .center_freq = 2412 },
  277. { .center_freq = 2417 },
  278. { .center_freq = 2422 },
  279. { .center_freq = 2427 },
  280. { .center_freq = 2432 },
  281. { .center_freq = 2437 },
  282. { .center_freq = 2442 },
  283. { .center_freq = 2447 },
  284. { .center_freq = 2452 },
  285. { .center_freq = 2457 },
  286. { .center_freq = 2462 },
  287. { .center_freq = 2467 },
  288. { .center_freq = 2472 },
  289. { .center_freq = 2484 },
  290. };
  291. static const struct ieee80211_rate rndis_rates[] = {
  292. { .bitrate = 10 },
  293. { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  294. { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  295. { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  296. { .bitrate = 60 },
  297. { .bitrate = 90 },
  298. { .bitrate = 120 },
  299. { .bitrate = 180 },
  300. { .bitrate = 240 },
  301. { .bitrate = 360 },
  302. { .bitrate = 480 },
  303. { .bitrate = 540 }
  304. };
  305. /* RNDIS device private data */
  306. struct rndis_wext_private {
  307. struct usbnet *usbdev;
  308. struct wireless_dev wdev;
  309. struct workqueue_struct *workqueue;
  310. struct delayed_work stats_work;
  311. struct work_struct work;
  312. struct mutex command_lock;
  313. spinlock_t stats_lock;
  314. unsigned long work_pending;
  315. struct ieee80211_supported_band band;
  316. struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
  317. struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
  318. struct iw_statistics iwstats;
  319. struct iw_statistics privstats;
  320. int nick_len;
  321. char nick[32];
  322. int caps;
  323. int multicast_size;
  324. /* module parameters */
  325. char param_country[4];
  326. int param_frameburst;
  327. int param_afterburner;
  328. int param_power_save;
  329. int param_power_output;
  330. int param_roamtrigger;
  331. int param_roamdelta;
  332. u32 param_workaround_interval;
  333. /* hardware state */
  334. int radio_on;
  335. int infra_mode;
  336. struct ndis_80211_ssid essid;
  337. /* encryption stuff */
  338. int encr_tx_key_index;
  339. char encr_keys[4][32];
  340. int encr_key_len[4];
  341. int wpa_version;
  342. int wpa_keymgmt;
  343. int wpa_authalg;
  344. int wpa_ie_len;
  345. u8 *wpa_ie;
  346. int wpa_cipher_pair;
  347. int wpa_cipher_group;
  348. u8 command_buffer[COMMAND_BUFFER_SIZE];
  349. };
  350. /*
  351. * cfg80211 ops
  352. */
  353. static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
  354. enum nl80211_iftype type, u32 *flags,
  355. struct vif_params *params);
  356. struct cfg80211_ops rndis_config_ops = {
  357. .change_virtual_intf = rndis_change_virtual_intf,
  358. };
  359. void *rndis_wiphy_privid = &rndis_wiphy_privid;
  360. static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
  361. static const unsigned char zero_bssid[ETH_ALEN] = {0,};
  362. static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
  363. 0xff, 0xff, 0xff };
  364. static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
  365. {
  366. return (struct rndis_wext_private *)dev->driver_priv;
  367. }
  368. static u32 get_bcm4320_power(struct rndis_wext_private *priv)
  369. {
  370. return BCM4320_DEFAULT_TXPOWER *
  371. bcm4320_power_output[priv->param_power_output] / 100;
  372. }
  373. /* translate error code */
  374. static int rndis_error_status(__le32 rndis_status)
  375. {
  376. int ret = -EINVAL;
  377. switch (rndis_status) {
  378. case RNDIS_STATUS_SUCCESS:
  379. ret = 0;
  380. break;
  381. case RNDIS_STATUS_FAILURE:
  382. case RNDIS_STATUS_INVALID_DATA:
  383. ret = -EINVAL;
  384. break;
  385. case RNDIS_STATUS_NOT_SUPPORTED:
  386. ret = -EOPNOTSUPP;
  387. break;
  388. case RNDIS_STATUS_ADAPTER_NOT_READY:
  389. case RNDIS_STATUS_ADAPTER_NOT_OPEN:
  390. ret = -EBUSY;
  391. break;
  392. }
  393. return ret;
  394. }
  395. static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
  396. {
  397. struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
  398. union {
  399. void *buf;
  400. struct rndis_msg_hdr *header;
  401. struct rndis_query *get;
  402. struct rndis_query_c *get_c;
  403. } u;
  404. int ret, buflen;
  405. buflen = *len + sizeof(*u.get);
  406. if (buflen < CONTROL_BUFFER_SIZE)
  407. buflen = CONTROL_BUFFER_SIZE;
  408. if (buflen > COMMAND_BUFFER_SIZE) {
  409. u.buf = kmalloc(buflen, GFP_KERNEL);
  410. if (!u.buf)
  411. return -ENOMEM;
  412. } else {
  413. u.buf = priv->command_buffer;
  414. }
  415. mutex_lock(&priv->command_lock);
  416. memset(u.get, 0, sizeof *u.get);
  417. u.get->msg_type = RNDIS_MSG_QUERY;
  418. u.get->msg_len = cpu_to_le32(sizeof *u.get);
  419. u.get->oid = oid;
  420. ret = rndis_command(dev, u.header, buflen);
  421. if (ret == 0) {
  422. ret = le32_to_cpu(u.get_c->len);
  423. *len = (*len > ret) ? ret : *len;
  424. memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
  425. ret = rndis_error_status(u.get_c->status);
  426. }
  427. mutex_unlock(&priv->command_lock);
  428. if (u.buf != priv->command_buffer)
  429. kfree(u.buf);
  430. return ret;
  431. }
  432. static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
  433. {
  434. struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
  435. union {
  436. void *buf;
  437. struct rndis_msg_hdr *header;
  438. struct rndis_set *set;
  439. struct rndis_set_c *set_c;
  440. } u;
  441. int ret, buflen;
  442. buflen = len + sizeof(*u.set);
  443. if (buflen < CONTROL_BUFFER_SIZE)
  444. buflen = CONTROL_BUFFER_SIZE;
  445. if (buflen > COMMAND_BUFFER_SIZE) {
  446. u.buf = kmalloc(buflen, GFP_KERNEL);
  447. if (!u.buf)
  448. return -ENOMEM;
  449. } else {
  450. u.buf = priv->command_buffer;
  451. }
  452. mutex_lock(&priv->command_lock);
  453. memset(u.set, 0, sizeof *u.set);
  454. u.set->msg_type = RNDIS_MSG_SET;
  455. u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
  456. u.set->oid = oid;
  457. u.set->len = cpu_to_le32(len);
  458. u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
  459. u.set->handle = cpu_to_le32(0);
  460. memcpy(u.buf + sizeof(*u.set), data, len);
  461. ret = rndis_command(dev, u.header, buflen);
  462. if (ret == 0)
  463. ret = rndis_error_status(u.set_c->status);
  464. mutex_unlock(&priv->command_lock);
  465. if (u.buf != priv->command_buffer)
  466. kfree(u.buf);
  467. return ret;
  468. }
  469. /*
  470. * Specs say that we can only set config parameters only soon after device
  471. * initialization.
  472. * value_type: 0 = u32, 2 = unicode string
  473. */
  474. static int rndis_set_config_parameter(struct usbnet *dev, char *param,
  475. int value_type, void *value)
  476. {
  477. struct ndis_config_param *infobuf;
  478. int value_len, info_len, param_len, ret, i;
  479. __le16 *unibuf;
  480. __le32 *dst_value;
  481. if (value_type == 0)
  482. value_len = sizeof(__le32);
  483. else if (value_type == 2)
  484. value_len = strlen(value) * sizeof(__le16);
  485. else
  486. return -EINVAL;
  487. param_len = strlen(param) * sizeof(__le16);
  488. info_len = sizeof(*infobuf) + param_len + value_len;
  489. #ifdef DEBUG
  490. info_len += 12;
  491. #endif
  492. infobuf = kmalloc(info_len, GFP_KERNEL);
  493. if (!infobuf)
  494. return -ENOMEM;
  495. #ifdef DEBUG
  496. info_len -= 12;
  497. /* extra 12 bytes are for padding (debug output) */
  498. memset(infobuf, 0xCC, info_len + 12);
  499. #endif
  500. if (value_type == 2)
  501. devdbg(dev, "setting config parameter: %s, value: %s",
  502. param, (u8 *)value);
  503. else
  504. devdbg(dev, "setting config parameter: %s, value: %d",
  505. param, *(u32 *)value);
  506. infobuf->name_offs = cpu_to_le32(sizeof(*infobuf));
  507. infobuf->name_length = cpu_to_le32(param_len);
  508. infobuf->type = cpu_to_le32(value_type);
  509. infobuf->value_offs = cpu_to_le32(sizeof(*infobuf) + param_len);
  510. infobuf->value_length = cpu_to_le32(value_len);
  511. /* simple string to unicode string conversion */
  512. unibuf = (void *)infobuf + sizeof(*infobuf);
  513. for (i = 0; i < param_len / sizeof(__le16); i++)
  514. unibuf[i] = cpu_to_le16(param[i]);
  515. if (value_type == 2) {
  516. unibuf = (void *)infobuf + sizeof(*infobuf) + param_len;
  517. for (i = 0; i < value_len / sizeof(__le16); i++)
  518. unibuf[i] = cpu_to_le16(((u8 *)value)[i]);
  519. } else {
  520. dst_value = (void *)infobuf + sizeof(*infobuf) + param_len;
  521. *dst_value = cpu_to_le32(*(u32 *)value);
  522. }
  523. #ifdef DEBUG
  524. devdbg(dev, "info buffer (len: %d):", info_len);
  525. for (i = 0; i < info_len; i += 12) {
  526. u32 *tmp = (u32 *)((u8 *)infobuf + i);
  527. devdbg(dev, "%08X:%08X:%08X",
  528. cpu_to_be32(tmp[0]),
  529. cpu_to_be32(tmp[1]),
  530. cpu_to_be32(tmp[2]));
  531. }
  532. #endif
  533. ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
  534. infobuf, info_len);
  535. if (ret != 0)
  536. devdbg(dev, "setting rndis config paramater failed, %d.", ret);
  537. kfree(infobuf);
  538. return ret;
  539. }
  540. static int rndis_set_config_parameter_str(struct usbnet *dev,
  541. char *param, char *value)
  542. {
  543. return(rndis_set_config_parameter(dev, param, 2, value));
  544. }
  545. /*static int rndis_set_config_parameter_u32(struct usbnet *dev,
  546. char *param, u32 value)
  547. {
  548. return(rndis_set_config_parameter(dev, param, 0, &value));
  549. }*/
  550. /*
  551. * data conversion functions
  552. */
  553. static int level_to_qual(int level)
  554. {
  555. int qual = 100 * (level - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
  556. return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
  557. }
  558. static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
  559. {
  560. freq->e = 0;
  561. freq->i = 0;
  562. freq->flags = 0;
  563. /* see comment in wireless.h above the "struct iw_freq"
  564. * definition for an explanation of this if
  565. * NOTE: 1000000 is due to the kHz
  566. */
  567. if (dsconfig > 1000000) {
  568. freq->m = dsconfig / 10;
  569. freq->e = 1;
  570. } else
  571. freq->m = dsconfig;
  572. /* convert from kHz to Hz */
  573. freq->e += 3;
  574. }
  575. static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
  576. {
  577. if (freq->m < 1000 && freq->e == 0) {
  578. if (freq->m >= 1 && freq->m <= 14)
  579. *dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
  580. else
  581. return -1;
  582. } else {
  583. int i;
  584. *dsconfig = freq->m;
  585. for (i = freq->e; i > 0; i--)
  586. *dsconfig *= 10;
  587. *dsconfig /= 1000;
  588. }
  589. return 0;
  590. }
  591. /*
  592. * common functions
  593. */
  594. static int
  595. add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
  596. static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
  597. {
  598. int ret, len;
  599. len = sizeof(*ssid);
  600. ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
  601. if (ret != 0)
  602. ssid->length = 0;
  603. #ifdef DEBUG
  604. {
  605. unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
  606. memcpy(tmp, ssid->essid, le32_to_cpu(ssid->length));
  607. tmp[le32_to_cpu(ssid->length)] = 0;
  608. devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
  609. }
  610. #endif
  611. return ret;
  612. }
  613. static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
  614. {
  615. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  616. int ret;
  617. ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
  618. if (ret == 0) {
  619. memcpy(&priv->essid, ssid, sizeof(priv->essid));
  620. priv->radio_on = 1;
  621. devdbg(usbdev, "set_essid: radio_on = 1");
  622. }
  623. return ret;
  624. }
  625. static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
  626. {
  627. int ret, len;
  628. len = ETH_ALEN;
  629. ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len);
  630. if (ret != 0)
  631. memset(bssid, 0, ETH_ALEN);
  632. return ret;
  633. }
  634. static int get_association_info(struct usbnet *usbdev,
  635. struct ndis_80211_assoc_info *info, int len)
  636. {
  637. return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION,
  638. info, &len);
  639. }
  640. static int is_associated(struct usbnet *usbdev)
  641. {
  642. u8 bssid[ETH_ALEN];
  643. int ret;
  644. ret = get_bssid(usbdev, bssid);
  645. return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
  646. }
  647. static int disassociate(struct usbnet *usbdev, int reset_ssid)
  648. {
  649. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  650. struct ndis_80211_ssid ssid;
  651. int i, ret = 0;
  652. if (priv->radio_on) {
  653. ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
  654. if (ret == 0) {
  655. priv->radio_on = 0;
  656. devdbg(usbdev, "disassociate: radio_on = 0");
  657. if (reset_ssid)
  658. msleep(100);
  659. }
  660. }
  661. /* disassociate causes radio to be turned off; if reset_ssid
  662. * is given, set random ssid to enable radio */
  663. if (reset_ssid) {
  664. ssid.length = cpu_to_le32(sizeof(ssid.essid));
  665. get_random_bytes(&ssid.essid[2], sizeof(ssid.essid)-2);
  666. ssid.essid[0] = 0x1;
  667. ssid.essid[1] = 0xff;
  668. for (i = 2; i < sizeof(ssid.essid); i++)
  669. ssid.essid[i] = 0x1 + (ssid.essid[i] * 0xfe / 0xff);
  670. ret = set_essid(usbdev, &ssid);
  671. }
  672. return ret;
  673. }
  674. static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
  675. {
  676. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  677. __le32 tmp;
  678. int auth_mode, ret;
  679. devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
  680. "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt);
  681. if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
  682. if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
  683. auth_mode = ndis_80211_auth_wpa2;
  684. else
  685. auth_mode = ndis_80211_auth_wpa2_psk;
  686. } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
  687. if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
  688. auth_mode = ndis_80211_auth_wpa;
  689. else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
  690. auth_mode = ndis_80211_auth_wpa_psk;
  691. else
  692. auth_mode = ndis_80211_auth_wpa_none;
  693. } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
  694. if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
  695. auth_mode = ndis_80211_auth_auto_switch;
  696. else
  697. auth_mode = ndis_80211_auth_shared;
  698. } else
  699. auth_mode = ndis_80211_auth_open;
  700. tmp = cpu_to_le32(auth_mode);
  701. ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
  702. sizeof(tmp));
  703. if (ret != 0) {
  704. devwarn(usbdev, "setting auth mode failed (%08X)", ret);
  705. return ret;
  706. }
  707. priv->wpa_version = wpa_version;
  708. priv->wpa_authalg = authalg;
  709. return 0;
  710. }
  711. static int set_priv_filter(struct usbnet *usbdev)
  712. {
  713. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  714. __le32 tmp;
  715. devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
  716. if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
  717. priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
  718. tmp = cpu_to_le32(ndis_80211_priv_8021x_wep);
  719. else
  720. tmp = cpu_to_le32(ndis_80211_priv_accept_all);
  721. return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
  722. sizeof(tmp));
  723. }
  724. static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
  725. {
  726. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  727. __le32 tmp;
  728. int encr_mode, ret;
  729. devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
  730. pairwise,
  731. groupwise);
  732. if (pairwise & IW_AUTH_CIPHER_CCMP)
  733. encr_mode = ndis_80211_encr_ccmp_enabled;
  734. else if (pairwise & IW_AUTH_CIPHER_TKIP)
  735. encr_mode = ndis_80211_encr_tkip_enabled;
  736. else if (pairwise &
  737. (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
  738. encr_mode = ndis_80211_encr_wep_enabled;
  739. else if (groupwise & IW_AUTH_CIPHER_CCMP)
  740. encr_mode = ndis_80211_encr_ccmp_enabled;
  741. else if (groupwise & IW_AUTH_CIPHER_TKIP)
  742. encr_mode = ndis_80211_encr_tkip_enabled;
  743. else
  744. encr_mode = ndis_80211_encr_disabled;
  745. tmp = cpu_to_le32(encr_mode);
  746. ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
  747. sizeof(tmp));
  748. if (ret != 0) {
  749. devwarn(usbdev, "setting encr mode failed (%08X)", ret);
  750. return ret;
  751. }
  752. priv->wpa_cipher_pair = pairwise;
  753. priv->wpa_cipher_group = groupwise;
  754. return 0;
  755. }
  756. static int set_assoc_params(struct usbnet *usbdev)
  757. {
  758. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  759. set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
  760. set_priv_filter(usbdev);
  761. set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
  762. return 0;
  763. }
  764. static int set_infra_mode(struct usbnet *usbdev, int mode)
  765. {
  766. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  767. __le32 tmp;
  768. int ret, i;
  769. devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
  770. tmp = cpu_to_le32(mode);
  771. ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
  772. sizeof(tmp));
  773. if (ret != 0) {
  774. devwarn(usbdev, "setting infra mode failed (%08X)", ret);
  775. return ret;
  776. }
  777. /* NDIS drivers clear keys when infrastructure mode is
  778. * changed. But Linux tools assume otherwise. So set the
  779. * keys */
  780. if (priv->wpa_keymgmt == 0 ||
  781. priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
  782. for (i = 0; i < 4; i++) {
  783. if (priv->encr_key_len[i] > 0)
  784. add_wep_key(usbdev, priv->encr_keys[i],
  785. priv->encr_key_len[i], i);
  786. }
  787. }
  788. priv->infra_mode = mode;
  789. return 0;
  790. }
  791. static void set_default_iw_params(struct usbnet *usbdev)
  792. {
  793. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  794. priv->wpa_keymgmt = 0;
  795. priv->wpa_version = 0;
  796. set_infra_mode(usbdev, ndis_80211_infra_infra);
  797. set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
  798. IW_AUTH_ALG_OPEN_SYSTEM);
  799. set_priv_filter(usbdev);
  800. set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
  801. }
  802. static int deauthenticate(struct usbnet *usbdev)
  803. {
  804. int ret;
  805. ret = disassociate(usbdev, 1);
  806. set_default_iw_params(usbdev);
  807. return ret;
  808. }
  809. /* index must be 0 - N, as per NDIS */
  810. static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
  811. {
  812. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  813. struct ndis_80211_wep_key ndis_key;
  814. int ret;
  815. if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
  816. return -EINVAL;
  817. memset(&ndis_key, 0, sizeof(ndis_key));
  818. ndis_key.size = cpu_to_le32(sizeof(ndis_key));
  819. ndis_key.length = cpu_to_le32(key_len);
  820. ndis_key.index = cpu_to_le32(index);
  821. memcpy(&ndis_key.material, key, key_len);
  822. if (index == priv->encr_tx_key_index) {
  823. ndis_key.index |= cpu_to_le32(1 << 31);
  824. ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
  825. IW_AUTH_CIPHER_NONE);
  826. if (ret)
  827. devwarn(usbdev, "encryption couldn't be enabled (%08X)",
  828. ret);
  829. }
  830. ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
  831. sizeof(ndis_key));
  832. if (ret != 0) {
  833. devwarn(usbdev, "adding encryption key %d failed (%08X)",
  834. index+1, ret);
  835. return ret;
  836. }
  837. priv->encr_key_len[index] = key_len;
  838. memcpy(&priv->encr_keys[index], key, key_len);
  839. return 0;
  840. }
  841. /* remove_key is for both wep and wpa */
  842. static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
  843. {
  844. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  845. struct ndis_80211_remove_key remove_key;
  846. __le32 keyindex;
  847. int ret;
  848. if (priv->encr_key_len[index] == 0)
  849. return 0;
  850. priv->encr_key_len[index] = 0;
  851. memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
  852. if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
  853. priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
  854. priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
  855. priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
  856. remove_key.size = cpu_to_le32(sizeof(remove_key));
  857. remove_key.index = cpu_to_le32(index);
  858. if (bssid) {
  859. /* pairwise key */
  860. if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
  861. remove_key.index |= cpu_to_le32(1 << 30);
  862. memcpy(remove_key.bssid, bssid,
  863. sizeof(remove_key.bssid));
  864. } else
  865. memset(remove_key.bssid, 0xff,
  866. sizeof(remove_key.bssid));
  867. ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
  868. sizeof(remove_key));
  869. if (ret != 0)
  870. return ret;
  871. } else {
  872. keyindex = cpu_to_le32(index);
  873. ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
  874. sizeof(keyindex));
  875. if (ret != 0) {
  876. devwarn(usbdev,
  877. "removing encryption key %d failed (%08X)",
  878. index, ret);
  879. return ret;
  880. }
  881. }
  882. /* if it is transmit key, disable encryption */
  883. if (index == priv->encr_tx_key_index)
  884. set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
  885. return 0;
  886. }
  887. static void set_multicast_list(struct usbnet *usbdev)
  888. {
  889. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  890. struct dev_mc_list *mclist;
  891. __le32 filter;
  892. int ret, i, size;
  893. char *buf;
  894. filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
  895. if (usbdev->net->flags & IFF_PROMISC) {
  896. filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
  897. RNDIS_PACKET_TYPE_ALL_LOCAL;
  898. } else if (usbdev->net->flags & IFF_ALLMULTI ||
  899. usbdev->net->mc_count > priv->multicast_size) {
  900. filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
  901. } else if (usbdev->net->mc_count > 0) {
  902. size = min(priv->multicast_size, usbdev->net->mc_count);
  903. buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
  904. if (!buf) {
  905. devwarn(usbdev,
  906. "couldn't alloc %d bytes of memory",
  907. size * ETH_ALEN);
  908. return;
  909. }
  910. mclist = usbdev->net->mc_list;
  911. for (i = 0; i < size && mclist; mclist = mclist->next) {
  912. if (mclist->dmi_addrlen != ETH_ALEN)
  913. continue;
  914. memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
  915. i++;
  916. }
  917. ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
  918. i * ETH_ALEN);
  919. if (ret == 0 && i > 0)
  920. filter |= RNDIS_PACKET_TYPE_MULTICAST;
  921. else
  922. filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
  923. devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d",
  924. i, priv->multicast_size, ret);
  925. kfree(buf);
  926. }
  927. ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
  928. sizeof(filter));
  929. if (ret < 0) {
  930. devwarn(usbdev, "couldn't set packet filter: %08x",
  931. le32_to_cpu(filter));
  932. }
  933. devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d",
  934. le32_to_cpu(filter), ret);
  935. }
  936. /*
  937. * cfg80211 ops
  938. */
  939. static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
  940. enum nl80211_iftype type, u32 *flags,
  941. struct vif_params *params)
  942. {
  943. struct net_device *dev;
  944. struct usbnet *usbdev;
  945. int mode;
  946. /* we're under RTNL */
  947. dev = __dev_get_by_index(&init_net, ifindex);
  948. if (!dev)
  949. return -ENODEV;
  950. usbdev = netdev_priv(dev);
  951. switch (type) {
  952. case NL80211_IFTYPE_ADHOC:
  953. mode = ndis_80211_infra_adhoc;
  954. break;
  955. case NL80211_IFTYPE_STATION:
  956. mode = ndis_80211_infra_infra;
  957. break;
  958. default:
  959. return -EINVAL;
  960. }
  961. return set_infra_mode(usbdev, mode);
  962. }
  963. /*
  964. * wireless extension handlers
  965. */
  966. static int rndis_iw_commit(struct net_device *dev,
  967. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  968. {
  969. /* dummy op */
  970. return 0;
  971. }
  972. static int rndis_iw_set_essid(struct net_device *dev,
  973. struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
  974. {
  975. struct ndis_80211_ssid ssid;
  976. int length = wrqu->essid.length;
  977. struct usbnet *usbdev = netdev_priv(dev);
  978. devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
  979. wrqu->essid.flags, wrqu->essid.length, essid);
  980. if (length > NDIS_802_11_LENGTH_SSID)
  981. length = NDIS_802_11_LENGTH_SSID;
  982. ssid.length = cpu_to_le32(length);
  983. if (length > 0)
  984. memcpy(ssid.essid, essid, length);
  985. else
  986. memset(ssid.essid, 0, NDIS_802_11_LENGTH_SSID);
  987. set_assoc_params(usbdev);
  988. if (!wrqu->essid.flags || length == 0)
  989. return disassociate(usbdev, 1);
  990. else
  991. return set_essid(usbdev, &ssid);
  992. }
  993. static int rndis_iw_get_essid(struct net_device *dev,
  994. struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
  995. {
  996. struct ndis_80211_ssid ssid;
  997. struct usbnet *usbdev = netdev_priv(dev);
  998. int ret;
  999. ret = get_essid(usbdev, &ssid);
  1000. if (ret == 0 && le32_to_cpu(ssid.length) > 0) {
  1001. wrqu->essid.flags = 1;
  1002. wrqu->essid.length = le32_to_cpu(ssid.length);
  1003. memcpy(essid, ssid.essid, wrqu->essid.length);
  1004. essid[wrqu->essid.length] = 0;
  1005. } else {
  1006. memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
  1007. wrqu->essid.flags = 0;
  1008. wrqu->essid.length = 0;
  1009. }
  1010. devdbg(usbdev, "SIOCGIWESSID: %s", essid);
  1011. return ret;
  1012. }
  1013. static int rndis_iw_get_bssid(struct net_device *dev,
  1014. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1015. {
  1016. struct usbnet *usbdev = netdev_priv(dev);
  1017. unsigned char bssid[ETH_ALEN];
  1018. int ret;
  1019. ret = get_bssid(usbdev, bssid);
  1020. if (ret == 0)
  1021. devdbg(usbdev, "SIOCGIWAP: %pM", bssid);
  1022. else
  1023. devdbg(usbdev, "SIOCGIWAP: <not associated>");
  1024. wrqu->ap_addr.sa_family = ARPHRD_ETHER;
  1025. memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
  1026. return ret;
  1027. }
  1028. static int rndis_iw_set_bssid(struct net_device *dev,
  1029. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1030. {
  1031. struct usbnet *usbdev = netdev_priv(dev);
  1032. u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
  1033. int ret;
  1034. devdbg(usbdev, "SIOCSIWAP: %pM", bssid);
  1035. ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
  1036. /* user apps may set ap's mac address, which is not required;
  1037. * they may fail to work if this function fails, so return
  1038. * success */
  1039. if (ret)
  1040. devwarn(usbdev, "setting AP mac address failed (%08X)", ret);
  1041. return 0;
  1042. }
  1043. static int rndis_iw_set_auth(struct net_device *dev,
  1044. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1045. {
  1046. struct iw_param *p = &wrqu->param;
  1047. struct usbnet *usbdev = netdev_priv(dev);
  1048. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1049. int ret = -ENOTSUPP;
  1050. switch (p->flags & IW_AUTH_INDEX) {
  1051. case IW_AUTH_WPA_VERSION:
  1052. devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value);
  1053. priv->wpa_version = p->value;
  1054. ret = 0;
  1055. break;
  1056. case IW_AUTH_CIPHER_PAIRWISE:
  1057. devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value);
  1058. priv->wpa_cipher_pair = p->value;
  1059. ret = 0;
  1060. break;
  1061. case IW_AUTH_CIPHER_GROUP:
  1062. devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value);
  1063. priv->wpa_cipher_group = p->value;
  1064. ret = 0;
  1065. break;
  1066. case IW_AUTH_KEY_MGMT:
  1067. devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value);
  1068. priv->wpa_keymgmt = p->value;
  1069. ret = 0;
  1070. break;
  1071. case IW_AUTH_TKIP_COUNTERMEASURES:
  1072. devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x",
  1073. p->value);
  1074. ret = 0;
  1075. break;
  1076. case IW_AUTH_DROP_UNENCRYPTED:
  1077. devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value);
  1078. ret = 0;
  1079. break;
  1080. case IW_AUTH_80211_AUTH_ALG:
  1081. devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value);
  1082. priv->wpa_authalg = p->value;
  1083. ret = 0;
  1084. break;
  1085. case IW_AUTH_WPA_ENABLED:
  1086. devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value);
  1087. if (wrqu->param.value)
  1088. deauthenticate(usbdev);
  1089. ret = 0;
  1090. break;
  1091. case IW_AUTH_RX_UNENCRYPTED_EAPOL:
  1092. devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x",
  1093. p->value);
  1094. ret = 0;
  1095. break;
  1096. case IW_AUTH_ROAMING_CONTROL:
  1097. devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value);
  1098. ret = 0;
  1099. break;
  1100. case IW_AUTH_PRIVACY_INVOKED:
  1101. devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d",
  1102. wrqu->param.flags & IW_AUTH_INDEX);
  1103. return -EOPNOTSUPP;
  1104. default:
  1105. devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN %08x, %08x",
  1106. p->flags & IW_AUTH_INDEX, p->value);
  1107. }
  1108. return ret;
  1109. }
  1110. static int rndis_iw_get_auth(struct net_device *dev,
  1111. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1112. {
  1113. struct iw_param *p = &wrqu->param;
  1114. struct usbnet *usbdev = netdev_priv(dev);
  1115. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1116. switch (p->flags & IW_AUTH_INDEX) {
  1117. case IW_AUTH_WPA_VERSION:
  1118. p->value = priv->wpa_version;
  1119. break;
  1120. case IW_AUTH_CIPHER_PAIRWISE:
  1121. p->value = priv->wpa_cipher_pair;
  1122. break;
  1123. case IW_AUTH_CIPHER_GROUP:
  1124. p->value = priv->wpa_cipher_group;
  1125. break;
  1126. case IW_AUTH_KEY_MGMT:
  1127. p->value = priv->wpa_keymgmt;
  1128. break;
  1129. case IW_AUTH_80211_AUTH_ALG:
  1130. p->value = priv->wpa_authalg;
  1131. break;
  1132. default:
  1133. devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d",
  1134. wrqu->param.flags & IW_AUTH_INDEX);
  1135. return -EOPNOTSUPP;
  1136. }
  1137. return 0;
  1138. }
  1139. static int rndis_iw_set_encode(struct net_device *dev,
  1140. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1141. {
  1142. struct usbnet *usbdev = netdev_priv(dev);
  1143. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1144. int ret, index, key_len;
  1145. u8 *key;
  1146. index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
  1147. /* iwconfig gives index as 1 - N */
  1148. if (index > 0)
  1149. index--;
  1150. else
  1151. index = priv->encr_tx_key_index;
  1152. if (index < 0 || index >= 4) {
  1153. devwarn(usbdev, "encryption index out of range (%u)", index);
  1154. return -EINVAL;
  1155. }
  1156. /* remove key if disabled */
  1157. if (wrqu->data.flags & IW_ENCODE_DISABLED) {
  1158. if (remove_key(usbdev, index, NULL))
  1159. return -EINVAL;
  1160. else
  1161. return 0;
  1162. }
  1163. /* global encryption state (for all keys) */
  1164. if (wrqu->data.flags & IW_ENCODE_OPEN)
  1165. ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
  1166. IW_AUTH_ALG_OPEN_SYSTEM);
  1167. else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
  1168. ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
  1169. IW_AUTH_ALG_SHARED_KEY);
  1170. if (ret != 0)
  1171. return ret;
  1172. if (wrqu->data.length > 0) {
  1173. key_len = wrqu->data.length;
  1174. key = extra;
  1175. } else {
  1176. /* must be set as tx key */
  1177. if (priv->encr_key_len[index] == 0)
  1178. return -EINVAL;
  1179. key_len = priv->encr_key_len[index];
  1180. key = priv->encr_keys[index];
  1181. priv->encr_tx_key_index = index;
  1182. }
  1183. if (add_wep_key(usbdev, key, key_len, index) != 0)
  1184. return -EINVAL;
  1185. if (index == priv->encr_tx_key_index)
  1186. /* ndis drivers want essid to be set after setting encr */
  1187. set_essid(usbdev, &priv->essid);
  1188. return 0;
  1189. }
  1190. static int rndis_iw_set_encode_ext(struct net_device *dev,
  1191. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1192. {
  1193. struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
  1194. struct usbnet *usbdev = netdev_priv(dev);
  1195. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1196. struct ndis_80211_key ndis_key;
  1197. int keyidx, ret;
  1198. u8 *addr;
  1199. keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
  1200. /* iwconfig gives index as 1 - N */
  1201. if (keyidx)
  1202. keyidx--;
  1203. else
  1204. keyidx = priv->encr_tx_key_index;
  1205. if (keyidx < 0 || keyidx >= 4)
  1206. return -EINVAL;
  1207. if (ext->alg == WPA_ALG_WEP) {
  1208. if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
  1209. priv->encr_tx_key_index = keyidx;
  1210. return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
  1211. }
  1212. if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
  1213. ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
  1214. return remove_key(usbdev, keyidx, NULL);
  1215. if (ext->key_len > sizeof(ndis_key.material))
  1216. return -1;
  1217. memset(&ndis_key, 0, sizeof(ndis_key));
  1218. ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
  1219. sizeof(ndis_key.material) + ext->key_len);
  1220. ndis_key.length = cpu_to_le32(ext->key_len);
  1221. ndis_key.index = cpu_to_le32(keyidx);
  1222. if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
  1223. memcpy(ndis_key.rsc, ext->rx_seq, 6);
  1224. ndis_key.index |= cpu_to_le32(1 << 29);
  1225. }
  1226. addr = ext->addr.sa_data;
  1227. if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
  1228. /* group key */
  1229. if (priv->infra_mode == ndis_80211_infra_adhoc)
  1230. memset(ndis_key.bssid, 0xff, ETH_ALEN);
  1231. else
  1232. get_bssid(usbdev, ndis_key.bssid);
  1233. } else {
  1234. /* pairwise key */
  1235. ndis_key.index |= cpu_to_le32(1 << 30);
  1236. memcpy(ndis_key.bssid, addr, ETH_ALEN);
  1237. }
  1238. if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
  1239. ndis_key.index |= cpu_to_le32(1 << 31);
  1240. if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
  1241. /* wpa_supplicant gives us the Michael MIC RX/TX keys in
  1242. * different order than NDIS spec, so swap the order here. */
  1243. memcpy(ndis_key.material, ext->key, 16);
  1244. memcpy(ndis_key.material + 16, ext->key + 24, 8);
  1245. memcpy(ndis_key.material + 24, ext->key + 16, 8);
  1246. } else
  1247. memcpy(ndis_key.material, ext->key, ext->key_len);
  1248. ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
  1249. le32_to_cpu(ndis_key.size));
  1250. devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
  1251. if (ret != 0)
  1252. return ret;
  1253. priv->encr_key_len[keyidx] = ext->key_len;
  1254. memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
  1255. if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
  1256. priv->encr_tx_key_index = keyidx;
  1257. return 0;
  1258. }
  1259. static int rndis_iw_set_scan(struct net_device *dev,
  1260. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1261. {
  1262. struct usbnet *usbdev = netdev_priv(dev);
  1263. union iwreq_data evt;
  1264. int ret = -EINVAL;
  1265. __le32 tmp;
  1266. devdbg(usbdev, "SIOCSIWSCAN");
  1267. if (wrqu->data.flags == 0) {
  1268. tmp = cpu_to_le32(1);
  1269. ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
  1270. sizeof(tmp));
  1271. evt.data.flags = 0;
  1272. evt.data.length = 0;
  1273. wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
  1274. }
  1275. return ret;
  1276. }
  1277. static char *rndis_translate_scan(struct net_device *dev,
  1278. struct iw_request_info *info, char *cev,
  1279. char *end_buf,
  1280. struct ndis_80211_bssid_ex *bssid)
  1281. {
  1282. struct usbnet *usbdev = netdev_priv(dev);
  1283. u8 *ie;
  1284. char *current_val;
  1285. int bssid_len, ie_len, i;
  1286. u32 beacon, atim;
  1287. struct iw_event iwe;
  1288. unsigned char sbuf[32];
  1289. bssid_len = le32_to_cpu(bssid->length);
  1290. devdbg(usbdev, "BSSID %pM", bssid->mac);
  1291. iwe.cmd = SIOCGIWAP;
  1292. iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
  1293. memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
  1294. cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
  1295. devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
  1296. bssid->ssid.essid);
  1297. iwe.cmd = SIOCGIWESSID;
  1298. iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
  1299. iwe.u.essid.flags = 1;
  1300. cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
  1301. devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
  1302. iwe.cmd = SIOCGIWMODE;
  1303. switch (le32_to_cpu(bssid->net_infra)) {
  1304. case ndis_80211_infra_adhoc:
  1305. iwe.u.mode = IW_MODE_ADHOC;
  1306. break;
  1307. case ndis_80211_infra_infra:
  1308. iwe.u.mode = IW_MODE_INFRA;
  1309. break;
  1310. /*case ndis_80211_infra_auto_unknown:*/
  1311. default:
  1312. iwe.u.mode = IW_MODE_AUTO;
  1313. break;
  1314. }
  1315. cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
  1316. devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
  1317. iwe.cmd = SIOCGIWFREQ;
  1318. dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
  1319. cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
  1320. devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
  1321. iwe.cmd = IWEVQUAL;
  1322. iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi));
  1323. iwe.u.qual.level = level_to_qual(le32_to_cpu(bssid->rssi));
  1324. iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
  1325. | IW_QUAL_LEVEL_UPDATED
  1326. | IW_QUAL_NOISE_INVALID;
  1327. cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
  1328. devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
  1329. iwe.cmd = SIOCGIWENCODE;
  1330. iwe.u.data.length = 0;
  1331. if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
  1332. iwe.u.data.flags = IW_ENCODE_DISABLED;
  1333. else
  1334. iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
  1335. cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
  1336. devdbg(usbdev, "RATES:");
  1337. current_val = cev + iwe_stream_lcp_len(info);
  1338. iwe.cmd = SIOCGIWRATE;
  1339. for (i = 0; i < sizeof(bssid->rates); i++) {
  1340. if (bssid->rates[i] & 0x7f) {
  1341. iwe.u.bitrate.value =
  1342. ((bssid->rates[i] & 0x7f) *
  1343. 500000);
  1344. devdbg(usbdev, " %d", iwe.u.bitrate.value);
  1345. current_val = iwe_stream_add_value(info, cev,
  1346. current_val, end_buf, &iwe,
  1347. IW_EV_PARAM_LEN);
  1348. }
  1349. }
  1350. if ((current_val - cev) > iwe_stream_lcp_len(info))
  1351. cev = current_val;
  1352. beacon = le32_to_cpu(bssid->config.beacon_period);
  1353. devdbg(usbdev, "BCN_INT %d", beacon);
  1354. iwe.cmd = IWEVCUSTOM;
  1355. snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
  1356. iwe.u.data.length = strlen(sbuf);
  1357. cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
  1358. atim = le32_to_cpu(bssid->config.atim_window);
  1359. devdbg(usbdev, "ATIM %d", atim);
  1360. iwe.cmd = IWEVCUSTOM;
  1361. snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
  1362. iwe.u.data.length = strlen(sbuf);
  1363. cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
  1364. ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
  1365. ie_len = min(bssid_len - (int)sizeof(*bssid),
  1366. (int)le32_to_cpu(bssid->ie_length));
  1367. ie_len -= sizeof(struct ndis_80211_fixed_ies);
  1368. while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
  1369. if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
  1370. memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
  1371. ie[0] == WLAN_EID_RSN) {
  1372. devdbg(usbdev, "IE: WPA%d",
  1373. (ie[0] == WLAN_EID_RSN) ? 2 : 1);
  1374. iwe.cmd = IWEVGENIE;
  1375. /* arbitrary cut-off at 64 */
  1376. iwe.u.data.length = min(ie[1] + 2, 64);
  1377. cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
  1378. }
  1379. ie_len -= 2 + ie[1];
  1380. ie += 2 + ie[1];
  1381. }
  1382. return cev;
  1383. }
  1384. static int rndis_iw_get_scan(struct net_device *dev,
  1385. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1386. {
  1387. struct usbnet *usbdev = netdev_priv(dev);
  1388. void *buf = NULL;
  1389. char *cev = extra;
  1390. struct ndis_80211_bssid_list_ex *bssid_list;
  1391. struct ndis_80211_bssid_ex *bssid;
  1392. int ret = -EINVAL, len, count, bssid_len;
  1393. devdbg(usbdev, "SIOCGIWSCAN");
  1394. len = CONTROL_BUFFER_SIZE;
  1395. buf = kmalloc(len, GFP_KERNEL);
  1396. if (!buf) {
  1397. ret = -ENOMEM;
  1398. goto out;
  1399. }
  1400. ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
  1401. if (ret != 0)
  1402. goto out;
  1403. bssid_list = buf;
  1404. bssid = bssid_list->bssid;
  1405. bssid_len = le32_to_cpu(bssid->length);
  1406. count = le32_to_cpu(bssid_list->num_items);
  1407. devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
  1408. while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
  1409. cev = rndis_translate_scan(dev, info, cev,
  1410. extra + IW_SCAN_MAX_DATA, bssid);
  1411. bssid = (void *)bssid + bssid_len;
  1412. bssid_len = le32_to_cpu(bssid->length);
  1413. count--;
  1414. }
  1415. out:
  1416. wrqu->data.length = cev - extra;
  1417. wrqu->data.flags = 0;
  1418. kfree(buf);
  1419. return ret;
  1420. }
  1421. static int rndis_iw_set_genie(struct net_device *dev,
  1422. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1423. {
  1424. struct usbnet *usbdev = netdev_priv(dev);
  1425. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1426. int ret = 0;
  1427. #ifdef DEBUG
  1428. int j;
  1429. u8 *gie = extra;
  1430. for (j = 0; j < wrqu->data.length; j += 8)
  1431. devdbg(usbdev,
  1432. "SIOCSIWGENIE %04x - "
  1433. "%02x %02x %02x %02x %02x %02x %02x %02x", j,
  1434. gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
  1435. gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
  1436. #endif
  1437. /* clear existing IEs */
  1438. if (priv->wpa_ie_len) {
  1439. kfree(priv->wpa_ie);
  1440. priv->wpa_ie_len = 0;
  1441. }
  1442. /* set new IEs */
  1443. priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
  1444. if (priv->wpa_ie) {
  1445. priv->wpa_ie_len = wrqu->data.length;
  1446. memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
  1447. } else
  1448. ret = -ENOMEM;
  1449. return ret;
  1450. }
  1451. static int rndis_iw_get_genie(struct net_device *dev,
  1452. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1453. {
  1454. struct usbnet *usbdev = netdev_priv(dev);
  1455. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1456. devdbg(usbdev, "SIOCGIWGENIE");
  1457. if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
  1458. wrqu->data.length = 0;
  1459. return 0;
  1460. }
  1461. if (wrqu->data.length < priv->wpa_ie_len)
  1462. return -E2BIG;
  1463. wrqu->data.length = priv->wpa_ie_len;
  1464. memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
  1465. return 0;
  1466. }
  1467. static int rndis_iw_set_rts(struct net_device *dev,
  1468. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1469. {
  1470. struct usbnet *usbdev = netdev_priv(dev);
  1471. __le32 tmp;
  1472. devdbg(usbdev, "SIOCSIWRTS");
  1473. tmp = cpu_to_le32(wrqu->rts.value);
  1474. return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
  1475. sizeof(tmp));
  1476. }
  1477. static int rndis_iw_get_rts(struct net_device *dev,
  1478. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1479. {
  1480. struct usbnet *usbdev = netdev_priv(dev);
  1481. __le32 tmp;
  1482. int len, ret;
  1483. len = sizeof(tmp);
  1484. ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len);
  1485. if (ret == 0) {
  1486. wrqu->rts.value = le32_to_cpu(tmp);
  1487. wrqu->rts.flags = 1;
  1488. wrqu->rts.disabled = 0;
  1489. }
  1490. devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value);
  1491. return ret;
  1492. }
  1493. static int rndis_iw_set_frag(struct net_device *dev,
  1494. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1495. {
  1496. struct usbnet *usbdev = netdev_priv(dev);
  1497. __le32 tmp;
  1498. devdbg(usbdev, "SIOCSIWFRAG");
  1499. tmp = cpu_to_le32(wrqu->frag.value);
  1500. return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
  1501. sizeof(tmp));
  1502. }
  1503. static int rndis_iw_get_frag(struct net_device *dev,
  1504. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1505. {
  1506. struct usbnet *usbdev = netdev_priv(dev);
  1507. __le32 tmp;
  1508. int len, ret;
  1509. len = sizeof(tmp);
  1510. ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
  1511. &len);
  1512. if (ret == 0) {
  1513. wrqu->frag.value = le32_to_cpu(tmp);
  1514. wrqu->frag.flags = 1;
  1515. wrqu->frag.disabled = 0;
  1516. }
  1517. devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value);
  1518. return ret;
  1519. }
  1520. static int rndis_iw_set_nick(struct net_device *dev,
  1521. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1522. {
  1523. struct usbnet *usbdev = netdev_priv(dev);
  1524. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1525. devdbg(usbdev, "SIOCSIWNICK");
  1526. priv->nick_len = wrqu->data.length;
  1527. if (priv->nick_len > 32)
  1528. priv->nick_len = 32;
  1529. memcpy(priv->nick, extra, priv->nick_len);
  1530. return 0;
  1531. }
  1532. static int rndis_iw_get_nick(struct net_device *dev,
  1533. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1534. {
  1535. struct usbnet *usbdev = netdev_priv(dev);
  1536. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1537. wrqu->data.flags = 1;
  1538. wrqu->data.length = priv->nick_len;
  1539. memcpy(extra, priv->nick, priv->nick_len);
  1540. devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
  1541. return 0;
  1542. }
  1543. static int rndis_iw_set_freq(struct net_device *dev,
  1544. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1545. {
  1546. struct usbnet *usbdev = netdev_priv(dev);
  1547. struct ndis_80211_conf config;
  1548. unsigned int dsconfig;
  1549. int len, ret;
  1550. /* this OID is valid only when not associated */
  1551. if (is_associated(usbdev))
  1552. return 0;
  1553. dsconfig = 0;
  1554. if (freq_to_dsconfig(&wrqu->freq, &dsconfig))
  1555. return -EINVAL;
  1556. len = sizeof(config);
  1557. ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
  1558. if (ret != 0) {
  1559. devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed");
  1560. return 0;
  1561. }
  1562. config.ds_config = cpu_to_le32(dsconfig);
  1563. devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
  1564. return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
  1565. sizeof(config));
  1566. }
  1567. static int rndis_iw_get_freq(struct net_device *dev,
  1568. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1569. {
  1570. struct usbnet *usbdev = netdev_priv(dev);
  1571. struct ndis_80211_conf config;
  1572. int len, ret;
  1573. len = sizeof(config);
  1574. ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
  1575. if (ret == 0)
  1576. dsconfig_to_freq(le32_to_cpu(config.ds_config), &wrqu->freq);
  1577. devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
  1578. return ret;
  1579. }
  1580. static int rndis_iw_get_txpower(struct net_device *dev,
  1581. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1582. {
  1583. struct usbnet *usbdev = netdev_priv(dev);
  1584. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1585. __le32 tx_power;
  1586. int ret = 0, len;
  1587. if (priv->radio_on) {
  1588. if (priv->caps & CAP_SUPPORT_TXPOWER) {
  1589. len = sizeof(tx_power);
  1590. ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
  1591. &tx_power, &len);
  1592. if (ret != 0)
  1593. return ret;
  1594. } else
  1595. /* fake incase not supported */
  1596. tx_power = cpu_to_le32(get_bcm4320_power(priv));
  1597. wrqu->txpower.flags = IW_TXPOW_MWATT;
  1598. wrqu->txpower.value = le32_to_cpu(tx_power);
  1599. wrqu->txpower.disabled = 0;
  1600. } else {
  1601. wrqu->txpower.flags = IW_TXPOW_MWATT;
  1602. wrqu->txpower.value = 0;
  1603. wrqu->txpower.disabled = 1;
  1604. }
  1605. devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
  1606. return ret;
  1607. }
  1608. static int rndis_iw_set_txpower(struct net_device *dev,
  1609. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1610. {
  1611. struct usbnet *usbdev = netdev_priv(dev);
  1612. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1613. __le32 tx_power = 0;
  1614. int ret = 0;
  1615. if (!wrqu->txpower.disabled) {
  1616. if (wrqu->txpower.flags == IW_TXPOW_MWATT)
  1617. tx_power = cpu_to_le32(wrqu->txpower.value);
  1618. else { /* wrqu->txpower.flags == IW_TXPOW_DBM */
  1619. if (wrqu->txpower.value > 20)
  1620. tx_power = cpu_to_le32(128);
  1621. else if (wrqu->txpower.value < -43)
  1622. tx_power = cpu_to_le32(127);
  1623. else {
  1624. signed char tmp;
  1625. tmp = wrqu->txpower.value;
  1626. tmp = -12 - tmp;
  1627. tmp <<= 2;
  1628. tx_power = cpu_to_le32((unsigned char)tmp);
  1629. }
  1630. }
  1631. }
  1632. devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
  1633. if (le32_to_cpu(tx_power) != 0) {
  1634. if (priv->caps & CAP_SUPPORT_TXPOWER) {
  1635. /* turn radio on first */
  1636. if (!priv->radio_on)
  1637. disassociate(usbdev, 1);
  1638. ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
  1639. &tx_power, sizeof(tx_power));
  1640. if (ret != 0)
  1641. ret = -EOPNOTSUPP;
  1642. return ret;
  1643. } else {
  1644. /* txpower unsupported, just turn radio on */
  1645. if (!priv->radio_on)
  1646. return disassociate(usbdev, 1);
  1647. return 0; /* all ready on */
  1648. }
  1649. }
  1650. /* tx_power == 0, turn off radio */
  1651. return disassociate(usbdev, 0);
  1652. }
  1653. static int rndis_iw_get_rate(struct net_device *dev,
  1654. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1655. {
  1656. struct usbnet *usbdev = netdev_priv(dev);
  1657. __le32 tmp;
  1658. int ret, len;
  1659. len = sizeof(tmp);
  1660. ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
  1661. if (ret == 0) {
  1662. wrqu->bitrate.value = le32_to_cpu(tmp) * 100;
  1663. wrqu->bitrate.disabled = 0;
  1664. wrqu->bitrate.flags = 1;
  1665. }
  1666. return ret;
  1667. }
  1668. static int rndis_iw_set_mlme(struct net_device *dev,
  1669. struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  1670. {
  1671. struct usbnet *usbdev = netdev_priv(dev);
  1672. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1673. struct iw_mlme *mlme = (struct iw_mlme *)extra;
  1674. unsigned char bssid[ETH_ALEN];
  1675. get_bssid(usbdev, bssid);
  1676. if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
  1677. return -EINVAL;
  1678. switch (mlme->cmd) {
  1679. case IW_MLME_DEAUTH:
  1680. return deauthenticate(usbdev);
  1681. case IW_MLME_DISASSOC:
  1682. return disassociate(usbdev, priv->radio_on);
  1683. default:
  1684. return -EOPNOTSUPP;
  1685. }
  1686. return 0;
  1687. }
  1688. static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
  1689. {
  1690. struct usbnet *usbdev = netdev_priv(dev);
  1691. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1692. unsigned long flags;
  1693. spin_lock_irqsave(&priv->stats_lock, flags);
  1694. memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats));
  1695. spin_unlock_irqrestore(&priv->stats_lock, flags);
  1696. return &priv->iwstats;
  1697. }
  1698. #define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT]
  1699. static const iw_handler rndis_iw_handler[] =
  1700. {
  1701. IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit,
  1702. IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
  1703. IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq,
  1704. IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq,
  1705. IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode,
  1706. IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode,
  1707. IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange,
  1708. IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid,
  1709. IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid,
  1710. IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan,
  1711. IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan,
  1712. IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid,
  1713. IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid,
  1714. IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick,
  1715. IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick,
  1716. IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
  1717. IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts,
  1718. IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts,
  1719. IW_IOCTL(SIOCSIWFRAG) = rndis_iw_set_frag,
  1720. IW_IOCTL(SIOCGIWFRAG) = rndis_iw_get_frag,
  1721. IW_IOCTL(SIOCSIWTXPOW) = rndis_iw_set_txpower,
  1722. IW_IOCTL(SIOCGIWTXPOW) = rndis_iw_get_txpower,
  1723. IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode,
  1724. IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
  1725. IW_IOCTL(SIOCSIWAUTH) = rndis_iw_set_auth,
  1726. IW_IOCTL(SIOCGIWAUTH) = rndis_iw_get_auth,
  1727. IW_IOCTL(SIOCSIWGENIE) = rndis_iw_set_genie,
  1728. IW_IOCTL(SIOCGIWGENIE) = rndis_iw_get_genie,
  1729. IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme,
  1730. };
  1731. static const iw_handler rndis_wext_private_handler[] = {
  1732. };
  1733. static const struct iw_priv_args rndis_wext_private_args[] = {
  1734. };
  1735. static const struct iw_handler_def rndis_iw_handlers = {
  1736. .num_standard = ARRAY_SIZE(rndis_iw_handler),
  1737. .num_private = ARRAY_SIZE(rndis_wext_private_handler),
  1738. .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
  1739. .standard = (iw_handler *)rndis_iw_handler,
  1740. .private = (iw_handler *)rndis_wext_private_handler,
  1741. .private_args = (struct iw_priv_args *)rndis_wext_private_args,
  1742. .get_wireless_stats = rndis_get_wireless_stats,
  1743. };
  1744. static void rndis_wext_worker(struct work_struct *work)
  1745. {
  1746. struct rndis_wext_private *priv =
  1747. container_of(work, struct rndis_wext_private, work);
  1748. struct usbnet *usbdev = priv->usbdev;
  1749. union iwreq_data evt;
  1750. unsigned char bssid[ETH_ALEN];
  1751. struct ndis_80211_assoc_info *info;
  1752. int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32;
  1753. int ret, offset;
  1754. if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) {
  1755. netif_carrier_on(usbdev->net);
  1756. info = kzalloc(assoc_size, GFP_KERNEL);
  1757. if (!info)
  1758. goto get_bssid;
  1759. /* Get association info IEs from device and send them back to
  1760. * userspace. */
  1761. ret = get_association_info(usbdev, info, assoc_size);
  1762. if (!ret) {
  1763. evt.data.length = le32_to_cpu(info->req_ie_length);
  1764. if (evt.data.length > 0) {
  1765. offset = le32_to_cpu(info->offset_req_ies);
  1766. wireless_send_event(usbdev->net,
  1767. IWEVASSOCREQIE, &evt,
  1768. (char *)info + offset);
  1769. }
  1770. evt.data.length = le32_to_cpu(info->resp_ie_length);
  1771. if (evt.data.length > 0) {
  1772. offset = le32_to_cpu(info->offset_resp_ies);
  1773. wireless_send_event(usbdev->net,
  1774. IWEVASSOCRESPIE, &evt,
  1775. (char *)info + offset);
  1776. }
  1777. }
  1778. kfree(info);
  1779. get_bssid:
  1780. ret = get_bssid(usbdev, bssid);
  1781. if (!ret) {
  1782. evt.data.flags = 0;
  1783. evt.data.length = 0;
  1784. memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
  1785. wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
  1786. }
  1787. }
  1788. if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) {
  1789. netif_carrier_off(usbdev->net);
  1790. evt.data.flags = 0;
  1791. evt.data.length = 0;
  1792. memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
  1793. wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
  1794. }
  1795. if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
  1796. set_multicast_list(usbdev);
  1797. }
  1798. static void rndis_wext_set_multicast_list(struct net_device *dev)
  1799. {
  1800. struct usbnet *usbdev = netdev_priv(dev);
  1801. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1802. if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
  1803. return;
  1804. set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
  1805. queue_work(priv->workqueue, &priv->work);
  1806. }
  1807. static void rndis_wext_link_change(struct usbnet *usbdev, int state)
  1808. {
  1809. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1810. /* queue work to avoid recursive calls into rndis_command */
  1811. set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
  1812. queue_work(priv->workqueue, &priv->work);
  1813. }
  1814. static int rndis_wext_get_caps(struct usbnet *usbdev)
  1815. {
  1816. struct {
  1817. __le32 num_items;
  1818. __le32 items[8];
  1819. } networks_supported;
  1820. int len, retval, i, n;
  1821. __le32 tx_power;
  1822. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1823. /* determine if supports setting txpower */
  1824. len = sizeof(tx_power);
  1825. retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power,
  1826. &len);
  1827. if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
  1828. priv->caps |= CAP_SUPPORT_TXPOWER;
  1829. /* determine supported modes */
  1830. len = sizeof(networks_supported);
  1831. retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED,
  1832. &networks_supported, &len);
  1833. if (retval >= 0) {
  1834. n = le32_to_cpu(networks_supported.num_items);
  1835. if (n > 8)
  1836. n = 8;
  1837. for (i = 0; i < n; i++) {
  1838. switch (le32_to_cpu(networks_supported.items[i])) {
  1839. case ndis_80211_type_freq_hop:
  1840. case ndis_80211_type_direct_seq:
  1841. priv->caps |= CAP_MODE_80211B;
  1842. break;
  1843. case ndis_80211_type_ofdm_a:
  1844. priv->caps |= CAP_MODE_80211A;
  1845. break;
  1846. case ndis_80211_type_ofdm_g:
  1847. priv->caps |= CAP_MODE_80211G;
  1848. break;
  1849. }
  1850. }
  1851. }
  1852. return retval;
  1853. }
  1854. #define STATS_UPDATE_JIFFIES (HZ)
  1855. static void rndis_update_wireless_stats(struct work_struct *work)
  1856. {
  1857. struct rndis_wext_private *priv =
  1858. container_of(work, struct rndis_wext_private, stats_work.work);
  1859. struct usbnet *usbdev = priv->usbdev;
  1860. struct iw_statistics iwstats;
  1861. __le32 rssi, tmp;
  1862. int len, ret, j;
  1863. unsigned long flags;
  1864. int update_jiffies = STATS_UPDATE_JIFFIES;
  1865. void *buf;
  1866. spin_lock_irqsave(&priv->stats_lock, flags);
  1867. memcpy(&iwstats, &priv->privstats, sizeof(iwstats));
  1868. spin_unlock_irqrestore(&priv->stats_lock, flags);
  1869. /* only update stats when connected */
  1870. if (!is_associated(usbdev)) {
  1871. iwstats.qual.qual = 0;
  1872. iwstats.qual.level = 0;
  1873. iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
  1874. | IW_QUAL_LEVEL_UPDATED
  1875. | IW_QUAL_NOISE_INVALID
  1876. | IW_QUAL_QUAL_INVALID
  1877. | IW_QUAL_LEVEL_INVALID;
  1878. goto end;
  1879. }
  1880. len = sizeof(rssi);
  1881. ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
  1882. devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret,
  1883. le32_to_cpu(rssi));
  1884. if (ret == 0) {
  1885. memset(&iwstats.qual, 0, sizeof(iwstats.qual));
  1886. iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi));
  1887. iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
  1888. iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
  1889. | IW_QUAL_LEVEL_UPDATED
  1890. | IW_QUAL_NOISE_INVALID;
  1891. }
  1892. memset(&iwstats.discard, 0, sizeof(iwstats.discard));
  1893. len = sizeof(tmp);
  1894. ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len);
  1895. if (ret == 0)
  1896. iwstats.discard.misc += le32_to_cpu(tmp);
  1897. len = sizeof(tmp);
  1898. ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len);
  1899. if (ret == 0)
  1900. iwstats.discard.misc += le32_to_cpu(tmp);
  1901. len = sizeof(tmp);
  1902. ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len);
  1903. if (ret == 0)
  1904. iwstats.discard.misc += le32_to_cpu(tmp);
  1905. /* Workaround transfer stalls on poor quality links.
  1906. * TODO: find right way to fix these stalls (as stalls do not happen
  1907. * with ndiswrapper/windows driver). */
  1908. if (iwstats.qual.qual <= 25) {
  1909. /* Decrease stats worker interval to catch stalls.
  1910. * faster. Faster than 400-500ms causes packet loss,
  1911. * Slower doesn't catch stalls fast enough.
  1912. */
  1913. j = msecs_to_jiffies(priv->param_workaround_interval);
  1914. if (j > STATS_UPDATE_JIFFIES)
  1915. j = STATS_UPDATE_JIFFIES;
  1916. else if (j <= 0)
  1917. j = 1;
  1918. update_jiffies = j;
  1919. /* Send scan OID. Use of both OIDs is required to get device
  1920. * working.
  1921. */
  1922. tmp = cpu_to_le32(1);
  1923. rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
  1924. sizeof(tmp));
  1925. len = CONTROL_BUFFER_SIZE;
  1926. buf = kmalloc(len, GFP_KERNEL);
  1927. if (!buf)
  1928. goto end;
  1929. rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
  1930. kfree(buf);
  1931. }
  1932. end:
  1933. spin_lock_irqsave(&priv->stats_lock, flags);
  1934. memcpy(&priv->privstats, &iwstats, sizeof(iwstats));
  1935. spin_unlock_irqrestore(&priv->stats_lock, flags);
  1936. if (update_jiffies >= HZ)
  1937. update_jiffies = round_jiffies_relative(update_jiffies);
  1938. else {
  1939. j = round_jiffies_relative(update_jiffies);
  1940. if (abs(j - update_jiffies) <= 10)
  1941. update_jiffies = j;
  1942. }
  1943. queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies);
  1944. }
  1945. static int bcm4320_early_init(struct usbnet *usbdev)
  1946. {
  1947. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  1948. char buf[8];
  1949. /* Early initialization settings, setting these won't have effect
  1950. * if called after generic_rndis_bind().
  1951. */
  1952. priv->param_country[0] = modparam_country[0];
  1953. priv->param_country[1] = modparam_country[1];
  1954. priv->param_country[2] = 0;
  1955. priv->param_frameburst = modparam_frameburst;
  1956. priv->param_afterburner = modparam_afterburner;
  1957. priv->param_power_save = modparam_power_save;
  1958. priv->param_power_output = modparam_power_output;
  1959. priv->param_roamtrigger = modparam_roamtrigger;
  1960. priv->param_roamdelta = modparam_roamdelta;
  1961. priv->param_country[0] = toupper(priv->param_country[0]);
  1962. priv->param_country[1] = toupper(priv->param_country[1]);
  1963. /* doesn't support EU as country code, use FI instead */
  1964. if (!strcmp(priv->param_country, "EU"))
  1965. strcpy(priv->param_country, "FI");
  1966. if (priv->param_power_save < 0)
  1967. priv->param_power_save = 0;
  1968. else if (priv->param_power_save > 2)
  1969. priv->param_power_save = 2;
  1970. if (priv->param_power_output < 0)
  1971. priv->param_power_output = 0;
  1972. else if (priv->param_power_output > 3)
  1973. priv->param_power_output = 3;
  1974. if (priv->param_roamtrigger < -80)
  1975. priv->param_roamtrigger = -80;
  1976. else if (priv->param_roamtrigger > -60)
  1977. priv->param_roamtrigger = -60;
  1978. if (priv->param_roamdelta < 0)
  1979. priv->param_roamdelta = 0;
  1980. else if (priv->param_roamdelta > 2)
  1981. priv->param_roamdelta = 2;
  1982. if (modparam_workaround_interval < 0)
  1983. priv->param_workaround_interval = 500;
  1984. else
  1985. priv->param_workaround_interval = modparam_workaround_interval;
  1986. rndis_set_config_parameter_str(usbdev, "Country", priv->param_country);
  1987. rndis_set_config_parameter_str(usbdev, "FrameBursting",
  1988. priv->param_frameburst ? "1" : "0");
  1989. rndis_set_config_parameter_str(usbdev, "Afterburner",
  1990. priv->param_afterburner ? "1" : "0");
  1991. sprintf(buf, "%d", priv->param_power_save);
  1992. rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf);
  1993. sprintf(buf, "%d", priv->param_power_output);
  1994. rndis_set_config_parameter_str(usbdev, "PwrOut", buf);
  1995. sprintf(buf, "%d", priv->param_roamtrigger);
  1996. rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf);
  1997. sprintf(buf, "%d", priv->param_roamdelta);
  1998. rndis_set_config_parameter_str(usbdev, "RoamDelta", buf);
  1999. return 0;
  2000. }
  2001. /* same as rndis_netdev_ops but with local multicast handler */
  2002. static const struct net_device_ops rndis_wext_netdev_ops = {
  2003. .ndo_open = usbnet_open,
  2004. .ndo_stop = usbnet_stop,
  2005. .ndo_start_xmit = usbnet_start_xmit,
  2006. .ndo_tx_timeout = usbnet_tx_timeout,
  2007. .ndo_set_mac_address = eth_mac_addr,
  2008. .ndo_validate_addr = eth_validate_addr,
  2009. .ndo_set_multicast_list = rndis_wext_set_multicast_list,
  2010. };
  2011. static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
  2012. {
  2013. struct wiphy *wiphy;
  2014. struct rndis_wext_private *priv;
  2015. int retval, len;
  2016. __le32 tmp;
  2017. /* allocate wiphy and rndis private data
  2018. * NOTE: We only support a single virtual interface, so wiphy
  2019. * and wireless_dev are somewhat synonymous for this device.
  2020. */
  2021. wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private));
  2022. if (!wiphy)
  2023. return -ENOMEM;
  2024. priv = wiphy_priv(wiphy);
  2025. usbdev->net->ieee80211_ptr = &priv->wdev;
  2026. priv->wdev.wiphy = wiphy;
  2027. priv->wdev.iftype = NL80211_IFTYPE_STATION;
  2028. /* These have to be initialized before calling generic_rndis_bind().
  2029. * Otherwise we'll be in big trouble in rndis_wext_early_init().
  2030. */
  2031. usbdev->driver_priv = priv;
  2032. usbdev->net->wireless_handlers = &rndis_iw_handlers;
  2033. priv->usbdev = usbdev;
  2034. mutex_init(&priv->command_lock);
  2035. spin_lock_init(&priv->stats_lock);
  2036. /* try bind rndis_host */
  2037. retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
  2038. if (retval < 0)
  2039. goto fail;
  2040. /* generic_rndis_bind set packet filter to multicast_all+
  2041. * promisc mode which doesn't work well for our devices (device
  2042. * picks up rssi to closest station instead of to access point).
  2043. *
  2044. * rndis_host wants to avoid all OID as much as possible
  2045. * so do promisc/multicast handling in rndis_wext.
  2046. */
  2047. usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
  2048. tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
  2049. retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
  2050. sizeof(tmp));
  2051. len = sizeof(tmp);
  2052. retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp,
  2053. &len);
  2054. priv->multicast_size = le32_to_cpu(tmp);
  2055. if (retval < 0 || priv->multicast_size < 0)
  2056. priv->multicast_size = 0;
  2057. if (priv->multicast_size > 0)
  2058. usbdev->net->flags |= IFF_MULTICAST;
  2059. else
  2060. usbdev->net->flags &= ~IFF_MULTICAST;
  2061. priv->iwstats.qual.qual = 0;
  2062. priv->iwstats.qual.level = 0;
  2063. priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
  2064. | IW_QUAL_LEVEL_UPDATED
  2065. | IW_QUAL_NOISE_INVALID
  2066. | IW_QUAL_QUAL_INVALID
  2067. | IW_QUAL_LEVEL_INVALID;
  2068. /* fill-out wiphy structure and register w/ cfg80211 */
  2069. memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
  2070. wiphy->privid = rndis_wiphy_privid;
  2071. wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
  2072. | BIT(NL80211_IFTYPE_ADHOC);
  2073. wiphy->max_scan_ssids = 1;
  2074. /* TODO: fill-out band information based on priv->caps */
  2075. rndis_wext_get_caps(usbdev);
  2076. memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
  2077. memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
  2078. priv->band.channels = priv->channels;
  2079. priv->band.n_channels = ARRAY_SIZE(rndis_channels);
  2080. priv->band.bitrates = priv->rates;
  2081. priv->band.n_bitrates = ARRAY_SIZE(rndis_rates);
  2082. wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
  2083. wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
  2084. set_wiphy_dev(wiphy, &usbdev->udev->dev);
  2085. if (wiphy_register(wiphy)) {
  2086. wiphy_free(wiphy);
  2087. return -ENODEV;
  2088. }
  2089. set_default_iw_params(usbdev);
  2090. /* turn radio on */
  2091. priv->radio_on = 1;
  2092. disassociate(usbdev, 1);
  2093. netif_carrier_off(usbdev->net);
  2094. /* because rndis_command() sleeps we need to use workqueue */
  2095. priv->workqueue = create_singlethread_workqueue("rndis_wlan");
  2096. INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
  2097. queue_delayed_work(priv->workqueue, &priv->stats_work,
  2098. round_jiffies_relative(STATS_UPDATE_JIFFIES));
  2099. INIT_WORK(&priv->work, rndis_wext_worker);
  2100. return 0;
  2101. fail:
  2102. kfree(priv);
  2103. return retval;
  2104. }
  2105. static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
  2106. {
  2107. struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
  2108. /* turn radio off */
  2109. disassociate(usbdev, 0);
  2110. cancel_delayed_work_sync(&priv->stats_work);
  2111. cancel_work_sync(&priv->work);
  2112. flush_workqueue(priv->workqueue);
  2113. destroy_workqueue(priv->workqueue);
  2114. if (priv && priv->wpa_ie_len)
  2115. kfree(priv->wpa_ie);
  2116. rndis_unbind(usbdev, intf);
  2117. wiphy_unregister(priv->wdev.wiphy);
  2118. wiphy_free(priv->wdev.wiphy);
  2119. }
  2120. static int rndis_wext_reset(struct usbnet *usbdev)
  2121. {
  2122. return deauthenticate(usbdev);
  2123. }
  2124. static const struct driver_info bcm4320b_info = {
  2125. .description = "Wireless RNDIS device, BCM4320b based",
  2126. .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
  2127. .bind = rndis_wext_bind,
  2128. .unbind = rndis_wext_unbind,
  2129. .status = rndis_status,
  2130. .rx_fixup = rndis_rx_fixup,
  2131. .tx_fixup = rndis_tx_fixup,
  2132. .reset = rndis_wext_reset,
  2133. .early_init = bcm4320_early_init,
  2134. .link_change = rndis_wext_link_change,
  2135. };
  2136. static const struct driver_info bcm4320a_info = {
  2137. .description = "Wireless RNDIS device, BCM4320a based",
  2138. .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
  2139. .bind = rndis_wext_bind,
  2140. .unbind = rndis_wext_unbind,
  2141. .status = rndis_status,
  2142. .rx_fixup = rndis_rx_fixup,
  2143. .tx_fixup = rndis_tx_fixup,
  2144. .reset = rndis_wext_reset,
  2145. .early_init = bcm4320_early_init,
  2146. .link_change = rndis_wext_link_change,
  2147. };
  2148. static const struct driver_info rndis_wext_info = {
  2149. .description = "Wireless RNDIS device",
  2150. .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
  2151. .bind = rndis_wext_bind,
  2152. .unbind = rndis_wext_unbind,
  2153. .status = rndis_status,
  2154. .rx_fixup = rndis_rx_fixup,
  2155. .tx_fixup = rndis_tx_fixup,
  2156. .reset = rndis_wext_reset,
  2157. .early_init = bcm4320_early_init,
  2158. .link_change = rndis_wext_link_change,
  2159. };
  2160. /*-------------------------------------------------------------------------*/
  2161. static const struct usb_device_id products [] = {
  2162. #define RNDIS_MASTER_INTERFACE \
  2163. .bInterfaceClass = USB_CLASS_COMM, \
  2164. .bInterfaceSubClass = 2 /* ACM */, \
  2165. .bInterfaceProtocol = 0x0ff
  2166. /* INF driver for these devices have DriverVer >= 4.xx.xx.xx and many custom
  2167. * parameters available. Chipset marked as 'BCM4320SKFBG' in NDISwrapper-wiki.
  2168. */
  2169. {
  2170. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2171. | USB_DEVICE_ID_MATCH_DEVICE,
  2172. .idVendor = 0x0411,
  2173. .idProduct = 0x00bc, /* Buffalo WLI-U2-KG125S */
  2174. RNDIS_MASTER_INTERFACE,
  2175. .driver_info = (unsigned long) &bcm4320b_info,
  2176. }, {
  2177. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2178. | USB_DEVICE_ID_MATCH_DEVICE,
  2179. .idVendor = 0x0baf,
  2180. .idProduct = 0x011b, /* U.S. Robotics USR5421 */
  2181. RNDIS_MASTER_INTERFACE,
  2182. .driver_info = (unsigned long) &bcm4320b_info,
  2183. }, {
  2184. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2185. | USB_DEVICE_ID_MATCH_DEVICE,
  2186. .idVendor = 0x050d,
  2187. .idProduct = 0x011b, /* Belkin F5D7051 */
  2188. RNDIS_MASTER_INTERFACE,
  2189. .driver_info = (unsigned long) &bcm4320b_info,
  2190. }, {
  2191. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2192. | USB_DEVICE_ID_MATCH_DEVICE,
  2193. .idVendor = 0x1799, /* Belkin has two vendor ids */
  2194. .idProduct = 0x011b, /* Belkin F5D7051 */
  2195. RNDIS_MASTER_INTERFACE,
  2196. .driver_info = (unsigned long) &bcm4320b_info,
  2197. }, {
  2198. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2199. | USB_DEVICE_ID_MATCH_DEVICE,
  2200. .idVendor = 0x13b1,
  2201. .idProduct = 0x0014, /* Linksys WUSB54GSv2 */
  2202. RNDIS_MASTER_INTERFACE,
  2203. .driver_info = (unsigned long) &bcm4320b_info,
  2204. }, {
  2205. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2206. | USB_DEVICE_ID_MATCH_DEVICE,
  2207. .idVendor = 0x13b1,
  2208. .idProduct = 0x0026, /* Linksys WUSB54GSC */
  2209. RNDIS_MASTER_INTERFACE,
  2210. .driver_info = (unsigned long) &bcm4320b_info,
  2211. }, {
  2212. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2213. | USB_DEVICE_ID_MATCH_DEVICE,
  2214. .idVendor = 0x0b05,
  2215. .idProduct = 0x1717, /* Asus WL169gE */
  2216. RNDIS_MASTER_INTERFACE,
  2217. .driver_info = (unsigned long) &bcm4320b_info,
  2218. }, {
  2219. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2220. | USB_DEVICE_ID_MATCH_DEVICE,
  2221. .idVendor = 0x0a5c,
  2222. .idProduct = 0xd11b, /* Eminent EM4045 */
  2223. RNDIS_MASTER_INTERFACE,
  2224. .driver_info = (unsigned long) &bcm4320b_info,
  2225. }, {
  2226. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2227. | USB_DEVICE_ID_MATCH_DEVICE,
  2228. .idVendor = 0x1690,
  2229. .idProduct = 0x0715, /* BT Voyager 1055 */
  2230. RNDIS_MASTER_INTERFACE,
  2231. .driver_info = (unsigned long) &bcm4320b_info,
  2232. },
  2233. /* These devices have DriverVer < 4.xx.xx.xx and do not have any custom
  2234. * parameters available, hardware probably contain older firmware version with
  2235. * no way of updating. Chipset marked as 'BCM4320????' in NDISwrapper-wiki.
  2236. */
  2237. {
  2238. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2239. | USB_DEVICE_ID_MATCH_DEVICE,
  2240. .idVendor = 0x13b1,
  2241. .idProduct = 0x000e, /* Linksys WUSB54GSv1 */
  2242. RNDIS_MASTER_INTERFACE,
  2243. .driver_info = (unsigned long) &bcm4320a_info,
  2244. }, {
  2245. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2246. | USB_DEVICE_ID_MATCH_DEVICE,
  2247. .idVendor = 0x0baf,
  2248. .idProduct = 0x0111, /* U.S. Robotics USR5420 */
  2249. RNDIS_MASTER_INTERFACE,
  2250. .driver_info = (unsigned long) &bcm4320a_info,
  2251. }, {
  2252. .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  2253. | USB_DEVICE_ID_MATCH_DEVICE,
  2254. .idVendor = 0x0411,
  2255. .idProduct = 0x004b, /* BUFFALO WLI-USB-G54 */
  2256. RNDIS_MASTER_INTERFACE,
  2257. .driver_info = (unsigned long) &bcm4320a_info,
  2258. },
  2259. /* Generic Wireless RNDIS devices that we don't have exact
  2260. * idVendor/idProduct/chip yet.
  2261. */
  2262. {
  2263. /* RNDIS is MSFT's un-official variant of CDC ACM */
  2264. USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
  2265. .driver_info = (unsigned long) &rndis_wext_info,
  2266. }, {
  2267. /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
  2268. USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
  2269. .driver_info = (unsigned long) &rndis_wext_info,
  2270. },
  2271. { }, // END
  2272. };
  2273. MODULE_DEVICE_TABLE(usb, products);
  2274. static struct usb_driver rndis_wlan_driver = {
  2275. .name = "rndis_wlan",
  2276. .id_table = products,
  2277. .probe = usbnet_probe,
  2278. .disconnect = usbnet_disconnect,
  2279. .suspend = usbnet_suspend,
  2280. .resume = usbnet_resume,
  2281. };
  2282. static int __init rndis_wlan_init(void)
  2283. {
  2284. return usb_register(&rndis_wlan_driver);
  2285. }
  2286. module_init(rndis_wlan_init);
  2287. static void __exit rndis_wlan_exit(void)
  2288. {
  2289. usb_deregister(&rndis_wlan_driver);
  2290. }
  2291. module_exit(rndis_wlan_exit);
  2292. MODULE_AUTHOR("Bjorge Dijkstra");
  2293. MODULE_AUTHOR("Jussi Kivilinna");
  2294. MODULE_DESCRIPTION("Driver for RNDIS based USB Wireless adapters");
  2295. MODULE_LICENSE("GPL");