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