cfg.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. /*
  2. * mac80211 configuration hooks for cfg80211
  3. *
  4. * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * This file is GPLv2 as found in COPYING.
  7. */
  8. #include <linux/ieee80211.h>
  9. #include <linux/nl80211.h>
  10. #include <linux/rtnetlink.h>
  11. #include <net/net_namespace.h>
  12. #include <linux/rcupdate.h>
  13. #include <net/cfg80211.h>
  14. #include "ieee80211_i.h"
  15. #include "cfg.h"
  16. #include "rate.h"
  17. #include "mesh.h"
  18. static bool nl80211_type_check(enum nl80211_iftype type)
  19. {
  20. switch (type) {
  21. case NL80211_IFTYPE_ADHOC:
  22. case NL80211_IFTYPE_STATION:
  23. case NL80211_IFTYPE_MONITOR:
  24. #ifdef CONFIG_MAC80211_MESH
  25. case NL80211_IFTYPE_MESH_POINT:
  26. #endif
  27. case NL80211_IFTYPE_AP:
  28. case NL80211_IFTYPE_AP_VLAN:
  29. case NL80211_IFTYPE_WDS:
  30. return true;
  31. default:
  32. return false;
  33. }
  34. }
  35. static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
  36. enum nl80211_iftype type, u32 *flags,
  37. struct vif_params *params)
  38. {
  39. struct ieee80211_local *local = wiphy_priv(wiphy);
  40. struct net_device *dev;
  41. struct ieee80211_sub_if_data *sdata;
  42. int err;
  43. if (!nl80211_type_check(type))
  44. return -EINVAL;
  45. err = ieee80211_if_add(local, name, &dev, type, params);
  46. if (err || type != NL80211_IFTYPE_MONITOR || !flags)
  47. return err;
  48. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  49. sdata->u.mntr_flags = *flags;
  50. return 0;
  51. }
  52. static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
  53. {
  54. struct net_device *dev;
  55. struct ieee80211_sub_if_data *sdata;
  56. /* we're under RTNL */
  57. dev = __dev_get_by_index(&init_net, ifindex);
  58. if (!dev)
  59. return -ENODEV;
  60. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  61. ieee80211_if_remove(sdata);
  62. return 0;
  63. }
  64. static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
  65. enum nl80211_iftype type, u32 *flags,
  66. struct vif_params *params)
  67. {
  68. struct net_device *dev;
  69. struct ieee80211_sub_if_data *sdata;
  70. int ret;
  71. /* we're under RTNL */
  72. dev = __dev_get_by_index(&init_net, ifindex);
  73. if (!dev)
  74. return -ENODEV;
  75. if (!nl80211_type_check(type))
  76. return -EINVAL;
  77. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  78. ret = ieee80211_if_change_type(sdata, type);
  79. if (ret)
  80. return ret;
  81. if (netif_running(sdata->dev))
  82. return -EBUSY;
  83. if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
  84. ieee80211_sdata_set_mesh_id(sdata,
  85. params->mesh_id_len,
  86. params->mesh_id);
  87. if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
  88. return 0;
  89. sdata->u.mntr_flags = *flags;
  90. return 0;
  91. }
  92. static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
  93. u8 key_idx, u8 *mac_addr,
  94. struct key_params *params)
  95. {
  96. struct ieee80211_sub_if_data *sdata;
  97. struct sta_info *sta = NULL;
  98. enum ieee80211_key_alg alg;
  99. struct ieee80211_key *key;
  100. int err;
  101. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  102. switch (params->cipher) {
  103. case WLAN_CIPHER_SUITE_WEP40:
  104. case WLAN_CIPHER_SUITE_WEP104:
  105. alg = ALG_WEP;
  106. break;
  107. case WLAN_CIPHER_SUITE_TKIP:
  108. alg = ALG_TKIP;
  109. break;
  110. case WLAN_CIPHER_SUITE_CCMP:
  111. alg = ALG_CCMP;
  112. break;
  113. case WLAN_CIPHER_SUITE_AES_CMAC:
  114. alg = ALG_AES_CMAC;
  115. break;
  116. default:
  117. return -EINVAL;
  118. }
  119. key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
  120. if (!key)
  121. return -ENOMEM;
  122. rcu_read_lock();
  123. if (mac_addr) {
  124. sta = sta_info_get(sdata->local, mac_addr);
  125. if (!sta) {
  126. ieee80211_key_free(key);
  127. err = -ENOENT;
  128. goto out_unlock;
  129. }
  130. }
  131. ieee80211_key_link(key, sdata, sta);
  132. err = 0;
  133. out_unlock:
  134. rcu_read_unlock();
  135. return err;
  136. }
  137. static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
  138. u8 key_idx, u8 *mac_addr)
  139. {
  140. struct ieee80211_sub_if_data *sdata;
  141. struct sta_info *sta;
  142. int ret;
  143. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  144. rcu_read_lock();
  145. if (mac_addr) {
  146. ret = -ENOENT;
  147. sta = sta_info_get(sdata->local, mac_addr);
  148. if (!sta)
  149. goto out_unlock;
  150. if (sta->key) {
  151. ieee80211_key_free(sta->key);
  152. WARN_ON(sta->key);
  153. ret = 0;
  154. }
  155. goto out_unlock;
  156. }
  157. if (!sdata->keys[key_idx]) {
  158. ret = -ENOENT;
  159. goto out_unlock;
  160. }
  161. ieee80211_key_free(sdata->keys[key_idx]);
  162. WARN_ON(sdata->keys[key_idx]);
  163. ret = 0;
  164. out_unlock:
  165. rcu_read_unlock();
  166. return ret;
  167. }
  168. static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
  169. u8 key_idx, u8 *mac_addr, void *cookie,
  170. void (*callback)(void *cookie,
  171. struct key_params *params))
  172. {
  173. struct ieee80211_sub_if_data *sdata;
  174. struct sta_info *sta = NULL;
  175. u8 seq[6] = {0};
  176. struct key_params params;
  177. struct ieee80211_key *key;
  178. u32 iv32;
  179. u16 iv16;
  180. int err = -ENOENT;
  181. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  182. rcu_read_lock();
  183. if (mac_addr) {
  184. sta = sta_info_get(sdata->local, mac_addr);
  185. if (!sta)
  186. goto out;
  187. key = sta->key;
  188. } else
  189. key = sdata->keys[key_idx];
  190. if (!key)
  191. goto out;
  192. memset(&params, 0, sizeof(params));
  193. switch (key->conf.alg) {
  194. case ALG_TKIP:
  195. params.cipher = WLAN_CIPHER_SUITE_TKIP;
  196. iv32 = key->u.tkip.tx.iv32;
  197. iv16 = key->u.tkip.tx.iv16;
  198. if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
  199. sdata->local->ops->get_tkip_seq)
  200. sdata->local->ops->get_tkip_seq(
  201. local_to_hw(sdata->local),
  202. key->conf.hw_key_idx,
  203. &iv32, &iv16);
  204. seq[0] = iv16 & 0xff;
  205. seq[1] = (iv16 >> 8) & 0xff;
  206. seq[2] = iv32 & 0xff;
  207. seq[3] = (iv32 >> 8) & 0xff;
  208. seq[4] = (iv32 >> 16) & 0xff;
  209. seq[5] = (iv32 >> 24) & 0xff;
  210. params.seq = seq;
  211. params.seq_len = 6;
  212. break;
  213. case ALG_CCMP:
  214. params.cipher = WLAN_CIPHER_SUITE_CCMP;
  215. seq[0] = key->u.ccmp.tx_pn[5];
  216. seq[1] = key->u.ccmp.tx_pn[4];
  217. seq[2] = key->u.ccmp.tx_pn[3];
  218. seq[3] = key->u.ccmp.tx_pn[2];
  219. seq[4] = key->u.ccmp.tx_pn[1];
  220. seq[5] = key->u.ccmp.tx_pn[0];
  221. params.seq = seq;
  222. params.seq_len = 6;
  223. break;
  224. case ALG_WEP:
  225. if (key->conf.keylen == 5)
  226. params.cipher = WLAN_CIPHER_SUITE_WEP40;
  227. else
  228. params.cipher = WLAN_CIPHER_SUITE_WEP104;
  229. break;
  230. case ALG_AES_CMAC:
  231. params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
  232. seq[0] = key->u.aes_cmac.tx_pn[5];
  233. seq[1] = key->u.aes_cmac.tx_pn[4];
  234. seq[2] = key->u.aes_cmac.tx_pn[3];
  235. seq[3] = key->u.aes_cmac.tx_pn[2];
  236. seq[4] = key->u.aes_cmac.tx_pn[1];
  237. seq[5] = key->u.aes_cmac.tx_pn[0];
  238. params.seq = seq;
  239. params.seq_len = 6;
  240. break;
  241. }
  242. params.key = key->conf.key;
  243. params.key_len = key->conf.keylen;
  244. callback(cookie, &params);
  245. err = 0;
  246. out:
  247. rcu_read_unlock();
  248. return err;
  249. }
  250. static int ieee80211_config_default_key(struct wiphy *wiphy,
  251. struct net_device *dev,
  252. u8 key_idx)
  253. {
  254. struct ieee80211_sub_if_data *sdata;
  255. rcu_read_lock();
  256. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  257. ieee80211_set_default_key(sdata, key_idx);
  258. rcu_read_unlock();
  259. return 0;
  260. }
  261. static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
  262. struct net_device *dev,
  263. u8 key_idx)
  264. {
  265. struct ieee80211_sub_if_data *sdata;
  266. rcu_read_lock();
  267. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  268. ieee80211_set_default_mgmt_key(sdata, key_idx);
  269. rcu_read_unlock();
  270. return 0;
  271. }
  272. static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
  273. {
  274. struct ieee80211_sub_if_data *sdata = sta->sdata;
  275. sinfo->filled = STATION_INFO_INACTIVE_TIME |
  276. STATION_INFO_RX_BYTES |
  277. STATION_INFO_TX_BYTES |
  278. STATION_INFO_TX_BITRATE;
  279. sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
  280. sinfo->rx_bytes = sta->rx_bytes;
  281. sinfo->tx_bytes = sta->tx_bytes;
  282. if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
  283. sinfo->filled |= STATION_INFO_SIGNAL;
  284. sinfo->signal = (s8)sta->last_signal;
  285. }
  286. sinfo->txrate.flags = 0;
  287. if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
  288. sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
  289. if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
  290. sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
  291. if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
  292. sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
  293. if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
  294. struct ieee80211_supported_band *sband;
  295. sband = sta->local->hw.wiphy->bands[
  296. sta->local->hw.conf.channel->band];
  297. sinfo->txrate.legacy =
  298. sband->bitrates[sta->last_tx_rate.idx].bitrate;
  299. } else
  300. sinfo->txrate.mcs = sta->last_tx_rate.idx;
  301. if (ieee80211_vif_is_mesh(&sdata->vif)) {
  302. #ifdef CONFIG_MAC80211_MESH
  303. sinfo->filled |= STATION_INFO_LLID |
  304. STATION_INFO_PLID |
  305. STATION_INFO_PLINK_STATE;
  306. sinfo->llid = le16_to_cpu(sta->llid);
  307. sinfo->plid = le16_to_cpu(sta->plid);
  308. sinfo->plink_state = sta->plink_state;
  309. #endif
  310. }
  311. }
  312. static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
  313. int idx, u8 *mac, struct station_info *sinfo)
  314. {
  315. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  316. struct sta_info *sta;
  317. int ret = -ENOENT;
  318. rcu_read_lock();
  319. sta = sta_info_get_by_idx(local, idx, dev);
  320. if (sta) {
  321. ret = 0;
  322. memcpy(mac, sta->sta.addr, ETH_ALEN);
  323. sta_set_sinfo(sta, sinfo);
  324. }
  325. rcu_read_unlock();
  326. return ret;
  327. }
  328. static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  329. u8 *mac, struct station_info *sinfo)
  330. {
  331. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  332. struct sta_info *sta;
  333. int ret = -ENOENT;
  334. rcu_read_lock();
  335. /* XXX: verify sta->dev == dev */
  336. sta = sta_info_get(local, mac);
  337. if (sta) {
  338. ret = 0;
  339. sta_set_sinfo(sta, sinfo);
  340. }
  341. rcu_read_unlock();
  342. return ret;
  343. }
  344. /*
  345. * This handles both adding a beacon and setting new beacon info
  346. */
  347. static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
  348. struct beacon_parameters *params)
  349. {
  350. struct beacon_data *new, *old;
  351. int new_head_len, new_tail_len;
  352. int size;
  353. int err = -EINVAL;
  354. old = sdata->u.ap.beacon;
  355. /* head must not be zero-length */
  356. if (params->head && !params->head_len)
  357. return -EINVAL;
  358. /*
  359. * This is a kludge. beacon interval should really be part
  360. * of the beacon information.
  361. */
  362. if (params->interval) {
  363. sdata->local->hw.conf.beacon_int = params->interval;
  364. err = ieee80211_hw_config(sdata->local,
  365. IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
  366. if (err < 0)
  367. return err;
  368. /*
  369. * We updated some parameter so if below bails out
  370. * it's not an error.
  371. */
  372. err = 0;
  373. }
  374. /* Need to have a beacon head if we don't have one yet */
  375. if (!params->head && !old)
  376. return err;
  377. /* sorry, no way to start beaconing without dtim period */
  378. if (!params->dtim_period && !old)
  379. return err;
  380. /* new or old head? */
  381. if (params->head)
  382. new_head_len = params->head_len;
  383. else
  384. new_head_len = old->head_len;
  385. /* new or old tail? */
  386. if (params->tail || !old)
  387. /* params->tail_len will be zero for !params->tail */
  388. new_tail_len = params->tail_len;
  389. else
  390. new_tail_len = old->tail_len;
  391. size = sizeof(*new) + new_head_len + new_tail_len;
  392. new = kzalloc(size, GFP_KERNEL);
  393. if (!new)
  394. return -ENOMEM;
  395. /* start filling the new info now */
  396. /* new or old dtim period? */
  397. if (params->dtim_period)
  398. new->dtim_period = params->dtim_period;
  399. else
  400. new->dtim_period = old->dtim_period;
  401. /*
  402. * pointers go into the block we allocated,
  403. * memory is | beacon_data | head | tail |
  404. */
  405. new->head = ((u8 *) new) + sizeof(*new);
  406. new->tail = new->head + new_head_len;
  407. new->head_len = new_head_len;
  408. new->tail_len = new_tail_len;
  409. /* copy in head */
  410. if (params->head)
  411. memcpy(new->head, params->head, new_head_len);
  412. else
  413. memcpy(new->head, old->head, new_head_len);
  414. /* copy in optional tail */
  415. if (params->tail)
  416. memcpy(new->tail, params->tail, new_tail_len);
  417. else
  418. if (old)
  419. memcpy(new->tail, old->tail, new_tail_len);
  420. rcu_assign_pointer(sdata->u.ap.beacon, new);
  421. synchronize_rcu();
  422. kfree(old);
  423. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  424. }
  425. static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
  426. struct beacon_parameters *params)
  427. {
  428. struct ieee80211_sub_if_data *sdata;
  429. struct beacon_data *old;
  430. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  431. if (sdata->vif.type != NL80211_IFTYPE_AP)
  432. return -EINVAL;
  433. old = sdata->u.ap.beacon;
  434. if (old)
  435. return -EALREADY;
  436. return ieee80211_config_beacon(sdata, params);
  437. }
  438. static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
  439. struct beacon_parameters *params)
  440. {
  441. struct ieee80211_sub_if_data *sdata;
  442. struct beacon_data *old;
  443. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  444. if (sdata->vif.type != NL80211_IFTYPE_AP)
  445. return -EINVAL;
  446. old = sdata->u.ap.beacon;
  447. if (!old)
  448. return -ENOENT;
  449. return ieee80211_config_beacon(sdata, params);
  450. }
  451. static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
  452. {
  453. struct ieee80211_sub_if_data *sdata;
  454. struct beacon_data *old;
  455. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  456. if (sdata->vif.type != NL80211_IFTYPE_AP)
  457. return -EINVAL;
  458. old = sdata->u.ap.beacon;
  459. if (!old)
  460. return -ENOENT;
  461. rcu_assign_pointer(sdata->u.ap.beacon, NULL);
  462. synchronize_rcu();
  463. kfree(old);
  464. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  465. }
  466. /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
  467. struct iapp_layer2_update {
  468. u8 da[ETH_ALEN]; /* broadcast */
  469. u8 sa[ETH_ALEN]; /* STA addr */
  470. __be16 len; /* 6 */
  471. u8 dsap; /* 0 */
  472. u8 ssap; /* 0 */
  473. u8 control;
  474. u8 xid_info[3];
  475. } __attribute__ ((packed));
  476. static void ieee80211_send_layer2_update(struct sta_info *sta)
  477. {
  478. struct iapp_layer2_update *msg;
  479. struct sk_buff *skb;
  480. /* Send Level 2 Update Frame to update forwarding tables in layer 2
  481. * bridge devices */
  482. skb = dev_alloc_skb(sizeof(*msg));
  483. if (!skb)
  484. return;
  485. msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
  486. /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
  487. * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
  488. memset(msg->da, 0xff, ETH_ALEN);
  489. memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
  490. msg->len = htons(6);
  491. msg->dsap = 0;
  492. msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
  493. msg->control = 0xaf; /* XID response lsb.1111F101.
  494. * F=0 (no poll command; unsolicited frame) */
  495. msg->xid_info[0] = 0x81; /* XID format identifier */
  496. msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
  497. msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
  498. skb->dev = sta->sdata->dev;
  499. skb->protocol = eth_type_trans(skb, sta->sdata->dev);
  500. memset(skb->cb, 0, sizeof(skb->cb));
  501. netif_rx(skb);
  502. }
  503. static void sta_apply_parameters(struct ieee80211_local *local,
  504. struct sta_info *sta,
  505. struct station_parameters *params)
  506. {
  507. u32 rates;
  508. int i, j;
  509. struct ieee80211_supported_band *sband;
  510. struct ieee80211_sub_if_data *sdata = sta->sdata;
  511. sband = local->hw.wiphy->bands[local->oper_channel->band];
  512. /*
  513. * FIXME: updating the flags is racy when this function is
  514. * called from ieee80211_change_station(), this will
  515. * be resolved in a future patch.
  516. */
  517. if (params->station_flags & STATION_FLAG_CHANGED) {
  518. spin_lock_bh(&sta->lock);
  519. sta->flags &= ~WLAN_STA_AUTHORIZED;
  520. if (params->station_flags & STATION_FLAG_AUTHORIZED)
  521. sta->flags |= WLAN_STA_AUTHORIZED;
  522. sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  523. if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
  524. sta->flags |= WLAN_STA_SHORT_PREAMBLE;
  525. sta->flags &= ~WLAN_STA_WME;
  526. if (params->station_flags & STATION_FLAG_WME)
  527. sta->flags |= WLAN_STA_WME;
  528. sta->flags &= ~WLAN_STA_MFP;
  529. if (params->station_flags & STATION_FLAG_MFP)
  530. sta->flags |= WLAN_STA_MFP;
  531. spin_unlock_bh(&sta->lock);
  532. }
  533. /*
  534. * FIXME: updating the following information is racy when this
  535. * function is called from ieee80211_change_station().
  536. * However, all this information should be static so
  537. * maybe we should just reject attemps to change it.
  538. */
  539. if (params->aid) {
  540. sta->sta.aid = params->aid;
  541. if (sta->sta.aid > IEEE80211_MAX_AID)
  542. sta->sta.aid = 0; /* XXX: should this be an error? */
  543. }
  544. if (params->listen_interval >= 0)
  545. sta->listen_interval = params->listen_interval;
  546. if (params->supported_rates) {
  547. rates = 0;
  548. for (i = 0; i < params->supported_rates_len; i++) {
  549. int rate = (params->supported_rates[i] & 0x7f) * 5;
  550. for (j = 0; j < sband->n_bitrates; j++) {
  551. if (sband->bitrates[j].bitrate == rate)
  552. rates |= BIT(j);
  553. }
  554. }
  555. sta->sta.supp_rates[local->oper_channel->band] = rates;
  556. }
  557. if (params->ht_capa)
  558. ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
  559. params->ht_capa,
  560. &sta->sta.ht_cap);
  561. if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
  562. switch (params->plink_action) {
  563. case PLINK_ACTION_OPEN:
  564. mesh_plink_open(sta);
  565. break;
  566. case PLINK_ACTION_BLOCK:
  567. mesh_plink_block(sta);
  568. break;
  569. }
  570. }
  571. }
  572. static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
  573. u8 *mac, struct station_parameters *params)
  574. {
  575. struct ieee80211_local *local = wiphy_priv(wiphy);
  576. struct sta_info *sta;
  577. struct ieee80211_sub_if_data *sdata;
  578. int err;
  579. int layer2_update;
  580. /* Prevent a race with changing the rate control algorithm */
  581. if (!netif_running(dev))
  582. return -ENETDOWN;
  583. if (params->vlan) {
  584. sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  585. if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  586. sdata->vif.type != NL80211_IFTYPE_AP)
  587. return -EINVAL;
  588. } else
  589. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  590. if (compare_ether_addr(mac, dev->dev_addr) == 0)
  591. return -EINVAL;
  592. if (is_multicast_ether_addr(mac))
  593. return -EINVAL;
  594. sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
  595. if (!sta)
  596. return -ENOMEM;
  597. sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
  598. sta_apply_parameters(local, sta, params);
  599. rate_control_rate_init(sta);
  600. layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
  601. sdata->vif.type == NL80211_IFTYPE_AP;
  602. rcu_read_lock();
  603. err = sta_info_insert(sta);
  604. if (err) {
  605. /* STA has been freed */
  606. if (err == -EEXIST && layer2_update) {
  607. /* Need to update layer 2 devices on reassociation */
  608. sta = sta_info_get(local, mac);
  609. if (sta)
  610. ieee80211_send_layer2_update(sta);
  611. }
  612. rcu_read_unlock();
  613. return err;
  614. }
  615. if (layer2_update)
  616. ieee80211_send_layer2_update(sta);
  617. rcu_read_unlock();
  618. return 0;
  619. }
  620. static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
  621. u8 *mac)
  622. {
  623. struct ieee80211_local *local = wiphy_priv(wiphy);
  624. struct ieee80211_sub_if_data *sdata;
  625. struct sta_info *sta;
  626. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  627. if (mac) {
  628. rcu_read_lock();
  629. /* XXX: get sta belonging to dev */
  630. sta = sta_info_get(local, mac);
  631. if (!sta) {
  632. rcu_read_unlock();
  633. return -ENOENT;
  634. }
  635. sta_info_unlink(&sta);
  636. rcu_read_unlock();
  637. sta_info_destroy(sta);
  638. } else
  639. sta_info_flush(local, sdata);
  640. return 0;
  641. }
  642. static int ieee80211_change_station(struct wiphy *wiphy,
  643. struct net_device *dev,
  644. u8 *mac,
  645. struct station_parameters *params)
  646. {
  647. struct ieee80211_local *local = wiphy_priv(wiphy);
  648. struct sta_info *sta;
  649. struct ieee80211_sub_if_data *vlansdata;
  650. rcu_read_lock();
  651. /* XXX: get sta belonging to dev */
  652. sta = sta_info_get(local, mac);
  653. if (!sta) {
  654. rcu_read_unlock();
  655. return -ENOENT;
  656. }
  657. if (params->vlan && params->vlan != sta->sdata->dev) {
  658. vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  659. if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  660. vlansdata->vif.type != NL80211_IFTYPE_AP) {
  661. rcu_read_unlock();
  662. return -EINVAL;
  663. }
  664. sta->sdata = vlansdata;
  665. ieee80211_send_layer2_update(sta);
  666. }
  667. sta_apply_parameters(local, sta, params);
  668. rcu_read_unlock();
  669. return 0;
  670. }
  671. #ifdef CONFIG_MAC80211_MESH
  672. static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
  673. u8 *dst, u8 *next_hop)
  674. {
  675. struct ieee80211_local *local = wiphy_priv(wiphy);
  676. struct ieee80211_sub_if_data *sdata;
  677. struct mesh_path *mpath;
  678. struct sta_info *sta;
  679. int err;
  680. if (!netif_running(dev))
  681. return -ENETDOWN;
  682. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  683. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  684. return -ENOTSUPP;
  685. rcu_read_lock();
  686. sta = sta_info_get(local, next_hop);
  687. if (!sta) {
  688. rcu_read_unlock();
  689. return -ENOENT;
  690. }
  691. err = mesh_path_add(dst, sdata);
  692. if (err) {
  693. rcu_read_unlock();
  694. return err;
  695. }
  696. mpath = mesh_path_lookup(dst, sdata);
  697. if (!mpath) {
  698. rcu_read_unlock();
  699. return -ENXIO;
  700. }
  701. mesh_path_fix_nexthop(mpath, sta);
  702. rcu_read_unlock();
  703. return 0;
  704. }
  705. static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
  706. u8 *dst)
  707. {
  708. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  709. if (dst)
  710. return mesh_path_del(dst, sdata);
  711. mesh_path_flush(sdata);
  712. return 0;
  713. }
  714. static int ieee80211_change_mpath(struct wiphy *wiphy,
  715. struct net_device *dev,
  716. u8 *dst, u8 *next_hop)
  717. {
  718. struct ieee80211_local *local = wiphy_priv(wiphy);
  719. struct ieee80211_sub_if_data *sdata;
  720. struct mesh_path *mpath;
  721. struct sta_info *sta;
  722. if (!netif_running(dev))
  723. return -ENETDOWN;
  724. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  725. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  726. return -ENOTSUPP;
  727. rcu_read_lock();
  728. sta = sta_info_get(local, next_hop);
  729. if (!sta) {
  730. rcu_read_unlock();
  731. return -ENOENT;
  732. }
  733. mpath = mesh_path_lookup(dst, sdata);
  734. if (!mpath) {
  735. rcu_read_unlock();
  736. return -ENOENT;
  737. }
  738. mesh_path_fix_nexthop(mpath, sta);
  739. rcu_read_unlock();
  740. return 0;
  741. }
  742. static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
  743. struct mpath_info *pinfo)
  744. {
  745. if (mpath->next_hop)
  746. memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
  747. else
  748. memset(next_hop, 0, ETH_ALEN);
  749. pinfo->filled = MPATH_INFO_FRAME_QLEN |
  750. MPATH_INFO_DSN |
  751. MPATH_INFO_METRIC |
  752. MPATH_INFO_EXPTIME |
  753. MPATH_INFO_DISCOVERY_TIMEOUT |
  754. MPATH_INFO_DISCOVERY_RETRIES |
  755. MPATH_INFO_FLAGS;
  756. pinfo->frame_qlen = mpath->frame_queue.qlen;
  757. pinfo->dsn = mpath->dsn;
  758. pinfo->metric = mpath->metric;
  759. if (time_before(jiffies, mpath->exp_time))
  760. pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
  761. pinfo->discovery_timeout =
  762. jiffies_to_msecs(mpath->discovery_timeout);
  763. pinfo->discovery_retries = mpath->discovery_retries;
  764. pinfo->flags = 0;
  765. if (mpath->flags & MESH_PATH_ACTIVE)
  766. pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
  767. if (mpath->flags & MESH_PATH_RESOLVING)
  768. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  769. if (mpath->flags & MESH_PATH_DSN_VALID)
  770. pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID;
  771. if (mpath->flags & MESH_PATH_FIXED)
  772. pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
  773. if (mpath->flags & MESH_PATH_RESOLVING)
  774. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  775. pinfo->flags = mpath->flags;
  776. }
  777. static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
  778. u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
  779. {
  780. struct ieee80211_sub_if_data *sdata;
  781. struct mesh_path *mpath;
  782. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  783. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  784. return -ENOTSUPP;
  785. rcu_read_lock();
  786. mpath = mesh_path_lookup(dst, sdata);
  787. if (!mpath) {
  788. rcu_read_unlock();
  789. return -ENOENT;
  790. }
  791. memcpy(dst, mpath->dst, ETH_ALEN);
  792. mpath_set_pinfo(mpath, next_hop, pinfo);
  793. rcu_read_unlock();
  794. return 0;
  795. }
  796. static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
  797. int idx, u8 *dst, u8 *next_hop,
  798. struct mpath_info *pinfo)
  799. {
  800. struct ieee80211_sub_if_data *sdata;
  801. struct mesh_path *mpath;
  802. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  803. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  804. return -ENOTSUPP;
  805. rcu_read_lock();
  806. mpath = mesh_path_lookup_by_idx(idx, sdata);
  807. if (!mpath) {
  808. rcu_read_unlock();
  809. return -ENOENT;
  810. }
  811. memcpy(dst, mpath->dst, ETH_ALEN);
  812. mpath_set_pinfo(mpath, next_hop, pinfo);
  813. rcu_read_unlock();
  814. return 0;
  815. }
  816. static int ieee80211_get_mesh_params(struct wiphy *wiphy,
  817. struct net_device *dev,
  818. struct mesh_config *conf)
  819. {
  820. struct ieee80211_sub_if_data *sdata;
  821. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  822. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  823. return -ENOTSUPP;
  824. memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
  825. return 0;
  826. }
  827. static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
  828. {
  829. return (mask >> (parm-1)) & 0x1;
  830. }
  831. static int ieee80211_set_mesh_params(struct wiphy *wiphy,
  832. struct net_device *dev,
  833. const struct mesh_config *nconf, u32 mask)
  834. {
  835. struct mesh_config *conf;
  836. struct ieee80211_sub_if_data *sdata;
  837. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  838. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  839. return -ENOTSUPP;
  840. /* Set the config options which we are interested in setting */
  841. conf = &(sdata->u.mesh.mshcfg);
  842. if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
  843. conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
  844. if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
  845. conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
  846. if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
  847. conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
  848. if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
  849. conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
  850. if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
  851. conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
  852. if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
  853. conf->dot11MeshTTL = nconf->dot11MeshTTL;
  854. if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
  855. conf->auto_open_plinks = nconf->auto_open_plinks;
  856. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
  857. conf->dot11MeshHWMPmaxPREQretries =
  858. nconf->dot11MeshHWMPmaxPREQretries;
  859. if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
  860. conf->path_refresh_time = nconf->path_refresh_time;
  861. if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
  862. conf->min_discovery_timeout = nconf->min_discovery_timeout;
  863. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
  864. conf->dot11MeshHWMPactivePathTimeout =
  865. nconf->dot11MeshHWMPactivePathTimeout;
  866. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
  867. conf->dot11MeshHWMPpreqMinInterval =
  868. nconf->dot11MeshHWMPpreqMinInterval;
  869. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
  870. mask))
  871. conf->dot11MeshHWMPnetDiameterTraversalTime =
  872. nconf->dot11MeshHWMPnetDiameterTraversalTime;
  873. return 0;
  874. }
  875. #endif
  876. static int ieee80211_change_bss(struct wiphy *wiphy,
  877. struct net_device *dev,
  878. struct bss_parameters *params)
  879. {
  880. struct ieee80211_sub_if_data *sdata;
  881. u32 changed = 0;
  882. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  883. if (sdata->vif.type != NL80211_IFTYPE_AP)
  884. return -EINVAL;
  885. if (params->use_cts_prot >= 0) {
  886. sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
  887. changed |= BSS_CHANGED_ERP_CTS_PROT;
  888. }
  889. if (params->use_short_preamble >= 0) {
  890. sdata->vif.bss_conf.use_short_preamble =
  891. params->use_short_preamble;
  892. changed |= BSS_CHANGED_ERP_PREAMBLE;
  893. }
  894. if (params->use_short_slot_time >= 0) {
  895. sdata->vif.bss_conf.use_short_slot =
  896. params->use_short_slot_time;
  897. changed |= BSS_CHANGED_ERP_SLOT;
  898. }
  899. if (params->basic_rates) {
  900. int i, j;
  901. u32 rates = 0;
  902. struct ieee80211_local *local = wiphy_priv(wiphy);
  903. struct ieee80211_supported_band *sband =
  904. wiphy->bands[local->oper_channel->band];
  905. for (i = 0; i < params->basic_rates_len; i++) {
  906. int rate = (params->basic_rates[i] & 0x7f) * 5;
  907. for (j = 0; j < sband->n_bitrates; j++) {
  908. if (sband->bitrates[j].bitrate == rate)
  909. rates |= BIT(j);
  910. }
  911. }
  912. sdata->vif.bss_conf.basic_rates = rates;
  913. changed |= BSS_CHANGED_BASIC_RATES;
  914. }
  915. ieee80211_bss_info_change_notify(sdata, changed);
  916. return 0;
  917. }
  918. static int ieee80211_set_txq_params(struct wiphy *wiphy,
  919. struct ieee80211_txq_params *params)
  920. {
  921. struct ieee80211_local *local = wiphy_priv(wiphy);
  922. struct ieee80211_tx_queue_params p;
  923. if (!local->ops->conf_tx)
  924. return -EOPNOTSUPP;
  925. memset(&p, 0, sizeof(p));
  926. p.aifs = params->aifs;
  927. p.cw_max = params->cwmax;
  928. p.cw_min = params->cwmin;
  929. p.txop = params->txop;
  930. if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
  931. printk(KERN_DEBUG "%s: failed to set TX queue "
  932. "parameters for queue %d\n", local->mdev->name,
  933. params->queue);
  934. return -EINVAL;
  935. }
  936. return 0;
  937. }
  938. static int ieee80211_set_channel(struct wiphy *wiphy,
  939. struct ieee80211_channel *chan,
  940. enum nl80211_channel_type channel_type)
  941. {
  942. struct ieee80211_local *local = wiphy_priv(wiphy);
  943. local->oper_channel = chan;
  944. local->oper_channel_type = channel_type;
  945. return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
  946. }
  947. static int set_mgmt_extra_ie_sta(struct ieee80211_if_sta *ifsta, u8 subtype,
  948. u8 *ies, size_t ies_len)
  949. {
  950. switch (subtype) {
  951. case IEEE80211_STYPE_PROBE_REQ >> 4:
  952. kfree(ifsta->ie_probereq);
  953. ifsta->ie_probereq = ies;
  954. ifsta->ie_probereq_len = ies_len;
  955. return 0;
  956. case IEEE80211_STYPE_PROBE_RESP >> 4:
  957. kfree(ifsta->ie_proberesp);
  958. ifsta->ie_proberesp = ies;
  959. ifsta->ie_proberesp_len = ies_len;
  960. return 0;
  961. case IEEE80211_STYPE_AUTH >> 4:
  962. kfree(ifsta->ie_auth);
  963. ifsta->ie_auth = ies;
  964. ifsta->ie_auth_len = ies_len;
  965. return 0;
  966. case IEEE80211_STYPE_ASSOC_REQ >> 4:
  967. kfree(ifsta->ie_assocreq);
  968. ifsta->ie_assocreq = ies;
  969. ifsta->ie_assocreq_len = ies_len;
  970. return 0;
  971. case IEEE80211_STYPE_REASSOC_REQ >> 4:
  972. kfree(ifsta->ie_reassocreq);
  973. ifsta->ie_reassocreq = ies;
  974. ifsta->ie_reassocreq_len = ies_len;
  975. return 0;
  976. case IEEE80211_STYPE_DEAUTH >> 4:
  977. kfree(ifsta->ie_deauth);
  978. ifsta->ie_deauth = ies;
  979. ifsta->ie_deauth_len = ies_len;
  980. return 0;
  981. case IEEE80211_STYPE_DISASSOC >> 4:
  982. kfree(ifsta->ie_disassoc);
  983. ifsta->ie_disassoc = ies;
  984. ifsta->ie_disassoc_len = ies_len;
  985. return 0;
  986. }
  987. return -EOPNOTSUPP;
  988. }
  989. static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy,
  990. struct net_device *dev,
  991. struct mgmt_extra_ie_params *params)
  992. {
  993. struct ieee80211_sub_if_data *sdata;
  994. u8 *ies;
  995. size_t ies_len;
  996. int ret = -EOPNOTSUPP;
  997. if (params->ies) {
  998. ies = kmemdup(params->ies, params->ies_len, GFP_KERNEL);
  999. if (ies == NULL)
  1000. return -ENOMEM;
  1001. ies_len = params->ies_len;
  1002. } else {
  1003. ies = NULL;
  1004. ies_len = 0;
  1005. }
  1006. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  1007. switch (sdata->vif.type) {
  1008. case NL80211_IFTYPE_STATION:
  1009. case NL80211_IFTYPE_ADHOC:
  1010. ret = set_mgmt_extra_ie_sta(&sdata->u.sta, params->subtype,
  1011. ies, ies_len);
  1012. break;
  1013. default:
  1014. ret = -EOPNOTSUPP;
  1015. break;
  1016. }
  1017. if (ret)
  1018. kfree(ies);
  1019. return ret;
  1020. }
  1021. #ifdef CONFIG_PM
  1022. static int ieee80211_suspend(struct wiphy *wiphy)
  1023. {
  1024. return __ieee80211_suspend(wiphy_priv(wiphy));
  1025. }
  1026. static int ieee80211_resume(struct wiphy *wiphy)
  1027. {
  1028. return __ieee80211_resume(wiphy_priv(wiphy));
  1029. }
  1030. #else
  1031. #define ieee80211_suspend NULL
  1032. #define ieee80211_resume NULL
  1033. #endif
  1034. struct cfg80211_ops mac80211_config_ops = {
  1035. .add_virtual_intf = ieee80211_add_iface,
  1036. .del_virtual_intf = ieee80211_del_iface,
  1037. .change_virtual_intf = ieee80211_change_iface,
  1038. .add_key = ieee80211_add_key,
  1039. .del_key = ieee80211_del_key,
  1040. .get_key = ieee80211_get_key,
  1041. .set_default_key = ieee80211_config_default_key,
  1042. .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
  1043. .add_beacon = ieee80211_add_beacon,
  1044. .set_beacon = ieee80211_set_beacon,
  1045. .del_beacon = ieee80211_del_beacon,
  1046. .add_station = ieee80211_add_station,
  1047. .del_station = ieee80211_del_station,
  1048. .change_station = ieee80211_change_station,
  1049. .get_station = ieee80211_get_station,
  1050. .dump_station = ieee80211_dump_station,
  1051. #ifdef CONFIG_MAC80211_MESH
  1052. .add_mpath = ieee80211_add_mpath,
  1053. .del_mpath = ieee80211_del_mpath,
  1054. .change_mpath = ieee80211_change_mpath,
  1055. .get_mpath = ieee80211_get_mpath,
  1056. .dump_mpath = ieee80211_dump_mpath,
  1057. .set_mesh_params = ieee80211_set_mesh_params,
  1058. .get_mesh_params = ieee80211_get_mesh_params,
  1059. #endif
  1060. .change_bss = ieee80211_change_bss,
  1061. .set_txq_params = ieee80211_set_txq_params,
  1062. .set_channel = ieee80211_set_channel,
  1063. .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
  1064. .suspend = ieee80211_suspend,
  1065. .resume = ieee80211_resume,
  1066. };