event.c 13 KB

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