staging: wfx: fix support for AP that do not support PS-Poll
[linux-2.6-microblaze.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 <linux/etherdevice.h>
9 #include <net/mac80211.h>
10
11 #include "sta.h"
12 #include "wfx.h"
13 #include "fwio.h"
14 #include "bh.h"
15 #include "key.h"
16 #include "scan.h"
17 #include "debug.h"
18 #include "hif_tx.h"
19 #include "hif_tx_mib.h"
20
21 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
22
23 u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
24 {
25         int i;
26         u32 ret = 0;
27         // WFx only support 2GHz
28         struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
29
30         for (i = 0; i < sband->n_bitrates; i++) {
31                 if (rates & BIT(i)) {
32                         if (i >= sband->n_bitrates)
33                                 dev_warn(wdev->dev, "unsupported basic rate\n");
34                         else
35                                 ret |= BIT(sband->bitrates[i].hw_value);
36                 }
37         }
38         return ret;
39 }
40
41 static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon)
42 {
43         const struct hif_ie_table_entry filter_ies[] = {
44                 {
45                         .ie_id        = WLAN_EID_VENDOR_SPECIFIC,
46                         .has_changed  = 1,
47                         .no_longer    = 1,
48                         .has_appeared = 1,
49                         .oui          = { 0x50, 0x6F, 0x9A },
50                 }, {
51                         .ie_id        = WLAN_EID_HT_OPERATION,
52                         .has_changed  = 1,
53                         .no_longer    = 1,
54                         .has_appeared = 1,
55                 }, {
56                         .ie_id        = WLAN_EID_ERP_INFO,
57                         .has_changed  = 1,
58                         .no_longer    = 1,
59                         .has_appeared = 1,
60                 }
61         };
62
63         if (!filter_beacon) {
64                 hif_set_beacon_filter_table(wvif, 0, NULL);
65                 hif_beacon_filter_control(wvif, 0, 1);
66         } else {
67                 hif_set_beacon_filter_table(wvif, 3, filter_ies);
68                 hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0);
69         }
70 }
71
72 static void wfx_filter_mcast(struct wfx_vif *wvif, bool filter_mcast)
73 {
74         int i;
75
76         // Temporary workaround for filters
77         hif_set_data_filtering(wvif, false, true);
78         return;
79
80         if (!filter_mcast) {
81                 hif_set_data_filtering(wvif, false, true);
82                 return;
83         }
84         for (i = 0; i < wvif->filter_mcast_count; i++)
85                 hif_set_mac_addr_condition(wvif, i, wvif->filter_mcast_addr[i]);
86         hif_set_uc_mc_bc_condition(wvif, 0,
87                                    HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST);
88         hif_set_config_data_filter(wvif, true, 0, BIT(1),
89                                    BIT(wvif->filter_mcast_count) - 1);
90         hif_set_data_filtering(wvif, true, true);
91 }
92
93 u64 wfx_prepare_multicast(struct ieee80211_hw *hw,
94                           struct netdev_hw_addr_list *mc_list)
95 {
96         int i;
97         struct netdev_hw_addr *ha;
98         struct wfx_vif *wvif = NULL;
99         struct wfx_dev *wdev = hw->priv;
100         int count = netdev_hw_addr_list_count(mc_list);
101
102         while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
103                 if (count > ARRAY_SIZE(wvif->filter_mcast_addr)) {
104                         wvif->filter_mcast_count = 0;
105                         continue;
106                 }
107                 wvif->filter_mcast_count = count;
108
109                 i = 0;
110                 netdev_hw_addr_list_for_each(ha, mc_list) {
111                         ether_addr_copy(wvif->filter_mcast_addr[i], ha->addr);
112                         i++;
113                 }
114         }
115
116         return 0;
117 }
118
119 void wfx_configure_filter(struct ieee80211_hw *hw,
120                              unsigned int changed_flags,
121                              unsigned int *total_flags,
122                              u64 unused)
123 {
124         struct wfx_vif *wvif = NULL;
125         struct wfx_dev *wdev = hw->priv;
126         bool filter_bssid, filter_prbreq, filter_beacon, filter_mcast;
127
128         // Notes:
129         //   - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered
130         //   - PS-Poll (FIF_PSPOLL) are never filtered
131         //   - RTS, CTS and Ack (FIF_CONTROL) are always filtered
132         //   - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered
133         //   - Firmware does (yet) allow to forward unicast traffic sent to
134         //     other stations (aka. promiscuous mode)
135         *total_flags &= FIF_BCN_PRBRESP_PROMISC | FIF_ALLMULTI | FIF_OTHER_BSS |
136                         FIF_PROBE_REQ | FIF_PSPOLL;
137
138         mutex_lock(&wdev->conf_mutex);
139         while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
140                 mutex_lock(&wvif->scan_lock);
141
142                 // Note: FIF_BCN_PRBRESP_PROMISC covers probe response and
143                 // beacons from other BSS
144                 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
145                         filter_beacon = false;
146                 else
147                         filter_beacon = true;
148                 wfx_filter_beacon(wvif, filter_beacon);
149
150                 if (*total_flags & FIF_ALLMULTI) {
151                         filter_mcast = false;
152                 } else if (!wvif->filter_mcast_count) {
153                         dev_dbg(wdev->dev, "disabling unconfigured multicast filter");
154                         filter_mcast = false;
155                 } else {
156                         filter_mcast = true;
157                 }
158                 wfx_filter_mcast(wvif, filter_mcast);
159
160                 if (*total_flags & FIF_OTHER_BSS)
161                         filter_bssid = false;
162                 else
163                         filter_bssid = true;
164
165                 // In AP mode, chip can reply to probe request itself
166                 if (*total_flags & FIF_PROBE_REQ &&
167                     wvif->vif->type == NL80211_IFTYPE_AP) {
168                         dev_dbg(wdev->dev, "do not forward probe request in AP mode\n");
169                         *total_flags &= ~FIF_PROBE_REQ;
170                 }
171
172                 if (*total_flags & FIF_PROBE_REQ)
173                         filter_prbreq = false;
174                 else
175                         filter_prbreq = true;
176                 hif_set_rx_filter(wvif, filter_bssid, filter_prbreq);
177
178                 mutex_unlock(&wvif->scan_lock);
179         }
180         mutex_unlock(&wdev->conf_mutex);
181 }
182
183 static int wfx_update_pm(struct wfx_vif *wvif)
184 {
185         struct ieee80211_conf *conf = &wvif->wdev->hw->conf;
186         bool ps = conf->flags & IEEE80211_CONF_PS;
187         int ps_timeout = conf->dynamic_ps_timeout;
188         struct ieee80211_channel *chan0 = NULL, *chan1 = NULL;
189
190         WARN_ON(conf->dynamic_ps_timeout < 0);
191         if (!wvif->vif->bss_conf.assoc)
192                 return 0;
193         if (!ps)
194                 ps_timeout = 0;
195         if (wvif->uapsd_mask)
196                 ps_timeout = 0;
197
198         // Kernel disable powersave when an AP is in use. In contrary, it is
199         // absolutely necessary to enable legacy powersave for WF200 if channels
200         // are differents.
201         if (wdev_to_wvif(wvif->wdev, 0))
202                 chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan;
203         if (wdev_to_wvif(wvif->wdev, 1))
204                 chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan;
205         if (chan0 && chan1 && chan0->hw_value != chan1->hw_value &&
206             wvif->vif->type != NL80211_IFTYPE_AP) {
207                 ps = true;
208                 if (wvif->bss_not_support_ps_poll)
209                         ps_timeout = 30;
210                 else
211                         ps_timeout = 0;
212         }
213
214         if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete,
215                                          TU_TO_JIFFIES(512)))
216                 dev_warn(wvif->wdev->dev,
217                          "timeout while waiting of set_pm_mode_complete\n");
218         return hif_set_pm(wvif, ps, ps_timeout);
219 }
220
221 static void wfx_update_pm_work(struct work_struct *work)
222 {
223         struct wfx_vif *wvif = container_of(work, struct wfx_vif,
224                                             update_pm_work);
225
226         wfx_update_pm(wvif);
227 }
228
229 int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
230                    u16 queue, const struct ieee80211_tx_queue_params *params)
231 {
232         struct wfx_dev *wdev = hw->priv;
233         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
234         int old_uapsd = wvif->uapsd_mask;
235
236         WARN_ON(queue >= hw->queues);
237
238         mutex_lock(&wdev->conf_mutex);
239         assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
240         hif_set_edca_queue_params(wvif, queue, params);
241         if (wvif->vif->type == NL80211_IFTYPE_STATION &&
242             old_uapsd != wvif->uapsd_mask) {
243                 hif_set_uapsd_info(wvif, wvif->uapsd_mask);
244                 wfx_update_pm(wvif);
245         }
246         mutex_unlock(&wdev->conf_mutex);
247         return 0;
248 }
249
250 int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
251 {
252         struct wfx_dev *wdev = hw->priv;
253         struct wfx_vif *wvif = NULL;
254
255         while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
256                 hif_rts_threshold(wvif, value);
257         return 0;
258 }
259
260 /* WSM callbacks */
261
262 void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
263 {
264         /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
265          * RSSI = RCPI / 2 - 110
266          */
267         int rcpi_rssi;
268         int cqm_evt;
269
270         rcpi_rssi = raw_rcpi_rssi / 2 - 110;
271         if (rcpi_rssi <= wvif->vif->bss_conf.cqm_rssi_thold)
272                 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
273         else
274                 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
275         ieee80211_cqm_rssi_notify(wvif->vif, cqm_evt, rcpi_rssi, GFP_KERNEL);
276 }
277
278 static void wfx_beacon_loss_work(struct work_struct *work)
279 {
280         struct wfx_vif *wvif = container_of(to_delayed_work(work),
281                                             struct wfx_vif, beacon_loss_work);
282         struct ieee80211_bss_conf *bss_conf = &wvif->vif->bss_conf;
283
284         ieee80211_beacon_loss(wvif->vif);
285         schedule_delayed_work(to_delayed_work(work),
286                               msecs_to_jiffies(bss_conf->beacon_int));
287 }
288
289 void wfx_set_default_unicast_key(struct ieee80211_hw *hw,
290                                  struct ieee80211_vif *vif, int idx)
291 {
292         struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
293
294         hif_wep_default_key_id(wvif, idx);
295 }
296
297 // Call it with wdev->conf_mutex locked
298 static void wfx_do_unjoin(struct wfx_vif *wvif)
299 {
300         /* Unjoin is a reset. */
301         wfx_tx_lock_flush(wvif->wdev);
302         hif_reset(wvif, false);
303         wfx_tx_policy_init(wvif);
304         if (wvif_count(wvif->wdev) <= 1)
305                 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
306         wfx_tx_unlock(wvif->wdev);
307         wvif->bss_not_support_ps_poll = false;
308         cancel_delayed_work_sync(&wvif->beacon_loss_work);
309 }
310
311 static void wfx_set_mfp(struct wfx_vif *wvif,
312                         struct cfg80211_bss *bss)
313 {
314         const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
315         const int pairwise_cipher_suite_size = 4 / sizeof(u16);
316         const int akm_suite_size = 4 / sizeof(u16);
317         const u16 *ptr = NULL;
318         bool mfpc = false;
319         bool mfpr = false;
320
321         /* 802.11w protected mgmt frames */
322
323         /* retrieve MFPC and MFPR flags from beacon or PBRSP */
324
325         rcu_read_lock();
326         if (bss)
327                 ptr = (const u16 *) ieee80211_bss_get_ie(bss,
328                                                               WLAN_EID_RSN);
329
330         if (ptr) {
331                 ptr += pairwise_cipher_suite_count_offset;
332                 ptr += 1 + pairwise_cipher_suite_size * *ptr;
333                 ptr += 1 + akm_suite_size * *ptr;
334                 mfpr = *ptr & BIT(6);
335                 mfpc = *ptr & BIT(7);
336         }
337         rcu_read_unlock();
338
339         hif_set_mfp(wvif, mfpc, mfpr);
340 }
341
342 static void wfx_do_join(struct wfx_vif *wvif)
343 {
344         int ret;
345         struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
346         struct cfg80211_bss *bss = NULL;
347         u8 ssid[IEEE80211_MAX_SSID_LEN];
348         const u8 *ssidie = NULL;
349         int ssidlen = 0;
350
351         wfx_tx_lock_flush(wvif->wdev);
352
353         bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel,
354                                conf->bssid, NULL, 0,
355                                IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
356         if (!bss && !conf->ibss_joined) {
357                 wfx_tx_unlock(wvif->wdev);
358                 return;
359         }
360
361         rcu_read_lock(); // protect ssidie
362         if (bss)
363                 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
364         if (ssidie) {
365                 ssidlen = ssidie[1];
366                 if (ssidlen > IEEE80211_MAX_SSID_LEN)
367                         ssidlen = IEEE80211_MAX_SSID_LEN;
368                 memcpy(ssid, &ssidie[2], ssidlen);
369         }
370         rcu_read_unlock();
371
372         wfx_set_mfp(wvif, bss);
373         cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
374
375         ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen);
376         if (ret) {
377                 ieee80211_connection_loss(wvif->vif);
378                 wfx_do_unjoin(wvif);
379         } else {
380                 /* Due to beacon filtering it is possible that the
381                  * AP's beacon is not known for the mac80211 stack.
382                  * Disable filtering temporary to make sure the stack
383                  * receives at least one
384                  */
385                 wfx_filter_beacon(wvif, false);
386         }
387         wfx_tx_unlock(wvif->wdev);
388 }
389
390 int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
391                 struct ieee80211_sta *sta)
392 {
393         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
394         struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
395
396         spin_lock_init(&sta_priv->lock);
397         sta_priv->vif_id = wvif->id;
398
399         // In station mode, the firmware interprets new link-id as a TDLS peer.
400         if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
401                 return 0;
402         sta_priv->link_id = ffz(wvif->link_id_map);
403         wvif->link_id_map |= BIT(sta_priv->link_id);
404         WARN_ON(!sta_priv->link_id);
405         WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX);
406         hif_map_link(wvif, sta->addr, 0, sta_priv->link_id);
407
408         return 0;
409 }
410
411 int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
412                    struct ieee80211_sta *sta)
413 {
414         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
415         struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
416         int i;
417
418         for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++)
419                 if (sta_priv->buffered[i])
420                         dev_warn(wvif->wdev->dev, "release station while %d pending frame on queue %d",
421                                  sta_priv->buffered[i], i);
422         // See note in wfx_sta_add()
423         if (!sta_priv->link_id)
424                 return 0;
425         // FIXME add a mutex?
426         hif_map_link(wvif, sta->addr, 1, sta_priv->link_id);
427         wvif->link_id_map &= ~BIT(sta_priv->link_id);
428         return 0;
429 }
430
431 static int wfx_upload_ap_templates(struct wfx_vif *wvif)
432 {
433         struct sk_buff *skb;
434
435         skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif);
436         if (!skb)
437                 return -ENOMEM;
438         hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN,
439                                API_RATE_INDEX_B_1MBPS);
440         dev_kfree_skb(skb);
441
442         skb = ieee80211_proberesp_get(wvif->wdev->hw, wvif->vif);
443         if (!skb)
444                 return -ENOMEM;
445         hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES,
446                                API_RATE_INDEX_B_1MBPS);
447         dev_kfree_skb(skb);
448         return 0;
449 }
450
451 int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
452 {
453         struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
454
455         wfx_upload_ap_templates(wvif);
456         hif_start(wvif, &vif->bss_conf, wvif->channel);
457         return 0;
458 }
459
460 void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
461 {
462         struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
463
464         hif_reset(wvif, false);
465         wfx_tx_policy_init(wvif);
466         if (wvif_count(wvif->wdev) <= 1)
467                 hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
468         wvif->bss_not_support_ps_poll = false;
469 }
470
471 static void wfx_join_finalize(struct wfx_vif *wvif,
472                               struct ieee80211_bss_conf *info)
473 {
474         hif_set_association_mode(wvif, info);
475         hif_keep_alive_period(wvif, 0);
476         // beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use
477         // the same value.
478         hif_set_bss_params(wvif, info->aid, 7);
479         hif_set_beacon_wakeup_period(wvif, 1, 1);
480         wfx_update_pm(wvif);
481 }
482
483 int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
484 {
485         struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
486
487         wfx_upload_ap_templates(wvif);
488         wfx_do_join(wvif);
489         return 0;
490 }
491
492 void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
493 {
494         struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
495
496         wfx_do_unjoin(wvif);
497 }
498
499 void wfx_enable_beacon(struct wfx_vif *wvif, bool enable)
500 {
501         // Driver has Content After DTIM Beacon in queue. Driver is waiting for
502         // a signal from the firmware. Since we are going to stop to send
503         // beacons, this signal will never happens. See also
504         // wfx_suspend_resume_mc()
505         if (!enable && wfx_tx_queues_has_cab(wvif)) {
506                 wvif->after_dtim_tx_allowed = true;
507                 wfx_bh_request_tx(wvif->wdev);
508         }
509         hif_beacon_transmit(wvif, enable);
510 }
511
512 void wfx_bss_info_changed(struct ieee80211_hw *hw,
513                              struct ieee80211_vif *vif,
514                              struct ieee80211_bss_conf *info,
515                              u32 changed)
516 {
517         struct wfx_dev *wdev = hw->priv;
518         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
519         int i;
520
521         mutex_lock(&wdev->conf_mutex);
522
523         /* TODO: BSS_CHANGED_QOS */
524         if (changed & BSS_CHANGED_ARP_FILTER) {
525                 for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) {
526                         __be32 *arp_addr = &info->arp_addr_list[i];
527
528                         if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
529                                 arp_addr = NULL;
530                         if (i >= info->arp_addr_cnt)
531                                 arp_addr = NULL;
532                         hif_set_arp_ipv4_filter(wvif, i, arp_addr);
533                 }
534         }
535
536         if (changed & BSS_CHANGED_BASIC_RATES ||
537             changed & BSS_CHANGED_BEACON_INT ||
538             changed & BSS_CHANGED_BSSID) {
539                 if (vif->type == NL80211_IFTYPE_STATION)
540                         wfx_do_join(wvif);
541         }
542
543         if (changed & BSS_CHANGED_AP_PROBE_RESP ||
544             changed & BSS_CHANGED_BEACON)
545                 wfx_upload_ap_templates(wvif);
546
547         if (changed & BSS_CHANGED_BEACON_ENABLED)
548                 wfx_enable_beacon(wvif, info->enable_beacon);
549
550         if (changed & BSS_CHANGED_BEACON_INFO) {
551                 if (vif->type != NL80211_IFTYPE_STATION)
552                         dev_warn(wdev->dev, "%s: misunderstood change: BEACON_INFO\n",
553                                  __func__);
554                 hif_set_beacon_wakeup_period(wvif, info->dtim_period,
555                                              info->dtim_period);
556                 // We temporary forwarded beacon for join process. It is now no
557                 // more necessary.
558                 wfx_filter_beacon(wvif, true);
559         }
560
561         if (changed & BSS_CHANGED_ASSOC) {
562                 if (info->assoc || info->ibss_joined)
563                         wfx_join_finalize(wvif, info);
564                 else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION)
565                         wfx_do_unjoin(wvif);
566                 else
567                         dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n",
568                                  __func__);
569         }
570
571         if (changed & BSS_CHANGED_KEEP_ALIVE)
572                 hif_keep_alive_period(wvif, info->max_idle_period *
573                                             USEC_PER_TU / USEC_PER_MSEC);
574
575         if (changed & BSS_CHANGED_ERP_CTS_PROT)
576                 hif_erp_use_protection(wvif, info->use_cts_prot);
577
578         if (changed & BSS_CHANGED_ERP_SLOT)
579                 hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
580
581         if (changed & BSS_CHANGED_CQM)
582                 hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold,
583                                             info->cqm_rssi_hyst);
584
585         if (changed & BSS_CHANGED_TXPOWER)
586                 hif_set_output_power(wvif, info->txpower);
587
588         if (changed & BSS_CHANGED_PS)
589                 wfx_update_pm(wvif);
590
591         mutex_unlock(&wdev->conf_mutex);
592 }
593
594 static int wfx_update_tim(struct wfx_vif *wvif)
595 {
596         struct sk_buff *skb;
597         u16 tim_offset, tim_length;
598         u8 *tim_ptr;
599
600         skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
601                                        &tim_offset, &tim_length);
602         if (!skb)
603                 return -ENOENT;
604         tim_ptr = skb->data + tim_offset;
605
606         if (tim_offset && tim_length >= 6) {
607                 /* Ignore DTIM count from mac80211:
608                  * firmware handles DTIM internally.
609                  */
610                 tim_ptr[2] = 0;
611
612                 /* Set/reset aid0 bit */
613                 if (wfx_tx_queues_has_cab(wvif))
614                         tim_ptr[4] |= 1;
615                 else
616                         tim_ptr[4] &= ~1;
617         }
618
619         hif_update_ie_beacon(wvif, tim_ptr, tim_length);
620         dev_kfree_skb(skb);
621
622         return 0;
623 }
624
625 static void wfx_update_tim_work(struct work_struct *work)
626 {
627         struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work);
628
629         wfx_update_tim(wvif);
630 }
631
632 int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
633 {
634         struct wfx_dev *wdev = hw->priv;
635         struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *)&sta->drv_priv;
636         struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id);
637
638         schedule_work(&wvif->update_tim_work);
639         return 0;
640 }
641
642 void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
643 {
644         WARN(!wfx_tx_queues_has_cab(wvif), "incorrect sequence");
645         WARN(wvif->after_dtim_tx_allowed, "incorrect sequence");
646         wvif->after_dtim_tx_allowed = true;
647         wfx_bh_request_tx(wvif->wdev);
648 }
649
650 int wfx_ampdu_action(struct ieee80211_hw *hw,
651                      struct ieee80211_vif *vif,
652                      struct ieee80211_ampdu_params *params)
653 {
654         /* Aggregation is implemented fully in firmware,
655          * including block ack negotiation. Do not allow
656          * mac80211 stack to do anything: it interferes with
657          * the firmware.
658          */
659
660         /* Note that we still need this function stubbed. */
661
662         return -ENOTSUPP;
663 }
664
665 int wfx_add_chanctx(struct ieee80211_hw *hw,
666                     struct ieee80211_chanctx_conf *conf)
667 {
668         return 0;
669 }
670
671 void wfx_remove_chanctx(struct ieee80211_hw *hw,
672                         struct ieee80211_chanctx_conf *conf)
673 {
674 }
675
676 void wfx_change_chanctx(struct ieee80211_hw *hw,
677                         struct ieee80211_chanctx_conf *conf,
678                         u32 changed)
679 {
680 }
681
682 int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
683                            struct ieee80211_chanctx_conf *conf)
684 {
685         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
686         struct ieee80211_channel *ch = conf->def.chan;
687
688         WARN(wvif->channel, "channel overwrite");
689         wvif->channel = ch;
690
691         return 0;
692 }
693
694 void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
695                               struct ieee80211_vif *vif,
696                               struct ieee80211_chanctx_conf *conf)
697 {
698         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
699         struct ieee80211_channel *ch = conf->def.chan;
700
701         WARN(wvif->channel != ch, "channel mismatch");
702         wvif->channel = NULL;
703 }
704
705 int wfx_config(struct ieee80211_hw *hw, u32 changed)
706 {
707         return 0;
708 }
709
710 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
711 {
712         int i, ret = 0;
713         struct wfx_dev *wdev = hw->priv;
714         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
715
716         vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
717                              IEEE80211_VIF_SUPPORTS_UAPSD |
718                              IEEE80211_VIF_SUPPORTS_CQM_RSSI;
719
720         mutex_lock(&wdev->conf_mutex);
721
722         switch (vif->type) {
723         case NL80211_IFTYPE_STATION:
724         case NL80211_IFTYPE_ADHOC:
725         case NL80211_IFTYPE_AP:
726                 break;
727         default:
728                 mutex_unlock(&wdev->conf_mutex);
729                 return -EOPNOTSUPP;
730         }
731
732         for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
733                 if (!wdev->vif[i]) {
734                         wdev->vif[i] = vif;
735                         wvif->id = i;
736                         break;
737                 }
738         }
739         if (i == ARRAY_SIZE(wdev->vif)) {
740                 mutex_unlock(&wdev->conf_mutex);
741                 return -EOPNOTSUPP;
742         }
743         // FIXME: prefer use of container_of() to get vif
744         wvif->vif = vif;
745         wvif->wdev = wdev;
746
747         wvif->link_id_map = 1; // link-id 0 is reserved for multicast
748         INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
749         INIT_DELAYED_WORK(&wvif->beacon_loss_work, wfx_beacon_loss_work);
750
751         init_completion(&wvif->set_pm_mode_complete);
752         complete(&wvif->set_pm_mode_complete);
753         INIT_WORK(&wvif->update_pm_work, wfx_update_pm_work);
754         INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
755
756         mutex_init(&wvif->scan_lock);
757         init_completion(&wvif->scan_complete);
758         INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
759
760         INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
761         mutex_unlock(&wdev->conf_mutex);
762
763         hif_set_macaddr(wvif, vif->addr);
764
765         wfx_tx_policy_init(wvif);
766         wvif = NULL;
767         while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
768                 // Combo mode does not support Block Acks. We can re-enable them
769                 if (wvif_count(wdev) == 1)
770                         hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
771                 else
772                         hif_set_block_ack_policy(wvif, 0x00, 0x00);
773                 // Combo force powersave mode. We can re-enable it now
774                 ret = wfx_update_pm(wvif);
775         }
776         return ret;
777 }
778
779 void wfx_remove_interface(struct ieee80211_hw *hw,
780                           struct ieee80211_vif *vif)
781 {
782         struct wfx_dev *wdev = hw->priv;
783         struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
784
785         wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300));
786
787         mutex_lock(&wdev->conf_mutex);
788         WARN(wvif->link_id_map != 1, "corrupted state");
789
790         hif_reset(wvif, false);
791         hif_set_macaddr(wvif, NULL);
792         wfx_tx_policy_init(wvif);
793
794         cancel_delayed_work_sync(&wvif->beacon_loss_work);
795         wdev->vif[wvif->id] = NULL;
796         wvif->vif = NULL;
797
798         mutex_unlock(&wdev->conf_mutex);
799         wvif = NULL;
800         while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
801                 // Combo mode does not support Block Acks. We can re-enable them
802                 if (wvif_count(wdev) == 1)
803                         hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
804                 else
805                         hif_set_block_ack_policy(wvif, 0x00, 0x00);
806                 // Combo force powersave mode. We can re-enable it now
807                 wfx_update_pm(wvif);
808         }
809 }
810
811 int wfx_start(struct ieee80211_hw *hw)
812 {
813         return 0;
814 }
815
816 void wfx_stop(struct ieee80211_hw *hw)
817 {
818         struct wfx_dev *wdev = hw->priv;
819
820         wfx_tx_queues_check_empty(wdev);
821 }