1 /* 2 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/moduleparam.h> 18 #include <linux/if_arp.h> 19 #include <linux/etherdevice.h> 20 21 #include "wil6210.h" 22 #include "txrx.h" 23 #include "wmi.h" 24 25 #define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000 26 #define WAIT_FOR_DISCONNECT_INTERVAL_MS 10 27 28 bool no_fw_recovery; 29 module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); 30 MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); 31 32 static bool no_fw_load = true; 33 module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); 34 MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash."); 35 36 static unsigned int itr_trsh = WIL6210_ITR_TRSH_DEFAULT; 37 38 module_param(itr_trsh, uint, S_IRUGO); 39 MODULE_PARM_DESC(itr_trsh, " Interrupt moderation threshold, usecs."); 40 41 #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ 42 #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ 43 44 /* 45 * Due to a hardware issue, 46 * one has to read/write to/from NIC in 32-bit chunks; 47 * regular memcpy_fromio and siblings will 48 * not work on 64-bit platform - it uses 64-bit transactions 49 * 50 * Force 32-bit transactions to enable NIC on 64-bit platforms 51 * 52 * To avoid byte swap on big endian host, __raw_{read|write}l 53 * should be used - {read|write}l would swap bytes to provide 54 * little endian on PCI value in host endianness. 55 */ 56 void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, 57 size_t count) 58 { 59 u32 *d = dst; 60 const volatile u32 __iomem *s = src; 61 62 /* size_t is unsigned, if (count%4 != 0) it will wrap */ 63 for (count += 4; count > 4; count -= 4) 64 *d++ = __raw_readl(s++); 65 } 66 67 void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 68 size_t count) 69 { 70 volatile u32 __iomem *d = dst; 71 const u32 *s = src; 72 73 for (count += 4; count > 4; count -= 4) 74 __raw_writel(*s++, d++); 75 } 76 77 static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) 78 { 79 uint i; 80 struct net_device *ndev = wil_to_ndev(wil); 81 struct wireless_dev *wdev = wil->wdev; 82 struct wil_sta_info *sta = &wil->sta[cid]; 83 84 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, 85 sta->status); 86 87 sta->data_port_open = false; 88 if (sta->status != wil_sta_unused) { 89 wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING); 90 switch (wdev->iftype) { 91 case NL80211_IFTYPE_AP: 92 case NL80211_IFTYPE_P2P_GO: 93 /* AP-like interface */ 94 cfg80211_del_sta(ndev, sta->addr, GFP_KERNEL); 95 break; 96 default: 97 break; 98 } 99 sta->status = wil_sta_unused; 100 } 101 102 for (i = 0; i < WIL_STA_TID_NUM; i++) { 103 struct wil_tid_ampdu_rx *r; 104 unsigned long flags; 105 106 spin_lock_irqsave(&sta->tid_rx_lock, flags); 107 108 r = sta->tid_rx[i]; 109 sta->tid_rx[i] = NULL; 110 wil_tid_ampdu_rx_free(wil, r); 111 112 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 113 } 114 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 115 if (wil->vring2cid_tid[i][0] == cid) 116 wil_vring_fini_tx(wil, i); 117 } 118 memset(&sta->stats, 0, sizeof(sta->stats)); 119 } 120 121 static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) 122 { 123 int cid = -ENOENT; 124 struct net_device *ndev = wil_to_ndev(wil); 125 struct wireless_dev *wdev = wil->wdev; 126 127 might_sleep(); 128 if (bssid) { 129 cid = wil_find_cid(wil, bssid); 130 wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); 131 } else { 132 wil_dbg_misc(wil, "%s(all)\n", __func__); 133 } 134 135 if (cid >= 0) /* disconnect 1 peer */ 136 wil_disconnect_cid(wil, cid); 137 else /* disconnect all */ 138 for (cid = 0; cid < WIL6210_MAX_CID; cid++) 139 wil_disconnect_cid(wil, cid); 140 141 /* link state */ 142 switch (wdev->iftype) { 143 case NL80211_IFTYPE_STATION: 144 case NL80211_IFTYPE_P2P_CLIENT: 145 wil_link_off(wil); 146 if (test_bit(wil_status_fwconnected, &wil->status)) { 147 clear_bit(wil_status_fwconnected, &wil->status); 148 cfg80211_disconnected(ndev, 149 WLAN_STATUS_UNSPECIFIED_FAILURE, 150 NULL, 0, GFP_KERNEL); 151 } else if (test_bit(wil_status_fwconnecting, &wil->status)) { 152 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 153 WLAN_STATUS_UNSPECIFIED_FAILURE, 154 GFP_KERNEL); 155 } 156 clear_bit(wil_status_fwconnecting, &wil->status); 157 break; 158 default: 159 break; 160 } 161 } 162 163 static void wil_disconnect_worker(struct work_struct *work) 164 { 165 struct wil6210_priv *wil = container_of(work, 166 struct wil6210_priv, disconnect_worker); 167 168 mutex_lock(&wil->mutex); 169 _wil6210_disconnect(wil, NULL); 170 mutex_unlock(&wil->mutex); 171 } 172 173 static void wil_connect_timer_fn(ulong x) 174 { 175 struct wil6210_priv *wil = (void *)x; 176 177 wil_dbg_misc(wil, "Connect timeout\n"); 178 179 /* reschedule to thread context - disconnect won't 180 * run from atomic context 181 */ 182 schedule_work(&wil->disconnect_worker); 183 } 184 185 static void wil_scan_timer_fn(ulong x) 186 { 187 struct wil6210_priv *wil = (void *)x; 188 189 clear_bit(wil_status_fwready, &wil->status); 190 wil_err(wil, "Scan timeout detected, start fw error recovery\n"); 191 schedule_work(&wil->fw_error_worker); 192 } 193 194 static int wil_wait_for_recovery(struct wil6210_priv *wil) 195 { 196 if (wait_event_interruptible(wil->wq, wil->recovery_state != 197 fw_recovery_pending)) { 198 wil_err(wil, "Interrupt, canceling recovery\n"); 199 return -ERESTARTSYS; 200 } 201 if (wil->recovery_state != fw_recovery_running) { 202 wil_info(wil, "Recovery cancelled\n"); 203 return -EINTR; 204 } 205 wil_info(wil, "Proceed with recovery\n"); 206 return 0; 207 } 208 209 void wil_set_recovery_state(struct wil6210_priv *wil, int state) 210 { 211 wil_dbg_misc(wil, "%s(%d -> %d)\n", __func__, 212 wil->recovery_state, state); 213 214 wil->recovery_state = state; 215 wake_up_interruptible(&wil->wq); 216 } 217 218 static void wil_fw_error_worker(struct work_struct *work) 219 { 220 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 221 fw_error_worker); 222 struct wireless_dev *wdev = wil->wdev; 223 224 wil_dbg_misc(wil, "fw error worker\n"); 225 226 /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO 227 * passed since last recovery attempt 228 */ 229 if (time_is_after_jiffies(wil->last_fw_recovery + 230 WIL6210_FW_RECOVERY_TO)) 231 wil->recovery_count++; 232 else 233 wil->recovery_count = 1; /* fw was alive for a long time */ 234 235 if (wil->recovery_count > WIL6210_FW_RECOVERY_RETRIES) { 236 wil_err(wil, "too many recovery attempts (%d), giving up\n", 237 wil->recovery_count); 238 return; 239 } 240 241 wil->last_fw_recovery = jiffies; 242 243 mutex_lock(&wil->mutex); 244 switch (wdev->iftype) { 245 case NL80211_IFTYPE_STATION: 246 case NL80211_IFTYPE_P2P_CLIENT: 247 case NL80211_IFTYPE_MONITOR: 248 wil_info(wil, "fw error recovery requested (try %d)...\n", 249 wil->recovery_count); 250 if (!no_fw_recovery) 251 wil->recovery_state = fw_recovery_running; 252 if (0 != wil_wait_for_recovery(wil)) 253 break; 254 255 __wil_down(wil); 256 __wil_up(wil); 257 break; 258 case NL80211_IFTYPE_AP: 259 case NL80211_IFTYPE_P2P_GO: 260 /* recovery in these modes is done by upper layers */ 261 break; 262 default: 263 break; 264 } 265 mutex_unlock(&wil->mutex); 266 } 267 268 static int wil_find_free_vring(struct wil6210_priv *wil) 269 { 270 int i; 271 272 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 273 if (!wil->vring_tx[i].va) 274 return i; 275 } 276 return -EINVAL; 277 } 278 279 static void wil_connect_worker(struct work_struct *work) 280 { 281 int rc; 282 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 283 connect_worker); 284 int cid = wil->pending_connect_cid; 285 int ringid = wil_find_free_vring(wil); 286 287 if (cid < 0) { 288 wil_err(wil, "No connection pending\n"); 289 return; 290 } 291 292 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid); 293 294 rc = wil_vring_init_tx(wil, ringid, WIL6210_TX_RING_SIZE, cid, 0); 295 wil->pending_connect_cid = -1; 296 if (rc == 0) { 297 wil->sta[cid].status = wil_sta_connected; 298 wil_link_on(wil); 299 } else { 300 wil->sta[cid].status = wil_sta_unused; 301 } 302 } 303 304 int wil_priv_init(struct wil6210_priv *wil) 305 { 306 uint i; 307 308 wil_dbg_misc(wil, "%s()\n", __func__); 309 310 memset(wil->sta, 0, sizeof(wil->sta)); 311 for (i = 0; i < WIL6210_MAX_CID; i++) 312 spin_lock_init(&wil->sta[i].tid_rx_lock); 313 314 mutex_init(&wil->mutex); 315 mutex_init(&wil->wmi_mutex); 316 317 init_completion(&wil->wmi_ready); 318 init_completion(&wil->wmi_call); 319 320 wil->pending_connect_cid = -1; 321 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 322 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil); 323 324 INIT_WORK(&wil->connect_worker, wil_connect_worker); 325 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 326 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 327 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 328 329 INIT_LIST_HEAD(&wil->pending_wmi_ev); 330 spin_lock_init(&wil->wmi_ev_lock); 331 init_waitqueue_head(&wil->wq); 332 333 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); 334 if (!wil->wmi_wq) 335 return -EAGAIN; 336 337 wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); 338 if (!wil->wmi_wq_conn) { 339 destroy_workqueue(wil->wmi_wq); 340 return -EAGAIN; 341 } 342 343 wil->last_fw_recovery = jiffies; 344 wil->itr_trsh = itr_trsh; 345 346 return 0; 347 } 348 349 void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) 350 { 351 wil_dbg_misc(wil, "%s()\n", __func__); 352 353 del_timer_sync(&wil->connect_timer); 354 _wil6210_disconnect(wil, bssid); 355 } 356 357 void wil_priv_deinit(struct wil6210_priv *wil) 358 { 359 wil_dbg_misc(wil, "%s()\n", __func__); 360 361 wil_set_recovery_state(wil, fw_recovery_idle); 362 del_timer_sync(&wil->scan_timer); 363 cancel_work_sync(&wil->disconnect_worker); 364 cancel_work_sync(&wil->fw_error_worker); 365 mutex_lock(&wil->mutex); 366 wil6210_disconnect(wil, NULL); 367 mutex_unlock(&wil->mutex); 368 wmi_event_flush(wil); 369 destroy_workqueue(wil->wmi_wq_conn); 370 destroy_workqueue(wil->wmi_wq); 371 } 372 373 /* target operations */ 374 /* register read */ 375 #define R(a) ioread32(wil->csr + HOSTADDR(a)) 376 /* register write. wmb() to make sure it is completed */ 377 #define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) 378 /* register set = read, OR, write */ 379 #define S(a, v) W(a, R(a) | v) 380 /* register clear = read, AND with inverted, write */ 381 #define C(a, v) W(a, R(a) & ~v) 382 383 static inline void wil_halt_cpu(struct wil6210_priv *wil) 384 { 385 W(RGF_USER_USER_CPU_0, BIT_USER_USER_CPU_MAN_RST); 386 W(RGF_USER_MAC_CPU_0, BIT_USER_MAC_CPU_MAN_RST); 387 } 388 389 static inline void wil_release_cpu(struct wil6210_priv *wil) 390 { 391 /* Start CPU */ 392 W(RGF_USER_USER_CPU_0, 1); 393 } 394 395 static int wil_target_reset(struct wil6210_priv *wil) 396 { 397 int delay = 0; 398 u32 hw_state; 399 u32 rev_id; 400 bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW); 401 402 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name); 403 404 wil->hw_version = R(RGF_USER_FW_REV_ID); 405 rev_id = wil->hw_version & 0xff; 406 407 /* Clear MAC link up */ 408 S(RGF_HP_CTRL, BIT(15)); 409 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_HPAL_PERST_FROM_PAD); 410 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_CAR_PERST_RST); 411 412 wil_halt_cpu(wil); 413 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); /* 40 MHz */ 414 415 if (is_sparrow) { 416 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); 417 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf); 418 } 419 420 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 421 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 422 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000f0 : 0x00000170); 423 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); 424 425 if (is_sparrow) { 426 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 427 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0); 428 } 429 430 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 431 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 432 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 433 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 434 435 if (is_sparrow) { 436 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 437 /* reset A2 PCIE AHB */ 438 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 439 } else { 440 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 441 if (rev_id == 1) { 442 /* reset A1 BOTH PCIE AHB & PCIE RGF */ 443 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 444 } else { 445 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8)); 446 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 447 } 448 } 449 450 /* TODO: check order here!!! Erez code is different */ 451 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 452 453 /* wait until device ready. typical time is 200..250 msec */ 454 do { 455 msleep(RST_DELAY); 456 hw_state = R(RGF_USER_HW_MACHINE_STATE); 457 if (delay++ > RST_COUNT) { 458 wil_err(wil, "Reset not completed, hw_state 0x%08x\n", 459 hw_state); 460 return -ETIME; 461 } 462 } while (hw_state != HW_MACHINE_BOOT_DONE); 463 464 /* TODO: Erez check rev_id != 1 */ 465 if (!is_sparrow && (rev_id != 1)) 466 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 467 468 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 469 470 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); 471 return 0; 472 } 473 474 /** 475 * wil_set_itr_trsh: - apply interrupt coalescing params 476 */ 477 void wil_set_itr_trsh(struct wil6210_priv *wil) 478 { 479 /* disable, use usec resolution */ 480 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EXT_TICK); 481 482 /* disable interrupt moderation for monitor 483 * to get better timestamp precision 484 */ 485 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) 486 return; 487 488 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->itr_trsh); 489 W(RGF_DMA_ITR_CNT_TRSH, wil->itr_trsh); 490 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EN | 491 BIT_DMA_ITR_CNT_CRL_EXT_TICK); /* start it */ 492 } 493 494 #undef R 495 #undef W 496 #undef S 497 #undef C 498 499 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 500 { 501 le32_to_cpus(&r->base); 502 le16_to_cpus(&r->entry_size); 503 le16_to_cpus(&r->size); 504 le32_to_cpus(&r->tail); 505 le32_to_cpus(&r->head); 506 } 507 508 static int wil_wait_for_fw_ready(struct wil6210_priv *wil) 509 { 510 ulong to = msecs_to_jiffies(1000); 511 ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); 512 513 if (0 == left) { 514 wil_err(wil, "Firmware not ready\n"); 515 return -ETIME; 516 } else { 517 wil_info(wil, "FW ready after %d ms. HW version 0x%08x\n", 518 jiffies_to_msecs(to-left), wil->hw_version); 519 } 520 return 0; 521 } 522 523 /* 524 * We reset all the structures, and we reset the UMAC. 525 * After calling this routine, you're expected to reload 526 * the firmware. 527 */ 528 int wil_reset(struct wil6210_priv *wil) 529 { 530 int rc; 531 532 wil_dbg_misc(wil, "%s()\n", __func__); 533 534 WARN_ON(!mutex_is_locked(&wil->mutex)); 535 WARN_ON(test_bit(wil_status_napi_en, &wil->status)); 536 537 cancel_work_sync(&wil->disconnect_worker); 538 wil6210_disconnect(wil, NULL); 539 540 wil->status = 0; /* prevent NAPI from being scheduled */ 541 542 if (wil->scan_request) { 543 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 544 wil->scan_request); 545 del_timer_sync(&wil->scan_timer); 546 cfg80211_scan_done(wil->scan_request, true); 547 wil->scan_request = NULL; 548 } 549 550 wil_mask_irq(wil); 551 552 wmi_event_flush(wil); 553 554 flush_workqueue(wil->wmi_wq_conn); 555 flush_workqueue(wil->wmi_wq); 556 557 rc = wil_target_reset(wil); 558 wil_rx_fini(wil); 559 if (rc) 560 return rc; 561 562 if (!no_fw_load) { 563 wil_info(wil, "Use firmware <%s>\n", WIL_FW_NAME); 564 wil_halt_cpu(wil); 565 /* Loading f/w from the file */ 566 rc = wil_request_firmware(wil, WIL_FW_NAME); 567 if (rc) 568 return rc; 569 570 /* clear any interrupts which on-card-firmware may have set */ 571 wil6210_clear_irq(wil); 572 { /* CAF_ICR - clear and mask */ 573 u32 a = HOSTADDR(RGF_CAF_ICR) + 574 offsetof(struct RGF_ICR, ICR); 575 u32 m = HOSTADDR(RGF_CAF_ICR) + 576 offsetof(struct RGF_ICR, IMV); 577 u32 icr = ioread32(wil->csr + a); 578 579 iowrite32(icr, wil->csr + a); /* W1C */ 580 iowrite32(~0, wil->csr + m); 581 wmb(); /* wait for completion */ 582 } 583 wil_release_cpu(wil); 584 } else { 585 wil_info(wil, "Use firmware from on-card flash\n"); 586 } 587 588 /* init after reset */ 589 wil->pending_connect_cid = -1; 590 reinit_completion(&wil->wmi_ready); 591 reinit_completion(&wil->wmi_call); 592 593 wil_unmask_irq(wil); 594 595 /* we just started MAC, wait for FW ready */ 596 rc = wil_wait_for_fw_ready(wil); 597 598 return rc; 599 } 600 601 void wil_fw_error_recovery(struct wil6210_priv *wil) 602 { 603 wil_dbg_misc(wil, "starting fw error recovery\n"); 604 wil->recovery_state = fw_recovery_pending; 605 schedule_work(&wil->fw_error_worker); 606 } 607 608 void wil_link_on(struct wil6210_priv *wil) 609 { 610 struct net_device *ndev = wil_to_ndev(wil); 611 612 wil_dbg_misc(wil, "%s()\n", __func__); 613 614 netif_carrier_on(ndev); 615 wil_dbg_misc(wil, "netif_tx_wake : link on\n"); 616 netif_tx_wake_all_queues(ndev); 617 } 618 619 void wil_link_off(struct wil6210_priv *wil) 620 { 621 struct net_device *ndev = wil_to_ndev(wil); 622 623 wil_dbg_misc(wil, "%s()\n", __func__); 624 625 netif_tx_stop_all_queues(ndev); 626 wil_dbg_misc(wil, "netif_tx_stop : link off\n"); 627 netif_carrier_off(ndev); 628 } 629 630 int __wil_up(struct wil6210_priv *wil) 631 { 632 struct net_device *ndev = wil_to_ndev(wil); 633 struct wireless_dev *wdev = wil->wdev; 634 int rc; 635 636 WARN_ON(!mutex_is_locked(&wil->mutex)); 637 638 rc = wil_reset(wil); 639 if (rc) 640 return rc; 641 642 /* Rx VRING. After MAC and beacon */ 643 rc = wil_rx_init(wil); 644 if (rc) 645 return rc; 646 647 switch (wdev->iftype) { 648 case NL80211_IFTYPE_STATION: 649 wil_dbg_misc(wil, "type: STATION\n"); 650 ndev->type = ARPHRD_ETHER; 651 break; 652 case NL80211_IFTYPE_AP: 653 wil_dbg_misc(wil, "type: AP\n"); 654 ndev->type = ARPHRD_ETHER; 655 break; 656 case NL80211_IFTYPE_P2P_CLIENT: 657 wil_dbg_misc(wil, "type: P2P_CLIENT\n"); 658 ndev->type = ARPHRD_ETHER; 659 break; 660 case NL80211_IFTYPE_P2P_GO: 661 wil_dbg_misc(wil, "type: P2P_GO\n"); 662 ndev->type = ARPHRD_ETHER; 663 break; 664 case NL80211_IFTYPE_MONITOR: 665 wil_dbg_misc(wil, "type: Monitor\n"); 666 ndev->type = ARPHRD_IEEE80211_RADIOTAP; 667 /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */ 668 break; 669 default: 670 return -EOPNOTSUPP; 671 } 672 673 /* MAC address - pre-requisite for other commands */ 674 wmi_set_mac_address(wil, ndev->dev_addr); 675 676 wil_dbg_misc(wil, "NAPI enable\n"); 677 napi_enable(&wil->napi_rx); 678 napi_enable(&wil->napi_tx); 679 set_bit(wil_status_napi_en, &wil->status); 680 681 if (wil->platform_ops.bus_request) 682 wil->platform_ops.bus_request(wil->platform_handle, 683 WIL_MAX_BUS_REQUEST_KBPS); 684 685 return 0; 686 } 687 688 int wil_up(struct wil6210_priv *wil) 689 { 690 int rc; 691 692 wil_dbg_misc(wil, "%s()\n", __func__); 693 694 mutex_lock(&wil->mutex); 695 rc = __wil_up(wil); 696 mutex_unlock(&wil->mutex); 697 698 return rc; 699 } 700 701 int __wil_down(struct wil6210_priv *wil) 702 { 703 int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS / 704 WAIT_FOR_DISCONNECT_INTERVAL_MS; 705 706 WARN_ON(!mutex_is_locked(&wil->mutex)); 707 708 if (wil->platform_ops.bus_request) 709 wil->platform_ops.bus_request(wil->platform_handle, 0); 710 711 wil_disable_irq(wil); 712 if (test_and_clear_bit(wil_status_napi_en, &wil->status)) { 713 napi_disable(&wil->napi_rx); 714 napi_disable(&wil->napi_tx); 715 wil_dbg_misc(wil, "NAPI disable\n"); 716 } 717 wil_enable_irq(wil); 718 719 if (wil->scan_request) { 720 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 721 wil->scan_request); 722 del_timer_sync(&wil->scan_timer); 723 cfg80211_scan_done(wil->scan_request, true); 724 wil->scan_request = NULL; 725 } 726 727 if (test_bit(wil_status_fwconnected, &wil->status) || 728 test_bit(wil_status_fwconnecting, &wil->status)) 729 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); 730 731 /* make sure wil is idle (not connected) */ 732 mutex_unlock(&wil->mutex); 733 while (iter--) { 734 int idle = !test_bit(wil_status_fwconnected, &wil->status) && 735 !test_bit(wil_status_fwconnecting, &wil->status); 736 if (idle) 737 break; 738 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS); 739 } 740 mutex_lock(&wil->mutex); 741 742 if (!iter) 743 wil_err(wil, "timeout waiting for idle FW/HW\n"); 744 745 wil_rx_fini(wil); 746 747 return 0; 748 } 749 750 int wil_down(struct wil6210_priv *wil) 751 { 752 int rc; 753 754 wil_dbg_misc(wil, "%s()\n", __func__); 755 756 wil_set_recovery_state(wil, fw_recovery_idle); 757 mutex_lock(&wil->mutex); 758 rc = __wil_down(wil); 759 mutex_unlock(&wil->mutex); 760 761 return rc; 762 } 763 764 int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) 765 { 766 int i; 767 int rc = -ENOENT; 768 769 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 770 if ((wil->sta[i].status != wil_sta_unused) && 771 ether_addr_equal(wil->sta[i].addr, mac)) { 772 rc = i; 773 break; 774 } 775 } 776 777 return rc; 778 } 779