• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * STA APIs for XRadio drivers
3  *
4  * Copyright (c) 2013
5  * Xradio Technology Co., Ltd. <www.xradiotech.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #include <linux/vmalloc.h>
13 #include <linux/sched.h>
14 #include <linux/firmware.h>
15 #include <linux/if_arp.h>
16 #include <linux/ipv6.h>
17 #include <linux/icmpv6.h>
18 #include <net/ndisc.h>
19 
20 #include "xradio.h"
21 #include "sta.h"
22 #include "ap.h"
23 #include "fwio.h"
24 #include "bh.h"
25 #include "wsm.h"
26 #ifdef ROAM_OFFLOAD
27 #include <net/netlink.h>
28 #endif /*ROAM_OFFLOAD*/
29 #ifdef CONFIG_XRADIO_TESTMODE
30 #include "nl80211_testmode_msg_copy.h"
31 #include <net/netlink.h>
32 #endif /* CONFIG_XRADIO_TESTMODE */
33 
34 #include "net/mac80211.h"
35 
36 #ifdef TES_P2P_0002_ROC_RESTART
37 #include <linux/time.h>
38 #endif
39 
40 #define WEP_ENCRYPT_HDR_SIZE    4
41 #define WEP_ENCRYPT_TAIL_SIZE   4
42 #define WPA_ENCRYPT_HDR_SIZE    8
43 #define WPA_ENCRYPT_TAIL_SIZE   12
44 #define WPA2_ENCRYPT_HDR_SIZE   8
45 #define WPA2_ENCRYPT_TAIL_SIZE  8
46 #define WAPI_ENCRYPT_HDR_SIZE   18
47 #define WAPI_ENCRYPT_TAIL_SIZE  16
48 #define MAX_ARP_REPLY_TEMPLATE_SIZE     120
49 #ifdef CONFIG_XRADIO_TESTMODE
50 const int xradio_1d_to_ac[8] = {
51 	IEEE80211_AC_BE,
52 	IEEE80211_AC_BK,
53 	IEEE80211_AC_BK,
54 	IEEE80211_AC_BE,
55 	IEEE80211_AC_VI,
56 	IEEE80211_AC_VI,
57 	IEEE80211_AC_VO,
58 	IEEE80211_AC_VO
59 };
60 
61 /**
62  * enum xradio_ac_numbers - AC numbers as used in xradio
63  * @XRADIO_AC_VO: voice
64  * @XRADIO_AC_VI: video
65  * @XRADIO_AC_BE: best effort
66  * @XRADIO_AC_BK: background
67  */
68 enum xradio_ac_numbers {
69 	XRADIO_AC_VO = 0,
70 	XRADIO_AC_VI = 1,
71 	XRADIO_AC_BE = 2,
72 	XRADIO_AC_BK = 3,
73 };
74 #endif /*CONFIG_XRADIO_TESTMODE */
75 
76 #ifdef IPV6_FILTERING
77 #define MAX_NEIGHBOR_ADVERTISEMENT_TEMPLATE_SIZE 144
78 #endif /*IPV6_FILTERING */
79 
__xradio_free_event_queue(struct list_head * list)80 static inline void __xradio_free_event_queue(struct list_head *list)
81 {
82 	while (!list_empty(list)) {
83 		struct xradio_wsm_event *event =
84 		    list_first_entry(list, struct xradio_wsm_event, link);
85 		list_del(&event->link);
86 		kfree(event);
87 	}
88 }
89 
90 #ifdef CONFIG_XRADIO_TESTMODE
91 /* User priority to WSM queue mapping */
92 const int xradio_priority_to_queueId[8] = {
93 	WSM_QUEUE_BEST_EFFORT,
94 	WSM_QUEUE_BACKGROUND,
95 	WSM_QUEUE_BACKGROUND,
96 	WSM_QUEUE_BEST_EFFORT,
97 	WSM_QUEUE_VIDEO,
98 	WSM_QUEUE_VIDEO,
99 	WSM_QUEUE_VOICE,
100 	WSM_QUEUE_VOICE
101 };
102 #endif /*CONFIG_XRADIO_TESTMODE */
103 
104 /**
105  * compare_ether_addr - Compare two Ethernet addresses
106  * @addr1: Pointer to a six-byte array containing the Ethernet address
107  * @addr2: Pointer other six-byte array containing the Ethernet address
108  *
109  * Compare two Ethernet addresses, returns 0 if equal, non-zero otherwise.
110  * Unlike memcmp(), it doesn't return a value suitable for sorting.
111  */
compare_ether_addr(const u8 * addr1,const u8 * addr2)112 static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
113 {
114 	const u16 *a = (const u16 *) addr1;
115 	const u16 *b = (const u16 *) addr2;
116 	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
117 }
118 
__xradio_bf_configure(struct xradio_vif * priv)119 static inline void __xradio_bf_configure(struct xradio_vif *priv)
120 {
121 	priv->bf_table.numOfIEs = __cpu_to_le32(3);
122 	priv->bf_table.entry[0].ieId = WLAN_EID_VENDOR_SPECIFIC;
123 	priv->bf_table.entry[0].actionFlags =
124 	    WSM_BEACON_FILTER_IE_HAS_CHANGED |
125 	    WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
126 	    WSM_BEACON_FILTER_IE_HAS_APPEARED;
127 
128 	priv->bf_table.entry[0].oui[0] = 0x50;
129 	priv->bf_table.entry[0].oui[1] = 0x6F;
130 	priv->bf_table.entry[0].oui[2] = 0x9A;
131 
132 	priv->bf_table.entry[1].ieId = WLAN_EID_ERP_INFO;
133 	priv->bf_table.entry[1].actionFlags =
134 	    WSM_BEACON_FILTER_IE_HAS_CHANGED |
135 	    WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
136 	    WSM_BEACON_FILTER_IE_HAS_APPEARED;
137 
138 	priv->bf_table.entry[2].ieId = WLAN_EID_HT_INFORMATION;
139 	priv->bf_table.entry[2].actionFlags =
140 	    WSM_BEACON_FILTER_IE_HAS_CHANGED |
141 	    WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
142 	    WSM_BEACON_FILTER_IE_HAS_APPEARED;
143 
144 	priv->bf_control.enabled = WSM_BEACON_FILTER_ENABLE;
145 }
146 
147 /* ******************************************************************** */
148 /* STA API								*/
149 
xradio_start(struct ieee80211_hw * dev)150 int xradio_start(struct ieee80211_hw *dev)
151 {
152 	struct xradio_common *hw_priv = dev->priv;
153 	int ret = 0;
154 	int suspend_lock_state;
155 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
156 
157 	if (wait_event_interruptible_timeout(hw_priv->wsm_startup_done,
158 				hw_priv->driver_ready, 3*HZ) <= 0) {
159 		sta_printk(XRADIO_DBG_ERROR,
160 				   "%s:driver is not ready\n", __func__);
161 		return -ETIMEDOUT;
162 	}
163 
164 	if (wait_event_interruptible_timeout(hw_priv->wsm_wakeup_done,
165 				XRADIO_RESUME == atomic_read(&hw_priv->suspend_state), 3*HZ) <= 0) {
166 		sta_printk(XRADIO_DBG_ERROR,
167 				   "%s:driver is suspending \n", __func__);
168 		return -ETIMEDOUT;
169 	}
170 
171 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
172 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
173 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
174 		sta_printk(XRADIO_DBG_WARN,
175 			   "%s:refuse because of suspend\n", __func__);
176 		return -EBUSY;
177 	}
178 	down(&hw_priv->conf_lock);
179 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
180 
181 #ifdef CONFIG_XRADIO_TESTMODE
182 	spin_lock_bh(&hw_priv->tsm_lock);
183 	memset(&hw_priv->tsm_stats, 0, sizeof(struct xr_tsm_stats));
184 	memset(&hw_priv->tsm_info, 0, sizeof(struct xradio_tsm_info));
185 	spin_unlock_bh(&hw_priv->tsm_lock);
186 #endif /*CONFIG_XRADIO_TESTMODE */
187 	hw_priv->softled_state = 0;
188 	memcpy(hw_priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
189 
190 	ret = xradio_setup_mac(hw_priv);
191 	if (SYS_WARN(ret)) {
192 		sta_printk(XRADIO_DBG_ERROR,
193 			   "%s, xradio_setup_mac failed(%d)\n", __func__, ret);
194 		goto out;
195 	}
196 
197 out:
198 	up(&hw_priv->conf_lock);
199 	return ret;
200 }
201 
xradio_stop(struct ieee80211_hw * dev)202 void xradio_stop(struct ieee80211_hw *dev)
203 {
204 	struct xradio_common *hw_priv = dev->priv;
205 	struct xradio_vif *priv = NULL;
206 	LIST_HEAD(list);
207 	int i;
208 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
209 
210 	wsm_lock_tx(hw_priv);
211 	while (down_trylock(&hw_priv->scan.lock)) {
212 		/* Scan is in progress. Force it to stop. */
213 		hw_priv->scan.req = NULL;
214 		schedule();
215 	}
216 	up(&hw_priv->scan.lock);
217 
218 	cancel_delayed_work_sync(&hw_priv->scan.probe_work);
219 	cancel_delayed_work_sync(&hw_priv->scan.timeout);
220 #ifdef CONFIG_XRADIO_TESTMODE
221 	cancel_delayed_work_sync(&hw_priv->advance_scan_timeout);
222 #endif
223 	flush_workqueue(hw_priv->workqueue);
224 	flush_workqueue(hw_priv->spare_workqueue);
225 	del_timer_sync(&hw_priv->ba_timer);
226 
227 	down(&hw_priv->conf_lock);
228 
229 	hw_priv->softled_state = 0;
230 	/* xradio_set_leds(hw_priv); */
231 
232 	spin_lock(&hw_priv->event_queue_lock);
233 	list_splice_init(&hw_priv->event_queue, &list);
234 	spin_unlock(&hw_priv->event_queue_lock);
235 	__xradio_free_event_queue(&list);
236 
237 	for (i = 0; i < 4; i++)
238 		xradio_queue_clear(&hw_priv->tx_queue[i], XRWL_ALL_IFS);
239 
240 	/* HACK! */
241 	if (atomic_xchg(&hw_priv->tx_lock, 1) != 1)
242 		sta_printk(XRADIO_DBG_WARN,
243 			   "TX is force-unlocked due to stop request.\n");
244 
245 	xradio_for_each_vif(hw_priv, priv, i) {
246 		if (!priv)
247 			continue;
248 		priv->mode = NL80211_IFTYPE_UNSPECIFIED;
249 		priv->listening = false;
250 		priv->delayed_link_loss = 0;
251 		priv->join_status = XRADIO_JOIN_STATUS_PASSIVE;
252 		cancel_delayed_work_sync(&priv->join_timeout);
253 		cancel_delayed_work_sync(&priv->bss_loss_work);
254 		cancel_delayed_work_sync(&priv->connection_loss_work);
255 		cancel_delayed_work_sync(&priv->link_id_gc_work);
256 		del_timer_sync(&priv->mcast_timeout);
257 	}
258 
259 	wsm_unlock_tx(hw_priv);
260 
261 	up(&hw_priv->conf_lock);
262 }
263 
xradio_add_interface(struct ieee80211_hw * dev,struct ieee80211_vif * vif)264 int xradio_add_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
265 {
266 	int ret;
267 	struct xradio_common *hw_priv = dev->priv;
268 	struct xradio_vif *priv;
269 	int suspend_lock_state;
270 
271 #ifndef P2P_MULTIVIF
272 	int i;
273 #endif
274 
275 	if (dev == NULL) {
276 		sta_printk(XRADIO_DBG_WARN, "%s Dev is null\n", __func__);
277 		return 0;
278 	}
279 
280 	if (atomic_read(&hw_priv->num_vifs) >= XRWL_MAX_VIFS) {
281 		WARN_ON(1);
282 		sta_printk(XRADIO_DBG_ERROR, "%s:Too many interfaces=%d\n",
283 			__func__, atomic_read(&hw_priv->num_vifs));
284 		return -EOPNOTSUPP;
285 	}
286 
287 	if (wait_event_interruptible_timeout(hw_priv->wsm_startup_done,
288 				hw_priv->driver_ready, 3*HZ) <= 0) {
289 		sta_printk(XRADIO_DBG_ERROR,
290 				   "%s:driver is not ready\n", __func__);
291 		return -ETIMEDOUT;
292 	}
293 
294 	if (hw_priv->bh_error) {
295 		sta_printk(XRADIO_DBG_ERROR, "%s:bh_error occurs=%d\n",
296 			__func__, hw_priv->bh_error);
297 		return -EIO;
298 	}
299 
300 #ifdef CONFIG_XRADIO_SUSPEND_POWER_OFF
301 	if (XRADIO_POWEROFF_SUSP == atomic_read(&hw_priv->suspend_state)) {
302 		sta_printk(XRADIO_DBG_WARN, "%s: driver has not finish resume "
303 			"from poweroff standby\n", __func__);
304 		/*we do nothing because mac80211_restart_hw will do it again.*/
305 		return 0;
306 	}
307 #endif
308 
309 	/*
310 	sta_printk(XRADIO_DBG_NIY, "%s: vif_type=%d, p2p=%d, ch=%d, addr=%pM\n",
311 		   __func__, vif->type, vif->p2p,
312 		   vif->bss_conf.chandef.chan->hw_value, vif->addr);
313 	*/
314 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
315 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
316 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
317 		sta_printk(XRADIO_DBG_WARN,
318 			   "%s:refuse because of suspend\n", __func__);
319 		return -EBUSY;
320 	}
321 	down(&hw_priv->conf_lock);
322 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
323 
324 	priv = xrwl_get_vif_from_ieee80211(vif);
325 	if (atomic_read(&priv->enabled)) {
326 		sta_printk(XRADIO_DBG_ERROR,
327 			 "%s:vif%d is exist(%p, new=%p, vif_list=%p), mode=%d\n",
328 			__func__, priv->if_id, priv->vif, vif,
329 			hw_priv->vif_list[priv->if_id], priv->mode);
330 		up(&hw_priv->conf_lock);
331 		return -EEXIST;
332 	}
333 	memset(priv, 0, sizeof(struct xradio_vif));
334 
335 	priv->mode = vif->type;
336 	spin_lock(&hw_priv->vif_list_lock);
337 	if (atomic_read(&hw_priv->num_vifs) < XRWL_MAX_VIFS) {
338 #ifdef P2P_MULTIVIF
339 		if (!memcmp(vif->addr, hw_priv->addresses[0].addr, ETH_ALEN)) {
340 			priv->if_id = 0;
341 		} else if (!memcmp(vif->addr, hw_priv->addresses[1].addr,
342 			ETH_ALEN)) {
343 			priv->if_id = 2;
344 		} else if (!memcmp(vif->addr, hw_priv->addresses[2].addr,
345 			ETH_ALEN)) {
346 			priv->if_id = 1;
347 		}
348 		sta_printk(XRADIO_DBG_ALWY, "%s: if_id %d mac %pM\n",
349 			   __func__, priv->if_id, vif->addr);
350 #else
351 		for (i = 0; i < XRWL_MAX_VIFS; i++)
352 			if (!memcmp(vif->addr, hw_priv->addresses[i].addr, ETH_ALEN))
353 				break;
354 		if (i == XRWL_MAX_VIFS) {
355 			spin_unlock(&hw_priv->vif_list_lock);
356 			up(&hw_priv->conf_lock);
357 			return -EINVAL;
358 		}
359 		priv->if_id = i;
360 #endif
361 #ifdef MONITOR_MODE
362 		if (priv->mode == NL80211_IFTYPE_MONITOR) {
363 			priv->if_id = 0;
364 			hw_priv->monitor_if_id = 0;
365 		}
366 #else
367 		if (priv->mode == NL80211_IFTYPE_MONITOR) {
368 			spin_unlock(&hw_priv->vif_list_lock);
369 			up(&hw_priv->conf_lock);
370 			sta_printk(XRADIO_DBG_WARN,
371 				   "%s: NL80211_IFTYPE_MONITOR unsupport!\n",
372 				   __func__);
373 			return -EOPNOTSUPP;
374 		}
375 #endif
376 		hw_priv->if_id_slot |= BIT(priv->if_id);
377 		priv->hw_priv = hw_priv;
378 		priv->hw = dev;
379 		priv->vif = vif;
380 		hw_priv->vif_list[priv->if_id] = vif;
381 		atomic_inc(&hw_priv->num_vifs);
382 	} else {
383 		spin_unlock(&hw_priv->vif_list_lock);
384 		up(&hw_priv->conf_lock);
385 		return -EOPNOTSUPP;
386 	}
387 	spin_unlock(&hw_priv->vif_list_lock);
388 	/* TODO:COMBO :Check if MAC address matches the one expected by FW */
389 	memcpy(hw_priv->mac_addr, vif->addr, ETH_ALEN);
390 
391 	/* Enable auto-calibration */
392 	/* Exception in subsequent channel switch; disabled.
393 	SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
394 		&auto_calibration_mode, sizeof(auto_calibration_mode)));
395 	*/
396 	sta_printk(XRADIO_DBG_MSG, "Interface ID:%d of type:%d added\n",
397 		   priv->if_id, priv->mode);
398 	xradio_vif_setup(priv);
399 	up(&hw_priv->conf_lock);
400 
401 	ret = SYS_WARN(xradio_setup_mac_pvif(priv));
402 
403 #ifdef MONITOR_MODE
404 	if (priv->mode == NL80211_IFTYPE_MONITOR) {
405 		struct ieee80211_channel chan;
406 		chan.band = WSM_PHY_BAND_2_4G;
407 		chan.hw_value = 5;
408 		xradio_enable_monitoring(priv, &chan);
409 	}
410 #endif
411 
412 	return ret;
413 }
414 
xradio_remove_interface(struct ieee80211_hw * dev,struct ieee80211_vif * vif)415 void xradio_remove_interface(struct ieee80211_hw *dev,
416 			     struct ieee80211_vif *vif)
417 {
418 	struct xradio_common *hw_priv = dev->priv;
419 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
420 	struct wsm_reset reset = {
421 		.reset_statistics = true,
422 	};
423 	int i;
424 	bool is_htcapie = false;
425 	struct xradio_vif *tmp_priv;
426 	struct wsm_operational_mode mode = {
427 		.power_mode = wsm_power_mode_quiescent,
428 		.disableMoreFlagUsage = true,
429 	};
430 	int suspend_lock_state;
431 
432 	sta_printk(XRADIO_DBG_WARN, "!!! %s: vif_id=%d, join_status = %d\n",
433 		   __func__, priv->if_id, priv->join_status);
434 
435 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
436 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
437 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
438 		sta_printk(XRADIO_DBG_WARN,
439 			   "%s:refuse because of suspend\n", __func__);
440 		return;
441 	}
442 
443 	down(&hw_priv->conf_lock);
444 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
445 
446 	if (atomic_read(&priv->enabled) == 0) {
447 		sta_printk(XRADIO_DBG_WARN, "%s:vif is not enable!\n", __func__);
448 		up(&hw_priv->conf_lock);
449 		return ;
450 	}
451 	up(&hw_priv->conf_lock);
452 
453 	cancel_delayed_work_sync(&priv->bss_loss_work);
454 	cancel_delayed_work_sync(&priv->connection_loss_work);
455 	cancel_delayed_work_sync(&priv->join_timeout);
456 	cancel_delayed_work_sync(&priv->set_cts_work);
457 	cancel_delayed_work_sync(&priv->pending_offchanneltx_work);
458 	del_timer_sync(&priv->mcast_timeout);
459 
460 	cancel_delayed_work_sync(&priv->unjoin_delayed_work);
461 	cancel_work_sync(&priv->update_filtering_work);
462 	cancel_work_sync(&priv->set_beacon_wakeup_period_work);
463 	cancel_work_sync(&priv->join_work);
464 	cancel_work_sync(&priv->unjoin_work);
465 	cancel_work_sync(&priv->offchannel_work);
466 	cancel_work_sync(&priv->wep_key_work);
467 	cancel_work_sync(&priv->set_tim_work);
468 	cancel_work_sync(&priv->multicast_start_work);
469 	cancel_work_sync(&priv->tx_failure_work);
470 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
471 	cancel_work_sync(&priv->linkid_reset_work);
472 #endif
473 #ifdef AP_HT_CAP_UPDATE
474 	cancel_work_sync(&priv->ht_info_update_work);
475 #endif
476 
477 	down(&hw_priv->scan.lock);
478 	if (atomic_xchg(&priv->delayed_unjoin, 0)) {
479 		wsm_unlock_tx(hw_priv);
480 		sta_printk(XRADIO_DBG_ERROR, "%s:delayed_unjoin exist!\n", __func__);
481 	}
482 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
483 		cancel_work_sync(&priv->unjoin_work);
484 		wsm_lock_tx(hw_priv);
485 		xradio_unjoin_work(&priv->unjoin_work);
486 		sta_printk(XRADIO_DBG_NIY, "%s:do unjoin_work!\n", __func__);
487 	}
488 
489 	down(&hw_priv->conf_lock);
490 	atomic_set(&priv->enabled, 0);
491 
492 	cancel_work_sync(&priv->link_id_work);
493 	cancel_delayed_work_sync(&priv->link_id_gc_work);
494 	cancel_delayed_work_sync(&priv->link_id_gc_work);
495 
496 	xradio_tx_queues_lock(hw_priv);
497 	wsm_lock_tx(hw_priv);
498 	switch (priv->join_status) {
499 	case XRADIO_JOIN_STATUS_AP:
500 		for (i = 0; priv->link_id_map; ++i) {
501 			if (priv->link_id_map & BIT(i)) {
502 				xrwl_unmap_link(priv, i);
503 				priv->link_id_map &= ~BIT(i);
504 			}
505 		}
506 		memset(priv->link_id_db, 0,
507 				sizeof(priv->link_id_db));
508 		priv->sta_asleep_mask = 0;
509 		priv->enable_beacon = false;
510 		priv->tx_multicast = false;
511 		priv->aid0_bit_set = false;
512 		priv->buffered_multicasts = false;
513 		priv->pspoll_mask = 0;
514 		reset.link_id = 0;
515 		wsm_reset(hw_priv, &reset, priv->if_id);
516 		SYS_WARN(wsm_set_operational_mode(hw_priv, &mode, priv->if_id));
517 		xradio_for_each_vif(hw_priv, tmp_priv, i) {
518 #ifdef P2P_MULTIVIF
519 			if ((i == (XRWL_MAX_VIFS - 1)) || !tmp_priv)
520 #else
521 			if (!tmp_priv)
522 #endif
523 				continue;
524 			if ((tmp_priv->join_status == XRADIO_JOIN_STATUS_STA)
525 				&& tmp_priv->htcap)
526 				is_htcapie = true;
527 		}
528 
529 		if (is_htcapie) {
530 			hw_priv->vif0_throttle = XRWL_HOST_VIF0_11N_THROTTLE;
531 			hw_priv->vif1_throttle = XRWL_HOST_VIF1_11N_THROTTLE;
532 			sta_printk(XRADIO_DBG_NIY, "AP REMOVE HTCAP 11N %d\n",
533 				   hw_priv->vif0_throttle);
534 		} else {
535 			hw_priv->vif0_throttle = XRWL_HOST_VIF0_11BG_THROTTLE;
536 			hw_priv->vif1_throttle = XRWL_HOST_VIF1_11BG_THROTTLE;
537 			sta_printk(XRADIO_DBG_NIY, "AP REMOVE 11BG %d\n",
538 				   hw_priv->vif0_throttle);
539 		}
540 		break;
541 	case XRADIO_JOIN_STATUS_MONITOR:
542 #ifdef MONITOR_MODE
543 		if (priv->mode == NL80211_IFTYPE_MONITOR)
544 			xradio_disable_monitoring(priv);
545 		else
546 #endif
547 			xradio_disable_listening(priv);
548 		break;
549 	default:
550 		break;
551 	}
552 	/* TODO:COMBO: Change Queue Module */
553 	__xradio_flush(hw_priv, true, priv->if_id);
554 
555 	/* After removing the P2P interface, we need to
556 	 * restore the address of sPasGlobal.StationId[1] in fw.
557 	 */
558 	if (priv->if_id == 1) {
559 		int ret = 0;
560 		u8 devAddr[ETH_ALEN];
561 
562 		memset(devAddr, 0, ETH_ALEN);
563 		memcpy(devAddr, priv->vif->addr, ETH_ALEN);
564 		devAddr[4] ^= 0x80;
565 		ret = wsm_write_mib(hw_priv, WSM_MIB_ID_CHANGE_MAC, devAddr, ETH_ALEN, 1);
566 		sta_printk(XRADIO_DBG_ALWY, "%s status:%s cur_p2p_dev_addr %pM\n", __func__,
567 							ret ? "error" : "success", devAddr);
568 	}
569 
570 	/* TODO:COMBO: May be reset of these variables "delayed_link_loss and
571 	 * join_status to default can be removed as dev_priv will be freed by
572 	 * mac80211 */
573 	priv->delayed_link_loss = 0;
574 	priv->join_status = XRADIO_JOIN_STATUS_PASSIVE;
575 	wsm_unlock_tx(hw_priv);
576 
577 	if ((priv->if_id == 1) && (priv->mode == NL80211_IFTYPE_AP
578 				   || priv->mode == NL80211_IFTYPE_P2P_GO)) {
579 		hw_priv->is_go_thru_go_neg = false;
580 	}
581 	spin_lock(&hw_priv->vif_list_lock);
582 	spin_lock(&priv->vif_lock);
583 	hw_priv->vif_list[priv->if_id] = NULL;
584 	hw_priv->if_id_slot &= (~BIT(priv->if_id));
585 	atomic_dec(&hw_priv->num_vifs);
586 	if (atomic_read(&hw_priv->num_vifs) == 0) {
587 		xradio_free_keys(hw_priv);
588 		memset(hw_priv->mac_addr, 0, ETH_ALEN);
589 	}
590 	spin_unlock(&priv->vif_lock);
591 	spin_unlock(&hw_priv->vif_list_lock);
592 	priv->listening = false;
593 
594 	xradio_debug_release_priv(priv);
595 
596 	xradio_tx_queues_unlock(hw_priv);
597 	up(&hw_priv->conf_lock);
598 
599 	if (atomic_read(&hw_priv->num_vifs) == 0) {
600 		flush_workqueue(hw_priv->workqueue);
601 		flush_workqueue(hw_priv->spare_workqueue);
602 	}
603 	up(&hw_priv->scan.lock);
604 }
605 
xradio_change_interface(struct ieee80211_hw * dev,struct ieee80211_vif * vif,enum nl80211_iftype new_type,bool p2p)606 int xradio_change_interface(struct ieee80211_hw *dev,
607 				struct ieee80211_vif *vif,
608 				enum nl80211_iftype new_type,
609 				bool p2p)
610 {
611 	int ret = 0;
612 	sta_printk(XRADIO_DBG_WARN, "%s: new type=%d(%d), p2p=%d(%d)\n",
613 		   __func__, new_type, vif->type, p2p, vif->p2p);
614 	if (new_type != vif->type || vif->p2p != p2p) {
615 		xradio_remove_interface(dev, vif);
616 		vif->type = new_type;
617 		vif->p2p = p2p;
618 		ret = xradio_add_interface(dev, vif);
619 	}
620 
621 	return ret;
622 }
623 
xradio_config(struct ieee80211_hw * dev,u32 changed)624 int xradio_config(struct ieee80211_hw *dev, u32 changed)
625 {
626 	int ret = 0;
627 	struct xradio_common *hw_priv = dev->priv;
628 	struct ieee80211_conf *conf = &dev->conf;
629 #ifdef CONFIG_XRADIO_TESTMODE
630 	int max_power_level = 0;
631 	int min_power_level = 0;
632 #endif
633 	/* TODO:COMBO: adjust to multi vif interface
634 	 * IEEE80211_CONF_CHANGE_IDLE is still handled per xradio_vif*/
635 	int if_id = 0;
636 	int suspend_lock_state;
637 
638 	/*
639 	struct xradio_vif *priv;
640 	*/
641 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
642 
643 	if (changed &
644 		(IEEE80211_CONF_CHANGE_MONITOR|IEEE80211_CONF_CHANGE_IDLE)) {
645 		/* TBD: It looks like it's transparent
646 		 * there's a monitor interface present -- use this
647 		 * to determine for example whether to calculate
648 		 * timestamps for packets or not, do not use instead
649 		 * of filter flags! */
650 		sta_printk(XRADIO_DBG_NIY, "ignore IEEE80211_CONF_CHANGE_MONITOR (%d)"
651 			   "IEEE80211_CONF_CHANGE_IDLE (%d)\n",
652 			   (changed & IEEE80211_CONF_CHANGE_MONITOR) ? 1 : 0,
653 			   (changed & IEEE80211_CONF_CHANGE_IDLE) ? 1 : 0);
654 		return ret;
655 	}
656 
657 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
658 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
659 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
660 		sta_printk(XRADIO_DBG_WARN,
661 			   "%s:refuse because of suspend\n", __func__);
662 		return -EBUSY;
663 	}
664 
665 	down(&hw_priv->scan.lock);
666 	down(&hw_priv->conf_lock);
667 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
668 	/*
669 	priv = __xrwl_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id);
670 	*/
671 	/* TODO: IEEE80211_CONF_CHANGE_QOS */
672 	/* TODO:COMBO:Change when support is available mac80211*/
673 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
674 		/*hw_priv->output_power = conf->power_level;*/
675 		hw_priv->output_power = 20;
676 #ifdef CONFIG_XRADIO_TESTMODE
677 		/* Testing if Power Level to set is out of device power range */
678 		if (conf->chan_conf->channel->band == NL80211_BAND_2GHZ) {
679 			max_power_level = hw_priv->txPowerRange[0].max_power_level;
680 			min_power_level = hw_priv->txPowerRange[0].min_power_level;
681 		} else {
682 			max_power_level = hw_priv->txPowerRange[1].max_power_level;
683 			min_power_level = hw_priv->txPowerRange[1].min_power_level;
684 		}
685 		if (hw_priv->output_power > max_power_level)
686 			hw_priv->output_power = max_power_level;
687 		else if (hw_priv->output_power < min_power_level)
688 			hw_priv->output_power = min_power_level;
689 #endif /* CONFIG_XRADIO_TESTMODE */
690 
691 		sta_printk(XRADIO_DBG_NIY, "Config Tx power=%d, but real=%d\n",
692 			   conf->power_level, hw_priv->output_power);
693 		SYS_WARN(wsm_set_output_power(hw_priv,
694 					      hw_priv->output_power * 10, if_id));
695 	}
696 
697 	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
698 	    (hw_priv->channel != conf->chandef.chan)) {
699 		/* Switch Channel commented for CC Mode */
700 		struct ieee80211_channel *ch = conf->chandef.chan;
701 		sta_printk(XRADIO_DBG_WARN, "Freq %d (wsm ch: %d) prev: %d.\n",
702 			   ch->center_freq, ch->hw_value,
703 			   hw_priv->channel ? hw_priv->channel->hw_value : -1);
704 		/* Earlier there was a call to __xradio_flush().
705 		   Removed as deemed unnecessary */
706 		hw_priv->channel = ch;
707 		hw_priv->channel_changed = 1;
708 #ifdef MONITOR_MODE
709 		if (hw_priv->monitor_if_id != -1 && hw_priv->monitor_running)
710 			xradio_channel_switch(hw_priv, hw_priv->channel);
711 #endif
712 	}
713 
714 	up(&hw_priv->conf_lock);
715 	up(&hw_priv->scan.lock);
716 	return ret;
717 }
718 
xradio_update_filtering(struct xradio_vif * priv)719 void xradio_update_filtering(struct xradio_vif *priv)
720 {
721 	int ret;
722 	bool bssid_filtering = !priv->rx_filter.bssid;
723 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
724 	static struct wsm_beacon_filter_control bf_disabled = {
725 		.enabled = 0,
726 		.bcn_count = 1,
727 	};
728 	bool ap_mode = 0;
729 	static struct wsm_beacon_filter_table bf_table_auto = {
730 		.numOfIEs = __cpu_to_le32(2),
731 		.entry[0].ieId = WLAN_EID_VENDOR_SPECIFIC,
732 		.entry[0].actionFlags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
733 		    WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
734 		    WSM_BEACON_FILTER_IE_HAS_APPEARED,
735 		.entry[0].oui[0] = 0x50,
736 		.entry[0].oui[1] = 0x6F,
737 		.entry[0].oui[2] = 0x9A,
738 
739 		.entry[1].ieId = WLAN_EID_HT_INFORMATION,
740 		.entry[1].actionFlags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
741 		    WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
742 		    WSM_BEACON_FILTER_IE_HAS_APPEARED,
743 	};
744 	static struct wsm_beacon_filter_control bf_auto = {
745 		.enabled = WSM_BEACON_FILTER_ENABLE |
746 
747 #ifdef SUPPORT_HT40
748 
749 			WSM_BEACON_FILTER_AUTO_ERP|
750 			WSM_BEACON_FILTER_AUTO_HT,
751 
752 #else
753 
754 		    WSM_BEACON_FILTER_AUTO_ERP,
755 
756 #endif
757 
758 		.bcn_count = 1,
759 	};
760 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
761 
762 	bf_auto.bcn_count = priv->bf_control.bcn_count;
763 
764 	if (priv->join_status == XRADIO_JOIN_STATUS_PASSIVE)
765 		return;
766 	else if (priv->join_status == XRADIO_JOIN_STATUS_MONITOR)
767 		bssid_filtering = false;
768 
769 	if (priv->vif && (priv->vif->type == NL80211_IFTYPE_AP))
770 		ap_mode = true;
771 	/*
772 	 * When acting as p2p client being connected to p2p GO, in order to
773 	 * receive frames from a different p2p device, turn off bssid filter.
774 	 *
775 	 * WARNING: FW dependency!
776 	 * This can only be used with FW WSM371 and its successors.
777 	 * In that FW version even with bssid filter turned off,
778 	 * device will block most of the unwanted frames.
779 	 */
780 	if (priv->vif && priv->vif->p2p)
781 		bssid_filtering = false;
782 
783 	ret = wsm_set_rx_filter(hw_priv, &priv->rx_filter, priv->if_id);
784 	if (!ret && !ap_mode) {
785 		if (priv->vif) {
786 			if (priv->vif->p2p || NL80211_IFTYPE_STATION != priv->vif->type)
787 				ret = wsm_set_beacon_filter_table(hw_priv,
788 						    &priv->bf_table, priv->if_id);
789 			else
790 				ret = wsm_set_beacon_filter_table(hw_priv,
791 						    &bf_table_auto, priv->if_id);
792 		} else
793 			SYS_WARN(1);
794 	}
795 	if (!ret && !ap_mode) {
796 		if (priv->disable_beacon_filter)
797 			ret = wsm_beacon_filter_control(hw_priv,
798 							&bf_disabled, priv->if_id);
799 		else {
800 			if (priv->vif) {
801 				if (priv->vif->p2p ||
802 					NL80211_IFTYPE_STATION != priv->vif->type)
803 					ret = wsm_beacon_filter_control(hw_priv,
804 									&priv->bf_control,
805 									priv->if_id);
806 				else
807 					ret = wsm_beacon_filter_control(hw_priv,
808 									&bf_auto, priv->if_id);
809 			} else
810 				SYS_WARN(1);
811 		}
812 	}
813 
814 	if (!ret)
815 		ret = wsm_set_bssid_filtering(hw_priv, bssid_filtering, priv->if_id);
816 #if 0
817 	if (!ret) {
818 		ret = wsm_set_multicast_filter(hw_priv, &priv->multicast_filter,
819 					       priv->if_id);
820 	}
821 #endif
822 	if (ret)
823 		sta_printk(XRADIO_DBG_ERROR, "%s: Update filtering failed: %d.\n",
824 			   __func__, ret);
825 	return;
826 }
827 
xradio_update_filtering_work(struct work_struct * work)828 void xradio_update_filtering_work(struct work_struct *work)
829 {
830 	struct xradio_vif *priv =
831 		container_of(work, struct xradio_vif,
832 		update_filtering_work);
833 
834 	xradio_update_filtering(priv);
835 }
836 
xradio_set_beacon_wakeup_period_work(struct work_struct * work)837 void xradio_set_beacon_wakeup_period_work(struct work_struct *work)
838 {
839 
840 	struct xradio_vif *priv =
841 	   container_of(work, struct xradio_vif, set_beacon_wakeup_period_work);
842 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
843 
844 #ifdef XRADIO_USE_LONG_DTIM_PERIOD
845 {
846 	int join_dtim_period_extend;
847 	if (priv->join_dtim_period <= 3) {
848 		join_dtim_period_extend = priv->join_dtim_period * 3;
849 	} else if (priv->join_dtim_period <= 5) {
850 		join_dtim_period_extend = priv->join_dtim_period * 2;
851 	} else {
852 		join_dtim_period_extend = priv->join_dtim_period;
853 	}
854 	SYS_WARN(wsm_set_beacon_wakeup_period(priv->hw_priv,
855 		 priv->beacon_int * join_dtim_period_extend >
856 		 MAX_BEACON_SKIP_TIME_MS ? 1 : join_dtim_period_extend,
857 		 0, priv->if_id));
858 }
859 #else
860 	SYS_WARN(wsm_set_beacon_wakeup_period(priv->hw_priv,
861 		 priv->beacon_int * priv->join_dtim_period >
862 		 MAX_BEACON_SKIP_TIME_MS ? 1 : priv->join_dtim_period,
863 		 0, priv->if_id));
864 #endif
865 }
866 
xradio_prepare_multicast(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct netdev_hw_addr_list * mc_list)867 u64 xradio_prepare_multicast(struct ieee80211_hw *hw,
868 			     struct ieee80211_vif *vif,
869 			     struct netdev_hw_addr_list *mc_list)
870 {
871 	static u8 broadcast_ipv6[ETH_ALEN] = {
872 		0x33, 0x33, 0x00, 0x00, 0x00, 0x01
873 	};
874 	static u8 broadcast_ipv4[ETH_ALEN] = {
875 		0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
876 	};
877 	struct netdev_hw_addr *ha;
878 	int count = 0;
879 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
880 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
881 	if (!atomic_read(&priv->enabled)) {
882 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
883 				__func__, vif->type);
884 		return 0;
885 	}
886 
887 	if (SYS_WARN(!priv))
888 		return netdev_hw_addr_list_count(mc_list);
889 
890 #ifdef P2P_MULTIVIF
891 	if (priv->if_id == XRWL_GENERIC_IF_ID)
892 		return 0;
893 #endif
894 
895 	/* Disable multicast filtering */
896 	priv->has_multicast_subscription = false;
897 	memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
898 
899 	if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
900 		return 0;
901 
902 	/* Enable if requested */
903 	netdev_hw_addr_list_for_each(ha, mc_list) {
904 		sta_printk(XRADIO_DBG_MSG, "multicast: %pM\n", ha->addr);
905 		memcpy(&priv->multicast_filter.macAddress[count], ha->addr, ETH_ALEN);
906 		if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) &&
907 		    memcmp(ha->addr, broadcast_ipv6, ETH_ALEN))
908 			priv->has_multicast_subscription = true;
909 		count++;
910 	}
911 
912 	if (count) {
913 		priv->multicast_filter.enable = __cpu_to_le32(1);
914 		priv->multicast_filter.numOfAddresses = __cpu_to_le32(count);
915 	}
916 
917 	return netdev_hw_addr_list_count(mc_list);
918 }
919 
xradio_configure_filter(struct ieee80211_hw * hw,struct ieee80211_vif * vif,unsigned int changed_flags,unsigned int * total_flags,u64 multicast)920 void xradio_configure_filter(struct ieee80211_hw *hw,
921 			     struct ieee80211_vif *vif,
922 			     unsigned int changed_flags,
923 			     unsigned int *total_flags,
924 			     u64 multicast)
925 {
926 	struct xradio_common *hw_priv = hw->priv;
927 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
928 	int suspend_lock_state;
929 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
930 
931 #ifdef P2P_MULTIVIF
932 	if (priv->if_id == XRWL_GENERIC_IF_ID) {
933 		*total_flags &= ~(1 << 31);
934 		return;
935 	}
936 #endif
937 
938 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
939 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
940 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
941 		sta_printk(XRADIO_DBG_WARN,
942 			   "%s:refuse because of suspend\n", __func__);
943 		*total_flags &= ~(1 << 31);
944 		return;
945 	}
946 
947 #if 0
948 	bool listening = !!(*total_flags &
949 			     (FIF_PROMISC_IN_BSS      |
950 			      FIF_OTHER_BSS           |
951 			      FIF_BCN_PRBRESP_PROMISC |
952 			      FIF_PROBE_REQ));
953 #endif
954 
955 	*total_flags &= /*FIF_PROMISC_IN_BSS |*/
956 			FIF_OTHER_BSS      |
957 			FIF_FCSFAIL        |
958 			FIF_BCN_PRBRESP_PROMISC |
959 			FIF_PROBE_REQ;
960 
961 	down(&hw_priv->scan.lock);
962 	down(&hw_priv->conf_lock);
963 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
964 	if (!atomic_read(&priv->enabled)) {
965 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
966 				__func__, vif->type);
967 		*total_flags &= ~(1 << 31);
968 		up(&hw_priv->conf_lock);
969 		up(&hw_priv->scan.lock);
970 		return ;
971 	}
972 
973 	//priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS) ? 1 : 0;
974 	priv->rx_filter.bssid = (*total_flags &
975 				 (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 1 : 0;
976 	priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
977 	priv->bf_control.bcn_count = (*total_flags &
978 				      (FIF_BCN_PRBRESP_PROMISC |
979 				       //FIF_PROMISC_IN_BSS |
980 				       FIF_PROBE_REQ)) ? 1 : 0;
981 
982 #if 0
983 	if (priv->listening ^ listening) {
984 		priv->listening = listening;
985 		wsm_lock_tx(hw_priv);
986 		xradio_update_listening(priv, listening);
987 		wsm_unlock_tx(hw_priv);
988 	}
989 #endif
990 	xradio_update_filtering(priv);
991 	up(&hw_priv->conf_lock);
992 	up(&hw_priv->scan.lock);
993 }
994 
xradio_conf_tx(struct ieee80211_hw * dev,struct ieee80211_vif * vif,u16 queue,const struct ieee80211_tx_queue_params * params)995 int xradio_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
996 		   u16 queue, const struct ieee80211_tx_queue_params *params)
997 {
998 	struct xradio_common *hw_priv = dev->priv;
999 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
1000 	int ret = 0;
1001 	int suspend_lock_state;
1002 	/* To prevent re-applying PM request OID again and again */
1003 	bool old_uapsdFlags;
1004 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1005 
1006 	if (SYS_WARN(!priv))
1007 		return -EOPNOTSUPP;
1008 
1009 #ifdef P2P_MULTIVIF
1010 	if (priv->if_id == XRWL_GENERIC_IF_ID)
1011 		return 0;
1012 #endif
1013 
1014 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
1015 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
1016 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
1017 		sta_printk(XRADIO_DBG_WARN,
1018 			   "%s:refuse because of suspend\n", __func__);
1019 		return 0;
1020 	}
1021 
1022 	down(&hw_priv->conf_lock);
1023 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
1024 	if (!atomic_read(&priv->enabled)) {
1025 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1026 				__func__, vif->type);
1027 		up(&hw_priv->conf_lock);
1028 		return 0;
1029 	}
1030 
1031 	if (queue < dev->queues) {
1032 		old_uapsdFlags = priv->uapsd_info.uapsdFlags;
1033 
1034 		WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
1035 		ret = wsm_set_tx_queue_params(hw_priv,
1036 					      &priv->tx_queue_params.params[queue],
1037 					      queue, priv->if_id);
1038 		if (ret) {
1039 			sta_printk(XRADIO_DBG_ERROR,
1040 				   "%s:wsm_set_tx_queue_params failed!\n", __func__);
1041 			ret = -EINVAL;
1042 			goto out;
1043 		}
1044 
1045 		WSM_EDCA_SET(&priv->edca, queue, params->aifs,
1046 			      params->cw_min, params->cw_max,
1047 			      params->txop, 0xc8, params->uapsd);
1048 		ret = wsm_set_edca_params(hw_priv, &priv->edca, priv->if_id);
1049 		if (ret) {
1050 			sta_printk(XRADIO_DBG_ERROR,
1051 				   "%s:wsm_set_edca_params failed!\n", __func__);
1052 			ret = -EINVAL;
1053 			goto out;
1054 		}
1055 
1056 		if (priv->mode == NL80211_IFTYPE_STATION ||
1057 			priv->mode == NL80211_IFTYPE_P2P_DEVICE) {
1058 			ret = xradio_set_uapsd_param(priv, &priv->edca);
1059 			if (!ret && priv->setbssparams_done &&
1060 			    (priv->join_status == XRADIO_JOIN_STATUS_STA) &&
1061 			    (old_uapsdFlags != priv->uapsd_info.uapsdFlags))
1062 				xradio_set_pm(priv, &priv->powersave_mode);
1063 		}
1064 	} else {
1065 		sta_printk(XRADIO_DBG_ERROR, "%s:queue is to large!\n", __func__);
1066 		ret = -EINVAL;
1067 	}
1068 
1069 out:
1070 	up(&hw_priv->conf_lock);
1071 	return ret;
1072 }
1073 
xradio_get_stats(struct ieee80211_hw * dev,struct ieee80211_low_level_stats * stats)1074 int xradio_get_stats(struct ieee80211_hw *dev,
1075 		     struct ieee80211_low_level_stats *stats)
1076 {
1077 	struct xradio_common *hw_priv = dev->priv;
1078 
1079 	memcpy(stats, &hw_priv->stats, sizeof(*stats));
1080 	return 0;
1081 }
1082 
1083 /*
1084 int xradio_get_tx_stats(struct ieee80211_hw *dev,
1085 			struct ieee80211_tx_queue_stats *stats)
1086 {
1087 	int i;
1088 	struct xradio_common *priv = dev->priv;
1089 
1090 	for (i = 0; i < dev->queues; ++i)
1091 		xradio_queue_get_stats(&priv->tx_queue[i], &stats[i]);
1092 
1093 	return 0;
1094 }
1095 */
1096 
1097 /* for ps debug */
1098 #ifdef CONFIG_XRADIO_DEBUGFS
1099 u8 ps_disable;
1100 u8 ps_idleperiod;
1101 u8 ps_changeperiod;
1102 #endif
1103 
xradio_set_pm(struct xradio_vif * priv,const struct wsm_set_pm * arg)1104 int xradio_set_pm(struct xradio_vif *priv, const struct wsm_set_pm *arg)
1105 {
1106 	struct wsm_set_pm pm = *arg;
1107 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1108 
1109 #ifdef CONFIG_XRADIO_DEBUGFS
1110 	if (ps_disable)
1111 		pm.pmMode = WSM_PSM_ACTIVE;
1112 	if (ps_idleperiod) {
1113 		pm.fastPsmIdlePeriod = ps_idleperiod << 1;
1114 		pm.apPsmChangePeriod = ps_changeperiod << 1;
1115 	}
1116 #endif
1117 
1118 	if (priv->uapsd_info.uapsdFlags != 0)
1119 		pm.pmMode &= ~WSM_PSM_FAST_PS_FLAG;
1120 
1121 	if (memcmp(&pm, &priv->firmware_ps_mode, sizeof(struct wsm_set_pm))) {
1122 		priv->firmware_ps_mode = pm;
1123 		sta_printk(XRADIO_DBG_NIY, "%s, mode=0x%x, Idle=%d, Change=%d\n",
1124 					__func__, pm.pmMode, pm.fastPsmIdlePeriod,
1125 					pm.apPsmChangePeriod);
1126 		return wsm_set_pm(priv->hw_priv, &pm, priv->if_id);
1127 	} else {
1128 		return 0;
1129 	}
1130 }
1131 
xradio_set_key(struct ieee80211_hw * dev,enum set_key_cmd cmd,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key)1132 int xradio_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
1133 		   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1134 		   struct ieee80211_key_conf *key)
1135 {
1136 	int ret = -EOPNOTSUPP;
1137 	struct xradio_common *hw_priv = dev->priv;
1138 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
1139 	struct wsm_protected_mgmt_policy mgmt_policy;
1140 	int suspend_lock_state;
1141 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1142 
1143 #ifdef P2P_MULTIVIF
1144 	SYS_WARN(priv->if_id == XRWL_GENERIC_IF_ID);
1145 #endif
1146 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
1147 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
1148 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
1149 		sta_printk(XRADIO_DBG_WARN,
1150 			   "%s:refuse because of suspend\n", __func__);
1151 		return -EBUSY;
1152 	}
1153 
1154 	down(&hw_priv->conf_lock);
1155 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
1156 	if (!atomic_read(&priv->enabled)) {
1157 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1158 				__func__, vif->type);
1159 		up(&hw_priv->conf_lock);
1160 		return 0;
1161 	}
1162 
1163 	if (cmd == SET_KEY) {
1164 		u8 *peer_addr = NULL;
1165 		int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ? 1 : 0;
1166 		int idx = xradio_alloc_key(hw_priv);
1167 		struct wsm_add_key *wsm_key = &hw_priv->keys[idx];
1168 
1169 		if (idx < 0) {
1170 			sta_printk(XRADIO_DBG_ERROR, "%s:xradio_alloc_key failed!\n",
1171 				   __func__);
1172 			ret = -EINVAL;
1173 			goto finally;
1174 		}
1175 
1176 		SYS_BUG(pairwise && !sta);
1177 		if (sta)
1178 			peer_addr = sta->addr;
1179 
1180 		switch (key->cipher) {
1181 		case WLAN_CIPHER_SUITE_WEP40:
1182 		case WLAN_CIPHER_SUITE_WEP104:
1183 			if (key->keylen > 16) {
1184 				xradio_free_key(hw_priv, idx);
1185 				sta_printk(XRADIO_DBG_ERROR, "%s: keylen too long=%d!\n",
1186 				       __func__, key->keylen);
1187 				ret = -EINVAL;
1188 				goto finally;
1189 			}
1190 
1191 			if (pairwise) {
1192 				wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
1193 				memcpy(wsm_key->wepPairwiseKey.peerAddress,
1194 				       peer_addr, ETH_ALEN);
1195 				memcpy(wsm_key->wepPairwiseKey.keyData, &key->key[0],
1196 				       key->keylen);
1197 				wsm_key->wepPairwiseKey.keyLength = key->keylen;
1198 				sta_printk(XRADIO_DBG_NIY, "%s: WEP_PAIRWISE keylen=%d!\n",
1199 				       __func__, key->keylen);
1200 			} else {
1201 				wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
1202 				memcpy(wsm_key->wepGroupKey.keyData, &key->key[0],
1203 				       key->keylen);
1204 				wsm_key->wepGroupKey.keyLength = key->keylen;
1205 				wsm_key->wepGroupKey.keyId     = key->keyidx;
1206 				sta_printk(XRADIO_DBG_NIY, "%s: WEP_GROUP keylen=%d!\n",
1207 				       __func__, key->keylen);
1208 			}
1209 			break;
1210 		case WLAN_CIPHER_SUITE_TKIP:
1211 			if (pairwise) {
1212 				wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
1213 				memcpy(wsm_key->tkipPairwiseKey.peerAddress,
1214 				       peer_addr, ETH_ALEN);
1215 				memcpy(wsm_key->tkipPairwiseKey.tkipKeyData,
1216 				       &key->key[0], 16);
1217 				memcpy(wsm_key->tkipPairwiseKey.txMicKey, &key->key[16], 8);
1218 				memcpy(wsm_key->tkipPairwiseKey.rxMicKey, &key->key[24], 8);
1219 				sta_printk(XRADIO_DBG_NIY, "%s: TKIP_PAIRWISE keylen=%d!\n",
1220 				       __func__, key->keylen);
1221 			} else {
1222 				size_t mic_offset =
1223 					    (priv->mode == NL80211_IFTYPE_AP) ? 16 : 24;
1224 				wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
1225 				memcpy(wsm_key->tkipGroupKey.tkipKeyData, &key->key[0], 16);
1226 				memcpy(wsm_key->tkipGroupKey.rxMicKey,
1227 				       &key->key[mic_offset], 8);
1228 
1229 				/* TODO: Where can I find TKIP SEQ? */
1230 				memset(wsm_key->tkipGroupKey.rxSeqCounter, 0, 8);
1231 				wsm_key->tkipGroupKey.keyId = key->keyidx;
1232 				sta_printk(XRADIO_DBG_NIY, "%s: TKIP_GROUP keylen=%d!\n",
1233 				       __func__, key->keylen);
1234 			}
1235 			break;
1236 		case WLAN_CIPHER_SUITE_CCMP:
1237 			if (pairwise) {
1238 				wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
1239 				memcpy(wsm_key->aesPairwiseKey.peerAddress,
1240 				       peer_addr, ETH_ALEN);
1241 				memcpy(wsm_key->aesPairwiseKey.aesKeyData, &key->key[0], 16);
1242 				sta_printk(XRADIO_DBG_NIY, "%s: CCMP_PAIRWISE keylen=%d!\n",
1243 				       __func__, key->keylen);
1244 			} else {
1245 				wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
1246 				memcpy(wsm_key->aesGroupKey.aesKeyData, &key->key[0], 16);
1247 				/* TODO: Where can I find AES SEQ? */
1248 				memset(wsm_key->aesGroupKey.rxSeqCounter, 0, 8);
1249 				wsm_key->aesGroupKey.keyId = key->keyidx;
1250 				sta_printk(XRADIO_DBG_NIY, "%s: CCMP_GROUP keylen=%d!\n",
1251 				       __func__, key->keylen);
1252 			}
1253 			break;
1254 #ifdef CONFIG_XRADIO_WAPI_SUPPORT
1255 		case WLAN_CIPHER_SUITE_SMS4:
1256 			if (pairwise) {
1257 				wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
1258 				memcpy(wsm_key->wapiPairwiseKey.peerAddress,
1259 				       peer_addr, ETH_ALEN);
1260 				memcpy(wsm_key->wapiPairwiseKey.wapiKeyData,
1261 				       &key->key[0],  16);
1262 				memcpy(wsm_key->wapiPairwiseKey.micKeyData,
1263 				       &key->key[16], 16);
1264 				wsm_key->wapiPairwiseKey.keyId = key->keyidx;
1265 				sta_printk(XRADIO_DBG_NIY, "%s: WAPI_PAIRWISE keylen=%d!\n",
1266 				       __func__, key->keylen);
1267 			} else {
1268 				wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
1269 				memcpy(wsm_key->wapiGroupKey.wapiKeyData, &key->key[0],  16);
1270 				memcpy(wsm_key->wapiGroupKey.micKeyData,  &key->key[16], 16);
1271 				wsm_key->wapiGroupKey.keyId = key->keyidx;
1272 				sta_printk(XRADIO_DBG_NIY, "%s: WAPI_GROUP keylen=%d!\n",
1273 				       __func__, key->keylen);
1274 			}
1275 			break;
1276 #endif /* CONFIG_XRADIO_WAPI_SUPPORT */
1277 		case WLAN_CIPHER_SUITE_AES_CMAC:
1278 			if (pairwise) {
1279 				sta_printk(XRADIO_DBG_ERROR, "%s: WLAN_CIPHER_SUITE_AES_CMAC but pairwise %d\n",
1280 					__func__, pairwise);
1281 				ret = -EINVAL;
1282 				goto finally;
1283 			} else {
1284 				wsm_key->type = WSM_KEY_TYPE_IGTK_GROUP;
1285 				memcpy(wsm_key->igtkGroupKey.igtkKeyData, &key->key[0], 16);
1286 				wsm_key->igtkGroupKey.keyId = key->keyidx;
1287 				memset(wsm_key->igtkGroupKey.ipn, 0, 8);
1288 				memcpy(wsm_key->igtkGroupKey.ipn, &key->tx_pn, 6);
1289 				sta_printk(XRADIO_DBG_NIY, "%s: IGTK_GROUP keylen=%d!\n",
1290 				       __func__, key->keylen);
1291 
1292 				mgmt_policy.protectedMgmtEnable = 1;
1293 				mgmt_policy.unprotectedMgmtFramesAllowed = 1;
1294 				mgmt_policy.encryptionForAuthFrame = 1;
1295 				wsm_set_protected_mgmt_policy(hw_priv, &mgmt_policy, priv->if_id);
1296 
1297 				if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
1298 					priv->is_mfp_connect = true;
1299 				}
1300 			}
1301 			break;
1302 		default:
1303 			sta_printk(XRADIO_DBG_ERROR, "%s: key->cipher unknown(%d)!\n",
1304 				   __func__, key->cipher);
1305 			xradio_free_key(hw_priv, idx);
1306 			ret = -EOPNOTSUPP;
1307 			goto finally;
1308 		}
1309 		ret = SYS_WARN(wsm_add_key(hw_priv, wsm_key, priv->if_id));
1310 		if (!ret)
1311 			key->hw_key_idx = idx;
1312 		else
1313 			xradio_free_key(hw_priv, idx);
1314 
1315 		if (!ret && (pairwise || wsm_key->type == WSM_KEY_TYPE_WEP_DEFAULT)) {
1316 			priv->unicast_cipher_type = key->cipher;
1317 		}
1318 
1319 		if (!ret && (pairwise || wsm_key->type == WSM_KEY_TYPE_WEP_DEFAULT)
1320 		    && (priv->filter4.enable & 0x2))
1321 			xradio_set_arpreply(dev, vif);
1322 #ifdef IPV6_FILTERING
1323 		if (!ret && (pairwise || wsm_key->type == WSM_KEY_TYPE_WEP_DEFAULT)
1324 		    && (priv->filter6.enable & 0x2))
1325 			xradio_set_na(dev, vif);
1326 #endif /*IPV6_FILTERING*/
1327 
1328 	} else if (cmd == DISABLE_KEY) {
1329 		struct wsm_remove_key wsm_key = {
1330 			.entryIndex = key->hw_key_idx,
1331 		};
1332 
1333 		if (wsm_key.entryIndex > WSM_KEY_MAX_IDX) {
1334 			ret = -EINVAL;
1335 			goto finally;
1336 		}
1337 
1338 		xradio_free_key(hw_priv, wsm_key.entryIndex);
1339 		ret = wsm_remove_key(hw_priv, &wsm_key, priv->if_id);
1340 	} else {
1341 		sta_printk(XRADIO_DBG_ERROR, "%s: Unsupported command", __func__);
1342 	}
1343 
1344 finally:
1345 	up(&hw_priv->conf_lock);
1346 	return ret;
1347 }
1348 
xradio_wep_key_work(struct work_struct * work)1349 void xradio_wep_key_work(struct work_struct *work)
1350 {
1351 	struct xradio_vif *priv =
1352 		container_of(work, struct xradio_vif, wep_key_work);
1353 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
1354 	u8 queueId = xradio_queue_get_queue_id(hw_priv->pending_frame_id);
1355 	struct xradio_queue *queue = &hw_priv->tx_queue[queueId];
1356 	__le32 wep_default_key_id = __cpu_to_le32(priv->wep_default_key_id);
1357 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1358 
1359 	SYS_BUG(queueId >= 4);
1360 
1361 	sta_printk(XRADIO_DBG_MSG, "Setting default WEP key: %d\n",
1362 		   priv->wep_default_key_id);
1363 
1364 	wsm_flush_tx(hw_priv);
1365 	SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
1366 			       &wep_default_key_id, sizeof(wep_default_key_id),
1367 			       priv->if_id));
1368 
1369 #ifdef CONFIG_XRADIO_TESTMODE
1370 	xradio_queue_requeue(hw_priv, queue, hw_priv->pending_frame_id, true);
1371 #else
1372 	xradio_queue_requeue(queue, hw_priv->pending_frame_id, true);
1373 #endif
1374 	wsm_unlock_tx(hw_priv);
1375 }
1376 
1377 #if 0
1378 int xradio_set_rts_threshold(struct ieee80211_hw *hw,
1379 		struct ieee80211_vif *vif, u32 value)
1380 {
1381 	struct xradio_common *hw_priv = hw->priv;
1382 	int ret;
1383 	__le32 val32;
1384 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
1385 	int if_id = priv->if_id;
1386 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1387 	if (!atomic_read(&priv->enabled)) {
1388 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1389 				__func__, vif->type);
1390 		return 0;
1391 	}
1392 
1393 #ifdef P2P_MULTIVIF
1394 	SYS_WARN(priv->if_id == XRWL_GENERIC_IF_ID);
1395 #endif
1396 
1397 	if (value != (u32)-1)
1398 		val32 = __cpu_to_le32(value);
1399 	else
1400 		val32 = 0;	/* disabled */
1401 
1402 	sta_printk(XRADIO_DBG_WARN, "%s if=%d, value=%d\n",
1403 				__func__, if_id, val32);
1404 	/* mutex_lock(&priv->conf_mutex); */
1405 	ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
1406 		&val32, sizeof(val32), if_id));
1407 	/* mutex_unlock(&priv->conf_mutex); */
1408 	return ret;
1409 }
1410 #endif
1411 
xradio_set_rts_thresholds(struct ieee80211_hw * hw,u32 value)1412 int xradio_set_rts_thresholds(struct ieee80211_hw *hw, u32 value)
1413 {
1414 #if 0
1415 	int err;
1416 	err = mac80211_set_rts_thresholds(hw, value);
1417 	return err;
1418 #endif
1419 
1420 	struct xradio_common *hw_priv = hw->priv;
1421 	int ret, i, if_id;
1422 	__le32 val32;
1423 	struct xradio_vif *priv;
1424 
1425 	for (i = 0; i < XRWL_GENERIC_IF_ID; i++) {
1426 		priv = __xrwl_hwpriv_to_vifpriv(hw_priv, i);
1427 
1428 		if (priv == NULL)
1429 			continue;
1430 
1431 		if_id = priv->if_id;
1432 		sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1433 		if (!atomic_read(&priv->enabled)) {
1434 			sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1435 					__func__, hw_priv->vif_list[if_id]->type);
1436 			return 0;
1437 		}
1438 
1439 #ifdef P2P_MULTIVIF
1440 		SYS_WARN(priv->if_id == XRWL_GENERIC_IF_ID);
1441 #endif
1442 
1443 		if (value != (u32)-1)
1444 			val32 = __cpu_to_le32(value);
1445 		else
1446 			val32 = 0;	/* disabled */
1447 
1448 		sta_printk(XRADIO_DBG_WARN, "%s if=%d, value=%d\n",
1449 					__func__, if_id, val32);
1450 		/* mutex_lock(&priv->conf_mutex); */
1451 		ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
1452 			&val32, sizeof(val32), if_id));
1453 		/* mutex_unlock(&priv->conf_mutex); */
1454 	}
1455 
1456 	return ret;
1457 }
1458 
1459 /* TODO: COMBO: Flush only a particular interface specific parts */
__xradio_flush(struct xradio_common * hw_priv,bool drop,int if_id)1460 int __xradio_flush(struct xradio_common *hw_priv, bool drop, int if_id)
1461 {
1462 	int i, ret;
1463 	struct xradio_vif *priv =
1464 		__xrwl_hwpriv_to_vifpriv(hw_priv, if_id);
1465 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1466 
1467 	if (!priv) {
1468 		SYS_WARN(1);
1469 		return -ENOMEM;
1470 	}
1471 
1472 	for (;;) {
1473 		/* TODO: correct flush handling is required when dev_stop.
1474 		 * Temporary workaround: 2s
1475 		 */
1476 		if (drop) {
1477 			for (i = 0; i < 4; ++i)
1478 				xradio_queue_clear(&hw_priv->tx_queue[i], if_id);
1479 		} else if (!hw_priv->bh_error) {
1480 			ret = wait_event_timeout(
1481 				hw_priv->tx_queue_stats.wait_link_id_empty,
1482 				xradio_queue_stats_is_empty(&hw_priv->tx_queue_stats,
1483 							    -1, if_id),
1484 				2 * HZ);
1485 		} else { /* don't wait when bh error */
1486 			sta_printk(XRADIO_DBG_ERROR, " %s:bh_error occur.\n", __func__);
1487 			ret = -1;
1488 			break;
1489 		}
1490 
1491 		if (!drop && unlikely(ret <= 0)) {
1492 			sta_printk(XRADIO_DBG_ERROR, " %s: timeout...\n", __func__);
1493 			ret = -ETIMEDOUT;
1494 			break;
1495 		} else {
1496 			ret = 0;
1497 		}
1498 
1499 		wsm_vif_lock_tx(priv);
1500 		if (unlikely(!xradio_queue_stats_is_empty(&hw_priv->tx_queue_stats,
1501 				  -1, if_id))) {
1502 			/* Highly unlekely: WSM requeued frames. */
1503 			wsm_unlock_tx(hw_priv);
1504 			continue;
1505 		}
1506 		wsm_unlock_tx(hw_priv);
1507 		break;
1508 	}
1509 	return ret;
1510 }
1511 
xradio_flush(struct ieee80211_hw * hw,struct ieee80211_vif * vif,u32 queues,bool drop)1512 void xradio_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues,
1513 			  bool drop)
1514 {
1515 	struct xradio_common *hw_priv = hw->priv;
1516 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
1517 	int suspend_lock_state;
1518 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1519 
1520 	if (vif == NULL) {
1521 		sta_printk(XRADIO_DBG_WARN, "%s vif is null return\n", __func__);
1522 		return;
1523 	}
1524 
1525 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
1526 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
1527 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
1528 		sta_printk(XRADIO_DBG_WARN,
1529 			   "%s:refuse because of suspend\n", __func__);
1530 		return;
1531 	}
1532 
1533 	down(&hw_priv->conf_lock);
1534 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
1535 	/*TODO:COMBO: reenable this part of code when flush callback
1536 	 * is implemented per vif */
1537 	/*switch (hw_priv->mode) {
1538 	case NL80211_IFTYPE_MONITOR:
1539 		drop = true;
1540 		break;
1541 	case NL80211_IFTYPE_AP:
1542 		if (!hw_priv->enable_beacon)
1543 			drop = true;
1544 		break;
1545 	}*/
1546 
1547 	if (!(hw_priv->if_id_slot & BIT(priv->if_id)))
1548 		goto exit;
1549 	if (!atomic_read(&priv->enabled)) {
1550 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1551 				__func__, vif->type);
1552 		goto exit;
1553 	}
1554 	up(&hw_priv->conf_lock);
1555 	__xradio_flush(hw_priv, drop, priv->if_id);
1556 	return;
1557 
1558 exit:
1559 	up(&hw_priv->conf_lock);
1560 	return;
1561 }
1562 
1563 #ifdef MONITOR_MODE
xradio_enable_monitoring(struct xradio_vif * priv,struct ieee80211_channel * chan)1564 int xradio_enable_monitoring(struct xradio_vif *priv,
1565 				     struct ieee80211_channel *chan)
1566 {
1567 
1568 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
1569 
1570 #ifdef SUPPORT_HT40
1571 
1572 	struct wsm_start start = {
1573 		.mode = WSM_START_MODE_MONITOR,
1574 		.PhyModeCfg.BandCfg = chan->band,
1575 		.channelNumber = chan->hw_value,
1576 	};
1577 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1578 
1579 #else
1580 
1581 	struct wsm_start start = {
1582 		.mode = WSM_START_MODE_MONITOR,
1583 		.band = (chan->band == NL80211_BAND_5GHZ) ?
1584 				WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
1585 		.channelNumber = chan->hw_value,
1586 	};
1587 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1588 
1589 #endif
1590 
1591 	SYS_WARN(hw_priv->monitor_if_id < 0);
1592 	SYS_WARN(priv->join_status > XRADIO_JOIN_STATUS_MONITOR);
1593 	priv->join_status = XRADIO_JOIN_STATUS_MONITOR;
1594 	hw_priv->monitor_running = true;
1595 
1596 	return wsm_start(hw_priv, &start, hw_priv->monitor_if_id);
1597 }
1598 
xradio_disable_monitoring(struct xradio_vif * priv)1599 int xradio_disable_monitoring(struct xradio_vif *priv)
1600 {
1601 	int ret;
1602 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
1603 	struct wsm_reset reset = {
1604 		.reset_statistics = true,
1605 	};
1606 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1607 
1608 	SYS_WARN(priv->join_status != XRADIO_JOIN_STATUS_MONITOR);
1609 	SYS_WARN(hw_priv->monitor_if_id < 0);
1610 	priv->join_status = XRADIO_JOIN_STATUS_PASSIVE;
1611 	hw_priv->monitor_if_id = -1;
1612 	hw_priv->monitor_running = false;
1613 
1614 	ret = wsm_reset(hw_priv, &reset, hw_priv->monitor_if_id);
1615 	return ret;
1616 }
1617 
xradio_channel_switch(struct xradio_common * hw_priv,struct ieee80211_channel * chan)1618 void xradio_channel_switch(struct xradio_common *hw_priv,
1619 			   struct ieee80211_channel *chan)
1620 {
1621 	struct wsm_switch_channel switch_arg = {
1622 		.channelMode = 1,
1623 		.channelSwitchCount = 0,
1624 		.newChannelNumber = chan->hw_value,
1625 	};
1626 
1627 	WARN_ON(hw_priv->monitor_if_id == -1);
1628 	wsm_switch_channel(hw_priv, &switch_arg, hw_priv->monitor_if_id);
1629 
1630 }
1631 #endif
xradio_remain_on_channel(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_channel * chan,int duration,enum ieee80211_roc_type type)1632 int xradio_remain_on_channel(struct ieee80211_hw *hw,
1633 				struct ieee80211_vif *vif,
1634 			     struct ieee80211_channel *chan,
1635 			     int duration, enum ieee80211_roc_type type)
1636 {
1637 	int ret;
1638 	struct xradio_common *hw_priv = hw->priv;
1639 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
1640 	int if_id = priv->if_id;
1641 	int suspend_lock_state;
1642 #ifdef	TES_P2P_0002_ROC_RESTART
1643 	struct timespec64 TES_P2P_0002_tmval;
1644 #endif
1645 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1646 
1647 #ifdef	TES_P2P_0002_ROC_RESTART
1648 	xr_do_gettimeofday(&TES_P2P_0002_tmval);
1649 	TES_P2P_0002_roc_dur = (s32) duration;
1650 	TES_P2P_0002_roc_sec = (s32) TES_P2P_0002_tmval.tv_sec;
1651 	TES_P2P_0002_roc_usec = (s32) TES_P2P_0002_tmval.tv_nsec / 1000;
1652 #endif
1653 
1654 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
1655 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
1656 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
1657 		sta_printk(XRADIO_DBG_WARN,
1658 			   "%s:refuse because of suspend\n", __func__);
1659 		return -EBUSY;
1660 	}
1661 
1662 	down(&hw_priv->scan.lock);
1663 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
1664 	if (!atomic_read(&priv->enabled)) {
1665 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
1666 				__func__, vif->type);
1667 		up(&hw_priv->scan.lock);
1668 		return 0;
1669 	}
1670 
1671 #ifdef ROC_DEBUG
1672 	sta_printk(XRADIO_DBG_WARN, "ROC IN %d ch %d\n",
1673 		   priv->if_id, chan->hw_value);
1674 #endif
1675 	ret = SYS_WARN(__xradio_flush(hw_priv, false, if_id));
1676 	down(&hw_priv->conf_lock);
1677 	hw_priv->roc_if_id = priv->if_id;
1678 	xradio_enable_listening(priv, chan);
1679 
1680 	if (!ret) {
1681 		atomic_set(&hw_priv->remain_on_channel, 1);
1682 		queue_delayed_work(hw_priv->spare_workqueue, &hw_priv->rem_chan_timeout,
1683 				   duration * HZ / 1000);
1684 		priv->join_status = XRADIO_JOIN_STATUS_MONITOR;
1685 		mac80211_ready_on_channel(hw);
1686 	} else {
1687 		hw_priv->roc_if_id = -1;
1688 		up(&hw_priv->scan.lock);
1689 	}
1690 
1691 #ifdef ROC_DEBUG
1692 	sta_printk(XRADIO_DBG_WARN, "ROC OUT %d\n", priv->if_id);
1693 #endif
1694 	/* set the channel to supplied ieee80211_channel pointer, if it
1695 	   is not set. This is to remove the crash while sending a probe res
1696 	   in listen state. Later channel will updated on
1697 	   IEEE80211_CONF_CHANGE_CHANNEL event */
1698 	if (!hw_priv->channel) {
1699 		hw_priv->channel = chan;
1700 	}
1701 	//hw_priv->roc_cookie = cookie;
1702 	up(&hw_priv->conf_lock);
1703 	return ret;
1704 }
1705 
1706 
xradio_cancel_rem_chan(struct xradio_common * hw_priv)1707 void xradio_cancel_rem_chan(struct xradio_common *hw_priv)
1708 {
1709 	int ret, if_id;
1710 	struct xradio_vif *priv;
1711 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1712 
1713 #ifdef TES_P2P_0002_ROC_RESTART
1714 	if (TES_P2P_0002_state == TES_P2P_0002_STATE_GET_PKTID) {
1715 		sta_printk(XRADIO_DBG_WARN, "[Restart rem_chan_timeout:Timeout]\n");
1716 		return;
1717 	}
1718 #endif
1719 
1720 	if (atomic_read(&hw_priv->remain_on_channel) == 0) {
1721 		return;
1722 	}
1723 
1724 	down(&hw_priv->conf_lock);
1725 	if_id = hw_priv->roc_if_id;
1726 #ifdef ROC_DEBUG
1727 	sta_printk(XRADIO_DBG_ERROR, "ROC TO IN %d\n", if_id);
1728 #endif
1729 	priv = __xrwl_hwpriv_to_vifpriv(hw_priv, if_id);
1730 	up(&hw_priv->conf_lock);
1731 	ret = SYS_WARN(__xradio_flush(hw_priv, false, if_id));
1732 	down(&hw_priv->conf_lock);
1733 	if (!ret) {
1734 		xradio_disable_listening(priv);
1735 	}
1736 	atomic_set(&hw_priv->remain_on_channel, 0);
1737 	hw_priv->roc_if_id = -1;
1738 
1739 #ifdef ROC_DEBUG
1740 	sta_printk(XRADIO_DBG_ERROR, "ROC TO OUT %d\n", if_id);
1741 #endif
1742 
1743 	up(&hw_priv->conf_lock);
1744 	up(&hw_priv->scan.lock);
1745 }
1746 
1747 
xradio_cancel_remain_on_channel(struct ieee80211_hw * hw,struct ieee80211_vif * vif)1748 int xradio_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1749 {
1750 	struct xradio_common *hw_priv = hw->priv;
1751 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1752 
1753 	sta_printk(XRADIO_DBG_NIY, "Cancel remain on channel\n");
1754 #ifdef TES_P2P_0002_ROC_RESTART
1755 	if (TES_P2P_0002_state == TES_P2P_0002_STATE_GET_PKTID) {
1756 		TES_P2P_0002_state = TES_P2P_0002_STATE_IDLE;
1757 		sta_printk(XRADIO_DBG_WARN, "[ROC_RESTART_STATE_IDLE][Cancel ROC]\n");
1758 	}
1759 #endif
1760 
1761 	if (atomic_read(&hw_priv->remain_on_channel))
1762 		cancel_delayed_work_sync(&hw_priv->rem_chan_timeout);
1763 
1764 	if (atomic_read(&hw_priv->remain_on_channel))
1765 		xradio_cancel_rem_chan(hw_priv);
1766 
1767 	return 0;
1768 }
1769 
1770 /* ******************************************************************** */
1771 /* WSM callbacks							*/
1772 
xradio_channel_switch_cb(struct xradio_common * hw_priv)1773 void xradio_channel_switch_cb(struct xradio_common *hw_priv)
1774 {
1775 /*   wsm_unlock_tx(hw_priv);*/
1776 }
1777 
xradio_free_event_queue(struct xradio_common * hw_priv)1778 void xradio_free_event_queue(struct xradio_common *hw_priv)
1779 {
1780 	LIST_HEAD(list);
1781 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1782 
1783 	spin_lock(&hw_priv->event_queue_lock);
1784 	list_splice_init(&hw_priv->event_queue, &list);
1785 	spin_unlock(&hw_priv->event_queue_lock);
1786 
1787 	__xradio_free_event_queue(&list);
1788 }
1789 
xradio_event_handler(struct work_struct * work)1790 void xradio_event_handler(struct work_struct *work)
1791 {
1792 	struct xradio_common *hw_priv =
1793 	    container_of(work, struct xradio_common, event_handler);
1794 	struct xradio_vif *priv;
1795 	struct xradio_wsm_event *event;
1796 	LIST_HEAD(list);
1797 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1798 
1799 	spin_lock(&hw_priv->event_queue_lock);
1800 	list_splice_init(&hw_priv->event_queue, &list);
1801 	spin_unlock(&hw_priv->event_queue_lock);
1802 
1803 	down(&hw_priv->conf_lock);
1804 	list_for_each_entry(event, &list, link) {
1805 		priv = __xrwl_hwpriv_to_vifpriv(hw_priv, event->if_id);
1806 		if (!priv) {
1807 			sta_printk(XRADIO_DBG_WARN, "[CQM] Event for non existing "
1808 				   "interface, ignoring.\n");
1809 			continue;
1810 		}
1811 		switch (event->evt.eventId) {
1812 		case WSM_EVENT_ERROR:
1813 			/* I even don't know what is it about.. */
1814 			sta_printk(XRADIO_DBG_ERROR, "%s FW error=0x%x\n",
1815 					__func__, event->evt.eventData);
1816 			break;
1817 		case WSM_EVENT_BSS_LOST:
1818 			{
1819 				spin_lock(&priv->bss_loss_lock);
1820 				if (priv->bss_loss_status > XRADIO_BSS_LOSS_NONE) {
1821 					spin_unlock(&priv->bss_loss_lock);
1822 					break;
1823 				}
1824 				priv->bss_loss_status = XRADIO_BSS_LOSS_CHECKING;
1825 				spin_unlock(&priv->bss_loss_lock);
1826 				sta_printk(XRADIO_DBG_WARN,
1827 					   "[CQM] BSS lost, Beacon miss=%d, event=%x.\n",
1828 					   (event->evt.eventData >> 8) & 0xff,
1829 					   event->evt.eventData & 0xff);
1830 
1831 				cancel_delayed_work_sync(&priv->bss_loss_work);
1832 				cancel_delayed_work_sync(&priv->connection_loss_work);
1833 				if (!down_trylock(&hw_priv->scan.lock)) {
1834 					up(&hw_priv->scan.lock);
1835 					priv->delayed_link_loss = 0;
1836 					queue_delayed_work(hw_priv->workqueue,
1837 							&priv->bss_loss_work, HZ/10); /* 100ms */
1838 				} else {
1839 					/* Scan is in progress. Delay reporting. */
1840 					/* Scan complete will trigger bss_loss_work */
1841 					priv->delayed_link_loss = 1;
1842 					/* Also we're starting watchdog. */
1843 					queue_delayed_work(hw_priv->workqueue,
1844 							&priv->bss_loss_work, 10 * HZ);
1845 				}
1846 				break;
1847 			}
1848 		case WSM_EVENT_BSS_REGAINED:
1849 			{
1850 				sta_printk(XRADIO_DBG_WARN, "[CQM] BSS regained.\n");
1851 				priv->delayed_link_loss = 0;
1852 				spin_lock(&priv->bss_loss_lock);
1853 				priv->bss_loss_status = XRADIO_BSS_LOSS_NONE;
1854 				spin_unlock(&priv->bss_loss_lock);
1855 				cancel_delayed_work_sync(&priv->bss_loss_work);
1856 				cancel_delayed_work_sync(&priv->connection_loss_work);
1857 				break;
1858 			}
1859 		case WSM_EVENT_RADAR_DETECTED:
1860 			sta_printk(XRADIO_DBG_WARN,
1861 				"%s WSM_EVENT_RADAR_DETECTED\n", __func__);
1862 			/*STUB();*/
1863 			break;
1864 		case WSM_EVENT_RCPI_RSSI:
1865 			{
1866 				/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1867 				 * RSSI = RCPI / 2 - 110 */
1868 				int rcpiRssi = (int)(event->evt.eventData & 0xFF);
1869 				int cqm_evt;
1870 
1871 				if (priv->cqm_use_rssi)
1872 					rcpiRssi = (s8)rcpiRssi;
1873 				else
1874 					rcpiRssi =  rcpiRssi / 2 - 110;
1875 
1876 				cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ?
1877 					NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
1878 					NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
1879 				sta_printk(XRADIO_DBG_NIY, "[CQM] RSSI event: %d", rcpiRssi);
1880 				mac80211_cqm_rssi_notify(priv->vif, cqm_evt, rcpiRssi, GFP_KERNEL);
1881 				break;
1882 			}
1883 		case WSM_EVENT_BT_INACTIVE:
1884 			if (hw_priv->is_BT_Present) {
1885 				u8 bt_link_type = ((event->evt.eventData>>16) & 0xff);
1886 				bool is_bt_block = xradio_is_bt_block(hw_priv);
1887 				hw_priv->BT_active &= ~xradio_bt_active_bit(bt_link_type);
1888 				if (is_bt_block && !xradio_is_bt_block(hw_priv)) {
1889 					xradio_proc_wakeup(hw_priv);
1890 				}
1891 				sta_printk(XRADIO_DBG_NIY,
1892 					"%s WSM_EVENT_BT_INACTIVE, type=%u\n",
1893 					__func__, bt_link_type);
1894 			} else {
1895 				sta_printk(XRADIO_DBG_WARN,
1896 					"%s WSM_EVENT_BT_INACTIVE, but BT is NOT Present!\n",
1897 					__func__);
1898 			}
1899 			/*STUB();*/
1900 			break;
1901 		case WSM_EVENT_BT_ACTIVE:
1902 			if (hw_priv->is_BT_Present) {
1903 				u8 bt_link_type = ((event->evt.eventData>>16) & 0xff);
1904 				u16 bt_duration = (event->evt.eventData & 0xffff);
1905 				del_timer_sync(&hw_priv->BT_timer);
1906 				if (xradio_bt_block_type(bt_link_type)) {
1907 					unsigned long new_time = 0;
1908 					if (bt_duration > BT_MAX_BLOCK_TIME) {
1909 						sta_printk(XRADIO_DBG_WARN,
1910 						"%s WSM_EVENT_BT_ACTIVE, type=%u, Duration=%u\n",
1911 						__func__, bt_link_type, bt_duration);
1912 						bt_duration = BT_MAX_BLOCK_TIME;
1913 					}
1914 					new_time = jiffies + msecs_to_jiffies(bt_duration);
1915 					if (!xradio_is_bt_block(hw_priv)) {
1916 						hw_priv->BT_duration = new_time;  /* init */
1917 					} else if (time_before(hw_priv->BT_duration, new_time)) {
1918 						hw_priv->BT_duration = new_time;  /* updata */
1919 					}
1920 				}
1921 				hw_priv->BT_active |= xradio_bt_active_bit(bt_link_type);
1922 				if (xradio_is_bt_block(hw_priv)) {
1923 					if (time_before(jiffies, hw_priv->BT_duration))
1924 						mod_timer(&hw_priv->BT_timer, hw_priv->BT_duration);
1925 					else
1926 						mod_timer(&hw_priv->BT_timer, jiffies + 1);
1927 				}
1928 				sta_printk(XRADIO_DBG_NIY,
1929 					"%s WSM_EVENT_BT_ACTIVE, type=%u, Duration=%ums, time=%ld\n",
1930 					__func__, bt_link_type, bt_duration, hw_priv->BT_duration);
1931 			} else {
1932 				sta_printk(XRADIO_DBG_WARN,
1933 					"%s WSM_EVENT_BT_ACTIVE, but BT is NOT Present!\n",
1934 					__func__);
1935 			}
1936 			/*STUB();*/
1937 			break;
1938 		case WSM_EVENT_PAS_EVENT:
1939 			sta_printk(XRADIO_DBG_WARN,
1940 				"%s WSM_EVENT_PAS_EVENT\n", __func__);
1941 			break;
1942 		case WSM_EVENT_INACTIVITY:
1943 			{
1944 				int link_id = ffs((u32)(event->evt.eventData)) - 1;
1945 				struct sk_buff *skb;
1946 				struct ieee80211_mgmt *deauth;
1947 				struct xradio_link_entry *entry = NULL;
1948 
1949 				sta_printk(XRADIO_DBG_WARN, "Inactivity Event Recieved for "
1950 						"link_id %d\n", link_id);
1951 				skb = xr_alloc_skb(sizeof(struct ieee80211_mgmt) + 64);
1952 				if (!skb)
1953 					break;
1954 				skb_reserve(skb, 64);
1955 				xrwl_unmap_link(priv, link_id);
1956 
1957 				deauth = (struct ieee80211_mgmt *)skb_put(skb, sizeof(struct ieee80211_mgmt));
1958 				SYS_WARN(!deauth);
1959 				entry = &priv->link_id_db[link_id - 1];
1960 				deauth->duration = 0;
1961 				memcpy(deauth->da, priv->vif->addr, ETH_ALEN);
1962 				memcpy(deauth->sa, entry->mac/*priv->link_id_db[i].mac*/, ETH_ALEN);
1963 				memcpy(deauth->bssid, priv->vif->addr, ETH_ALEN);
1964 				deauth->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1965 								    IEEE80211_STYPE_DEAUTH);
1966 				deauth->u.deauth.reason_code = WLAN_REASON_DEAUTH_LEAVING;
1967 				deauth->seq_ctrl = 0;
1968 				mac80211_rx_irqsafe(priv->hw, skb);
1969 				sta_printk(XRADIO_DBG_WARN, "Inactivity Deauth Frame sent" \
1970 					   " for MAC SA %pM and DA %pM\n",
1971 					   deauth->sa, deauth->da);
1972 				queue_work(priv->hw_priv->workqueue, &priv->set_tim_work);
1973 				break;
1974 			}
1975 		case WSM_EVENT_PS_MODE_ERROR:
1976 			sta_printk(XRADIO_DBG_WARN, "%s EVENT_PS_MODE_ERROR\n", __func__);
1977 #if 0
1978 			{
1979 				if (!priv->uapsd_info.uapsdFlags &&
1980 					(priv->user_pm_mode != WSM_PSM_PS)) {
1981 					struct wsm_set_pm pm = priv->powersave_mode;
1982 					int ret = 0;
1983 
1984 					priv->powersave_mode.pmMode = WSM_PSM_ACTIVE;
1985 					ret = xradio_set_pm (priv, &priv->powersave_mode);
1986 					if (ret)
1987 						priv->powersave_mode = pm;
1988 				}
1989 				break;
1990 			}
1991 #else
1992 			break;
1993 #endif
1994 		}
1995 	}
1996 	up(&hw_priv->conf_lock);
1997 	__xradio_free_event_queue(&list);
1998 }
1999 
xradio_bss_loss_work(struct work_struct * work)2000 void xradio_bss_loss_work(struct work_struct *work)
2001 {
2002 	struct xradio_vif *priv =
2003 	    container_of(work, struct xradio_vif, bss_loss_work.work);
2004 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2005 	int timeout;		/* in beacons */
2006 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2007 
2008 	timeout = priv->cqm_link_loss_count - priv->cqm_beacon_loss_count;
2009 	/* Skip the confimration procedure in P2P case */
2010 	if (priv->vif->p2p)
2011 		goto report;
2012 
2013 	spin_lock(&priv->bss_loss_lock);
2014 	if (priv->bss_loss_status == XRADIO_BSS_LOSS_CONFIRMING) {
2015 		/*do loss report next time.*/
2016 		priv->bss_loss_status = XRADIO_BSS_LOSS_CONFIRMED;
2017 		spin_unlock(&priv->bss_loss_lock);
2018 		/*wait for more 1s to loss confirm.*/
2019 		queue_delayed_work(hw_priv->workqueue, &priv->bss_loss_work, 1 * HZ);
2020 		return;
2021 	} else if (priv->bss_loss_status == XRADIO_BSS_LOSS_NONE) {
2022 		spin_unlock(&priv->bss_loss_lock);
2023 		/*link is alive.*/
2024 		cancel_delayed_work_sync(&priv->connection_loss_work);
2025 		return;
2026 	} else if (priv->bss_loss_status == XRADIO_BSS_LOSS_CHECKING) {
2027 		/* it mean no confirming packets, just report loss. */
2028 	}
2029 	spin_unlock(&priv->bss_loss_lock);
2030 
2031 report:
2032 	if (priv->cqm_beacon_loss_count) {
2033 		sta_printk(XRADIO_DBG_WARN, "[CQM] Beacon loss.\n");
2034 		if (timeout <= 0)
2035 			timeout = 0;
2036 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
2037 		/*ieee80211_cqm_beacon_miss_notify(priv->vif, GFP_KERNEL);*/
2038 #endif /* CONFIG_XRADIO_USE_EXTENSIONS */
2039 	} else {
2040 		timeout = 0;
2041 	}
2042 
2043 	cancel_delayed_work_sync(&priv->connection_loss_work);
2044 	queue_delayed_work(hw_priv->workqueue, &priv->connection_loss_work,
2045 			   timeout * HZ / 10);
2046 
2047 	spin_lock(&priv->bss_loss_lock);
2048 	priv->bss_loss_status = XRADIO_BSS_LOSS_NONE;
2049 	spin_unlock(&priv->bss_loss_lock);
2050 }
2051 
xradio_connection_loss_work(struct work_struct * work)2052 void xradio_connection_loss_work(struct work_struct *work)
2053 {
2054 	struct xradio_vif *priv =
2055 	  container_of(work, struct xradio_vif, connection_loss_work.work);
2056 	sta_printk(XRADIO_DBG_ERROR, "[CQM] if%d Reporting connection loss.\n",
2057 		   priv->if_id);
2058 	mac80211_connection_loss(priv->vif);
2059 }
2060 
xradio_tx_failure_work(struct work_struct * work)2061 void xradio_tx_failure_work(struct work_struct *work)
2062 {
2063 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
2064 	/*
2065 	struct xradio_vif *priv =
2066 		container_of(work, struct xradio_vif, tx_failure_work);
2067 	sta_printk(XRADIO_DBG_WARN, "[CQM] Reporting TX failure.\n");
2068 	ieee80211_cqm_tx_fail_notify(priv->vif, GFP_KERNEL);
2069 	*/
2070 #endif /* CONFIG_XRADIO_USE_EXTENSIONS */
2071 }
2072 
2073 #ifdef CONFIG_XRADIO_TESTMODE
2074 /**
2075  * xradio_device_power_calc- Device power calculation
2076  * from values fetch from SDD File.
2077  *
2078  * @priv: the private structure
2079  * @Max_output_power: Power fetch from SDD
2080  * @fe_cor: front-end loss correction
2081  * @band: Either 2GHz or 5GHz
2082  *
2083  */
xradio_device_power_calc(struct xradio_common * hw_priv,s16 max_output_power,s16 fe_cor,u32 band)2084 void xradio_device_power_calc(struct xradio_common *hw_priv,
2085 		s16 max_output_power, s16 fe_cor, u32 band)
2086 {
2087 	s16 power_calc;
2088 
2089 	power_calc = max_output_power - fe_cor;
2090 	if ((power_calc % 16) != 0)
2091 		power_calc += 16;
2092 
2093 	hw_priv->txPowerRange[band].max_power_level = power_calc/16;
2094 	/*
2095 	 * 12dBm is control range supported by firmware.
2096 	 * This means absolute min power is
2097 	 * max_power_level - 12.
2098 	 */
2099 	hw_priv->txPowerRange[band].min_power_level =
2100 		hw_priv->txPowerRange[band].max_power_level - 12;
2101 	hw_priv->txPowerRange[band].stepping = 1;
2102 
2103 }
2104 #endif
2105 /* ******************************************************************** */
2106 #ifdef CONFIG_XRADIO_TESTMODE
2107 #define SDD_MAX_OUTPUT_POWER_2G4_ELT_ID 0xE3
2108 #define SDD_MAX_OUTPUT_POWER_5G_ELT_ID  0xE4
2109 #define SDD_FE_COR_2G4_ELT_ID   0x30
2110 #define SDD_FE_COR_5G_ELT_ID    0x31
2111 #define MIN(x, y, z) (x < y ? (x < z ? x : z) : (y < z ? y : z))
xradio_test_pwrlevel(struct xradio_common * hw_priv)2112 static int xradio_test_pwrlevel(struct xradio_common *hw_priv)
2113 {
2114 	int ret = -1;
2115 	int parsedLength = 0;
2116 	struct xradio_sdd *pElement = (struct xradio_sdd *)hw_priv->sdd->data;
2117 
2118 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2119 
2120 	parsedLength += (FIELD_OFFSET(struct xradio_sdd, data) + pElement->length);
2121 	pElement = FIND_NEXT_ELT(pElement);
2122 
2123 	while (parsedLength <= hw_priv->sdd->size) {
2124 		switch (pElement->id) {
2125 		case SDD_MAX_OUTPUT_POWER_2G4_ELT_ID:
2126 			max_output_power_2G = *((s16 *)pElement->data);
2127 			break;
2128 		case SDD_FE_COR_2G4_ELT_ID:
2129 			fe_cor_2G = *((s16 *)pElement->data);
2130 			break;
2131 		case SDD_MAX_OUTPUT_POWER_5G_ELT_ID:
2132 			max_output_power_5G = *((s16 *)(pElement->data + 4));
2133 			break;
2134 		case SDD_FE_COR_5G_ELT_ID:
2135 			fe_cor_5G = MIN(*((s16 *)pElement->data),
2136 					*((s16 *)(pElement->data + 2)),
2137 					*((s16 *)(pElement->data + 4)));
2138 			fe_cor_5G = MIN(fe_cor_5G,
2139 					*((s16 *)(pElement->data + 6)),
2140 					*((s16 *)(pElement->data + 8)));
2141 			break;
2142 		default:
2143 			break;
2144 		}
2145 		parsedLength += (FIELD_OFFSET(struct xradio_sdd, data) +
2146 				 pElement->length);
2147 		pElement = FIND_NEXT_ELT(pElement);
2148 	}
2149 
2150 	/* Max/Min Power Calculation for 2.4G */
2151 	xradio_device_power_calc(hw_priv, max_output_power_2G, fe_cor_2G,
2152 				 NL80211_BAND_2GHZ);
2153 	/* Max/Min Power Calculation for 5G */
2154 	xradio_device_power_calc(hw_priv, max_output_power_5G, fe_cor_5G,
2155 				 NL80211_BAND_5GHZ);
2156 	for (i = 0; i < 2; ++i) {
2157 		sta_printk(XRADIO_DBG_MSG, "Power Values Read from SDD %s:"
2158 			   "min_power_level[%d]: %d max_power_level[%d]:"
2159 			   "%d stepping[%d]: %d\n", __func__, i,
2160 			   hw_priv->txPowerRange[i].min_power_level, i,
2161 			   hw_priv->txPowerRange[i].max_power_level, i,
2162 			   hw_priv->txPowerRange[i].stepping);
2163 	}
2164 	return 0;
2165 }
2166 #endif
2167 
2168 /* Internal API								*/
xradio_setup_mac(struct xradio_common * hw_priv)2169 int xradio_setup_mac(struct xradio_common *hw_priv)
2170 {
2171 	int ret = 0, if_id;
2172 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2173 
2174 	if (hw_priv->sdd) {
2175 		struct wsm_configuration cfg = {
2176 			.dot11StationId = &hw_priv->mac_addr[0],
2177 			.dpdData = hw_priv->sdd->data,
2178 			.dpdData_size = hw_priv->sdd->size,
2179 		};
2180 		for (if_id = 0; if_id < xrwl_get_nr_hw_ifaces(hw_priv);
2181 		     if_id++) {
2182 			/* Set low-power mode. */
2183 			ret |= SYS_WARN(wsm_configuration(hw_priv, &cfg,
2184 				       if_id));
2185 		}
2186 #ifdef CONFIG_XRADIO_TESTMODE
2187 		/* Parse SDD file for power level test */
2188 		xradio_test_pwrlevel(hw_priv);
2189 #endif
2190 		/* wsm_configuration only once, so release it */
2191 		release_firmware(hw_priv->sdd);
2192 		hw_priv->sdd = NULL;
2193 	}
2194 
2195 	/*
2196 	 * It will be different after reinit. So we reset it.
2197 	 * Cause only mac_address of if0 will be changed, we reset it only.
2198 	 */
2199 	if (compare_ether_addr(hw_priv->mac_addr, hw_priv->addresses[0].addr) != 0)
2200 		wsm_write_mib(hw_priv, WSM_MIB_ID_CHANGE_MAC,
2201 			hw_priv->addresses[0].addr, ETH_ALEN, 0);
2202 
2203 	/* BUG:TX output power is not set untill config_xradio is called.
2204 	 * This would lead to 0 power set in fw and would effect scan & p2p-find
2205 	 * Setting to default value here from sdd which would be overwritten when
2206 	 * we make connection to AP.This value is used only during scan & p2p-ops
2207 	 * untill AP connection is made */
2208 	/*BUG:TX output power: Hardcoding to 20dbm if CCX is not enabled*/
2209 	/*TODO: This might change*/
2210 	if (!hw_priv->output_power)
2211 		hw_priv->output_power = 20;
2212 	sta_printk(XRADIO_DBG_MSG, "%s output power %d\n",
2213 		   __func__, hw_priv->output_power);
2214 
2215 	return ret;
2216 }
2217 
xradio_pending_offchanneltx_work(struct work_struct * work)2218 void xradio_pending_offchanneltx_work(struct work_struct *work)
2219 {
2220 	struct xradio_vif *priv =
2221 	container_of(work, struct xradio_vif, pending_offchanneltx_work.work);
2222 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2223 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2224 
2225 	down(&hw_priv->conf_lock);
2226 #ifdef ROC_DEBUG
2227 	sta_printk(XRADIO_DBG_WARN, "OFFCHAN PEND IN\n");
2228 #endif
2229 	xradio_disable_listening(priv);
2230 	hw_priv->roc_if_id = -1;
2231 #ifdef ROC_DEBUG
2232 	sta_printk(XRADIO_DBG_WARN, "OFFCHAN PEND OUT\n");
2233 #endif
2234 	up(&hw_priv->scan.lock);
2235 	up(&hw_priv->conf_lock);
2236 }
2237 
xradio_offchannel_work(struct work_struct * work)2238 void xradio_offchannel_work(struct work_struct *work)
2239 {
2240 	struct xradio_vif *priv =
2241 		container_of(work, struct xradio_vif, offchannel_work);
2242 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2243 	u8 queueId = xradio_queue_get_queue_id(hw_priv->pending_frame_id);
2244 	struct xradio_queue *queue = &hw_priv->tx_queue[queueId];
2245 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2246 
2247 	SYS_BUG(queueId >= 4);
2248 	SYS_BUG(!hw_priv->channel);
2249 
2250 	if (unlikely(down_trylock(&hw_priv->scan.lock))) {
2251 		int ret = 0;
2252 		sta_printk(XRADIO_DBG_ERROR,
2253 			   "xradio_offchannel_work***** drop frame\n");
2254 #ifdef CONFIG_XRADIO_TESTMODE
2255 		xradio_queue_remove(hw_priv, queue,
2256 				hw_priv->pending_frame_id);
2257 #else
2258 		ret = xradio_queue_remove(queue, hw_priv->pending_frame_id);
2259 #endif
2260 		if (ret)
2261 			sta_printk(XRADIO_DBG_ERROR, "xradio_offchannel_work: "
2262 				       "queue_remove failed %d\n", ret);
2263 		wsm_unlock_tx(hw_priv);
2264 		LOG_FILE(1, "xradio_offchannel_work error\n");
2265 		/*up(&hw_priv->scan.lock);*/
2266 		mac80211_connection_loss(priv->vif);
2267 		sta_printk(XRADIO_DBG_ERROR, "lock %d\n", hw_priv->scan.lock.count);
2268 
2269 		return;
2270 	}
2271 	down(&hw_priv->conf_lock);
2272 #ifdef ROC_DEBUG
2273 	sta_printk(XRADIO_DBG_WARN, "OFFCHAN WORK IN %d\n", priv->if_id);
2274 #endif
2275 	/*hw_priv->roc_if_id = priv->if_id;*/
2276 	if (likely(!priv->join_status) && (2 == priv->if_id)) {
2277 		wsm_vif_flush_tx(priv);
2278 		xradio_enable_listening(priv, hw_priv->channel);
2279 		/* xradio_update_filtering(priv); */
2280 	}
2281 	if (unlikely(!priv->join_status))
2282 #ifdef CONFIG_XRADIO_TESTMODE
2283 		xradio_queue_remove(hw_priv, queue,
2284 				hw_priv->pending_frame_id);
2285 #else
2286 		xradio_queue_remove(queue, hw_priv->pending_frame_id);
2287 #endif /*CONFIG_XRADIO_TESTMODE*/
2288 	else
2289 #ifdef CONFIG_XRADIO_TESTMODE
2290 		xradio_queue_requeue(hw_priv, queue,
2291 			hw_priv->pending_frame_id, false);
2292 #else
2293 		xradio_queue_requeue(queue, hw_priv->pending_frame_id, false);
2294 #endif
2295 
2296 	if (likely(priv->join_status) && (2 == priv->if_id)) {
2297 		hw_priv->roc_if_id = priv->if_id;
2298 		queue_delayed_work(hw_priv->workqueue,
2299 				&priv->pending_offchanneltx_work, 204 * HZ/1000);
2300 	} else {
2301 		up(&hw_priv->scan.lock);
2302 	}
2303 #ifdef ROC_DEBUG
2304 	sta_printk(XRADIO_DBG_WARN, "OFFCHAN WORK OUT %d\n", priv->if_id);
2305 #endif
2306 	up(&hw_priv->conf_lock);
2307 	wsm_unlock_tx(hw_priv);
2308 }
2309 
xradio_join_work(struct work_struct * work)2310 void xradio_join_work(struct work_struct *work)
2311 {
2312 	struct xradio_vif *priv =
2313 		container_of(work, struct xradio_vif, join_work);
2314 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2315 	u8 queueId = xradio_queue_get_queue_id(hw_priv->pending_frame_id);
2316 	struct xradio_queue *queue = &hw_priv->tx_queue[queueId];
2317 	const struct xradio_txpriv *txpriv = NULL;
2318 	struct sk_buff *skb = NULL;
2319 	const struct wsm_tx *wsm;
2320 	const struct ieee80211_hdr *frame;
2321 	const u8 *bssid;
2322 	struct cfg80211_bss *bss;
2323 	const u8 *ssidie;
2324 	const u8 *dtimie;
2325 	const struct ieee80211_tim_ie *tim = NULL;
2326 	struct wsm_protected_mgmt_policy mgmt_policy;
2327 	struct wsm_operational_mode mode = {
2328 		.power_mode = wsm_power_mode_quiescent,
2329 		.disableMoreFlagUsage = true,
2330 	};
2331 	/*
2332 	struct wsm_reset reset = {
2333 		.reset_statistics = true,
2334 	}; */
2335 	sta_printk(XRADIO_DBG_ALWY, "%s  join_status=%d \n", __func__, priv->join_status);
2336 
2337 	SYS_BUG(queueId >= 4);
2338 	if (xradio_queue_get_skb(queue,	hw_priv->pending_frame_id,
2339 			&skb, &txpriv)) {
2340 		wsm_unlock_tx(hw_priv);
2341 		return;
2342 	}
2343 	wsm = (struct wsm_tx *)&skb->data[0];
2344 	frame = (struct ieee80211_hdr *)&skb->data[txpriv->offset];
2345 	bssid = &frame->addr1[0]; /* AP SSID in a 802.11 frame */
2346 
2347 	SYS_BUG(!wsm);
2348 	SYS_BUG(!hw_priv->channel);
2349 
2350 	cancel_delayed_work_sync(&priv->join_timeout);
2351 	if (unlikely(priv->join_status)) {
2352 		sta_printk(XRADIO_DBG_WARN, "%s, pre join_status=%d.\n",
2353 			  __func__, priv->join_status);
2354 		wsm_lock_tx(hw_priv);
2355 		xradio_unjoin_work(&priv->unjoin_work);
2356 	}
2357 
2358 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
2359 	bss = cfg80211_get_bss(hw_priv->hw->wiphy, hw_priv->channel,
2360 			bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
2361 #else
2362 	bss = cfg80211_get_bss(hw_priv->hw->wiphy, hw_priv->channel,
2363 			bssid, NULL, 0, 0, 0);
2364 #endif
2365 	if (!bss) {
2366 #ifdef CONFIG_XRADIO_TESTMODE
2367 		xradio_queue_remove(hw_priv, queue, hw_priv->pending_frame_id);
2368 #else
2369 		xradio_queue_remove(queue, hw_priv->pending_frame_id);
2370 #endif /*CONFIG_XRADIO_TESTMODE*/
2371 		wsm_unlock_tx(hw_priv);
2372 		return;
2373 	}
2374 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2375 	ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
2376 	dtimie = ieee80211_bss_get_ie(bss, WLAN_EID_TIM);
2377 #else
2378 	ssidie = cfg80211_find_ie(WLAN_EID_SSID,
2379 		bss->information_elements,
2380 		bss->len_information_elements);
2381 	dtimie = cfg80211_find_ie(WLAN_EID_TIM,
2382 		bss->information_elements,
2383 		bss->len_information_elements);
2384 #endif
2385 	if (dtimie)
2386 		tim = (struct ieee80211_tim_ie *)&dtimie[2];
2387 
2388 	down(&hw_priv->conf_lock);
2389 	{
2390 
2391 #ifdef SUPPORT_HT40
2392 
2393 		const u8 *bss_ht_info_ie;
2394 
2395 		struct wsm_join join = {
2396 			.mode = (bss->capability & WLAN_CAPABILITY_IBSS) ?
2397 				WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
2398 			.probeForJoin = 1,
2399 			/* dtimPeriod will be updated after association */
2400 			.dtimPeriod = 1,
2401 			.beaconInterval = bss->beacon_interval,
2402 		};
2403 
2404 		join.PhyModeCfg.BandCfg     = hw_priv->channel->band;
2405 		join.PhyModeCfg.ModemFlags  = (hw_priv->channel->band ==
2406 			NL80211_BAND_5GHZ) ? (MODEM_F_A_OFDM|MODEM_F_N_OFDM) :
2407 				(MODEM_F_B_DSSS|MODEM_F_A_OFDM|MODEM_F_N_OFDM);
2408 		join.PhyModeCfg.PreambleCfg = PREAMBLE_L;
2409 		join.PhyModeCfg.ChWidthCfg  = CHAN_WIDTH_20MHz;
2410 		join.PhyModeCfg.PriChCfg    = PRIMARY_CH_1ST;
2411 		join.PhyModeCfg.SGI_Enable  = false;
2412 		join.PhyModeCfg.STBC_Enable = false;
2413 		join.PhyModeCfg.GF_Enable   = false;
2414 		join.PhyModeCfg.Reserved    = 0;
2415 
2416 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2417 			bss_ht_info_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION);
2418 #else
2419 			bss_ht_info_ie = cfg80211_find_ie(WLAN_EID_HT_INFORMATION,
2420 			bss->information_elements,
2421 			bss->len_information_elements);
2422 #endif
2423 
2424 		if (bss_ht_info_ie != NULL) {
2425 
2426 			struct ieee80211_ht_operation *bss_ht_info;
2427 			struct ieee80211_supported_band *sband;
2428 
2429 			bss_ht_info = (struct ieee80211_ht_operation *)(bss_ht_info_ie + 2);
2430 
2431 			sband = priv->hw->wiphy->bands[hw_priv->channel->band];
2432 
2433 			sta_printk(XRADIO_DBG_WARN, "[HT40][%s]"\
2434 				"[bss_ht_info]:\n"\
2435 				"[primary_chan  :0x%08x]\n"\
2436 				"[ht_param      :0x%08x]\n"\
2437 				"[operation_mode:0x%08x]\n"\
2438 				"[stbc_param    :0x%08x]\n"\
2439 				"[basic_set[0]  :0x%08x]\n",
2440 				__func__,
2441 				bss_ht_info->primary_chan,
2442 				bss_ht_info->ht_param,
2443 				bss_ht_info->operation_mode,
2444 				bss_ht_info->stbc_param,
2445 				bss_ht_info->basic_set[0]);
2446 
2447 			if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
2448 				switch (bss_ht_info->ht_param &
2449 					IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
2450 				case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
2451 					join.PhyModeCfg.ChWidthCfg = CHAN_WIDTH_40MHz;
2452 					join.PhyModeCfg.PriChCfg = PRIMARY_CH_2ND;
2453 					break;
2454 				case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
2455 					join.PhyModeCfg.ChWidthCfg = CHAN_WIDTH_40MHz;
2456 					join.PhyModeCfg.PriChCfg = PRIMARY_CH_1ST;
2457 					break;
2458 				}
2459 
2460 			} else {
2461 				sta_printk(XRADIO_DBG_WARN, "[HT40][%s]"\
2462 						"[ONLY_USE_HT20]\n", __func__);
2463 			}
2464 		} else {
2465 			sta_printk(XRADIO_DBG_WARN, "[HT40][%s]"\
2466 				"[bss_ht_info]: [Not HT]\n", __func__);
2467 		}
2468 
2469 		sta_printk(XRADIO_DBG_WARN, "[HT40][%s][PhyModeCfg:0x%04x]\n"
2470 			"[ModemFlags    :0x%08x]\n"
2471 			"[ChWidthCfg    :0x%08x]\n"
2472 			"[PriChCfg      :0x%08x]\n"
2473 			"[BandCfg       :0x%08x]\n"
2474 			"[STBC_Enable   :0x%08x]\n"
2475 			"[PreambleCfg   :0x%08x]\n"
2476 			"[SGI_Enable    :0x%08x]\n"
2477 			"GF_Enable      :0x%08x]\n",
2478 			__func__, *(u16 *)&join.PhyModeCfg,
2479 			join.PhyModeCfg.ModemFlags,
2480 			join.PhyModeCfg.ChWidthCfg,
2481 			join.PhyModeCfg.PriChCfg,
2482 			join.PhyModeCfg.BandCfg,
2483 			join.PhyModeCfg.STBC_Enable,
2484 			join.PhyModeCfg.PreambleCfg,
2485 			join.PhyModeCfg.SGI_Enable,
2486 			join.PhyModeCfg.GF_Enable
2487 			);
2488 
2489 #else
2490 
2491 		struct wsm_join join = {
2492 			.mode = (bss->capability & WLAN_CAPABILITY_IBSS) ?
2493 				WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
2494 			/* default changed to LONG, by HuangLu, fix 2/5.5/11m tx fail*/
2495 			.preambleType = WSM_JOIN_PREAMBLE_LONG,
2496 			.probeForJoin = 1,
2497 			/* dtimPeriod will be updated after association */
2498 			.dtimPeriod = 1,
2499 			.beaconInterval = bss->beacon_interval,
2500 		};
2501 
2502 #endif
2503 
2504 		if (priv->if_id)
2505 			join.flags |= WSM_FLAG_MAC_INSTANCE_1;
2506 		else
2507 			join.flags &= ~WSM_FLAG_MAC_INSTANCE_1;
2508 
2509 		/* BT Coex related changes */
2510 		if (hw_priv->is_BT_Present) {
2511 			if (((hw_priv->conf_listen_interval * 100) %
2512 					bss->beacon_interval) == 0)
2513 				priv->listen_interval =
2514 					((hw_priv->conf_listen_interval * 100) /
2515 					bss->beacon_interval);
2516 			else
2517 				priv->listen_interval =
2518 					((hw_priv->conf_listen_interval * 100) /
2519 					bss->beacon_interval + 1);
2520 		}
2521 
2522 		if (tim && tim->dtim_period > 1) {
2523 			join.dtimPeriod = tim->dtim_period;
2524 			priv->join_dtim_period = tim->dtim_period;
2525 		}
2526 		priv->beacon_int = bss->beacon_interval;
2527 		sta_printk(XRADIO_DBG_NIY, "Join DTIM: %d, interval: %d\n",
2528 				join.dtimPeriod, priv->beacon_int);
2529 
2530 		hw_priv->is_go_thru_go_neg = false;
2531 		join.channelNumber = hw_priv->channel->hw_value;
2532 		hw_priv->join_chan = join.channelNumber;
2533 		/* basicRateSet will be updated after association.
2534 		Currently these values are hardcoded */
2535 #ifdef SUPPORT_HT40
2536 
2537 		if (hw_priv->channel->band == NL80211_BAND_5GHZ) {
2538 			join.basicRateSet = 64; /*6 mbps*/
2539 		} else {
2540 			join.basicRateSet = 7; /*1, 2, 5.5 mbps*/
2541 		}
2542 
2543 #else
2544 
2545 		if (hw_priv->channel->band == NL80211_BAND_5GHZ) {
2546 			join.band = WSM_PHY_BAND_5G;
2547 			join.basicRateSet = 64; /*6 mbps*/
2548 		} else {
2549 			join.band = WSM_PHY_BAND_2_4G;
2550 			join.basicRateSet = 7; /*1, 2, 5.5 mbps*/
2551 		}
2552 
2553 #endif
2554 
2555 		memcpy(&join.bssid[0], bssid, sizeof(join.bssid));
2556 		memcpy(&priv->join_bssid[0], bssid, sizeof(priv->join_bssid));
2557 
2558 		if (ssidie) {
2559 			join.ssidLength = ssidie[1];
2560 			if (SYS_WARN(join.ssidLength > sizeof(join.ssid)))
2561 				join.ssidLength = sizeof(join.ssid);
2562 			memcpy(&join.ssid[0], &ssidie[2], join.ssidLength);
2563 			if (strstr(&join.ssid[0], "5.1.4"))
2564 				msleep(200);
2565 #ifdef ROAM_OFFLOAD
2566 			if ((priv->vif->type == NL80211_IFTYPE_STATION)) {
2567 				priv->ssid_length = join.ssidLength;
2568 				memcpy(priv->ssid, &join.ssid[0], priv->ssid_length);
2569 			}
2570 #endif /*ROAM_OFFLOAD*/
2571 		}
2572 
2573 		if (priv->vif->p2p) {
2574 			join.flags |= WSM_JOIN_FLAGS_P2P_GO;
2575 
2576 #ifdef SUPPORT_HT40
2577 
2578 			join.PhyModeCfg.ModemFlags &= ~(MODEM_F_B_DSSS);
2579 
2580 #endif
2581 
2582 #ifdef P2P_MULTIVIF
2583 			join.flags |= (1 << 6);
2584 #endif
2585 			join.basicRateSet =
2586 				xradio_rate_mask_to_wsm(hw_priv, 0xFF0);
2587 		}
2588 
2589 		wsm_flush_tx(hw_priv);
2590 
2591 		/* Queue unjoin if not associated in 3 sec. */
2592 		queue_delayed_work(hw_priv->workqueue,
2593 			&priv->join_timeout, 3 * HZ);
2594 		/*Stay Awake for Join Timeout*/
2595 #ifdef CONFIG_PM
2596 		xradio_pm_stay_awake(&hw_priv->pm_state, 3 * HZ);
2597 #endif
2598 		xradio_disable_listening(priv);
2599 
2600 		/* SYS_WARN(wsm_reset(hw_priv, &reset, priv->if_id)); */
2601 		SYS_WARN(wsm_set_operational_mode(hw_priv, &mode, priv->if_id));
2602 		SYS_WARN(wsm_set_block_ack_policy(hw_priv,
2603 			0, hw_priv->ba_tid_mask, priv->if_id));
2604 		spin_lock_bh(&hw_priv->ba_lock);
2605 		hw_priv->ba_ena = false;
2606 		hw_priv->ba_cnt = 0;
2607 		hw_priv->ba_acc = 0;
2608 		hw_priv->ba_hist = 0;
2609 		hw_priv->ba_cnt_rx = 0;
2610 		hw_priv->ba_acc_rx = 0;
2611 		spin_unlock_bh(&hw_priv->ba_lock);
2612 
2613 		mgmt_policy.protectedMgmtEnable = 0;
2614 		mgmt_policy.unprotectedMgmtFramesAllowed = 1;
2615 		mgmt_policy.encryptionForAuthFrame = 1;
2616 		wsm_set_protected_mgmt_policy(hw_priv, &mgmt_policy, priv->if_id);
2617 
2618 		if (wsm_join(hw_priv, &join, priv->if_id)) {
2619 			memset(&priv->join_bssid[0],
2620 				0, sizeof(priv->join_bssid));
2621 #ifdef CONFIG_XRADIO_TESTMODE
2622 			xradio_queue_remove(hw_priv, queue,
2623 						hw_priv->pending_frame_id);
2624 #else
2625 			xradio_queue_remove(queue, hw_priv->pending_frame_id);
2626 #endif /*CONFIG_XRADIO_TESTMODE*/
2627 			cancel_delayed_work_sync(&priv->join_timeout);
2628 		} else {
2629 			/* Upload keys */
2630 #ifdef CONFIG_XRADIO_TESTMODE
2631 			xradio_queue_requeue(hw_priv, queue,
2632 				hw_priv->pending_frame_id, true);
2633 #else
2634 			xradio_queue_requeue(queue, hw_priv->pending_frame_id,
2635 						true);
2636 #endif
2637 			priv->join_status = XRADIO_JOIN_STATUS_STA;
2638 
2639 			/* Due to beacon filtering it is possible that the
2640 			 * AP's beacon is not known for the mac80211 stack.
2641 			 * Disable filtering temporary to make sure the stack
2642 			 * receives at least one */
2643 			priv->disable_beacon_filter = true;
2644 
2645 		}
2646 		xradio_update_filtering(priv);
2647 	}
2648 	up(&hw_priv->conf_lock);
2649 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
2650 	cfg80211_put_bss(priv->hw->wiphy, bss);
2651 #else
2652 	cfg80211_put_bss(bss);
2653 #endif
2654 	wsm_unlock_tx(hw_priv);
2655 }
2656 
xradio_join_timeout(struct work_struct * work)2657 void xradio_join_timeout(struct work_struct *work)
2658 {
2659 	struct xradio_vif *priv =
2660 		container_of(work, struct xradio_vif, join_timeout.work);
2661 	sta_printk(XRADIO_DBG_WARN, "[WSM] Issue unjoin command (TMO).\n");
2662 	wsm_lock_tx(priv->hw_priv);
2663 	xradio_unjoin_work(&priv->unjoin_work);
2664 }
2665 
xradio_unjoin_work(struct work_struct * work)2666 void xradio_unjoin_work(struct work_struct *work)
2667 {
2668 	struct xradio_vif *priv =
2669 		container_of(work, struct xradio_vif, unjoin_work);
2670 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2671 
2672 	struct wsm_reset reset = {
2673 		.reset_statistics = true,
2674 	};
2675 	bool is_htcapie = false;
2676 	int i;
2677 	struct xradio_vif *tmp_priv;
2678 	struct wsm_operational_mode mode = {
2679 		.power_mode = wsm_power_mode_quiescent,
2680 		.disableMoreFlagUsage = true,
2681 	};
2682 	sta_printk(XRADIO_DBG_ALWY, "%s \n", __func__);
2683 
2684 	hw_priv->scan_delay_status[priv->if_id] = XRADIO_SCAN_ALLOW;
2685 #ifdef AP_HT_COMPAT_FIX
2686 	priv->ht_compat_det &= ~1;
2687 	priv->ht_compat_cnt = 0;
2688 #endif
2689 
2690 	del_timer_sync(&hw_priv->ba_timer);
2691 	down(&hw_priv->conf_lock);
2692 	if (unlikely(atomic_read(&hw_priv->scan.in_progress))) {
2693 		if (atomic_xchg(&priv->delayed_unjoin, 1)) {
2694 			sta_printk(XRADIO_DBG_NIY,
2695 				"%s: Delayed unjoin is already scheduled.\n", __func__);
2696 			wsm_unlock_tx(hw_priv);
2697 		}
2698 		up(&hw_priv->conf_lock);
2699 		return;
2700 	}
2701 
2702 	if (priv->join_status && priv->join_status > XRADIO_JOIN_STATUS_STA) {
2703 		sta_printk(XRADIO_DBG_ERROR,
2704 				"%s: Unexpected: join status: %d\n",
2705 				__func__, priv->join_status);
2706 		SYS_BUG(1);
2707 	}
2708 	if (priv->join_status) {
2709 		cancel_work_sync(&priv->update_filtering_work);
2710 		cancel_work_sync(&priv->set_beacon_wakeup_period_work);
2711 		memset(&priv->join_bssid[0], 0, sizeof(priv->join_bssid));
2712 		priv->join_status = XRADIO_JOIN_STATUS_PASSIVE;
2713 
2714 		/* Unjoin is a reset. */
2715 		wsm_flush_tx(hw_priv);
2716 		SYS_WARN(wsm_keep_alive_period(hw_priv, 0, priv->if_id));
2717 		SYS_WARN(wsm_reset(hw_priv, &reset, priv->if_id));
2718 		SYS_WARN(wsm_set_operational_mode(hw_priv, &mode, priv->if_id));
2719 		SYS_WARN(wsm_set_output_power(hw_priv,
2720 			hw_priv->output_power * 10, priv->if_id));
2721 		priv->join_dtim_period = 0;
2722 		priv->unicast_cipher_type = 0;
2723 		SYS_WARN(xradio_setup_mac_pvif(priv));
2724 		xradio_free_event_queue(hw_priv);
2725 		cancel_work_sync(&hw_priv->event_handler);
2726 		cancel_delayed_work_sync(&priv->connection_loss_work);
2727 		SYS_WARN(wsm_set_block_ack_policy(hw_priv,
2728 			0, hw_priv->ba_tid_mask, priv->if_id));
2729 		priv->disable_beacon_filter = false;
2730 		xradio_update_filtering(priv);
2731 		priv->setbssparams_done = false;
2732 		memset(&priv->association_mode, 0,
2733 			sizeof(priv->association_mode));
2734 		memset(&priv->bss_params, 0, sizeof(priv->bss_params));
2735 		memset(&priv->firmware_ps_mode, 0,
2736 			sizeof(priv->firmware_ps_mode));
2737 		priv->powersave_mode.pmMode = WSM_PSM_ACTIVE; /*reset driver pm mode too.*/
2738 		priv->htcap = false;
2739 		priv->is_mfp_connect = false;
2740 		xradio_for_each_vif(hw_priv, tmp_priv, i) {
2741 #ifdef P2P_MULTIVIF
2742 			if ((i == (XRWL_MAX_VIFS - 1)) || !tmp_priv)
2743 #else
2744 			if (!tmp_priv)
2745 #endif
2746 				continue;
2747 			if ((tmp_priv->join_status == XRADIO_JOIN_STATUS_STA) &&
2748 				 tmp_priv->htcap)
2749 				is_htcapie = true;
2750 		}
2751 
2752 		if (is_htcapie) {
2753 			hw_priv->vif0_throttle = XRWL_HOST_VIF0_11N_THROTTLE;
2754 			hw_priv->vif1_throttle = XRWL_HOST_VIF1_11N_THROTTLE;
2755 			sta_printk(XRADIO_DBG_NIY, "UNJOIN HTCAP 11N %d\n",
2756 				   hw_priv->vif0_throttle);
2757 		} else {
2758 			hw_priv->vif0_throttle = XRWL_HOST_VIF0_11BG_THROTTLE;
2759 			hw_priv->vif1_throttle = XRWL_HOST_VIF1_11BG_THROTTLE;
2760 			sta_printk(XRADIO_DBG_NIY, "UNJOIN 11BG %d\n",
2761 				   hw_priv->vif0_throttle);
2762 		}
2763 		sta_printk(XRADIO_DBG_NIY, "Unjoin.\n");
2764 	}
2765 	up(&hw_priv->conf_lock);
2766 	wsm_unlock_tx(hw_priv);
2767 }
2768 
xradio_unjoin_delayed_work(struct work_struct * work)2769 void xradio_unjoin_delayed_work(struct work_struct *work)
2770 {
2771 	struct xradio_vif *priv =
2772 		container_of(work, struct xradio_vif, unjoin_delayed_work.work);
2773 
2774 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2775 
2776 	wsm_lock_tx_async(hw_priv);
2777 	xradio_unjoin_work(&priv->unjoin_work);
2778 }
2779 
xradio_enable_listening(struct xradio_vif * priv,struct ieee80211_channel * chan)2780 int xradio_enable_listening(struct xradio_vif *priv,
2781 				struct ieee80211_channel *chan)
2782 {
2783 	/* TODO:COMBO: Channel is common to HW currently in mac80211.
2784 	Change the code below once channel is made per VIF */
2785 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2786 
2787 #ifdef SUPPORT_HT40
2788 
2789 	struct wsm_start start = {
2790 #ifdef P2P_MULTIVIF
2791 		.mode = WSM_START_MODE_P2P_DEV | (priv->if_id ? (1 << 4) : 0),
2792 #else
2793 		.mode = WSM_START_MODE_P2P_DEV | (priv->if_id << 4),
2794 #endif
2795 
2796 		.PhyModeCfg.BandCfg = (chan->band == NL80211_BAND_5GHZ) ?
2797 				WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2798 		.PhyModeCfg.ModemFlags = (chan->band == NL80211_BAND_5GHZ) ?
2799 				(MODEM_F_A_OFDM|MODEM_F_N_OFDM) :
2800 				(MODEM_F_B_DSSS|MODEM_F_A_OFDM|MODEM_F_N_OFDM),
2801 		.PhyModeCfg.ChWidthCfg  = CHAN_WIDTH_20MHz,
2802 		.PhyModeCfg.PriChCfg    = PRIMARY_CH_1ST,
2803 		.PhyModeCfg.SGI_Enable	= false,
2804 		.PhyModeCfg.STBC_Enable = false,
2805 		.PhyModeCfg.GF_Enable   = false,
2806 		.PhyModeCfg.PreambleCfg = WSM_JOIN_PREAMBLE_LONG,
2807 
2808 		.channelNumber = chan->hw_value,
2809 		.beaconInterval = 100,
2810 		.DTIMPeriod = 1,
2811 		.probeDelay = 0,
2812 		.basicRateSet = 0x0F,
2813 	};
2814 
2815 #else
2816 
2817 	struct wsm_start start = {
2818 #ifdef P2P_MULTIVIF
2819 		.mode = WSM_START_MODE_P2P_DEV | (priv->if_id ? (1 << 4) : 0),
2820 #else
2821 		.mode = WSM_START_MODE_P2P_DEV | (priv->if_id << 4),
2822 #endif
2823 		.band = (chan->band == NL80211_BAND_5GHZ) ?
2824 				WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2825 		.channelNumber = chan->hw_value,
2826 		.beaconInterval = 100,
2827 		.DTIMPeriod = 1,
2828 		.probeDelay = 0,
2829 		.basicRateSet = 0x0F,
2830 	};
2831 
2832 #endif
2833 
2834 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2835 
2836 	if (priv->if_id != 2) {
2837 		SYS_WARN(priv->join_status > XRADIO_JOIN_STATUS_MONITOR);
2838 		return 0;
2839 	}
2840 	if (priv->join_status == XRADIO_JOIN_STATUS_MONITOR)
2841 		return 0;
2842 	if (priv->join_status == XRADIO_JOIN_STATUS_PASSIVE)
2843 		priv->join_status = XRADIO_JOIN_STATUS_MONITOR;
2844 
2845 	SYS_WARN(priv->join_status > XRADIO_JOIN_STATUS_MONITOR);
2846 
2847 	return wsm_start(hw_priv, &start, XRWL_GENERIC_IF_ID);
2848 }
2849 
xradio_disable_listening(struct xradio_vif * priv)2850 int xradio_disable_listening(struct xradio_vif *priv)
2851 {
2852 	int ret;
2853 	struct wsm_reset reset = {
2854 		.reset_statistics = true,
2855 	};
2856 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2857 
2858 	if (priv->if_id != 2) {
2859 		SYS_WARN(priv->join_status > XRADIO_JOIN_STATUS_MONITOR);
2860 	return 0;
2861 	}
2862 	priv->join_status = XRADIO_JOIN_STATUS_PASSIVE;
2863 
2864 	SYS_WARN(priv->join_status > XRADIO_JOIN_STATUS_MONITOR);
2865 
2866 	if (priv->hw_priv->roc_if_id == -1)
2867 		return 0;
2868 
2869 	ret = wsm_reset(priv->hw_priv, &reset, XRWL_GENERIC_IF_ID);
2870 	return ret;
2871 }
2872 
2873 /* TODO:COMBO:UAPSD will be supported only on one interface */
xradio_set_uapsd_param(struct xradio_vif * priv,const struct wsm_edca_params * arg)2874 int xradio_set_uapsd_param(struct xradio_vif *priv,
2875 				const struct wsm_edca_params *arg)
2876 {
2877 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
2878 	int ret;
2879 	u16 uapsdFlags = 0;
2880 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2881 
2882 	/* Here's the mapping AC [queue, bit]
2883 	VO [0, 3], VI [1, 2], BE [2, 1], BK [3, 0]*/
2884 
2885 	if (arg->params[0].uapsdEnable)
2886 		uapsdFlags |= 1 << 3;
2887 
2888 	if (arg->params[1].uapsdEnable)
2889 		uapsdFlags |= 1 << 2;
2890 
2891 	if (arg->params[2].uapsdEnable)
2892 		uapsdFlags |= 1 << 1;
2893 
2894 	if (arg->params[3].uapsdEnable)
2895 		uapsdFlags |= 1;
2896 
2897 	/* Currently pseudo U-APSD operation is not supported, so setting
2898 	* MinAutoTriggerInterval, MaxAutoTriggerInterval and
2899 	* AutoTriggerStep to 0 */
2900 
2901 	priv->uapsd_info.uapsdFlags = cpu_to_le16(uapsdFlags);
2902 	priv->uapsd_info.minAutoTriggerInterval = 0;
2903 	priv->uapsd_info.maxAutoTriggerInterval = 0;
2904 	priv->uapsd_info.autoTriggerStep = 0;
2905 
2906 	ret = wsm_set_uapsd_info(hw_priv, &priv->uapsd_info,
2907 				 priv->if_id);
2908 	return ret;
2909 }
2910 
xradio_ba_work(struct work_struct * work)2911 void xradio_ba_work(struct work_struct *work)
2912 {
2913 	struct xradio_common *hw_priv =
2914 		container_of(work, struct xradio_common, ba_work);
2915 	u8 tx_ba_tid_mask;
2916 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2917 
2918 	/* TODO:COMBO: reenable this part of code */
2919 	/*
2920 	if (priv->join_status != XRADIO_JOIN_STATUS_STA)
2921 		return;
2922 	if (!priv->setbssparams_done)
2923 		return;
2924 	*/
2925 
2926 	sta_printk(XRADIO_DBG_WARN, "BA work****\n");
2927 	spin_lock_bh(&hw_priv->ba_lock);
2928 	/* tx_ba_tid_mask = hw_priv->ba_ena ? hw_priv->ba_tid_mask : 0; */
2929 	tx_ba_tid_mask = hw_priv->ba_tid_mask;
2930 	spin_unlock_bh(&hw_priv->ba_lock);
2931 
2932 	wsm_lock_tx(hw_priv);
2933 
2934 	SYS_WARN(wsm_set_block_ack_policy(hw_priv,
2935 		tx_ba_tid_mask, hw_priv->ba_tid_mask, -1)); /*TODO:COMBO*/
2936 
2937 	wsm_unlock_tx(hw_priv);
2938 }
2939 
xradio_bt_timer(struct timer_list * t)2940 void xradio_bt_timer(struct timer_list *t)
2941 {
2942 	struct xradio_common *hw_priv = from_timer(hw_priv, t, BT_timer);
2943 	sta_printk(XRADIO_DBG_NIY, "%s:BT_active=0x%x\n",
2944 		__func__, hw_priv->BT_active);
2945 	hw_priv->BT_active &= ~xradio_bt_active_bit(BT_LINK_TPYE_INQUIRY);
2946 	xradio_proc_wakeup(hw_priv);
2947 }
2948 
xradio_ba_timer(struct timer_list * t)2949 void xradio_ba_timer(struct timer_list *t)
2950 {
2951 	bool ba_ena;
2952 	struct xradio_common *hw_priv = from_timer(hw_priv, t, ba_timer);
2953 
2954 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
2955 	spin_lock_bh(&hw_priv->ba_lock);
2956 	xradio_debug_ba(hw_priv, hw_priv->ba_cnt, hw_priv->ba_acc,
2957 			hw_priv->ba_cnt_rx, hw_priv->ba_acc_rx);
2958 
2959 	if (atomic_read(&hw_priv->scan.in_progress)) {
2960 		hw_priv->ba_cnt = 0;
2961 		hw_priv->ba_acc = 0;
2962 		hw_priv->ba_cnt_rx = 0;
2963 		hw_priv->ba_acc_rx = 0;
2964 		goto skip_statistic_update;
2965 	}
2966 
2967 	if (hw_priv->ba_cnt >= XRADIO_BLOCK_ACK_CNT &&
2968 		(hw_priv->ba_acc / hw_priv->ba_cnt >= XRADIO_BLOCK_ACK_THLD ||
2969 		(hw_priv->ba_cnt_rx >= XRADIO_BLOCK_ACK_CNT &&
2970 		hw_priv->ba_acc_rx / hw_priv->ba_cnt_rx >=
2971 			XRADIO_BLOCK_ACK_THLD)))
2972 		ba_ena = true;
2973 	else
2974 		ba_ena = false;
2975 
2976 	hw_priv->ba_cnt = 0;
2977 	hw_priv->ba_acc = 0;
2978 	hw_priv->ba_cnt_rx = 0;
2979 	hw_priv->ba_acc_rx = 0;
2980 
2981 	if (ba_ena != hw_priv->ba_ena) {
2982 		if (ba_ena || ++hw_priv->ba_hist >= XRADIO_BLOCK_ACK_HIST) {
2983 			hw_priv->ba_ena = ba_ena;
2984 			hw_priv->ba_hist = 0;
2985 #if 0
2986 			sta_printk(XRADIO_DBG_NIY, "%s block ACK:\n",
2987 				ba_ena ? "enable" : "disable");
2988 			queue_work(hw_priv->workqueue, &hw_priv->ba_work);
2989 #endif
2990 		}
2991 	} else if (hw_priv->ba_hist)
2992 		--hw_priv->ba_hist;
2993 
2994 skip_statistic_update:
2995 	spin_unlock_bh(&hw_priv->ba_lock);
2996 }
2997 
xradio_vif_setup(struct xradio_vif * priv)2998 int xradio_vif_setup(struct xradio_vif *priv)
2999 {
3000 	struct xradio_common *hw_priv = priv->hw_priv;
3001 	int ret = 0;
3002 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3003 
3004 	/* reset channel change flag */
3005 	hw_priv->channel_changed  = 0;
3006 	/* Setup per vif workitems and locks */
3007 	spin_lock_init(&priv->vif_lock);
3008 	INIT_WORK(&priv->join_work, xradio_join_work);
3009 	INIT_DELAYED_WORK(&priv->join_timeout, xradio_join_timeout);
3010 	INIT_WORK(&priv->unjoin_work, xradio_unjoin_work);
3011 	INIT_DELAYED_WORK(&priv->unjoin_delayed_work, xradio_unjoin_delayed_work);
3012 	INIT_WORK(&priv->wep_key_work, xradio_wep_key_work);
3013 	INIT_WORK(&priv->offchannel_work, xradio_offchannel_work);
3014 	INIT_DELAYED_WORK(&priv->bss_loss_work, xradio_bss_loss_work);
3015 	INIT_DELAYED_WORK(&priv->connection_loss_work,
3016 			  xradio_connection_loss_work);
3017 	priv->bss_loss_status = XRADIO_BSS_LOSS_NONE;
3018 	spin_lock_init(&priv->bss_loss_lock);
3019 	INIT_WORK(&priv->tx_failure_work, xradio_tx_failure_work);
3020 	spin_lock_init(&priv->ps_state_lock);
3021 	INIT_DELAYED_WORK(&priv->set_cts_work, xradio_set_cts_work);
3022 	INIT_WORK(&priv->set_tim_work, xradio_set_tim_work);
3023 	INIT_WORK(&priv->multicast_start_work, xradio_multicast_start_work);
3024 	INIT_WORK(&priv->multicast_stop_work, xradio_multicast_stop_work);
3025 	INIT_WORK(&priv->link_id_work, xradio_link_id_work);
3026 	INIT_DELAYED_WORK(&priv->link_id_gc_work, xradio_link_id_gc_work);
3027 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
3028 	INIT_WORK(&priv->linkid_reset_work, xradio_link_id_reset);
3029 #endif
3030 	INIT_WORK(&priv->update_filtering_work, xradio_update_filtering_work);
3031 	INIT_DELAYED_WORK(&priv->pending_offchanneltx_work,
3032 			xradio_pending_offchanneltx_work);
3033 	INIT_WORK(&priv->set_beacon_wakeup_period_work,
3034 		xradio_set_beacon_wakeup_period_work);
3035 #ifdef AP_HT_CAP_UPDATE
3036 	INIT_WORK(&priv->ht_info_update_work, xradio_ht_info_update_work);
3037 #endif
3038 	timer_setup(&priv->mcast_timeout, xradio_mcast_timeout, 0);
3039 	priv->setbssparams_done = false;
3040 	priv->power_set_true = 0;
3041 	priv->user_power_set_true = 0;
3042 	priv->user_pm_mode = 0;
3043 	SYS_WARN(xradio_debug_init_priv(hw_priv, priv));
3044 
3045 	/* Initialising the broadcast filter */
3046 	memset(priv->broadcast_filter.MacAddr, 0xFF, ETH_ALEN);
3047 	priv->broadcast_filter.nummacaddr = 1;
3048 	priv->broadcast_filter.address_mode = 1;
3049 	priv->broadcast_filter.filter_mode = 1;
3050 	priv->htcap = false;
3051 #ifdef AP_HT_COMPAT_FIX
3052 	priv->ht_compat_det = 0;
3053 	priv->ht_compat_cnt = 0;
3054 #endif
3055 
3056 #ifdef AP_ARP_COMPAT_FIX
3057 		priv->arp_compat_cnt = 0;
3058 #endif
3059 
3060 	/*set default value of powersave_mode */
3061 	priv->powersave_mode.fastPsmIdlePeriod = 200;	/*100ms */
3062 	priv->powersave_mode.apPsmChangePeriod = 200;	/*100ms */
3063 	priv->powersave_mode.minAutoPsPollPeriod = 0;	/*disable*/
3064 
3065 	sta_printk(XRADIO_DBG_ALWY, "!!!%s: id=%d, type=%d, p2p=%d, addr=%pM\n",
3066 			__func__, priv->if_id, priv->vif->type, priv->vif->p2p, priv->vif->addr);
3067 
3068 	atomic_set(&priv->enabled, 1);
3069 
3070 #ifdef P2P_MULTIVIF
3071 	if (priv->if_id < 2) {
3072 #endif
3073 		/* default EDCA */
3074 		WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007,
3075 				47, 0xc8, false);
3076 		WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f,
3077 				94, 0xc8, false);
3078 
3079 #if 0
3080 		if (priv->vif->p2p == true) {
3081 #endif
3082 			WSM_EDCA_SET(&priv->edca, 2, 0x0002, 0x0003, 0x0007,
3083 				0, 0xc8, false);
3084 			sta_printk(XRADIO_DBG_MSG,
3085 				   "EDCA params Best effort for sta/p2p is " \
3086 				   "aifs=%u, cw_min=%u, cw_max=%u \n",
3087 				   priv->edca.params[2].aifns,
3088 				   priv->edca.params[2].cwMin,
3089 				   priv->edca.params[2].cwMax);
3090 #if 0
3091 		} else {
3092 			WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff,
3093 				0, 0xc8, false);
3094 			sta_printk(XRADIO_DBG_MSG,
3095 				   "EDCA params Best effort for sta is " \
3096 				   "aifs=%u, cw_min=%u, cw_max=%u \n",
3097 				   priv->edca.params[2].aifns,
3098 				   priv->edca.params[2].cwMin,
3099 				   priv->edca.params[2].cwMax);
3100 		}
3101 #endif
3102 		WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff,
3103 				0, 0xc8, false);
3104 
3105 		ret = wsm_set_edca_params(hw_priv, &priv->edca, priv->if_id);
3106 		if (SYS_WARN(ret))
3107 			goto out;
3108 
3109 		ret = xradio_set_uapsd_param(priv, &priv->edca);
3110 		if (SYS_WARN(ret))
3111 			goto out;
3112 
3113 		memset(priv->bssid, ~0, ETH_ALEN);
3114 		priv->wep_default_key_id = -1;
3115 		priv->unicast_cipher_type = 0;
3116 		priv->cqm_link_loss_count   = XRADIO_LINK_LOSS_THOLD_DEF;
3117 		priv->cqm_beacon_loss_count = XRADIO_BSS_LOSS_THOLD_DEF;
3118 
3119 		/* Temporary configuration - beacon filter table */
3120 		__xradio_bf_configure(priv);
3121 #ifdef P2P_MULTIVIF
3122 	}
3123 #endif
3124 out:
3125 	return ret;
3126 }
3127 
xradio_setup_mac_pvif(struct xradio_vif * priv)3128 int xradio_setup_mac_pvif(struct xradio_vif *priv)
3129 {
3130 	int ret = 0;
3131 	/* NOTE: There is a bug in FW: it reports signal
3132 	* as RSSI if RSSI subscription is enabled.
3133 	* It's not enough to set WSM_RCPI_RSSI_USE_RSSI. */
3134 	/* NOTE2: RSSI based reports have been switched to RCPI, since
3135 	* FW has a bug and RSSI reported values are not stable,
3136 	* what can leads to signal level oscilations in user-end applications */
3137 	struct wsm_rcpi_rssi_threshold threshold = {
3138 		.rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
3139 		WSM_RCPI_RSSI_DONT_USE_UPPER |
3140 		WSM_RCPI_RSSI_DONT_USE_LOWER,
3141 		.rollingAverageCount = 16,
3142 	};
3143 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3144 
3145 	/* Remember the decission here to make sure, we will handle
3146 	 * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS */
3147 	if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
3148 		priv->cqm_use_rssi = true;
3149 
3150 
3151 	/* Configure RSSI/SCPI reporting as RSSI. */
3152 #ifdef P2P_MULTIVIF
3153 	ret = wsm_set_rcpi_rssi_threshold(priv->hw_priv,
3154 					  &threshold, priv->if_id ? 1 : 0);
3155 #else
3156 	ret = wsm_set_rcpi_rssi_threshold(priv->hw_priv,
3157 					  &threshold, priv->if_id);
3158 #endif
3159 	return ret;
3160 }
3161 
xradio_rem_chan_timeout(struct work_struct * work)3162 void xradio_rem_chan_timeout(struct work_struct *work)
3163 {
3164 	struct xradio_common *hw_priv =
3165 		container_of(work, struct xradio_common, rem_chan_timeout.work);
3166 	xradio_cancel_rem_chan(hw_priv);
3167 	mac80211_remain_on_channel_expired(hw_priv->hw);
3168 }
3169 
xradio_get_ie(u8 * start,size_t len,u8 ie)3170 const u8 *xradio_get_ie(u8 *start, size_t len, u8 ie)
3171 {
3172 	u8 *end, *pos;
3173 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3174 
3175 	pos = start;
3176 	if (pos == NULL)
3177 		return NULL;
3178 	end = pos + len;
3179 
3180 	while (pos + 1 < end) {
3181 		if (pos + 2 + pos[1] > end)
3182 			break;
3183 		if (pos[0] == ie)
3184 			return pos;
3185 		pos += 2 + pos[1];
3186 	}
3187 
3188 	return NULL;
3189 }
3190 
3191 /**
3192  * xradio_set_macaddrfilter -called when tesmode command
3193  * is for setting mac address filter
3194  *
3195  * @hw: the hardware
3196  * @data: incoming data
3197  *
3198  * Returns: 0 on success or non zero value on failure
3199  */
xradio_set_macaddrfilter(struct xradio_common * hw_priv,struct xradio_vif * priv,u8 * data)3200 int xradio_set_macaddrfilter(struct xradio_common *hw_priv,
3201 				     struct xradio_vif *priv, u8 *data)
3202 {
3203 	struct wsm_mac_addr_filter *mac_addr_filter =  NULL;
3204 	struct wsm_mac_addr_info *addr_info = NULL;
3205 	u8 action_mode = 0, no_of_mac_addr = 0, i = 0;
3206 	int ret = 0;
3207 	u16 macaddrfiltersize = 0;
3208 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3209 
3210 	/* Retrieving Action Mode */
3211 	action_mode = data[0];
3212 	/* Retrieving number of address entries */
3213 	no_of_mac_addr = data[1];
3214 
3215 	addr_info = (struct wsm_mac_addr_info *)&data[2];
3216 
3217 	/* Computing sizeof Mac addr filter */
3218 	macaddrfiltersize =  sizeof(*mac_addr_filter) + \
3219 			(no_of_mac_addr * sizeof(struct wsm_mac_addr_info));
3220 
3221 	mac_addr_filter = xr_kzalloc(macaddrfiltersize, false);
3222 	if (!mac_addr_filter) {
3223 		ret = -ENOMEM;
3224 		goto exit_p;
3225 	}
3226 	mac_addr_filter->action_mode = action_mode;
3227 	mac_addr_filter->numfilter = no_of_mac_addr;
3228 
3229 	for (i = 0; i < no_of_mac_addr; i++) {
3230 		mac_addr_filter->macaddrfilter[i].address_mode = \
3231 						addr_info[i].address_mode;
3232 		memcpy(mac_addr_filter->macaddrfilter[i].MacAddr, \
3233 				addr_info[i].MacAddr, ETH_ALEN);
3234 		mac_addr_filter->macaddrfilter[i].filter_mode = \
3235 						addr_info[i].filter_mode;
3236 	}
3237 	ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_MAC_ADDR_FILTER, \
3238 					 mac_addr_filter, macaddrfiltersize, priv->if_id));
3239 
3240 	kfree(mac_addr_filter);
3241 exit_p:
3242 	return ret;
3243 }
3244 
xradio_change_mac(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct sockaddr * sa)3245 int xradio_change_mac(struct ieee80211_hw *hw,
3246 				struct ieee80211_vif *vif, struct sockaddr *sa)
3247 {
3248 	struct xradio_common *hw_priv = (struct xradio_common *) hw->priv;
3249 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
3250 	int address_id = 0;
3251 	int ret = 0;
3252 
3253 
3254 	if (atomic_read(&priv->enabled)) {
3255 		sta_printk(XRADIO_DBG_ERROR, "%s:vif%d is opened(type = %d, p2p = %d)\n",
3256 					__func__, priv->if_id, vif->type, vif->p2p);
3257 		return -EBUSY;
3258 	}
3259 
3260 	if (priv->if_id == 1) {
3261 		sta_printk(XRADIO_DBG_ERROR, "%s:Can not change p2p interface mac address\n",
3262 					__func__);
3263 		return -EINVAL;
3264 	}
3265 
3266 	if (!is_valid_ether_addr(sa->sa_data)) {
3267 		sta_printk(XRADIO_DBG_ERROR, "%s:Can not set multicaset or zero addr:%pM\n",
3268 			__func__, sa->sa_data);
3269 		return -EADDRNOTAVAIL;
3270 	}
3271 
3272 	/*
3273 	 * address_id: 0 for sta\ap; 1 for p2p device; 2 for p2p interface
3274 	 * if_id: 0 for sta\ap; 1 for p2p interface; 2 for p2p device
3275 	 * It is different between address_id and if_id in 1 and 2
3276 	 */
3277 	address_id = priv->if_id;
3278 	if (address_id == 2)
3279 		address_id = 1;
3280 
3281 	sta_printk(XRADIO_DBG_ALWY, "%s: old mac_address:%pM, new mac_address:%pM\n", __func__,
3282 				hw_priv->addresses[address_id].addr, sa->sa_data);
3283 
3284 	/*Change mac in fw*/
3285 	ret = wsm_write_mib(hw_priv, WSM_MIB_ID_CHANGE_MAC,
3286 			sa->sa_data, ETH_ALEN, address_id);
3287 	if (ret)
3288 		return ret;
3289 
3290 	memcpy(hw_priv->addresses[address_id].addr, sa->sa_data, ETH_ALEN);
3291 
3292 	return 0;
3293 }
3294 
3295 
3296 #if 0
3297 /**
3298  * xradio_set_multicastaddrfilter -called when tesmode command
3299  * is for setting the ipv4 address filter
3300  *
3301  * @hw: the hardware
3302  * @data: incoming data
3303  *
3304  * Returns: 0 on success or non zero value on failure
3305  */
3306 static int xradio_set_multicastfilter(struct xradio_common *hw_priv,
3307 					      struct xradio_vif *priv, u8 *data)
3308 {
3309 	u8 i = 0;
3310 	int ret = 0;
3311 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3312 
3313 	memset(&priv->multicast_filter, 0, sizeof(priv->multicast_filter));
3314 	priv->multicast_filter.enable = (u32)data[0];
3315 	priv->multicast_filter.numOfAddresses = (u32)data[1];
3316 
3317 	for (i = 0; i < priv->multicast_filter.numOfAddresses; i++) {
3318 		memcpy(&priv->multicast_filter.macAddress[i], \
3319 			   &data[2+(i*ETH_ALEN)], ETH_ALEN);
3320 	}
3321 	/* Configure the multicast mib in case of drop all multicast */
3322 	if (priv->multicast_filter.enable != 2)
3323 		return ret;
3324 
3325 	ret = wsm_write_mib(hw_priv, WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE, \
3326 		&priv->multicast_filter, sizeof(priv->multicast_filter), priv->if_id);
3327 
3328 	return ret;
3329 }
3330 #endif
3331 
3332 #ifdef IPV6_FILTERING
3333 /**
3334  * xradio_set_ipv6addrfilter -called when tesmode command
3335  * is for setting the ipv6 address filter
3336  *
3337  * @hw: the hardware
3338  * @data: incoming data
3339  * @if_id: interface id
3340  *
3341  * Returns: 0 on success or non zero value on failure
3342  */
xradio_set_ipv6addrfilter(struct ieee80211_hw * hw,u8 * data,int if_id)3343 static int xradio_set_ipv6addrfilter(struct ieee80211_hw *hw,
3344 				     u8 *data, int if_id)
3345 {
3346 	struct xradio_common *hw_priv = (struct xradio_common *) hw->priv;
3347 	struct wsm_ipv6_filter  *ipv6_filter =  NULL;
3348 	struct ipv6_addr_info *ipv6_info = NULL;
3349 	u8 action_mode = 0, no_of_ip_addr = 0, i = 0, ret = 0;
3350 	u16 ipaddrfiltersize = 0;
3351 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3352 
3353 	/* Retrieving Action Mode */
3354 	action_mode = data[0];
3355 	/* Retrieving number of ipv4 address entries */
3356 	no_of_ip_addr = data[1];
3357 
3358 	ipv6_info = (struct ipv6_addr_info *)&data[2];
3359 
3360 	/* Computing sizeof Mac addr filter */
3361 	ipaddrfiltersize =  sizeof(*ipv6_filter) + \
3362 			(no_of_ip_addr * sizeof(struct wsm_ip6_addr_info));
3363 
3364 
3365 	ipv6_filter = xr_kzalloc(ipaddrfiltersize, false);
3366 	if (!ipv6_filter) {
3367 		ret = -ENOMEM;
3368 		goto exit_p;
3369 	}
3370 	ipv6_filter->action_mode = action_mode;
3371 	ipv6_filter->numfilter = no_of_ip_addr;
3372 
3373 	for (i = 0; i < no_of_ip_addr; i++) {
3374 		ipv6_filter->ipv6filter[i].address_mode = \
3375 					ipv6_info[i].address_mode;
3376 		ipv6_filter->ipv6filter[i].filter_mode = \
3377 					ipv6_info[i].filter_mode;
3378 		memcpy(ipv6_filter->ipv6filter[i].ipv6, \
3379 					(u8 *)(ipv6_info[i].ipv6), 16);
3380 	}
3381 
3382 	ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_IP_IPV6_ADDR_FILTER, \
3383 					 ipv6_filter, ipaddrfiltersize, \
3384 					 if_id));
3385 
3386 	kfree(ipv6_filter);
3387 exit_p:
3388 	return ret;
3389 }
3390 #endif /*IPV6_FILTERING*/
3391 
3392 /**
3393  * xradio_set_data_filter -configure data filter in device
3394 *
3395  * @hw: the hardware
3396  * @vif: vif
3397  * @data: incoming data
3398  * @len: incoming data length
3399  *
3400  */
xradio_set_data_filter(struct ieee80211_hw * hw,struct ieee80211_vif * vif,void * data,int len)3401 void xradio_set_data_filter(struct ieee80211_hw *hw,
3402 			   struct ieee80211_vif *vif,
3403 			   void *data, int len)
3404 {
3405 	int ret = 0;
3406 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
3407 	int filter_id;
3408 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3409 	if (!atomic_read(&priv->enabled)) {
3410 		sta_printk(XRADIO_DBG_NIY, "%s vif(type=%d) is not enable!\n",
3411 				__func__, vif->type);
3412 		return ;
3413 	}
3414 
3415 	if (!data) {
3416 		ret = -EINVAL;
3417 		goto exit_p;
3418 	}
3419 	filter_id = *((enum xradio_data_filterid *)data);
3420 
3421 	switch (filter_id) {
3422 #ifdef IPV6_FILTERING
3423 	case IPV6ADDR_FILTER_ID:
3424 		ret = xradio_set_ipv6addrfilter(hw, \
3425 			&((u8 *)data)[4], priv->if_id);
3426 		break;
3427 #endif /*IPV6_FILTERING*/
3428 	default:
3429 		ret = -EINVAL;
3430 		break;
3431 	}
3432 exit_p:
3433 
3434 	 return ;
3435 }
3436 
3437 /**
3438  * xradio_set_arpreply -called for creating and
3439  * configuring arp response template frame
3440  *
3441  * @hw: the hardware
3442  *
3443  * Returns: 0 on success or non zero value on failure
3444  */
xradio_set_arpreply(struct ieee80211_hw * hw,struct ieee80211_vif * vif)3445 int xradio_set_arpreply(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3446 {
3447 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
3448 	struct xradio_common *hw_priv = (struct xradio_common *)hw->priv;
3449 	u32 framehdrlen, encrypthdr, encrypttailsize, framebdylen = 0;
3450 	bool encrypt = false;
3451 	int ret = 0;
3452 
3453 #ifdef SUPPORT_HT40
3454 
3455 	struct template_frame_hdr *tmp_hdr  = NULL;
3456 
3457 #else
3458 
3459 	u8 *template_frame = NULL;
3460 
3461 #endif
3462 
3463 	struct ieee80211_hdr_3addr *dot11hdr = NULL;
3464 	struct ieee80211_snap_hdr *snaphdr = NULL;
3465 	struct arphdr *arp_hdr = NULL;
3466 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3467 
3468 #ifdef SUPPORT_HT40
3469 
3470 	tmp_hdr = (struct template_frame_hdr *)
3471 			xr_kzalloc(MAX_ARP_REPLY_TEMPLATE_SIZE, false);
3472 
3473 	if (!tmp_hdr) {
3474 		sta_printk(XRADIO_DBG_ERROR, "Template frame memory failed\n");
3475 		ret = -ENOMEM;
3476 		goto exit_p;
3477 	}
3478 	dot11hdr = (struct ieee80211_hdr_3addr *)&tmp_hdr[1];
3479 
3480 #else
3481 
3482 	template_frame = xr_kzalloc(MAX_ARP_REPLY_TEMPLATE_SIZE, false);
3483 	if (!template_frame) {
3484 		sta_printk(XRADIO_DBG_ERROR, "Template frame memory failed\n");
3485 		ret = -ENOMEM;
3486 		goto exit_p;
3487 	}
3488 	dot11hdr = (struct ieee80211_hdr_3addr *)&template_frame[4];
3489 
3490 #endif
3491 
3492 	framehdrlen = sizeof(*dot11hdr);
3493 	if ((priv->vif->type == NL80211_IFTYPE_AP) && priv->vif->p2p)
3494 		priv->unicast_cipher_type = WLAN_CIPHER_SUITE_CCMP;
3495 	switch (priv->unicast_cipher_type) {
3496 
3497 	case WLAN_CIPHER_SUITE_WEP40:
3498 	case WLAN_CIPHER_SUITE_WEP104:
3499 		sta_printk(XRADIO_DBG_NIY, "WEP\n");
3500 		encrypthdr = WEP_ENCRYPT_HDR_SIZE;
3501 		encrypttailsize = WEP_ENCRYPT_TAIL_SIZE;
3502 		encrypt = 1;
3503 		break;
3504 
3505 
3506 	case WLAN_CIPHER_SUITE_TKIP:
3507 		sta_printk(XRADIO_DBG_NIY, "WPA\n");
3508 		encrypthdr = WPA_ENCRYPT_HDR_SIZE;
3509 		encrypttailsize = WPA_ENCRYPT_TAIL_SIZE;
3510 		encrypt = 1;
3511 		break;
3512 
3513 	case WLAN_CIPHER_SUITE_CCMP:
3514 		sta_printk(XRADIO_DBG_NIY, "WPA2\n");
3515 		encrypthdr = WPA2_ENCRYPT_HDR_SIZE;
3516 		encrypttailsize = WPA2_ENCRYPT_TAIL_SIZE;
3517 		encrypt = 1;
3518 		break;
3519 
3520 	case WLAN_CIPHER_SUITE_SMS4:
3521 		sta_printk(XRADIO_DBG_NIY, "WAPI\n");
3522 		encrypthdr = WAPI_ENCRYPT_HDR_SIZE;
3523 		encrypttailsize = WAPI_ENCRYPT_TAIL_SIZE;
3524 		encrypt = 1;
3525 		break;
3526 
3527 	default:
3528 		encrypthdr = 0;
3529 		encrypttailsize = 0;
3530 		encrypt = 0;
3531 		break;
3532 	}
3533 
3534 	framehdrlen += encrypthdr;
3535 	/* Filling the 802.11 Hdr */
3536 	dot11hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
3537 	if (priv->vif->type == NL80211_IFTYPE_STATION ||
3538 		priv->vif->type == NL80211_IFTYPE_P2P_DEVICE)
3539 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3540 	else
3541 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3542 
3543 	if (encrypt)
3544 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_WEP);
3545 
3546 	if (priv->vif->bss_conf.qos) {
3547 		sta_printk(XRADIO_DBG_NIY, "QOS Enabled\n");
3548 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_QOS_DATAGRP);
3549 		*(u16 *)(dot11hdr + 1) = 0x0;
3550 		framehdrlen += 2;
3551 	} else {
3552 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_STYPE_DATA);
3553 	}
3554 
3555 	memcpy(dot11hdr->addr1, priv->vif->bss_conf.bssid, ETH_ALEN);
3556 	memcpy(dot11hdr->addr2, priv->vif->addr, ETH_ALEN);
3557 	memcpy(dot11hdr->addr3, priv->vif->bss_conf.bssid, ETH_ALEN);
3558 
3559 	/* Filling the LLC/SNAP Hdr */
3560 	snaphdr = (struct ieee80211_snap_hdr *)((u8 *)dot11hdr + framehdrlen);
3561 	memcpy(snaphdr, (struct ieee80211_snap_hdr *)rfc1042_header, \
3562 		sizeof(*snaphdr));
3563 	*(u16 *)(++snaphdr) = cpu_to_be16(ETH_P_ARP);
3564 	/* Updating the framebdylen with snaphdr and LLC hdr size */
3565 	framebdylen = sizeof(*snaphdr) + 2;
3566 
3567 	/* Filling the ARP Reply Payload */
3568 	arp_hdr = (struct arphdr *)((u8 *)dot11hdr + framehdrlen + framebdylen);
3569 	arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER);
3570 	arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP);
3571 	arp_hdr->ar_hln = ETH_ALEN;
3572 	arp_hdr->ar_pln = 4;
3573 	arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
3574 
3575 	/* Updating the frmbdylen with Arp Reply Hdr and Arp payload size(20) */
3576 	framebdylen += sizeof(*arp_hdr) + 20;
3577 
3578 	/* Updating the framebdylen with Encryption Tail Size */
3579 	framebdylen += encrypttailsize;
3580 
3581 	/* Filling the Template Frame Hdr */
3582 
3583 #ifdef SUPPORT_HT40
3584 
3585 	/* Template frame type */
3586 	tmp_hdr->frame_type = WSM_FRAME_TYPE_ARP_REPLY;
3587 
3588 	/* Rate to be fixed */
3589 	tmp_hdr->rate_entry = 0x00F0;
3590 
3591 	tmp_hdr->frmlen     = framehdrlen + framebdylen;
3592 
3593 	ret = WARN_ON(wsm_write_mib(hw_priv,
3594 			WSM_MIB_ID_TEMPLATE_FRAME, (void *)tmp_hdr,
3595 			(framehdrlen+framebdylen+sizeof(*tmp_hdr)),
3596 			priv->if_id));
3597 
3598 	kfree((void *)tmp_hdr);
3599 
3600 #else
3601 
3602 	template_frame[0] = WSM_FRAME_TYPE_ARP_REPLY; /* Template frame type */
3603 	template_frame[1] = 0xFF; /* Rate to be fixed */
3604 	((u16 *)&template_frame[2])[0] = framehdrlen + framebdylen;
3605 
3606 	ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_TEMPLATE_FRAME, \
3607 				      template_frame, (framehdrlen+framebdylen+4),
3608 				      priv->if_id));
3609 	kfree(template_frame);
3610 
3611 #endif
3612 
3613 exit_p:
3614 	return ret;
3615 }
3616 
3617 #ifdef ROAM_OFFLOAD
3618 /**
3619  * xradio_testmode_event -send asynchronous event
3620  * to userspace
3621  *
3622  * @wiphy: the wiphy
3623  * @msg_id: XR msg ID
3624  * @data: data to be sent
3625  * @len: data length
3626  * @gfp: allocation flag
3627  *
3628  * Returns: 0 on success or non zero value on failure
3629  */
xradio_testmode_event(struct wiphy * wiphy,const u32 msg_id,const void * data,int len,gfp_t gfp)3630 int xradio_testmode_event(struct wiphy *wiphy, const u32 msg_id,
3631 			  const void *data, int len, gfp_t gfp)
3632 {
3633 	struct sk_buff *skb = NULL;
3634 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3635 
3636 	skb = cfg80211_testmode_alloc_event_skb(wiphy,
3637 	      nla_total_size(len+sizeof(msg_id)), gfp);
3638 
3639 	if (!skb)
3640 		return -ENOMEM;
3641 
3642 	cfg80211_testmode_event(skb, gfp);
3643 	return 0;
3644 }
3645 #endif /*ROAM_OFFLOAD*/
3646 
3647 #ifdef IPV6_FILTERING
3648 /**
3649  * xradio_set_na -called for creating and
3650  * configuring NDP Neighbor Advertisement (NA) template frame
3651  *
3652  * @hw: the hardware
3653  * @vif: vif
3654  *
3655  * Returns: 0 on success or non zero value on failure
3656  */
xradio_set_na(struct ieee80211_hw * hw,struct ieee80211_vif * vif)3657 int xradio_set_na(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3658 {
3659 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
3660 	struct xradio_common *hw_priv = (struct xradio_common *)hw->priv;
3661 	u32 framehdrlen, encrypthdr, encrypttailsize, framebdylen = 0;
3662 	bool encrypt = false;
3663 	int ret = 0;
3664 
3665 #ifdef SUPPORT_HT40
3666 
3667 	struct template_frame_hdr *tmp_hdr  = NULL;
3668 
3669 #else
3670 
3671 	u8 *template_frame = NULL;
3672 
3673 #endif
3674 
3675 	struct ieee80211_hdr_3addr *dot11hdr = NULL;
3676 	struct ieee80211_snap_hdr *snaphdr = NULL;
3677 	struct ipv6hdr *ipv6_hdr = NULL;
3678 	struct icmp6hdr *icmp6_hdr = NULL;
3679 	struct nd_msg *na = NULL;
3680 	struct nd_opt_hdr *opt_hdr = NULL;
3681 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3682 
3683 #ifdef SUPPORT_HT40
3684 
3685 	tmp_hdr = xr_kzalloc(MAX_NEIGHBOR_ADVERTISEMENT_TEMPLATE_SIZE, false);
3686 	if (!tmp_hdr) {
3687 		sta_printk(XRADIO_DBG_ERROR, "Template frame memory failed\n");
3688 		ret = -ENOMEM;
3689 		goto exit_p;
3690 	}
3691 	dot11hdr = (struct ieee80211_hdr_3addr *)&tmp_hdr[1];
3692 
3693 #else
3694 
3695 	template_frame = xr_kzalloc(MAX_NEIGHBOR_ADVERTISEMENT_TEMPLATE_SIZE, false);
3696 	if (!template_frame) {
3697 		sta_printk(XRADIO_DBG_ERROR, "Template frame memory failed\n");
3698 		ret = -ENOMEM;
3699 		goto exit_p;
3700 	}
3701 	dot11hdr = (struct ieee80211_hdr_3addr *)&template_frame[4];
3702 
3703 #endif
3704 
3705 	framehdrlen = sizeof(*dot11hdr);
3706 	if ((priv->vif->type == NL80211_IFTYPE_AP) && priv->vif->p2p)
3707 		priv->unicast_cipher_type = WLAN_CIPHER_SUITE_CCMP;
3708 	switch (priv->unicast_cipher_type) {
3709 
3710 	case WLAN_CIPHER_SUITE_WEP40:
3711 	case WLAN_CIPHER_SUITE_WEP104:
3712 		sta_printk(XRADIO_DBG_NIY, "WEP\n");
3713 		encrypthdr = WEP_ENCRYPT_HDR_SIZE;
3714 		encrypttailsize = WEP_ENCRYPT_TAIL_SIZE;
3715 		encrypt = 1;
3716 		break;
3717 
3718 
3719 	case WLAN_CIPHER_SUITE_TKIP:
3720 		sta_printk(XRADIO_DBG_NIY, "WPA\n");
3721 		encrypthdr = WPA_ENCRYPT_HDR_SIZE;
3722 		encrypttailsize = WPA_ENCRYPT_TAIL_SIZE;
3723 		encrypt = 1;
3724 		break;
3725 
3726 	case WLAN_CIPHER_SUITE_CCMP:
3727 		sta_printk(XRADIO_DBG_NIY, "WPA2\n");
3728 		encrypthdr = WPA2_ENCRYPT_HDR_SIZE;
3729 		encrypttailsize = WPA2_ENCRYPT_TAIL_SIZE;
3730 		encrypt = 1;
3731 		break;
3732 
3733 	case WLAN_CIPHER_SUITE_SMS4:
3734 		sta_printk(XRADIO_DBG_NIY, "WAPI\n");
3735 		encrypthdr = WAPI_ENCRYPT_HDR_SIZE;
3736 		encrypttailsize = WAPI_ENCRYPT_TAIL_SIZE;
3737 		encrypt = 1;
3738 		break;
3739 
3740 	default:
3741 		encrypthdr = 0;
3742 		encrypttailsize = 0;
3743 		encrypt = 0;
3744 		break;
3745 	}
3746 
3747 	framehdrlen += encrypthdr;
3748 
3749 	/* Filling the 802.11 Hdr */
3750 	dot11hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
3751 	if (priv->vif->type == NL80211_IFTYPE_STATION ||
3752 		priv->vif->type == NL80211_IFTYPE_P2P_DEVICE)
3753 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3754 	else
3755 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3756 
3757 	if (encrypt)
3758 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_WEP);
3759 
3760 	if (priv->vif->bss_conf.qos) {
3761 		sta_printk(XRADIO_DBG_MSG, "QOS Enabled\n");
3762 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_QOS_DATAGRP);
3763 		/* Filling QOS Control Field */
3764 		 *(u16 *)(dot11hdr + 1) = 0x0;
3765 		 framehdrlen += 2;
3766 	} else {
3767 		dot11hdr->frame_control |= cpu_to_le16(IEEE80211_STYPE_DATA);
3768 	}
3769 
3770 	memcpy(dot11hdr->addr1, priv->vif->bss_conf.bssid, ETH_ALEN);
3771 	memcpy(dot11hdr->addr2, priv->vif->addr, ETH_ALEN);
3772 	memcpy(dot11hdr->addr3, priv->vif->bss_conf.bssid, ETH_ALEN);
3773 
3774 	/* Filling the LLC/SNAP Hdr */
3775 	snaphdr = (struct ieee80211_snap_hdr *)((u8 *)dot11hdr + framehdrlen);
3776 	memcpy(snaphdr, (struct ieee80211_snap_hdr *)rfc1042_header, \
3777 		sizeof(*snaphdr));
3778 	*(u16 *)(++snaphdr) = cpu_to_be16(ETH_P_IPV6);
3779 	/* Updating the framebdylen with snaphdr and LLC hdr size */
3780 	framebdylen = sizeof(*snaphdr) + 2;
3781 
3782 	/* Filling the ipv6 header */
3783 	ipv6_hdr = (struct ipv6hdr *)((u8 *)dot11hdr + framehdrlen + framebdylen);
3784 	ipv6_hdr->version = 6;
3785 	ipv6_hdr->priority = 0;
3786 	/* ??? check the be or le ??? whether to use cpu_to_be16(32)*/
3787 	ipv6_hdr->payload_len = cpu_to_be16(32);
3788 	ipv6_hdr->nexthdr = 58;
3789 	ipv6_hdr->hop_limit = 255;
3790 
3791 	/* Updating the framebdylen with ipv6 Hdr */
3792 	framebdylen += sizeof(*ipv6_hdr);
3793 
3794 	/* Filling the Neighbor Advertisement */
3795 	na = (struct nd_msg *)((u8 *)dot11hdr + framehdrlen + framebdylen);
3796 	icmp6_hdr = (struct icmp6hdr *)(&na->icmph);
3797 	icmp6_hdr->icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
3798 	icmp6_hdr->icmp6_code = 0;
3799 	/* checksum (2 bytes), RSO fields (4 bytes) and
3800 	 * target IP address (16 bytes) shall be filled by firmware */
3801 
3802 	/* Filling the target link layer address in the optional field */
3803 	opt_hdr = (struct nd_opt_hdr *)(&na->opt[0]);
3804 	opt_hdr->nd_opt_type = 2;
3805 	opt_hdr->nd_opt_len = 1;
3806 	/* optional target link layer address (6 bytes)
3807 	 * shall be filled by firmware */
3808 
3809 	/* Updating the framebdylen with the ipv6 payload length */
3810 	framebdylen += 32;
3811 
3812 	/* Updating the framebdylen with Encryption Tail Size */
3813 	framebdylen += encrypttailsize;
3814 
3815 	/* Filling the Template Frame Hdr */
3816 
3817 #ifdef SUPPORT_HT40
3818 
3819 	tmp_hdr->frame_type = WSM_FRAME_TYPE_NA; /* Template frame type */
3820 	tmp_hdr->rate_entry = 0x00F0; /* Rate to be fixed */
3821 	tmp_hdr->frmlen = framehdrlen + framebdylen;
3822 
3823 	ret = WARN_ON(wsm_write_mib(hw_priv,
3824 			WSM_MIB_ID_TEMPLATE_FRAME, (void *)tmp_hdr,
3825 			(framehdrlen+framebdylen+sizeof(*tmp_hdr)),
3826 			priv->if_id));
3827 
3828 	kfree((void *)tmp_hdr);
3829 
3830 #else
3831 
3832 	template_frame[0] = WSM_FRAME_TYPE_NA; /* Template frame type */
3833 	template_frame[1] = 0xFF; /* Rate to be fixed */
3834 	((u16 *)&template_frame[2])[0] = framehdrlen + framebdylen;
3835 
3836 	ret = SYS_WARN(wsm_write_mib(hw_priv, WSM_MIB_ID_TEMPLATE_FRAME, \
3837 				template_frame, (framehdrlen+framebdylen+4), \
3838 				priv->if_id));
3839 
3840 	kfree(template_frame);
3841 
3842 #endif
3843 
3844 exit_p:
3845 	return ret;
3846 }
3847 #endif /*IPV6_FILTERING*/
3848 
3849 #ifdef CONFIG_XRADIO_TESTMODE
3850 /**
3851  * xradio_set_snap_frame -Set SNAP frame format
3852  *
3853  * @hw: the hardware
3854  * @data: data frame
3855  * @len: data length
3856  *
3857  * Returns: 0 on success or non zero value on failure
3858  */
xradio_set_snap_frame(struct ieee80211_hw * hw,u8 * data,int len)3859 static int xradio_set_snap_frame(struct ieee80211_hw *hw,
3860 				 u8 *data, int len)
3861 {
3862 	struct xr_msg_set_snap_frame *snap_frame =
3863 		(struct xr_msg_set_snap_frame *) data;
3864 	struct xradio_common *priv = (struct xradio_common *) hw->priv;
3865 	u8 frame_len = snap_frame->len;
3866 	u8 *frame = &snap_frame->frame[0];
3867 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3868 
3869 	/*
3870 	 * Check length of incoming frame format:
3871 	 * SNAP + SNAP_LEN (u8)
3872 	 */
3873 	if (frame_len + sizeof(snap_frame->len) != len)
3874 		return -EINVAL;
3875 
3876 	if (frame_len > 0) {
3877 		priv->test_frame.data = (u8 *) xr_krealloc(priv->test_frame.data,
3878 						sizeof(u8) * frame_len, false);
3879 		if (priv->test_frame.data == NULL) {
3880 			sta_printk(XRADIO_DBG_ERROR, "xradio_set_snap_frame memory" \
3881 					 "allocation failed");
3882 			priv->test_frame.len = 0;
3883 			return -EINVAL;
3884 		}
3885 		memcpy(priv->test_frame.data, frame, frame_len);
3886 	} else {
3887 		kfree(priv->test_frame.data);
3888 		priv->test_frame.data = NULL;
3889 	}
3890 	priv->test_frame.len = frame_len;
3891 	return 0;
3892 }
3893 
3894 #ifdef CONFIG_XRADIO_TESTMODE
3895 /**
3896  * xradio_set_txqueue_params -Set txqueue
3897  * params after successful TSPEC negotiation
3898  *
3899  * @hw: the hardware
3900  * @data: data frame
3901  * @len: data length
3902  *
3903  * Returns: 0 on success or non zero value on failure
3904  */
xradio_set_txqueue_params(struct ieee80211_hw * hw,u8 * data,int len)3905 static int xradio_set_txqueue_params(struct ieee80211_hw *hw,
3906 				     u8 *data, int len)
3907 {
3908 	struct xr_msg_set_txqueue_params *txqueue_params =
3909 		(struct xr_msg_set_txqueue_params *) data;
3910 	struct xradio_common *hw_priv = (struct xradio_common *) hw->priv;
3911 	struct xradio_vif *priv;
3912 	/* Interface ID is hard coded here, as interface is not
3913 	 * passed in testmode command.
3914 	 * Also it is assumed here that STA will be on interface
3915 	 * 0 always.
3916 	 */
3917 
3918 	int if_id = 0;
3919 	u16 queueId = xradio_priority_to_queueId[txqueue_params->user_priority];
3920 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3921 
3922 	priv = xrwl_hwpriv_to_vifpriv(hw_priv, if_id);
3923 
3924 	if (unlikely(!priv)) {
3925 		sta_printk(XRADIO_DBG_ERROR, "%s: Warning Priv is Null\n",
3926 			   __func__);
3927 		return 0;
3928 	}
3929 	spin_unlock(&priv->vif_lock);
3930 
3931 	/* Default Ack policy is WSM_ACK_POLICY_NORMAL */
3932 	WSM_TX_QUEUE_SET(&priv->tx_queue_params,
3933 			queueId,
3934 			WSM_ACK_POLICY_NORMAL,
3935 			txqueue_params->medium_time,
3936 			txqueue_params->expiry_time);
3937 	return SYS_WARN(wsm_set_tx_queue_params(hw_priv,
3938 			&priv->tx_queue_params.params[queueId], queueId,
3939 			priv->if_id));
3940 }
3941 #endif /*CONFIG_XRADIO_TESTMODE*/
3942 
3943 /**
3944  * xradio_tesmode_reply -called inside a testmode command
3945  * handler to send a response to user space
3946  *
3947  * @wiphy: the wiphy
3948  * @data: data to be send to user space
3949  * @len: data length
3950  *
3951  * Returns: 0 on success or non zero value on failure
3952  */
xradio_tesmode_reply(struct wiphy * wiphy,const void * data,int len)3953 static int xradio_tesmode_reply(struct wiphy *wiphy,
3954 				const void *data, int len)
3955 {
3956 	int ret = 0;
3957 	struct sk_buff *skb = NULL;
3958 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3959 
3960 	skb = cfg80211_testmode_alloc_reply_skb(wiphy, nla_total_size(len));
3961 
3962 	if (!skb)
3963 		return -ENOMEM;
3964 
3965 	ret = nla_put(skb, XR_TM_MSG_DATA, len, data);
3966 	if (ret) {
3967 		kfree_skb(skb);
3968 		return ret;
3969 	}
3970 
3971 	return cfg80211_testmode_reply(skb);
3972 }
3973 
3974 /**
3975  * xradio_tesmode_event -send asynchronous event
3976  * to userspace
3977  *
3978  * @wiphy: the wiphy
3979  * @msg_id: XR msg ID
3980  * @data: data to be sent
3981  * @len: data length
3982  * @gfp: allocation flag
3983  *
3984  * Returns: 0 on success or non zero value on failure
3985  */
xradio_tesmode_event(struct wiphy * wiphy,const u32 msg_id,const void * data,int len,gfp_t gfp)3986 int xradio_tesmode_event(struct wiphy *wiphy, const u32 msg_id,
3987 			 const void *data, int len, gfp_t gfp)
3988 {
3989 	struct sk_buff *skb = NULL;
3990 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
3991 
3992 	skb = cfg80211_testmode_alloc_event_skb(wiphy,
3993 	      nla_total_size(len+sizeof(msg_id)), gfp);
3994 	if (!skb)
3995 		return -ENOMEM;
3996 
3997 	NLA_PUT_U32(skb, XR_TM_MSG_ID, msg_id);
3998 	if (data)
3999 		NLA_PUT(skb, XR_TM_MSG_DATA, len, data);
4000 
4001 	cfg80211_testmode_event(skb, gfp);
4002 	return 0;
4003 nla_put_failure:
4004 	kfree_skb(skb);
4005 	return -ENOBUFS;
4006 }
4007 
4008 /**
4009  * example function for test purposes
4010  * sends both: synchronous reply and asynchronous event
4011  */
xradio_test(struct ieee80211_hw * hw,void * data,int len)4012 static int xradio_test(struct ieee80211_hw *hw,
4013 		       void *data, int len)
4014 {
4015 	struct xr_msg_test_t *test_p;
4016 	struct xr_reply_test_t reply;
4017 	struct xr_event_test_t event;
4018 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4019 
4020 	if (sizeof(struct xr_msg_test_t)  != len)
4021 		return -EINVAL;
4022 
4023 	test_p = (struct xr_msg_test_t *) data;
4024 
4025 	reply.dummy = test_p->dummy + 10;
4026 
4027 	event.dummy = test_p->dummy + 20;
4028 
4029 	if (xradio_tesmode_event(hw->wiphy, XR_MSG_EVENT_TEST,
4030 		&event, sizeof(event), GFP_KERNEL))
4031 		return -1;
4032 
4033 	return xradio_tesmode_reply(hw->wiphy, &reply, sizeof(reply));
4034 }
4035 
4036 /**
4037  * xradio_get_tx_power_level - send tx power level
4038  * to userspace
4039  *
4040  * @hw: the hardware
4041  *
4042  * Returns: 0 on success or non zero value on failure
4043  */
xradio_get_tx_power_level(struct ieee80211_hw * hw)4044 int xradio_get_tx_power_level(struct ieee80211_hw *hw)
4045 {
4046 	struct xradio_common *hw_priv = hw->priv;
4047 	int get_power = 0;
4048 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4049 
4050 	get_power = hw_priv->output_power;
4051 	sta_printk(XRADIO_DBG_MSG, "%s: Power set on Device : %d",
4052 		__func__, get_power);
4053 	return xradio_tesmode_reply(hw->wiphy, &get_power, sizeof(get_power));
4054 }
4055 
4056 /**
4057  * xradio_get_tx_power_range- send tx power range
4058  * to userspace for each band
4059  *
4060  * @hw: the hardware
4061  *
4062  * Returns: 0 on success or non zero value on failure
4063  */
xradio_get_tx_power_range(struct ieee80211_hw * hw)4064 int xradio_get_tx_power_range(struct ieee80211_hw *hw)
4065 {
4066 	struct xradio_common *hw_priv = hw->priv;
4067 	struct wsm_tx_power_range txPowerRange[2];
4068 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4069 
4070 	size_t len = sizeof(txPowerRange);
4071 	memcpy(txPowerRange, hw_priv->txPowerRange, len);
4072 	return xradio_tesmode_reply(hw->wiphy, txPowerRange, len);
4073 }
4074 
4075 /**
4076  * xradio_set_advance_scan_elems -Set Advcance Scan
4077  * elements
4078  * @hw: the hardware
4079  * @data: data frame
4080  * @len: data length
4081  *
4082  * Returns: 0 on success or non zero value on failure
4083  */
xradio_set_advance_scan_elems(struct ieee80211_hw * hw,u8 * data,int len)4084 static int xradio_set_advance_scan_elems(struct ieee80211_hw *hw,
4085 				 u8 *data, int len)
4086 {
4087 	struct advance_scan_elems *scan_elems =
4088 		(struct advance_scan_elems *) data;
4089 	struct xradio_common *hw_priv = (struct xradio_common *) hw->priv;
4090 	size_t elems_len = sizeof(struct advance_scan_elems);
4091 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4092 
4093 	if (elems_len != len)
4094 		return -EINVAL;
4095 
4096 	scan_elems = (struct advance_scan_elems *) data;
4097 
4098 	/* Locks required to prevent simultaneous scan */
4099 	down(&hw_priv->scan.lock);
4100 	down(&hw_priv->conf_lock);
4101 
4102 	hw_priv->advanceScanElems.scanMode = scan_elems->scanMode;
4103 	hw_priv->advanceScanElems.duration = scan_elems->duration;
4104 	hw_priv->enable_advance_scan = true;
4105 
4106 	up(&hw_priv->conf_lock);
4107 	up(&hw_priv->scan.lock);
4108 
4109 	return 0;
4110 }
4111 
4112 /**
4113  * xradio_set_power_save -Set Power Save
4114  * elements
4115  * @hw: the hardware
4116  * @data: data frame
4117  * @len: data length
4118  *
4119  * Returns: 0 on success or non zero value on failure
4120  */
xradio_set_power_save(struct ieee80211_hw * hw,u8 * data,int len)4121 static int xradio_set_power_save(struct ieee80211_hw *hw,
4122 				 u8 *data, int len)
4123 {
4124 	struct power_save_elems *ps_elems =
4125 		(struct power_save_elems *) data;
4126 	struct xradio_common *hw_priv = (struct xradio_common *) hw->priv;
4127 	size_t elems_len = sizeof(struct power_save_elems);
4128 	struct xradio_vif *priv;
4129 	int if_id = 0;
4130 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4131 
4132 	/* Interface ID is hard coded here, as interface is not
4133 	* passed in testmode command.
4134 	* Also it is assumed here that STA will be on interface
4135 	* 0 always. */
4136 
4137 	if (elems_len != len)
4138 		return -EINVAL;
4139 
4140 	priv = xrwl_hwpriv_to_vifpriv(hw_priv, if_id);
4141 
4142 	if (unlikely(!priv)) {
4143 		sta_printk(XRADIO_DBG_ERROR, "%s: Warning Priv is Null\n",
4144 			   __func__);
4145 		return 0;
4146 	}
4147 
4148 	spin_unlock(&priv->vif_lock);
4149 	down(&hw_priv->conf_lock);
4150 
4151 	ps_elems = (struct power_save_elems *) data;
4152 
4153 	if (ps_elems->powerSave == 1)
4154 		priv->user_pm_mode = WSM_PSM_PS;
4155 	else
4156 		priv->user_pm_mode = WSM_PSM_FAST_PS;
4157 
4158 	sta_printk(XRADIO_DBG_MSG, "Aid: %d, Joined: %s, Powersave: %s\n",
4159 		priv->bss_params.aid,
4160 		priv->join_status == XRADIO_JOIN_STATUS_STA ? "yes" : "no",
4161 		priv->user_pm_mode == WSM_PSM_ACTIVE ? "WSM_PSM_ACTIVE" :
4162 		priv->user_pm_mode == WSM_PSM_PS ? "WSM_PSM_PS" :
4163 		priv->user_pm_mode == WSM_PSM_FAST_PS ? "WSM_PSM_FAST_PS" : "UNKNOWN");
4164 	if (priv->join_status == XRADIO_JOIN_STATUS_STA &&
4165 			priv->bss_params.aid &&
4166 			priv->setbssparams_done &&
4167 			priv->filter4.enable) {
4168 		priv->powersave_mode.pmMode = priv->user_pm_mode;
4169 		xradio_set_pm(priv, &priv->powersave_mode);
4170 	} else {
4171 		priv->user_power_set_true = ps_elems->powerSave;
4172 	}
4173 	up(&hw_priv->conf_lock);
4174 	return 0;
4175 }
4176 /**
4177  * xradio_start_stop_tsm - starts/stops collecting TSM
4178  *
4179  * @hw: the hardware
4180  * @data: data frame
4181  *
4182  * Returns: 0 on success or non zero value on failure
4183  */
xradio_start_stop_tsm(struct ieee80211_hw * hw,void * data)4184 int xradio_start_stop_tsm(struct ieee80211_hw *hw, void *data)
4185 {
4186 	struct xr_msg_start_stop_tsm *start_stop_tsm =
4187 		(struct xr_msg_start_stop_tsm *) data;
4188 	struct xradio_common *hw_priv = hw->priv;
4189 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4190 
4191 	hw_priv->start_stop_tsm.start = start_stop_tsm->start;
4192 	hw_priv->start_stop_tsm.up = start_stop_tsm->up;
4193 	hw_priv->start_stop_tsm.packetization_delay =
4194 		start_stop_tsm->packetization_delay;
4195 	sta_printk(XRADIO_DBG_MSG, "%s: start : %u: up : %u",
4196 		__func__, hw_priv->start_stop_tsm.start,
4197 		hw_priv->start_stop_tsm.up);
4198 	hw_priv->tsm_info.ac = xradio_1d_to_ac[start_stop_tsm->up];
4199 
4200 	if (!hw_priv->start_stop_tsm.start) {
4201 		spin_lock_bh(&hw_priv->tsm_lock);
4202 		memset(&hw_priv->tsm_stats, 0, sizeof(hw_priv->tsm_stats));
4203 		memset(&hw_priv->tsm_info, 0, sizeof(hw_priv->tsm_info));
4204 		spin_unlock_bh(&hw_priv->tsm_lock);
4205 	}
4206 	return 0;
4207 }
4208 
4209 /**
4210  * xradio_get_tsm_params - Retrieves TSM parameters
4211  *
4212  * @hw: the hardware
4213  *
4214  * Returns: TSM parameters collected
4215  */
xradio_get_tsm_params(struct ieee80211_hw * hw)4216 int xradio_get_tsm_params(struct ieee80211_hw *hw)
4217 {
4218 	struct xradio_common *hw_priv = hw->priv;
4219 	struct xr_tsm_stats tsm_stats;
4220 	u32 pkt_count;
4221 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4222 
4223 	spin_lock_bh(&hw_priv->tsm_lock);
4224 	pkt_count = hw_priv->tsm_stats.txed_msdu_count -
4225 			 hw_priv->tsm_stats.msdu_discarded_count;
4226 	if (pkt_count) {
4227 		hw_priv->tsm_stats.avg_q_delay =
4228 			hw_priv->tsm_info.sum_pkt_q_delay/(pkt_count * 1000);
4229 		hw_priv->tsm_stats.avg_transmit_delay =
4230 			hw_priv->tsm_info.sum_media_delay/pkt_count;
4231 	} else {
4232 		hw_priv->tsm_stats.avg_q_delay = 0;
4233 		hw_priv->tsm_stats.avg_transmit_delay = 0;
4234 	}
4235 	sta_printk(XRADIO_DBG_MSG, "%s: Txed MSDU count : %u",
4236 		__func__, hw_priv->tsm_stats.txed_msdu_count);
4237 	sta_printk(XRADIO_DBG_MSG, "%s: Average queue delay : %u",
4238 			__func__, hw_priv->tsm_stats.avg_q_delay);
4239 	sta_printk(XRADIO_DBG_MSG, "%s: Average transmit delay : %u",
4240 			__func__, hw_priv->tsm_stats.avg_transmit_delay);
4241 	memcpy(&tsm_stats, &hw_priv->tsm_stats, sizeof(hw_priv->tsm_stats));
4242 	/* Reset the TSM statistics */
4243 	memset(&hw_priv->tsm_stats, 0, sizeof(hw_priv->tsm_stats));
4244 	hw_priv->tsm_info.sum_pkt_q_delay = 0;
4245 	hw_priv->tsm_info.sum_media_delay = 0;
4246 	spin_unlock_bh(&hw_priv->tsm_lock);
4247 	return xradio_tesmode_reply(hw->wiphy, &tsm_stats,
4248 				     sizeof(hw_priv->tsm_stats));
4249 }
4250 
4251 /**
4252  * xradio_get_roam_delay - Retrieves roam delay
4253  *
4254  * @hw: the hardware
4255  *
4256  * Returns: Returns the last measured roam delay
4257  */
xradio_get_roam_delay(struct ieee80211_hw * hw)4258 int xradio_get_roam_delay(struct ieee80211_hw *hw)
4259 {
4260 	struct xradio_common *hw_priv = hw->priv;
4261 	u16 roam_delay = hw_priv->tsm_info.roam_delay / 1000;
4262 	sta_printk(XRADIO_DBG_MSG, "%s: Roam delay : %u",
4263 		__func__, roam_delay);
4264 
4265 	spin_lock_bh(&hw_priv->tsm_lock);
4266 	hw_priv->tsm_info.roam_delay = 0;
4267 	hw_priv->tsm_info.use_rx_roaming = 0;
4268 	spin_unlock_bh(&hw_priv->tsm_lock);
4269 	return xradio_tesmode_reply(hw->wiphy, &roam_delay, sizeof(u16));
4270 }
4271 
4272 /**
4273  * xradio_testmode_cmd -called when tesmode command
4274  * reaches xradio
4275  *
4276  * @hw: the hardware
4277  * @data: incoming data
4278  * @len: incoming data length
4279  *
4280  * Returns: 0 on success or non zero value on failure
4281  */
xradio_testmode_cmd(struct ieee80211_hw * hw,void * data,int len)4282 int xradio_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
4283 {
4284 	int ret = 0;
4285 	struct nlattr *type_p = nla_find(data, len, XR_TM_MSG_ID);
4286 	struct nlattr *data_p = nla_find(data, len, XR_TM_MSG_DATA);
4287 	sta_printk(XRADIO_DBG_TRC, "%s\n", __func__);
4288 
4289 	if (!type_p || !data_p)
4290 		return -EINVAL;
4291 
4292 	sta_printk(XRADIO_DBG_MSG,  "%s: type: %i",
4293 		   __func__, nla_get_u32(type_p));
4294 
4295 	switch (nla_get_u32(type_p)) {
4296 	case XR_MSG_TEST:
4297 		ret = xradio_test(hw,
4298 			nla_data(data_p), nla_len(data_p));
4299 		break;
4300 	case XR_MSG_SET_SNAP_FRAME:
4301 		ret = xradio_set_snap_frame(hw, (u8 *) nla_data(data_p),
4302 			nla_len(data_p));
4303 		break;
4304 	case XR_MSG_GET_TX_POWER_LEVEL:
4305 		ret = xradio_get_tx_power_level(hw);
4306 		break;
4307 	case XR_MSG_GET_TX_POWER_RANGE:
4308 		ret = xradio_get_tx_power_range(hw);
4309 		break;
4310 	case XR_MSG_SET_ADVANCE_SCAN_ELEMS:
4311 		ret = xradio_set_advance_scan_elems(hw, (u8 *) nla_data(data_p),
4312 			nla_len(data_p));
4313 		break;
4314 	case XR_MSG_SET_TX_QUEUE_PARAMS:
4315 		ret = xradio_set_txqueue_params(hw, (u8 *) nla_data(data_p),
4316 			nla_len(data_p));
4317 		break;
4318 	case XR_MSG_GET_TSM_PARAMS:
4319 		ret = xradio_get_tsm_params(hw);
4320 		break;
4321 	case XR_MSG_START_STOP_TSM:
4322 		ret = xradio_start_stop_tsm(hw, (u8 *) nla_data(data_p));
4323 		break;
4324 	case XR_MSG_GET_ROAM_DELAY:
4325 		ret = xradio_get_roam_delay(hw);
4326 		break;
4327 	case XR_MSG_SET_POWER_SAVE:
4328 		ret = xradio_set_power_save(hw, (u8 *) nla_data(data_p),
4329 			nla_len(data_p));
4330 		break;
4331 	default:
4332 		break;
4333 	}
4334 	return ret;
4335 }
4336 #endif /* CONFIG_XRADIO_TESTMODE */
4337