1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #include <linux/module.h> 8 #include <linux/platform_device.h> 9 #include <linux/of_device.h> 10 #include <linux/of.h> 11 #include <linux/dma-mapping.h> 12 #include "ahb.h" 13 #include "debug.h" 14 #include "hif.h" 15 #include <linux/remoteproc.h> 16 #include "pcic.h" 17 18 static const struct of_device_id ath11k_ahb_of_match[] = { 19 /* TODO: Should we change the compatible string to something similar 20 * to one that ath10k uses? 21 */ 22 { .compatible = "qcom,ipq8074-wifi", 23 .data = (void *)ATH11K_HW_IPQ8074, 24 }, 25 { .compatible = "qcom,ipq6018-wifi", 26 .data = (void *)ATH11K_HW_IPQ6018_HW10, 27 }, 28 { .compatible = "qcom,wcn6750-wifi", 29 .data = (void *)ATH11K_HW_WCN6750_HW10, 30 }, 31 { } 32 }; 33 34 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match); 35 36 #define ATH11K_IRQ_CE0_OFFSET 4 37 38 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { 39 "misc-pulse1", 40 "misc-latch", 41 "sw-exception", 42 "watchdog", 43 "ce0", 44 "ce1", 45 "ce2", 46 "ce3", 47 "ce4", 48 "ce5", 49 "ce6", 50 "ce7", 51 "ce8", 52 "ce9", 53 "ce10", 54 "ce11", 55 "host2wbm-desc-feed", 56 "host2reo-re-injection", 57 "host2reo-command", 58 "host2rxdma-monitor-ring3", 59 "host2rxdma-monitor-ring2", 60 "host2rxdma-monitor-ring1", 61 "reo2ost-exception", 62 "wbm2host-rx-release", 63 "reo2host-status", 64 "reo2host-destination-ring4", 65 "reo2host-destination-ring3", 66 "reo2host-destination-ring2", 67 "reo2host-destination-ring1", 68 "rxdma2host-monitor-destination-mac3", 69 "rxdma2host-monitor-destination-mac2", 70 "rxdma2host-monitor-destination-mac1", 71 "ppdu-end-interrupts-mac3", 72 "ppdu-end-interrupts-mac2", 73 "ppdu-end-interrupts-mac1", 74 "rxdma2host-monitor-status-ring-mac3", 75 "rxdma2host-monitor-status-ring-mac2", 76 "rxdma2host-monitor-status-ring-mac1", 77 "host2rxdma-host-buf-ring-mac3", 78 "host2rxdma-host-buf-ring-mac2", 79 "host2rxdma-host-buf-ring-mac1", 80 "rxdma2host-destination-ring-mac3", 81 "rxdma2host-destination-ring-mac2", 82 "rxdma2host-destination-ring-mac1", 83 "host2tcl-input-ring4", 84 "host2tcl-input-ring3", 85 "host2tcl-input-ring2", 86 "host2tcl-input-ring1", 87 "wbm2host-tx-completions-ring3", 88 "wbm2host-tx-completions-ring2", 89 "wbm2host-tx-completions-ring1", 90 "tcl2host-status-ring", 91 }; 92 93 /* enum ext_irq_num - irq numbers that can be used by external modules 94 * like datapath 95 */ 96 enum ext_irq_num { 97 host2wbm_desc_feed = 16, 98 host2reo_re_injection, 99 host2reo_command, 100 host2rxdma_monitor_ring3, 101 host2rxdma_monitor_ring2, 102 host2rxdma_monitor_ring1, 103 reo2host_exception, 104 wbm2host_rx_release, 105 reo2host_status, 106 reo2host_destination_ring4, 107 reo2host_destination_ring3, 108 reo2host_destination_ring2, 109 reo2host_destination_ring1, 110 rxdma2host_monitor_destination_mac3, 111 rxdma2host_monitor_destination_mac2, 112 rxdma2host_monitor_destination_mac1, 113 ppdu_end_interrupts_mac3, 114 ppdu_end_interrupts_mac2, 115 ppdu_end_interrupts_mac1, 116 rxdma2host_monitor_status_ring_mac3, 117 rxdma2host_monitor_status_ring_mac2, 118 rxdma2host_monitor_status_ring_mac1, 119 host2rxdma_host_buf_ring_mac3, 120 host2rxdma_host_buf_ring_mac2, 121 host2rxdma_host_buf_ring_mac1, 122 rxdma2host_destination_ring_mac3, 123 rxdma2host_destination_ring_mac2, 124 rxdma2host_destination_ring_mac1, 125 host2tcl_input_ring4, 126 host2tcl_input_ring3, 127 host2tcl_input_ring2, 128 host2tcl_input_ring1, 129 wbm2host_tx_completions_ring3, 130 wbm2host_tx_completions_ring2, 131 wbm2host_tx_completions_ring1, 132 tcl2host_status_ring, 133 }; 134 135 static int 136 ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector) 137 { 138 return ab->pci.msi.irqs[vector]; 139 } 140 141 static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = { 142 .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750, 143 }; 144 145 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) 146 { 147 return ioread32(ab->mem + offset); 148 } 149 150 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value) 151 { 152 iowrite32(value, ab->mem + offset); 153 } 154 155 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab) 156 { 157 int i; 158 159 for (i = 0; i < ab->hw_params.ce_count; i++) { 160 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; 161 162 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 163 continue; 164 165 tasklet_kill(&ce_pipe->intr_tq); 166 } 167 } 168 169 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) 170 { 171 int i; 172 173 for (i = 0; i < irq_grp->num_irq; i++) 174 disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); 175 } 176 177 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) 178 { 179 int i; 180 181 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 182 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 183 184 ath11k_ahb_ext_grp_disable(irq_grp); 185 186 if (irq_grp->napi_enabled) { 187 napi_synchronize(&irq_grp->napi); 188 napi_disable(&irq_grp->napi); 189 irq_grp->napi_enabled = false; 190 } 191 } 192 } 193 194 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) 195 { 196 int i; 197 198 for (i = 0; i < irq_grp->num_irq; i++) 199 enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); 200 } 201 202 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset) 203 { 204 u32 val; 205 206 val = ath11k_ahb_read32(ab, offset); 207 ath11k_ahb_write32(ab, offset, val | BIT(bit)); 208 } 209 210 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset) 211 { 212 u32 val; 213 214 val = ath11k_ahb_read32(ab, offset); 215 ath11k_ahb_write32(ab, offset, val & ~BIT(bit)); 216 } 217 218 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) 219 { 220 const struct ce_attr *ce_attr; 221 222 ce_attr = &ab->hw_params.host_ce_config[ce_id]; 223 if (ce_attr->src_nentries) 224 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 225 226 if (ce_attr->dest_nentries) { 227 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 228 ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 229 CE_HOST_IE_3_ADDRESS); 230 } 231 } 232 233 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) 234 { 235 const struct ce_attr *ce_attr; 236 237 ce_attr = &ab->hw_params.host_ce_config[ce_id]; 238 if (ce_attr->src_nentries) 239 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 240 241 if (ce_attr->dest_nentries) { 242 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 243 ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 244 CE_HOST_IE_3_ADDRESS); 245 } 246 } 247 248 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab) 249 { 250 int i; 251 int irq_idx; 252 253 for (i = 0; i < ab->hw_params.ce_count; i++) { 254 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 255 continue; 256 257 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 258 synchronize_irq(ab->irq_num[irq_idx]); 259 } 260 } 261 262 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab) 263 { 264 int i, j; 265 int irq_idx; 266 267 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 268 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 269 270 for (j = 0; j < irq_grp->num_irq; j++) { 271 irq_idx = irq_grp->irqs[j]; 272 synchronize_irq(ab->irq_num[irq_idx]); 273 } 274 } 275 } 276 277 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab) 278 { 279 int i; 280 281 for (i = 0; i < ab->hw_params.ce_count; i++) { 282 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 283 continue; 284 ath11k_ahb_ce_irq_enable(ab, i); 285 } 286 } 287 288 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab) 289 { 290 int i; 291 292 for (i = 0; i < ab->hw_params.ce_count; i++) { 293 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 294 continue; 295 ath11k_ahb_ce_irq_disable(ab, i); 296 } 297 } 298 299 static int ath11k_ahb_start(struct ath11k_base *ab) 300 { 301 ath11k_ahb_ce_irqs_enable(ab); 302 ath11k_ce_rx_post_buf(ab); 303 304 return 0; 305 } 306 307 static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) 308 { 309 int i; 310 311 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 312 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 313 314 if (!irq_grp->napi_enabled) { 315 napi_enable(&irq_grp->napi); 316 irq_grp->napi_enabled = true; 317 } 318 ath11k_ahb_ext_grp_enable(irq_grp); 319 } 320 } 321 322 static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) 323 { 324 __ath11k_ahb_ext_irq_disable(ab); 325 ath11k_ahb_sync_ext_irqs(ab); 326 } 327 328 static void ath11k_ahb_stop(struct ath11k_base *ab) 329 { 330 if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) 331 ath11k_ahb_ce_irqs_disable(ab); 332 ath11k_ahb_sync_ce_irqs(ab); 333 ath11k_ahb_kill_tasklets(ab); 334 del_timer_sync(&ab->rx_replenish_retry); 335 ath11k_ce_cleanup_pipes(ab); 336 } 337 338 static int ath11k_ahb_power_up(struct ath11k_base *ab) 339 { 340 struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); 341 int ret; 342 343 ret = rproc_boot(ab_ahb->tgt_rproc); 344 if (ret) 345 ath11k_err(ab, "failed to boot the remote processor Q6\n"); 346 347 return ret; 348 } 349 350 static void ath11k_ahb_power_down(struct ath11k_base *ab) 351 { 352 struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); 353 354 rproc_shutdown(ab_ahb->tgt_rproc); 355 } 356 357 static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab) 358 { 359 int timeout; 360 361 if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done || 362 ab->hw_params.cold_boot_calib == 0) 363 return 0; 364 365 ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n"); 366 timeout = wait_event_timeout(ab->qmi.cold_boot_waitq, 367 (ab->qmi.cal_done == 1), 368 ATH11K_COLD_BOOT_FW_RESET_DELAY); 369 if (timeout <= 0) { 370 ath11k_cold_boot_cal = 0; 371 ath11k_warn(ab, "Coldboot Calibration failed timed out\n"); 372 } 373 374 /* reset the firmware */ 375 ath11k_ahb_power_down(ab); 376 ath11k_ahb_power_up(ab); 377 378 ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n"); 379 return 0; 380 } 381 382 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab) 383 { 384 struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; 385 386 cfg->tgt_ce_len = ab->hw_params.target_ce_count; 387 cfg->tgt_ce = ab->hw_params.target_ce_config; 388 cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len; 389 cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map; 390 ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; 391 } 392 393 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab) 394 { 395 int i, j; 396 397 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 398 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 399 400 for (j = 0; j < irq_grp->num_irq; j++) 401 free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp); 402 403 netif_napi_del(&irq_grp->napi); 404 } 405 } 406 407 static void ath11k_ahb_free_irq(struct ath11k_base *ab) 408 { 409 int irq_idx; 410 int i; 411 412 if (ab->hw_params.hybrid_bus_type) 413 return ath11k_pcic_free_irq(ab); 414 415 for (i = 0; i < ab->hw_params.ce_count; i++) { 416 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 417 continue; 418 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 419 free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); 420 } 421 422 ath11k_ahb_free_ext_irq(ab); 423 } 424 425 static void ath11k_ahb_ce_tasklet(struct tasklet_struct *t) 426 { 427 struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq); 428 429 ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); 430 431 ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num); 432 } 433 434 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg) 435 { 436 struct ath11k_ce_pipe *ce_pipe = arg; 437 438 /* last interrupt received for this CE */ 439 ce_pipe->timestamp = jiffies; 440 441 ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num); 442 443 tasklet_schedule(&ce_pipe->intr_tq); 444 445 return IRQ_HANDLED; 446 } 447 448 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) 449 { 450 struct ath11k_ext_irq_grp *irq_grp = container_of(napi, 451 struct ath11k_ext_irq_grp, 452 napi); 453 struct ath11k_base *ab = irq_grp->ab; 454 int work_done; 455 456 work_done = ath11k_dp_service_srng(ab, irq_grp, budget); 457 if (work_done < budget) { 458 napi_complete_done(napi, work_done); 459 ath11k_ahb_ext_grp_enable(irq_grp); 460 } 461 462 if (work_done > budget) 463 work_done = budget; 464 465 return work_done; 466 } 467 468 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg) 469 { 470 struct ath11k_ext_irq_grp *irq_grp = arg; 471 472 /* last interrupt received for this group */ 473 irq_grp->timestamp = jiffies; 474 475 ath11k_ahb_ext_grp_disable(irq_grp); 476 477 napi_schedule(&irq_grp->napi); 478 479 return IRQ_HANDLED; 480 } 481 482 static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab) 483 { 484 struct ath11k_hw_params *hw = &ab->hw_params; 485 int i, j; 486 int irq; 487 int ret; 488 489 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 490 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 491 u32 num_irq = 0; 492 493 irq_grp->ab = ab; 494 irq_grp->grp_id = i; 495 init_dummy_netdev(&irq_grp->napi_ndev); 496 netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, 497 ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT); 498 499 for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { 500 if (ab->hw_params.ring_mask->tx[i] & BIT(j)) { 501 irq_grp->irqs[num_irq++] = 502 wbm2host_tx_completions_ring1 - j; 503 } 504 505 if (ab->hw_params.ring_mask->rx[i] & BIT(j)) { 506 irq_grp->irqs[num_irq++] = 507 reo2host_destination_ring1 - j; 508 } 509 510 if (ab->hw_params.ring_mask->rx_err[i] & BIT(j)) 511 irq_grp->irqs[num_irq++] = reo2host_exception; 512 513 if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) 514 irq_grp->irqs[num_irq++] = wbm2host_rx_release; 515 516 if (ab->hw_params.ring_mask->reo_status[i] & BIT(j)) 517 irq_grp->irqs[num_irq++] = reo2host_status; 518 519 if (j < ab->hw_params.max_radios) { 520 if (ab->hw_params.ring_mask->rxdma2host[i] & BIT(j)) { 521 irq_grp->irqs[num_irq++] = 522 rxdma2host_destination_ring_mac1 - 523 ath11k_hw_get_mac_from_pdev_id(hw, j); 524 } 525 526 if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { 527 irq_grp->irqs[num_irq++] = 528 host2rxdma_host_buf_ring_mac1 - 529 ath11k_hw_get_mac_from_pdev_id(hw, j); 530 } 531 532 if (ab->hw_params.ring_mask->rx_mon_status[i] & BIT(j)) { 533 irq_grp->irqs[num_irq++] = 534 ppdu_end_interrupts_mac1 - 535 ath11k_hw_get_mac_from_pdev_id(hw, j); 536 irq_grp->irqs[num_irq++] = 537 rxdma2host_monitor_status_ring_mac1 - 538 ath11k_hw_get_mac_from_pdev_id(hw, j); 539 } 540 } 541 } 542 irq_grp->num_irq = num_irq; 543 544 for (j = 0; j < irq_grp->num_irq; j++) { 545 int irq_idx = irq_grp->irqs[j]; 546 547 irq = platform_get_irq_byname(ab->pdev, 548 irq_name[irq_idx]); 549 ab->irq_num[irq_idx] = irq; 550 irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY); 551 ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler, 552 IRQF_TRIGGER_RISING, 553 irq_name[irq_idx], irq_grp); 554 if (ret) { 555 ath11k_err(ab, "failed request_irq for %d\n", 556 irq); 557 } 558 } 559 } 560 561 return 0; 562 } 563 564 static int ath11k_ahb_config_irq(struct ath11k_base *ab) 565 { 566 int irq, irq_idx, i; 567 int ret; 568 569 if (ab->hw_params.hybrid_bus_type) 570 return ath11k_pcic_config_irq(ab); 571 572 /* Configure CE irqs */ 573 for (i = 0; i < ab->hw_params.ce_count; i++) { 574 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; 575 576 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 577 continue; 578 579 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 580 581 tasklet_setup(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet); 582 irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]); 583 ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler, 584 IRQF_TRIGGER_RISING, irq_name[irq_idx], 585 ce_pipe); 586 if (ret) 587 return ret; 588 589 ab->irq_num[irq_idx] = irq; 590 } 591 592 /* Configure external interrupts */ 593 ret = ath11k_ahb_config_ext_irq(ab); 594 595 return ret; 596 } 597 598 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, 599 u8 *ul_pipe, u8 *dl_pipe) 600 { 601 const struct service_to_pipe *entry; 602 bool ul_set = false, dl_set = false; 603 int i; 604 605 for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) { 606 entry = &ab->hw_params.svc_to_ce_map[i]; 607 608 if (__le32_to_cpu(entry->service_id) != service_id) 609 continue; 610 611 switch (__le32_to_cpu(entry->pipedir)) { 612 case PIPEDIR_NONE: 613 break; 614 case PIPEDIR_IN: 615 WARN_ON(dl_set); 616 *dl_pipe = __le32_to_cpu(entry->pipenum); 617 dl_set = true; 618 break; 619 case PIPEDIR_OUT: 620 WARN_ON(ul_set); 621 *ul_pipe = __le32_to_cpu(entry->pipenum); 622 ul_set = true; 623 break; 624 case PIPEDIR_INOUT: 625 WARN_ON(dl_set); 626 WARN_ON(ul_set); 627 *dl_pipe = __le32_to_cpu(entry->pipenum); 628 *ul_pipe = __le32_to_cpu(entry->pipenum); 629 dl_set = true; 630 ul_set = true; 631 break; 632 } 633 } 634 635 if (WARN_ON(!ul_set || !dl_set)) 636 return -ENOENT; 637 638 return 0; 639 } 640 641 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = { 642 .start = ath11k_ahb_start, 643 .stop = ath11k_ahb_stop, 644 .read32 = ath11k_ahb_read32, 645 .write32 = ath11k_ahb_write32, 646 .irq_enable = ath11k_ahb_ext_irq_enable, 647 .irq_disable = ath11k_ahb_ext_irq_disable, 648 .map_service_to_pipe = ath11k_ahb_map_service_to_pipe, 649 .power_down = ath11k_ahb_power_down, 650 .power_up = ath11k_ahb_power_up, 651 }; 652 653 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = { 654 .start = ath11k_pcic_start, 655 .stop = ath11k_pcic_stop, 656 .read32 = ath11k_pcic_read32, 657 .write32 = ath11k_pcic_write32, 658 .irq_enable = ath11k_pcic_ext_irq_enable, 659 .irq_disable = ath11k_pcic_ext_irq_disable, 660 .get_msi_address = ath11k_pcic_get_msi_address, 661 .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment, 662 .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, 663 .power_down = ath11k_ahb_power_down, 664 .power_up = ath11k_ahb_power_up, 665 }; 666 667 static int ath11k_core_get_rproc(struct ath11k_base *ab) 668 { 669 struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); 670 struct device *dev = ab->dev; 671 struct rproc *prproc; 672 phandle rproc_phandle; 673 674 if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) { 675 ath11k_err(ab, "failed to get q6_rproc handle\n"); 676 return -ENOENT; 677 } 678 679 prproc = rproc_get_by_phandle(rproc_phandle); 680 if (!prproc) { 681 ath11k_err(ab, "failed to get rproc\n"); 682 return -EINVAL; 683 } 684 ab_ahb->tgt_rproc = prproc; 685 686 return 0; 687 } 688 689 static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab) 690 { 691 struct platform_device *pdev = ab->pdev; 692 phys_addr_t msi_addr_pa; 693 dma_addr_t msi_addr_iova; 694 struct resource *res; 695 int int_prop; 696 int ret; 697 int i; 698 699 ret = ath11k_pcic_init_msi_config(ab); 700 if (ret) { 701 ath11k_err(ab, "failed to init msi config: %d\n", ret); 702 return ret; 703 } 704 705 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 706 if (!res) { 707 ath11k_err(ab, "failed to fetch msi_addr\n"); 708 return -ENOENT; 709 } 710 711 msi_addr_pa = res->start; 712 msi_addr_iova = dma_map_resource(ab->dev, msi_addr_pa, PAGE_SIZE, 713 DMA_FROM_DEVICE, 0); 714 if (dma_mapping_error(ab->dev, msi_addr_iova)) 715 return -ENOMEM; 716 717 ab->pci.msi.addr_lo = lower_32_bits(msi_addr_iova); 718 ab->pci.msi.addr_hi = upper_32_bits(msi_addr_iova); 719 720 ret = of_property_read_u32_index(ab->dev->of_node, "interrupts", 1, &int_prop); 721 if (ret) 722 return ret; 723 724 ab->pci.msi.ep_base_data = int_prop + 32; 725 726 for (i = 0; i < ab->pci.msi.config->total_vectors; i++) { 727 res = platform_get_resource(pdev, IORESOURCE_IRQ, i); 728 if (!res) 729 return -ENODEV; 730 731 ab->pci.msi.irqs[i] = res->start; 732 } 733 734 set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); 735 736 return 0; 737 } 738 739 static int ath11k_ahb_setup_resources(struct ath11k_base *ab) 740 { 741 struct platform_device *pdev = ab->pdev; 742 struct resource *mem_res; 743 void __iomem *mem; 744 745 if (ab->hw_params.hybrid_bus_type) 746 return ath11k_ahb_setup_msi_resources(ab); 747 748 mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); 749 if (IS_ERR(mem)) { 750 dev_err(&pdev->dev, "ioremap error\n"); 751 return PTR_ERR(mem); 752 } 753 754 ab->mem = mem; 755 ab->mem_len = resource_size(mem_res); 756 757 return 0; 758 } 759 760 static int ath11k_ahb_probe(struct platform_device *pdev) 761 { 762 struct ath11k_base *ab; 763 const struct of_device_id *of_id; 764 const struct ath11k_hif_ops *hif_ops; 765 const struct ath11k_pci_ops *pci_ops; 766 enum ath11k_hw_rev hw_rev; 767 int ret; 768 769 of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev); 770 if (!of_id) { 771 dev_err(&pdev->dev, "failed to find matching device tree id\n"); 772 return -EINVAL; 773 } 774 775 hw_rev = (enum ath11k_hw_rev)of_id->data; 776 777 switch (hw_rev) { 778 case ATH11K_HW_IPQ8074: 779 case ATH11K_HW_IPQ6018_HW10: 780 hif_ops = &ath11k_ahb_hif_ops_ipq8074; 781 pci_ops = NULL; 782 break; 783 case ATH11K_HW_WCN6750_HW10: 784 hif_ops = &ath11k_ahb_hif_ops_wcn6750; 785 pci_ops = &ath11k_ahb_pci_ops_wcn6750; 786 break; 787 default: 788 dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev); 789 return -EOPNOTSUPP; 790 } 791 792 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 793 if (ret) { 794 dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n"); 795 return ret; 796 } 797 798 ab = ath11k_core_alloc(&pdev->dev, sizeof(struct ath11k_ahb), 799 ATH11K_BUS_AHB); 800 if (!ab) { 801 dev_err(&pdev->dev, "failed to allocate ath11k base\n"); 802 return -ENOMEM; 803 } 804 805 ab->hif.ops = hif_ops; 806 ab->pci.ops = pci_ops; 807 ab->pdev = pdev; 808 ab->hw_rev = hw_rev; 809 platform_set_drvdata(pdev, ab); 810 811 ret = ath11k_ahb_setup_resources(ab); 812 if (ret) 813 goto err_core_free; 814 815 ret = ath11k_core_pre_init(ab); 816 if (ret) 817 goto err_core_free; 818 819 ret = ath11k_hal_srng_init(ab); 820 if (ret) 821 goto err_core_free; 822 823 ret = ath11k_ce_alloc_pipes(ab); 824 if (ret) { 825 ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret); 826 goto err_hal_srng_deinit; 827 } 828 829 ath11k_ahb_init_qmi_ce_config(ab); 830 831 ret = ath11k_core_get_rproc(ab); 832 if (ret) { 833 ath11k_err(ab, "failed to get rproc: %d\n", ret); 834 goto err_ce_free; 835 } 836 837 ret = ath11k_core_init(ab); 838 if (ret) { 839 ath11k_err(ab, "failed to init core: %d\n", ret); 840 goto err_ce_free; 841 } 842 843 ret = ath11k_ahb_config_irq(ab); 844 if (ret) { 845 ath11k_err(ab, "failed to configure irq: %d\n", ret); 846 goto err_ce_free; 847 } 848 849 ath11k_ahb_fwreset_from_cold_boot(ab); 850 851 return 0; 852 853 err_ce_free: 854 ath11k_ce_free_pipes(ab); 855 856 err_hal_srng_deinit: 857 ath11k_hal_srng_deinit(ab); 858 859 err_core_free: 860 ath11k_core_free(ab); 861 platform_set_drvdata(pdev, NULL); 862 863 return ret; 864 } 865 866 static int ath11k_ahb_remove(struct platform_device *pdev) 867 { 868 struct ath11k_base *ab = platform_get_drvdata(pdev); 869 unsigned long left; 870 871 if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { 872 ath11k_ahb_power_down(ab); 873 ath11k_debugfs_soc_destroy(ab); 874 ath11k_qmi_deinit_service(ab); 875 goto qmi_fail; 876 } 877 878 reinit_completion(&ab->driver_recovery); 879 880 if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) { 881 left = wait_for_completion_timeout(&ab->driver_recovery, 882 ATH11K_AHB_RECOVERY_TIMEOUT); 883 if (!left) 884 ath11k_warn(ab, "failed to receive recovery response completion\n"); 885 } 886 887 set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); 888 cancel_work_sync(&ab->restart_work); 889 890 ath11k_core_deinit(ab); 891 qmi_fail: 892 ath11k_ahb_free_irq(ab); 893 ath11k_hal_srng_deinit(ab); 894 ath11k_ce_free_pipes(ab); 895 ath11k_core_free(ab); 896 platform_set_drvdata(pdev, NULL); 897 898 return 0; 899 } 900 901 static struct platform_driver ath11k_ahb_driver = { 902 .driver = { 903 .name = "ath11k", 904 .of_match_table = ath11k_ahb_of_match, 905 }, 906 .probe = ath11k_ahb_probe, 907 .remove = ath11k_ahb_remove, 908 }; 909 910 static int ath11k_ahb_init(void) 911 { 912 return platform_driver_register(&ath11k_ahb_driver); 913 } 914 module_init(ath11k_ahb_init); 915 916 static void ath11k_ahb_exit(void) 917 { 918 platform_driver_unregister(&ath11k_ahb_driver); 919 } 920 module_exit(ath11k_ahb_exit); 921 922 MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN AHB devices"); 923 MODULE_LICENSE("Dual BSD/GPL"); 924