mlme.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * cfg80211 MLME SAP interface
  4. *
  5. * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  6. * Copyright (c) 2015 Intel Deutschland GmbH
  7. * Copyright (C) 2019-2020, 2022-2024 Intel Corporation
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/etherdevice.h>
  12. #include <linux/netdevice.h>
  13. #include <linux/nl80211.h>
  14. #include <linux/slab.h>
  15. #include <linux/wireless.h>
  16. #include <net/cfg80211.h>
  17. #include <net/iw_handler.h>
  18. #include "core.h"
  19. #include "nl80211.h"
  20. #include "rdev-ops.h"
  21. void cfg80211_rx_assoc_resp(struct net_device *dev,
  22. const struct cfg80211_rx_assoc_resp_data *data)
  23. {
  24. struct wireless_dev *wdev = dev->ieee80211_ptr;
  25. struct wiphy *wiphy = wdev->wiphy;
  26. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  27. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf;
  28. struct cfg80211_connect_resp_params cr = {
  29. .timeout_reason = NL80211_TIMEOUT_UNSPECIFIED,
  30. .req_ie = data->req_ies,
  31. .req_ie_len = data->req_ies_len,
  32. .resp_ie = mgmt->u.assoc_resp.variable,
  33. .resp_ie_len = data->len -
  34. offsetof(struct ieee80211_mgmt,
  35. u.assoc_resp.variable),
  36. .status = le16_to_cpu(mgmt->u.assoc_resp.status_code),
  37. .ap_mld_addr = data->ap_mld_addr,
  38. };
  39. unsigned int link_id;
  40. for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
  41. cr.links[link_id].status = data->links[link_id].status;
  42. cr.links[link_id].bss = data->links[link_id].bss;
  43. WARN_ON_ONCE(cr.links[link_id].status != WLAN_STATUS_SUCCESS &&
  44. (!cr.ap_mld_addr || !cr.links[link_id].bss));
  45. if (!cr.links[link_id].bss)
  46. continue;
  47. cr.links[link_id].bssid = data->links[link_id].bss->bssid;
  48. cr.links[link_id].addr = data->links[link_id].addr;
  49. /* need to have local link addresses for MLO connections */
  50. WARN_ON(cr.ap_mld_addr &&
  51. !is_valid_ether_addr(cr.links[link_id].addr));
  52. BUG_ON(!cr.links[link_id].bss->channel);
  53. if (cr.links[link_id].bss->channel->band == NL80211_BAND_S1GHZ) {
  54. WARN_ON(link_id);
  55. cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
  56. cr.resp_ie_len = data->len -
  57. offsetof(struct ieee80211_mgmt,
  58. u.s1g_assoc_resp.variable);
  59. }
  60. if (cr.ap_mld_addr)
  61. cr.valid_links |= BIT(link_id);
  62. }
  63. trace_cfg80211_send_rx_assoc(dev, data);
  64. /*
  65. * This is a bit of a hack, we don't notify userspace of
  66. * a (re-)association reply if we tried to send a reassoc
  67. * and got a reject -- we only try again with an assoc
  68. * frame instead of reassoc.
  69. */
  70. if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
  71. for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
  72. struct cfg80211_bss *bss = data->links[link_id].bss;
  73. if (!bss)
  74. continue;
  75. cfg80211_unhold_bss(bss_from_pub(bss));
  76. cfg80211_put_bss(wiphy, bss);
  77. }
  78. return;
  79. }
  80. nl80211_send_rx_assoc(rdev, dev, data);
  81. /* update current_bss etc., consumes the bss reference */
  82. __cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
  83. }
  84. EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
  85. static void cfg80211_process_auth(struct wireless_dev *wdev,
  86. const u8 *buf, size_t len)
  87. {
  88. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  89. nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
  90. cfg80211_sme_rx_auth(wdev, buf, len);
  91. }
  92. static void cfg80211_process_deauth(struct wireless_dev *wdev,
  93. const u8 *buf, size_t len,
  94. bool reconnect)
  95. {
  96. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  97. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  98. const u8 *bssid = mgmt->bssid;
  99. u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
  100. bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
  101. nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
  102. if (!wdev->connected || !ether_addr_equal(wdev->u.client.connected_addr, bssid))
  103. return;
  104. __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
  105. cfg80211_sme_deauth(wdev);
  106. }
  107. static void cfg80211_process_disassoc(struct wireless_dev *wdev,
  108. const u8 *buf, size_t len,
  109. bool reconnect)
  110. {
  111. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  112. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  113. const u8 *bssid = mgmt->bssid;
  114. u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
  115. bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
  116. nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect,
  117. GFP_KERNEL);
  118. if (WARN_ON(!wdev->connected ||
  119. !ether_addr_equal(wdev->u.client.connected_addr, bssid)))
  120. return;
  121. __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
  122. cfg80211_sme_disassoc(wdev);
  123. }
  124. void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
  125. {
  126. struct wireless_dev *wdev = dev->ieee80211_ptr;
  127. struct ieee80211_mgmt *mgmt = (void *)buf;
  128. lockdep_assert_wiphy(wdev->wiphy);
  129. trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
  130. if (WARN_ON(len < 2))
  131. return;
  132. if (ieee80211_is_auth(mgmt->frame_control))
  133. cfg80211_process_auth(wdev, buf, len);
  134. else if (ieee80211_is_deauth(mgmt->frame_control))
  135. cfg80211_process_deauth(wdev, buf, len, false);
  136. else if (ieee80211_is_disassoc(mgmt->frame_control))
  137. cfg80211_process_disassoc(wdev, buf, len, false);
  138. }
  139. EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
  140. void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
  141. {
  142. struct wireless_dev *wdev = dev->ieee80211_ptr;
  143. struct wiphy *wiphy = wdev->wiphy;
  144. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  145. trace_cfg80211_send_auth_timeout(dev, addr);
  146. nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
  147. cfg80211_sme_auth_timeout(wdev);
  148. }
  149. EXPORT_SYMBOL(cfg80211_auth_timeout);
  150. void cfg80211_assoc_failure(struct net_device *dev,
  151. struct cfg80211_assoc_failure *data)
  152. {
  153. struct wireless_dev *wdev = dev->ieee80211_ptr;
  154. struct wiphy *wiphy = wdev->wiphy;
  155. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  156. const u8 *addr = data->ap_mld_addr ?: data->bss[0]->bssid;
  157. int i;
  158. trace_cfg80211_send_assoc_failure(dev, data);
  159. if (data->timeout) {
  160. nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
  161. cfg80211_sme_assoc_timeout(wdev);
  162. } else {
  163. cfg80211_sme_abandon_assoc(wdev);
  164. }
  165. for (i = 0; i < ARRAY_SIZE(data->bss); i++) {
  166. struct cfg80211_bss *bss = data->bss[i];
  167. if (!bss)
  168. continue;
  169. cfg80211_unhold_bss(bss_from_pub(bss));
  170. cfg80211_put_bss(wiphy, bss);
  171. }
  172. }
  173. EXPORT_SYMBOL(cfg80211_assoc_failure);
  174. void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
  175. bool reconnect)
  176. {
  177. struct wireless_dev *wdev = dev->ieee80211_ptr;
  178. struct ieee80211_mgmt *mgmt = (void *)buf;
  179. lockdep_assert_wiphy(wdev->wiphy);
  180. trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect);
  181. if (WARN_ON(len < 2))
  182. return;
  183. if (ieee80211_is_deauth(mgmt->frame_control))
  184. cfg80211_process_deauth(wdev, buf, len, reconnect);
  185. else
  186. cfg80211_process_disassoc(wdev, buf, len, reconnect);
  187. }
  188. EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
  189. void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
  190. enum nl80211_key_type key_type, int key_id,
  191. const u8 *tsc, gfp_t gfp)
  192. {
  193. struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
  194. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  195. #ifdef CONFIG_CFG80211_WEXT
  196. union iwreq_data wrqu;
  197. char *buf = kmalloc(128, gfp);
  198. if (buf) {
  199. memset(&wrqu, 0, sizeof(wrqu));
  200. wrqu.data.length =
  201. sprintf(buf, "MLME-MICHAELMICFAILURE."
  202. "indication(keyid=%d %scast addr=%pM)",
  203. key_id, key_type == NL80211_KEYTYPE_GROUP
  204. ? "broad" : "uni", addr);
  205. wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
  206. kfree(buf);
  207. }
  208. #endif
  209. trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
  210. nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
  211. }
  212. EXPORT_SYMBOL(cfg80211_michael_mic_failure);
  213. /* some MLME handling for userspace SME */
  214. int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
  215. struct net_device *dev,
  216. struct cfg80211_auth_request *req)
  217. {
  218. struct wireless_dev *wdev = dev->ieee80211_ptr;
  219. lockdep_assert_wiphy(wdev->wiphy);
  220. if (!req->bss)
  221. return -ENOENT;
  222. if (req->link_id >= 0 &&
  223. !(wdev->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))
  224. return -EINVAL;
  225. if (req->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
  226. if (!req->key || !req->key_len ||
  227. req->key_idx < 0 || req->key_idx > 3)
  228. return -EINVAL;
  229. }
  230. if (wdev->connected &&
  231. ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr))
  232. return -EALREADY;
  233. if (ether_addr_equal(req->bss->bssid, dev->dev_addr) ||
  234. (req->link_id >= 0 &&
  235. ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
  236. return -EINVAL;
  237. return rdev_auth(rdev, dev, req);
  238. }
  239. /* Do a logical ht_capa &= ht_capa_mask. */
  240. void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
  241. const struct ieee80211_ht_cap *ht_capa_mask)
  242. {
  243. int i;
  244. u8 *p1, *p2;
  245. if (!ht_capa_mask) {
  246. memset(ht_capa, 0, sizeof(*ht_capa));
  247. return;
  248. }
  249. p1 = (u8*)(ht_capa);
  250. p2 = (u8*)(ht_capa_mask);
  251. for (i = 0; i < sizeof(*ht_capa); i++)
  252. p1[i] &= p2[i];
  253. }
  254. /* Do a logical vht_capa &= vht_capa_mask. */
  255. void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
  256. const struct ieee80211_vht_cap *vht_capa_mask)
  257. {
  258. int i;
  259. u8 *p1, *p2;
  260. if (!vht_capa_mask) {
  261. memset(vht_capa, 0, sizeof(*vht_capa));
  262. return;
  263. }
  264. p1 = (u8*)(vht_capa);
  265. p2 = (u8*)(vht_capa_mask);
  266. for (i = 0; i < sizeof(*vht_capa); i++)
  267. p1[i] &= p2[i];
  268. }
  269. static int
  270. cfg80211_mlme_check_mlo_compat(const struct ieee80211_multi_link_elem *mle_a,
  271. const struct ieee80211_multi_link_elem *mle_b,
  272. struct netlink_ext_ack *extack)
  273. {
  274. const struct ieee80211_mle_basic_common_info *common_a, *common_b;
  275. common_a = (const void *)mle_a->variable;
  276. common_b = (const void *)mle_b->variable;
  277. if (memcmp(common_a->mld_mac_addr, common_b->mld_mac_addr, ETH_ALEN)) {
  278. NL_SET_ERR_MSG(extack, "AP MLD address mismatch");
  279. return -EINVAL;
  280. }
  281. if (ieee80211_mle_get_eml_cap((const u8 *)mle_a) !=
  282. ieee80211_mle_get_eml_cap((const u8 *)mle_b)) {
  283. NL_SET_ERR_MSG(extack, "link EML capabilities mismatch");
  284. return -EINVAL;
  285. }
  286. if (ieee80211_mle_get_mld_capa_op((const u8 *)mle_a) !=
  287. ieee80211_mle_get_mld_capa_op((const u8 *)mle_b)) {
  288. NL_SET_ERR_MSG(extack, "link MLD capabilities/ops mismatch");
  289. return -EINVAL;
  290. }
  291. return 0;
  292. }
  293. static int cfg80211_mlme_check_mlo(struct net_device *dev,
  294. struct cfg80211_assoc_request *req,
  295. struct netlink_ext_ack *extack)
  296. {
  297. const struct ieee80211_multi_link_elem *mles[ARRAY_SIZE(req->links)] = {};
  298. int i;
  299. if (req->link_id < 0)
  300. return 0;
  301. if (!req->links[req->link_id].bss) {
  302. NL_SET_ERR_MSG(extack, "no BSS for assoc link");
  303. return -EINVAL;
  304. }
  305. rcu_read_lock();
  306. for (i = 0; i < ARRAY_SIZE(req->links); i++) {
  307. const struct cfg80211_bss_ies *ies;
  308. const struct element *ml;
  309. if (!req->links[i].bss)
  310. continue;
  311. if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr)) {
  312. NL_SET_ERR_MSG(extack, "BSSID must not be our address");
  313. req->links[i].error = -EINVAL;
  314. goto error;
  315. }
  316. ies = rcu_dereference(req->links[i].bss->ies);
  317. ml = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_MULTI_LINK,
  318. ies->data, ies->len);
  319. if (!ml) {
  320. NL_SET_ERR_MSG(extack, "MLO BSS w/o ML element");
  321. req->links[i].error = -EINVAL;
  322. goto error;
  323. }
  324. if (!ieee80211_mle_type_ok(ml->data + 1,
  325. IEEE80211_ML_CONTROL_TYPE_BASIC,
  326. ml->datalen - 1)) {
  327. NL_SET_ERR_MSG(extack, "BSS with invalid ML element");
  328. req->links[i].error = -EINVAL;
  329. goto error;
  330. }
  331. mles[i] = (const void *)(ml->data + 1);
  332. if (ieee80211_mle_get_link_id((const u8 *)mles[i]) != i) {
  333. NL_SET_ERR_MSG(extack, "link ID mismatch");
  334. req->links[i].error = -EINVAL;
  335. goto error;
  336. }
  337. }
  338. if (WARN_ON(!mles[req->link_id]))
  339. goto error;
  340. for (i = 0; i < ARRAY_SIZE(req->links); i++) {
  341. if (i == req->link_id || !req->links[i].bss)
  342. continue;
  343. if (WARN_ON(!mles[i]))
  344. goto error;
  345. if (cfg80211_mlme_check_mlo_compat(mles[req->link_id], mles[i],
  346. extack)) {
  347. req->links[i].error = -EINVAL;
  348. goto error;
  349. }
  350. }
  351. rcu_read_unlock();
  352. return 0;
  353. error:
  354. rcu_read_unlock();
  355. return -EINVAL;
  356. }
  357. /* Note: caller must cfg80211_put_bss() regardless of result */
  358. int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
  359. struct net_device *dev,
  360. struct cfg80211_assoc_request *req,
  361. struct netlink_ext_ack *extack)
  362. {
  363. struct wireless_dev *wdev = dev->ieee80211_ptr;
  364. int err;
  365. lockdep_assert_wiphy(wdev->wiphy);
  366. err = cfg80211_mlme_check_mlo(dev, req, extack);
  367. if (err)
  368. return err;
  369. if (wdev->connected &&
  370. (!req->prev_bssid ||
  371. !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid)))
  372. return -EALREADY;
  373. if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) ||
  374. (req->link_id >= 0 &&
  375. ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
  376. return -EINVAL;
  377. cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
  378. rdev->wiphy.ht_capa_mod_mask);
  379. cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
  380. rdev->wiphy.vht_capa_mod_mask);
  381. err = rdev_assoc(rdev, dev, req);
  382. if (!err) {
  383. int link_id;
  384. if (req->bss) {
  385. cfg80211_ref_bss(&rdev->wiphy, req->bss);
  386. cfg80211_hold_bss(bss_from_pub(req->bss));
  387. }
  388. for (link_id = 0; link_id < ARRAY_SIZE(req->links); link_id++) {
  389. if (!req->links[link_id].bss)
  390. continue;
  391. cfg80211_ref_bss(&rdev->wiphy, req->links[link_id].bss);
  392. cfg80211_hold_bss(bss_from_pub(req->links[link_id].bss));
  393. }
  394. }
  395. return err;
  396. }
  397. int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
  398. struct net_device *dev, const u8 *bssid,
  399. const u8 *ie, int ie_len, u16 reason,
  400. bool local_state_change)
  401. {
  402. struct wireless_dev *wdev = dev->ieee80211_ptr;
  403. struct cfg80211_deauth_request req = {
  404. .bssid = bssid,
  405. .reason_code = reason,
  406. .ie = ie,
  407. .ie_len = ie_len,
  408. .local_state_change = local_state_change,
  409. };
  410. lockdep_assert_wiphy(wdev->wiphy);
  411. if (local_state_change &&
  412. (!wdev->connected ||
  413. !ether_addr_equal(wdev->u.client.connected_addr, bssid)))
  414. return 0;
  415. if (ether_addr_equal(wdev->disconnect_bssid, bssid) ||
  416. (wdev->connected &&
  417. ether_addr_equal(wdev->u.client.connected_addr, bssid)))
  418. wdev->conn_owner_nlportid = 0;
  419. return rdev_deauth(rdev, dev, &req);
  420. }
  421. int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
  422. struct net_device *dev, const u8 *ap_addr,
  423. const u8 *ie, int ie_len, u16 reason,
  424. bool local_state_change)
  425. {
  426. struct wireless_dev *wdev = dev->ieee80211_ptr;
  427. struct cfg80211_disassoc_request req = {
  428. .reason_code = reason,
  429. .local_state_change = local_state_change,
  430. .ie = ie,
  431. .ie_len = ie_len,
  432. .ap_addr = ap_addr,
  433. };
  434. int err;
  435. lockdep_assert_wiphy(wdev->wiphy);
  436. if (!wdev->connected)
  437. return -ENOTCONN;
  438. if (memcmp(wdev->u.client.connected_addr, ap_addr, ETH_ALEN))
  439. return -ENOTCONN;
  440. err = rdev_disassoc(rdev, dev, &req);
  441. if (err)
  442. return err;
  443. /* driver should have reported the disassoc */
  444. WARN_ON(wdev->connected);
  445. return 0;
  446. }
  447. void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
  448. struct net_device *dev)
  449. {
  450. struct wireless_dev *wdev = dev->ieee80211_ptr;
  451. u8 bssid[ETH_ALEN];
  452. lockdep_assert_wiphy(wdev->wiphy);
  453. if (!rdev->ops->deauth)
  454. return;
  455. if (!wdev->connected)
  456. return;
  457. memcpy(bssid, wdev->u.client.connected_addr, ETH_ALEN);
  458. cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
  459. WLAN_REASON_DEAUTH_LEAVING, false);
  460. }
  461. struct cfg80211_mgmt_registration {
  462. struct list_head list;
  463. struct wireless_dev *wdev;
  464. u32 nlportid;
  465. int match_len;
  466. __le16 frame_type;
  467. bool multicast_rx;
  468. u8 match[];
  469. };
  470. static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
  471. {
  472. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  473. struct wireless_dev *tmp;
  474. struct cfg80211_mgmt_registration *reg;
  475. struct mgmt_frame_regs upd = {};
  476. lockdep_assert_held(&rdev->wiphy.mtx);
  477. spin_lock_bh(&rdev->mgmt_registrations_lock);
  478. if (!wdev->mgmt_registrations_need_update) {
  479. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  480. return;
  481. }
  482. rcu_read_lock();
  483. list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
  484. list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
  485. u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
  486. u32 mcast_mask = 0;
  487. if (reg->multicast_rx)
  488. mcast_mask = mask;
  489. upd.global_stypes |= mask;
  490. upd.global_mcast_stypes |= mcast_mask;
  491. if (tmp == wdev) {
  492. upd.interface_stypes |= mask;
  493. upd.interface_mcast_stypes |= mcast_mask;
  494. }
  495. }
  496. }
  497. rcu_read_unlock();
  498. wdev->mgmt_registrations_need_update = 0;
  499. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  500. rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
  501. }
  502. void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
  503. {
  504. struct cfg80211_registered_device *rdev;
  505. struct wireless_dev *wdev;
  506. rdev = container_of(wk, struct cfg80211_registered_device,
  507. mgmt_registrations_update_wk);
  508. wiphy_lock(&rdev->wiphy);
  509. list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
  510. cfg80211_mgmt_registrations_update(wdev);
  511. wiphy_unlock(&rdev->wiphy);
  512. }
  513. int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
  514. u16 frame_type, const u8 *match_data,
  515. int match_len, bool multicast_rx,
  516. struct netlink_ext_ack *extack)
  517. {
  518. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  519. struct cfg80211_mgmt_registration *reg, *nreg;
  520. int err = 0;
  521. u16 mgmt_type;
  522. bool update_multicast = false;
  523. if (!wdev->wiphy->mgmt_stypes)
  524. return -EOPNOTSUPP;
  525. if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) {
  526. NL_SET_ERR_MSG(extack, "frame type not management");
  527. return -EINVAL;
  528. }
  529. if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) {
  530. NL_SET_ERR_MSG(extack, "Invalid frame type");
  531. return -EINVAL;
  532. }
  533. mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
  534. if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) {
  535. NL_SET_ERR_MSG(extack,
  536. "Registration to specific type not supported");
  537. return -EINVAL;
  538. }
  539. /*
  540. * To support Pre Association Security Negotiation (PASN), registration
  541. * for authentication frames should be supported. However, as some
  542. * versions of the user space daemons wrongly register to all types of
  543. * authentication frames (which might result in unexpected behavior)
  544. * allow such registration if the request is for a specific
  545. * authentication algorithm number.
  546. */
  547. if (wdev->iftype == NL80211_IFTYPE_STATION &&
  548. (frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_AUTH &&
  549. !(match_data && match_len >= 2)) {
  550. NL_SET_ERR_MSG(extack,
  551. "Authentication algorithm number required");
  552. return -EINVAL;
  553. }
  554. nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
  555. if (!nreg)
  556. return -ENOMEM;
  557. spin_lock_bh(&rdev->mgmt_registrations_lock);
  558. list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
  559. int mlen = min(match_len, reg->match_len);
  560. if (frame_type != le16_to_cpu(reg->frame_type))
  561. continue;
  562. if (memcmp(reg->match, match_data, mlen) == 0) {
  563. if (reg->multicast_rx != multicast_rx) {
  564. update_multicast = true;
  565. reg->multicast_rx = multicast_rx;
  566. break;
  567. }
  568. NL_SET_ERR_MSG(extack, "Match already configured");
  569. err = -EALREADY;
  570. break;
  571. }
  572. }
  573. if (err)
  574. goto out;
  575. if (update_multicast) {
  576. kfree(nreg);
  577. } else {
  578. memcpy(nreg->match, match_data, match_len);
  579. nreg->match_len = match_len;
  580. nreg->nlportid = snd_portid;
  581. nreg->frame_type = cpu_to_le16(frame_type);
  582. nreg->wdev = wdev;
  583. nreg->multicast_rx = multicast_rx;
  584. list_add(&nreg->list, &wdev->mgmt_registrations);
  585. }
  586. wdev->mgmt_registrations_need_update = 1;
  587. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  588. cfg80211_mgmt_registrations_update(wdev);
  589. return 0;
  590. out:
  591. kfree(nreg);
  592. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  593. return err;
  594. }
  595. void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
  596. {
  597. struct wiphy *wiphy = wdev->wiphy;
  598. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  599. struct cfg80211_mgmt_registration *reg, *tmp;
  600. spin_lock_bh(&rdev->mgmt_registrations_lock);
  601. list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
  602. if (reg->nlportid != nlportid)
  603. continue;
  604. list_del(&reg->list);
  605. kfree(reg);
  606. wdev->mgmt_registrations_need_update = 1;
  607. schedule_work(&rdev->mgmt_registrations_update_wk);
  608. }
  609. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  610. if (nlportid && rdev->crit_proto_nlportid == nlportid) {
  611. rdev->crit_proto_nlportid = 0;
  612. rdev_crit_proto_stop(rdev, wdev);
  613. }
  614. if (nlportid == wdev->ap_unexpected_nlportid)
  615. wdev->ap_unexpected_nlportid = 0;
  616. }
  617. void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
  618. {
  619. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
  620. struct cfg80211_mgmt_registration *reg, *tmp;
  621. spin_lock_bh(&rdev->mgmt_registrations_lock);
  622. list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
  623. list_del(&reg->list);
  624. kfree(reg);
  625. }
  626. wdev->mgmt_registrations_need_update = 1;
  627. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  628. cfg80211_mgmt_registrations_update(wdev);
  629. }
  630. static bool cfg80211_allowed_address(struct wireless_dev *wdev, const u8 *addr)
  631. {
  632. int i;
  633. for_each_valid_link(wdev, i) {
  634. if (ether_addr_equal(addr, wdev->links[i].addr))
  635. return true;
  636. }
  637. return ether_addr_equal(addr, wdev_address(wdev));
  638. }
  639. static bool cfg80211_allowed_random_address(struct wireless_dev *wdev,
  640. const struct ieee80211_mgmt *mgmt)
  641. {
  642. if (ieee80211_is_auth(mgmt->frame_control) ||
  643. ieee80211_is_deauth(mgmt->frame_control)) {
  644. /* Allow random TA to be used with authentication and
  645. * deauthentication frames if the driver has indicated support.
  646. */
  647. if (wiphy_ext_feature_isset(
  648. wdev->wiphy,
  649. NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA))
  650. return true;
  651. } else if (ieee80211_is_action(mgmt->frame_control) &&
  652. mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
  653. /* Allow random TA to be used with Public Action frames if the
  654. * driver has indicated support.
  655. */
  656. if (!wdev->connected &&
  657. wiphy_ext_feature_isset(
  658. wdev->wiphy,
  659. NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
  660. return true;
  661. if (wdev->connected &&
  662. wiphy_ext_feature_isset(
  663. wdev->wiphy,
  664. NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
  665. return true;
  666. }
  667. return false;
  668. }
  669. int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
  670. struct wireless_dev *wdev,
  671. struct cfg80211_mgmt_tx_params *params, u64 *cookie)
  672. {
  673. const struct ieee80211_mgmt *mgmt;
  674. u16 stype;
  675. lockdep_assert_wiphy(&rdev->wiphy);
  676. if (!wdev->wiphy->mgmt_stypes)
  677. return -EOPNOTSUPP;
  678. if (!rdev->ops->mgmt_tx)
  679. return -EOPNOTSUPP;
  680. if (params->len < 24 + 1)
  681. return -EINVAL;
  682. mgmt = (const struct ieee80211_mgmt *)params->buf;
  683. if (!ieee80211_is_mgmt(mgmt->frame_control) ||
  684. ieee80211_has_order(mgmt->frame_control))
  685. return -EINVAL;
  686. stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
  687. if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
  688. return -EINVAL;
  689. if (ieee80211_is_action(mgmt->frame_control) &&
  690. mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
  691. int err = 0;
  692. switch (wdev->iftype) {
  693. case NL80211_IFTYPE_ADHOC:
  694. /*
  695. * check for IBSS DA must be done by driver as
  696. * cfg80211 doesn't track the stations
  697. */
  698. if (!wdev->u.ibss.current_bss ||
  699. !ether_addr_equal(wdev->u.ibss.current_bss->pub.bssid,
  700. mgmt->bssid)) {
  701. err = -ENOTCONN;
  702. break;
  703. }
  704. break;
  705. case NL80211_IFTYPE_STATION:
  706. case NL80211_IFTYPE_P2P_CLIENT:
  707. if (!wdev->connected) {
  708. err = -ENOTCONN;
  709. break;
  710. }
  711. /* FIXME: MLD may address this differently */
  712. if (!ether_addr_equal(wdev->u.client.connected_addr,
  713. mgmt->bssid)) {
  714. err = -ENOTCONN;
  715. break;
  716. }
  717. /* for station, check that DA is the AP */
  718. if (!ether_addr_equal(wdev->u.client.connected_addr,
  719. mgmt->da)) {
  720. err = -ENOTCONN;
  721. break;
  722. }
  723. break;
  724. case NL80211_IFTYPE_AP:
  725. case NL80211_IFTYPE_P2P_GO:
  726. case NL80211_IFTYPE_AP_VLAN:
  727. if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)) &&
  728. (params->link_id < 0 ||
  729. !ether_addr_equal(mgmt->bssid,
  730. wdev->links[params->link_id].addr)))
  731. err = -EINVAL;
  732. break;
  733. case NL80211_IFTYPE_MESH_POINT:
  734. if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
  735. err = -EINVAL;
  736. break;
  737. }
  738. /*
  739. * check for mesh DA must be done by driver as
  740. * cfg80211 doesn't track the stations
  741. */
  742. break;
  743. case NL80211_IFTYPE_P2P_DEVICE:
  744. /*
  745. * fall through, P2P device only supports
  746. * public action frames
  747. */
  748. case NL80211_IFTYPE_NAN:
  749. default:
  750. err = -EOPNOTSUPP;
  751. break;
  752. }
  753. if (err)
  754. return err;
  755. }
  756. if (!cfg80211_allowed_address(wdev, mgmt->sa) &&
  757. !cfg80211_allowed_random_address(wdev, mgmt))
  758. return -EINVAL;
  759. /* Transmit the management frame as requested by user space */
  760. return rdev_mgmt_tx(rdev, wdev, params, cookie);
  761. }
  762. bool cfg80211_rx_mgmt_ext(struct wireless_dev *wdev,
  763. struct cfg80211_rx_info *info)
  764. {
  765. struct wiphy *wiphy = wdev->wiphy;
  766. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  767. struct cfg80211_mgmt_registration *reg;
  768. const struct ieee80211_txrx_stypes *stypes =
  769. &wiphy->mgmt_stypes[wdev->iftype];
  770. struct ieee80211_mgmt *mgmt = (void *)info->buf;
  771. const u8 *data;
  772. int data_len;
  773. bool result = false;
  774. __le16 ftype = mgmt->frame_control &
  775. cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
  776. u16 stype;
  777. trace_cfg80211_rx_mgmt(wdev, info);
  778. stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
  779. if (!(stypes->rx & BIT(stype))) {
  780. trace_cfg80211_return_bool(false);
  781. return false;
  782. }
  783. data = info->buf + ieee80211_hdrlen(mgmt->frame_control);
  784. data_len = info->len - ieee80211_hdrlen(mgmt->frame_control);
  785. spin_lock_bh(&rdev->mgmt_registrations_lock);
  786. list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
  787. if (reg->frame_type != ftype)
  788. continue;
  789. if (reg->match_len > data_len)
  790. continue;
  791. if (memcmp(reg->match, data, reg->match_len))
  792. continue;
  793. /* found match! */
  794. /* Indicate the received Action frame to user space */
  795. if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, info,
  796. GFP_ATOMIC))
  797. continue;
  798. result = true;
  799. break;
  800. }
  801. spin_unlock_bh(&rdev->mgmt_registrations_lock);
  802. trace_cfg80211_return_bool(result);
  803. return result;
  804. }
  805. EXPORT_SYMBOL(cfg80211_rx_mgmt_ext);
  806. void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
  807. {
  808. cancel_delayed_work(&rdev->dfs_update_channels_wk);
  809. queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk, 0);
  810. }
  811. void cfg80211_dfs_channels_update_work(struct work_struct *work)
  812. {
  813. struct delayed_work *delayed_work = to_delayed_work(work);
  814. struct cfg80211_registered_device *rdev;
  815. struct cfg80211_chan_def chandef;
  816. struct ieee80211_supported_band *sband;
  817. struct ieee80211_channel *c;
  818. struct wiphy *wiphy;
  819. bool check_again = false;
  820. unsigned long timeout, next_time = 0;
  821. unsigned long time_dfs_update;
  822. enum nl80211_radar_event radar_event;
  823. int bandid, i;
  824. rdev = container_of(delayed_work, struct cfg80211_registered_device,
  825. dfs_update_channels_wk);
  826. wiphy = &rdev->wiphy;
  827. rtnl_lock();
  828. for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
  829. sband = wiphy->bands[bandid];
  830. if (!sband)
  831. continue;
  832. for (i = 0; i < sband->n_channels; i++) {
  833. c = &sband->channels[i];
  834. if (!(c->flags & IEEE80211_CHAN_RADAR))
  835. continue;
  836. if (c->dfs_state != NL80211_DFS_UNAVAILABLE &&
  837. c->dfs_state != NL80211_DFS_AVAILABLE)
  838. continue;
  839. if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
  840. time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
  841. radar_event = NL80211_RADAR_NOP_FINISHED;
  842. } else {
  843. if (regulatory_pre_cac_allowed(wiphy) ||
  844. cfg80211_any_wiphy_oper_chan(wiphy, c))
  845. continue;
  846. time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
  847. radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
  848. }
  849. timeout = c->dfs_state_entered +
  850. msecs_to_jiffies(time_dfs_update);
  851. if (time_after_eq(jiffies, timeout)) {
  852. c->dfs_state = NL80211_DFS_USABLE;
  853. c->dfs_state_entered = jiffies;
  854. cfg80211_chandef_create(&chandef, c,
  855. NL80211_CHAN_NO_HT);
  856. nl80211_radar_notify(rdev, &chandef,
  857. radar_event, NULL,
  858. GFP_ATOMIC);
  859. regulatory_propagate_dfs_state(wiphy, &chandef,
  860. c->dfs_state,
  861. radar_event);
  862. continue;
  863. }
  864. if (!check_again)
  865. next_time = timeout - jiffies;
  866. else
  867. next_time = min(next_time, timeout - jiffies);
  868. check_again = true;
  869. }
  870. }
  871. rtnl_unlock();
  872. /* reschedule if there are other channels waiting to be cleared again */
  873. if (check_again)
  874. queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
  875. next_time);
  876. }
  877. void __cfg80211_radar_event(struct wiphy *wiphy,
  878. struct cfg80211_chan_def *chandef,
  879. bool offchan, gfp_t gfp)
  880. {
  881. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  882. trace_cfg80211_radar_event(wiphy, chandef, offchan);
  883. /* only set the chandef supplied channel to unavailable, in
  884. * case the radar is detected on only one of multiple channels
  885. * spanned by the chandef.
  886. */
  887. cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
  888. if (offchan)
  889. queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
  890. cfg80211_sched_dfs_chan_update(rdev);
  891. nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
  892. memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
  893. queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
  894. }
  895. EXPORT_SYMBOL(__cfg80211_radar_event);
  896. void cfg80211_cac_event(struct net_device *netdev,
  897. const struct cfg80211_chan_def *chandef,
  898. enum nl80211_radar_event event, gfp_t gfp,
  899. unsigned int link_id)
  900. {
  901. struct wireless_dev *wdev = netdev->ieee80211_ptr;
  902. struct wiphy *wiphy = wdev->wiphy;
  903. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  904. unsigned long timeout;
  905. if (WARN_ON(wdev->valid_links &&
  906. !(wdev->valid_links & BIT(link_id))))
  907. return;
  908. trace_cfg80211_cac_event(netdev, event, link_id);
  909. if (WARN_ON(!wdev->links[link_id].cac_started &&
  910. event != NL80211_RADAR_CAC_STARTED))
  911. return;
  912. switch (event) {
  913. case NL80211_RADAR_CAC_FINISHED:
  914. timeout = wdev->links[link_id].cac_start_time +
  915. msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
  916. WARN_ON(!time_after_eq(jiffies, timeout));
  917. cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
  918. memcpy(&rdev->cac_done_chandef, chandef,
  919. sizeof(struct cfg80211_chan_def));
  920. queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
  921. cfg80211_sched_dfs_chan_update(rdev);
  922. fallthrough;
  923. case NL80211_RADAR_CAC_ABORTED:
  924. wdev->links[link_id].cac_started = false;
  925. break;
  926. case NL80211_RADAR_CAC_STARTED:
  927. wdev->links[link_id].cac_started = true;
  928. break;
  929. default:
  930. WARN_ON(1);
  931. return;
  932. }
  933. nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
  934. }
  935. EXPORT_SYMBOL(cfg80211_cac_event);
  936. static void
  937. __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  938. struct wireless_dev *wdev,
  939. const struct cfg80211_chan_def *chandef,
  940. enum nl80211_radar_event event)
  941. {
  942. struct wiphy *wiphy = &rdev->wiphy;
  943. struct net_device *netdev;
  944. lockdep_assert_wiphy(&rdev->wiphy);
  945. if (!cfg80211_chandef_valid(chandef))
  946. return;
  947. if (!rdev->background_radar_wdev)
  948. return;
  949. switch (event) {
  950. case NL80211_RADAR_CAC_FINISHED:
  951. cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
  952. memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
  953. queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
  954. cfg80211_sched_dfs_chan_update(rdev);
  955. wdev = rdev->background_radar_wdev;
  956. break;
  957. case NL80211_RADAR_CAC_ABORTED:
  958. if (!cancel_delayed_work(&rdev->background_cac_done_wk))
  959. return;
  960. wdev = rdev->background_radar_wdev;
  961. break;
  962. case NL80211_RADAR_CAC_STARTED:
  963. break;
  964. default:
  965. return;
  966. }
  967. netdev = wdev ? wdev->netdev : NULL;
  968. nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
  969. }
  970. static void
  971. cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  972. const struct cfg80211_chan_def *chandef,
  973. enum nl80211_radar_event event)
  974. {
  975. wiphy_lock(&rdev->wiphy);
  976. __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
  977. chandef, event);
  978. wiphy_unlock(&rdev->wiphy);
  979. }
  980. void cfg80211_background_cac_done_wk(struct work_struct *work)
  981. {
  982. struct delayed_work *delayed_work = to_delayed_work(work);
  983. struct cfg80211_registered_device *rdev;
  984. rdev = container_of(delayed_work, struct cfg80211_registered_device,
  985. background_cac_done_wk);
  986. cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
  987. NL80211_RADAR_CAC_FINISHED);
  988. }
  989. void cfg80211_background_cac_abort_wk(struct work_struct *work)
  990. {
  991. struct cfg80211_registered_device *rdev;
  992. rdev = container_of(work, struct cfg80211_registered_device,
  993. background_cac_abort_wk);
  994. cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
  995. NL80211_RADAR_CAC_ABORTED);
  996. }
  997. void cfg80211_background_cac_abort(struct wiphy *wiphy)
  998. {
  999. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  1000. queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
  1001. }
  1002. EXPORT_SYMBOL(cfg80211_background_cac_abort);
  1003. int
  1004. cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev,
  1005. struct wireless_dev *wdev,
  1006. struct cfg80211_chan_def *chandef)
  1007. {
  1008. unsigned int cac_time_ms;
  1009. int err;
  1010. lockdep_assert_wiphy(&rdev->wiphy);
  1011. if (!wiphy_ext_feature_isset(&rdev->wiphy,
  1012. NL80211_EXT_FEATURE_RADAR_BACKGROUND))
  1013. return -EOPNOTSUPP;
  1014. /* Offchannel chain already locked by another wdev */
  1015. if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev)
  1016. return -EBUSY;
  1017. /* CAC already in progress on the offchannel chain */
  1018. if (rdev->background_radar_wdev == wdev &&
  1019. delayed_work_pending(&rdev->background_cac_done_wk))
  1020. return -EBUSY;
  1021. err = rdev_set_radar_background(rdev, chandef);
  1022. if (err)
  1023. return err;
  1024. cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef);
  1025. if (!cac_time_ms)
  1026. cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
  1027. rdev->background_radar_chandef = *chandef;
  1028. rdev->background_radar_wdev = wdev; /* Get offchain ownership */
  1029. __cfg80211_background_cac_event(rdev, wdev, chandef,
  1030. NL80211_RADAR_CAC_STARTED);
  1031. queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk,
  1032. msecs_to_jiffies(cac_time_ms));
  1033. return 0;
  1034. }
  1035. void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
  1036. {
  1037. struct wiphy *wiphy = wdev->wiphy;
  1038. struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  1039. lockdep_assert_wiphy(wiphy);
  1040. if (wdev != rdev->background_radar_wdev)
  1041. return;
  1042. rdev_set_radar_background(rdev, NULL);
  1043. rdev->background_radar_wdev = NULL; /* Release offchain ownership */
  1044. __cfg80211_background_cac_event(rdev, wdev,
  1045. &rdev->background_radar_chandef,
  1046. NL80211_RADAR_CAC_ABORTED);
  1047. }