1 /* 2 * Copyright (c) 2012 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 24 static bool no_fw_recovery; 25 module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); 26 MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); 27 28 /* 29 * Due to a hardware issue, 30 * one has to read/write to/from NIC in 32-bit chunks; 31 * regular memcpy_fromio and siblings will 32 * not work on 64-bit platform - it uses 64-bit transactions 33 * 34 * Force 32-bit transactions to enable NIC on 64-bit platforms 35 * 36 * To avoid byte swap on big endian host, __raw_{read|write}l 37 * should be used - {read|write}l would swap bytes to provide 38 * little endian on PCI value in host endianness. 39 */ 40 void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, 41 size_t count) 42 { 43 u32 *d = dst; 44 const volatile u32 __iomem *s = src; 45 46 /* size_t is unsigned, if (count%4 != 0) it will wrap */ 47 for (count += 4; count > 4; count -= 4) 48 *d++ = __raw_readl(s++); 49 } 50 51 void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 52 size_t count) 53 { 54 volatile u32 __iomem *d = dst; 55 const u32 *s = src; 56 57 for (count += 4; count > 4; count -= 4) 58 __raw_writel(*s++, d++); 59 } 60 61 static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) 62 { 63 uint i; 64 struct wil_sta_info *sta = &wil->sta[cid]; 65 66 sta->data_port_open = false; 67 if (sta->status != wil_sta_unused) { 68 wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING); 69 sta->status = wil_sta_unused; 70 } 71 72 for (i = 0; i < WIL_STA_TID_NUM; i++) { 73 struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; 74 sta->tid_rx[i] = NULL; 75 wil_tid_ampdu_rx_free(wil, r); 76 } 77 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 78 if (wil->vring2cid_tid[i][0] == cid) 79 wil_vring_fini_tx(wil, i); 80 } 81 memset(&sta->stats, 0, sizeof(sta->stats)); 82 } 83 84 static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) 85 { 86 int cid = -ENOENT; 87 struct net_device *ndev = wil_to_ndev(wil); 88 struct wireless_dev *wdev = wil->wdev; 89 90 might_sleep(); 91 if (bssid) { 92 cid = wil_find_cid(wil, bssid); 93 wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); 94 } else { 95 wil_dbg_misc(wil, "%s(all)\n", __func__); 96 } 97 98 if (cid >= 0) /* disconnect 1 peer */ 99 wil_disconnect_cid(wil, cid); 100 else /* disconnect all */ 101 for (cid = 0; cid < WIL6210_MAX_CID; cid++) 102 wil_disconnect_cid(wil, cid); 103 104 /* link state */ 105 switch (wdev->iftype) { 106 case NL80211_IFTYPE_STATION: 107 case NL80211_IFTYPE_P2P_CLIENT: 108 wil_link_off(wil); 109 if (test_bit(wil_status_fwconnected, &wil->status)) { 110 clear_bit(wil_status_fwconnected, &wil->status); 111 cfg80211_disconnected(ndev, 112 WLAN_STATUS_UNSPECIFIED_FAILURE, 113 NULL, 0, GFP_KERNEL); 114 } else if (test_bit(wil_status_fwconnecting, &wil->status)) { 115 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 116 WLAN_STATUS_UNSPECIFIED_FAILURE, 117 GFP_KERNEL); 118 } 119 clear_bit(wil_status_fwconnecting, &wil->status); 120 break; 121 default: 122 /* AP-like interface and monitor: 123 * never scan, always connected 124 */ 125 if (bssid) 126 cfg80211_del_sta(ndev, bssid, GFP_KERNEL); 127 break; 128 } 129 } 130 131 static void wil_disconnect_worker(struct work_struct *work) 132 { 133 struct wil6210_priv *wil = container_of(work, 134 struct wil6210_priv, disconnect_worker); 135 136 mutex_lock(&wil->mutex); 137 _wil6210_disconnect(wil, NULL); 138 mutex_unlock(&wil->mutex); 139 } 140 141 static void wil_connect_timer_fn(ulong x) 142 { 143 struct wil6210_priv *wil = (void *)x; 144 145 wil_dbg_misc(wil, "Connect timeout\n"); 146 147 /* reschedule to thread context - disconnect won't 148 * run from atomic context 149 */ 150 schedule_work(&wil->disconnect_worker); 151 } 152 153 static void wil_fw_error_worker(struct work_struct *work) 154 { 155 struct wil6210_priv *wil = container_of(work, 156 struct wil6210_priv, fw_error_worker); 157 struct wireless_dev *wdev = wil->wdev; 158 159 wil_dbg_misc(wil, "fw error worker\n"); 160 161 if (no_fw_recovery) 162 return; 163 164 mutex_lock(&wil->mutex); 165 switch (wdev->iftype) { 166 case NL80211_IFTYPE_STATION: 167 case NL80211_IFTYPE_P2P_CLIENT: 168 case NL80211_IFTYPE_MONITOR: 169 wil_info(wil, "fw error recovery started...\n"); 170 wil_reset(wil); 171 172 /* need to re-allocate Rx ring after reset */ 173 wil_rx_init(wil); 174 break; 175 case NL80211_IFTYPE_AP: 176 case NL80211_IFTYPE_P2P_GO: 177 /* recovery in these modes is done by upper layers */ 178 break; 179 default: 180 break; 181 } 182 mutex_unlock(&wil->mutex); 183 } 184 185 static int wil_find_free_vring(struct wil6210_priv *wil) 186 { 187 int i; 188 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 189 if (!wil->vring_tx[i].va) 190 return i; 191 } 192 return -EINVAL; 193 } 194 195 static void wil_connect_worker(struct work_struct *work) 196 { 197 int rc; 198 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 199 connect_worker); 200 int cid = wil->pending_connect_cid; 201 int ringid = wil_find_free_vring(wil); 202 203 if (cid < 0) { 204 wil_err(wil, "No connection pending\n"); 205 return; 206 } 207 208 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid); 209 210 rc = wil_vring_init_tx(wil, ringid, WIL6210_TX_RING_SIZE, cid, 0); 211 wil->pending_connect_cid = -1; 212 if (rc == 0) { 213 wil->sta[cid].status = wil_sta_connected; 214 wil_link_on(wil); 215 } else { 216 wil->sta[cid].status = wil_sta_unused; 217 } 218 } 219 220 int wil_priv_init(struct wil6210_priv *wil) 221 { 222 wil_dbg_misc(wil, "%s()\n", __func__); 223 224 memset(wil->sta, 0, sizeof(wil->sta)); 225 226 mutex_init(&wil->mutex); 227 mutex_init(&wil->wmi_mutex); 228 229 init_completion(&wil->wmi_ready); 230 231 wil->pending_connect_cid = -1; 232 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 233 234 INIT_WORK(&wil->connect_worker, wil_connect_worker); 235 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 236 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 237 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 238 239 INIT_LIST_HEAD(&wil->pending_wmi_ev); 240 spin_lock_init(&wil->wmi_ev_lock); 241 242 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); 243 if (!wil->wmi_wq) 244 return -EAGAIN; 245 246 wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); 247 if (!wil->wmi_wq_conn) { 248 destroy_workqueue(wil->wmi_wq); 249 return -EAGAIN; 250 } 251 252 return 0; 253 } 254 255 void wil6210_disconnect(struct wil6210_priv *wil, void *bssid) 256 { 257 del_timer_sync(&wil->connect_timer); 258 _wil6210_disconnect(wil, bssid); 259 } 260 261 void wil_priv_deinit(struct wil6210_priv *wil) 262 { 263 cancel_work_sync(&wil->disconnect_worker); 264 cancel_work_sync(&wil->fw_error_worker); 265 mutex_lock(&wil->mutex); 266 wil6210_disconnect(wil, NULL); 267 mutex_unlock(&wil->mutex); 268 wmi_event_flush(wil); 269 destroy_workqueue(wil->wmi_wq_conn); 270 destroy_workqueue(wil->wmi_wq); 271 } 272 273 static void wil_target_reset(struct wil6210_priv *wil) 274 { 275 int delay = 0; 276 u32 hw_state; 277 u32 rev_id; 278 279 wil_dbg_misc(wil, "Resetting...\n"); 280 281 /* register read */ 282 #define R(a) ioread32(wil->csr + HOSTADDR(a)) 283 /* register write */ 284 #define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a)) 285 /* register set = read, OR, write */ 286 #define S(a, v) W(a, R(a) | v) 287 /* register clear = read, AND with inverted, write */ 288 #define C(a, v) W(a, R(a) & ~v) 289 290 wil->hw_version = R(RGF_USER_FW_REV_ID); 291 rev_id = wil->hw_version & 0xff; 292 /* hpal_perst_from_pad_src_n_mask */ 293 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); 294 /* car_perst_rst_src_n_mask */ 295 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); 296 wmb(); /* order is important here */ 297 298 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ 299 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ 300 wmb(); /* order is important here */ 301 302 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 303 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 304 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); 305 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 306 wmb(); /* order is important here */ 307 308 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 309 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 310 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 311 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 312 wmb(); /* order is important here */ 313 314 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 315 if (rev_id == 1) { 316 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 317 } else { 318 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8)); 319 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 320 } 321 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 322 wmb(); /* order is important here */ 323 324 /* wait until device ready */ 325 do { 326 msleep(1); 327 hw_state = R(RGF_USER_HW_MACHINE_STATE); 328 if (delay++ > 100) { 329 wil_err(wil, "Reset not completed, hw_state 0x%08x\n", 330 hw_state); 331 return; 332 } 333 } while (hw_state != HW_MACHINE_BOOT_DONE); 334 335 if (rev_id == 2) 336 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 337 338 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 339 wmb(); /* order is important here */ 340 341 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay); 342 343 #undef R 344 #undef W 345 #undef S 346 #undef C 347 } 348 349 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 350 { 351 le32_to_cpus(&r->base); 352 le16_to_cpus(&r->entry_size); 353 le16_to_cpus(&r->size); 354 le32_to_cpus(&r->tail); 355 le32_to_cpus(&r->head); 356 } 357 358 static int wil_wait_for_fw_ready(struct wil6210_priv *wil) 359 { 360 ulong to = msecs_to_jiffies(1000); 361 ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); 362 if (0 == left) { 363 wil_err(wil, "Firmware not ready\n"); 364 return -ETIME; 365 } else { 366 wil_dbg_misc(wil, "FW ready after %d ms\n", 367 jiffies_to_msecs(to-left)); 368 } 369 return 0; 370 } 371 372 /* 373 * We reset all the structures, and we reset the UMAC. 374 * After calling this routine, you're expected to reload 375 * the firmware. 376 */ 377 int wil_reset(struct wil6210_priv *wil) 378 { 379 int rc; 380 381 WARN_ON(!mutex_is_locked(&wil->mutex)); 382 383 cancel_work_sync(&wil->disconnect_worker); 384 wil6210_disconnect(wil, NULL); 385 386 wil->status = 0; /* prevent NAPI from being scheduled */ 387 if (test_bit(wil_status_napi_en, &wil->status)) { 388 napi_synchronize(&wil->napi_rx); 389 } 390 391 if (wil->scan_request) { 392 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 393 wil->scan_request); 394 cfg80211_scan_done(wil->scan_request, true); 395 wil->scan_request = NULL; 396 } 397 398 wil6210_disable_irq(wil); 399 400 wmi_event_flush(wil); 401 402 flush_workqueue(wil->wmi_wq_conn); 403 flush_workqueue(wil->wmi_wq); 404 405 /* TODO: put MAC in reset */ 406 wil_target_reset(wil); 407 408 wil_rx_fini(wil); 409 410 /* init after reset */ 411 wil->pending_connect_cid = -1; 412 reinit_completion(&wil->wmi_ready); 413 414 /* TODO: release MAC reset */ 415 wil6210_enable_irq(wil); 416 417 /* we just started MAC, wait for FW ready */ 418 rc = wil_wait_for_fw_ready(wil); 419 420 return rc; 421 } 422 423 void wil_fw_error_recovery(struct wil6210_priv *wil) 424 { 425 wil_dbg_misc(wil, "starting fw error recovery\n"); 426 schedule_work(&wil->fw_error_worker); 427 } 428 429 void wil_link_on(struct wil6210_priv *wil) 430 { 431 struct net_device *ndev = wil_to_ndev(wil); 432 433 wil_dbg_misc(wil, "%s()\n", __func__); 434 435 netif_carrier_on(ndev); 436 netif_tx_wake_all_queues(ndev); 437 } 438 439 void wil_link_off(struct wil6210_priv *wil) 440 { 441 struct net_device *ndev = wil_to_ndev(wil); 442 443 wil_dbg_misc(wil, "%s()\n", __func__); 444 445 netif_tx_stop_all_queues(ndev); 446 netif_carrier_off(ndev); 447 } 448 449 static int __wil_up(struct wil6210_priv *wil) 450 { 451 struct net_device *ndev = wil_to_ndev(wil); 452 struct wireless_dev *wdev = wil->wdev; 453 int rc; 454 455 WARN_ON(!mutex_is_locked(&wil->mutex)); 456 457 rc = wil_reset(wil); 458 if (rc) 459 return rc; 460 461 /* Rx VRING. After MAC and beacon */ 462 rc = wil_rx_init(wil); 463 if (rc) 464 return rc; 465 466 switch (wdev->iftype) { 467 case NL80211_IFTYPE_STATION: 468 wil_dbg_misc(wil, "type: STATION\n"); 469 ndev->type = ARPHRD_ETHER; 470 break; 471 case NL80211_IFTYPE_AP: 472 wil_dbg_misc(wil, "type: AP\n"); 473 ndev->type = ARPHRD_ETHER; 474 break; 475 case NL80211_IFTYPE_P2P_CLIENT: 476 wil_dbg_misc(wil, "type: P2P_CLIENT\n"); 477 ndev->type = ARPHRD_ETHER; 478 break; 479 case NL80211_IFTYPE_P2P_GO: 480 wil_dbg_misc(wil, "type: P2P_GO\n"); 481 ndev->type = ARPHRD_ETHER; 482 break; 483 case NL80211_IFTYPE_MONITOR: 484 wil_dbg_misc(wil, "type: Monitor\n"); 485 ndev->type = ARPHRD_IEEE80211_RADIOTAP; 486 /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */ 487 break; 488 default: 489 return -EOPNOTSUPP; 490 } 491 492 /* MAC address - pre-requisite for other commands */ 493 wmi_set_mac_address(wil, ndev->dev_addr); 494 495 496 napi_enable(&wil->napi_rx); 497 napi_enable(&wil->napi_tx); 498 set_bit(wil_status_napi_en, &wil->status); 499 500 return 0; 501 } 502 503 int wil_up(struct wil6210_priv *wil) 504 { 505 int rc; 506 507 mutex_lock(&wil->mutex); 508 rc = __wil_up(wil); 509 mutex_unlock(&wil->mutex); 510 511 return rc; 512 } 513 514 static int __wil_down(struct wil6210_priv *wil) 515 { 516 WARN_ON(!mutex_is_locked(&wil->mutex)); 517 518 clear_bit(wil_status_napi_en, &wil->status); 519 napi_disable(&wil->napi_rx); 520 napi_disable(&wil->napi_tx); 521 522 if (wil->scan_request) { 523 cfg80211_scan_done(wil->scan_request, true); 524 wil->scan_request = NULL; 525 } 526 527 wil6210_disconnect(wil, NULL); 528 wil_rx_fini(wil); 529 530 return 0; 531 } 532 533 int wil_down(struct wil6210_priv *wil) 534 { 535 int rc; 536 537 mutex_lock(&wil->mutex); 538 rc = __wil_down(wil); 539 mutex_unlock(&wil->mutex); 540 541 return rc; 542 } 543 544 int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) 545 { 546 int i; 547 int rc = -ENOENT; 548 549 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 550 if ((wil->sta[i].status != wil_sta_unused) && 551 ether_addr_equal(wil->sta[i].addr, mac)) { 552 rc = i; 553 break; 554 } 555 } 556 557 return rc; 558 } 559