cfg.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  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. default:
  114. return -EINVAL;
  115. }
  116. key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
  117. if (!key)
  118. return -ENOMEM;
  119. rcu_read_lock();
  120. if (mac_addr) {
  121. sta = sta_info_get(sdata->local, mac_addr);
  122. if (!sta) {
  123. ieee80211_key_free(key);
  124. err = -ENOENT;
  125. goto out_unlock;
  126. }
  127. }
  128. ieee80211_key_link(key, sdata, sta);
  129. err = 0;
  130. out_unlock:
  131. rcu_read_unlock();
  132. return err;
  133. }
  134. static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
  135. u8 key_idx, u8 *mac_addr)
  136. {
  137. struct ieee80211_sub_if_data *sdata;
  138. struct sta_info *sta;
  139. int ret;
  140. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  141. rcu_read_lock();
  142. if (mac_addr) {
  143. ret = -ENOENT;
  144. sta = sta_info_get(sdata->local, mac_addr);
  145. if (!sta)
  146. goto out_unlock;
  147. if (sta->key) {
  148. ieee80211_key_free(sta->key);
  149. WARN_ON(sta->key);
  150. ret = 0;
  151. }
  152. goto out_unlock;
  153. }
  154. if (!sdata->keys[key_idx]) {
  155. ret = -ENOENT;
  156. goto out_unlock;
  157. }
  158. ieee80211_key_free(sdata->keys[key_idx]);
  159. WARN_ON(sdata->keys[key_idx]);
  160. ret = 0;
  161. out_unlock:
  162. rcu_read_unlock();
  163. return ret;
  164. }
  165. static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
  166. u8 key_idx, u8 *mac_addr, void *cookie,
  167. void (*callback)(void *cookie,
  168. struct key_params *params))
  169. {
  170. struct ieee80211_sub_if_data *sdata;
  171. struct sta_info *sta = NULL;
  172. u8 seq[6] = {0};
  173. struct key_params params;
  174. struct ieee80211_key *key;
  175. u32 iv32;
  176. u16 iv16;
  177. int err = -ENOENT;
  178. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  179. rcu_read_lock();
  180. if (mac_addr) {
  181. sta = sta_info_get(sdata->local, mac_addr);
  182. if (!sta)
  183. goto out;
  184. key = sta->key;
  185. } else
  186. key = sdata->keys[key_idx];
  187. if (!key)
  188. goto out;
  189. memset(&params, 0, sizeof(params));
  190. switch (key->conf.alg) {
  191. case ALG_TKIP:
  192. params.cipher = WLAN_CIPHER_SUITE_TKIP;
  193. iv32 = key->u.tkip.tx.iv32;
  194. iv16 = key->u.tkip.tx.iv16;
  195. if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
  196. sdata->local->ops->get_tkip_seq)
  197. sdata->local->ops->get_tkip_seq(
  198. local_to_hw(sdata->local),
  199. key->conf.hw_key_idx,
  200. &iv32, &iv16);
  201. seq[0] = iv16 & 0xff;
  202. seq[1] = (iv16 >> 8) & 0xff;
  203. seq[2] = iv32 & 0xff;
  204. seq[3] = (iv32 >> 8) & 0xff;
  205. seq[4] = (iv32 >> 16) & 0xff;
  206. seq[5] = (iv32 >> 24) & 0xff;
  207. params.seq = seq;
  208. params.seq_len = 6;
  209. break;
  210. case ALG_CCMP:
  211. params.cipher = WLAN_CIPHER_SUITE_CCMP;
  212. seq[0] = key->u.ccmp.tx_pn[5];
  213. seq[1] = key->u.ccmp.tx_pn[4];
  214. seq[2] = key->u.ccmp.tx_pn[3];
  215. seq[3] = key->u.ccmp.tx_pn[2];
  216. seq[4] = key->u.ccmp.tx_pn[1];
  217. seq[5] = key->u.ccmp.tx_pn[0];
  218. params.seq = seq;
  219. params.seq_len = 6;
  220. break;
  221. case ALG_WEP:
  222. if (key->conf.keylen == 5)
  223. params.cipher = WLAN_CIPHER_SUITE_WEP40;
  224. else
  225. params.cipher = WLAN_CIPHER_SUITE_WEP104;
  226. break;
  227. }
  228. params.key = key->conf.key;
  229. params.key_len = key->conf.keylen;
  230. callback(cookie, &params);
  231. err = 0;
  232. out:
  233. rcu_read_unlock();
  234. return err;
  235. }
  236. static int ieee80211_config_default_key(struct wiphy *wiphy,
  237. struct net_device *dev,
  238. u8 key_idx)
  239. {
  240. struct ieee80211_sub_if_data *sdata;
  241. rcu_read_lock();
  242. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  243. ieee80211_set_default_key(sdata, key_idx);
  244. rcu_read_unlock();
  245. return 0;
  246. }
  247. static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
  248. {
  249. struct ieee80211_sub_if_data *sdata = sta->sdata;
  250. sinfo->filled = STATION_INFO_INACTIVE_TIME |
  251. STATION_INFO_RX_BYTES |
  252. STATION_INFO_TX_BYTES;
  253. sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
  254. sinfo->rx_bytes = sta->rx_bytes;
  255. sinfo->tx_bytes = sta->tx_bytes;
  256. if (ieee80211_vif_is_mesh(&sdata->vif)) {
  257. #ifdef CONFIG_MAC80211_MESH
  258. sinfo->filled |= STATION_INFO_LLID |
  259. STATION_INFO_PLID |
  260. STATION_INFO_PLINK_STATE;
  261. sinfo->llid = le16_to_cpu(sta->llid);
  262. sinfo->plid = le16_to_cpu(sta->plid);
  263. sinfo->plink_state = sta->plink_state;
  264. #endif
  265. }
  266. }
  267. static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
  268. int idx, u8 *mac, struct station_info *sinfo)
  269. {
  270. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  271. struct sta_info *sta;
  272. int ret = -ENOENT;
  273. rcu_read_lock();
  274. sta = sta_info_get_by_idx(local, idx, dev);
  275. if (sta) {
  276. ret = 0;
  277. memcpy(mac, sta->sta.addr, ETH_ALEN);
  278. sta_set_sinfo(sta, sinfo);
  279. }
  280. rcu_read_unlock();
  281. return ret;
  282. }
  283. static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  284. u8 *mac, struct station_info *sinfo)
  285. {
  286. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  287. struct sta_info *sta;
  288. int ret = -ENOENT;
  289. rcu_read_lock();
  290. /* XXX: verify sta->dev == dev */
  291. sta = sta_info_get(local, mac);
  292. if (sta) {
  293. ret = 0;
  294. sta_set_sinfo(sta, sinfo);
  295. }
  296. rcu_read_unlock();
  297. return ret;
  298. }
  299. /*
  300. * This handles both adding a beacon and setting new beacon info
  301. */
  302. static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
  303. struct beacon_parameters *params)
  304. {
  305. struct beacon_data *new, *old;
  306. int new_head_len, new_tail_len;
  307. int size;
  308. int err = -EINVAL;
  309. old = sdata->u.ap.beacon;
  310. /* head must not be zero-length */
  311. if (params->head && !params->head_len)
  312. return -EINVAL;
  313. /*
  314. * This is a kludge. beacon interval should really be part
  315. * of the beacon information.
  316. */
  317. if (params->interval) {
  318. sdata->local->hw.conf.beacon_int = params->interval;
  319. err = ieee80211_hw_config(sdata->local,
  320. IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
  321. if (err < 0)
  322. return err;
  323. /*
  324. * We updated some parameter so if below bails out
  325. * it's not an error.
  326. */
  327. err = 0;
  328. }
  329. /* Need to have a beacon head if we don't have one yet */
  330. if (!params->head && !old)
  331. return err;
  332. /* sorry, no way to start beaconing without dtim period */
  333. if (!params->dtim_period && !old)
  334. return err;
  335. /* new or old head? */
  336. if (params->head)
  337. new_head_len = params->head_len;
  338. else
  339. new_head_len = old->head_len;
  340. /* new or old tail? */
  341. if (params->tail || !old)
  342. /* params->tail_len will be zero for !params->tail */
  343. new_tail_len = params->tail_len;
  344. else
  345. new_tail_len = old->tail_len;
  346. size = sizeof(*new) + new_head_len + new_tail_len;
  347. new = kzalloc(size, GFP_KERNEL);
  348. if (!new)
  349. return -ENOMEM;
  350. /* start filling the new info now */
  351. /* new or old dtim period? */
  352. if (params->dtim_period)
  353. new->dtim_period = params->dtim_period;
  354. else
  355. new->dtim_period = old->dtim_period;
  356. /*
  357. * pointers go into the block we allocated,
  358. * memory is | beacon_data | head | tail |
  359. */
  360. new->head = ((u8 *) new) + sizeof(*new);
  361. new->tail = new->head + new_head_len;
  362. new->head_len = new_head_len;
  363. new->tail_len = new_tail_len;
  364. /* copy in head */
  365. if (params->head)
  366. memcpy(new->head, params->head, new_head_len);
  367. else
  368. memcpy(new->head, old->head, new_head_len);
  369. /* copy in optional tail */
  370. if (params->tail)
  371. memcpy(new->tail, params->tail, new_tail_len);
  372. else
  373. if (old)
  374. memcpy(new->tail, old->tail, new_tail_len);
  375. rcu_assign_pointer(sdata->u.ap.beacon, new);
  376. synchronize_rcu();
  377. kfree(old);
  378. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  379. }
  380. static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
  381. struct beacon_parameters *params)
  382. {
  383. struct ieee80211_sub_if_data *sdata;
  384. struct beacon_data *old;
  385. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  386. if (sdata->vif.type != NL80211_IFTYPE_AP)
  387. return -EINVAL;
  388. old = sdata->u.ap.beacon;
  389. if (old)
  390. return -EALREADY;
  391. return ieee80211_config_beacon(sdata, params);
  392. }
  393. static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
  394. struct beacon_parameters *params)
  395. {
  396. struct ieee80211_sub_if_data *sdata;
  397. struct beacon_data *old;
  398. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  399. if (sdata->vif.type != NL80211_IFTYPE_AP)
  400. return -EINVAL;
  401. old = sdata->u.ap.beacon;
  402. if (!old)
  403. return -ENOENT;
  404. return ieee80211_config_beacon(sdata, params);
  405. }
  406. static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
  407. {
  408. struct ieee80211_sub_if_data *sdata;
  409. struct beacon_data *old;
  410. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  411. if (sdata->vif.type != NL80211_IFTYPE_AP)
  412. return -EINVAL;
  413. old = sdata->u.ap.beacon;
  414. if (!old)
  415. return -ENOENT;
  416. rcu_assign_pointer(sdata->u.ap.beacon, NULL);
  417. synchronize_rcu();
  418. kfree(old);
  419. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  420. }
  421. /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
  422. struct iapp_layer2_update {
  423. u8 da[ETH_ALEN]; /* broadcast */
  424. u8 sa[ETH_ALEN]; /* STA addr */
  425. __be16 len; /* 6 */
  426. u8 dsap; /* 0 */
  427. u8 ssap; /* 0 */
  428. u8 control;
  429. u8 xid_info[3];
  430. } __attribute__ ((packed));
  431. static void ieee80211_send_layer2_update(struct sta_info *sta)
  432. {
  433. struct iapp_layer2_update *msg;
  434. struct sk_buff *skb;
  435. /* Send Level 2 Update Frame to update forwarding tables in layer 2
  436. * bridge devices */
  437. skb = dev_alloc_skb(sizeof(*msg));
  438. if (!skb)
  439. return;
  440. msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
  441. /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
  442. * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
  443. memset(msg->da, 0xff, ETH_ALEN);
  444. memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
  445. msg->len = htons(6);
  446. msg->dsap = 0;
  447. msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
  448. msg->control = 0xaf; /* XID response lsb.1111F101.
  449. * F=0 (no poll command; unsolicited frame) */
  450. msg->xid_info[0] = 0x81; /* XID format identifier */
  451. msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
  452. msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
  453. skb->dev = sta->sdata->dev;
  454. skb->protocol = eth_type_trans(skb, sta->sdata->dev);
  455. memset(skb->cb, 0, sizeof(skb->cb));
  456. netif_rx(skb);
  457. }
  458. static void sta_apply_parameters(struct ieee80211_local *local,
  459. struct sta_info *sta,
  460. struct station_parameters *params)
  461. {
  462. u32 rates;
  463. int i, j;
  464. struct ieee80211_supported_band *sband;
  465. struct ieee80211_sub_if_data *sdata = sta->sdata;
  466. sband = local->hw.wiphy->bands[local->oper_channel->band];
  467. /*
  468. * FIXME: updating the flags is racy when this function is
  469. * called from ieee80211_change_station(), this will
  470. * be resolved in a future patch.
  471. */
  472. if (params->station_flags & STATION_FLAG_CHANGED) {
  473. spin_lock_bh(&sta->lock);
  474. sta->flags &= ~WLAN_STA_AUTHORIZED;
  475. if (params->station_flags & STATION_FLAG_AUTHORIZED)
  476. sta->flags |= WLAN_STA_AUTHORIZED;
  477. sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  478. if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
  479. sta->flags |= WLAN_STA_SHORT_PREAMBLE;
  480. sta->flags &= ~WLAN_STA_WME;
  481. if (params->station_flags & STATION_FLAG_WME)
  482. sta->flags |= WLAN_STA_WME;
  483. spin_unlock_bh(&sta->lock);
  484. }
  485. /*
  486. * FIXME: updating the following information is racy when this
  487. * function is called from ieee80211_change_station().
  488. * However, all this information should be static so
  489. * maybe we should just reject attemps to change it.
  490. */
  491. if (params->aid) {
  492. sta->sta.aid = params->aid;
  493. if (sta->sta.aid > IEEE80211_MAX_AID)
  494. sta->sta.aid = 0; /* XXX: should this be an error? */
  495. }
  496. if (params->listen_interval >= 0)
  497. sta->listen_interval = params->listen_interval;
  498. if (params->supported_rates) {
  499. rates = 0;
  500. for (i = 0; i < params->supported_rates_len; i++) {
  501. int rate = (params->supported_rates[i] & 0x7f) * 5;
  502. for (j = 0; j < sband->n_bitrates; j++) {
  503. if (sband->bitrates[j].bitrate == rate)
  504. rates |= BIT(j);
  505. }
  506. }
  507. sta->sta.supp_rates[local->oper_channel->band] = rates;
  508. }
  509. if (params->ht_capa)
  510. ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
  511. params->ht_capa,
  512. &sta->sta.ht_cap);
  513. if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
  514. switch (params->plink_action) {
  515. case PLINK_ACTION_OPEN:
  516. mesh_plink_open(sta);
  517. break;
  518. case PLINK_ACTION_BLOCK:
  519. mesh_plink_block(sta);
  520. break;
  521. }
  522. }
  523. }
  524. static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
  525. u8 *mac, struct station_parameters *params)
  526. {
  527. struct ieee80211_local *local = wiphy_priv(wiphy);
  528. struct sta_info *sta;
  529. struct ieee80211_sub_if_data *sdata;
  530. int err;
  531. /* Prevent a race with changing the rate control algorithm */
  532. if (!netif_running(dev))
  533. return -ENETDOWN;
  534. if (params->vlan) {
  535. sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  536. if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  537. sdata->vif.type != NL80211_IFTYPE_AP)
  538. return -EINVAL;
  539. } else
  540. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  541. if (compare_ether_addr(mac, dev->dev_addr) == 0)
  542. return -EINVAL;
  543. if (is_multicast_ether_addr(mac))
  544. return -EINVAL;
  545. sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
  546. if (!sta)
  547. return -ENOMEM;
  548. sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
  549. sta_apply_parameters(local, sta, params);
  550. rate_control_rate_init(sta);
  551. rcu_read_lock();
  552. err = sta_info_insert(sta);
  553. if (err) {
  554. /* STA has been freed */
  555. rcu_read_unlock();
  556. return err;
  557. }
  558. if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
  559. sdata->vif.type == NL80211_IFTYPE_AP)
  560. ieee80211_send_layer2_update(sta);
  561. rcu_read_unlock();
  562. return 0;
  563. }
  564. static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
  565. u8 *mac)
  566. {
  567. struct ieee80211_local *local = wiphy_priv(wiphy);
  568. struct ieee80211_sub_if_data *sdata;
  569. struct sta_info *sta;
  570. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  571. if (mac) {
  572. rcu_read_lock();
  573. /* XXX: get sta belonging to dev */
  574. sta = sta_info_get(local, mac);
  575. if (!sta) {
  576. rcu_read_unlock();
  577. return -ENOENT;
  578. }
  579. sta_info_unlink(&sta);
  580. rcu_read_unlock();
  581. sta_info_destroy(sta);
  582. } else
  583. sta_info_flush(local, sdata);
  584. return 0;
  585. }
  586. static int ieee80211_change_station(struct wiphy *wiphy,
  587. struct net_device *dev,
  588. u8 *mac,
  589. struct station_parameters *params)
  590. {
  591. struct ieee80211_local *local = wiphy_priv(wiphy);
  592. struct sta_info *sta;
  593. struct ieee80211_sub_if_data *vlansdata;
  594. rcu_read_lock();
  595. /* XXX: get sta belonging to dev */
  596. sta = sta_info_get(local, mac);
  597. if (!sta) {
  598. rcu_read_unlock();
  599. return -ENOENT;
  600. }
  601. if (params->vlan && params->vlan != sta->sdata->dev) {
  602. vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  603. if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  604. vlansdata->vif.type != NL80211_IFTYPE_AP) {
  605. rcu_read_unlock();
  606. return -EINVAL;
  607. }
  608. sta->sdata = vlansdata;
  609. ieee80211_send_layer2_update(sta);
  610. }
  611. sta_apply_parameters(local, sta, params);
  612. rcu_read_unlock();
  613. return 0;
  614. }
  615. #ifdef CONFIG_MAC80211_MESH
  616. static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
  617. u8 *dst, u8 *next_hop)
  618. {
  619. struct ieee80211_local *local = wiphy_priv(wiphy);
  620. struct ieee80211_sub_if_data *sdata;
  621. struct mesh_path *mpath;
  622. struct sta_info *sta;
  623. int err;
  624. if (!netif_running(dev))
  625. return -ENETDOWN;
  626. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  627. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  628. return -ENOTSUPP;
  629. rcu_read_lock();
  630. sta = sta_info_get(local, next_hop);
  631. if (!sta) {
  632. rcu_read_unlock();
  633. return -ENOENT;
  634. }
  635. err = mesh_path_add(dst, sdata);
  636. if (err) {
  637. rcu_read_unlock();
  638. return err;
  639. }
  640. mpath = mesh_path_lookup(dst, sdata);
  641. if (!mpath) {
  642. rcu_read_unlock();
  643. return -ENXIO;
  644. }
  645. mesh_path_fix_nexthop(mpath, sta);
  646. rcu_read_unlock();
  647. return 0;
  648. }
  649. static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
  650. u8 *dst)
  651. {
  652. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  653. if (dst)
  654. return mesh_path_del(dst, sdata);
  655. mesh_path_flush(sdata);
  656. return 0;
  657. }
  658. static int ieee80211_change_mpath(struct wiphy *wiphy,
  659. struct net_device *dev,
  660. u8 *dst, u8 *next_hop)
  661. {
  662. struct ieee80211_local *local = wiphy_priv(wiphy);
  663. struct ieee80211_sub_if_data *sdata;
  664. struct mesh_path *mpath;
  665. struct sta_info *sta;
  666. if (!netif_running(dev))
  667. return -ENETDOWN;
  668. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  669. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  670. return -ENOTSUPP;
  671. rcu_read_lock();
  672. sta = sta_info_get(local, next_hop);
  673. if (!sta) {
  674. rcu_read_unlock();
  675. return -ENOENT;
  676. }
  677. mpath = mesh_path_lookup(dst, sdata);
  678. if (!mpath) {
  679. rcu_read_unlock();
  680. return -ENOENT;
  681. }
  682. mesh_path_fix_nexthop(mpath, sta);
  683. rcu_read_unlock();
  684. return 0;
  685. }
  686. static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
  687. struct mpath_info *pinfo)
  688. {
  689. if (mpath->next_hop)
  690. memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
  691. else
  692. memset(next_hop, 0, ETH_ALEN);
  693. pinfo->filled = MPATH_INFO_FRAME_QLEN |
  694. MPATH_INFO_DSN |
  695. MPATH_INFO_METRIC |
  696. MPATH_INFO_EXPTIME |
  697. MPATH_INFO_DISCOVERY_TIMEOUT |
  698. MPATH_INFO_DISCOVERY_RETRIES |
  699. MPATH_INFO_FLAGS;
  700. pinfo->frame_qlen = mpath->frame_queue.qlen;
  701. pinfo->dsn = mpath->dsn;
  702. pinfo->metric = mpath->metric;
  703. if (time_before(jiffies, mpath->exp_time))
  704. pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
  705. pinfo->discovery_timeout =
  706. jiffies_to_msecs(mpath->discovery_timeout);
  707. pinfo->discovery_retries = mpath->discovery_retries;
  708. pinfo->flags = 0;
  709. if (mpath->flags & MESH_PATH_ACTIVE)
  710. pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
  711. if (mpath->flags & MESH_PATH_RESOLVING)
  712. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  713. if (mpath->flags & MESH_PATH_DSN_VALID)
  714. pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID;
  715. if (mpath->flags & MESH_PATH_FIXED)
  716. pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
  717. if (mpath->flags & MESH_PATH_RESOLVING)
  718. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  719. pinfo->flags = mpath->flags;
  720. }
  721. static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
  722. u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
  723. {
  724. struct ieee80211_sub_if_data *sdata;
  725. struct mesh_path *mpath;
  726. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  727. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  728. return -ENOTSUPP;
  729. rcu_read_lock();
  730. mpath = mesh_path_lookup(dst, sdata);
  731. if (!mpath) {
  732. rcu_read_unlock();
  733. return -ENOENT;
  734. }
  735. memcpy(dst, mpath->dst, ETH_ALEN);
  736. mpath_set_pinfo(mpath, next_hop, pinfo);
  737. rcu_read_unlock();
  738. return 0;
  739. }
  740. static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
  741. int idx, u8 *dst, u8 *next_hop,
  742. struct mpath_info *pinfo)
  743. {
  744. struct ieee80211_sub_if_data *sdata;
  745. struct mesh_path *mpath;
  746. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  747. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  748. return -ENOTSUPP;
  749. rcu_read_lock();
  750. mpath = mesh_path_lookup_by_idx(idx, sdata);
  751. if (!mpath) {
  752. rcu_read_unlock();
  753. return -ENOENT;
  754. }
  755. memcpy(dst, mpath->dst, ETH_ALEN);
  756. mpath_set_pinfo(mpath, next_hop, pinfo);
  757. rcu_read_unlock();
  758. return 0;
  759. }
  760. static int ieee80211_get_mesh_params(struct wiphy *wiphy,
  761. struct net_device *dev,
  762. struct mesh_config *conf)
  763. {
  764. struct ieee80211_sub_if_data *sdata;
  765. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  766. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  767. return -ENOTSUPP;
  768. memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
  769. return 0;
  770. }
  771. static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
  772. {
  773. return (mask >> (parm-1)) & 0x1;
  774. }
  775. static int ieee80211_set_mesh_params(struct wiphy *wiphy,
  776. struct net_device *dev,
  777. const struct mesh_config *nconf, u32 mask)
  778. {
  779. struct mesh_config *conf;
  780. struct ieee80211_sub_if_data *sdata;
  781. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  782. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  783. return -ENOTSUPP;
  784. /* Set the config options which we are interested in setting */
  785. conf = &(sdata->u.mesh.mshcfg);
  786. if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
  787. conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
  788. if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
  789. conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
  790. if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
  791. conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
  792. if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
  793. conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
  794. if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
  795. conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
  796. if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
  797. conf->dot11MeshTTL = nconf->dot11MeshTTL;
  798. if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
  799. conf->auto_open_plinks = nconf->auto_open_plinks;
  800. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
  801. conf->dot11MeshHWMPmaxPREQretries =
  802. nconf->dot11MeshHWMPmaxPREQretries;
  803. if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
  804. conf->path_refresh_time = nconf->path_refresh_time;
  805. if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
  806. conf->min_discovery_timeout = nconf->min_discovery_timeout;
  807. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
  808. conf->dot11MeshHWMPactivePathTimeout =
  809. nconf->dot11MeshHWMPactivePathTimeout;
  810. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
  811. conf->dot11MeshHWMPpreqMinInterval =
  812. nconf->dot11MeshHWMPpreqMinInterval;
  813. if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
  814. mask))
  815. conf->dot11MeshHWMPnetDiameterTraversalTime =
  816. nconf->dot11MeshHWMPnetDiameterTraversalTime;
  817. return 0;
  818. }
  819. #endif
  820. static int ieee80211_change_bss(struct wiphy *wiphy,
  821. struct net_device *dev,
  822. struct bss_parameters *params)
  823. {
  824. struct ieee80211_sub_if_data *sdata;
  825. u32 changed = 0;
  826. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  827. if (sdata->vif.type != NL80211_IFTYPE_AP)
  828. return -EINVAL;
  829. if (params->use_cts_prot >= 0) {
  830. sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
  831. changed |= BSS_CHANGED_ERP_CTS_PROT;
  832. }
  833. if (params->use_short_preamble >= 0) {
  834. sdata->vif.bss_conf.use_short_preamble =
  835. params->use_short_preamble;
  836. changed |= BSS_CHANGED_ERP_PREAMBLE;
  837. }
  838. if (params->use_short_slot_time >= 0) {
  839. sdata->vif.bss_conf.use_short_slot =
  840. params->use_short_slot_time;
  841. changed |= BSS_CHANGED_ERP_SLOT;
  842. }
  843. if (params->basic_rates) {
  844. int i, j;
  845. u32 rates = 0;
  846. struct ieee80211_local *local = wiphy_priv(wiphy);
  847. struct ieee80211_supported_band *sband =
  848. wiphy->bands[local->oper_channel->band];
  849. for (i = 0; i < params->basic_rates_len; i++) {
  850. int rate = (params->basic_rates[i] & 0x7f) * 5;
  851. for (j = 0; j < sband->n_bitrates; j++) {
  852. if (sband->bitrates[j].bitrate == rate)
  853. rates |= BIT(j);
  854. }
  855. }
  856. sdata->vif.bss_conf.basic_rates = rates;
  857. changed |= BSS_CHANGED_BASIC_RATES;
  858. }
  859. ieee80211_bss_info_change_notify(sdata, changed);
  860. return 0;
  861. }
  862. static int ieee80211_set_txq_params(struct wiphy *wiphy,
  863. struct ieee80211_txq_params *params)
  864. {
  865. struct ieee80211_local *local = wiphy_priv(wiphy);
  866. struct ieee80211_tx_queue_params p;
  867. if (!local->ops->conf_tx)
  868. return -EOPNOTSUPP;
  869. memset(&p, 0, sizeof(p));
  870. p.aifs = params->aifs;
  871. p.cw_max = params->cwmax;
  872. p.cw_min = params->cwmin;
  873. p.txop = params->txop;
  874. if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
  875. printk(KERN_DEBUG "%s: failed to set TX queue "
  876. "parameters for queue %d\n", local->mdev->name,
  877. params->queue);
  878. return -EINVAL;
  879. }
  880. return 0;
  881. }
  882. static int ieee80211_set_channel(struct wiphy *wiphy,
  883. struct ieee80211_channel *chan,
  884. enum nl80211_sec_chan_offset sec_chan_offset)
  885. {
  886. struct ieee80211_local *local = wiphy_priv(wiphy);
  887. local->oper_channel = chan;
  888. local->oper_sec_chan_offset = sec_chan_offset;
  889. return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
  890. }
  891. struct cfg80211_ops mac80211_config_ops = {
  892. .add_virtual_intf = ieee80211_add_iface,
  893. .del_virtual_intf = ieee80211_del_iface,
  894. .change_virtual_intf = ieee80211_change_iface,
  895. .add_key = ieee80211_add_key,
  896. .del_key = ieee80211_del_key,
  897. .get_key = ieee80211_get_key,
  898. .set_default_key = ieee80211_config_default_key,
  899. .add_beacon = ieee80211_add_beacon,
  900. .set_beacon = ieee80211_set_beacon,
  901. .del_beacon = ieee80211_del_beacon,
  902. .add_station = ieee80211_add_station,
  903. .del_station = ieee80211_del_station,
  904. .change_station = ieee80211_change_station,
  905. .get_station = ieee80211_get_station,
  906. .dump_station = ieee80211_dump_station,
  907. #ifdef CONFIG_MAC80211_MESH
  908. .add_mpath = ieee80211_add_mpath,
  909. .del_mpath = ieee80211_del_mpath,
  910. .change_mpath = ieee80211_change_mpath,
  911. .get_mpath = ieee80211_get_mpath,
  912. .dump_mpath = ieee80211_dump_mpath,
  913. .set_mesh_params = ieee80211_set_mesh_params,
  914. .get_mesh_params = ieee80211_get_mesh_params,
  915. #endif
  916. .change_bss = ieee80211_change_bss,
  917. .set_txq_params = ieee80211_set_txq_params,
  918. .set_channel = ieee80211_set_channel,
  919. };