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