event.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */
  3. #include <linux/kernel.h>
  4. #include <linux/module.h>
  5. #include <linux/slab.h>
  6. #include <linux/nospec.h>
  7. #include "cfg80211.h"
  8. #include "core.h"
  9. #include "qlink.h"
  10. #include "bus.h"
  11. #include "trans.h"
  12. #include "util.h"
  13. #include "event.h"
  14. #include "qlink_util.h"
  15. static int
  16. qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
  17. const struct qlink_event_sta_assoc *sta_assoc,
  18. u16 len)
  19. {
  20. const u8 *sta_addr;
  21. u16 frame_control;
  22. struct station_info *sinfo;
  23. size_t payload_len;
  24. u16 tlv_type;
  25. u16 tlv_value_len;
  26. const struct qlink_tlv_hdr *tlv;
  27. int ret = 0;
  28. if (unlikely(len < sizeof(*sta_assoc))) {
  29. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  30. mac->macid, vif->vifid, len, sizeof(*sta_assoc));
  31. return -EINVAL;
  32. }
  33. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  34. pr_err("VIF%u.%u: STA_ASSOC event when not in AP mode\n",
  35. mac->macid, vif->vifid);
  36. return -EPROTO;
  37. }
  38. sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
  39. if (!sinfo)
  40. return -ENOMEM;
  41. sta_addr = sta_assoc->sta_addr;
  42. frame_control = le16_to_cpu(sta_assoc->frame_control);
  43. pr_debug("VIF%u.%u: MAC:%pM FC:%x\n", mac->macid, vif->vifid, sta_addr,
  44. frame_control);
  45. qtnf_sta_list_add(vif, sta_addr);
  46. sinfo->assoc_req_ies = NULL;
  47. sinfo->assoc_req_ies_len = 0;
  48. sinfo->generation = vif->generation;
  49. payload_len = len - sizeof(*sta_assoc);
  50. qlink_for_each_tlv(tlv, sta_assoc->ies, payload_len) {
  51. tlv_type = le16_to_cpu(tlv->type);
  52. tlv_value_len = le16_to_cpu(tlv->len);
  53. if (tlv_type == QTN_TLV_ID_IE_SET) {
  54. const struct qlink_tlv_ie_set *ie_set;
  55. unsigned int ie_len;
  56. if (tlv_value_len <
  57. (sizeof(*ie_set) - sizeof(ie_set->hdr))) {
  58. ret = -EINVAL;
  59. goto out;
  60. }
  61. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  62. ie_len = tlv_value_len -
  63. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  64. if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
  65. sinfo->assoc_req_ies = ie_set->ie_data;
  66. sinfo->assoc_req_ies_len = ie_len;
  67. }
  68. }
  69. }
  70. if (!qlink_tlv_parsing_ok(tlv, sta_assoc->ies, payload_len)) {
  71. pr_err("Malformed TLV buffer\n");
  72. ret = -EINVAL;
  73. goto out;
  74. }
  75. cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, sinfo,
  76. GFP_KERNEL);
  77. out:
  78. kfree(sinfo);
  79. return ret;
  80. }
  81. static int
  82. qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif,
  83. const struct qlink_event_sta_deauth *sta_deauth,
  84. u16 len)
  85. {
  86. const u8 *sta_addr;
  87. u16 reason;
  88. if (unlikely(len < sizeof(*sta_deauth))) {
  89. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  90. mac->macid, vif->vifid, len,
  91. sizeof(struct qlink_event_sta_deauth));
  92. return -EINVAL;
  93. }
  94. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  95. pr_err("VIF%u.%u: STA_DEAUTH event when not in AP mode\n",
  96. mac->macid, vif->vifid);
  97. return -EPROTO;
  98. }
  99. sta_addr = sta_deauth->sta_addr;
  100. reason = le16_to_cpu(sta_deauth->reason);
  101. pr_debug("VIF%u.%u: MAC:%pM reason:%x\n", mac->macid, vif->vifid,
  102. sta_addr, reason);
  103. if (qtnf_sta_list_del(vif, sta_addr))
  104. cfg80211_del_sta(vif->netdev, sta_deauth->sta_addr,
  105. GFP_KERNEL);
  106. return 0;
  107. }
  108. static int
  109. qtnf_event_handle_bss_join(struct qtnf_vif *vif,
  110. const struct qlink_event_bss_join *join_info,
  111. u16 len)
  112. {
  113. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  114. enum ieee80211_statuscode status = le16_to_cpu(join_info->status);
  115. struct cfg80211_chan_def chandef;
  116. struct cfg80211_bss *bss = NULL;
  117. u8 *ie = NULL;
  118. size_t payload_len;
  119. u16 tlv_type;
  120. u16 tlv_value_len;
  121. const struct qlink_tlv_hdr *tlv;
  122. const u8 *rsp_ies = NULL;
  123. size_t rsp_ies_len = 0;
  124. if (unlikely(len < sizeof(*join_info))) {
  125. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  126. vif->mac->macid, vif->vifid, len,
  127. sizeof(struct qlink_event_bss_join));
  128. return -EINVAL;
  129. }
  130. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  131. pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n",
  132. vif->mac->macid, vif->vifid);
  133. return -EPROTO;
  134. }
  135. pr_debug("VIF%u.%u: BSSID:%pM chan:%u status:%u\n",
  136. vif->mac->macid, vif->vifid, join_info->bssid,
  137. le16_to_cpu(join_info->chan.chan.center_freq), status);
  138. if (status != WLAN_STATUS_SUCCESS)
  139. goto done;
  140. qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef);
  141. if (!cfg80211_chandef_valid(&chandef)) {
  142. pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
  143. vif->mac->macid, vif->vifid,
  144. chandef.chan ? chandef.chan->center_freq : 0,
  145. chandef.center_freq1,
  146. chandef.center_freq2,
  147. chandef.width);
  148. status = WLAN_STATUS_UNSPECIFIED_FAILURE;
  149. goto done;
  150. }
  151. bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid,
  152. NULL, 0, IEEE80211_BSS_TYPE_ESS,
  153. IEEE80211_PRIVACY_ANY);
  154. if (!bss) {
  155. pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n",
  156. vif->mac->macid, vif->vifid,
  157. join_info->bssid, chandef.chan->hw_value);
  158. if (!vif->wdev.u.client.ssid_len) {
  159. pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n",
  160. vif->mac->macid, vif->vifid,
  161. join_info->bssid);
  162. status = WLAN_STATUS_UNSPECIFIED_FAILURE;
  163. goto done;
  164. }
  165. ie = kzalloc(2 + vif->wdev.u.client.ssid_len, GFP_KERNEL);
  166. if (!ie) {
  167. pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n",
  168. vif->mac->macid, vif->vifid,
  169. join_info->bssid);
  170. status = WLAN_STATUS_UNSPECIFIED_FAILURE;
  171. goto done;
  172. }
  173. ie[0] = WLAN_EID_SSID;
  174. ie[1] = vif->wdev.u.client.ssid_len;
  175. memcpy(ie + 2, vif->wdev.u.client.ssid,
  176. vif->wdev.u.client.ssid_len);
  177. bss = cfg80211_inform_bss(wiphy, chandef.chan,
  178. CFG80211_BSS_FTYPE_UNKNOWN,
  179. join_info->bssid, 0,
  180. WLAN_CAPABILITY_ESS, 100,
  181. ie, 2 + vif->wdev.u.client.ssid_len,
  182. 0, GFP_KERNEL);
  183. if (!bss) {
  184. pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n",
  185. vif->mac->macid, vif->vifid,
  186. join_info->bssid);
  187. status = WLAN_STATUS_UNSPECIFIED_FAILURE;
  188. goto done;
  189. }
  190. }
  191. payload_len = len - sizeof(*join_info);
  192. qlink_for_each_tlv(tlv, join_info->ies, payload_len) {
  193. tlv_type = le16_to_cpu(tlv->type);
  194. tlv_value_len = le16_to_cpu(tlv->len);
  195. if (tlv_type == QTN_TLV_ID_IE_SET) {
  196. const struct qlink_tlv_ie_set *ie_set;
  197. unsigned int ie_len;
  198. if (tlv_value_len <
  199. (sizeof(*ie_set) - sizeof(ie_set->hdr))) {
  200. pr_warn("invalid IE_SET TLV\n");
  201. status = WLAN_STATUS_UNSPECIFIED_FAILURE;
  202. goto done;
  203. }
  204. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  205. ie_len = tlv_value_len -
  206. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  207. switch (ie_set->type) {
  208. case QLINK_IE_SET_ASSOC_RESP:
  209. if (ie_len) {
  210. rsp_ies = ie_set->ie_data;
  211. rsp_ies_len = ie_len;
  212. }
  213. break;
  214. default:
  215. pr_warn("unexpected IE type: %u\n",
  216. ie_set->type);
  217. break;
  218. }
  219. }
  220. }
  221. if (!qlink_tlv_parsing_ok(tlv, join_info->ies, payload_len))
  222. pr_warn("Malformed TLV buffer\n");
  223. done:
  224. cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, rsp_ies,
  225. rsp_ies_len, status, GFP_KERNEL);
  226. if (bss) {
  227. if (!ether_addr_equal(vif->bssid, join_info->bssid))
  228. ether_addr_copy(vif->bssid, join_info->bssid);
  229. cfg80211_put_bss(wiphy, bss);
  230. }
  231. if (status == WLAN_STATUS_SUCCESS)
  232. netif_carrier_on(vif->netdev);
  233. kfree(ie);
  234. return 0;
  235. }
  236. static int
  237. qtnf_event_handle_bss_leave(struct qtnf_vif *vif,
  238. const struct qlink_event_bss_leave *leave_info,
  239. u16 len)
  240. {
  241. if (unlikely(len < sizeof(*leave_info))) {
  242. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  243. vif->mac->macid, vif->vifid, len,
  244. sizeof(struct qlink_event_bss_leave));
  245. return -EINVAL;
  246. }
  247. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  248. pr_err("VIF%u.%u: BSS_LEAVE event when not in STA mode\n",
  249. vif->mac->macid, vif->vifid);
  250. return -EPROTO;
  251. }
  252. pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);
  253. cfg80211_disconnected(vif->netdev, le16_to_cpu(leave_info->reason),
  254. NULL, 0, 0, GFP_KERNEL);
  255. netif_carrier_off(vif->netdev);
  256. return 0;
  257. }
  258. static int
  259. qtnf_event_handle_mgmt_received(struct qtnf_vif *vif,
  260. const struct qlink_event_rxmgmt *rxmgmt,
  261. u16 len)
  262. {
  263. const size_t min_len = sizeof(*rxmgmt) +
  264. sizeof(struct ieee80211_hdr_3addr);
  265. const struct ieee80211_hdr_3addr *frame = (void *)rxmgmt->frame_data;
  266. const u16 frame_len = len - sizeof(*rxmgmt);
  267. enum nl80211_rxmgmt_flags flags = 0;
  268. if (unlikely(len < min_len)) {
  269. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  270. vif->mac->macid, vif->vifid, len, min_len);
  271. return -EINVAL;
  272. }
  273. if (le32_to_cpu(rxmgmt->flags) & QLINK_RXMGMT_FLAG_ANSWERED)
  274. flags |= NL80211_RXMGMT_FLAG_ANSWERED;
  275. pr_debug("%s LEN:%u FC:%.4X SA:%pM\n", vif->netdev->name, frame_len,
  276. le16_to_cpu(frame->frame_control), frame->addr2);
  277. cfg80211_rx_mgmt(&vif->wdev, le32_to_cpu(rxmgmt->freq), rxmgmt->sig_dbm,
  278. rxmgmt->frame_data, frame_len, flags);
  279. return 0;
  280. }
  281. static int
  282. qtnf_event_handle_scan_results(struct qtnf_vif *vif,
  283. const struct qlink_event_scan_result *sr,
  284. u16 len)
  285. {
  286. struct cfg80211_bss *bss;
  287. struct ieee80211_channel *channel;
  288. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  289. enum cfg80211_bss_frame_type frame_type = CFG80211_BSS_FTYPE_UNKNOWN;
  290. size_t payload_len;
  291. u16 tlv_type;
  292. u16 tlv_value_len;
  293. const struct qlink_tlv_hdr *tlv;
  294. const u8 *ies = NULL;
  295. size_t ies_len = 0;
  296. if (len < sizeof(*sr)) {
  297. pr_err("VIF%u.%u: payload is too short\n", vif->mac->macid,
  298. vif->vifid);
  299. return -EINVAL;
  300. }
  301. channel = ieee80211_get_channel(wiphy, le16_to_cpu(sr->freq));
  302. if (!channel) {
  303. pr_err("VIF%u.%u: channel at %u MHz not found\n",
  304. vif->mac->macid, vif->vifid, le16_to_cpu(sr->freq));
  305. return -EINVAL;
  306. }
  307. payload_len = len - sizeof(*sr);
  308. qlink_for_each_tlv(tlv, sr->payload, payload_len) {
  309. tlv_type = le16_to_cpu(tlv->type);
  310. tlv_value_len = le16_to_cpu(tlv->len);
  311. if (tlv_type == QTN_TLV_ID_IE_SET) {
  312. const struct qlink_tlv_ie_set *ie_set;
  313. unsigned int ie_len;
  314. if (tlv_value_len <
  315. (sizeof(*ie_set) - sizeof(ie_set->hdr)))
  316. return -EINVAL;
  317. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  318. ie_len = tlv_value_len -
  319. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  320. switch (ie_set->type) {
  321. case QLINK_IE_SET_BEACON_IES:
  322. frame_type = CFG80211_BSS_FTYPE_BEACON;
  323. break;
  324. case QLINK_IE_SET_PROBE_RESP_IES:
  325. frame_type = CFG80211_BSS_FTYPE_PRESP;
  326. break;
  327. default:
  328. frame_type = CFG80211_BSS_FTYPE_UNKNOWN;
  329. }
  330. if (ie_len) {
  331. ies = ie_set->ie_data;
  332. ies_len = ie_len;
  333. }
  334. }
  335. }
  336. if (!qlink_tlv_parsing_ok(tlv, sr->payload, payload_len))
  337. return -EINVAL;
  338. bss = cfg80211_inform_bss(wiphy, channel, frame_type,
  339. sr->bssid, get_unaligned_le64(&sr->tsf),
  340. le16_to_cpu(sr->capab),
  341. le16_to_cpu(sr->bintval), ies, ies_len,
  342. DBM_TO_MBM(sr->sig_dbm), GFP_KERNEL);
  343. if (!bss)
  344. return -ENOMEM;
  345. cfg80211_put_bss(wiphy, bss);
  346. return 0;
  347. }
  348. static int
  349. qtnf_event_handle_scan_complete(struct qtnf_wmac *mac,
  350. const struct qlink_event_scan_complete *status,
  351. u16 len)
  352. {
  353. if (len < sizeof(*status)) {
  354. pr_err("MAC%u: payload is too short\n", mac->macid);
  355. return -EINVAL;
  356. }
  357. qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED);
  358. return 0;
  359. }
  360. static int
  361. qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
  362. const struct qlink_event_freq_change *data,
  363. u16 len)
  364. {
  365. struct wiphy *wiphy = priv_to_wiphy(mac);
  366. struct cfg80211_chan_def chandef;
  367. struct qtnf_vif *vif;
  368. int i;
  369. if (len < sizeof(*data)) {
  370. pr_err("MAC%u: payload is too short\n", mac->macid);
  371. return -EINVAL;
  372. }
  373. if (!wiphy->registered)
  374. return 0;
  375. qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
  376. if (!cfg80211_chandef_valid(&chandef)) {
  377. pr_err("MAC%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
  378. mac->macid, chandef.chan->center_freq,
  379. chandef.center_freq1, chandef.center_freq2,
  380. chandef.width);
  381. return -EINVAL;
  382. }
  383. pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
  384. mac->macid, chandef.chan->hw_value, chandef.center_freq1,
  385. chandef.center_freq2, chandef.width);
  386. for (i = 0; i < QTNF_MAX_INTF; i++) {
  387. vif = &mac->iflist[i];
  388. if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
  389. continue;
  390. if (vif->wdev.iftype == NL80211_IFTYPE_STATION &&
  391. !vif->wdev.connected)
  392. continue;
  393. if (!vif->netdev)
  394. continue;
  395. mutex_lock(&vif->wdev.mtx);
  396. cfg80211_ch_switch_notify(vif->netdev, &chandef, 0, 0);
  397. mutex_unlock(&vif->wdev.mtx);
  398. }
  399. return 0;
  400. }
  401. static int qtnf_event_handle_radar(struct qtnf_vif *vif,
  402. const struct qlink_event_radar *ev,
  403. u16 len)
  404. {
  405. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  406. struct cfg80211_chan_def chandef;
  407. if (len < sizeof(*ev)) {
  408. pr_err("MAC%u: payload is too short\n", vif->mac->macid);
  409. return -EINVAL;
  410. }
  411. if (!wiphy->registered || !vif->netdev)
  412. return 0;
  413. qlink_chandef_q2cfg(wiphy, &ev->chan, &chandef);
  414. if (!cfg80211_chandef_valid(&chandef)) {
  415. pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n",
  416. vif->mac->macid,
  417. chandef.center_freq1, chandef.center_freq2,
  418. chandef.width);
  419. return -EINVAL;
  420. }
  421. pr_info("%s: radar event=%u f1=%u f2=%u bw=%u\n",
  422. vif->netdev->name, ev->event,
  423. chandef.center_freq1, chandef.center_freq2,
  424. chandef.width);
  425. switch (ev->event) {
  426. case QLINK_RADAR_DETECTED:
  427. cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL);
  428. break;
  429. case QLINK_RADAR_CAC_FINISHED:
  430. if (!vif->wdev.cac_started)
  431. break;
  432. cfg80211_cac_event(vif->netdev, &chandef,
  433. NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
  434. break;
  435. case QLINK_RADAR_CAC_ABORTED:
  436. if (!vif->wdev.cac_started)
  437. break;
  438. cfg80211_cac_event(vif->netdev, &chandef,
  439. NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
  440. break;
  441. case QLINK_RADAR_CAC_STARTED:
  442. if (vif->wdev.cac_started)
  443. break;
  444. if (!wiphy_ext_feature_isset(wiphy,
  445. NL80211_EXT_FEATURE_DFS_OFFLOAD))
  446. break;
  447. cfg80211_cac_event(vif->netdev, &chandef,
  448. NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
  449. break;
  450. default:
  451. pr_warn("%s: unhandled radar event %u\n",
  452. vif->netdev->name, ev->event);
  453. break;
  454. }
  455. return 0;
  456. }
  457. static int
  458. qtnf_event_handle_external_auth(struct qtnf_vif *vif,
  459. const struct qlink_event_external_auth *ev,
  460. u16 len)
  461. {
  462. struct cfg80211_external_auth_params auth = {0};
  463. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  464. int ret;
  465. if (len < sizeof(*ev)) {
  466. pr_err("MAC%u: payload is too short\n", vif->mac->macid);
  467. return -EINVAL;
  468. }
  469. if (!wiphy->registered || !vif->netdev)
  470. return 0;
  471. if (ev->ssid_len) {
  472. int len = clamp_val(ev->ssid_len, 0, IEEE80211_MAX_SSID_LEN);
  473. memcpy(auth.ssid.ssid, ev->ssid, len);
  474. auth.ssid.ssid_len = len;
  475. }
  476. auth.key_mgmt_suite = le32_to_cpu(ev->akm_suite);
  477. ether_addr_copy(auth.bssid, ev->bssid);
  478. auth.action = ev->action;
  479. pr_debug("%s: external SAE processing: bss=%pM action=%u akm=%u\n",
  480. vif->netdev->name, auth.bssid, auth.action,
  481. auth.key_mgmt_suite);
  482. ret = cfg80211_external_auth_request(vif->netdev, &auth, GFP_KERNEL);
  483. if (ret)
  484. pr_warn("failed to offload external auth request\n");
  485. return ret;
  486. }
  487. static int
  488. qtnf_event_handle_mic_failure(struct qtnf_vif *vif,
  489. const struct qlink_event_mic_failure *mic_ev,
  490. u16 len)
  491. {
  492. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  493. u8 pairwise;
  494. if (len < sizeof(*mic_ev)) {
  495. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  496. vif->mac->macid, vif->vifid, len,
  497. sizeof(struct qlink_event_mic_failure));
  498. return -EINVAL;
  499. }
  500. if (!wiphy->registered || !vif->netdev)
  501. return 0;
  502. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  503. pr_err("VIF%u.%u: MIC_FAILURE event when not in STA mode\n",
  504. vif->mac->macid, vif->vifid);
  505. return -EPROTO;
  506. }
  507. pairwise = mic_ev->pairwise ?
  508. NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP;
  509. pr_info("%s: MIC error: src=%pM key_index=%u pairwise=%u\n",
  510. vif->netdev->name, mic_ev->src, mic_ev->key_index, pairwise);
  511. cfg80211_michael_mic_failure(vif->netdev, mic_ev->src, pairwise,
  512. mic_ev->key_index, NULL, GFP_KERNEL);
  513. return 0;
  514. }
  515. static int
  516. qtnf_event_handle_update_owe(struct qtnf_vif *vif,
  517. const struct qlink_event_update_owe *owe_ev,
  518. u16 len)
  519. {
  520. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  521. struct cfg80211_update_owe_info owe_info = {};
  522. const u16 ie_len = len - sizeof(*owe_ev);
  523. u8 *ie;
  524. if (len < sizeof(*owe_ev)) {
  525. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  526. vif->mac->macid, vif->vifid, len,
  527. sizeof(struct qlink_event_update_owe));
  528. return -EINVAL;
  529. }
  530. if (!wiphy->registered || !vif->netdev)
  531. return 0;
  532. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  533. pr_err("VIF%u.%u: UPDATE_OWE event when not in AP mode\n",
  534. vif->mac->macid, vif->vifid);
  535. return -EPROTO;
  536. }
  537. ie = kzalloc(ie_len, GFP_KERNEL);
  538. if (!ie)
  539. return -ENOMEM;
  540. memcpy(owe_info.peer, owe_ev->peer, ETH_ALEN);
  541. memcpy(ie, owe_ev->ies, ie_len);
  542. owe_info.ie_len = ie_len;
  543. owe_info.ie = ie;
  544. owe_info.assoc_link_id = -1;
  545. pr_info("%s: external OWE processing: peer=%pM\n",
  546. vif->netdev->name, owe_ev->peer);
  547. cfg80211_update_owe_info_event(vif->netdev, &owe_info, GFP_KERNEL);
  548. kfree(ie);
  549. return 0;
  550. }
  551. static int qtnf_event_parse(struct qtnf_wmac *mac,
  552. const struct sk_buff *event_skb)
  553. {
  554. const struct qlink_event *event;
  555. struct qtnf_vif *vif = NULL;
  556. int ret = -1;
  557. u16 event_id;
  558. u16 event_len;
  559. u8 vifid;
  560. event = (const struct qlink_event *)event_skb->data;
  561. event_id = le16_to_cpu(event->event_id);
  562. event_len = le16_to_cpu(event->mhdr.len);
  563. if (event->vifid >= QTNF_MAX_INTF) {
  564. pr_err("invalid vif(%u)\n", event->vifid);
  565. return -EINVAL;
  566. }
  567. vifid = array_index_nospec(event->vifid, QTNF_MAX_INTF);
  568. vif = &mac->iflist[vifid];
  569. switch (event_id) {
  570. case QLINK_EVENT_STA_ASSOCIATED:
  571. ret = qtnf_event_handle_sta_assoc(mac, vif, (const void *)event,
  572. event_len);
  573. break;
  574. case QLINK_EVENT_STA_DEAUTH:
  575. ret = qtnf_event_handle_sta_deauth(mac, vif,
  576. (const void *)event,
  577. event_len);
  578. break;
  579. case QLINK_EVENT_MGMT_RECEIVED:
  580. ret = qtnf_event_handle_mgmt_received(vif, (const void *)event,
  581. event_len);
  582. break;
  583. case QLINK_EVENT_SCAN_RESULTS:
  584. ret = qtnf_event_handle_scan_results(vif, (const void *)event,
  585. event_len);
  586. break;
  587. case QLINK_EVENT_SCAN_COMPLETE:
  588. ret = qtnf_event_handle_scan_complete(mac, (const void *)event,
  589. event_len);
  590. break;
  591. case QLINK_EVENT_BSS_JOIN:
  592. ret = qtnf_event_handle_bss_join(vif, (const void *)event,
  593. event_len);
  594. break;
  595. case QLINK_EVENT_BSS_LEAVE:
  596. ret = qtnf_event_handle_bss_leave(vif, (const void *)event,
  597. event_len);
  598. break;
  599. case QLINK_EVENT_FREQ_CHANGE:
  600. ret = qtnf_event_handle_freq_change(mac, (const void *)event,
  601. event_len);
  602. break;
  603. case QLINK_EVENT_RADAR:
  604. ret = qtnf_event_handle_radar(vif, (const void *)event,
  605. event_len);
  606. break;
  607. case QLINK_EVENT_EXTERNAL_AUTH:
  608. ret = qtnf_event_handle_external_auth(vif, (const void *)event,
  609. event_len);
  610. break;
  611. case QLINK_EVENT_MIC_FAILURE:
  612. ret = qtnf_event_handle_mic_failure(vif, (const void *)event,
  613. event_len);
  614. break;
  615. case QLINK_EVENT_UPDATE_OWE:
  616. ret = qtnf_event_handle_update_owe(vif, (const void *)event,
  617. event_len);
  618. break;
  619. default:
  620. pr_warn("unknown event type: %x\n", event_id);
  621. break;
  622. }
  623. return ret;
  624. }
  625. static int qtnf_event_process_skb(struct qtnf_bus *bus,
  626. const struct sk_buff *skb)
  627. {
  628. const struct qlink_event *event;
  629. struct qtnf_wmac *mac;
  630. int res;
  631. if (unlikely(!skb || skb->len < sizeof(*event))) {
  632. pr_err("invalid event buffer\n");
  633. return -EINVAL;
  634. }
  635. event = (struct qlink_event *)skb->data;
  636. mac = qtnf_core_get_mac(bus, event->macid);
  637. pr_debug("new event id:%x len:%u mac:%u vif:%u\n",
  638. le16_to_cpu(event->event_id), le16_to_cpu(event->mhdr.len),
  639. event->macid, event->vifid);
  640. if (unlikely(!mac))
  641. return -ENXIO;
  642. rtnl_lock();
  643. res = qtnf_event_parse(mac, skb);
  644. rtnl_unlock();
  645. return res;
  646. }
  647. void qtnf_event_work_handler(struct work_struct *work)
  648. {
  649. struct qtnf_bus *bus = container_of(work, struct qtnf_bus, event_work);
  650. struct sk_buff_head *event_queue = &bus->trans.event_queue;
  651. struct sk_buff *current_event_skb = skb_dequeue(event_queue);
  652. while (current_event_skb) {
  653. qtnf_event_process_skb(bus, current_event_skb);
  654. dev_kfree_skb_any(current_event_skb);
  655. current_event_skb = skb_dequeue(event_queue);
  656. }
  657. }