event.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /*
  2. * Copyright (c) 2015-2016 Quantenna Communications, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <linux/slab.h>
  19. #include "cfg80211.h"
  20. #include "core.h"
  21. #include "qlink.h"
  22. #include "bus.h"
  23. #include "trans.h"
  24. #include "util.h"
  25. #include "event.h"
  26. #include "qlink_util.h"
  27. static int
  28. qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
  29. const struct qlink_event_sta_assoc *sta_assoc,
  30. u16 len)
  31. {
  32. const u8 *sta_addr;
  33. u16 frame_control;
  34. struct station_info *sinfo;
  35. size_t payload_len;
  36. u16 tlv_type;
  37. u16 tlv_value_len;
  38. size_t tlv_full_len;
  39. const struct qlink_tlv_hdr *tlv;
  40. int ret = 0;
  41. if (unlikely(len < sizeof(*sta_assoc))) {
  42. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  43. mac->macid, vif->vifid, len, sizeof(*sta_assoc));
  44. return -EINVAL;
  45. }
  46. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  47. pr_err("VIF%u.%u: STA_ASSOC event when not in AP mode\n",
  48. mac->macid, vif->vifid);
  49. return -EPROTO;
  50. }
  51. sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
  52. if (!sinfo)
  53. return -ENOMEM;
  54. sta_addr = sta_assoc->sta_addr;
  55. frame_control = le16_to_cpu(sta_assoc->frame_control);
  56. pr_debug("VIF%u.%u: MAC:%pM FC:%x\n", mac->macid, vif->vifid, sta_addr,
  57. frame_control);
  58. qtnf_sta_list_add(vif, sta_addr);
  59. sinfo->assoc_req_ies = NULL;
  60. sinfo->assoc_req_ies_len = 0;
  61. sinfo->generation = vif->generation;
  62. payload_len = len - sizeof(*sta_assoc);
  63. tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies;
  64. while (payload_len >= sizeof(*tlv)) {
  65. tlv_type = le16_to_cpu(tlv->type);
  66. tlv_value_len = le16_to_cpu(tlv->len);
  67. tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
  68. if (tlv_full_len > payload_len) {
  69. ret = -EINVAL;
  70. goto out;
  71. }
  72. if (tlv_type == QTN_TLV_ID_IE_SET) {
  73. const struct qlink_tlv_ie_set *ie_set;
  74. unsigned int ie_len;
  75. if (payload_len < sizeof(*ie_set)) {
  76. ret = -EINVAL;
  77. goto out;
  78. }
  79. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  80. ie_len = tlv_value_len -
  81. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  82. if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
  83. sinfo->assoc_req_ies = ie_set->ie_data;
  84. sinfo->assoc_req_ies_len = ie_len;
  85. }
  86. }
  87. payload_len -= tlv_full_len;
  88. tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
  89. }
  90. if (payload_len) {
  91. ret = -EINVAL;
  92. goto out;
  93. }
  94. cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, sinfo,
  95. GFP_KERNEL);
  96. out:
  97. kfree(sinfo);
  98. return ret;
  99. }
  100. static int
  101. qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif,
  102. const struct qlink_event_sta_deauth *sta_deauth,
  103. u16 len)
  104. {
  105. const u8 *sta_addr;
  106. u16 reason;
  107. if (unlikely(len < sizeof(*sta_deauth))) {
  108. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  109. mac->macid, vif->vifid, len,
  110. sizeof(struct qlink_event_sta_deauth));
  111. return -EINVAL;
  112. }
  113. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  114. pr_err("VIF%u.%u: STA_DEAUTH event when not in AP mode\n",
  115. mac->macid, vif->vifid);
  116. return -EPROTO;
  117. }
  118. sta_addr = sta_deauth->sta_addr;
  119. reason = le16_to_cpu(sta_deauth->reason);
  120. pr_debug("VIF%u.%u: MAC:%pM reason:%x\n", mac->macid, vif->vifid,
  121. sta_addr, reason);
  122. if (qtnf_sta_list_del(vif, sta_addr))
  123. cfg80211_del_sta(vif->netdev, sta_deauth->sta_addr,
  124. GFP_KERNEL);
  125. return 0;
  126. }
  127. static int
  128. qtnf_event_handle_bss_join(struct qtnf_vif *vif,
  129. const struct qlink_event_bss_join *join_info,
  130. u16 len)
  131. {
  132. if (unlikely(len < sizeof(*join_info))) {
  133. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  134. vif->mac->macid, vif->vifid, len,
  135. sizeof(struct qlink_event_bss_join));
  136. return -EINVAL;
  137. }
  138. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  139. pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n",
  140. vif->mac->macid, vif->vifid);
  141. return -EPROTO;
  142. }
  143. if (vif->sta_state != QTNF_STA_CONNECTING) {
  144. pr_err("VIF%u.%u: BSS_JOIN event when STA is not connecting\n",
  145. vif->mac->macid, vif->vifid);
  146. return -EPROTO;
  147. }
  148. pr_debug("VIF%u.%u: BSSID:%pM\n", vif->mac->macid, vif->vifid,
  149. join_info->bssid);
  150. cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, NULL,
  151. 0, le16_to_cpu(join_info->status), GFP_KERNEL);
  152. if (le16_to_cpu(join_info->status) == WLAN_STATUS_SUCCESS) {
  153. vif->sta_state = QTNF_STA_CONNECTED;
  154. netif_carrier_on(vif->netdev);
  155. } else {
  156. vif->sta_state = QTNF_STA_DISCONNECTED;
  157. }
  158. return 0;
  159. }
  160. static int
  161. qtnf_event_handle_bss_leave(struct qtnf_vif *vif,
  162. const struct qlink_event_bss_leave *leave_info,
  163. u16 len)
  164. {
  165. if (unlikely(len < sizeof(*leave_info))) {
  166. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  167. vif->mac->macid, vif->vifid, len,
  168. sizeof(struct qlink_event_bss_leave));
  169. return -EINVAL;
  170. }
  171. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  172. pr_err("VIF%u.%u: BSS_LEAVE event when not in STA mode\n",
  173. vif->mac->macid, vif->vifid);
  174. return -EPROTO;
  175. }
  176. if (vif->sta_state != QTNF_STA_CONNECTED)
  177. pr_warn("VIF%u.%u: BSS_LEAVE event when STA is not connected\n",
  178. vif->mac->macid, vif->vifid);
  179. pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);
  180. cfg80211_disconnected(vif->netdev, le16_to_cpu(leave_info->reason),
  181. NULL, 0, 0, GFP_KERNEL);
  182. vif->sta_state = QTNF_STA_DISCONNECTED;
  183. netif_carrier_off(vif->netdev);
  184. return 0;
  185. }
  186. static int
  187. qtnf_event_handle_mgmt_received(struct qtnf_vif *vif,
  188. const struct qlink_event_rxmgmt *rxmgmt,
  189. u16 len)
  190. {
  191. const size_t min_len = sizeof(*rxmgmt) +
  192. sizeof(struct ieee80211_hdr_3addr);
  193. const struct ieee80211_hdr_3addr *frame = (void *)rxmgmt->frame_data;
  194. const u16 frame_len = len - sizeof(*rxmgmt);
  195. enum nl80211_rxmgmt_flags flags = 0;
  196. if (unlikely(len < min_len)) {
  197. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  198. vif->mac->macid, vif->vifid, len, min_len);
  199. return -EINVAL;
  200. }
  201. if (le32_to_cpu(rxmgmt->flags) & QLINK_RXMGMT_FLAG_ANSWERED)
  202. flags |= NL80211_RXMGMT_FLAG_ANSWERED;
  203. pr_debug("%s LEN:%u FC:%.4X SA:%pM\n", vif->netdev->name, frame_len,
  204. le16_to_cpu(frame->frame_control), frame->addr2);
  205. cfg80211_rx_mgmt(&vif->wdev, le32_to_cpu(rxmgmt->freq), rxmgmt->sig_dbm,
  206. rxmgmt->frame_data, frame_len, flags);
  207. return 0;
  208. }
  209. static int
  210. qtnf_event_handle_scan_results(struct qtnf_vif *vif,
  211. const struct qlink_event_scan_result *sr,
  212. u16 len)
  213. {
  214. struct cfg80211_bss *bss;
  215. struct ieee80211_channel *channel;
  216. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  217. enum cfg80211_bss_frame_type frame_type = CFG80211_BSS_FTYPE_UNKNOWN;
  218. size_t payload_len;
  219. u16 tlv_type;
  220. u16 tlv_value_len;
  221. size_t tlv_full_len;
  222. const struct qlink_tlv_hdr *tlv;
  223. const u8 *ies = NULL;
  224. size_t ies_len = 0;
  225. if (len < sizeof(*sr)) {
  226. pr_err("VIF%u.%u: payload is too short\n", vif->mac->macid,
  227. vif->vifid);
  228. return -EINVAL;
  229. }
  230. channel = ieee80211_get_channel(wiphy, le16_to_cpu(sr->freq));
  231. if (!channel) {
  232. pr_err("VIF%u.%u: channel at %u MHz not found\n",
  233. vif->mac->macid, vif->vifid, le16_to_cpu(sr->freq));
  234. return -EINVAL;
  235. }
  236. payload_len = len - sizeof(*sr);
  237. tlv = (struct qlink_tlv_hdr *)sr->payload;
  238. while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
  239. tlv_type = le16_to_cpu(tlv->type);
  240. tlv_value_len = le16_to_cpu(tlv->len);
  241. tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
  242. if (tlv_full_len > payload_len)
  243. return -EINVAL;
  244. if (tlv_type == QTN_TLV_ID_IE_SET) {
  245. const struct qlink_tlv_ie_set *ie_set;
  246. unsigned int ie_len;
  247. if (payload_len < sizeof(*ie_set))
  248. return -EINVAL;
  249. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  250. ie_len = tlv_value_len -
  251. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  252. switch (ie_set->type) {
  253. case QLINK_IE_SET_BEACON_IES:
  254. frame_type = CFG80211_BSS_FTYPE_BEACON;
  255. break;
  256. case QLINK_IE_SET_PROBE_RESP_IES:
  257. frame_type = CFG80211_BSS_FTYPE_PRESP;
  258. break;
  259. default:
  260. frame_type = CFG80211_BSS_FTYPE_UNKNOWN;
  261. }
  262. if (ie_len) {
  263. ies = ie_set->ie_data;
  264. ies_len = ie_len;
  265. }
  266. }
  267. payload_len -= tlv_full_len;
  268. tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
  269. }
  270. if (payload_len)
  271. return -EINVAL;
  272. bss = cfg80211_inform_bss(wiphy, channel, frame_type,
  273. sr->bssid, get_unaligned_le64(&sr->tsf),
  274. le16_to_cpu(sr->capab),
  275. le16_to_cpu(sr->bintval), ies, ies_len,
  276. DBM_TO_MBM(sr->sig_dbm), GFP_KERNEL);
  277. if (!bss)
  278. return -ENOMEM;
  279. cfg80211_put_bss(wiphy, bss);
  280. return 0;
  281. }
  282. static int
  283. qtnf_event_handle_scan_complete(struct qtnf_wmac *mac,
  284. const struct qlink_event_scan_complete *status,
  285. u16 len)
  286. {
  287. if (len < sizeof(*status)) {
  288. pr_err("MAC%u: payload is too short\n", mac->macid);
  289. return -EINVAL;
  290. }
  291. qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED);
  292. return 0;
  293. }
  294. static int
  295. qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
  296. const struct qlink_event_freq_change *data,
  297. u16 len)
  298. {
  299. struct wiphy *wiphy = priv_to_wiphy(mac);
  300. struct cfg80211_chan_def chandef;
  301. struct qtnf_vif *vif;
  302. int i;
  303. if (len < sizeof(*data)) {
  304. pr_err("MAC%u: payload is too short\n", mac->macid);
  305. return -EINVAL;
  306. }
  307. if (!wiphy->registered)
  308. return 0;
  309. qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
  310. if (!cfg80211_chandef_valid(&chandef)) {
  311. pr_err("MAC%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
  312. mac->macid, chandef.chan->center_freq,
  313. chandef.center_freq1, chandef.center_freq2,
  314. chandef.width);
  315. return -EINVAL;
  316. }
  317. pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
  318. mac->macid, chandef.chan->hw_value, chandef.center_freq1,
  319. chandef.center_freq2, chandef.width);
  320. for (i = 0; i < QTNF_MAX_INTF; i++) {
  321. vif = &mac->iflist[i];
  322. if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
  323. continue;
  324. if (vif->netdev) {
  325. mutex_lock(&vif->wdev.mtx);
  326. cfg80211_ch_switch_notify(vif->netdev, &chandef);
  327. mutex_unlock(&vif->wdev.mtx);
  328. }
  329. }
  330. return 0;
  331. }
  332. static int qtnf_event_handle_radar(struct qtnf_vif *vif,
  333. const struct qlink_event_radar *ev,
  334. u16 len)
  335. {
  336. struct wiphy *wiphy = priv_to_wiphy(vif->mac);
  337. struct cfg80211_chan_def chandef;
  338. if (len < sizeof(*ev)) {
  339. pr_err("MAC%u: payload is too short\n", vif->mac->macid);
  340. return -EINVAL;
  341. }
  342. if (!wiphy->registered || !vif->netdev)
  343. return 0;
  344. qlink_chandef_q2cfg(wiphy, &ev->chan, &chandef);
  345. if (!cfg80211_chandef_valid(&chandef)) {
  346. pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n",
  347. vif->mac->macid,
  348. chandef.center_freq1, chandef.center_freq2,
  349. chandef.width);
  350. return -EINVAL;
  351. }
  352. pr_info("%s: radar event=%u f1=%u f2=%u bw=%u\n",
  353. vif->netdev->name, ev->event,
  354. chandef.center_freq1, chandef.center_freq2,
  355. chandef.width);
  356. switch (ev->event) {
  357. case QLINK_RADAR_DETECTED:
  358. cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL);
  359. break;
  360. case QLINK_RADAR_CAC_FINISHED:
  361. if (!vif->wdev.cac_started)
  362. break;
  363. cfg80211_cac_event(vif->netdev, &chandef,
  364. NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
  365. break;
  366. case QLINK_RADAR_CAC_ABORTED:
  367. if (!vif->wdev.cac_started)
  368. break;
  369. cfg80211_cac_event(vif->netdev, &chandef,
  370. NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
  371. break;
  372. case QLINK_RADAR_CAC_STARTED:
  373. if (vif->wdev.cac_started)
  374. break;
  375. if (!wiphy_ext_feature_isset(wiphy,
  376. NL80211_EXT_FEATURE_DFS_OFFLOAD))
  377. break;
  378. cfg80211_cac_event(vif->netdev, &chandef,
  379. NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
  380. break;
  381. default:
  382. pr_warn("%s: unhandled radar event %u\n",
  383. vif->netdev->name, ev->event);
  384. break;
  385. }
  386. return 0;
  387. }
  388. static int qtnf_event_parse(struct qtnf_wmac *mac,
  389. const struct sk_buff *event_skb)
  390. {
  391. const struct qlink_event *event;
  392. struct qtnf_vif *vif = NULL;
  393. int ret = -1;
  394. u16 event_id;
  395. u16 event_len;
  396. event = (const struct qlink_event *)event_skb->data;
  397. event_id = le16_to_cpu(event->event_id);
  398. event_len = le16_to_cpu(event->mhdr.len);
  399. if (likely(event->vifid < QTNF_MAX_INTF)) {
  400. vif = &mac->iflist[event->vifid];
  401. } else {
  402. pr_err("invalid vif(%u)\n", event->vifid);
  403. return -EINVAL;
  404. }
  405. switch (event_id) {
  406. case QLINK_EVENT_STA_ASSOCIATED:
  407. ret = qtnf_event_handle_sta_assoc(mac, vif, (const void *)event,
  408. event_len);
  409. break;
  410. case QLINK_EVENT_STA_DEAUTH:
  411. ret = qtnf_event_handle_sta_deauth(mac, vif,
  412. (const void *)event,
  413. event_len);
  414. break;
  415. case QLINK_EVENT_MGMT_RECEIVED:
  416. ret = qtnf_event_handle_mgmt_received(vif, (const void *)event,
  417. event_len);
  418. break;
  419. case QLINK_EVENT_SCAN_RESULTS:
  420. ret = qtnf_event_handle_scan_results(vif, (const void *)event,
  421. event_len);
  422. break;
  423. case QLINK_EVENT_SCAN_COMPLETE:
  424. ret = qtnf_event_handle_scan_complete(mac, (const void *)event,
  425. event_len);
  426. break;
  427. case QLINK_EVENT_BSS_JOIN:
  428. ret = qtnf_event_handle_bss_join(vif, (const void *)event,
  429. event_len);
  430. break;
  431. case QLINK_EVENT_BSS_LEAVE:
  432. ret = qtnf_event_handle_bss_leave(vif, (const void *)event,
  433. event_len);
  434. break;
  435. case QLINK_EVENT_FREQ_CHANGE:
  436. ret = qtnf_event_handle_freq_change(mac, (const void *)event,
  437. event_len);
  438. break;
  439. case QLINK_EVENT_RADAR:
  440. ret = qtnf_event_handle_radar(vif, (const void *)event,
  441. event_len);
  442. break;
  443. default:
  444. pr_warn("unknown event type: %x\n", event_id);
  445. break;
  446. }
  447. return ret;
  448. }
  449. static int qtnf_event_process_skb(struct qtnf_bus *bus,
  450. const struct sk_buff *skb)
  451. {
  452. const struct qlink_event *event;
  453. struct qtnf_wmac *mac;
  454. int res;
  455. if (unlikely(!skb || skb->len < sizeof(*event))) {
  456. pr_err("invalid event buffer\n");
  457. return -EINVAL;
  458. }
  459. event = (struct qlink_event *)skb->data;
  460. mac = qtnf_core_get_mac(bus, event->macid);
  461. pr_debug("new event id:%x len:%u mac:%u vif:%u\n",
  462. le16_to_cpu(event->event_id), le16_to_cpu(event->mhdr.len),
  463. event->macid, event->vifid);
  464. if (unlikely(!mac))
  465. return -ENXIO;
  466. rtnl_lock();
  467. res = qtnf_event_parse(mac, skb);
  468. rtnl_unlock();
  469. return res;
  470. }
  471. void qtnf_event_work_handler(struct work_struct *work)
  472. {
  473. struct qtnf_bus *bus = container_of(work, struct qtnf_bus, event_work);
  474. struct sk_buff_head *event_queue = &bus->trans.event_queue;
  475. struct sk_buff *current_event_skb = skb_dequeue(event_queue);
  476. while (current_event_skb) {
  477. qtnf_event_process_skb(bus, current_event_skb);
  478. dev_kfree_skb_any(current_event_skb);
  479. current_event_skb = skb_dequeue(event_queue);
  480. }
  481. }