event.c 14 KB

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