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