1 // SPDX-License-Identifier: GPL-2.0
2 /* IEEE 802.11 SoftMAC layer
3  * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
4  *
5  * Mostly extracted from the rtl8180-sa2400 driver for the
6  * in-kernel generic ieee802.11 stack.
7  *
8  * Some pieces of code might be stolen from ipw2100 driver
9  * copyright of who own it's copyright ;-)
10  *
11  * PS wx handler mostly stolen from hostap, copyright who
12  * own it's copyright ;-)
13  */
14 #include <linux/etherdevice.h>
15 
16 #include "rtllib.h"
17 #include "dot11d.h"
18 /* FIXME: add A freqs */
19 
20 const long rtllib_wlan_frequencies[] = {
21 	2412, 2417, 2422, 2427,
22 	2432, 2437, 2442, 2447,
23 	2452, 2457, 2462, 2467,
24 	2472, 2484
25 };
26 EXPORT_SYMBOL(rtllib_wlan_frequencies);
27 
28 
29 int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
30 			     union iwreq_data *wrqu, char *b)
31 {
32 	int ret;
33 	struct iw_freq *fwrq = &wrqu->freq;
34 
35 	mutex_lock(&ieee->wx_mutex);
36 
37 	if (ieee->iw_mode == IW_MODE_INFRA) {
38 		ret = 0;
39 		goto out;
40 	}
41 
42 	/* if setting by freq convert to channel */
43 	if (fwrq->e == 1) {
44 		if ((fwrq->m >= (int)2.412e8 &&
45 		     fwrq->m <= (int)2.487e8)) {
46 			int f = fwrq->m / 100000;
47 			int c = 0;
48 
49 			while ((c < 14) && (f != rtllib_wlan_frequencies[c]))
50 				c++;
51 
52 			/* hack to fall through */
53 			fwrq->e = 0;
54 			fwrq->m = c + 1;
55 		}
56 	}
57 
58 	if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
59 		ret = -EOPNOTSUPP;
60 		goto out;
61 
62 	} else { /* Set the channel */
63 
64 		if (ieee->active_channel_map[fwrq->m] != 1) {
65 			ret = -EINVAL;
66 			goto out;
67 		}
68 		ieee->current_network.channel = fwrq->m;
69 		ieee->set_chan(ieee->dev, ieee->current_network.channel);
70 
71 		if (ieee->iw_mode == IW_MODE_ADHOC ||
72 		    ieee->iw_mode == IW_MODE_MASTER)
73 			if (ieee->state == RTLLIB_LINKED) {
74 				rtllib_stop_send_beacons(ieee);
75 				rtllib_start_send_beacons(ieee);
76 			}
77 	}
78 
79 	ret = 0;
80 out:
81 	mutex_unlock(&ieee->wx_mutex);
82 	return ret;
83 }
84 EXPORT_SYMBOL(rtllib_wx_set_freq);
85 
86 
87 int rtllib_wx_get_freq(struct rtllib_device *ieee,
88 			     struct iw_request_info *a,
89 			     union iwreq_data *wrqu, char *b)
90 {
91 	struct iw_freq *fwrq = &wrqu->freq;
92 
93 	if (ieee->current_network.channel == 0)
94 		return -1;
95 	fwrq->m = rtllib_wlan_frequencies[ieee->current_network.channel-1] *
96 		  100000;
97 	fwrq->e = 1;
98 	return 0;
99 }
100 EXPORT_SYMBOL(rtllib_wx_get_freq);
101 
102 int rtllib_wx_get_wap(struct rtllib_device *ieee,
103 			    struct iw_request_info *info,
104 			    union iwreq_data *wrqu, char *extra)
105 {
106 	unsigned long flags;
107 
108 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
109 
110 	if (ieee->iw_mode == IW_MODE_MONITOR)
111 		return -1;
112 
113 	/* We want avoid to give to the user inconsistent infos*/
114 	spin_lock_irqsave(&ieee->lock, flags);
115 
116 	if (ieee->state != RTLLIB_LINKED &&
117 		ieee->state != RTLLIB_LINKED_SCANNING &&
118 		ieee->wap_set == 0)
119 
120 		eth_zero_addr(wrqu->ap_addr.sa_data);
121 	else
122 		memcpy(wrqu->ap_addr.sa_data,
123 		       ieee->current_network.bssid, ETH_ALEN);
124 
125 	spin_unlock_irqrestore(&ieee->lock, flags);
126 
127 	return 0;
128 }
129 EXPORT_SYMBOL(rtllib_wx_get_wap);
130 
131 
132 int rtllib_wx_set_wap(struct rtllib_device *ieee,
133 			 struct iw_request_info *info,
134 			 union iwreq_data *awrq,
135 			 char *extra)
136 {
137 
138 	int ret = 0;
139 	unsigned long flags;
140 
141 	short ifup = ieee->proto_started;
142 	struct sockaddr *temp = (struct sockaddr *)awrq;
143 
144 	rtllib_stop_scan_syncro(ieee);
145 
146 	mutex_lock(&ieee->wx_mutex);
147 	/* use ifconfig hw ether */
148 	if (ieee->iw_mode == IW_MODE_MASTER) {
149 		ret = -1;
150 		goto out;
151 	}
152 
153 	if (temp->sa_family != ARPHRD_ETHER) {
154 		ret = -EINVAL;
155 		goto out;
156 	}
157 
158 	if (is_zero_ether_addr(temp->sa_data)) {
159 		spin_lock_irqsave(&ieee->lock, flags);
160 		ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
161 		ieee->wap_set = 0;
162 		spin_unlock_irqrestore(&ieee->lock, flags);
163 		ret = -1;
164 		goto out;
165 	}
166 
167 
168 	if (ifup)
169 		rtllib_stop_protocol(ieee, true);
170 
171 	/* just to avoid to give inconsistent infos in the
172 	 * get wx method. not really needed otherwise
173 	 */
174 	spin_lock_irqsave(&ieee->lock, flags);
175 
176 	ieee->cannot_notify = false;
177 	ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
178 	ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
179 
180 	spin_unlock_irqrestore(&ieee->lock, flags);
181 
182 	if (ifup)
183 		rtllib_start_protocol(ieee);
184 out:
185 	mutex_unlock(&ieee->wx_mutex);
186 	return ret;
187 }
188 EXPORT_SYMBOL(rtllib_wx_set_wap);
189 
190 int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
191 			 union iwreq_data *wrqu, char *b)
192 {
193 	int len, ret = 0;
194 	unsigned long flags;
195 
196 	if (ieee->iw_mode == IW_MODE_MONITOR)
197 		return -1;
198 
199 	/* We want avoid to give to the user inconsistent infos*/
200 	spin_lock_irqsave(&ieee->lock, flags);
201 
202 	if (ieee->current_network.ssid[0] == '\0' ||
203 		ieee->current_network.ssid_len == 0) {
204 		ret = -1;
205 		goto out;
206 	}
207 
208 	if (ieee->state != RTLLIB_LINKED &&
209 		ieee->state != RTLLIB_LINKED_SCANNING &&
210 		ieee->ssid_set == 0) {
211 		ret = -1;
212 		goto out;
213 	}
214 	len = ieee->current_network.ssid_len;
215 	wrqu->essid.length = len;
216 	strncpy(b, ieee->current_network.ssid, len);
217 	wrqu->essid.flags = 1;
218 
219 out:
220 	spin_unlock_irqrestore(&ieee->lock, flags);
221 
222 	return ret;
223 
224 }
225 EXPORT_SYMBOL(rtllib_wx_get_essid);
226 
227 int rtllib_wx_set_rate(struct rtllib_device *ieee,
228 			     struct iw_request_info *info,
229 			     union iwreq_data *wrqu, char *extra)
230 {
231 
232 	u32 target_rate = wrqu->bitrate.value;
233 
234 	ieee->rate = target_rate/100000;
235 	return 0;
236 }
237 EXPORT_SYMBOL(rtllib_wx_set_rate);
238 
239 int rtllib_wx_get_rate(struct rtllib_device *ieee,
240 			     struct iw_request_info *info,
241 			     union iwreq_data *wrqu, char *extra)
242 {
243 	u32 tmp_rate;
244 
245 	tmp_rate = TxCountToDataRate(ieee,
246 				     ieee->softmac_stats.CurrentShowTxate);
247 	wrqu->bitrate.value = tmp_rate * 500000;
248 
249 	return 0;
250 }
251 EXPORT_SYMBOL(rtllib_wx_get_rate);
252 
253 
254 int rtllib_wx_set_rts(struct rtllib_device *ieee,
255 			     struct iw_request_info *info,
256 			     union iwreq_data *wrqu, char *extra)
257 {
258 	if (wrqu->rts.disabled || !wrqu->rts.fixed)
259 		ieee->rts = DEFAULT_RTS_THRESHOLD;
260 	else {
261 		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
262 				wrqu->rts.value > MAX_RTS_THRESHOLD)
263 			return -EINVAL;
264 		ieee->rts = wrqu->rts.value;
265 	}
266 	return 0;
267 }
268 EXPORT_SYMBOL(rtllib_wx_set_rts);
269 
270 int rtllib_wx_get_rts(struct rtllib_device *ieee,
271 			     struct iw_request_info *info,
272 			     union iwreq_data *wrqu, char *extra)
273 {
274 	wrqu->rts.value = ieee->rts;
275 	wrqu->rts.fixed = 0;	/* no auto select */
276 	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
277 	return 0;
278 }
279 EXPORT_SYMBOL(rtllib_wx_get_rts);
280 
281 int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
282 			     union iwreq_data *wrqu, char *b)
283 {
284 	int set_mode_status = 0;
285 
286 	rtllib_stop_scan_syncro(ieee);
287 	mutex_lock(&ieee->wx_mutex);
288 	switch (wrqu->mode) {
289 	case IW_MODE_MONITOR:
290 	case IW_MODE_ADHOC:
291 	case IW_MODE_INFRA:
292 		break;
293 	case IW_MODE_AUTO:
294 		wrqu->mode = IW_MODE_INFRA;
295 		break;
296 	default:
297 		set_mode_status = -EINVAL;
298 		goto out;
299 	}
300 
301 	if (wrqu->mode == ieee->iw_mode)
302 		goto out;
303 
304 	if (wrqu->mode == IW_MODE_MONITOR) {
305 		ieee->dev->type = ARPHRD_IEEE80211;
306 		rtllib_EnableNetMonitorMode(ieee->dev, false);
307 	} else {
308 		ieee->dev->type = ARPHRD_ETHER;
309 		if (ieee->iw_mode == IW_MODE_MONITOR)
310 			rtllib_DisableNetMonitorMode(ieee->dev, false);
311 	}
312 
313 	if (!ieee->proto_started) {
314 		ieee->iw_mode = wrqu->mode;
315 	} else {
316 		rtllib_stop_protocol(ieee, true);
317 		ieee->iw_mode = wrqu->mode;
318 		rtllib_start_protocol(ieee);
319 	}
320 
321 out:
322 	mutex_unlock(&ieee->wx_mutex);
323 	return set_mode_status;
324 }
325 EXPORT_SYMBOL(rtllib_wx_set_mode);
326 
327 void rtllib_wx_sync_scan_wq(void *data)
328 {
329 	struct rtllib_device *ieee = container_of_work_rsl(data,
330 				     struct rtllib_device, wx_sync_scan_wq);
331 	short chan;
332 	enum ht_extchnl_offset chan_offset = 0;
333 	enum ht_channel_width bandwidth = 0;
334 	int b40M = 0;
335 
336 	if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
337 		rtllib_start_scan_syncro(ieee, 0);
338 		goto out;
339 	}
340 
341 	chan = ieee->current_network.channel;
342 
343 	ieee->LeisurePSLeave(ieee->dev);
344 	/* notify AP to be in PS mode */
345 	rtllib_sta_ps_send_null_frame(ieee, 1);
346 	rtllib_sta_ps_send_null_frame(ieee, 1);
347 
348 	rtllib_stop_all_queues(ieee);
349 
350 	if (ieee->data_hard_stop)
351 		ieee->data_hard_stop(ieee->dev);
352 	rtllib_stop_send_beacons(ieee);
353 	ieee->state = RTLLIB_LINKED_SCANNING;
354 	ieee->link_change(ieee->dev);
355 	/* wait for ps packet to be kicked out successfully */
356 	msleep(50);
357 
358 	if (ieee->ScanOperationBackupHandler)
359 		ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
360 
361 	if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht &&
362 	    ieee->ht_info->bCurBW40MHz) {
363 		b40M = 1;
364 		chan_offset = ieee->ht_info->CurSTAExtChnlOffset;
365 		bandwidth = (enum ht_channel_width)ieee->ht_info->bCurBW40MHz;
366 		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20,
367 				       HT_EXTCHNL_OFFSET_NO_EXT);
368 	}
369 
370 	rtllib_start_scan_syncro(ieee, 0);
371 
372 	if (b40M) {
373 		if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
374 			ieee->set_chan(ieee->dev, chan + 2);
375 		else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
376 			ieee->set_chan(ieee->dev, chan - 2);
377 		else
378 			ieee->set_chan(ieee->dev, chan);
379 		ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
380 	} else {
381 		ieee->set_chan(ieee->dev, chan);
382 	}
383 
384 	if (ieee->ScanOperationBackupHandler)
385 		ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE);
386 
387 	ieee->state = RTLLIB_LINKED;
388 	ieee->link_change(ieee->dev);
389 
390 	/* Notify AP that I wake up again */
391 	rtllib_sta_ps_send_null_frame(ieee, 0);
392 
393 	if (ieee->link_detect_info.NumRecvBcnInPeriod == 0 ||
394 	    ieee->link_detect_info.NumRecvDataInPeriod == 0) {
395 		ieee->link_detect_info.NumRecvBcnInPeriod = 1;
396 		ieee->link_detect_info.NumRecvDataInPeriod = 1;
397 	}
398 
399 	if (ieee->data_hard_resume)
400 		ieee->data_hard_resume(ieee->dev);
401 
402 	if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
403 		rtllib_start_send_beacons(ieee);
404 
405 	rtllib_wake_all_queues(ieee);
406 
407 out:
408 	mutex_unlock(&ieee->wx_mutex);
409 
410 }
411 
412 int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
413 			     union iwreq_data *wrqu, char *b)
414 {
415 	int ret = 0;
416 
417 	mutex_lock(&ieee->wx_mutex);
418 
419 	if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
420 		ret = -1;
421 		goto out;
422 	}
423 
424 	if (ieee->state == RTLLIB_LINKED) {
425 		schedule_work(&ieee->wx_sync_scan_wq);
426 		/* intentionally forget to up sem */
427 		return 0;
428 	}
429 
430 out:
431 	mutex_unlock(&ieee->wx_mutex);
432 	return ret;
433 }
434 EXPORT_SYMBOL(rtllib_wx_set_scan);
435 
436 int rtllib_wx_set_essid(struct rtllib_device *ieee,
437 			struct iw_request_info *a,
438 			union iwreq_data *wrqu, char *extra)
439 {
440 
441 	int ret = 0, len;
442 	short proto_started;
443 	unsigned long flags;
444 
445 	rtllib_stop_scan_syncro(ieee);
446 	mutex_lock(&ieee->wx_mutex);
447 
448 	proto_started = ieee->proto_started;
449 
450 	len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE);
451 
452 	if (ieee->iw_mode == IW_MODE_MONITOR) {
453 		ret = -1;
454 		goto out;
455 	}
456 
457 	if (proto_started)
458 		rtllib_stop_protocol(ieee, true);
459 
460 
461 	/* this is just to be sure that the GET wx callback
462 	 * has consistent infos. not needed otherwise
463 	 */
464 	spin_lock_irqsave(&ieee->lock, flags);
465 
466 	if (wrqu->essid.flags && wrqu->essid.length) {
467 		strncpy(ieee->current_network.ssid, extra, len);
468 		ieee->current_network.ssid_len = len;
469 		ieee->cannot_notify = false;
470 		ieee->ssid_set = 1;
471 	} else {
472 		ieee->ssid_set = 0;
473 		ieee->current_network.ssid[0] = '\0';
474 		ieee->current_network.ssid_len = 0;
475 	}
476 	spin_unlock_irqrestore(&ieee->lock, flags);
477 
478 	if (proto_started)
479 		rtllib_start_protocol(ieee);
480 out:
481 	mutex_unlock(&ieee->wx_mutex);
482 	return ret;
483 }
484 EXPORT_SYMBOL(rtllib_wx_set_essid);
485 
486 int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
487 		       union iwreq_data *wrqu, char *b)
488 {
489 	wrqu->mode = ieee->iw_mode;
490 	return 0;
491 }
492 EXPORT_SYMBOL(rtllib_wx_get_mode);
493 
494 int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
495 			struct iw_request_info *info,
496 			union iwreq_data *wrqu, char *extra)
497 {
498 
499 	int *parms = (int *)extra;
500 	int enable = (parms[0] > 0);
501 	short prev = ieee->raw_tx;
502 
503 	mutex_lock(&ieee->wx_mutex);
504 
505 	if (enable)
506 		ieee->raw_tx = 1;
507 	else
508 		ieee->raw_tx = 0;
509 
510 	netdev_info(ieee->dev, "raw TX is %s\n",
511 		    ieee->raw_tx ? "enabled" : "disabled");
512 
513 	if (ieee->iw_mode == IW_MODE_MONITOR) {
514 		if (prev == 0 && ieee->raw_tx) {
515 			if (ieee->data_hard_resume)
516 				ieee->data_hard_resume(ieee->dev);
517 
518 			netif_carrier_on(ieee->dev);
519 		}
520 
521 		if (prev && ieee->raw_tx == 1)
522 			netif_carrier_off(ieee->dev);
523 	}
524 
525 	mutex_unlock(&ieee->wx_mutex);
526 
527 	return 0;
528 }
529 EXPORT_SYMBOL(rtllib_wx_set_rawtx);
530 
531 int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
532 		       union iwreq_data *wrqu, char *extra)
533 {
534 	const char *b = ieee->modulation & RTLLIB_CCK_MODULATION ? "b" : "";
535 	const char *g = ieee->modulation & RTLLIB_OFDM_MODULATION ? "g" : "";
536 	const char *n = ieee->mode & (IEEE_N_24G | IEEE_N_5G) ? "n" : "";
537 
538 	scnprintf(wrqu->name, sizeof(wrqu->name), "802.11%s%s%s", b, g, n);
539 	return 0;
540 }
541 EXPORT_SYMBOL(rtllib_wx_get_name);
542 
543 
544 /* this is mostly stolen from hostap */
545 int rtllib_wx_set_power(struct rtllib_device *ieee,
546 				 struct iw_request_info *info,
547 				 union iwreq_data *wrqu, char *extra)
548 {
549 	int ret = 0;
550 
551 	if ((!ieee->sta_wake_up) ||
552 	    (!ieee->enter_sleep_state) ||
553 	    (!ieee->ps_is_queue_empty)) {
554 		netdev_warn(ieee->dev,
555 			    "%s(): PS mode is tried to be use but driver missed a callback\n",
556 			    __func__);
557 		return -1;
558 	}
559 
560 	mutex_lock(&ieee->wx_mutex);
561 
562 	if (wrqu->power.disabled) {
563 		ieee->ps = RTLLIB_PS_DISABLED;
564 		goto exit;
565 	}
566 	if (wrqu->power.flags & IW_POWER_TIMEOUT)
567 		ieee->ps_timeout = wrqu->power.value / 1000;
568 
569 	if (wrqu->power.flags & IW_POWER_PERIOD)
570 		ieee->ps_period = wrqu->power.value / 1000;
571 
572 	switch (wrqu->power.flags & IW_POWER_MODE) {
573 	case IW_POWER_UNICAST_R:
574 		ieee->ps = RTLLIB_PS_UNICAST;
575 		break;
576 	case IW_POWER_MULTICAST_R:
577 		ieee->ps = RTLLIB_PS_MBCAST;
578 		break;
579 	case IW_POWER_ALL_R:
580 		ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;
581 		break;
582 
583 	case IW_POWER_ON:
584 		break;
585 
586 	default:
587 		ret = -EINVAL;
588 		goto exit;
589 
590 	}
591 exit:
592 	mutex_unlock(&ieee->wx_mutex);
593 	return ret;
594 
595 }
596 EXPORT_SYMBOL(rtllib_wx_set_power);
597 
598 /* this is stolen from hostap */
599 int rtllib_wx_get_power(struct rtllib_device *ieee,
600 				 struct iw_request_info *info,
601 				 union iwreq_data *wrqu, char *extra)
602 {
603 	mutex_lock(&ieee->wx_mutex);
604 
605 	if (ieee->ps == RTLLIB_PS_DISABLED) {
606 		wrqu->power.disabled = 1;
607 		goto exit;
608 	}
609 
610 	wrqu->power.disabled = 0;
611 
612 	if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
613 		wrqu->power.flags = IW_POWER_TIMEOUT;
614 		wrqu->power.value = ieee->ps_timeout * 1000;
615 	} else {
616 		wrqu->power.flags = IW_POWER_PERIOD;
617 		wrqu->power.value = ieee->ps_period * 1000;
618 	}
619 
620 	if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) ==
621 	    (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
622 		wrqu->power.flags |= IW_POWER_ALL_R;
623 	else if (ieee->ps & RTLLIB_PS_MBCAST)
624 		wrqu->power.flags |= IW_POWER_MULTICAST_R;
625 	else
626 		wrqu->power.flags |= IW_POWER_UNICAST_R;
627 
628 exit:
629 	mutex_unlock(&ieee->wx_mutex);
630 	return 0;
631 
632 }
633 EXPORT_SYMBOL(rtllib_wx_get_power);
634