event.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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_list, sta_addr);
  55. sinfo.assoc_req_ies = NULL;
  56. sinfo.assoc_req_ies_len = 0;
  57. payload_len = len - sizeof(*sta_assoc);
  58. tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies;
  59. while (payload_len >= sizeof(*tlv)) {
  60. tlv_type = le16_to_cpu(tlv->type);
  61. tlv_value_len = le16_to_cpu(tlv->len);
  62. tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
  63. if (tlv_full_len > payload_len)
  64. return -EINVAL;
  65. if (tlv_type == QTN_TLV_ID_IE_SET) {
  66. const struct qlink_tlv_ie_set *ie_set;
  67. unsigned int ie_len;
  68. if (payload_len < sizeof(*ie_set))
  69. return -EINVAL;
  70. ie_set = (const struct qlink_tlv_ie_set *)tlv;
  71. ie_len = tlv_value_len -
  72. (sizeof(*ie_set) - sizeof(ie_set->hdr));
  73. if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
  74. sinfo.assoc_req_ies = ie_set->ie_data;
  75. sinfo.assoc_req_ies_len = ie_len;
  76. }
  77. }
  78. payload_len -= tlv_full_len;
  79. tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
  80. }
  81. if (payload_len)
  82. return -EINVAL;
  83. cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo,
  84. GFP_KERNEL);
  85. return 0;
  86. }
  87. static int
  88. qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif,
  89. const struct qlink_event_sta_deauth *sta_deauth,
  90. u16 len)
  91. {
  92. const u8 *sta_addr;
  93. u16 reason;
  94. if (unlikely(len < sizeof(*sta_deauth))) {
  95. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  96. mac->macid, vif->vifid, len,
  97. sizeof(struct qlink_event_sta_deauth));
  98. return -EINVAL;
  99. }
  100. if (vif->wdev.iftype != NL80211_IFTYPE_AP) {
  101. pr_err("VIF%u.%u: STA_DEAUTH event when not in AP mode\n",
  102. mac->macid, vif->vifid);
  103. return -EPROTO;
  104. }
  105. sta_addr = sta_deauth->sta_addr;
  106. reason = le16_to_cpu(sta_deauth->reason);
  107. pr_debug("VIF%u.%u: MAC:%pM reason:%x\n", mac->macid, vif->vifid,
  108. sta_addr, reason);
  109. if (qtnf_sta_list_del(&vif->sta_list, sta_addr))
  110. cfg80211_del_sta(vif->netdev, sta_deauth->sta_addr,
  111. GFP_KERNEL);
  112. return 0;
  113. }
  114. static int
  115. qtnf_event_handle_bss_join(struct qtnf_vif *vif,
  116. const struct qlink_event_bss_join *join_info,
  117. u16 len)
  118. {
  119. if (unlikely(len < sizeof(*join_info))) {
  120. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  121. vif->mac->macid, vif->vifid, len,
  122. sizeof(struct qlink_event_bss_join));
  123. return -EINVAL;
  124. }
  125. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  126. pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n",
  127. vif->mac->macid, vif->vifid);
  128. return -EPROTO;
  129. }
  130. if (vif->sta_state != QTNF_STA_CONNECTING) {
  131. pr_err("VIF%u.%u: BSS_JOIN event when STA is not connecting\n",
  132. vif->mac->macid, vif->vifid);
  133. return -EPROTO;
  134. }
  135. pr_debug("VIF%u.%u: BSSID:%pM\n", vif->mac->macid, vif->vifid,
  136. join_info->bssid);
  137. cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, NULL,
  138. 0, le16_to_cpu(join_info->status), GFP_KERNEL);
  139. if (le16_to_cpu(join_info->status) == WLAN_STATUS_SUCCESS) {
  140. vif->sta_state = QTNF_STA_CONNECTED;
  141. netif_carrier_on(vif->netdev);
  142. } else {
  143. vif->sta_state = QTNF_STA_DISCONNECTED;
  144. }
  145. return 0;
  146. }
  147. static int
  148. qtnf_event_handle_bss_leave(struct qtnf_vif *vif,
  149. const struct qlink_event_bss_leave *leave_info,
  150. u16 len)
  151. {
  152. if (unlikely(len < sizeof(*leave_info))) {
  153. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  154. vif->mac->macid, vif->vifid, len,
  155. sizeof(struct qlink_event_bss_leave));
  156. return -EINVAL;
  157. }
  158. if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
  159. pr_err("VIF%u.%u: BSS_LEAVE event when not in STA mode\n",
  160. vif->mac->macid, vif->vifid);
  161. return -EPROTO;
  162. }
  163. if (vif->sta_state != QTNF_STA_CONNECTED) {
  164. pr_err("VIF%u.%u: BSS_LEAVE event when STA is not connected\n",
  165. vif->mac->macid, vif->vifid);
  166. return -EPROTO;
  167. }
  168. pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);
  169. cfg80211_disconnected(vif->netdev, le16_to_cpu(leave_info->reason),
  170. NULL, 0, 0, GFP_KERNEL);
  171. vif->sta_state = QTNF_STA_DISCONNECTED;
  172. netif_carrier_off(vif->netdev);
  173. return 0;
  174. }
  175. static int
  176. qtnf_event_handle_mgmt_received(struct qtnf_vif *vif,
  177. const struct qlink_event_rxmgmt *rxmgmt,
  178. u16 len)
  179. {
  180. const size_t min_len = sizeof(*rxmgmt) +
  181. sizeof(struct ieee80211_hdr_3addr);
  182. const struct ieee80211_hdr_3addr *frame = (void *)rxmgmt->frame_data;
  183. const u16 frame_len = len - sizeof(*rxmgmt);
  184. enum nl80211_rxmgmt_flags flags = 0;
  185. if (unlikely(len < min_len)) {
  186. pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
  187. vif->mac->macid, vif->vifid, len, min_len);
  188. return -EINVAL;
  189. }
  190. if (le32_to_cpu(rxmgmt->flags) & QLINK_RXMGMT_FLAG_ANSWERED)
  191. flags |= NL80211_RXMGMT_FLAG_ANSWERED;
  192. pr_debug("%s LEN:%u FC:%.4X SA:%pM\n", vif->netdev->name, frame_len,
  193. le16_to_cpu(frame->frame_control), frame->addr2);
  194. cfg80211_rx_mgmt(&vif->wdev, le32_to_cpu(rxmgmt->freq),
  195. le32_to_cpu(rxmgmt->sig_dbm), rxmgmt->frame_data,
  196. 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. sr->signal, 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 f1=%u f2=%u bw=%u\n", mac->macid,
  302. chandef.center_freq1, chandef.center_freq2,
  303. chandef.width);
  304. return -EINVAL;
  305. }
  306. pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
  307. mac->macid, chandef.chan->hw_value, chandef.center_freq1,
  308. chandef.center_freq2, chandef.width);
  309. for (i = 0; i < QTNF_MAX_INTF; i++) {
  310. vif = &mac->iflist[i];
  311. if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
  312. continue;
  313. if (vif->netdev) {
  314. mutex_lock(&vif->wdev.mtx);
  315. cfg80211_ch_switch_notify(vif->netdev, &chandef);
  316. mutex_unlock(&vif->wdev.mtx);
  317. }
  318. }
  319. return 0;
  320. }
  321. static int qtnf_event_parse(struct qtnf_wmac *mac,
  322. const struct sk_buff *event_skb)
  323. {
  324. const struct qlink_event *event;
  325. struct qtnf_vif *vif = NULL;
  326. int ret = -1;
  327. u16 event_id;
  328. u16 event_len;
  329. event = (const struct qlink_event *)event_skb->data;
  330. event_id = le16_to_cpu(event->event_id);
  331. event_len = le16_to_cpu(event->mhdr.len);
  332. if (likely(event->vifid < QTNF_MAX_INTF)) {
  333. vif = &mac->iflist[event->vifid];
  334. } else {
  335. pr_err("invalid vif(%u)\n", event->vifid);
  336. return -EINVAL;
  337. }
  338. switch (event_id) {
  339. case QLINK_EVENT_STA_ASSOCIATED:
  340. ret = qtnf_event_handle_sta_assoc(mac, vif, (const void *)event,
  341. event_len);
  342. break;
  343. case QLINK_EVENT_STA_DEAUTH:
  344. ret = qtnf_event_handle_sta_deauth(mac, vif,
  345. (const void *)event,
  346. event_len);
  347. break;
  348. case QLINK_EVENT_MGMT_RECEIVED:
  349. ret = qtnf_event_handle_mgmt_received(vif, (const void *)event,
  350. event_len);
  351. break;
  352. case QLINK_EVENT_SCAN_RESULTS:
  353. ret = qtnf_event_handle_scan_results(vif, (const void *)event,
  354. event_len);
  355. break;
  356. case QLINK_EVENT_SCAN_COMPLETE:
  357. ret = qtnf_event_handle_scan_complete(mac, (const void *)event,
  358. event_len);
  359. break;
  360. case QLINK_EVENT_BSS_JOIN:
  361. ret = qtnf_event_handle_bss_join(vif, (const void *)event,
  362. event_len);
  363. break;
  364. case QLINK_EVENT_BSS_LEAVE:
  365. ret = qtnf_event_handle_bss_leave(vif, (const void *)event,
  366. event_len);
  367. break;
  368. case QLINK_EVENT_FREQ_CHANGE:
  369. ret = qtnf_event_handle_freq_change(mac, (const void *)event,
  370. event_len);
  371. break;
  372. default:
  373. pr_warn("unknown event type: %x\n", event_id);
  374. break;
  375. }
  376. return ret;
  377. }
  378. static int qtnf_event_process_skb(struct qtnf_bus *bus,
  379. const struct sk_buff *skb)
  380. {
  381. const struct qlink_event *event;
  382. struct qtnf_wmac *mac;
  383. int res;
  384. if (unlikely(!skb || skb->len < sizeof(*event))) {
  385. pr_err("invalid event buffer\n");
  386. return -EINVAL;
  387. }
  388. event = (struct qlink_event *)skb->data;
  389. mac = qtnf_core_get_mac(bus, event->macid);
  390. pr_debug("new event id:%x len:%u mac:%u vif:%u\n",
  391. le16_to_cpu(event->event_id), le16_to_cpu(event->mhdr.len),
  392. event->macid, event->vifid);
  393. if (unlikely(!mac))
  394. return -ENXIO;
  395. qtnf_bus_lock(bus);
  396. res = qtnf_event_parse(mac, skb);
  397. qtnf_bus_unlock(bus);
  398. return res;
  399. }
  400. void qtnf_event_work_handler(struct work_struct *work)
  401. {
  402. struct qtnf_bus *bus = container_of(work, struct qtnf_bus, event_work);
  403. struct sk_buff_head *event_queue = &bus->trans.event_queue;
  404. struct sk_buff *current_event_skb = skb_dequeue(event_queue);
  405. while (current_event_skb) {
  406. qtnf_event_process_skb(bus, current_event_skb);
  407. dev_kfree_skb_any(current_event_skb);
  408. current_event_skb = skb_dequeue(event_queue);
  409. }
  410. }