1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/module.h> 7 #include <linux/platform_device.h> 8 #include <linux/of_device.h> 9 #include <linux/of.h> 10 #include <linux/dma-mapping.h> 11 #include "ahb.h" 12 #include "debug.h" 13 #include <linux/remoteproc.h> 14 15 static const struct of_device_id ath11k_ahb_of_match[] = { 16 /* TODO: Should we change the compatible string to something similar 17 * to one that ath10k uses? 18 */ 19 { .compatible = "qcom,ipq8074-wifi", 20 .data = (void *)ATH11K_HW_IPQ8074, 21 }, 22 { } 23 }; 24 25 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match); 26 27 /* Target firmware's Copy Engine configuration. */ 28 static const struct ce_pipe_config target_ce_config_wlan[] = { 29 /* CE0: host->target HTC control and raw streams */ 30 { 31 .pipenum = __cpu_to_le32(0), 32 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 33 .nentries = __cpu_to_le32(32), 34 .nbytes_max = __cpu_to_le32(2048), 35 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 36 .reserved = __cpu_to_le32(0), 37 }, 38 39 /* CE1: target->host HTT + HTC control */ 40 { 41 .pipenum = __cpu_to_le32(1), 42 .pipedir = __cpu_to_le32(PIPEDIR_IN), 43 .nentries = __cpu_to_le32(32), 44 .nbytes_max = __cpu_to_le32(2048), 45 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 46 .reserved = __cpu_to_le32(0), 47 }, 48 49 /* CE2: target->host WMI */ 50 { 51 .pipenum = __cpu_to_le32(2), 52 .pipedir = __cpu_to_le32(PIPEDIR_IN), 53 .nentries = __cpu_to_le32(32), 54 .nbytes_max = __cpu_to_le32(2048), 55 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 56 .reserved = __cpu_to_le32(0), 57 }, 58 59 /* CE3: host->target WMI */ 60 { 61 .pipenum = __cpu_to_le32(3), 62 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 63 .nentries = __cpu_to_le32(32), 64 .nbytes_max = __cpu_to_le32(2048), 65 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 66 .reserved = __cpu_to_le32(0), 67 }, 68 69 /* CE4: host->target HTT */ 70 { 71 .pipenum = __cpu_to_le32(4), 72 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 73 .nentries = __cpu_to_le32(256), 74 .nbytes_max = __cpu_to_le32(256), 75 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), 76 .reserved = __cpu_to_le32(0), 77 }, 78 79 /* CE5: target->host Pktlog */ 80 { 81 .pipenum = __cpu_to_le32(5), 82 .pipedir = __cpu_to_le32(PIPEDIR_IN), 83 .nentries = __cpu_to_le32(32), 84 .nbytes_max = __cpu_to_le32(2048), 85 .flags = __cpu_to_le32(0), 86 .reserved = __cpu_to_le32(0), 87 }, 88 89 /* CE6: Reserved for target autonomous hif_memcpy */ 90 { 91 .pipenum = __cpu_to_le32(6), 92 .pipedir = __cpu_to_le32(PIPEDIR_INOUT), 93 .nentries = __cpu_to_le32(32), 94 .nbytes_max = __cpu_to_le32(65535), 95 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 96 .reserved = __cpu_to_le32(0), 97 }, 98 99 /* CE7 used only by Host */ 100 { 101 .pipenum = __cpu_to_le32(7), 102 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 103 .nentries = __cpu_to_le32(32), 104 .nbytes_max = __cpu_to_le32(2048), 105 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 106 .reserved = __cpu_to_le32(0), 107 }, 108 109 /* CE8 target->host used only by IPA */ 110 { 111 .pipenum = __cpu_to_le32(8), 112 .pipedir = __cpu_to_le32(PIPEDIR_INOUT), 113 .nentries = __cpu_to_le32(32), 114 .nbytes_max = __cpu_to_le32(65535), 115 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 116 .reserved = __cpu_to_le32(0), 117 }, 118 119 /* CE9 host->target HTT */ 120 { 121 .pipenum = __cpu_to_le32(9), 122 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 123 .nentries = __cpu_to_le32(32), 124 .nbytes_max = __cpu_to_le32(2048), 125 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 126 .reserved = __cpu_to_le32(0), 127 }, 128 129 /* CE10 target->host HTT */ 130 { 131 .pipenum = __cpu_to_le32(10), 132 .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), 133 .nentries = __cpu_to_le32(0), 134 .nbytes_max = __cpu_to_le32(0), 135 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 136 .reserved = __cpu_to_le32(0), 137 }, 138 139 /* CE11 Not used */ 140 { 141 .pipenum = __cpu_to_le32(0), 142 .pipedir = __cpu_to_le32(0), 143 .nentries = __cpu_to_le32(0), 144 .nbytes_max = __cpu_to_le32(0), 145 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 146 .reserved = __cpu_to_le32(0), 147 }, 148 }; 149 150 /* Map from service/endpoint to Copy Engine. 151 * This table is derived from the CE_PCI TABLE, above. 152 * It is passed to the Target at startup for use by firmware. 153 */ 154 static const struct service_to_pipe target_service_to_ce_map_wlan[] = { 155 { 156 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), 157 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 158 .pipenum = __cpu_to_le32(3), 159 }, 160 { 161 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), 162 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 163 .pipenum = __cpu_to_le32(2), 164 }, 165 { 166 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), 167 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 168 .pipenum = __cpu_to_le32(3), 169 }, 170 { 171 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), 172 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 173 .pipenum = __cpu_to_le32(2), 174 }, 175 { 176 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), 177 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 178 .pipenum = __cpu_to_le32(3), 179 }, 180 { 181 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), 182 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 183 .pipenum = __cpu_to_le32(2), 184 }, 185 { 186 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), 187 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 188 .pipenum = __cpu_to_le32(3), 189 }, 190 { 191 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), 192 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 193 .pipenum = __cpu_to_le32(2), 194 }, 195 { 196 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), 197 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 198 .pipenum = __cpu_to_le32(3), 199 }, 200 { 201 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), 202 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 203 .pipenum = __cpu_to_le32(2), 204 }, 205 { 206 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1), 207 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 208 .pipenum = __cpu_to_le32(7), 209 }, 210 { 211 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1), 212 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 213 .pipenum = __cpu_to_le32(2), 214 }, 215 { 216 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2), 217 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 218 .pipenum = __cpu_to_le32(9), 219 }, 220 { 221 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2), 222 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 223 .pipenum = __cpu_to_le32(2), 224 }, 225 { 226 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), 227 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 228 .pipenum = __cpu_to_le32(0), 229 }, 230 { 231 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), 232 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 233 .pipenum = __cpu_to_le32(1), 234 }, 235 { /* not used */ 236 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), 237 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 238 .pipenum = __cpu_to_le32(0), 239 }, 240 { /* not used */ 241 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), 242 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 243 .pipenum = __cpu_to_le32(1), 244 }, 245 { 246 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), 247 .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 248 .pipenum = __cpu_to_le32(4), 249 }, 250 { 251 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), 252 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 253 .pipenum = __cpu_to_le32(1), 254 }, 255 { 256 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG), 257 .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ 258 .pipenum = __cpu_to_le32(5), 259 }, 260 261 /* (Additions here) */ 262 263 { /* terminator entry */ } 264 }; 265 266 #define ATH11K_IRQ_CE0_OFFSET 4 267 268 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = { 269 "misc-pulse1", 270 "misc-latch", 271 "sw-exception", 272 "watchdog", 273 "ce0", 274 "ce1", 275 "ce2", 276 "ce3", 277 "ce4", 278 "ce5", 279 "ce6", 280 "ce7", 281 "ce8", 282 "ce9", 283 "ce10", 284 "ce11", 285 "host2wbm-desc-feed", 286 "host2reo-re-injection", 287 "host2reo-command", 288 "host2rxdma-monitor-ring3", 289 "host2rxdma-monitor-ring2", 290 "host2rxdma-monitor-ring1", 291 "reo2ost-exception", 292 "wbm2host-rx-release", 293 "reo2host-status", 294 "reo2host-destination-ring4", 295 "reo2host-destination-ring3", 296 "reo2host-destination-ring2", 297 "reo2host-destination-ring1", 298 "rxdma2host-monitor-destination-mac3", 299 "rxdma2host-monitor-destination-mac2", 300 "rxdma2host-monitor-destination-mac1", 301 "ppdu-end-interrupts-mac3", 302 "ppdu-end-interrupts-mac2", 303 "ppdu-end-interrupts-mac1", 304 "rxdma2host-monitor-status-ring-mac3", 305 "rxdma2host-monitor-status-ring-mac2", 306 "rxdma2host-monitor-status-ring-mac1", 307 "host2rxdma-host-buf-ring-mac3", 308 "host2rxdma-host-buf-ring-mac2", 309 "host2rxdma-host-buf-ring-mac1", 310 "rxdma2host-destination-ring-mac3", 311 "rxdma2host-destination-ring-mac2", 312 "rxdma2host-destination-ring-mac1", 313 "host2tcl-input-ring4", 314 "host2tcl-input-ring3", 315 "host2tcl-input-ring2", 316 "host2tcl-input-ring1", 317 "wbm2host-tx-completions-ring3", 318 "wbm2host-tx-completions-ring2", 319 "wbm2host-tx-completions-ring1", 320 "tcl2host-status-ring", 321 }; 322 323 #define ATH11K_TX_RING_MASK_0 0x1 324 #define ATH11K_TX_RING_MASK_1 0x2 325 #define ATH11K_TX_RING_MASK_2 0x4 326 327 #define ATH11K_RX_RING_MASK_0 0x1 328 #define ATH11K_RX_RING_MASK_1 0x2 329 #define ATH11K_RX_RING_MASK_2 0x4 330 #define ATH11K_RX_RING_MASK_3 0x8 331 332 #define ATH11K_RX_ERR_RING_MASK_0 0x1 333 334 #define ATH11K_RX_WBM_REL_RING_MASK_0 0x1 335 336 #define ATH11K_REO_STATUS_RING_MASK_0 0x1 337 338 #define ATH11K_RXDMA2HOST_RING_MASK_0 0x1 339 #define ATH11K_RXDMA2HOST_RING_MASK_1 0x2 340 #define ATH11K_RXDMA2HOST_RING_MASK_2 0x4 341 342 #define ATH11K_HOST2RXDMA_RING_MASK_0 0x1 343 #define ATH11K_HOST2RXDMA_RING_MASK_1 0x2 344 #define ATH11K_HOST2RXDMA_RING_MASK_2 0x4 345 346 #define ATH11K_RX_MON_STATUS_RING_MASK_0 0x1 347 #define ATH11K_RX_MON_STATUS_RING_MASK_1 0x2 348 #define ATH11K_RX_MON_STATUS_RING_MASK_2 0x4 349 350 const u8 ath11k_tx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 351 ATH11K_TX_RING_MASK_0, 352 ATH11K_TX_RING_MASK_1, 353 ATH11K_TX_RING_MASK_2, 354 }; 355 356 const u8 rx_mon_status_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 357 0, 0, 0, 0, 358 ATH11K_RX_MON_STATUS_RING_MASK_0, 359 ATH11K_RX_MON_STATUS_RING_MASK_1, 360 ATH11K_RX_MON_STATUS_RING_MASK_2, 361 }; 362 363 const u8 ath11k_rx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 364 0, 0, 0, 0, 0, 0, 0, 365 ATH11K_RX_RING_MASK_0, 366 ATH11K_RX_RING_MASK_1, 367 ATH11K_RX_RING_MASK_2, 368 ATH11K_RX_RING_MASK_3, 369 }; 370 371 const u8 ath11k_rx_err_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 372 ATH11K_RX_ERR_RING_MASK_0, 373 }; 374 375 const u8 ath11k_rx_wbm_rel_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 376 ATH11K_RX_WBM_REL_RING_MASK_0, 377 }; 378 379 const u8 ath11k_reo_status_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 380 ATH11K_REO_STATUS_RING_MASK_0, 381 }; 382 383 const u8 ath11k_rxdma2host_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 384 ATH11K_RXDMA2HOST_RING_MASK_0, 385 ATH11K_RXDMA2HOST_RING_MASK_1, 386 ATH11K_RXDMA2HOST_RING_MASK_2, 387 }; 388 389 const u8 ath11k_host2rxdma_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = { 390 ATH11K_HOST2RXDMA_RING_MASK_0, 391 ATH11K_HOST2RXDMA_RING_MASK_1, 392 ATH11K_HOST2RXDMA_RING_MASK_2, 393 }; 394 395 /* enum ext_irq_num - irq numbers that can be used by external modules 396 * like datapath 397 */ 398 enum ext_irq_num { 399 host2wbm_desc_feed = 16, 400 host2reo_re_injection, 401 host2reo_command, 402 host2rxdma_monitor_ring3, 403 host2rxdma_monitor_ring2, 404 host2rxdma_monitor_ring1, 405 reo2host_exception, 406 wbm2host_rx_release, 407 reo2host_status, 408 reo2host_destination_ring4, 409 reo2host_destination_ring3, 410 reo2host_destination_ring2, 411 reo2host_destination_ring1, 412 rxdma2host_monitor_destination_mac3, 413 rxdma2host_monitor_destination_mac2, 414 rxdma2host_monitor_destination_mac1, 415 ppdu_end_interrupts_mac3, 416 ppdu_end_interrupts_mac2, 417 ppdu_end_interrupts_mac1, 418 rxdma2host_monitor_status_ring_mac3, 419 rxdma2host_monitor_status_ring_mac2, 420 rxdma2host_monitor_status_ring_mac1, 421 host2rxdma_host_buf_ring_mac3, 422 host2rxdma_host_buf_ring_mac2, 423 host2rxdma_host_buf_ring_mac1, 424 rxdma2host_destination_ring_mac3, 425 rxdma2host_destination_ring_mac2, 426 rxdma2host_destination_ring_mac1, 427 host2tcl_input_ring4, 428 host2tcl_input_ring3, 429 host2tcl_input_ring2, 430 host2tcl_input_ring1, 431 wbm2host_tx_completions_ring3, 432 wbm2host_tx_completions_ring2, 433 wbm2host_tx_completions_ring1, 434 tcl2host_status_ring, 435 }; 436 437 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab) 438 { 439 int i; 440 441 for (i = 0; i < CE_COUNT; i++) { 442 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; 443 444 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 445 continue; 446 447 tasklet_kill(&ce_pipe->intr_tq); 448 } 449 } 450 451 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) 452 { 453 int i; 454 455 for (i = 0; i < irq_grp->num_irq; i++) 456 disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); 457 } 458 459 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) 460 { 461 int i; 462 463 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 464 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 465 466 ath11k_ahb_ext_grp_disable(irq_grp); 467 468 napi_synchronize(&irq_grp->napi); 469 napi_disable(&irq_grp->napi); 470 } 471 } 472 473 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) 474 { 475 int i; 476 477 for (i = 0; i < irq_grp->num_irq; i++) 478 enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); 479 } 480 481 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset) 482 { 483 u32 val; 484 485 val = ath11k_ahb_read32(ab, offset); 486 ath11k_ahb_write32(ab, offset, val | BIT(bit)); 487 } 488 489 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset) 490 { 491 u32 val; 492 493 val = ath11k_ahb_read32(ab, offset); 494 ath11k_ahb_write32(ab, offset, val & ~BIT(bit)); 495 } 496 497 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) 498 { 499 const struct ce_pipe_config *ce_config; 500 501 ce_config = &target_ce_config_wlan[ce_id]; 502 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) 503 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 504 505 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { 506 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 507 ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 508 CE_HOST_IE_3_ADDRESS); 509 } 510 } 511 512 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) 513 { 514 const struct ce_pipe_config *ce_config; 515 516 ce_config = &target_ce_config_wlan[ce_id]; 517 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) 518 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 519 520 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { 521 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 522 ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 523 CE_HOST_IE_3_ADDRESS); 524 } 525 } 526 527 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab) 528 { 529 int i; 530 int irq_idx; 531 532 for (i = 0; i < CE_COUNT; i++) { 533 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 534 continue; 535 536 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 537 synchronize_irq(ab->irq_num[irq_idx]); 538 } 539 } 540 541 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab) 542 { 543 int i, j; 544 int irq_idx; 545 546 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 547 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 548 549 for (j = 0; j < irq_grp->num_irq; j++) { 550 irq_idx = irq_grp->irqs[j]; 551 synchronize_irq(ab->irq_num[irq_idx]); 552 } 553 } 554 } 555 556 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab) 557 { 558 int i; 559 560 for (i = 0; i < CE_COUNT; i++) { 561 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 562 continue; 563 ath11k_ahb_ce_irq_enable(ab, i); 564 } 565 } 566 567 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab) 568 { 569 int i; 570 571 for (i = 0; i < CE_COUNT; i++) { 572 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 573 continue; 574 ath11k_ahb_ce_irq_disable(ab, i); 575 } 576 } 577 578 int ath11k_ahb_start(struct ath11k_base *ab) 579 { 580 ath11k_ahb_ce_irqs_enable(ab); 581 ath11k_ce_rx_post_buf(ab); 582 583 return 0; 584 } 585 586 void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) 587 { 588 int i; 589 590 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 591 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 592 593 napi_enable(&irq_grp->napi); 594 ath11k_ahb_ext_grp_enable(irq_grp); 595 } 596 } 597 598 void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) 599 { 600 __ath11k_ahb_ext_irq_disable(ab); 601 ath11k_ahb_sync_ext_irqs(ab); 602 } 603 604 void ath11k_ahb_stop(struct ath11k_base *ab) 605 { 606 if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) 607 ath11k_ahb_ce_irqs_disable(ab); 608 ath11k_ahb_sync_ce_irqs(ab); 609 ath11k_ahb_kill_tasklets(ab); 610 del_timer_sync(&ab->rx_replenish_retry); 611 ath11k_ce_cleanup_pipes(ab); 612 } 613 614 int ath11k_ahb_power_up(struct ath11k_base *ab) 615 { 616 int ret; 617 618 ret = rproc_boot(ab->tgt_rproc); 619 if (ret) 620 ath11k_err(ab, "failed to boot the remote processor Q6\n"); 621 622 return ret; 623 } 624 625 void ath11k_ahb_power_down(struct ath11k_base *ab) 626 { 627 rproc_shutdown(ab->tgt_rproc); 628 } 629 630 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab) 631 { 632 struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; 633 634 cfg->tgt_ce_len = ARRAY_SIZE(target_ce_config_wlan) - 1; 635 cfg->tgt_ce = target_ce_config_wlan; 636 cfg->svc_to_ce_map_len = ARRAY_SIZE(target_service_to_ce_map_wlan); 637 cfg->svc_to_ce_map = target_service_to_ce_map_wlan; 638 } 639 640 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab) 641 { 642 int i, j; 643 644 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 645 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 646 647 for (j = 0; j < irq_grp->num_irq; j++) 648 free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp); 649 } 650 } 651 652 static void ath11k_ahb_free_irq(struct ath11k_base *ab) 653 { 654 int irq_idx; 655 int i; 656 657 for (i = 0; i < CE_COUNT; i++) { 658 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 659 continue; 660 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 661 free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); 662 } 663 664 ath11k_ahb_free_ext_irq(ab); 665 } 666 667 static void ath11k_ahb_ce_tasklet(unsigned long data) 668 { 669 struct ath11k_ce_pipe *ce_pipe = (struct ath11k_ce_pipe *)data; 670 671 ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); 672 673 ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num); 674 } 675 676 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg) 677 { 678 struct ath11k_ce_pipe *ce_pipe = arg; 679 680 /* last interrupt received for this CE */ 681 ce_pipe->timestamp = jiffies; 682 683 ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num); 684 685 tasklet_schedule(&ce_pipe->intr_tq); 686 687 return IRQ_HANDLED; 688 } 689 690 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) 691 { 692 struct ath11k_ext_irq_grp *irq_grp = container_of(napi, 693 struct ath11k_ext_irq_grp, 694 napi); 695 struct ath11k_base *ab = irq_grp->ab; 696 int work_done; 697 698 work_done = ath11k_dp_service_srng(ab, irq_grp, budget); 699 if (work_done < budget) { 700 napi_complete_done(napi, work_done); 701 ath11k_ahb_ext_grp_enable(irq_grp); 702 } 703 704 if (work_done > budget) 705 work_done = budget; 706 707 return work_done; 708 } 709 710 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg) 711 { 712 struct ath11k_ext_irq_grp *irq_grp = arg; 713 714 /* last interrupt received for this group */ 715 irq_grp->timestamp = jiffies; 716 717 ath11k_ahb_ext_grp_disable(irq_grp); 718 719 napi_schedule(&irq_grp->napi); 720 721 return IRQ_HANDLED; 722 } 723 724 static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab) 725 { 726 int i, j; 727 int irq; 728 int ret; 729 730 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 731 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 732 u32 num_irq = 0; 733 734 irq_grp->ab = ab; 735 irq_grp->grp_id = i; 736 init_dummy_netdev(&irq_grp->napi_ndev); 737 netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, 738 ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT); 739 740 for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { 741 if (ath11k_tx_ring_mask[i] & BIT(j)) { 742 irq_grp->irqs[num_irq++] = 743 wbm2host_tx_completions_ring1 - j; 744 } 745 746 if (ath11k_rx_ring_mask[i] & BIT(j)) { 747 irq_grp->irqs[num_irq++] = 748 reo2host_destination_ring1 - j; 749 } 750 751 if (ath11k_rx_err_ring_mask[i] & BIT(j)) 752 irq_grp->irqs[num_irq++] = reo2host_exception; 753 754 if (ath11k_rx_wbm_rel_ring_mask[i] & BIT(j)) 755 irq_grp->irqs[num_irq++] = wbm2host_rx_release; 756 757 if (ath11k_reo_status_ring_mask[i] & BIT(j)) 758 irq_grp->irqs[num_irq++] = reo2host_status; 759 760 if (j < MAX_RADIOS) { 761 if (ath11k_rxdma2host_ring_mask[i] & BIT(j)) { 762 irq_grp->irqs[num_irq++] = 763 rxdma2host_destination_ring_mac1 764 - ath11k_core_get_hw_mac_id(ab, j); 765 } 766 767 if (ath11k_host2rxdma_ring_mask[i] & BIT(j)) { 768 irq_grp->irqs[num_irq++] = 769 host2rxdma_host_buf_ring_mac1 770 - ath11k_core_get_hw_mac_id(ab, j); 771 } 772 773 if (rx_mon_status_ring_mask[i] & BIT(j)) { 774 irq_grp->irqs[num_irq++] = 775 ppdu_end_interrupts_mac1 - 776 ath11k_core_get_hw_mac_id(ab, j); 777 irq_grp->irqs[num_irq++] = 778 rxdma2host_monitor_status_ring_mac1 - 779 ath11k_core_get_hw_mac_id(ab, j); 780 } 781 } 782 } 783 irq_grp->num_irq = num_irq; 784 785 for (j = 0; j < irq_grp->num_irq; j++) { 786 int irq_idx = irq_grp->irqs[j]; 787 788 irq = platform_get_irq_byname(ab->pdev, 789 irq_name[irq_idx]); 790 ab->irq_num[irq_idx] = irq; 791 irq_set_status_flags(irq, IRQ_NOAUTOEN); 792 ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler, 793 IRQF_TRIGGER_RISING, 794 irq_name[irq_idx], irq_grp); 795 if (ret) { 796 ath11k_err(ab, "failed request_irq for %d\n", 797 irq); 798 } 799 } 800 } 801 802 return 0; 803 } 804 805 static int ath11k_ahb_config_irq(struct ath11k_base *ab) 806 { 807 int irq, irq_idx, i; 808 int ret; 809 810 /* Configure CE irqs */ 811 for (i = 0; i < CE_COUNT; i++) { 812 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; 813 814 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 815 continue; 816 817 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 818 819 tasklet_init(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet, 820 (unsigned long)ce_pipe); 821 irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]); 822 ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler, 823 IRQF_TRIGGER_RISING, irq_name[irq_idx], 824 ce_pipe); 825 if (ret) 826 return ret; 827 828 ab->irq_num[irq_idx] = irq; 829 } 830 831 /* Configure external interrupts */ 832 ret = ath11k_ahb_ext_irq_config(ab); 833 834 return ret; 835 } 836 837 int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, 838 u8 *ul_pipe, u8 *dl_pipe) 839 { 840 const struct service_to_pipe *entry; 841 bool ul_set = false, dl_set = false; 842 int i; 843 844 for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) { 845 entry = &target_service_to_ce_map_wlan[i]; 846 847 if (__le32_to_cpu(entry->service_id) != service_id) 848 continue; 849 850 switch (__le32_to_cpu(entry->pipedir)) { 851 case PIPEDIR_NONE: 852 break; 853 case PIPEDIR_IN: 854 WARN_ON(dl_set); 855 *dl_pipe = __le32_to_cpu(entry->pipenum); 856 dl_set = true; 857 break; 858 case PIPEDIR_OUT: 859 WARN_ON(ul_set); 860 *ul_pipe = __le32_to_cpu(entry->pipenum); 861 ul_set = true; 862 break; 863 case PIPEDIR_INOUT: 864 WARN_ON(dl_set); 865 WARN_ON(ul_set); 866 *dl_pipe = __le32_to_cpu(entry->pipenum); 867 *ul_pipe = __le32_to_cpu(entry->pipenum); 868 dl_set = true; 869 ul_set = true; 870 break; 871 } 872 } 873 874 if (WARN_ON(!ul_set || !dl_set)) 875 return -ENOENT; 876 877 return 0; 878 } 879 880 static int ath11k_ahb_probe(struct platform_device *pdev) 881 { 882 struct ath11k_base *ab; 883 const struct of_device_id *of_id; 884 struct resource *mem_res; 885 void __iomem *mem; 886 int ret; 887 888 of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev); 889 if (!of_id) { 890 dev_err(&pdev->dev, "failed to find matching device tree id\n"); 891 return -EINVAL; 892 } 893 894 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 895 if (!mem_res) { 896 dev_err(&pdev->dev, "failed to get IO memory resource\n"); 897 return -ENXIO; 898 } 899 900 mem = devm_ioremap_resource(&pdev->dev, mem_res); 901 if (IS_ERR(mem)) { 902 dev_err(&pdev->dev, "ioremap error\n"); 903 return PTR_ERR(mem); 904 } 905 906 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 907 if (ret) { 908 dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n"); 909 return ret; 910 } 911 912 ab = ath11k_core_alloc(&pdev->dev); 913 if (!ab) { 914 dev_err(&pdev->dev, "failed to allocate ath11k base\n"); 915 return -ENOMEM; 916 } 917 918 ab->pdev = pdev; 919 ab->hw_rev = (enum ath11k_hw_rev)of_id->data; 920 ab->mem = mem; 921 ab->mem_len = resource_size(mem_res); 922 platform_set_drvdata(pdev, ab); 923 924 ret = ath11k_hal_srng_init(ab); 925 if (ret) 926 goto err_core_free; 927 928 ret = ath11k_ce_alloc_pipes(ab); 929 if (ret) { 930 ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret); 931 goto err_hal_srng_deinit; 932 } 933 934 ath11k_ahb_init_qmi_ce_config(ab); 935 936 ret = ath11k_ahb_config_irq(ab); 937 if (ret) { 938 ath11k_err(ab, "failed to configure irq: %d\n", ret); 939 goto err_ce_free; 940 } 941 942 ret = ath11k_core_init(ab); 943 if (ret) { 944 ath11k_err(ab, "failed to init core: %d\n", ret); 945 goto err_ce_free; 946 } 947 948 return 0; 949 950 err_ce_free: 951 ath11k_ce_free_pipes(ab); 952 953 err_hal_srng_deinit: 954 ath11k_hal_srng_deinit(ab); 955 956 err_core_free: 957 ath11k_core_free(ab); 958 platform_set_drvdata(pdev, NULL); 959 960 return ret; 961 } 962 963 static int ath11k_ahb_remove(struct platform_device *pdev) 964 { 965 struct ath11k_base *ab = platform_get_drvdata(pdev); 966 967 reinit_completion(&ab->driver_recovery); 968 969 if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) 970 wait_for_completion_timeout(&ab->driver_recovery, 971 ATH11K_AHB_RECOVERY_TIMEOUT); 972 973 set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); 974 cancel_work_sync(&ab->restart_work); 975 976 ath11k_core_deinit(ab); 977 ath11k_ahb_free_irq(ab); 978 979 ath11k_hal_srng_deinit(ab); 980 ath11k_ce_free_pipes(ab); 981 ath11k_core_free(ab); 982 platform_set_drvdata(pdev, NULL); 983 984 return 0; 985 } 986 987 static struct platform_driver ath11k_ahb_driver = { 988 .driver = { 989 .name = "ath11k", 990 .of_match_table = ath11k_ahb_of_match, 991 }, 992 .probe = ath11k_ahb_probe, 993 .remove = ath11k_ahb_remove, 994 }; 995 996 int ath11k_ahb_init(void) 997 { 998 return platform_driver_register(&ath11k_ahb_driver); 999 } 1000 1001 void ath11k_ahb_exit(void) 1002 { 1003 platform_driver_unregister(&ath11k_ahb_driver); 1004 } 1005