wext-compat.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * cfg80211 - wext compat code
  4. *
  5. * This is temporary code until all wireless functionality is migrated
  6. * into cfg80211, when that happens all the exports here go away and
  7. * we directly assign the wireless handlers of wireless interfaces.
  8. *
  9. * Copyright 2008-2009 Johannes Berg <[email protected]>
  10. * Copyright (C) 2019-2022 Intel Corporation
  11. */
  12. #include <linux/export.h>
  13. #include <linux/wireless.h>
  14. #include <linux/nl80211.h>
  15. #include <linux/if_arp.h>
  16. #include <linux/etherdevice.h>
  17. #include <linux/slab.h>
  18. #include <net/iw_handler.h>
  19. #include <net/cfg80211.h>
  20. #include <net/cfg80211-wext.h>
  21. #include "wext-compat.h"
  22. #include "core.h"
  23. #include "rdev-ops.h"
  24. int cfg80211_wext_giwname(struct net_device *dev,
  25. struct iw_request_info *info,
  26. char *name, char *extra)
  27. {
  28. strcpy(name, "IEEE 802.11");
  29. return 0;
  30. }
  31. EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
  32. int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
  33. u32 *mode, char *extra)
  34. {
  35. struct wireless_dev *wdev = dev->ieee80211_ptr;
  36. struct cfg80211_registered_device *rdev;
  37. struct vif_params vifparams;
  38. enum nl80211_iftype type;
  39. int ret;
  40. rdev = wiphy_to_rdev(wdev->wiphy);
  41. switch (*mode) {
  42. case IW_MODE_INFRA:
  43. type = NL80211_IFTYPE_STATION;
  44. break;
  45. case IW_MODE_ADHOC:
  46. type = NL80211_IFTYPE_ADHOC;
  47. break;
  48. case IW_MODE_MONITOR:
  49. type = NL80211_IFTYPE_MONITOR;
  50. break;
  51. default:
  52. return -EINVAL;
  53. }
  54. if (type == wdev->iftype)
  55. return 0;
  56. memset(&vifparams, 0, sizeof(vifparams));
  57. wiphy_lock(wdev->wiphy);
  58. ret = cfg80211_change_iface(rdev, dev, type, &vifparams);
  59. wiphy_unlock(wdev->wiphy);
  60. return ret;
  61. }
  62. EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
  63. int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
  64. u32 *mode, char *extra)
  65. {
  66. struct wireless_dev *wdev = dev->ieee80211_ptr;
  67. if (!wdev)
  68. return -EOPNOTSUPP;
  69. switch (wdev->iftype) {
  70. case NL80211_IFTYPE_AP:
  71. *mode = IW_MODE_MASTER;
  72. break;
  73. case NL80211_IFTYPE_STATION:
  74. *mode = IW_MODE_INFRA;
  75. break;
  76. case NL80211_IFTYPE_ADHOC:
  77. *mode = IW_MODE_ADHOC;
  78. break;
  79. case NL80211_IFTYPE_MONITOR:
  80. *mode = IW_MODE_MONITOR;
  81. break;
  82. case NL80211_IFTYPE_WDS:
  83. *mode = IW_MODE_REPEAT;
  84. break;
  85. case NL80211_IFTYPE_AP_VLAN:
  86. *mode = IW_MODE_SECOND; /* FIXME */
  87. break;
  88. default:
  89. *mode = IW_MODE_AUTO;
  90. break;
  91. }
  92. return 0;
  93. }
  94. EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode);
  95. int cfg80211_wext_giwrange(struct net_device *dev,
  96. struct iw_request_info *info,
  97. struct iw_point *data, char *extra)
  98. {
  99. struct wireless_dev *wdev = dev->ieee80211_ptr;
  100. struct iw_range *range = (struct iw_range *) extra;
  101. enum nl80211_band band;
  102. int i, c = 0;
  103. if (!wdev)
  104. return -EOPNOTSUPP;
  105. data->length = sizeof(struct iw_range);
  106. memset(range, 0, sizeof(struct iw_range));
  107. range->we_version_compiled = WIRELESS_EXT;
  108. range->we_version_source = 21;
  109. range->retry_capa = IW_RETRY_LIMIT;
  110. range->retry_flags = IW_RETRY_LIMIT;
  111. range->min_retry = 0;
  112. range->max_retry = 255;
  113. range->min_rts = 0;
  114. range->max_rts = 2347;
  115. range->min_frag = 256;
  116. range->max_frag = 2346;
  117. range->max_encoding_tokens = 4;
  118. range->max_qual.updated = IW_QUAL_NOISE_INVALID;
  119. switch (wdev->wiphy->signal_type) {
  120. case CFG80211_SIGNAL_TYPE_NONE:
  121. break;
  122. case CFG80211_SIGNAL_TYPE_MBM:
  123. range->max_qual.level = (u8)-110;
  124. range->max_qual.qual = 70;
  125. range->avg_qual.qual = 35;
  126. range->max_qual.updated |= IW_QUAL_DBM;
  127. range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
  128. range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
  129. break;
  130. case CFG80211_SIGNAL_TYPE_UNSPEC:
  131. range->max_qual.level = 100;
  132. range->max_qual.qual = 100;
  133. range->avg_qual.qual = 50;
  134. range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
  135. range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
  136. break;
  137. }
  138. range->avg_qual.level = range->max_qual.level / 2;
  139. range->avg_qual.noise = range->max_qual.noise / 2;
  140. range->avg_qual.updated = range->max_qual.updated;
  141. for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) {
  142. switch (wdev->wiphy->cipher_suites[i]) {
  143. case WLAN_CIPHER_SUITE_TKIP:
  144. range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
  145. IW_ENC_CAPA_WPA);
  146. break;
  147. case WLAN_CIPHER_SUITE_CCMP:
  148. range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
  149. IW_ENC_CAPA_WPA2);
  150. break;
  151. case WLAN_CIPHER_SUITE_WEP40:
  152. range->encoding_size[range->num_encoding_sizes++] =
  153. WLAN_KEY_LEN_WEP40;
  154. break;
  155. case WLAN_CIPHER_SUITE_WEP104:
  156. range->encoding_size[range->num_encoding_sizes++] =
  157. WLAN_KEY_LEN_WEP104;
  158. break;
  159. }
  160. }
  161. for (band = 0; band < NUM_NL80211_BANDS; band ++) {
  162. struct ieee80211_supported_band *sband;
  163. sband = wdev->wiphy->bands[band];
  164. if (!sband)
  165. continue;
  166. for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
  167. struct ieee80211_channel *chan = &sband->channels[i];
  168. if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
  169. range->freq[c].i =
  170. ieee80211_frequency_to_channel(
  171. chan->center_freq);
  172. range->freq[c].m = chan->center_freq;
  173. range->freq[c].e = 6;
  174. c++;
  175. }
  176. }
  177. }
  178. range->num_channels = c;
  179. range->num_frequency = c;
  180. IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
  181. IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
  182. IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
  183. if (wdev->wiphy->max_scan_ssids > 0)
  184. range->scan_capa |= IW_SCAN_CAPA_ESSID;
  185. return 0;
  186. }
  187. EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange);
  188. /**
  189. * cfg80211_wext_freq - get wext frequency for non-"auto"
  190. * @freq: the wext freq encoding
  191. *
  192. * Returns a frequency, or a negative error code, or 0 for auto.
  193. */
  194. int cfg80211_wext_freq(struct iw_freq *freq)
  195. {
  196. /*
  197. * Parse frequency - return 0 for auto and
  198. * -EINVAL for impossible things.
  199. */
  200. if (freq->e == 0) {
  201. enum nl80211_band band = NL80211_BAND_2GHZ;
  202. if (freq->m < 0)
  203. return 0;
  204. if (freq->m > 14)
  205. band = NL80211_BAND_5GHZ;
  206. return ieee80211_channel_to_frequency(freq->m, band);
  207. } else {
  208. int i, div = 1000000;
  209. for (i = 0; i < freq->e; i++)
  210. div /= 10;
  211. if (div <= 0)
  212. return -EINVAL;
  213. return freq->m / div;
  214. }
  215. }
  216. int cfg80211_wext_siwrts(struct net_device *dev,
  217. struct iw_request_info *info,
  218. struct iw_param *rts, char *extra)
  219. {
  220. struct wireless_dev *wdev = dev->ieee80211_ptr;
  221. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  222. u32 orts = wdev->wiphy->rts_threshold;
  223. int err;
  224. wiphy_lock(&rdev->wiphy);
  225. if (rts->disabled || !rts->fixed) {
  226. wdev->wiphy->rts_threshold = (u32) -1;
  227. } else if (rts->value < 0) {
  228. err = -EINVAL;
  229. goto out;
  230. } else {
  231. wdev->wiphy->rts_threshold = rts->value;
  232. }
  233. err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD);
  234. if (err)
  235. wdev->wiphy->rts_threshold = orts;
  236. out:
  237. wiphy_unlock(&rdev->wiphy);
  238. return err;
  239. }
  240. EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
  241. int cfg80211_wext_giwrts(struct net_device *dev,
  242. struct iw_request_info *info,
  243. struct iw_param *rts, char *extra)
  244. {
  245. struct wireless_dev *wdev = dev->ieee80211_ptr;
  246. rts->value = wdev->wiphy->rts_threshold;
  247. rts->disabled = rts->value == (u32) -1;
  248. rts->fixed = 1;
  249. return 0;
  250. }
  251. EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts);
  252. int cfg80211_wext_siwfrag(struct net_device *dev,
  253. struct iw_request_info *info,
  254. struct iw_param *frag, char *extra)
  255. {
  256. struct wireless_dev *wdev = dev->ieee80211_ptr;
  257. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  258. u32 ofrag = wdev->wiphy->frag_threshold;
  259. int err;
  260. wiphy_lock(&rdev->wiphy);
  261. if (frag->disabled || !frag->fixed) {
  262. wdev->wiphy->frag_threshold = (u32) -1;
  263. } else if (frag->value < 256) {
  264. err = -EINVAL;
  265. goto out;
  266. } else {
  267. /* Fragment length must be even, so strip LSB. */
  268. wdev->wiphy->frag_threshold = frag->value & ~0x1;
  269. }
  270. err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD);
  271. if (err)
  272. wdev->wiphy->frag_threshold = ofrag;
  273. out:
  274. wiphy_unlock(&rdev->wiphy);
  275. return err;
  276. }
  277. EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
  278. int cfg80211_wext_giwfrag(struct net_device *dev,
  279. struct iw_request_info *info,
  280. struct iw_param *frag, char *extra)
  281. {
  282. struct wireless_dev *wdev = dev->ieee80211_ptr;
  283. frag->value = wdev->wiphy->frag_threshold;
  284. frag->disabled = frag->value == (u32) -1;
  285. frag->fixed = 1;
  286. return 0;
  287. }
  288. EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag);
  289. static int cfg80211_wext_siwretry(struct net_device *dev,
  290. struct iw_request_info *info,
  291. struct iw_param *retry, char *extra)
  292. {
  293. struct wireless_dev *wdev = dev->ieee80211_ptr;
  294. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  295. u32 changed = 0;
  296. u8 olong = wdev->wiphy->retry_long;
  297. u8 oshort = wdev->wiphy->retry_short;
  298. int err;
  299. if (retry->disabled || retry->value < 1 || retry->value > 255 ||
  300. (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
  301. return -EINVAL;
  302. wiphy_lock(&rdev->wiphy);
  303. if (retry->flags & IW_RETRY_LONG) {
  304. wdev->wiphy->retry_long = retry->value;
  305. changed |= WIPHY_PARAM_RETRY_LONG;
  306. } else if (retry->flags & IW_RETRY_SHORT) {
  307. wdev->wiphy->retry_short = retry->value;
  308. changed |= WIPHY_PARAM_RETRY_SHORT;
  309. } else {
  310. wdev->wiphy->retry_short = retry->value;
  311. wdev->wiphy->retry_long = retry->value;
  312. changed |= WIPHY_PARAM_RETRY_LONG;
  313. changed |= WIPHY_PARAM_RETRY_SHORT;
  314. }
  315. err = rdev_set_wiphy_params(rdev, changed);
  316. if (err) {
  317. wdev->wiphy->retry_short = oshort;
  318. wdev->wiphy->retry_long = olong;
  319. }
  320. wiphy_unlock(&rdev->wiphy);
  321. return err;
  322. }
  323. int cfg80211_wext_giwretry(struct net_device *dev,
  324. struct iw_request_info *info,
  325. struct iw_param *retry, char *extra)
  326. {
  327. struct wireless_dev *wdev = dev->ieee80211_ptr;
  328. retry->disabled = 0;
  329. if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
  330. /*
  331. * First return short value, iwconfig will ask long value
  332. * later if needed
  333. */
  334. retry->flags |= IW_RETRY_LIMIT | IW_RETRY_SHORT;
  335. retry->value = wdev->wiphy->retry_short;
  336. if (wdev->wiphy->retry_long == wdev->wiphy->retry_short)
  337. retry->flags |= IW_RETRY_LONG;
  338. return 0;
  339. }
  340. if (retry->flags & IW_RETRY_LONG) {
  341. retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
  342. retry->value = wdev->wiphy->retry_long;
  343. }
  344. return 0;
  345. }
  346. EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry);
  347. static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
  348. struct net_device *dev, bool pairwise,
  349. const u8 *addr, bool remove, bool tx_key,
  350. int idx, struct key_params *params)
  351. {
  352. struct wireless_dev *wdev = dev->ieee80211_ptr;
  353. int err, i;
  354. bool rejoin = false;
  355. if (wdev->valid_links)
  356. return -EINVAL;
  357. if (pairwise && !addr)
  358. return -EINVAL;
  359. /*
  360. * In many cases we won't actually need this, but it's better
  361. * to do it first in case the allocation fails. Don't use wext.
  362. */
  363. if (!wdev->wext.keys) {
  364. wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
  365. GFP_KERNEL);
  366. if (!wdev->wext.keys)
  367. return -ENOMEM;
  368. for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
  369. wdev->wext.keys->params[i].key =
  370. wdev->wext.keys->data[i];
  371. }
  372. if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
  373. wdev->iftype != NL80211_IFTYPE_STATION)
  374. return -EOPNOTSUPP;
  375. if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
  376. if (!wdev->connected)
  377. return -ENOLINK;
  378. if (!rdev->ops->set_default_mgmt_key)
  379. return -EOPNOTSUPP;
  380. if (idx < 4 || idx > 5)
  381. return -EINVAL;
  382. } else if (idx < 0 || idx > 3)
  383. return -EINVAL;
  384. if (remove) {
  385. err = 0;
  386. if (wdev->connected ||
  387. (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  388. wdev->u.ibss.current_bss)) {
  389. /*
  390. * If removing the current TX key, we will need to
  391. * join a new IBSS without the privacy bit clear.
  392. */
  393. if (idx == wdev->wext.default_key &&
  394. wdev->iftype == NL80211_IFTYPE_ADHOC) {
  395. __cfg80211_leave_ibss(rdev, wdev->netdev, true);
  396. rejoin = true;
  397. }
  398. if (!pairwise && addr &&
  399. !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
  400. err = -ENOENT;
  401. else
  402. err = rdev_del_key(rdev, dev, -1, idx, pairwise,
  403. addr);
  404. }
  405. wdev->wext.connect.privacy = false;
  406. /*
  407. * Applications using wireless extensions expect to be
  408. * able to delete keys that don't exist, so allow that.
  409. */
  410. if (err == -ENOENT)
  411. err = 0;
  412. if (!err) {
  413. if (!addr && idx < 4) {
  414. memset(wdev->wext.keys->data[idx], 0,
  415. sizeof(wdev->wext.keys->data[idx]));
  416. wdev->wext.keys->params[idx].key_len = 0;
  417. wdev->wext.keys->params[idx].cipher = 0;
  418. }
  419. if (idx == wdev->wext.default_key)
  420. wdev->wext.default_key = -1;
  421. else if (idx == wdev->wext.default_mgmt_key)
  422. wdev->wext.default_mgmt_key = -1;
  423. }
  424. if (!err && rejoin)
  425. err = cfg80211_ibss_wext_join(rdev, wdev);
  426. return err;
  427. }
  428. if (addr)
  429. tx_key = false;
  430. if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
  431. return -EINVAL;
  432. err = 0;
  433. if (wdev->connected ||
  434. (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  435. wdev->u.ibss.current_bss))
  436. err = rdev_add_key(rdev, dev, -1, idx, pairwise, addr, params);
  437. else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
  438. params->cipher != WLAN_CIPHER_SUITE_WEP104)
  439. return -EINVAL;
  440. if (err)
  441. return err;
  442. /*
  443. * We only need to store WEP keys, since they're the only keys that
  444. * can be set before a connection is established and persist after
  445. * disconnecting.
  446. */
  447. if (!addr && (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
  448. params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
  449. wdev->wext.keys->params[idx] = *params;
  450. memcpy(wdev->wext.keys->data[idx],
  451. params->key, params->key_len);
  452. wdev->wext.keys->params[idx].key =
  453. wdev->wext.keys->data[idx];
  454. }
  455. if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
  456. params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
  457. (tx_key || (!addr && wdev->wext.default_key == -1))) {
  458. if (wdev->connected ||
  459. (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  460. wdev->u.ibss.current_bss)) {
  461. /*
  462. * If we are getting a new TX key from not having
  463. * had one before we need to join a new IBSS with
  464. * the privacy bit set.
  465. */
  466. if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  467. wdev->wext.default_key == -1) {
  468. __cfg80211_leave_ibss(rdev, wdev->netdev, true);
  469. rejoin = true;
  470. }
  471. err = rdev_set_default_key(rdev, dev, -1, idx, true,
  472. true);
  473. }
  474. if (!err) {
  475. wdev->wext.default_key = idx;
  476. if (rejoin)
  477. err = cfg80211_ibss_wext_join(rdev, wdev);
  478. }
  479. return err;
  480. }
  481. if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
  482. (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
  483. if (wdev->connected ||
  484. (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  485. wdev->u.ibss.current_bss))
  486. err = rdev_set_default_mgmt_key(rdev, dev, -1, idx);
  487. if (!err)
  488. wdev->wext.default_mgmt_key = idx;
  489. return err;
  490. }
  491. return 0;
  492. }
  493. static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
  494. struct net_device *dev, bool pairwise,
  495. const u8 *addr, bool remove, bool tx_key,
  496. int idx, struct key_params *params)
  497. {
  498. int err;
  499. wdev_lock(dev->ieee80211_ptr);
  500. err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
  501. remove, tx_key, idx, params);
  502. wdev_unlock(dev->ieee80211_ptr);
  503. return err;
  504. }
  505. static int cfg80211_wext_siwencode(struct net_device *dev,
  506. struct iw_request_info *info,
  507. struct iw_point *erq, char *keybuf)
  508. {
  509. struct wireless_dev *wdev = dev->ieee80211_ptr;
  510. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  511. int idx, err;
  512. bool remove = false;
  513. struct key_params params;
  514. if (wdev->iftype != NL80211_IFTYPE_STATION &&
  515. wdev->iftype != NL80211_IFTYPE_ADHOC)
  516. return -EOPNOTSUPP;
  517. /* no use -- only MFP (set_default_mgmt_key) is optional */
  518. if (!rdev->ops->del_key ||
  519. !rdev->ops->add_key ||
  520. !rdev->ops->set_default_key)
  521. return -EOPNOTSUPP;
  522. wiphy_lock(&rdev->wiphy);
  523. if (wdev->valid_links) {
  524. err = -EOPNOTSUPP;
  525. goto out;
  526. }
  527. idx = erq->flags & IW_ENCODE_INDEX;
  528. if (idx == 0) {
  529. idx = wdev->wext.default_key;
  530. if (idx < 0)
  531. idx = 0;
  532. } else if (idx < 1 || idx > 4) {
  533. err = -EINVAL;
  534. goto out;
  535. } else {
  536. idx--;
  537. }
  538. if (erq->flags & IW_ENCODE_DISABLED)
  539. remove = true;
  540. else if (erq->length == 0) {
  541. /* No key data - just set the default TX key index */
  542. err = 0;
  543. wdev_lock(wdev);
  544. if (wdev->connected ||
  545. (wdev->iftype == NL80211_IFTYPE_ADHOC &&
  546. wdev->u.ibss.current_bss))
  547. err = rdev_set_default_key(rdev, dev, -1, idx, true,
  548. true);
  549. if (!err)
  550. wdev->wext.default_key = idx;
  551. wdev_unlock(wdev);
  552. goto out;
  553. }
  554. memset(&params, 0, sizeof(params));
  555. params.key = keybuf;
  556. params.key_len = erq->length;
  557. if (erq->length == 5) {
  558. params.cipher = WLAN_CIPHER_SUITE_WEP40;
  559. } else if (erq->length == 13) {
  560. params.cipher = WLAN_CIPHER_SUITE_WEP104;
  561. } else if (!remove) {
  562. err = -EINVAL;
  563. goto out;
  564. }
  565. err = cfg80211_set_encryption(rdev, dev, false, NULL, remove,
  566. wdev->wext.default_key == -1,
  567. idx, &params);
  568. out:
  569. wiphy_unlock(&rdev->wiphy);
  570. return err;
  571. }
  572. static int cfg80211_wext_siwencodeext(struct net_device *dev,
  573. struct iw_request_info *info,
  574. struct iw_point *erq, char *extra)
  575. {
  576. struct wireless_dev *wdev = dev->ieee80211_ptr;
  577. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  578. struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
  579. const u8 *addr;
  580. int idx;
  581. bool remove = false;
  582. struct key_params params;
  583. u32 cipher;
  584. int ret;
  585. if (wdev->iftype != NL80211_IFTYPE_STATION &&
  586. wdev->iftype != NL80211_IFTYPE_ADHOC)
  587. return -EOPNOTSUPP;
  588. /* no use -- only MFP (set_default_mgmt_key) is optional */
  589. if (!rdev->ops->del_key ||
  590. !rdev->ops->add_key ||
  591. !rdev->ops->set_default_key)
  592. return -EOPNOTSUPP;
  593. wdev_lock(wdev);
  594. if (wdev->valid_links) {
  595. wdev_unlock(wdev);
  596. return -EOPNOTSUPP;
  597. }
  598. wdev_unlock(wdev);
  599. switch (ext->alg) {
  600. case IW_ENCODE_ALG_NONE:
  601. remove = true;
  602. cipher = 0;
  603. break;
  604. case IW_ENCODE_ALG_WEP:
  605. if (ext->key_len == 5)
  606. cipher = WLAN_CIPHER_SUITE_WEP40;
  607. else if (ext->key_len == 13)
  608. cipher = WLAN_CIPHER_SUITE_WEP104;
  609. else
  610. return -EINVAL;
  611. break;
  612. case IW_ENCODE_ALG_TKIP:
  613. cipher = WLAN_CIPHER_SUITE_TKIP;
  614. break;
  615. case IW_ENCODE_ALG_CCMP:
  616. cipher = WLAN_CIPHER_SUITE_CCMP;
  617. break;
  618. case IW_ENCODE_ALG_AES_CMAC:
  619. cipher = WLAN_CIPHER_SUITE_AES_CMAC;
  620. break;
  621. default:
  622. return -EOPNOTSUPP;
  623. }
  624. if (erq->flags & IW_ENCODE_DISABLED)
  625. remove = true;
  626. idx = erq->flags & IW_ENCODE_INDEX;
  627. if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
  628. if (idx < 4 || idx > 5) {
  629. idx = wdev->wext.default_mgmt_key;
  630. if (idx < 0)
  631. return -EINVAL;
  632. } else
  633. idx--;
  634. } else {
  635. if (idx < 1 || idx > 4) {
  636. idx = wdev->wext.default_key;
  637. if (idx < 0)
  638. return -EINVAL;
  639. } else
  640. idx--;
  641. }
  642. addr = ext->addr.sa_data;
  643. if (is_broadcast_ether_addr(addr))
  644. addr = NULL;
  645. memset(&params, 0, sizeof(params));
  646. params.key = ext->key;
  647. params.key_len = ext->key_len;
  648. params.cipher = cipher;
  649. if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
  650. params.seq = ext->rx_seq;
  651. params.seq_len = 6;
  652. }
  653. wiphy_lock(wdev->wiphy);
  654. ret = cfg80211_set_encryption(
  655. rdev, dev,
  656. !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
  657. addr, remove,
  658. ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
  659. idx, &params);
  660. wiphy_unlock(wdev->wiphy);
  661. return ret;
  662. }
  663. static int cfg80211_wext_giwencode(struct net_device *dev,
  664. struct iw_request_info *info,
  665. struct iw_point *erq, char *keybuf)
  666. {
  667. struct wireless_dev *wdev = dev->ieee80211_ptr;
  668. int idx;
  669. if (wdev->iftype != NL80211_IFTYPE_STATION &&
  670. wdev->iftype != NL80211_IFTYPE_ADHOC)
  671. return -EOPNOTSUPP;
  672. idx = erq->flags & IW_ENCODE_INDEX;
  673. if (idx == 0) {
  674. idx = wdev->wext.default_key;
  675. if (idx < 0)
  676. idx = 0;
  677. } else if (idx < 1 || idx > 4)
  678. return -EINVAL;
  679. else
  680. idx--;
  681. erq->flags = idx + 1;
  682. if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
  683. erq->flags |= IW_ENCODE_DISABLED;
  684. erq->length = 0;
  685. return 0;
  686. }
  687. erq->length = min_t(size_t, erq->length,
  688. wdev->wext.keys->params[idx].key_len);
  689. memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
  690. erq->flags |= IW_ENCODE_ENABLED;
  691. return 0;
  692. }
  693. static int cfg80211_wext_siwfreq(struct net_device *dev,
  694. struct iw_request_info *info,
  695. struct iw_freq *wextfreq, char *extra)
  696. {
  697. struct wireless_dev *wdev = dev->ieee80211_ptr;
  698. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  699. struct cfg80211_chan_def chandef = {
  700. .width = NL80211_CHAN_WIDTH_20_NOHT,
  701. };
  702. int freq, ret;
  703. wiphy_lock(&rdev->wiphy);
  704. switch (wdev->iftype) {
  705. case NL80211_IFTYPE_STATION:
  706. ret = cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
  707. break;
  708. case NL80211_IFTYPE_ADHOC:
  709. ret = cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
  710. break;
  711. case NL80211_IFTYPE_MONITOR:
  712. freq = cfg80211_wext_freq(wextfreq);
  713. if (freq < 0) {
  714. ret = freq;
  715. break;
  716. }
  717. if (freq == 0) {
  718. ret = -EINVAL;
  719. break;
  720. }
  721. chandef.center_freq1 = freq;
  722. chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
  723. if (!chandef.chan) {
  724. ret = -EINVAL;
  725. break;
  726. }
  727. ret = cfg80211_set_monitor_channel(rdev, &chandef);
  728. break;
  729. case NL80211_IFTYPE_MESH_POINT:
  730. freq = cfg80211_wext_freq(wextfreq);
  731. if (freq < 0) {
  732. ret = freq;
  733. break;
  734. }
  735. if (freq == 0) {
  736. ret = -EINVAL;
  737. break;
  738. }
  739. chandef.center_freq1 = freq;
  740. chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
  741. if (!chandef.chan) {
  742. ret = -EINVAL;
  743. break;
  744. }
  745. ret = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
  746. break;
  747. default:
  748. ret = -EOPNOTSUPP;
  749. break;
  750. }
  751. wiphy_unlock(&rdev->wiphy);
  752. return ret;
  753. }
  754. static int cfg80211_wext_giwfreq(struct net_device *dev,
  755. struct iw_request_info *info,
  756. struct iw_freq *freq, char *extra)
  757. {
  758. struct wireless_dev *wdev = dev->ieee80211_ptr;
  759. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  760. struct cfg80211_chan_def chandef = {};
  761. int ret;
  762. wiphy_lock(&rdev->wiphy);
  763. switch (wdev->iftype) {
  764. case NL80211_IFTYPE_STATION:
  765. ret = cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
  766. break;
  767. case NL80211_IFTYPE_ADHOC:
  768. ret = cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
  769. break;
  770. case NL80211_IFTYPE_MONITOR:
  771. if (!rdev->ops->get_channel) {
  772. ret = -EINVAL;
  773. break;
  774. }
  775. ret = rdev_get_channel(rdev, wdev, 0, &chandef);
  776. if (ret)
  777. break;
  778. freq->m = chandef.chan->center_freq;
  779. freq->e = 6;
  780. ret = 0;
  781. break;
  782. default:
  783. ret = -EINVAL;
  784. break;
  785. }
  786. wiphy_unlock(&rdev->wiphy);
  787. return ret;
  788. }
  789. static int cfg80211_wext_siwtxpower(struct net_device *dev,
  790. struct iw_request_info *info,
  791. union iwreq_data *data, char *extra)
  792. {
  793. struct wireless_dev *wdev = dev->ieee80211_ptr;
  794. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  795. enum nl80211_tx_power_setting type;
  796. int dbm = 0;
  797. int ret;
  798. if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
  799. return -EINVAL;
  800. if (data->txpower.flags & IW_TXPOW_RANGE)
  801. return -EINVAL;
  802. if (!rdev->ops->set_tx_power)
  803. return -EOPNOTSUPP;
  804. /* only change when not disabling */
  805. if (!data->txpower.disabled) {
  806. rfkill_set_sw_state(rdev->wiphy.rfkill, false);
  807. if (data->txpower.fixed) {
  808. /*
  809. * wext doesn't support negative values, see
  810. * below where it's for automatic
  811. */
  812. if (data->txpower.value < 0)
  813. return -EINVAL;
  814. dbm = data->txpower.value;
  815. type = NL80211_TX_POWER_FIXED;
  816. /* TODO: do regulatory check! */
  817. } else {
  818. /*
  819. * Automatic power level setting, max being the value
  820. * passed in from userland.
  821. */
  822. if (data->txpower.value < 0) {
  823. type = NL80211_TX_POWER_AUTOMATIC;
  824. } else {
  825. dbm = data->txpower.value;
  826. type = NL80211_TX_POWER_LIMITED;
  827. }
  828. }
  829. } else {
  830. if (rfkill_set_sw_state(rdev->wiphy.rfkill, true))
  831. schedule_work(&rdev->rfkill_block);
  832. return 0;
  833. }
  834. wiphy_lock(&rdev->wiphy);
  835. ret = rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
  836. wiphy_unlock(&rdev->wiphy);
  837. return ret;
  838. }
  839. static int cfg80211_wext_giwtxpower(struct net_device *dev,
  840. struct iw_request_info *info,
  841. union iwreq_data *data, char *extra)
  842. {
  843. struct wireless_dev *wdev = dev->ieee80211_ptr;
  844. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  845. int err, val;
  846. if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
  847. return -EINVAL;
  848. if (data->txpower.flags & IW_TXPOW_RANGE)
  849. return -EINVAL;
  850. if (!rdev->ops->get_tx_power)
  851. return -EOPNOTSUPP;
  852. wiphy_lock(&rdev->wiphy);
  853. err = rdev_get_tx_power(rdev, wdev, &val);
  854. wiphy_unlock(&rdev->wiphy);
  855. if (err)
  856. return err;
  857. /* well... oh well */
  858. data->txpower.fixed = 1;
  859. data->txpower.disabled = rfkill_blocked(rdev->wiphy.rfkill);
  860. data->txpower.value = val;
  861. data->txpower.flags = IW_TXPOW_DBM;
  862. return 0;
  863. }
  864. static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
  865. s32 auth_alg)
  866. {
  867. int nr_alg = 0;
  868. if (!auth_alg)
  869. return -EINVAL;
  870. if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM |
  871. IW_AUTH_ALG_SHARED_KEY |
  872. IW_AUTH_ALG_LEAP))
  873. return -EINVAL;
  874. if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) {
  875. nr_alg++;
  876. wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
  877. }
  878. if (auth_alg & IW_AUTH_ALG_SHARED_KEY) {
  879. nr_alg++;
  880. wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
  881. }
  882. if (auth_alg & IW_AUTH_ALG_LEAP) {
  883. nr_alg++;
  884. wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
  885. }
  886. if (nr_alg > 1)
  887. wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
  888. return 0;
  889. }
  890. static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
  891. {
  892. if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
  893. IW_AUTH_WPA_VERSION_WPA2|
  894. IW_AUTH_WPA_VERSION_DISABLED))
  895. return -EINVAL;
  896. if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
  897. (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
  898. IW_AUTH_WPA_VERSION_WPA2)))
  899. return -EINVAL;
  900. if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
  901. wdev->wext.connect.crypto.wpa_versions &=
  902. ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
  903. if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
  904. wdev->wext.connect.crypto.wpa_versions |=
  905. NL80211_WPA_VERSION_1;
  906. if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2)
  907. wdev->wext.connect.crypto.wpa_versions |=
  908. NL80211_WPA_VERSION_2;
  909. return 0;
  910. }
  911. static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
  912. {
  913. if (cipher & IW_AUTH_CIPHER_WEP40)
  914. wdev->wext.connect.crypto.cipher_group =
  915. WLAN_CIPHER_SUITE_WEP40;
  916. else if (cipher & IW_AUTH_CIPHER_WEP104)
  917. wdev->wext.connect.crypto.cipher_group =
  918. WLAN_CIPHER_SUITE_WEP104;
  919. else if (cipher & IW_AUTH_CIPHER_TKIP)
  920. wdev->wext.connect.crypto.cipher_group =
  921. WLAN_CIPHER_SUITE_TKIP;
  922. else if (cipher & IW_AUTH_CIPHER_CCMP)
  923. wdev->wext.connect.crypto.cipher_group =
  924. WLAN_CIPHER_SUITE_CCMP;
  925. else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
  926. wdev->wext.connect.crypto.cipher_group =
  927. WLAN_CIPHER_SUITE_AES_CMAC;
  928. else if (cipher & IW_AUTH_CIPHER_NONE)
  929. wdev->wext.connect.crypto.cipher_group = 0;
  930. else
  931. return -EINVAL;
  932. return 0;
  933. }
  934. static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
  935. {
  936. int nr_ciphers = 0;
  937. u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
  938. if (cipher & IW_AUTH_CIPHER_WEP40) {
  939. ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40;
  940. nr_ciphers++;
  941. }
  942. if (cipher & IW_AUTH_CIPHER_WEP104) {
  943. ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104;
  944. nr_ciphers++;
  945. }
  946. if (cipher & IW_AUTH_CIPHER_TKIP) {
  947. ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP;
  948. nr_ciphers++;
  949. }
  950. if (cipher & IW_AUTH_CIPHER_CCMP) {
  951. ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP;
  952. nr_ciphers++;
  953. }
  954. if (cipher & IW_AUTH_CIPHER_AES_CMAC) {
  955. ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC;
  956. nr_ciphers++;
  957. }
  958. BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5);
  959. wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers;
  960. return 0;
  961. }
  962. static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
  963. {
  964. int nr_akm_suites = 0;
  965. if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X |
  966. IW_AUTH_KEY_MGMT_PSK))
  967. return -EINVAL;
  968. if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) {
  969. wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
  970. WLAN_AKM_SUITE_8021X;
  971. nr_akm_suites++;
  972. }
  973. if (key_mgt & IW_AUTH_KEY_MGMT_PSK) {
  974. wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
  975. WLAN_AKM_SUITE_PSK;
  976. nr_akm_suites++;
  977. }
  978. wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites;
  979. return 0;
  980. }
  981. static int cfg80211_wext_siwauth(struct net_device *dev,
  982. struct iw_request_info *info,
  983. struct iw_param *data, char *extra)
  984. {
  985. struct wireless_dev *wdev = dev->ieee80211_ptr;
  986. if (wdev->iftype != NL80211_IFTYPE_STATION)
  987. return -EOPNOTSUPP;
  988. switch (data->flags & IW_AUTH_INDEX) {
  989. case IW_AUTH_PRIVACY_INVOKED:
  990. wdev->wext.connect.privacy = data->value;
  991. return 0;
  992. case IW_AUTH_WPA_VERSION:
  993. return cfg80211_set_wpa_version(wdev, data->value);
  994. case IW_AUTH_CIPHER_GROUP:
  995. return cfg80211_set_cipher_group(wdev, data->value);
  996. case IW_AUTH_KEY_MGMT:
  997. return cfg80211_set_key_mgt(wdev, data->value);
  998. case IW_AUTH_CIPHER_PAIRWISE:
  999. return cfg80211_set_cipher_pairwise(wdev, data->value);
  1000. case IW_AUTH_80211_AUTH_ALG:
  1001. return cfg80211_set_auth_alg(wdev, data->value);
  1002. case IW_AUTH_WPA_ENABLED:
  1003. case IW_AUTH_RX_UNENCRYPTED_EAPOL:
  1004. case IW_AUTH_DROP_UNENCRYPTED:
  1005. case IW_AUTH_MFP:
  1006. return 0;
  1007. default:
  1008. return -EOPNOTSUPP;
  1009. }
  1010. }
  1011. static int cfg80211_wext_giwauth(struct net_device *dev,
  1012. struct iw_request_info *info,
  1013. struct iw_param *data, char *extra)
  1014. {
  1015. /* XXX: what do we need? */
  1016. return -EOPNOTSUPP;
  1017. }
  1018. static int cfg80211_wext_siwpower(struct net_device *dev,
  1019. struct iw_request_info *info,
  1020. struct iw_param *wrq, char *extra)
  1021. {
  1022. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1023. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1024. bool ps;
  1025. int timeout = wdev->ps_timeout;
  1026. int err;
  1027. if (wdev->iftype != NL80211_IFTYPE_STATION)
  1028. return -EINVAL;
  1029. if (!rdev->ops->set_power_mgmt)
  1030. return -EOPNOTSUPP;
  1031. if (wrq->disabled) {
  1032. ps = false;
  1033. } else {
  1034. switch (wrq->flags & IW_POWER_MODE) {
  1035. case IW_POWER_ON: /* If not specified */
  1036. case IW_POWER_MODE: /* If set all mask */
  1037. case IW_POWER_ALL_R: /* If explicitely state all */
  1038. ps = true;
  1039. break;
  1040. default: /* Otherwise we ignore */
  1041. return -EINVAL;
  1042. }
  1043. if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
  1044. return -EINVAL;
  1045. if (wrq->flags & IW_POWER_TIMEOUT)
  1046. timeout = wrq->value / 1000;
  1047. }
  1048. wiphy_lock(&rdev->wiphy);
  1049. err = rdev_set_power_mgmt(rdev, dev, ps, timeout);
  1050. wiphy_unlock(&rdev->wiphy);
  1051. if (err)
  1052. return err;
  1053. wdev->ps = ps;
  1054. wdev->ps_timeout = timeout;
  1055. return 0;
  1056. }
  1057. static int cfg80211_wext_giwpower(struct net_device *dev,
  1058. struct iw_request_info *info,
  1059. struct iw_param *wrq, char *extra)
  1060. {
  1061. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1062. wrq->disabled = !wdev->ps;
  1063. return 0;
  1064. }
  1065. static int cfg80211_wext_siwrate(struct net_device *dev,
  1066. struct iw_request_info *info,
  1067. struct iw_param *rate, char *extra)
  1068. {
  1069. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1070. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1071. struct cfg80211_bitrate_mask mask;
  1072. u32 fixed, maxrate;
  1073. struct ieee80211_supported_band *sband;
  1074. int band, ridx, ret;
  1075. bool match = false;
  1076. if (!rdev->ops->set_bitrate_mask)
  1077. return -EOPNOTSUPP;
  1078. memset(&mask, 0, sizeof(mask));
  1079. fixed = 0;
  1080. maxrate = (u32)-1;
  1081. if (rate->value < 0) {
  1082. /* nothing */
  1083. } else if (rate->fixed) {
  1084. fixed = rate->value / 100000;
  1085. } else {
  1086. maxrate = rate->value / 100000;
  1087. }
  1088. for (band = 0; band < NUM_NL80211_BANDS; band++) {
  1089. sband = wdev->wiphy->bands[band];
  1090. if (sband == NULL)
  1091. continue;
  1092. for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
  1093. struct ieee80211_rate *srate = &sband->bitrates[ridx];
  1094. if (fixed == srate->bitrate) {
  1095. mask.control[band].legacy = 1 << ridx;
  1096. match = true;
  1097. break;
  1098. }
  1099. if (srate->bitrate <= maxrate) {
  1100. mask.control[band].legacy |= 1 << ridx;
  1101. match = true;
  1102. }
  1103. }
  1104. }
  1105. if (!match)
  1106. return -EINVAL;
  1107. wiphy_lock(&rdev->wiphy);
  1108. if (dev->ieee80211_ptr->valid_links)
  1109. ret = -EOPNOTSUPP;
  1110. else
  1111. ret = rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask);
  1112. wiphy_unlock(&rdev->wiphy);
  1113. return ret;
  1114. }
  1115. static int cfg80211_wext_giwrate(struct net_device *dev,
  1116. struct iw_request_info *info,
  1117. struct iw_param *rate, char *extra)
  1118. {
  1119. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1120. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1121. struct station_info sinfo = {};
  1122. u8 addr[ETH_ALEN];
  1123. int err;
  1124. if (wdev->iftype != NL80211_IFTYPE_STATION)
  1125. return -EOPNOTSUPP;
  1126. if (!rdev->ops->get_station)
  1127. return -EOPNOTSUPP;
  1128. err = 0;
  1129. wdev_lock(wdev);
  1130. if (!wdev->valid_links && wdev->links[0].client.current_bss)
  1131. memcpy(addr, wdev->links[0].client.current_bss->pub.bssid,
  1132. ETH_ALEN);
  1133. else
  1134. err = -EOPNOTSUPP;
  1135. wdev_unlock(wdev);
  1136. if (err)
  1137. return err;
  1138. wiphy_lock(&rdev->wiphy);
  1139. err = rdev_get_station(rdev, dev, addr, &sinfo);
  1140. wiphy_unlock(&rdev->wiphy);
  1141. if (err)
  1142. return err;
  1143. if (!(sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) {
  1144. err = -EOPNOTSUPP;
  1145. goto free;
  1146. }
  1147. rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
  1148. free:
  1149. cfg80211_sinfo_release_content(&sinfo);
  1150. return err;
  1151. }
  1152. /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
  1153. static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
  1154. {
  1155. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1156. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1157. /* we are under RTNL - globally locked - so can use static structs */
  1158. static struct iw_statistics wstats;
  1159. static struct station_info sinfo = {};
  1160. u8 bssid[ETH_ALEN];
  1161. int ret;
  1162. if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
  1163. return NULL;
  1164. if (!rdev->ops->get_station)
  1165. return NULL;
  1166. /* Grab BSSID of current BSS, if any */
  1167. wdev_lock(wdev);
  1168. if (wdev->valid_links || !wdev->links[0].client.current_bss) {
  1169. wdev_unlock(wdev);
  1170. return NULL;
  1171. }
  1172. memcpy(bssid, wdev->links[0].client.current_bss->pub.bssid, ETH_ALEN);
  1173. wdev_unlock(wdev);
  1174. memset(&sinfo, 0, sizeof(sinfo));
  1175. wiphy_lock(&rdev->wiphy);
  1176. ret = rdev_get_station(rdev, dev, bssid, &sinfo);
  1177. wiphy_unlock(&rdev->wiphy);
  1178. if (ret)
  1179. return NULL;
  1180. memset(&wstats, 0, sizeof(wstats));
  1181. switch (rdev->wiphy.signal_type) {
  1182. case CFG80211_SIGNAL_TYPE_MBM:
  1183. if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
  1184. int sig = sinfo.signal;
  1185. wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
  1186. wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
  1187. wstats.qual.updated |= IW_QUAL_DBM;
  1188. wstats.qual.level = sig;
  1189. if (sig < -110)
  1190. sig = -110;
  1191. else if (sig > -40)
  1192. sig = -40;
  1193. wstats.qual.qual = sig + 110;
  1194. break;
  1195. }
  1196. fallthrough;
  1197. case CFG80211_SIGNAL_TYPE_UNSPEC:
  1198. if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
  1199. wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
  1200. wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
  1201. wstats.qual.level = sinfo.signal;
  1202. wstats.qual.qual = sinfo.signal;
  1203. break;
  1204. }
  1205. fallthrough;
  1206. default:
  1207. wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
  1208. wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
  1209. }
  1210. wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
  1211. if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC))
  1212. wstats.discard.misc = sinfo.rx_dropped_misc;
  1213. if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))
  1214. wstats.discard.retries = sinfo.tx_failed;
  1215. cfg80211_sinfo_release_content(&sinfo);
  1216. return &wstats;
  1217. }
  1218. static int cfg80211_wext_siwap(struct net_device *dev,
  1219. struct iw_request_info *info,
  1220. struct sockaddr *ap_addr, char *extra)
  1221. {
  1222. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1223. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1224. int ret;
  1225. wiphy_lock(&rdev->wiphy);
  1226. switch (wdev->iftype) {
  1227. case NL80211_IFTYPE_ADHOC:
  1228. ret = cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
  1229. break;
  1230. case NL80211_IFTYPE_STATION:
  1231. ret = cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
  1232. break;
  1233. default:
  1234. ret = -EOPNOTSUPP;
  1235. break;
  1236. }
  1237. wiphy_unlock(&rdev->wiphy);
  1238. return ret;
  1239. }
  1240. static int cfg80211_wext_giwap(struct net_device *dev,
  1241. struct iw_request_info *info,
  1242. struct sockaddr *ap_addr, char *extra)
  1243. {
  1244. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1245. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1246. int ret;
  1247. wiphy_lock(&rdev->wiphy);
  1248. switch (wdev->iftype) {
  1249. case NL80211_IFTYPE_ADHOC:
  1250. ret = cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
  1251. break;
  1252. case NL80211_IFTYPE_STATION:
  1253. ret = cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
  1254. break;
  1255. default:
  1256. ret = -EOPNOTSUPP;
  1257. break;
  1258. }
  1259. wiphy_unlock(&rdev->wiphy);
  1260. return ret;
  1261. }
  1262. static int cfg80211_wext_siwessid(struct net_device *dev,
  1263. struct iw_request_info *info,
  1264. struct iw_point *data, char *ssid)
  1265. {
  1266. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1267. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1268. int ret;
  1269. wiphy_lock(&rdev->wiphy);
  1270. switch (wdev->iftype) {
  1271. case NL80211_IFTYPE_ADHOC:
  1272. ret = cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
  1273. break;
  1274. case NL80211_IFTYPE_STATION:
  1275. ret = cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
  1276. break;
  1277. default:
  1278. ret = -EOPNOTSUPP;
  1279. break;
  1280. }
  1281. wiphy_unlock(&rdev->wiphy);
  1282. return ret;
  1283. }
  1284. static int cfg80211_wext_giwessid(struct net_device *dev,
  1285. struct iw_request_info *info,
  1286. struct iw_point *data, char *ssid)
  1287. {
  1288. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1289. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1290. int ret;
  1291. data->flags = 0;
  1292. data->length = 0;
  1293. wiphy_lock(&rdev->wiphy);
  1294. switch (wdev->iftype) {
  1295. case NL80211_IFTYPE_ADHOC:
  1296. ret = cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
  1297. break;
  1298. case NL80211_IFTYPE_STATION:
  1299. ret = cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
  1300. break;
  1301. default:
  1302. ret = -EOPNOTSUPP;
  1303. break;
  1304. }
  1305. wiphy_unlock(&rdev->wiphy);
  1306. return ret;
  1307. }
  1308. static int cfg80211_wext_siwpmksa(struct net_device *dev,
  1309. struct iw_request_info *info,
  1310. struct iw_point *data, char *extra)
  1311. {
  1312. struct wireless_dev *wdev = dev->ieee80211_ptr;
  1313. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  1314. struct cfg80211_pmksa cfg_pmksa;
  1315. struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
  1316. int ret;
  1317. memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
  1318. if (wdev->iftype != NL80211_IFTYPE_STATION)
  1319. return -EINVAL;
  1320. cfg_pmksa.bssid = pmksa->bssid.sa_data;
  1321. cfg_pmksa.pmkid = pmksa->pmkid;
  1322. wiphy_lock(&rdev->wiphy);
  1323. switch (pmksa->cmd) {
  1324. case IW_PMKSA_ADD:
  1325. if (!rdev->ops->set_pmksa) {
  1326. ret = -EOPNOTSUPP;
  1327. break;
  1328. }
  1329. ret = rdev_set_pmksa(rdev, dev, &cfg_pmksa);
  1330. break;
  1331. case IW_PMKSA_REMOVE:
  1332. if (!rdev->ops->del_pmksa) {
  1333. ret = -EOPNOTSUPP;
  1334. break;
  1335. }
  1336. ret = rdev_del_pmksa(rdev, dev, &cfg_pmksa);
  1337. break;
  1338. case IW_PMKSA_FLUSH:
  1339. if (!rdev->ops->flush_pmksa) {
  1340. ret = -EOPNOTSUPP;
  1341. break;
  1342. }
  1343. ret = rdev_flush_pmksa(rdev, dev);
  1344. break;
  1345. default:
  1346. ret = -EOPNOTSUPP;
  1347. break;
  1348. }
  1349. wiphy_unlock(&rdev->wiphy);
  1350. return ret;
  1351. }
  1352. #define DEFINE_WEXT_COMPAT_STUB(func, type) \
  1353. static int __ ## func(struct net_device *dev, \
  1354. struct iw_request_info *info, \
  1355. union iwreq_data *wrqu, \
  1356. char *extra) \
  1357. { \
  1358. return func(dev, info, (type *)wrqu, extra); \
  1359. }
  1360. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwname, char)
  1361. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfreq, struct iw_freq)
  1362. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfreq, struct iw_freq)
  1363. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmode, u32)
  1364. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwmode, u32)
  1365. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrange, struct iw_point)
  1366. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwap, struct sockaddr)
  1367. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwap, struct sockaddr)
  1368. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmlme, struct iw_point)
  1369. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwscan, struct iw_point)
  1370. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwessid, struct iw_point)
  1371. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwessid, struct iw_point)
  1372. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrate, struct iw_param)
  1373. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrate, struct iw_param)
  1374. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrts, struct iw_param)
  1375. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrts, struct iw_param)
  1376. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfrag, struct iw_param)
  1377. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfrag, struct iw_param)
  1378. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwretry, struct iw_param)
  1379. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwretry, struct iw_param)
  1380. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencode, struct iw_point)
  1381. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwencode, struct iw_point)
  1382. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwpower, struct iw_param)
  1383. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpower, struct iw_param)
  1384. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwgenie, struct iw_point)
  1385. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwauth, struct iw_param)
  1386. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwauth, struct iw_param)
  1387. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencodeext, struct iw_point)
  1388. DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpmksa, struct iw_point)
  1389. static const iw_handler cfg80211_handlers[] = {
  1390. [IW_IOCTL_IDX(SIOCGIWNAME)] = __cfg80211_wext_giwname,
  1391. [IW_IOCTL_IDX(SIOCSIWFREQ)] = __cfg80211_wext_siwfreq,
  1392. [IW_IOCTL_IDX(SIOCGIWFREQ)] = __cfg80211_wext_giwfreq,
  1393. [IW_IOCTL_IDX(SIOCSIWMODE)] = __cfg80211_wext_siwmode,
  1394. [IW_IOCTL_IDX(SIOCGIWMODE)] = __cfg80211_wext_giwmode,
  1395. [IW_IOCTL_IDX(SIOCGIWRANGE)] = __cfg80211_wext_giwrange,
  1396. [IW_IOCTL_IDX(SIOCSIWAP)] = __cfg80211_wext_siwap,
  1397. [IW_IOCTL_IDX(SIOCGIWAP)] = __cfg80211_wext_giwap,
  1398. [IW_IOCTL_IDX(SIOCSIWMLME)] = __cfg80211_wext_siwmlme,
  1399. [IW_IOCTL_IDX(SIOCSIWSCAN)] = cfg80211_wext_siwscan,
  1400. [IW_IOCTL_IDX(SIOCGIWSCAN)] = __cfg80211_wext_giwscan,
  1401. [IW_IOCTL_IDX(SIOCSIWESSID)] = __cfg80211_wext_siwessid,
  1402. [IW_IOCTL_IDX(SIOCGIWESSID)] = __cfg80211_wext_giwessid,
  1403. [IW_IOCTL_IDX(SIOCSIWRATE)] = __cfg80211_wext_siwrate,
  1404. [IW_IOCTL_IDX(SIOCGIWRATE)] = __cfg80211_wext_giwrate,
  1405. [IW_IOCTL_IDX(SIOCSIWRTS)] = __cfg80211_wext_siwrts,
  1406. [IW_IOCTL_IDX(SIOCGIWRTS)] = __cfg80211_wext_giwrts,
  1407. [IW_IOCTL_IDX(SIOCSIWFRAG)] = __cfg80211_wext_siwfrag,
  1408. [IW_IOCTL_IDX(SIOCGIWFRAG)] = __cfg80211_wext_giwfrag,
  1409. [IW_IOCTL_IDX(SIOCSIWTXPOW)] = cfg80211_wext_siwtxpower,
  1410. [IW_IOCTL_IDX(SIOCGIWTXPOW)] = cfg80211_wext_giwtxpower,
  1411. [IW_IOCTL_IDX(SIOCSIWRETRY)] = __cfg80211_wext_siwretry,
  1412. [IW_IOCTL_IDX(SIOCGIWRETRY)] = __cfg80211_wext_giwretry,
  1413. [IW_IOCTL_IDX(SIOCSIWENCODE)] = __cfg80211_wext_siwencode,
  1414. [IW_IOCTL_IDX(SIOCGIWENCODE)] = __cfg80211_wext_giwencode,
  1415. [IW_IOCTL_IDX(SIOCSIWPOWER)] = __cfg80211_wext_siwpower,
  1416. [IW_IOCTL_IDX(SIOCGIWPOWER)] = __cfg80211_wext_giwpower,
  1417. [IW_IOCTL_IDX(SIOCSIWGENIE)] = __cfg80211_wext_siwgenie,
  1418. [IW_IOCTL_IDX(SIOCSIWAUTH)] = __cfg80211_wext_siwauth,
  1419. [IW_IOCTL_IDX(SIOCGIWAUTH)] = __cfg80211_wext_giwauth,
  1420. [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= __cfg80211_wext_siwencodeext,
  1421. [IW_IOCTL_IDX(SIOCSIWPMKSA)] = __cfg80211_wext_siwpmksa,
  1422. };
  1423. const struct iw_handler_def cfg80211_wext_handler = {
  1424. .num_standard = ARRAY_SIZE(cfg80211_handlers),
  1425. .standard = cfg80211_handlers,
  1426. .get_wireless_stats = cfg80211_wireless_stats,
  1427. };