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 struct sk_buff *skb; 462 int i; 463 464 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 465 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 466 467 ath11k_ahb_ext_grp_disable(irq_grp); 468 469 napi_synchronize(&irq_grp->napi); 470 napi_disable(&irq_grp->napi); 471 472 while ((skb = __skb_dequeue(&irq_grp->pending_q))) 473 dev_kfree_skb_any(skb); 474 } 475 } 476 477 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) 478 { 479 int i; 480 481 for (i = 0; i < irq_grp->num_irq; i++) 482 enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); 483 } 484 485 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset) 486 { 487 u32 val; 488 489 val = ath11k_ahb_read32(ab, offset); 490 ath11k_ahb_write32(ab, offset, val | BIT(bit)); 491 } 492 493 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset) 494 { 495 u32 val; 496 497 val = ath11k_ahb_read32(ab, offset); 498 ath11k_ahb_write32(ab, offset, val & ~BIT(bit)); 499 } 500 501 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) 502 { 503 const struct ce_pipe_config *ce_config; 504 505 ce_config = &target_ce_config_wlan[ce_id]; 506 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) 507 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 508 509 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { 510 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 511 ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 512 CE_HOST_IE_3_ADDRESS); 513 } 514 } 515 516 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) 517 { 518 const struct ce_pipe_config *ce_config; 519 520 ce_config = &target_ce_config_wlan[ce_id]; 521 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) 522 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); 523 524 if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { 525 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); 526 ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, 527 CE_HOST_IE_3_ADDRESS); 528 } 529 } 530 531 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab) 532 { 533 int i; 534 int irq_idx; 535 536 for (i = 0; i < CE_COUNT; i++) { 537 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 538 continue; 539 540 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 541 synchronize_irq(ab->irq_num[irq_idx]); 542 } 543 } 544 545 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab) 546 { 547 int i, j; 548 int irq_idx; 549 550 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 551 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 552 553 for (j = 0; j < irq_grp->num_irq; j++) { 554 irq_idx = irq_grp->irqs[j]; 555 synchronize_irq(ab->irq_num[irq_idx]); 556 } 557 } 558 } 559 560 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab) 561 { 562 int i; 563 564 for (i = 0; i < CE_COUNT; i++) { 565 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 566 continue; 567 ath11k_ahb_ce_irq_enable(ab, i); 568 } 569 } 570 571 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab) 572 { 573 int i; 574 575 for (i = 0; i < CE_COUNT; i++) { 576 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 577 continue; 578 ath11k_ahb_ce_irq_disable(ab, i); 579 } 580 } 581 582 int ath11k_ahb_start(struct ath11k_base *ab) 583 { 584 ath11k_ahb_ce_irqs_enable(ab); 585 ath11k_ce_rx_post_buf(ab); 586 587 return 0; 588 } 589 590 void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) 591 { 592 int i; 593 594 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 595 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 596 597 napi_enable(&irq_grp->napi); 598 ath11k_ahb_ext_grp_enable(irq_grp); 599 } 600 } 601 602 void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) 603 { 604 __ath11k_ahb_ext_irq_disable(ab); 605 ath11k_ahb_sync_ext_irqs(ab); 606 } 607 608 void ath11k_ahb_stop(struct ath11k_base *ab) 609 { 610 if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) 611 ath11k_ahb_ce_irqs_disable(ab); 612 ath11k_ahb_sync_ce_irqs(ab); 613 ath11k_ahb_kill_tasklets(ab); 614 del_timer_sync(&ab->rx_replenish_retry); 615 ath11k_ce_cleanup_pipes(ab); 616 } 617 618 int ath11k_ahb_power_up(struct ath11k_base *ab) 619 { 620 int ret; 621 622 ret = rproc_boot(ab->tgt_rproc); 623 if (ret) 624 ath11k_err(ab, "failed to boot the remote processor Q6\n"); 625 626 return ret; 627 } 628 629 void ath11k_ahb_power_down(struct ath11k_base *ab) 630 { 631 rproc_shutdown(ab->tgt_rproc); 632 } 633 634 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab) 635 { 636 struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; 637 638 cfg->tgt_ce_len = ARRAY_SIZE(target_ce_config_wlan) - 1; 639 cfg->tgt_ce = target_ce_config_wlan; 640 cfg->svc_to_ce_map_len = ARRAY_SIZE(target_service_to_ce_map_wlan); 641 cfg->svc_to_ce_map = target_service_to_ce_map_wlan; 642 } 643 644 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab) 645 { 646 int i, j; 647 648 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 649 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 650 651 for (j = 0; j < irq_grp->num_irq; j++) 652 free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp); 653 } 654 } 655 656 static void ath11k_ahb_free_irq(struct ath11k_base *ab) 657 { 658 int irq_idx; 659 int i; 660 661 for (i = 0; i < CE_COUNT; i++) { 662 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 663 continue; 664 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 665 free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]); 666 } 667 668 ath11k_ahb_free_ext_irq(ab); 669 } 670 671 static void ath11k_ahb_ce_tasklet(unsigned long data) 672 { 673 struct ath11k_ce_pipe *ce_pipe = (struct ath11k_ce_pipe *)data; 674 675 ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num); 676 677 ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num); 678 } 679 680 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg) 681 { 682 struct ath11k_ce_pipe *ce_pipe = arg; 683 684 ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num); 685 686 tasklet_schedule(&ce_pipe->intr_tq); 687 688 return IRQ_HANDLED; 689 } 690 691 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) 692 { 693 struct ath11k_ext_irq_grp *irq_grp = container_of(napi, 694 struct ath11k_ext_irq_grp, 695 napi); 696 struct ath11k_base *ab = irq_grp->ab; 697 int work_done; 698 699 work_done = ath11k_dp_service_srng(ab, irq_grp, budget); 700 if (work_done < budget) { 701 napi_complete_done(napi, work_done); 702 ath11k_ahb_ext_grp_enable(irq_grp); 703 } 704 705 if (work_done > budget) 706 work_done = budget; 707 708 return work_done; 709 } 710 711 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg) 712 { 713 struct ath11k_ext_irq_grp *irq_grp = arg; 714 715 ath11k_ahb_ext_grp_disable(irq_grp); 716 717 napi_schedule(&irq_grp->napi); 718 719 return IRQ_HANDLED; 720 } 721 722 static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab) 723 { 724 int i, j; 725 int irq; 726 int ret; 727 728 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 729 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; 730 u32 num_irq = 0; 731 732 irq_grp->ab = ab; 733 irq_grp->grp_id = i; 734 init_dummy_netdev(&irq_grp->napi_ndev); 735 netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, 736 ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT); 737 __skb_queue_head_init(&irq_grp->pending_q); 738 739 for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { 740 if (ath11k_tx_ring_mask[i] & BIT(j)) { 741 irq_grp->irqs[num_irq++] = 742 wbm2host_tx_completions_ring1 - j; 743 } 744 745 if (ath11k_rx_ring_mask[i] & BIT(j)) { 746 irq_grp->irqs[num_irq++] = 747 reo2host_destination_ring1 - j; 748 } 749 750 if (ath11k_rx_err_ring_mask[i] & BIT(j)) 751 irq_grp->irqs[num_irq++] = reo2host_exception; 752 753 if (ath11k_rx_wbm_rel_ring_mask[i] & BIT(j)) 754 irq_grp->irqs[num_irq++] = wbm2host_rx_release; 755 756 if (ath11k_reo_status_ring_mask[i] & BIT(j)) 757 irq_grp->irqs[num_irq++] = reo2host_status; 758 759 if (j < MAX_RADIOS) { 760 if (ath11k_rxdma2host_ring_mask[i] & BIT(j)) { 761 irq_grp->irqs[num_irq++] = 762 rxdma2host_destination_ring_mac1 763 - ath11k_core_get_hw_mac_id(ab, j); 764 } 765 766 if (ath11k_host2rxdma_ring_mask[i] & BIT(j)) { 767 irq_grp->irqs[num_irq++] = 768 host2rxdma_host_buf_ring_mac1 769 - ath11k_core_get_hw_mac_id(ab, j); 770 } 771 772 if (rx_mon_status_ring_mask[i] & BIT(j)) { 773 irq_grp->irqs[num_irq++] = 774 ppdu_end_interrupts_mac1 - 775 ath11k_core_get_hw_mac_id(ab, j); 776 irq_grp->irqs[num_irq++] = 777 rxdma2host_monitor_status_ring_mac1 - 778 ath11k_core_get_hw_mac_id(ab, j); 779 } 780 } 781 } 782 irq_grp->num_irq = num_irq; 783 784 for (j = 0; j < irq_grp->num_irq; j++) { 785 int irq_idx = irq_grp->irqs[j]; 786 787 irq = platform_get_irq_byname(ab->pdev, 788 irq_name[irq_idx]); 789 ab->irq_num[irq_idx] = irq; 790 irq_set_status_flags(irq, IRQ_NOAUTOEN); 791 ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler, 792 IRQF_TRIGGER_RISING, 793 irq_name[irq_idx], irq_grp); 794 if (ret) { 795 ath11k_err(ab, "failed request_irq for %d\n", 796 irq); 797 } 798 } 799 } 800 801 return 0; 802 } 803 804 static int ath11k_ahb_config_irq(struct ath11k_base *ab) 805 { 806 int irq, irq_idx, i; 807 int ret; 808 809 /* Configure CE irqs */ 810 for (i = 0; i < CE_COUNT; i++) { 811 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i]; 812 813 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR) 814 continue; 815 816 irq_idx = ATH11K_IRQ_CE0_OFFSET + i; 817 818 tasklet_init(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet, 819 (unsigned long)ce_pipe); 820 irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]); 821 ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler, 822 IRQF_TRIGGER_RISING, irq_name[irq_idx], 823 ce_pipe); 824 if (ret) 825 return ret; 826 827 ab->irq_num[irq_idx] = irq; 828 } 829 830 /* Configure external interrupts */ 831 ret = ath11k_ahb_ext_irq_config(ab); 832 833 return ret; 834 } 835 836 int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, 837 u8 *ul_pipe, u8 *dl_pipe) 838 { 839 const struct service_to_pipe *entry; 840 bool ul_set = false, dl_set = false; 841 int i; 842 843 for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) { 844 entry = &target_service_to_ce_map_wlan[i]; 845 846 if (__le32_to_cpu(entry->service_id) != service_id) 847 continue; 848 849 switch (__le32_to_cpu(entry->pipedir)) { 850 case PIPEDIR_NONE: 851 break; 852 case PIPEDIR_IN: 853 WARN_ON(dl_set); 854 *dl_pipe = __le32_to_cpu(entry->pipenum); 855 dl_set = true; 856 break; 857 case PIPEDIR_OUT: 858 WARN_ON(ul_set); 859 *ul_pipe = __le32_to_cpu(entry->pipenum); 860 ul_set = true; 861 break; 862 case PIPEDIR_INOUT: 863 WARN_ON(dl_set); 864 WARN_ON(ul_set); 865 *dl_pipe = __le32_to_cpu(entry->pipenum); 866 *ul_pipe = __le32_to_cpu(entry->pipenum); 867 dl_set = true; 868 ul_set = true; 869 break; 870 } 871 } 872 873 if (WARN_ON(!ul_set || !dl_set)) 874 return -ENOENT; 875 876 return 0; 877 } 878 879 static int ath11k_ahb_probe(struct platform_device *pdev) 880 { 881 struct ath11k_base *ab; 882 const struct of_device_id *of_id; 883 struct resource *mem_res; 884 void __iomem *mem; 885 int ret; 886 887 of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev); 888 if (!of_id) { 889 dev_err(&pdev->dev, "failed to find matching device tree id\n"); 890 return -EINVAL; 891 } 892 893 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 894 if (!mem_res) { 895 dev_err(&pdev->dev, "failed to get IO memory resource\n"); 896 return -ENXIO; 897 } 898 899 mem = devm_ioremap_resource(&pdev->dev, mem_res); 900 if (IS_ERR(mem)) { 901 dev_err(&pdev->dev, "ioremap error\n"); 902 return PTR_ERR(mem); 903 } 904 905 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 906 if (ret) { 907 dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n"); 908 return ret; 909 } 910 911 ab = ath11k_core_alloc(&pdev->dev); 912 if (!ab) { 913 dev_err(&pdev->dev, "failed to allocate ath11k base\n"); 914 return -ENOMEM; 915 } 916 917 ab->pdev = pdev; 918 ab->hw_rev = (enum ath11k_hw_rev)of_id->data; 919 ab->mem = mem; 920 ab->mem_len = resource_size(mem_res); 921 platform_set_drvdata(pdev, ab); 922 923 ret = ath11k_hal_srng_init(ab); 924 if (ret) 925 goto err_core_free; 926 927 ret = ath11k_ce_alloc_pipes(ab); 928 if (ret) { 929 ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret); 930 goto err_hal_srng_deinit; 931 } 932 933 ath11k_ahb_init_qmi_ce_config(ab); 934 935 ret = ath11k_ahb_config_irq(ab); 936 if (ret) { 937 ath11k_err(ab, "failed to configure irq: %d\n", ret); 938 goto err_ce_free; 939 } 940 941 ret = ath11k_core_init(ab); 942 if (ret) { 943 ath11k_err(ab, "failed to init core: %d\n", ret); 944 goto err_ce_free; 945 } 946 947 return 0; 948 949 err_ce_free: 950 ath11k_ce_free_pipes(ab); 951 952 err_hal_srng_deinit: 953 ath11k_hal_srng_deinit(ab); 954 955 err_core_free: 956 ath11k_core_free(ab); 957 platform_set_drvdata(pdev, NULL); 958 959 return ret; 960 } 961 962 static int ath11k_ahb_remove(struct platform_device *pdev) 963 { 964 struct ath11k_base *ab = platform_get_drvdata(pdev); 965 966 reinit_completion(&ab->driver_recovery); 967 968 if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) 969 wait_for_completion_timeout(&ab->driver_recovery, 970 ATH11K_AHB_RECOVERY_TIMEOUT); 971 972 set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); 973 cancel_work_sync(&ab->restart_work); 974 975 ath11k_core_deinit(ab); 976 ath11k_ahb_free_irq(ab); 977 978 ath11k_hal_srng_deinit(ab); 979 ath11k_ce_free_pipes(ab); 980 ath11k_core_free(ab); 981 platform_set_drvdata(pdev, NULL); 982 983 return 0; 984 } 985 986 static struct platform_driver ath11k_ahb_driver = { 987 .driver = { 988 .name = "ath11k", 989 .of_match_table = ath11k_ahb_of_match, 990 }, 991 .probe = ath11k_ahb_probe, 992 .remove = ath11k_ahb_remove, 993 }; 994 995 int ath11k_ahb_init(void) 996 { 997 return platform_driver_register(&ath11k_ahb_driver); 998 } 999 1000 void ath11k_ahb_exit(void) 1001 { 1002 platform_driver_unregister(&ath11k_ahb_driver); 1003 } 1004