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