Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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