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