at v5.7 1138 lines 30 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 <net/mac80211.h> 9 10#include "sta.h" 11#include "wfx.h" 12#include "fwio.h" 13#include "bh.h" 14#include "key.h" 15#include "scan.h" 16#include "debug.h" 17#include "hif_tx.h" 18#include "hif_tx_mib.h" 19 20#define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2 21 22u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates) 23{ 24 int i; 25 u32 ret = 0; 26 // WFx only support 2GHz 27 struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; 28 29 for (i = 0; i < sband->n_bitrates; i++) { 30 if (rates & BIT(i)) { 31 if (i >= sband->n_bitrates) 32 dev_warn(wdev->dev, "unsupported basic rate\n"); 33 else 34 ret |= BIT(sband->bitrates[i].hw_value); 35 } 36 } 37 return ret; 38} 39 40static void __wfx_free_event_queue(struct list_head *list) 41{ 42 struct wfx_hif_event *event, *tmp; 43 44 list_for_each_entry_safe(event, tmp, list, link) { 45 list_del(&event->link); 46 kfree(event); 47 } 48} 49 50static void wfx_free_event_queue(struct wfx_vif *wvif) 51{ 52 LIST_HEAD(list); 53 54 spin_lock(&wvif->event_queue_lock); 55 list_splice_init(&wvif->event_queue, &list); 56 spin_unlock(&wvif->event_queue_lock); 57 58 __wfx_free_event_queue(&list); 59} 60 61void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) 62{ 63 int tx = 0; 64 65 mutex_lock(&wvif->bss_loss_lock); 66 cancel_work_sync(&wvif->bss_params_work); 67 68 if (init) { 69 schedule_delayed_work(&wvif->bss_loss_work, HZ); 70 wvif->bss_loss_state = 0; 71 72 if (!atomic_read(&wvif->wdev->tx_lock)) 73 tx = 1; 74 } else if (good) { 75 cancel_delayed_work_sync(&wvif->bss_loss_work); 76 wvif->bss_loss_state = 0; 77 schedule_work(&wvif->bss_params_work); 78 } else if (bad) { 79 /* FIXME Should we just keep going until we time out? */ 80 if (wvif->bss_loss_state < 3) 81 tx = 1; 82 } else { 83 cancel_delayed_work_sync(&wvif->bss_loss_work); 84 wvif->bss_loss_state = 0; 85 } 86 87 /* Spit out a NULL packet to our AP if necessary */ 88 // FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead 89 if (tx) { 90 struct sk_buff *skb; 91 struct ieee80211_hdr *hdr; 92 struct ieee80211_tx_control control = { }; 93 94 wvif->bss_loss_state++; 95 96 skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false); 97 if (!skb) 98 goto end; 99 hdr = (struct ieee80211_hdr *)skb->data; 100 memset(IEEE80211_SKB_CB(skb), 0, 101 sizeof(*IEEE80211_SKB_CB(skb))); 102 IEEE80211_SKB_CB(skb)->control.vif = wvif->vif; 103 IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0; 104 IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1; 105 IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1; 106 rcu_read_lock(); // protect control.sta 107 control.sta = ieee80211_find_sta(wvif->vif, hdr->addr1); 108 wfx_tx(wvif->wdev->hw, &control, skb); 109 rcu_read_unlock(); 110 } 111end: 112 mutex_unlock(&wvif->bss_loss_lock); 113} 114 115int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable) 116{ 117 wvif->fwd_probe_req = enable; 118 return hif_set_rx_filter(wvif, wvif->filter_bssid, 119 wvif->fwd_probe_req); 120} 121 122static int wfx_set_mcast_filter(struct wfx_vif *wvif, 123 struct wfx_grp_addr_table *fp) 124{ 125 int i; 126 127 // Temporary workaround for filters 128 return hif_set_data_filtering(wvif, false, true); 129 130 if (!fp->enable) 131 return hif_set_data_filtering(wvif, false, true); 132 133 for (i = 0; i < fp->num_addresses; i++) 134 hif_set_mac_addr_condition(wvif, i, fp->address_list[i]); 135 hif_set_uc_mc_bc_condition(wvif, 0, 136 HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST); 137 hif_set_config_data_filter(wvif, true, 0, BIT(1), 138 BIT(fp->num_addresses) - 1); 139 hif_set_data_filtering(wvif, true, true); 140 141 return 0; 142} 143 144void wfx_update_filtering(struct wfx_vif *wvif) 145{ 146 int ret; 147 int bf_enable; 148 int bf_count; 149 int n_filter_ies; 150 struct hif_ie_table_entry filter_ies[] = { 151 { 152 .ie_id = WLAN_EID_VENDOR_SPECIFIC, 153 .has_changed = 1, 154 .no_longer = 1, 155 .has_appeared = 1, 156 .oui = { 0x50, 0x6F, 0x9A }, 157 }, { 158 .ie_id = WLAN_EID_HT_OPERATION, 159 .has_changed = 1, 160 .no_longer = 1, 161 .has_appeared = 1, 162 }, { 163 .ie_id = WLAN_EID_ERP_INFO, 164 .has_changed = 1, 165 .no_longer = 1, 166 .has_appeared = 1, 167 } 168 }; 169 170 if (wvif->state == WFX_STATE_PASSIVE) 171 return; 172 173 if (wvif->disable_beacon_filter) { 174 bf_enable = 0; 175 bf_count = 1; 176 n_filter_ies = 0; 177 } else if (wvif->vif->type != NL80211_IFTYPE_STATION) { 178 bf_enable = HIF_BEACON_FILTER_ENABLE | HIF_BEACON_FILTER_AUTO_ERP; 179 bf_count = 0; 180 n_filter_ies = 2; 181 } else { 182 bf_enable = HIF_BEACON_FILTER_ENABLE; 183 bf_count = 0; 184 n_filter_ies = 3; 185 } 186 187 ret = hif_set_rx_filter(wvif, wvif->filter_bssid, wvif->fwd_probe_req); 188 if (!ret) 189 ret = hif_set_beacon_filter_table(wvif, n_filter_ies, filter_ies); 190 if (!ret) 191 ret = hif_beacon_filter_control(wvif, bf_enable, bf_count); 192 if (!ret) 193 ret = wfx_set_mcast_filter(wvif, &wvif->mcast_filter); 194 if (ret) 195 dev_err(wvif->wdev->dev, "update filtering failed: %d\n", ret); 196} 197 198static void wfx_update_filtering_work(struct work_struct *work) 199{ 200 struct wfx_vif *wvif = container_of(work, struct wfx_vif, 201 update_filtering_work); 202 203 wfx_update_filtering(wvif); 204} 205 206u64 wfx_prepare_multicast(struct ieee80211_hw *hw, 207 struct netdev_hw_addr_list *mc_list) 208{ 209 int i; 210 struct netdev_hw_addr *ha; 211 struct wfx_vif *wvif = NULL; 212 struct wfx_dev *wdev = hw->priv; 213 int count = netdev_hw_addr_list_count(mc_list); 214 215 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { 216 memset(&wvif->mcast_filter, 0x00, sizeof(wvif->mcast_filter)); 217 if (!count || 218 count > ARRAY_SIZE(wvif->mcast_filter.address_list)) 219 continue; 220 221 i = 0; 222 netdev_hw_addr_list_for_each(ha, mc_list) { 223 ether_addr_copy(wvif->mcast_filter.address_list[i], 224 ha->addr); 225 i++; 226 } 227 wvif->mcast_filter.enable = true; 228 wvif->mcast_filter.num_addresses = count; 229 } 230 231 return 0; 232} 233 234void wfx_configure_filter(struct ieee80211_hw *hw, 235 unsigned int changed_flags, 236 unsigned int *total_flags, 237 u64 unused) 238{ 239 struct wfx_vif *wvif = NULL; 240 struct wfx_dev *wdev = hw->priv; 241 242 *total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ; 243 244 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { 245 mutex_lock(&wvif->scan_lock); 246 wvif->filter_bssid = (*total_flags & 247 (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 0 : 1; 248 wvif->disable_beacon_filter = !(*total_flags & FIF_PROBE_REQ); 249 wfx_fwd_probe_req(wvif, true); 250 wfx_update_filtering(wvif); 251 mutex_unlock(&wvif->scan_lock); 252 } 253} 254 255static int wfx_update_pm(struct wfx_vif *wvif) 256{ 257 struct ieee80211_conf *conf = &wvif->wdev->hw->conf; 258 bool ps = conf->flags & IEEE80211_CONF_PS; 259 int ps_timeout = conf->dynamic_ps_timeout; 260 struct ieee80211_channel *chan0 = NULL, *chan1 = NULL; 261 262 WARN_ON(conf->dynamic_ps_timeout < 0); 263 if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) 264 return 0; 265 if (!ps) 266 ps_timeout = 0; 267 if (wvif->uapsd_mask) 268 ps_timeout = 0; 269 270 // Kernel disable powersave when an AP is in use. In contrary, it is 271 // absolutely necessary to enable legacy powersave for WF200 if channels 272 // are differents. 273 if (wdev_to_wvif(wvif->wdev, 0)) 274 chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; 275 if (wdev_to_wvif(wvif->wdev, 1)) 276 chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; 277 if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && 278 wvif->vif->type != NL80211_IFTYPE_AP) { 279 ps = true; 280 ps_timeout = 0; 281 } 282 283 if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete, 284 TU_TO_JIFFIES(512))) 285 dev_warn(wvif->wdev->dev, 286 "timeout while waiting of set_pm_mode_complete\n"); 287 return hif_set_pm(wvif, ps, ps_timeout); 288} 289 290int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 291 u16 queue, const struct ieee80211_tx_queue_params *params) 292{ 293 struct wfx_dev *wdev = hw->priv; 294 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 295 int old_uapsd = wvif->uapsd_mask; 296 297 WARN_ON(queue >= hw->queues); 298 299 mutex_lock(&wdev->conf_mutex); 300 assign_bit(queue, &wvif->uapsd_mask, params->uapsd); 301 memcpy(&wvif->edca_params[queue], params, sizeof(*params)); 302 hif_set_edca_queue_params(wvif, queue, params); 303 if (wvif->vif->type == NL80211_IFTYPE_STATION && 304 old_uapsd != wvif->uapsd_mask) { 305 hif_set_uapsd_info(wvif, wvif->uapsd_mask); 306 wfx_update_pm(wvif); 307 } 308 mutex_unlock(&wdev->conf_mutex); 309 return 0; 310} 311 312int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 313{ 314 struct wfx_dev *wdev = hw->priv; 315 struct wfx_vif *wvif = NULL; 316 317 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) 318 hif_rts_threshold(wvif, value); 319 return 0; 320} 321 322static int __wfx_flush(struct wfx_dev *wdev, bool drop) 323{ 324 for (;;) { 325 if (drop) 326 wfx_tx_queues_clear(wdev); 327 if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty, 328 wfx_tx_queues_is_empty(wdev), 329 2 * HZ) <= 0) 330 return -ETIMEDOUT; 331 wfx_tx_flush(wdev); 332 if (wfx_tx_queues_is_empty(wdev)) 333 return 0; 334 dev_warn(wdev->dev, "frames queued while flushing tx queues"); 335 } 336} 337 338void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 339 u32 queues, bool drop) 340{ 341 // FIXME: only flush requested vif and queues 342 __wfx_flush(hw->priv, drop); 343} 344 345/* WSM callbacks */ 346 347static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi) 348{ 349 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1 350 * RSSI = RCPI / 2 - 110 351 */ 352 int rcpi_rssi; 353 int cqm_evt; 354 355 rcpi_rssi = raw_rcpi_rssi / 2 - 110; 356 if (rcpi_rssi <= wvif->vif->bss_conf.cqm_rssi_thold) 357 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; 358 else 359 cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; 360 ieee80211_cqm_rssi_notify(wvif->vif, cqm_evt, rcpi_rssi, GFP_KERNEL); 361} 362 363static void wfx_event_handler_work(struct work_struct *work) 364{ 365 struct wfx_vif *wvif = 366 container_of(work, struct wfx_vif, event_handler_work); 367 struct wfx_hif_event *event; 368 369 LIST_HEAD(list); 370 371 spin_lock(&wvif->event_queue_lock); 372 list_splice_init(&wvif->event_queue, &list); 373 spin_unlock(&wvif->event_queue_lock); 374 375 list_for_each_entry(event, &list, link) { 376 switch (event->evt.event_id) { 377 case HIF_EVENT_IND_BSSLOST: 378 cancel_work_sync(&wvif->unjoin_work); 379 mutex_lock(&wvif->scan_lock); 380 wfx_cqm_bssloss_sm(wvif, 1, 0, 0); 381 mutex_unlock(&wvif->scan_lock); 382 break; 383 case HIF_EVENT_IND_BSSREGAINED: 384 wfx_cqm_bssloss_sm(wvif, 0, 0, 0); 385 cancel_work_sync(&wvif->unjoin_work); 386 break; 387 case HIF_EVENT_IND_RCPI_RSSI: 388 wfx_event_report_rssi(wvif, 389 event->evt.event_data.rcpi_rssi); 390 break; 391 case HIF_EVENT_IND_PS_MODE_ERROR: 392 dev_warn(wvif->wdev->dev, 393 "error while processing power save request\n"); 394 break; 395 default: 396 dev_warn(wvif->wdev->dev, 397 "unhandled event indication: %.2x\n", 398 event->evt.event_id); 399 break; 400 } 401 } 402 __wfx_free_event_queue(&list); 403} 404 405static void wfx_bss_loss_work(struct work_struct *work) 406{ 407 struct wfx_vif *wvif = container_of(work, struct wfx_vif, 408 bss_loss_work.work); 409 410 ieee80211_connection_loss(wvif->vif); 411} 412 413static void wfx_bss_params_work(struct work_struct *work) 414{ 415 struct wfx_vif *wvif = container_of(work, struct wfx_vif, 416 bss_params_work); 417 418 mutex_lock(&wvif->wdev->conf_mutex); 419 wvif->bss_params.bss_flags.lost_count_only = 1; 420 hif_set_bss_params(wvif, &wvif->bss_params); 421 wvif->bss_params.bss_flags.lost_count_only = 0; 422 mutex_unlock(&wvif->wdev->conf_mutex); 423} 424 425static void wfx_do_unjoin(struct wfx_vif *wvif) 426{ 427 mutex_lock(&wvif->wdev->conf_mutex); 428 429 if (!wvif->state) 430 goto done; 431 432 if (wvif->state == WFX_STATE_AP) 433 goto done; 434 435 cancel_work_sync(&wvif->update_filtering_work); 436 wvif->state = WFX_STATE_PASSIVE; 437 438 /* Unjoin is a reset. */ 439 wfx_tx_flush(wvif->wdev); 440 hif_keep_alive_period(wvif, 0); 441 hif_reset(wvif, false); 442 wfx_tx_policy_init(wvif); 443 hif_set_macaddr(wvif, wvif->vif->addr); 444 wfx_free_event_queue(wvif); 445 cancel_work_sync(&wvif->event_handler_work); 446 wfx_cqm_bssloss_sm(wvif, 0, 0, 0); 447 448 /* Disable Block ACKs */ 449 hif_set_block_ack_policy(wvif, 0, 0); 450 451 wvif->disable_beacon_filter = false; 452 wfx_update_filtering(wvif); 453 memset(&wvif->bss_params, 0, sizeof(wvif->bss_params)); 454 455done: 456 mutex_unlock(&wvif->wdev->conf_mutex); 457} 458 459static void wfx_set_mfp(struct wfx_vif *wvif, 460 struct cfg80211_bss *bss) 461{ 462 const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); 463 const int pairwise_cipher_suite_size = 4 / sizeof(u16); 464 const int akm_suite_size = 4 / sizeof(u16); 465 const u16 *ptr = NULL; 466 bool mfpc = false; 467 bool mfpr = false; 468 469 /* 802.11w protected mgmt frames */ 470 471 /* retrieve MFPC and MFPR flags from beacon or PBRSP */ 472 473 rcu_read_lock(); 474 if (bss) 475 ptr = (const u16 *) ieee80211_bss_get_ie(bss, 476 WLAN_EID_RSN); 477 478 if (ptr) { 479 ptr += pairwise_cipher_suite_count_offset; 480 ptr += 1 + pairwise_cipher_suite_size * *ptr; 481 ptr += 1 + akm_suite_size * *ptr; 482 mfpr = *ptr & BIT(6); 483 mfpc = *ptr & BIT(7); 484 } 485 rcu_read_unlock(); 486 487 hif_set_mfp(wvif, mfpc, mfpr); 488} 489 490static void wfx_do_join(struct wfx_vif *wvif) 491{ 492 int ret; 493 struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; 494 struct cfg80211_bss *bss = NULL; 495 u8 ssid[IEEE80211_MAX_SSID_LEN]; 496 const u8 *ssidie = NULL; 497 int ssidlen = 0; 498 499 wfx_tx_lock_flush(wvif->wdev); 500 501 if (wvif->state) 502 wfx_do_unjoin(wvif); 503 504 bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, 505 conf->bssid, NULL, 0, 506 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); 507 if (!bss && !conf->ibss_joined) { 508 wfx_tx_unlock(wvif->wdev); 509 return; 510 } 511 512 mutex_lock(&wvif->wdev->conf_mutex); 513 514 /* Sanity check beacon interval */ 515 if (!wvif->beacon_int) 516 wvif->beacon_int = 1; 517 518 rcu_read_lock(); // protect ssidie 519 if (!conf->ibss_joined) 520 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); 521 if (ssidie) { 522 ssidlen = ssidie[1]; 523 memcpy(ssid, &ssidie[2], ssidie[1]); 524 } 525 rcu_read_unlock(); 526 527 wfx_tx_flush(wvif->wdev); 528 529 if (wvif_count(wvif->wdev) <= 1) 530 hif_set_block_ack_policy(wvif, 0xFF, 0xFF); 531 532 wfx_set_mfp(wvif, bss); 533 534 wvif->wdev->tx_burst_idx = -1; 535 ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); 536 if (ret) { 537 ieee80211_connection_loss(wvif->vif); 538 wvif->join_complete_status = -1; 539 /* Tx lock still held, unjoin will clear it. */ 540 if (!schedule_work(&wvif->unjoin_work)) 541 wfx_tx_unlock(wvif->wdev); 542 } else { 543 wvif->join_complete_status = 0; 544 if (wvif->vif->type == NL80211_IFTYPE_ADHOC) 545 wvif->state = WFX_STATE_IBSS; 546 else 547 wvif->state = WFX_STATE_PRE_STA; 548 wfx_tx_unlock(wvif->wdev); 549 550 /* Upload keys */ 551 wfx_upload_keys(wvif); 552 553 /* Due to beacon filtering it is possible that the 554 * AP's beacon is not known for the mac80211 stack. 555 * Disable filtering temporary to make sure the stack 556 * receives at least one 557 */ 558 wvif->disable_beacon_filter = true; 559 } 560 wfx_update_filtering(wvif); 561 562 mutex_unlock(&wvif->wdev->conf_mutex); 563 if (bss) 564 cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); 565} 566 567static void wfx_unjoin_work(struct work_struct *work) 568{ 569 struct wfx_vif *wvif = container_of(work, struct wfx_vif, unjoin_work); 570 571 wfx_do_unjoin(wvif); 572 wfx_tx_unlock(wvif->wdev); 573} 574 575int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 576 struct ieee80211_sta *sta) 577{ 578 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 579 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv; 580 581 spin_lock_init(&sta_priv->lock); 582 sta_priv->vif_id = wvif->id; 583 584 // FIXME: in station mode, the current API interprets new link-id as a 585 // tdls peer. 586 if (vif->type == NL80211_IFTYPE_STATION) 587 return 0; 588 sta_priv->link_id = ffz(wvif->link_id_map); 589 wvif->link_id_map |= BIT(sta_priv->link_id); 590 WARN_ON(!sta_priv->link_id); 591 WARN_ON(sta_priv->link_id >= WFX_MAX_STA_IN_AP_MODE); 592 hif_map_link(wvif, sta->addr, 0, sta_priv->link_id); 593 594 spin_lock_bh(&wvif->ps_state_lock); 595 if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) == 596 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) 597 wvif->sta_asleep_mask |= BIT(sta_priv->link_id); 598 spin_unlock_bh(&wvif->ps_state_lock); 599 return 0; 600} 601 602int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 603 struct ieee80211_sta *sta) 604{ 605 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 606 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv; 607 int i; 608 609 for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++) 610 if (sta_priv->buffered[i]) 611 dev_warn(wvif->wdev->dev, "release station while %d pending frame on queue %d", 612 sta_priv->buffered[i], i); 613 // FIXME: see note in wfx_sta_add() 614 if (vif->type == NL80211_IFTYPE_STATION) 615 return 0; 616 // FIXME add a mutex? 617 hif_map_link(wvif, sta->addr, 1, sta_priv->link_id); 618 wvif->link_id_map &= ~BIT(sta_priv->link_id); 619 return 0; 620} 621 622static int wfx_start_ap(struct wfx_vif *wvif) 623{ 624 int ret; 625 626 wvif->beacon_int = wvif->vif->bss_conf.beacon_int; 627 wvif->wdev->tx_burst_idx = -1; 628 ret = hif_start(wvif, &wvif->vif->bss_conf, wvif->channel); 629 if (ret) 630 return ret; 631 ret = wfx_upload_keys(wvif); 632 if (ret) 633 return ret; 634 if (wvif_count(wvif->wdev) <= 1) 635 hif_set_block_ack_policy(wvif, 0xFF, 0xFF); 636 wvif->state = WFX_STATE_AP; 637 wfx_update_filtering(wvif); 638 return 0; 639} 640 641static int wfx_update_beaconing(struct wfx_vif *wvif) 642{ 643 if (wvif->vif->type != NL80211_IFTYPE_AP) 644 return 0; 645 if (wvif->state == WFX_STATE_AP && 646 wvif->beacon_int == wvif->vif->bss_conf.beacon_int) 647 return 0; 648 wfx_tx_lock_flush(wvif->wdev); 649 hif_reset(wvif, false); 650 wfx_tx_policy_init(wvif); 651 wvif->state = WFX_STATE_PASSIVE; 652 wfx_start_ap(wvif); 653 wfx_tx_unlock(wvif->wdev); 654 return 0; 655} 656 657static int wfx_upload_ap_templates(struct wfx_vif *wvif) 658{ 659 struct sk_buff *skb; 660 661 if (wvif->vif->type == NL80211_IFTYPE_STATION || 662 wvif->vif->type == NL80211_IFTYPE_MONITOR || 663 wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED) 664 return 0; 665 666 skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); 667 if (!skb) 668 return -ENOMEM; 669 hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, 670 API_RATE_INDEX_B_1MBPS); 671 dev_kfree_skb(skb); 672 673 skb = ieee80211_proberesp_get(wvif->wdev->hw, wvif->vif); 674 if (!skb) 675 return -ENOMEM; 676 hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES, 677 API_RATE_INDEX_B_1MBPS); 678 dev_kfree_skb(skb); 679 return 0; 680} 681 682static void wfx_join_finalize(struct wfx_vif *wvif, 683 struct ieee80211_bss_conf *info) 684{ 685 struct ieee80211_sta *sta = NULL; 686 687 wvif->beacon_int = info->beacon_int; 688 rcu_read_lock(); // protect sta 689 if (info->bssid && !info->ibss_joined) 690 sta = ieee80211_find_sta(wvif->vif, info->bssid); 691 if (sta) 692 wvif->bss_params.operational_rate_set = 693 wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]); 694 else 695 wvif->bss_params.operational_rate_set = -1; 696 rcu_read_unlock(); 697 if (sta && 698 info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) 699 hif_dual_cts_protection(wvif, true); 700 else 701 hif_dual_cts_protection(wvif, false); 702 703 wfx_cqm_bssloss_sm(wvif, 0, 0, 0); 704 cancel_work_sync(&wvif->unjoin_work); 705 706 wvif->bss_params.beacon_lost_count = 20; 707 wvif->bss_params.aid = info->aid; 708 709 hif_set_association_mode(wvif, info); 710 711 if (!info->ibss_joined) { 712 hif_keep_alive_period(wvif, 30 /* sec */); 713 hif_set_bss_params(wvif, &wvif->bss_params); 714 hif_set_beacon_wakeup_period(wvif, info->dtim_period, 715 info->dtim_period); 716 wfx_update_pm(wvif); 717 } 718} 719 720void wfx_bss_info_changed(struct ieee80211_hw *hw, 721 struct ieee80211_vif *vif, 722 struct ieee80211_bss_conf *info, 723 u32 changed) 724{ 725 struct wfx_dev *wdev = hw->priv; 726 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 727 bool do_join = false; 728 int i; 729 730 mutex_lock(&wdev->conf_mutex); 731 732 /* TODO: BSS_CHANGED_QOS */ 733 if (changed & BSS_CHANGED_ARP_FILTER) { 734 for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { 735 __be32 *arp_addr = &info->arp_addr_list[i]; 736 737 if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) 738 arp_addr = NULL; 739 if (i >= info->arp_addr_cnt) 740 arp_addr = NULL; 741 hif_set_arp_ipv4_filter(wvif, i, arp_addr); 742 } 743 } 744 745 if (changed & BSS_CHANGED_BEACON || 746 changed & BSS_CHANGED_AP_PROBE_RESP || 747 changed & BSS_CHANGED_BSSID || 748 changed & BSS_CHANGED_SSID || 749 changed & BSS_CHANGED_IBSS) { 750 wvif->beacon_int = info->beacon_int; 751 wfx_update_beaconing(wvif); 752 wfx_upload_ap_templates(wvif); 753 wfx_fwd_probe_req(wvif, false); 754 } 755 756 if (changed & BSS_CHANGED_BEACON_ENABLED && 757 wvif->state != WFX_STATE_IBSS) 758 hif_beacon_transmit(wvif, info->enable_beacon); 759 760 if (changed & BSS_CHANGED_BEACON_INFO) 761 hif_set_beacon_wakeup_period(wvif, info->dtim_period, 762 info->dtim_period); 763 764 /* assoc/disassoc, or maybe AID changed */ 765 if (changed & BSS_CHANGED_ASSOC) { 766 wfx_tx_lock_flush(wdev); 767 wvif->wep_default_key_id = -1; 768 wfx_tx_unlock(wdev); 769 } 770 771 if (changed & BSS_CHANGED_ASSOC && !info->assoc && 772 (wvif->state == WFX_STATE_STA || wvif->state == WFX_STATE_IBSS)) { 773 /* Shedule unjoin work */ 774 wfx_tx_lock(wdev); 775 if (!schedule_work(&wvif->unjoin_work)) 776 wfx_tx_unlock(wdev); 777 } else { 778 if (changed & BSS_CHANGED_BEACON_INT) { 779 if (info->ibss_joined) 780 do_join = true; 781 else if (wvif->state == WFX_STATE_AP) 782 wfx_update_beaconing(wvif); 783 } 784 785 if (changed & BSS_CHANGED_BSSID) 786 do_join = true; 787 788 if (changed & BSS_CHANGED_ASSOC || 789 changed & BSS_CHANGED_BSSID || 790 changed & BSS_CHANGED_IBSS || 791 changed & BSS_CHANGED_BASIC_RATES || 792 changed & BSS_CHANGED_HT) { 793 if (info->assoc) { 794 if (wvif->state < WFX_STATE_PRE_STA) { 795 ieee80211_connection_loss(vif); 796 mutex_unlock(&wdev->conf_mutex); 797 return; 798 } else if (wvif->state == WFX_STATE_PRE_STA) { 799 wvif->state = WFX_STATE_STA; 800 } 801 } else { 802 do_join = true; 803 } 804 805 if (info->assoc || info->ibss_joined) 806 wfx_join_finalize(wvif, info); 807 else 808 memset(&wvif->bss_params, 0, 809 sizeof(wvif->bss_params)); 810 } 811 } 812 813 if (changed & BSS_CHANGED_ASSOC || 814 changed & BSS_CHANGED_ERP_CTS_PROT || 815 changed & BSS_CHANGED_ERP_PREAMBLE) { 816 u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 }; 817 818 hif_erp_use_protection(wvif, info->use_cts_prot); 819 if (info->use_cts_prot) 820 erp_ie[2] |= WLAN_ERP_USE_PROTECTION; 821 if (info->use_short_preamble) 822 erp_ie[2] |= WLAN_ERP_BARKER_PREAMBLE; 823 if (wvif->vif->type != NL80211_IFTYPE_STATION) 824 hif_update_ie_beacon(wvif, erp_ie, sizeof(erp_ie)); 825 } 826 827 if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT) 828 hif_slot_time(wvif, info->use_short_slot ? 9 : 20); 829 830 if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) 831 hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold, 832 info->cqm_rssi_hyst); 833 834 if (changed & BSS_CHANGED_TXPOWER) 835 hif_set_output_power(wvif, info->txpower); 836 837 if (changed & BSS_CHANGED_PS) 838 wfx_update_pm(wvif); 839 840 mutex_unlock(&wdev->conf_mutex); 841 842 if (do_join) 843 wfx_do_join(wvif); 844} 845 846static void wfx_ps_notify_sta(struct wfx_vif *wvif, 847 enum sta_notify_cmd notify_cmd, int link_id) 848{ 849 spin_lock_bh(&wvif->ps_state_lock); 850 if (notify_cmd == STA_NOTIFY_SLEEP) 851 wvif->sta_asleep_mask |= BIT(link_id); 852 else // notify_cmd == STA_NOTIFY_AWAKE 853 wvif->sta_asleep_mask &= ~BIT(link_id); 854 spin_unlock_bh(&wvif->ps_state_lock); 855 if (notify_cmd == STA_NOTIFY_AWAKE) 856 wfx_bh_request_tx(wvif->wdev); 857} 858 859void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 860 enum sta_notify_cmd notify_cmd, struct ieee80211_sta *sta) 861{ 862 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 863 struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv; 864 865 wfx_ps_notify_sta(wvif, notify_cmd, sta_priv->link_id); 866} 867 868static int wfx_update_tim(struct wfx_vif *wvif) 869{ 870 struct sk_buff *skb; 871 u16 tim_offset, tim_length; 872 u8 *tim_ptr; 873 874 skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif, 875 &tim_offset, &tim_length); 876 if (!skb) { 877 __wfx_flush(wvif->wdev, true); 878 return -ENOENT; 879 } 880 tim_ptr = skb->data + tim_offset; 881 882 if (tim_offset && tim_length >= 6) { 883 /* Ignore DTIM count from mac80211: 884 * firmware handles DTIM internally. 885 */ 886 tim_ptr[2] = 0; 887 888 /* Set/reset aid0 bit */ 889 if (wfx_tx_queues_get_after_dtim(wvif)) 890 tim_ptr[4] |= 1; 891 else 892 tim_ptr[4] &= ~1; 893 } 894 895 hif_update_ie_beacon(wvif, tim_ptr, tim_length); 896 dev_kfree_skb(skb); 897 898 return 0; 899} 900 901static void wfx_update_tim_work(struct work_struct *work) 902{ 903 struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work); 904 905 wfx_update_tim(wvif); 906} 907 908int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) 909{ 910 struct wfx_dev *wdev = hw->priv; 911 struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *)&sta->drv_priv; 912 struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id); 913 914 schedule_work(&wvif->update_tim_work); 915 return 0; 916} 917 918void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) 919{ 920 WARN(!wfx_tx_queues_get_after_dtim(wvif), "incorrect sequence"); 921 WARN(wvif->after_dtim_tx_allowed, "incorrect sequence"); 922 wvif->after_dtim_tx_allowed = true; 923 wfx_bh_request_tx(wvif->wdev); 924} 925 926int wfx_ampdu_action(struct ieee80211_hw *hw, 927 struct ieee80211_vif *vif, 928 struct ieee80211_ampdu_params *params) 929{ 930 /* Aggregation is implemented fully in firmware, 931 * including block ack negotiation. Do not allow 932 * mac80211 stack to do anything: it interferes with 933 * the firmware. 934 */ 935 936 /* Note that we still need this function stubbed. */ 937 938 return -ENOTSUPP; 939} 940 941int wfx_add_chanctx(struct ieee80211_hw *hw, 942 struct ieee80211_chanctx_conf *conf) 943{ 944 return 0; 945} 946 947void wfx_remove_chanctx(struct ieee80211_hw *hw, 948 struct ieee80211_chanctx_conf *conf) 949{ 950} 951 952void wfx_change_chanctx(struct ieee80211_hw *hw, 953 struct ieee80211_chanctx_conf *conf, 954 u32 changed) 955{ 956} 957 958int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 959 struct ieee80211_chanctx_conf *conf) 960{ 961 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 962 struct ieee80211_channel *ch = conf->def.chan; 963 964 WARN(wvif->channel, "channel overwrite"); 965 wvif->channel = ch; 966 967 return 0; 968} 969 970void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, 971 struct ieee80211_vif *vif, 972 struct ieee80211_chanctx_conf *conf) 973{ 974 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 975 struct ieee80211_channel *ch = conf->def.chan; 976 977 WARN(wvif->channel != ch, "channel mismatch"); 978 wvif->channel = NULL; 979} 980 981int wfx_config(struct ieee80211_hw *hw, u32 changed) 982{ 983 return 0; 984} 985 986int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 987{ 988 int i, ret = 0; 989 struct wfx_dev *wdev = hw->priv; 990 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 991 992 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 993 IEEE80211_VIF_SUPPORTS_UAPSD | 994 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 995 996 mutex_lock(&wdev->conf_mutex); 997 998 switch (vif->type) { 999 case NL80211_IFTYPE_STATION: 1000 case NL80211_IFTYPE_ADHOC: 1001 case NL80211_IFTYPE_AP: 1002 break; 1003 default: 1004 mutex_unlock(&wdev->conf_mutex); 1005 return -EOPNOTSUPP; 1006 } 1007 1008 for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { 1009 if (!wdev->vif[i]) { 1010 wdev->vif[i] = vif; 1011 wvif->id = i; 1012 break; 1013 } 1014 } 1015 if (i == ARRAY_SIZE(wdev->vif)) { 1016 mutex_unlock(&wdev->conf_mutex); 1017 return -EOPNOTSUPP; 1018 } 1019 // FIXME: prefer use of container_of() to get vif 1020 wvif->vif = vif; 1021 wvif->wdev = wdev; 1022 1023 wvif->link_id_map = 1; // link-id 0 is reserved for multicast 1024 spin_lock_init(&wvif->ps_state_lock); 1025 INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work); 1026 1027 memset(&wvif->bss_params, 0, sizeof(wvif->bss_params)); 1028 1029 mutex_init(&wvif->bss_loss_lock); 1030 INIT_DELAYED_WORK(&wvif->bss_loss_work, wfx_bss_loss_work); 1031 1032 wvif->wep_default_key_id = -1; 1033 INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work); 1034 1035 spin_lock_init(&wvif->event_queue_lock); 1036 INIT_LIST_HEAD(&wvif->event_queue); 1037 INIT_WORK(&wvif->event_handler_work, wfx_event_handler_work); 1038 1039 init_completion(&wvif->set_pm_mode_complete); 1040 complete(&wvif->set_pm_mode_complete); 1041 INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work); 1042 INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work); 1043 INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work); 1044 INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); 1045 1046 mutex_init(&wvif->scan_lock); 1047 init_completion(&wvif->scan_complete); 1048 INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); 1049 1050 INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); 1051 mutex_unlock(&wdev->conf_mutex); 1052 1053 hif_set_macaddr(wvif, vif->addr); 1054 1055 wfx_tx_policy_init(wvif); 1056 wvif = NULL; 1057 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { 1058 // Combo mode does not support Block Acks. We can re-enable them 1059 if (wvif_count(wdev) == 1) 1060 hif_set_block_ack_policy(wvif, 0xFF, 0xFF); 1061 else 1062 hif_set_block_ack_policy(wvif, 0x00, 0x00); 1063 // Combo force powersave mode. We can re-enable it now 1064 ret = wfx_update_pm(wvif); 1065 } 1066 return ret; 1067} 1068 1069void wfx_remove_interface(struct ieee80211_hw *hw, 1070 struct ieee80211_vif *vif) 1071{ 1072 struct wfx_dev *wdev = hw->priv; 1073 struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; 1074 1075 wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300)); 1076 1077 mutex_lock(&wdev->conf_mutex); 1078 WARN(wvif->link_id_map != 1, "corrupted state"); 1079 switch (wvif->state) { 1080 case WFX_STATE_PRE_STA: 1081 case WFX_STATE_STA: 1082 case WFX_STATE_IBSS: 1083 wfx_tx_lock_flush(wdev); 1084 if (!schedule_work(&wvif->unjoin_work)) 1085 wfx_tx_unlock(wdev); 1086 break; 1087 case WFX_STATE_AP: 1088 wvif->sta_asleep_mask = 0; 1089 /* reset.link_id = 0; */ 1090 hif_reset(wvif, false); 1091 break; 1092 default: 1093 break; 1094 } 1095 1096 wvif->state = WFX_STATE_PASSIVE; 1097 wfx_tx_queues_wait_empty_vif(wvif); 1098 wfx_tx_unlock(wdev); 1099 1100 /* FIXME: In add to reset MAC address, try to reset interface */ 1101 hif_set_macaddr(wvif, NULL); 1102 1103 wfx_cqm_bssloss_sm(wvif, 0, 0, 0); 1104 cancel_work_sync(&wvif->unjoin_work); 1105 wfx_free_event_queue(wvif); 1106 1107 wdev->vif[wvif->id] = NULL; 1108 wvif->vif = NULL; 1109 1110 mutex_unlock(&wdev->conf_mutex); 1111 wvif = NULL; 1112 while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { 1113 // Combo mode does not support Block Acks. We can re-enable them 1114 if (wvif_count(wdev) == 1) 1115 hif_set_block_ack_policy(wvif, 0xFF, 0xFF); 1116 else 1117 hif_set_block_ack_policy(wvif, 0x00, 0x00); 1118 // Combo force powersave mode. We can re-enable it now 1119 wfx_update_pm(wvif); 1120 } 1121} 1122 1123int wfx_start(struct ieee80211_hw *hw) 1124{ 1125 return 0; 1126} 1127 1128void wfx_stop(struct ieee80211_hw *hw) 1129{ 1130 struct wfx_dev *wdev = hw->priv; 1131 1132 wfx_tx_lock_flush(wdev); 1133 mutex_lock(&wdev->conf_mutex); 1134 wfx_tx_queues_clear(wdev); 1135 mutex_unlock(&wdev->conf_mutex); 1136 wfx_tx_unlock(wdev); 1137 WARN(atomic_read(&wdev->tx_lock), "tx_lock is locked"); 1138}