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