]> git.ipfire.org Git - thirdparty/linux.git/blob - drivers/staging/wfx/sta.c
staging: wfx: check for memory allocation failures from wfx_alloc_hif
[thirdparty/linux.git] / drivers / staging / wfx / sta.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Implementation of mac80211 API.
4 *
5 * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
7 */
8 #include <net/mac80211.h>
9
10 #include "sta.h"
11 #include "wfx.h"
12 #include "fwio.h"
13 #include "bh.h"
14 #include "key.h"
15 #include "scan.h"
16 #include "debug.h"
17 #include "hif_tx.h"
18 #include "hif_tx_mib.h"
19
20 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
21
22 static u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
23 {
24 int i;
25 u32 ret = 0;
26 // WFx only support 2GHz
27 struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
28
29 for (i = 0; i < sband->n_bitrates; i++) {
30 if (rates & BIT(i)) {
31 if (i >= sband->n_bitrates)
32 dev_warn(wdev->dev, "unsupported basic rate\n");
33 else
34 ret |= BIT(sband->bitrates[i].hw_value);
35 }
36 }
37 return ret;
38 }
39
40 static void __wfx_free_event_queue(struct list_head *list)
41 {
42 struct wfx_hif_event *event, *tmp;
43
44 list_for_each_entry_safe(event, tmp, list, link) {
45 list_del(&event->link);
46 kfree(event);
47 }
48 }
49
50 static void wfx_free_event_queue(struct wfx_vif *wvif)
51 {
52 LIST_HEAD(list);
53
54 spin_lock(&wvif->event_queue_lock);
55 list_splice_init(&wvif->event_queue, &list);
56 spin_unlock(&wvif->event_queue_lock);
57
58 __wfx_free_event_queue(&list);
59 }
60
61 void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad)
62 {
63 int tx = 0;
64
65 mutex_lock(&wvif->bss_loss_lock);
66 cancel_work_sync(&wvif->bss_params_work);
67
68 if (init) {
69 schedule_delayed_work(&wvif->bss_loss_work, HZ);
70 wvif->bss_loss_state = 0;
71
72 if (!atomic_read(&wvif->wdev->tx_lock))
73 tx = 1;
74 } else if (good) {
75 cancel_delayed_work_sync(&wvif->bss_loss_work);
76 wvif->bss_loss_state = 0;
77 schedule_work(&wvif->bss_params_work);
78 } else if (bad) {
79 /* FIXME Should we just keep going until we time out? */
80 if (wvif->bss_loss_state < 3)
81 tx = 1;
82 } else {
83 cancel_delayed_work_sync(&wvif->bss_loss_work);
84 wvif->bss_loss_state = 0;
85 }
86
87 /* Spit out a NULL packet to our AP if necessary */
88 // FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
89 if (tx) {
90 struct sk_buff *skb;
91
92 wvif->bss_loss_state++;
93
94 skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false);
95 if (!skb)
96 goto end;
97 memset(IEEE80211_SKB_CB(skb), 0,
98 sizeof(*IEEE80211_SKB_CB(skb)));
99 IEEE80211_SKB_CB(skb)->control.vif = wvif->vif;
100 IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0;
101 IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1;
102 IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1;
103 wfx_tx(wvif->wdev->hw, NULL, skb);
104 }
105 end:
106 mutex_unlock(&wvif->bss_loss_lock);
107 }
108
109 int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable)
110 {
111 wvif->fwd_probe_req = enable;
112 return hif_set_rx_filter(wvif, wvif->filter_bssid,
113 wvif->fwd_probe_req);
114 }
115
116 static int wfx_set_mcast_filter(struct wfx_vif *wvif,
117 struct wfx_grp_addr_table *fp)
118 {
119 int i, ret;
120 struct hif_mib_config_data_filter config = { };
121 struct hif_mib_set_data_filtering filter_data = { };
122 struct hif_mib_mac_addr_data_frame_condition filter_addr_val = { };
123 struct hif_mib_uc_mc_bc_data_frame_condition filter_addr_type = { };
124
125 // Temporary workaround for filters
126 return hif_set_data_filtering(wvif, &filter_data);
127
128 if (!fp->enable) {
129 filter_data.enable = 0;
130 return hif_set_data_filtering(wvif, &filter_data);
131 }
132
133 // A1 Address match on list
134 for (i = 0; i < fp->num_addresses; i++) {
135 filter_addr_val.condition_idx = i;
136 filter_addr_val.address_type = HIF_MAC_ADDR_A1;
137 ether_addr_copy(filter_addr_val.mac_address,
138 fp->address_list[i]);
139 ret = hif_set_mac_addr_condition(wvif,
140 &filter_addr_val);
141 if (ret)
142 return ret;
143 config.mac_cond |= 1 << i;
144 }
145
146 // Accept unicast and broadcast
147 filter_addr_type.condition_idx = 0;
148 filter_addr_type.param.bits.type_unicast = 1;
149 filter_addr_type.param.bits.type_broadcast = 1;
150 ret = hif_set_uc_mc_bc_condition(wvif, &filter_addr_type);
151 if (ret)
152 return ret;
153
154 config.uc_mc_bc_cond = 1;
155 config.filter_idx = 0; // TODO #define MULTICAST_FILTERING 0
156 config.enable = 1;
157 ret = hif_set_config_data_filter(wvif, &config);
158 if (ret)
159 return ret;
160
161 // discard all data frames except match filter
162 filter_data.enable = 1;
163 filter_data.default_filter = 1; // discard all
164 ret = hif_set_data_filtering(wvif, &filter_data);
165
166 return ret;
167 }
168
169 void wfx_update_filtering(struct wfx_vif *wvif)
170 {
171 int ret;
172 bool is_sta = wvif->vif && NL80211_IFTYPE_STATION == wvif->vif->type;
173 bool filter_bssid = wvif->filter_bssid;
174 bool fwd_probe_req = wvif->fwd_probe_req;
175 struct hif_mib_bcn_filter_enable bf_ctrl;
176 struct hif_ie_table_entry filter_ies[] = {
177 {
178 .ie_id = WLAN_EID_VENDOR_SPECIFIC,
179 .has_changed = 1,
180 .no_longer = 1,
181 .has_appeared = 1,
182 .oui = { 0x50, 0x6F, 0x9A },
183 }, {
184 .ie_id = WLAN_EID_HT_OPERATION,
185 .has_changed = 1,
186 .no_longer = 1,
187 .has_appeared = 1,
188 }, {
189 .ie_id = WLAN_EID_ERP_INFO,
190 .has_changed = 1,
191 .no_longer = 1,
192 .has_appeared = 1,
193 }
194 };
195 int n_filter_ies;
196
197 if (wvif->state == WFX_STATE_PASSIVE)
198 return;
199
200 if (wvif->disable_beacon_filter) {
201 bf_ctrl.enable = 0;
202 bf_ctrl.bcn_count = 1;
203 n_filter_ies = 0;
204 } else if (!is_sta) {
205 bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE |
206 HIF_BEACON_FILTER_AUTO_ERP;
207 bf_ctrl.bcn_count = 0;
208 n_filter_ies = 2;
209 } else {
210 bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE;
211 bf_ctrl.bcn_count = 0;
212 n_filter_ies = 3;
213 }
214
215 ret = hif_set_rx_filter(wvif, filter_bssid, fwd_probe_req);
216 if (!ret)
217 ret = hif_set_beacon_filter_table(wvif, n_filter_ies,
218 filter_ies);
219 if (!ret)
220 ret = hif_beacon_filter_control(wvif, bf_ctrl.enable,
221 bf_ctrl.bcn_count);
222 if (!ret)
223 ret = wfx_set_mcast_filter(wvif, &wvif->mcast_filter);
224 if (ret)
225 dev_err(wvif->wdev->dev, "update filtering failed: %d\n", ret);
226 }
227
228 static void wfx_update_filtering_work(struct work_struct *work)
229 {
230 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
231 update_filtering_work);
232
233 wfx_update_filtering(wvif);
234 }
235
236 u64 wfx_prepare_multicast(struct ieee80211_hw *hw,
237 struct netdev_hw_addr_list *mc_list)
238 {
239 int i;
240 struct netdev_hw_addr *ha;
241 struct wfx_vif *wvif = NULL;
242 struct wfx_dev *wdev = hw->priv;
243 int count = netdev_hw_addr_list_count(mc_list);
244
245 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
246 memset(&wvif->mcast_filter, 0x00, sizeof(wvif->mcast_filter));
247 if (!count ||
248 count > ARRAY_SIZE(wvif->mcast_filter.address_list))
249 continue;
250
251 i = 0;
252 netdev_hw_addr_list_for_each(ha, mc_list) {
253 ether_addr_copy(wvif->mcast_filter.address_list[i],
254 ha->addr);
255 i++;
256 }
257 wvif->mcast_filter.enable = true;
258 wvif->mcast_filter.num_addresses = count;
259 }
260
261 return 0;
262 }
263
264 void wfx_configure_filter(struct ieee80211_hw *hw,
265 unsigned int changed_flags,
266 unsigned int *total_flags,
267 u64 unused)
268 {
269 struct wfx_vif *wvif = NULL;
270 struct wfx_dev *wdev = hw->priv;
271
272 *total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ;
273
274 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
275 mutex_lock(&wvif->scan_lock);
276 wvif->filter_bssid = (*total_flags &
277 (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 0 : 1;
278 wvif->disable_beacon_filter = !(*total_flags & FIF_PROBE_REQ);
279 wfx_fwd_probe_req(wvif, true);
280 wfx_update_filtering(wvif);
281 mutex_unlock(&wvif->scan_lock);
282 }
283 }
284
285 static int wfx_update_pm(struct wfx_vif *wvif)
286 {
287 struct ieee80211_conf *conf = &wvif->wdev->hw->conf;
288 bool ps = conf->flags & IEEE80211_CONF_PS;
289 int ps_timeout = conf->dynamic_ps_timeout;
290
291 WARN_ON(conf->dynamic_ps_timeout < 0);
292 if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid)
293 return 0;
294 if (!ps)
295 ps_timeout = 0;
296 if (wvif->uapsd_mask)
297 ps_timeout = 0;
298
299 // Kernel disable PowerSave when multiple vifs are in use. In contrary,
300 // it is absolutly necessary to enable PowerSave for WF200
301 // FIXME: only if channel vif0 != channel vif1
302 if (wvif_count(wvif->wdev) > 1) {
303 ps = true;
304 ps_timeout = 0;
305 }
306
307 if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete,
308 TU_TO_JIFFIES(512)))
309 dev_warn(wvif->wdev->dev,
310 "timeout while waiting of set_pm_mode_complete\n");
311 return hif_set_pm(wvif, ps, ps_timeout);
312 }
313
314 int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
315 u16 queue, const struct ieee80211_tx_queue_params *params)
316 {
317 struct wfx_dev *wdev = hw->priv;
318 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
319 int ret = 0;
320
321 WARN_ON(queue >= hw->queues);
322
323 mutex_lock(&wdev->conf_mutex);
324 assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
325 memcpy(&wvif->edca_params[queue], params, sizeof(*params));
326 hif_set_edca_queue_params(wvif, queue, params);
327 if (wvif->vif->type == NL80211_IFTYPE_STATION) {
328 hif_set_uapsd_info(wvif, wvif->uapsd_mask);
329 if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA)
330 ret = wfx_update_pm(wvif);
331 }
332 mutex_unlock(&wdev->conf_mutex);
333 return ret;
334 }
335
336 int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
337 {
338 struct wfx_dev *wdev = hw->priv;
339 struct wfx_vif *wvif = NULL;
340
341 while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
342 hif_rts_threshold(wvif, value);
343 return 0;
344 }
345
346 /* If successful, LOCKS the TX queue! */
347 static int __wfx_flush(struct wfx_dev *wdev, bool drop)
348 {
349 int ret;
350
351 for (;;) {
352 if (drop) {
353 wfx_tx_queues_clear(wdev);
354 } else {
355 ret = wait_event_timeout(
356 wdev->tx_queue_stats.wait_link_id_empty,
357 wfx_tx_queues_is_empty(wdev),
358 2 * HZ);
359 }
360
361 if (!drop && ret <= 0) {
362 ret = -ETIMEDOUT;
363 break;
364 }
365 ret = 0;
366
367 wfx_tx_lock_flush(wdev);
368 if (!wfx_tx_queues_is_empty(wdev)) {
369 /* Highly unlikely: WSM requeued frames. */
370 wfx_tx_unlock(wdev);
371 continue;
372 }
373 break;
374 }
375 return ret;
376 }
377
378 void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
379 u32 queues, bool drop)
380 {
381 struct wfx_dev *wdev = hw->priv;
382 struct wfx_vif *wvif;
383
384 if (vif) {
385 wvif = (struct wfx_vif *) vif->drv_priv;
386 if (wvif->vif->type == NL80211_IFTYPE_MONITOR)
387 drop = true;
388 if (wvif->vif->type == NL80211_IFTYPE_AP &&
389 !wvif->enable_beacon)
390 drop = true;
391 }
392
393 // FIXME: only flush requested vif
394 if (!__wfx_flush(wdev, drop))
395 wfx_tx_unlock(wdev);
396 }
397
398 /* WSM callbacks */
399
400 static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
401 {
402 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
403 * RSSI = RCPI / 2 - 110
404 */
405 int rcpi_rssi;
406 int cqm_evt;
407
408 rcpi_rssi = raw_rcpi_rssi / 2 - 110;
409 if (rcpi_rssi <= wvif->cqm_rssi_thold)
410 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
411 else
412 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
413 ieee80211_cqm_rssi_notify(wvif->vif, cqm_evt, rcpi_rssi, GFP_KERNEL);
414 }
415
416 static void wfx_event_handler_work(struct work_struct *work)
417 {
418 struct wfx_vif *wvif =
419 container_of(work, struct wfx_vif, event_handler_work);
420 struct wfx_hif_event *event;
421
422 LIST_HEAD(list);
423
424 spin_lock(&wvif->event_queue_lock);
425 list_splice_init(&wvif->event_queue, &list);
426 spin_unlock(&wvif->event_queue_lock);
427
428 list_for_each_entry(event, &list, link) {
429 switch (event->evt.event_id) {
430 case HIF_EVENT_IND_BSSLOST:
431 cancel_work_sync(&wvif->unjoin_work);
432 mutex_lock(&wvif->scan_lock);
433 wfx_cqm_bssloss_sm(wvif, 1, 0, 0);
434 mutex_unlock(&wvif->scan_lock);
435 break;
436 case HIF_EVENT_IND_BSSREGAINED:
437 wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
438 cancel_work_sync(&wvif->unjoin_work);
439 break;
440 case HIF_EVENT_IND_RCPI_RSSI:
441 wfx_event_report_rssi(wvif,
442 event->evt.event_data.rcpi_rssi);
443 break;
444 case HIF_EVENT_IND_PS_MODE_ERROR:
445 dev_warn(wvif->wdev->dev,
446 "error while processing power save request\n");
447 break;
448 default:
449 dev_warn(wvif->wdev->dev,
450 "unhandled event indication: %.2x\n",
451 event->evt.event_id);
452 break;
453 }
454 }
455 __wfx_free_event_queue(&list);
456 }
457
458 static void wfx_bss_loss_work(struct work_struct *work)
459 {
460 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
461 bss_loss_work.work);
462
463 ieee80211_connection_loss(wvif->vif);
464 }
465
466 static void wfx_bss_params_work(struct work_struct *work)
467 {
468 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
469 bss_params_work);
470
471 mutex_lock(&wvif->wdev->conf_mutex);
472 wvif->bss_params.bss_flags.lost_count_only = 1;
473 hif_set_bss_params(wvif, &wvif->bss_params);
474 wvif->bss_params.bss_flags.lost_count_only = 0;
475 mutex_unlock(&wvif->wdev->conf_mutex);
476 }
477
478 static void wfx_set_beacon_wakeup_period_work(struct work_struct *work)
479 {
480 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
481 set_beacon_wakeup_period_work);
482
483 hif_set_beacon_wakeup_period(wvif, wvif->dtim_period,
484 wvif->dtim_period);
485 }
486
487 static void wfx_do_unjoin(struct wfx_vif *wvif)
488 {
489 mutex_lock(&wvif->wdev->conf_mutex);
490
491 if (!wvif->state)
492 goto done;
493
494 if (wvif->state == WFX_STATE_AP)
495 goto done;
496
497 cancel_work_sync(&wvif->update_filtering_work);
498 cancel_work_sync(&wvif->set_beacon_wakeup_period_work);
499 wvif->state = WFX_STATE_PASSIVE;
500
501 /* Unjoin is a reset. */
502 wfx_tx_flush(wvif->wdev);
503 hif_keep_alive_period(wvif, 0);
504 hif_reset(wvif, false);
505 wfx_tx_policy_init(wvif);
506 hif_set_output_power(wvif, wvif->wdev->output_power * 10);
507 wvif->dtim_period = 0;
508 hif_set_macaddr(wvif, wvif->vif->addr);
509 wfx_free_event_queue(wvif);
510 cancel_work_sync(&wvif->event_handler_work);
511 wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
512
513 /* Disable Block ACKs */
514 hif_set_block_ack_policy(wvif, 0, 0);
515
516 wvif->disable_beacon_filter = false;
517 wfx_update_filtering(wvif);
518 memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
519 wvif->setbssparams_done = false;
520 memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
521
522 done:
523 mutex_unlock(&wvif->wdev->conf_mutex);
524 }
525
526 static void wfx_set_mfp(struct wfx_vif *wvif,
527 struct cfg80211_bss *bss)
528 {
529 const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
530 const int pairwise_cipher_suite_size = 4 / sizeof(u16);
531 const int akm_suite_size = 4 / sizeof(u16);
532 const u16 *ptr = NULL;
533 bool mfpc = false;
534 bool mfpr = false;
535
536 /* 802.11w protected mgmt frames */
537
538 /* retrieve MFPC and MFPR flags from beacon or PBRSP */
539
540 rcu_read_lock();
541 if (bss)
542 ptr = (const u16 *) ieee80211_bss_get_ie(bss,
543 WLAN_EID_RSN);
544
545 if (ptr) {
546 ptr += pairwise_cipher_suite_count_offset;
547 ptr += 1 + pairwise_cipher_suite_size * *ptr;
548 ptr += 1 + akm_suite_size * *ptr;
549 mfpr = *ptr & BIT(6);
550 mfpc = *ptr & BIT(7);
551 }
552 rcu_read_unlock();
553
554 hif_set_mfp(wvif, mfpc, mfpr);
555 }
556
557 static void wfx_do_join(struct wfx_vif *wvif)
558 {
559 const u8 *bssid;
560 struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
561 struct cfg80211_bss *bss = NULL;
562 struct hif_req_join join = {
563 .infrastructure_bss_mode = !conf->ibss_joined,
564 .short_preamble = conf->use_short_preamble,
565 .probe_for_join = 1,
566 .atim_window = 0,
567 .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
568 conf->basic_rates),
569 };
570
571 wfx_tx_lock_flush(wvif->wdev);
572
573 if (wvif->channel->flags & IEEE80211_CHAN_NO_IR)
574 join.probe_for_join = 0;
575
576 if (wvif->state)
577 wfx_do_unjoin(wvif);
578
579 bssid = wvif->vif->bss_conf.bssid;
580
581 bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel,
582 bssid, NULL, 0,
583 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
584
585 if (!bss && !conf->ibss_joined) {
586 wfx_tx_unlock(wvif->wdev);
587 return;
588 }
589
590 mutex_lock(&wvif->wdev->conf_mutex);
591
592 /* Sanity check basic rates */
593 if (!join.basic_rate_set)
594 join.basic_rate_set = 7;
595
596 /* Sanity check beacon interval */
597 if (!wvif->beacon_int)
598 wvif->beacon_int = 1;
599
600 join.beacon_interval = wvif->beacon_int;
601
602 // DTIM period will be set on first Beacon
603 wvif->dtim_period = 0;
604
605 join.channel_number = wvif->channel->hw_value;
606 memcpy(join.bssid, bssid, sizeof(join.bssid));
607
608 if (!conf->ibss_joined) {
609 const u8 *ssidie;
610
611 rcu_read_lock();
612 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
613 if (ssidie) {
614 join.ssid_length = ssidie[1];
615 memcpy(join.ssid, &ssidie[2], join.ssid_length);
616 }
617 rcu_read_unlock();
618 }
619
620 wfx_tx_flush(wvif->wdev);
621
622 if (wvif_count(wvif->wdev) <= 1)
623 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
624
625 wfx_set_mfp(wvif, bss);
626
627 /* Perform actual join */
628 wvif->wdev->tx_burst_idx = -1;
629 if (hif_join(wvif, &join)) {
630 ieee80211_connection_loss(wvif->vif);
631 wvif->join_complete_status = -1;
632 /* Tx lock still held, unjoin will clear it. */
633 if (!schedule_work(&wvif->unjoin_work))
634 wfx_tx_unlock(wvif->wdev);
635 } else {
636 wvif->join_complete_status = 0;
637 if (wvif->vif->type == NL80211_IFTYPE_ADHOC)
638 wvif->state = WFX_STATE_IBSS;
639 else
640 wvif->state = WFX_STATE_PRE_STA;
641 wfx_tx_unlock(wvif->wdev);
642
643 /* Upload keys */
644 wfx_upload_keys(wvif);
645
646 /* Due to beacon filtering it is possible that the
647 * AP's beacon is not known for the mac80211 stack.
648 * Disable filtering temporary to make sure the stack
649 * receives at least one
650 */
651 wvif->disable_beacon_filter = true;
652 }
653 wfx_update_filtering(wvif);
654
655 mutex_unlock(&wvif->wdev->conf_mutex);
656 if (bss)
657 cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
658 }
659
660 static void wfx_unjoin_work(struct work_struct *work)
661 {
662 struct wfx_vif *wvif = container_of(work, struct wfx_vif, unjoin_work);
663
664 wfx_do_unjoin(wvif);
665 wfx_tx_unlock(wvif->wdev);
666 }
667
668 int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
669 struct ieee80211_sta *sta)
670 {
671 struct wfx_dev *wdev = hw->priv;
672 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
673 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
674 struct wfx_link_entry *entry;
675 struct sk_buff *skb;
676
677 if (wvif->vif->type != NL80211_IFTYPE_AP)
678 return 0;
679
680 sta_priv->vif_id = wvif->id;
681 sta_priv->link_id = wfx_find_link_id(wvif, sta->addr);
682 if (!sta_priv->link_id) {
683 dev_warn(wdev->dev, "mo more link-id available\n");
684 return -ENOENT;
685 }
686
687 entry = &wvif->link_id_db[sta_priv->link_id - 1];
688 spin_lock_bh(&wvif->ps_state_lock);
689 if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
690 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
691 wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
692 entry->status = WFX_LINK_HARD;
693 while ((skb = skb_dequeue(&entry->rx_queue)))
694 ieee80211_rx_irqsafe(wdev->hw, skb);
695 spin_unlock_bh(&wvif->ps_state_lock);
696 return 0;
697 }
698
699 int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
700 struct ieee80211_sta *sta)
701 {
702 struct wfx_dev *wdev = hw->priv;
703 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
704 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
705 struct wfx_link_entry *entry;
706
707 if (wvif->vif->type != NL80211_IFTYPE_AP || !sta_priv->link_id)
708 return 0;
709
710 entry = &wvif->link_id_db[sta_priv->link_id - 1];
711 spin_lock_bh(&wvif->ps_state_lock);
712 entry->status = WFX_LINK_RESERVE;
713 entry->timestamp = jiffies;
714 wfx_tx_lock(wdev);
715 if (!schedule_work(&wvif->link_id_work))
716 wfx_tx_unlock(wdev);
717 spin_unlock_bh(&wvif->ps_state_lock);
718 flush_work(&wvif->link_id_work);
719 return 0;
720 }
721
722 static void wfx_set_cts_work(struct work_struct *work)
723 {
724 struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_cts_work);
725 u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
726 struct hif_ie_flags target_frame = {
727 .beacon = 1,
728 };
729
730 mutex_lock(&wvif->wdev->conf_mutex);
731 erp_ie[2] = wvif->erp_info;
732 mutex_unlock(&wvif->wdev->conf_mutex);
733
734 hif_erp_use_protection(wvif, erp_ie[2] & WLAN_ERP_USE_PROTECTION);
735
736 if (wvif->vif->type != NL80211_IFTYPE_STATION)
737 hif_update_ie(wvif, &target_frame, erp_ie, sizeof(erp_ie));
738 }
739
740 static int wfx_start_ap(struct wfx_vif *wvif)
741 {
742 int ret;
743 struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
744 struct hif_req_start start = {
745 .channel_number = wvif->channel->hw_value,
746 .beacon_interval = conf->beacon_int,
747 .dtim_period = conf->dtim_period,
748 .short_preamble = conf->use_short_preamble,
749 .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
750 conf->basic_rates),
751 };
752
753 memset(start.ssid, 0, sizeof(start.ssid));
754 if (!conf->hidden_ssid) {
755 start.ssid_length = conf->ssid_len;
756 memcpy(start.ssid, conf->ssid, start.ssid_length);
757 }
758
759 wvif->beacon_int = conf->beacon_int;
760 wvif->dtim_period = conf->dtim_period;
761
762 memset(&wvif->link_id_db, 0, sizeof(wvif->link_id_db));
763
764 wvif->wdev->tx_burst_idx = -1;
765 ret = hif_start(wvif, &start);
766 if (!ret)
767 ret = wfx_upload_keys(wvif);
768 if (!ret) {
769 if (wvif_count(wvif->wdev) <= 1)
770 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
771 wvif->state = WFX_STATE_AP;
772 wfx_update_filtering(wvif);
773 }
774 return ret;
775 }
776
777 static int wfx_update_beaconing(struct wfx_vif *wvif)
778 {
779 struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
780
781 if (wvif->vif->type == NL80211_IFTYPE_AP) {
782 /* TODO: check if changed channel, band */
783 if (wvif->state != WFX_STATE_AP ||
784 wvif->beacon_int != conf->beacon_int) {
785 wfx_tx_lock_flush(wvif->wdev);
786 if (wvif->state != WFX_STATE_PASSIVE) {
787 hif_reset(wvif, false);
788 wfx_tx_policy_init(wvif);
789 }
790 wvif->state = WFX_STATE_PASSIVE;
791 wfx_start_ap(wvif);
792 wfx_tx_unlock(wvif->wdev);
793 } else {
794 }
795 }
796 return 0;
797 }
798
799 static int wfx_upload_beacon(struct wfx_vif *wvif)
800 {
801 struct sk_buff *skb;
802 struct ieee80211_mgmt *mgmt;
803
804 if (wvif->vif->type == NL80211_IFTYPE_STATION ||
805 wvif->vif->type == NL80211_IFTYPE_MONITOR ||
806 wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED)
807 return 0;
808
809 skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif);
810 if (!skb)
811 return -ENOMEM;
812 hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN,
813 API_RATE_INDEX_B_1MBPS);
814
815 /* TODO: Distill probe resp; remove TIM and any other beacon-specific
816 * IEs
817 */
818 mgmt = (void *)skb->data;
819 mgmt->frame_control =
820 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
821
822 hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES,
823 API_RATE_INDEX_B_1MBPS);
824 wfx_fwd_probe_req(wvif, false);
825 dev_kfree_skb(skb);
826 return 0;
827 }
828
829 static int wfx_is_ht(const struct wfx_ht_info *ht_info)
830 {
831 return ht_info->channel_type != NL80211_CHAN_NO_HT;
832 }
833
834 static int wfx_ht_greenfield(const struct wfx_ht_info *ht_info)
835 {
836 return wfx_is_ht(ht_info) &&
837 (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
838 !(ht_info->operation_mode &
839 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
840 }
841
842 static int wfx_ht_ampdu_density(const struct wfx_ht_info *ht_info)
843 {
844 if (!wfx_is_ht(ht_info))
845 return 0;
846 return ht_info->ht_cap.ampdu_density;
847 }
848
849 static void wfx_join_finalize(struct wfx_vif *wvif,
850 struct ieee80211_bss_conf *info)
851 {
852 struct ieee80211_sta *sta = NULL;
853 struct hif_mib_set_association_mode association_mode = { };
854
855 if (info->dtim_period)
856 wvif->dtim_period = info->dtim_period;
857 wvif->beacon_int = info->beacon_int;
858
859 rcu_read_lock();
860 if (info->bssid && !info->ibss_joined)
861 sta = ieee80211_find_sta(wvif->vif, info->bssid);
862 if (sta) {
863 wvif->ht_info.ht_cap = sta->ht_cap;
864 wvif->bss_params.operational_rate_set =
865 wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
866 wvif->ht_info.operation_mode = info->ht_operation_mode;
867 } else {
868 memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
869 wvif->bss_params.operational_rate_set = -1;
870 }
871 rcu_read_unlock();
872
873 /* Non Greenfield stations present */
874 if (wvif->ht_info.operation_mode &
875 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
876 hif_dual_cts_protection(wvif, true);
877 else
878 hif_dual_cts_protection(wvif, false);
879
880 association_mode.preambtype_use = 1;
881 association_mode.mode = 1;
882 association_mode.rateset = 1;
883 association_mode.spacing = 1;
884 association_mode.short_preamble = info->use_short_preamble;
885 association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates));
886 association_mode.greenfield = wfx_ht_greenfield(&wvif->ht_info);
887 association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(&wvif->ht_info);
888
889 wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
890 cancel_work_sync(&wvif->unjoin_work);
891
892 wvif->bss_params.beacon_lost_count = 20;
893 wvif->bss_params.aid = info->aid;
894
895 if (wvif->dtim_period < 1)
896 wvif->dtim_period = 1;
897
898 hif_set_association_mode(wvif, &association_mode);
899
900 if (!info->ibss_joined) {
901 hif_keep_alive_period(wvif, 30 /* sec */);
902 hif_set_bss_params(wvif, &wvif->bss_params);
903 wvif->setbssparams_done = true;
904 wfx_set_beacon_wakeup_period_work(&wvif->set_beacon_wakeup_period_work);
905 wfx_update_pm(wvif);
906 }
907 }
908
909 void wfx_bss_info_changed(struct ieee80211_hw *hw,
910 struct ieee80211_vif *vif,
911 struct ieee80211_bss_conf *info,
912 u32 changed)
913 {
914 struct wfx_dev *wdev = hw->priv;
915 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
916 bool do_join = false;
917 int i;
918 int nb_arp_addr;
919
920 mutex_lock(&wdev->conf_mutex);
921
922 /* TODO: BSS_CHANGED_QOS */
923 if (changed & BSS_CHANGED_ARP_FILTER) {
924 struct hif_mib_arp_ip_addr_table filter = { };
925
926 nb_arp_addr = info->arp_addr_cnt;
927 if (nb_arp_addr <= 0 || nb_arp_addr > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
928 nb_arp_addr = 0;
929
930 for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) {
931 filter.condition_idx = i;
932 if (i < nb_arp_addr) {
933 // Caution: type of arp_addr_list[i] is __be32
934 memcpy(filter.ipv4_address,
935 &info->arp_addr_list[i],
936 sizeof(filter.ipv4_address));
937 filter.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
938 } else {
939 filter.arp_enable = HIF_ARP_NS_FILTERING_DISABLE;
940 }
941 hif_set_arp_ipv4_filter(wvif, &filter);
942 }
943 }
944
945 if (changed & BSS_CHANGED_BEACON ||
946 changed & BSS_CHANGED_AP_PROBE_RESP ||
947 changed & BSS_CHANGED_BSSID ||
948 changed & BSS_CHANGED_SSID ||
949 changed & BSS_CHANGED_IBSS) {
950 wvif->beacon_int = info->beacon_int;
951 wfx_update_beaconing(wvif);
952 wfx_upload_beacon(wvif);
953 }
954
955 if (changed & BSS_CHANGED_BEACON_ENABLED &&
956 wvif->state != WFX_STATE_IBSS) {
957 if (wvif->enable_beacon != info->enable_beacon) {
958 hif_beacon_transmit(wvif, info->enable_beacon);
959 wvif->enable_beacon = info->enable_beacon;
960 }
961 }
962
963 /* assoc/disassoc, or maybe AID changed */
964 if (changed & BSS_CHANGED_ASSOC) {
965 wfx_tx_lock_flush(wdev);
966 wvif->wep_default_key_id = -1;
967 wfx_tx_unlock(wdev);
968 }
969
970 if (changed & BSS_CHANGED_ASSOC && !info->assoc &&
971 (wvif->state == WFX_STATE_STA || wvif->state == WFX_STATE_IBSS)) {
972 /* Shedule unjoin work */
973 wfx_tx_lock(wdev);
974 if (!schedule_work(&wvif->unjoin_work))
975 wfx_tx_unlock(wdev);
976 } else {
977 if (changed & BSS_CHANGED_BEACON_INT) {
978 if (info->ibss_joined)
979 do_join = true;
980 else if (wvif->state == WFX_STATE_AP)
981 wfx_update_beaconing(wvif);
982 }
983
984 if (changed & BSS_CHANGED_BSSID)
985 do_join = true;
986
987 if (changed & BSS_CHANGED_ASSOC ||
988 changed & BSS_CHANGED_BSSID ||
989 changed & BSS_CHANGED_IBSS ||
990 changed & BSS_CHANGED_BASIC_RATES ||
991 changed & BSS_CHANGED_HT) {
992 if (info->assoc) {
993 if (wvif->state < WFX_STATE_PRE_STA) {
994 ieee80211_connection_loss(vif);
995 mutex_unlock(&wdev->conf_mutex);
996 return;
997 } else if (wvif->state == WFX_STATE_PRE_STA) {
998 wvif->state = WFX_STATE_STA;
999 }
1000 } else {
1001 do_join = true;
1002 }
1003
1004 if (info->assoc || info->ibss_joined)
1005 wfx_join_finalize(wvif, info);
1006 else
1007 memset(&wvif->bss_params, 0,
1008 sizeof(wvif->bss_params));
1009 }
1010 }
1011
1012 /* ERP Protection */
1013 if (changed & BSS_CHANGED_ASSOC ||
1014 changed & BSS_CHANGED_ERP_CTS_PROT ||
1015 changed & BSS_CHANGED_ERP_PREAMBLE) {
1016 u32 prev_erp_info = wvif->erp_info;
1017
1018 if (info->use_cts_prot)
1019 wvif->erp_info |= WLAN_ERP_USE_PROTECTION;
1020 else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
1021 wvif->erp_info &= ~WLAN_ERP_USE_PROTECTION;
1022
1023 if (info->use_short_preamble)
1024 wvif->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
1025 else
1026 wvif->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
1027
1028 if (prev_erp_info != wvif->erp_info)
1029 schedule_work(&wvif->set_cts_work);
1030 }
1031
1032 if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
1033 hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
1034
1035 if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) {
1036 struct hif_mib_rcpi_rssi_threshold th = {
1037 .rolling_average_count = 8,
1038 .detection = 1,
1039 };
1040
1041 wvif->cqm_rssi_thold = info->cqm_rssi_thold;
1042
1043 if (!info->cqm_rssi_thold && !info->cqm_rssi_hyst) {
1044 th.upperthresh = 1;
1045 th.lowerthresh = 1;
1046 } else {
1047 /* FIXME It's not a correct way of setting threshold.
1048 * Upper and lower must be set equal here and adjusted
1049 * in callback. However current implementation is much
1050 * more reliable and stable.
1051 */
1052 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1053 * RSSI = RCPI / 2 - 110
1054 */
1055 th.upper_threshold = info->cqm_rssi_thold + info->cqm_rssi_hyst;
1056 th.upper_threshold = (th.upper_threshold + 110) * 2;
1057 th.lower_threshold = info->cqm_rssi_thold;
1058 th.lower_threshold = (th.lower_threshold + 110) * 2;
1059 }
1060 hif_set_rcpi_rssi_threshold(wvif, &th);
1061 }
1062
1063 if (changed & BSS_CHANGED_TXPOWER &&
1064 info->txpower != wdev->output_power) {
1065 wdev->output_power = info->txpower;
1066 hif_set_output_power(wvif, wdev->output_power * 10);
1067 }
1068 mutex_unlock(&wdev->conf_mutex);
1069
1070 if (do_join)
1071 wfx_do_join(wvif);
1072 }
1073
1074 static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
1075 int link_id)
1076 {
1077 u32 bit, prev;
1078
1079 spin_lock_bh(&wvif->ps_state_lock);
1080 /* Zero link id means "for all link IDs" */
1081 if (link_id) {
1082 bit = BIT(link_id);
1083 } else if (notify_cmd != STA_NOTIFY_AWAKE) {
1084 dev_warn(wvif->wdev->dev, "unsupported notify command\n");
1085 bit = 0;
1086 } else {
1087 bit = wvif->link_id_map;
1088 }
1089 prev = wvif->sta_asleep_mask & bit;
1090
1091 switch (notify_cmd) {
1092 case STA_NOTIFY_SLEEP:
1093 if (!prev) {
1094 if (wvif->mcast_buffered && !wvif->sta_asleep_mask)
1095 schedule_work(&wvif->mcast_start_work);
1096 wvif->sta_asleep_mask |= bit;
1097 }
1098 break;
1099 case STA_NOTIFY_AWAKE:
1100 if (prev) {
1101 wvif->sta_asleep_mask &= ~bit;
1102 wvif->pspoll_mask &= ~bit;
1103 if (link_id && !wvif->sta_asleep_mask)
1104 schedule_work(&wvif->mcast_stop_work);
1105 wfx_bh_request_tx(wvif->wdev);
1106 }
1107 break;
1108 }
1109 spin_unlock_bh(&wvif->ps_state_lock);
1110 }
1111
1112 void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1113 enum sta_notify_cmd notify_cmd, struct ieee80211_sta *sta)
1114 {
1115 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
1116 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
1117
1118 wfx_ps_notify(wvif, notify_cmd, sta_priv->link_id);
1119 }
1120
1121 static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
1122 {
1123 struct sk_buff *skb;
1124 struct hif_ie_flags target_frame = {
1125 .beacon = 1,
1126 };
1127 u16 tim_offset, tim_length;
1128 u8 *tim_ptr;
1129
1130 skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
1131 &tim_offset, &tim_length);
1132 if (!skb) {
1133 if (!__wfx_flush(wvif->wdev, true))
1134 wfx_tx_unlock(wvif->wdev);
1135 return -ENOENT;
1136 }
1137 tim_ptr = skb->data + tim_offset;
1138
1139 if (tim_offset && tim_length >= 6) {
1140 /* Ignore DTIM count from mac80211:
1141 * firmware handles DTIM internally.
1142 */
1143 tim_ptr[2] = 0;
1144
1145 /* Set/reset aid0 bit */
1146 if (aid0_bit_set)
1147 tim_ptr[4] |= 1;
1148 else
1149 tim_ptr[4] &= ~1;
1150 }
1151
1152 hif_update_ie(wvif, &target_frame, tim_ptr, tim_length);
1153 dev_kfree_skb(skb);
1154
1155 return 0;
1156 }
1157
1158 static void wfx_set_tim_work(struct work_struct *work)
1159 {
1160 struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_tim_work);
1161
1162 wfx_set_tim_impl(wvif, wvif->aid0_bit_set);
1163 }
1164
1165 int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
1166 {
1167 struct wfx_dev *wdev = hw->priv;
1168 struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *) &sta->drv_priv;
1169 struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id);
1170
1171 schedule_work(&wvif->set_tim_work);
1172 return 0;
1173 }
1174
1175 static void wfx_mcast_start_work(struct work_struct *work)
1176 {
1177 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
1178 mcast_start_work);
1179 long tmo = wvif->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20);
1180
1181 cancel_work_sync(&wvif->mcast_stop_work);
1182 if (!wvif->aid0_bit_set) {
1183 wfx_tx_lock_flush(wvif->wdev);
1184 wfx_set_tim_impl(wvif, true);
1185 wvif->aid0_bit_set = true;
1186 mod_timer(&wvif->mcast_timeout, jiffies + tmo);
1187 wfx_tx_unlock(wvif->wdev);
1188 }
1189 }
1190
1191 static void wfx_mcast_stop_work(struct work_struct *work)
1192 {
1193 struct wfx_vif *wvif = container_of(work, struct wfx_vif,
1194 mcast_stop_work);
1195
1196 if (wvif->aid0_bit_set) {
1197 del_timer_sync(&wvif->mcast_timeout);
1198 wfx_tx_lock_flush(wvif->wdev);
1199 wvif->aid0_bit_set = false;
1200 wfx_set_tim_impl(wvif, false);
1201 wfx_tx_unlock(wvif->wdev);
1202 }
1203 }
1204
1205 static void wfx_mcast_timeout(struct timer_list *t)
1206 {
1207 struct wfx_vif *wvif = from_timer(wvif, t, mcast_timeout);
1208
1209 dev_warn(wvif->wdev->dev, "multicast delivery timeout\n");
1210 spin_lock_bh(&wvif->ps_state_lock);
1211 wvif->mcast_tx = wvif->aid0_bit_set && wvif->mcast_buffered;
1212 if (wvif->mcast_tx)
1213 wfx_bh_request_tx(wvif->wdev);
1214 spin_unlock_bh(&wvif->ps_state_lock);
1215 }
1216
1217 int wfx_ampdu_action(struct ieee80211_hw *hw,
1218 struct ieee80211_vif *vif,
1219 struct ieee80211_ampdu_params *params)
1220 {
1221 /* Aggregation is implemented fully in firmware,
1222 * including block ack negotiation. Do not allow
1223 * mac80211 stack to do anything: it interferes with
1224 * the firmware.
1225 */
1226
1227 /* Note that we still need this function stubbed. */
1228
1229 return -ENOTSUPP;
1230 }
1231
1232 void wfx_suspend_resume(struct wfx_vif *wvif,
1233 const struct hif_ind_suspend_resume_tx *arg)
1234 {
1235 if (arg->suspend_resume_flags.bc_mc_only) {
1236 bool cancel_tmo = false;
1237
1238 spin_lock_bh(&wvif->ps_state_lock);
1239 if (!arg->suspend_resume_flags.resume)
1240 wvif->mcast_tx = false;
1241 else
1242 wvif->mcast_tx = wvif->aid0_bit_set &&
1243 wvif->mcast_buffered;
1244 if (wvif->mcast_tx) {
1245 cancel_tmo = true;
1246 wfx_bh_request_tx(wvif->wdev);
1247 }
1248 spin_unlock_bh(&wvif->ps_state_lock);
1249 if (cancel_tmo)
1250 del_timer_sync(&wvif->mcast_timeout);
1251 } else if (arg->suspend_resume_flags.resume) {
1252 // FIXME: should change each station status independently
1253 wfx_ps_notify(wvif, STA_NOTIFY_AWAKE, 0);
1254 wfx_bh_request_tx(wvif->wdev);
1255 } else {
1256 // FIXME: should change each station status independently
1257 wfx_ps_notify(wvif, STA_NOTIFY_SLEEP, 0);
1258 }
1259 }
1260
1261 int wfx_add_chanctx(struct ieee80211_hw *hw,
1262 struct ieee80211_chanctx_conf *conf)
1263 {
1264 return 0;
1265 }
1266
1267 void wfx_remove_chanctx(struct ieee80211_hw *hw,
1268 struct ieee80211_chanctx_conf *conf)
1269 {
1270 }
1271
1272 void wfx_change_chanctx(struct ieee80211_hw *hw,
1273 struct ieee80211_chanctx_conf *conf,
1274 u32 changed)
1275 {
1276 }
1277
1278 int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1279 struct ieee80211_chanctx_conf *conf)
1280 {
1281 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
1282 struct ieee80211_channel *ch = conf->def.chan;
1283
1284 WARN(wvif->channel, "channel overwrite");
1285 wvif->channel = ch;
1286 wvif->ht_info.channel_type = cfg80211_get_chandef_type(&conf->def);
1287
1288 return 0;
1289 }
1290
1291 void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
1292 struct ieee80211_vif *vif,
1293 struct ieee80211_chanctx_conf *conf)
1294 {
1295 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
1296 struct ieee80211_channel *ch = conf->def.chan;
1297
1298 WARN(wvif->channel != ch, "channel mismatch");
1299 wvif->channel = NULL;
1300 }
1301
1302 int wfx_config(struct ieee80211_hw *hw, u32 changed)
1303 {
1304 int ret = 0;
1305 struct wfx_dev *wdev = hw->priv;
1306 struct ieee80211_conf *conf = &hw->conf;
1307 struct wfx_vif *wvif;
1308
1309 // FIXME: Interface id should not been hardcoded
1310 wvif = wdev_to_wvif(wdev, 0);
1311 if (!wvif) {
1312 WARN(1, "interface 0 does not exist anymore");
1313 return 0;
1314 }
1315
1316 mutex_lock(&wvif->scan_lock);
1317 mutex_lock(&wdev->conf_mutex);
1318 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1319 wdev->output_power = conf->power_level;
1320 hif_set_output_power(wvif, wdev->output_power * 10);
1321 }
1322
1323 if (changed & IEEE80211_CONF_CHANGE_PS) {
1324 wvif = NULL;
1325 while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
1326 ret = wfx_update_pm(wvif);
1327 wvif = wdev_to_wvif(wdev, 0);
1328 }
1329
1330 mutex_unlock(&wdev->conf_mutex);
1331 mutex_unlock(&wvif->scan_lock);
1332 return ret;
1333 }
1334
1335 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1336 {
1337 int i, ret = 0;
1338 struct wfx_dev *wdev = hw->priv;
1339 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
1340
1341 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
1342 IEEE80211_VIF_SUPPORTS_UAPSD |
1343 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
1344
1345 mutex_lock(&wdev->conf_mutex);
1346
1347 switch (vif->type) {
1348 case NL80211_IFTYPE_STATION:
1349 case NL80211_IFTYPE_ADHOC:
1350 case NL80211_IFTYPE_AP:
1351 break;
1352 default:
1353 mutex_unlock(&wdev->conf_mutex);
1354 return -EOPNOTSUPP;
1355 }
1356
1357 for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
1358 if (!wdev->vif[i]) {
1359 wdev->vif[i] = vif;
1360 wvif->id = i;
1361 break;
1362 }
1363 }
1364 if (i == ARRAY_SIZE(wdev->vif)) {
1365 mutex_unlock(&wdev->conf_mutex);
1366 return -EOPNOTSUPP;
1367 }
1368 // FIXME: prefer use of container_of() to get vif
1369 wvif->vif = vif;
1370 wvif->wdev = wdev;
1371
1372 INIT_WORK(&wvif->link_id_work, wfx_link_id_work);
1373 INIT_DELAYED_WORK(&wvif->link_id_gc_work, wfx_link_id_gc_work);
1374
1375 spin_lock_init(&wvif->ps_state_lock);
1376 INIT_WORK(&wvif->set_tim_work, wfx_set_tim_work);
1377
1378 INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work);
1379 INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
1380 timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0);
1381
1382 wvif->setbssparams_done = false;
1383 mutex_init(&wvif->bss_loss_lock);
1384 INIT_DELAYED_WORK(&wvif->bss_loss_work, wfx_bss_loss_work);
1385
1386 wvif->wep_default_key_id = -1;
1387 INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work);
1388
1389 spin_lock_init(&wvif->event_queue_lock);
1390 INIT_LIST_HEAD(&wvif->event_queue);
1391 INIT_WORK(&wvif->event_handler_work, wfx_event_handler_work);
1392
1393 init_completion(&wvif->set_pm_mode_complete);
1394 complete(&wvif->set_pm_mode_complete);
1395 INIT_WORK(&wvif->set_beacon_wakeup_period_work,
1396 wfx_set_beacon_wakeup_period_work);
1397 INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work);
1398 INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work);
1399 INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
1400 INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
1401 INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
1402
1403 mutex_init(&wvif->scan_lock);
1404 init_completion(&wvif->scan_complete);
1405 INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
1406
1407 INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
1408 mutex_unlock(&wdev->conf_mutex);
1409
1410 hif_set_macaddr(wvif, vif->addr);
1411
1412 wfx_tx_policy_init(wvif);
1413 wvif = NULL;
1414 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
1415 // Combo mode does not support Block Acks. We can re-enable them
1416 if (wvif_count(wdev) == 1)
1417 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
1418 else
1419 hif_set_block_ack_policy(wvif, 0x00, 0x00);
1420 // Combo force powersave mode. We can re-enable it now
1421 ret = wfx_update_pm(wvif);
1422 }
1423 return ret;
1424 }
1425
1426 void wfx_remove_interface(struct ieee80211_hw *hw,
1427 struct ieee80211_vif *vif)
1428 {
1429 struct wfx_dev *wdev = hw->priv;
1430 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
1431 int i;
1432
1433 wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300));
1434
1435 mutex_lock(&wdev->conf_mutex);
1436 switch (wvif->state) {
1437 case WFX_STATE_PRE_STA:
1438 case WFX_STATE_STA:
1439 case WFX_STATE_IBSS:
1440 wfx_tx_lock_flush(wdev);
1441 if (!schedule_work(&wvif->unjoin_work))
1442 wfx_tx_unlock(wdev);
1443 break;
1444 case WFX_STATE_AP:
1445 for (i = 0; wvif->link_id_map; ++i) {
1446 if (wvif->link_id_map & BIT(i)) {
1447 wfx_unmap_link(wvif, i);
1448 wvif->link_id_map &= ~BIT(i);
1449 }
1450 }
1451 memset(wvif->link_id_db, 0, sizeof(wvif->link_id_db));
1452 wvif->sta_asleep_mask = 0;
1453 wvif->enable_beacon = false;
1454 wvif->mcast_tx = false;
1455 wvif->aid0_bit_set = false;
1456 wvif->mcast_buffered = false;
1457 wvif->pspoll_mask = 0;
1458 /* reset.link_id = 0; */
1459 hif_reset(wvif, false);
1460 break;
1461 default:
1462 break;
1463 }
1464
1465 wvif->state = WFX_STATE_PASSIVE;
1466 wfx_tx_queues_wait_empty_vif(wvif);
1467 wfx_tx_unlock(wdev);
1468
1469 /* FIXME: In add to reset MAC address, try to reset interface */
1470 hif_set_macaddr(wvif, NULL);
1471
1472 wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
1473 cancel_work_sync(&wvif->unjoin_work);
1474 cancel_delayed_work_sync(&wvif->link_id_gc_work);
1475 del_timer_sync(&wvif->mcast_timeout);
1476 wfx_free_event_queue(wvif);
1477
1478 wdev->vif[wvif->id] = NULL;
1479 wvif->vif = NULL;
1480
1481 mutex_unlock(&wdev->conf_mutex);
1482 wvif = NULL;
1483 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
1484 // Combo mode does not support Block Acks. We can re-enable them
1485 if (wvif_count(wdev) == 1)
1486 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
1487 else
1488 hif_set_block_ack_policy(wvif, 0x00, 0x00);
1489 // Combo force powersave mode. We can re-enable it now
1490 wfx_update_pm(wvif);
1491 }
1492 }
1493
1494 int wfx_start(struct ieee80211_hw *hw)
1495 {
1496 return 0;
1497 }
1498
1499 void wfx_stop(struct ieee80211_hw *hw)
1500 {
1501 struct wfx_dev *wdev = hw->priv;
1502
1503 wfx_tx_lock_flush(wdev);
1504 mutex_lock(&wdev->conf_mutex);
1505 wfx_tx_queues_clear(wdev);
1506 mutex_unlock(&wdev->conf_mutex);
1507 wfx_tx_unlock(wdev);
1508 WARN(atomic_read(&wdev->tx_lock), "tx_lock is locked");
1509 }