Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause-Clear
0002 /*
0003  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
0004  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/of_device.h>
0010 #include <linux/of.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/of_address.h>
0013 #include <linux/iommu.h>
0014 #include "ahb.h"
0015 #include "debug.h"
0016 #include "hif.h"
0017 #include <linux/remoteproc.h>
0018 #include "pcic.h"
0019 
0020 static const struct of_device_id ath11k_ahb_of_match[] = {
0021     /* TODO: Should we change the compatible string to something similar
0022      * to one that ath10k uses?
0023      */
0024     { .compatible = "qcom,ipq8074-wifi",
0025       .data = (void *)ATH11K_HW_IPQ8074,
0026     },
0027     { .compatible = "qcom,ipq6018-wifi",
0028       .data = (void *)ATH11K_HW_IPQ6018_HW10,
0029     },
0030     { .compatible = "qcom,wcn6750-wifi",
0031       .data = (void *)ATH11K_HW_WCN6750_HW10,
0032     },
0033     { }
0034 };
0035 
0036 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match);
0037 
0038 #define ATH11K_IRQ_CE0_OFFSET 4
0039 
0040 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
0041     "misc-pulse1",
0042     "misc-latch",
0043     "sw-exception",
0044     "watchdog",
0045     "ce0",
0046     "ce1",
0047     "ce2",
0048     "ce3",
0049     "ce4",
0050     "ce5",
0051     "ce6",
0052     "ce7",
0053     "ce8",
0054     "ce9",
0055     "ce10",
0056     "ce11",
0057     "host2wbm-desc-feed",
0058     "host2reo-re-injection",
0059     "host2reo-command",
0060     "host2rxdma-monitor-ring3",
0061     "host2rxdma-monitor-ring2",
0062     "host2rxdma-monitor-ring1",
0063     "reo2ost-exception",
0064     "wbm2host-rx-release",
0065     "reo2host-status",
0066     "reo2host-destination-ring4",
0067     "reo2host-destination-ring3",
0068     "reo2host-destination-ring2",
0069     "reo2host-destination-ring1",
0070     "rxdma2host-monitor-destination-mac3",
0071     "rxdma2host-monitor-destination-mac2",
0072     "rxdma2host-monitor-destination-mac1",
0073     "ppdu-end-interrupts-mac3",
0074     "ppdu-end-interrupts-mac2",
0075     "ppdu-end-interrupts-mac1",
0076     "rxdma2host-monitor-status-ring-mac3",
0077     "rxdma2host-monitor-status-ring-mac2",
0078     "rxdma2host-monitor-status-ring-mac1",
0079     "host2rxdma-host-buf-ring-mac3",
0080     "host2rxdma-host-buf-ring-mac2",
0081     "host2rxdma-host-buf-ring-mac1",
0082     "rxdma2host-destination-ring-mac3",
0083     "rxdma2host-destination-ring-mac2",
0084     "rxdma2host-destination-ring-mac1",
0085     "host2tcl-input-ring4",
0086     "host2tcl-input-ring3",
0087     "host2tcl-input-ring2",
0088     "host2tcl-input-ring1",
0089     "wbm2host-tx-completions-ring3",
0090     "wbm2host-tx-completions-ring2",
0091     "wbm2host-tx-completions-ring1",
0092     "tcl2host-status-ring",
0093 };
0094 
0095 /* enum ext_irq_num - irq numbers that can be used by external modules
0096  * like datapath
0097  */
0098 enum ext_irq_num {
0099     host2wbm_desc_feed = 16,
0100     host2reo_re_injection,
0101     host2reo_command,
0102     host2rxdma_monitor_ring3,
0103     host2rxdma_monitor_ring2,
0104     host2rxdma_monitor_ring1,
0105     reo2host_exception,
0106     wbm2host_rx_release,
0107     reo2host_status,
0108     reo2host_destination_ring4,
0109     reo2host_destination_ring3,
0110     reo2host_destination_ring2,
0111     reo2host_destination_ring1,
0112     rxdma2host_monitor_destination_mac3,
0113     rxdma2host_monitor_destination_mac2,
0114     rxdma2host_monitor_destination_mac1,
0115     ppdu_end_interrupts_mac3,
0116     ppdu_end_interrupts_mac2,
0117     ppdu_end_interrupts_mac1,
0118     rxdma2host_monitor_status_ring_mac3,
0119     rxdma2host_monitor_status_ring_mac2,
0120     rxdma2host_monitor_status_ring_mac1,
0121     host2rxdma_host_buf_ring_mac3,
0122     host2rxdma_host_buf_ring_mac2,
0123     host2rxdma_host_buf_ring_mac1,
0124     rxdma2host_destination_ring_mac3,
0125     rxdma2host_destination_ring_mac2,
0126     rxdma2host_destination_ring_mac1,
0127     host2tcl_input_ring4,
0128     host2tcl_input_ring3,
0129     host2tcl_input_ring2,
0130     host2tcl_input_ring1,
0131     wbm2host_tx_completions_ring3,
0132     wbm2host_tx_completions_ring2,
0133     wbm2host_tx_completions_ring1,
0134     tcl2host_status_ring,
0135 };
0136 
0137 static int
0138 ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector)
0139 {
0140     return ab->pci.msi.irqs[vector];
0141 }
0142 
0143 static inline u32
0144 ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset)
0145 {
0146     u32 window_start = 0;
0147 
0148     /* If offset lies within DP register range, use 1st window */
0149     if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK)
0150         window_start = ATH11K_PCI_WINDOW_START;
0151     /* If offset lies within CE register range, use 2nd window */
0152     else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) <
0153          ATH11K_PCI_WINDOW_RANGE_MASK)
0154         window_start = 2 * ATH11K_PCI_WINDOW_START;
0155 
0156     return window_start;
0157 }
0158 
0159 static void
0160 ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value)
0161 {
0162     u32 window_start;
0163 
0164     /* WCN6750 uses static window based register access*/
0165     window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
0166 
0167     iowrite32(value, ab->mem + window_start +
0168           (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
0169 }
0170 
0171 static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset)
0172 {
0173     u32 window_start;
0174     u32 val;
0175 
0176     /* WCN6750 uses static window based register access */
0177     window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
0178 
0179     val = ioread32(ab->mem + window_start +
0180                (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
0181     return val;
0182 }
0183 
0184 static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = {
0185     .wakeup = NULL,
0186     .release = NULL,
0187     .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750,
0188     .window_write32 = ath11k_ahb_window_write32_wcn6750,
0189     .window_read32 = ath11k_ahb_window_read32_wcn6750,
0190 };
0191 
0192 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
0193 {
0194     return ioread32(ab->mem + offset);
0195 }
0196 
0197 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
0198 {
0199     iowrite32(value, ab->mem + offset);
0200 }
0201 
0202 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab)
0203 {
0204     int i;
0205 
0206     for (i = 0; i < ab->hw_params.ce_count; i++) {
0207         struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
0208 
0209         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0210             continue;
0211 
0212         tasklet_kill(&ce_pipe->intr_tq);
0213     }
0214 }
0215 
0216 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
0217 {
0218     int i;
0219 
0220     for (i = 0; i < irq_grp->num_irq; i++)
0221         disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
0222 }
0223 
0224 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
0225 {
0226     int i;
0227 
0228     for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
0229         struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
0230 
0231         ath11k_ahb_ext_grp_disable(irq_grp);
0232 
0233         if (irq_grp->napi_enabled) {
0234             napi_synchronize(&irq_grp->napi);
0235             napi_disable(&irq_grp->napi);
0236             irq_grp->napi_enabled = false;
0237         }
0238     }
0239 }
0240 
0241 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
0242 {
0243     int i;
0244 
0245     for (i = 0; i < irq_grp->num_irq; i++)
0246         enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
0247 }
0248 
0249 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset)
0250 {
0251     u32 val;
0252 
0253     val = ath11k_ahb_read32(ab, offset);
0254     ath11k_ahb_write32(ab, offset, val | BIT(bit));
0255 }
0256 
0257 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset)
0258 {
0259     u32 val;
0260 
0261     val = ath11k_ahb_read32(ab, offset);
0262     ath11k_ahb_write32(ab, offset, val & ~BIT(bit));
0263 }
0264 
0265 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
0266 {
0267     const struct ce_attr *ce_attr;
0268 
0269     ce_attr = &ab->hw_params.host_ce_config[ce_id];
0270     if (ce_attr->src_nentries)
0271         ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
0272 
0273     if (ce_attr->dest_nentries) {
0274         ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
0275         ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
0276                     CE_HOST_IE_3_ADDRESS);
0277     }
0278 }
0279 
0280 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
0281 {
0282     const struct ce_attr *ce_attr;
0283 
0284     ce_attr = &ab->hw_params.host_ce_config[ce_id];
0285     if (ce_attr->src_nentries)
0286         ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
0287 
0288     if (ce_attr->dest_nentries) {
0289         ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
0290         ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
0291                       CE_HOST_IE_3_ADDRESS);
0292     }
0293 }
0294 
0295 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab)
0296 {
0297     int i;
0298     int irq_idx;
0299 
0300     for (i = 0; i < ab->hw_params.ce_count; i++) {
0301         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0302             continue;
0303 
0304         irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
0305         synchronize_irq(ab->irq_num[irq_idx]);
0306     }
0307 }
0308 
0309 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab)
0310 {
0311     int i, j;
0312     int irq_idx;
0313 
0314     for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
0315         struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
0316 
0317         for (j = 0; j < irq_grp->num_irq; j++) {
0318             irq_idx = irq_grp->irqs[j];
0319             synchronize_irq(ab->irq_num[irq_idx]);
0320         }
0321     }
0322 }
0323 
0324 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab)
0325 {
0326     int i;
0327 
0328     for (i = 0; i < ab->hw_params.ce_count; i++) {
0329         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0330             continue;
0331         ath11k_ahb_ce_irq_enable(ab, i);
0332     }
0333 }
0334 
0335 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab)
0336 {
0337     int i;
0338 
0339     for (i = 0; i < ab->hw_params.ce_count; i++) {
0340         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0341             continue;
0342         ath11k_ahb_ce_irq_disable(ab, i);
0343     }
0344 }
0345 
0346 static int ath11k_ahb_start(struct ath11k_base *ab)
0347 {
0348     ath11k_ahb_ce_irqs_enable(ab);
0349     ath11k_ce_rx_post_buf(ab);
0350 
0351     return 0;
0352 }
0353 
0354 static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
0355 {
0356     int i;
0357 
0358     for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
0359         struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
0360 
0361         if (!irq_grp->napi_enabled) {
0362             napi_enable(&irq_grp->napi);
0363             irq_grp->napi_enabled = true;
0364         }
0365         ath11k_ahb_ext_grp_enable(irq_grp);
0366     }
0367 }
0368 
0369 static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
0370 {
0371     __ath11k_ahb_ext_irq_disable(ab);
0372     ath11k_ahb_sync_ext_irqs(ab);
0373 }
0374 
0375 static void ath11k_ahb_stop(struct ath11k_base *ab)
0376 {
0377     if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
0378         ath11k_ahb_ce_irqs_disable(ab);
0379     ath11k_ahb_sync_ce_irqs(ab);
0380     ath11k_ahb_kill_tasklets(ab);
0381     del_timer_sync(&ab->rx_replenish_retry);
0382     ath11k_ce_cleanup_pipes(ab);
0383 }
0384 
0385 static int ath11k_ahb_power_up(struct ath11k_base *ab)
0386 {
0387     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0388     int ret;
0389 
0390     ret = rproc_boot(ab_ahb->tgt_rproc);
0391     if (ret)
0392         ath11k_err(ab, "failed to boot the remote processor Q6\n");
0393 
0394     return ret;
0395 }
0396 
0397 static void ath11k_ahb_power_down(struct ath11k_base *ab)
0398 {
0399     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0400 
0401     rproc_shutdown(ab_ahb->tgt_rproc);
0402 }
0403 
0404 static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab)
0405 {
0406     int timeout;
0407 
0408     if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done ||
0409         ab->hw_params.cold_boot_calib == 0)
0410         return 0;
0411 
0412     ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n");
0413     timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
0414                      (ab->qmi.cal_done  == 1),
0415                      ATH11K_COLD_BOOT_FW_RESET_DELAY);
0416     if (timeout <= 0) {
0417         ath11k_cold_boot_cal = 0;
0418         ath11k_warn(ab, "Coldboot Calibration failed timed out\n");
0419     }
0420 
0421     /* reset the firmware */
0422     ath11k_ahb_power_down(ab);
0423     ath11k_ahb_power_up(ab);
0424 
0425     ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n");
0426     return 0;
0427 }
0428 
0429 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
0430 {
0431     struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
0432 
0433     cfg->tgt_ce_len = ab->hw_params.target_ce_count;
0434     cfg->tgt_ce = ab->hw_params.target_ce_config;
0435     cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
0436     cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
0437     ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
0438 }
0439 
0440 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
0441 {
0442     int i, j;
0443 
0444     for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
0445         struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
0446 
0447         for (j = 0; j < irq_grp->num_irq; j++)
0448             free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
0449 
0450         netif_napi_del(&irq_grp->napi);
0451     }
0452 }
0453 
0454 static void ath11k_ahb_free_irq(struct ath11k_base *ab)
0455 {
0456     int irq_idx;
0457     int i;
0458 
0459     if (ab->hw_params.hybrid_bus_type)
0460         return ath11k_pcic_free_irq(ab);
0461 
0462     for (i = 0; i < ab->hw_params.ce_count; i++) {
0463         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0464             continue;
0465         irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
0466         free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
0467     }
0468 
0469     ath11k_ahb_free_ext_irq(ab);
0470 }
0471 
0472 static void ath11k_ahb_ce_tasklet(struct tasklet_struct *t)
0473 {
0474     struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
0475 
0476     ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
0477 
0478     ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
0479 }
0480 
0481 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
0482 {
0483     struct ath11k_ce_pipe *ce_pipe = arg;
0484 
0485     /* last interrupt received for this CE */
0486     ce_pipe->timestamp = jiffies;
0487 
0488     ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
0489 
0490     tasklet_schedule(&ce_pipe->intr_tq);
0491 
0492     return IRQ_HANDLED;
0493 }
0494 
0495 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget)
0496 {
0497     struct ath11k_ext_irq_grp *irq_grp = container_of(napi,
0498                         struct ath11k_ext_irq_grp,
0499                         napi);
0500     struct ath11k_base *ab = irq_grp->ab;
0501     int work_done;
0502 
0503     work_done = ath11k_dp_service_srng(ab, irq_grp, budget);
0504     if (work_done < budget) {
0505         napi_complete_done(napi, work_done);
0506         ath11k_ahb_ext_grp_enable(irq_grp);
0507     }
0508 
0509     if (work_done > budget)
0510         work_done = budget;
0511 
0512     return work_done;
0513 }
0514 
0515 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
0516 {
0517     struct ath11k_ext_irq_grp *irq_grp = arg;
0518 
0519     /* last interrupt received for this group */
0520     irq_grp->timestamp = jiffies;
0521 
0522     ath11k_ahb_ext_grp_disable(irq_grp);
0523 
0524     napi_schedule(&irq_grp->napi);
0525 
0526     return IRQ_HANDLED;
0527 }
0528 
0529 static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
0530 {
0531     struct ath11k_hw_params *hw = &ab->hw_params;
0532     int i, j;
0533     int irq;
0534     int ret;
0535 
0536     for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
0537         struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
0538         u32 num_irq = 0;
0539 
0540         irq_grp->ab = ab;
0541         irq_grp->grp_id = i;
0542         init_dummy_netdev(&irq_grp->napi_ndev);
0543         netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
0544                    ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT);
0545 
0546         for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
0547             if (ab->hw_params.ring_mask->tx[i] & BIT(j)) {
0548                 irq_grp->irqs[num_irq++] =
0549                     wbm2host_tx_completions_ring1 - j;
0550             }
0551 
0552             if (ab->hw_params.ring_mask->rx[i] & BIT(j)) {
0553                 irq_grp->irqs[num_irq++] =
0554                     reo2host_destination_ring1 - j;
0555             }
0556 
0557             if (ab->hw_params.ring_mask->rx_err[i] & BIT(j))
0558                 irq_grp->irqs[num_irq++] = reo2host_exception;
0559 
0560             if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j))
0561                 irq_grp->irqs[num_irq++] = wbm2host_rx_release;
0562 
0563             if (ab->hw_params.ring_mask->reo_status[i] & BIT(j))
0564                 irq_grp->irqs[num_irq++] = reo2host_status;
0565 
0566             if (j < ab->hw_params.max_radios) {
0567                 if (ab->hw_params.ring_mask->rxdma2host[i] & BIT(j)) {
0568                     irq_grp->irqs[num_irq++] =
0569                         rxdma2host_destination_ring_mac1 -
0570                         ath11k_hw_get_mac_from_pdev_id(hw, j);
0571                 }
0572 
0573                 if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) {
0574                     irq_grp->irqs[num_irq++] =
0575                         host2rxdma_host_buf_ring_mac1 -
0576                         ath11k_hw_get_mac_from_pdev_id(hw, j);
0577                 }
0578 
0579                 if (ab->hw_params.ring_mask->rx_mon_status[i] & BIT(j)) {
0580                     irq_grp->irqs[num_irq++] =
0581                         ppdu_end_interrupts_mac1 -
0582                         ath11k_hw_get_mac_from_pdev_id(hw, j);
0583                     irq_grp->irqs[num_irq++] =
0584                         rxdma2host_monitor_status_ring_mac1 -
0585                         ath11k_hw_get_mac_from_pdev_id(hw, j);
0586                 }
0587             }
0588         }
0589         irq_grp->num_irq = num_irq;
0590 
0591         for (j = 0; j < irq_grp->num_irq; j++) {
0592             int irq_idx = irq_grp->irqs[j];
0593 
0594             irq = platform_get_irq_byname(ab->pdev,
0595                               irq_name[irq_idx]);
0596             ab->irq_num[irq_idx] = irq;
0597             irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
0598             ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
0599                       IRQF_TRIGGER_RISING,
0600                       irq_name[irq_idx], irq_grp);
0601             if (ret) {
0602                 ath11k_err(ab, "failed request_irq for %d\n",
0603                        irq);
0604             }
0605         }
0606     }
0607 
0608     return 0;
0609 }
0610 
0611 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
0612 {
0613     int irq, irq_idx, i;
0614     int ret;
0615 
0616     if (ab->hw_params.hybrid_bus_type)
0617         return ath11k_pcic_config_irq(ab);
0618 
0619     /* Configure CE irqs */
0620     for (i = 0; i < ab->hw_params.ce_count; i++) {
0621         struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
0622 
0623         if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
0624             continue;
0625 
0626         irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
0627 
0628         tasklet_setup(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet);
0629         irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]);
0630         ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
0631                   IRQF_TRIGGER_RISING, irq_name[irq_idx],
0632                   ce_pipe);
0633         if (ret)
0634             return ret;
0635 
0636         ab->irq_num[irq_idx] = irq;
0637     }
0638 
0639     /* Configure external interrupts */
0640     ret = ath11k_ahb_config_ext_irq(ab);
0641 
0642     return ret;
0643 }
0644 
0645 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
0646                       u8 *ul_pipe, u8 *dl_pipe)
0647 {
0648     const struct service_to_pipe *entry;
0649     bool ul_set = false, dl_set = false;
0650     int i;
0651 
0652     for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) {
0653         entry = &ab->hw_params.svc_to_ce_map[i];
0654 
0655         if (__le32_to_cpu(entry->service_id) != service_id)
0656             continue;
0657 
0658         switch (__le32_to_cpu(entry->pipedir)) {
0659         case PIPEDIR_NONE:
0660             break;
0661         case PIPEDIR_IN:
0662             WARN_ON(dl_set);
0663             *dl_pipe = __le32_to_cpu(entry->pipenum);
0664             dl_set = true;
0665             break;
0666         case PIPEDIR_OUT:
0667             WARN_ON(ul_set);
0668             *ul_pipe = __le32_to_cpu(entry->pipenum);
0669             ul_set = true;
0670             break;
0671         case PIPEDIR_INOUT:
0672             WARN_ON(dl_set);
0673             WARN_ON(ul_set);
0674             *dl_pipe = __le32_to_cpu(entry->pipenum);
0675             *ul_pipe = __le32_to_cpu(entry->pipenum);
0676             dl_set = true;
0677             ul_set = true;
0678             break;
0679         }
0680     }
0681 
0682     if (WARN_ON(!ul_set || !dl_set))
0683         return -ENOENT;
0684 
0685     return 0;
0686 }
0687 
0688 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
0689     .start = ath11k_ahb_start,
0690     .stop = ath11k_ahb_stop,
0691     .read32 = ath11k_ahb_read32,
0692     .write32 = ath11k_ahb_write32,
0693     .irq_enable = ath11k_ahb_ext_irq_enable,
0694     .irq_disable = ath11k_ahb_ext_irq_disable,
0695     .map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
0696     .power_down = ath11k_ahb_power_down,
0697     .power_up = ath11k_ahb_power_up,
0698 };
0699 
0700 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
0701     .start = ath11k_pcic_start,
0702     .stop = ath11k_pcic_stop,
0703     .read32 = ath11k_pcic_read32,
0704     .write32 = ath11k_pcic_write32,
0705     .irq_enable = ath11k_pcic_ext_irq_enable,
0706     .irq_disable = ath11k_pcic_ext_irq_disable,
0707     .get_msi_address =  ath11k_pcic_get_msi_address,
0708     .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment,
0709     .map_service_to_pipe = ath11k_pcic_map_service_to_pipe,
0710     .power_down = ath11k_ahb_power_down,
0711     .power_up = ath11k_ahb_power_up,
0712 };
0713 
0714 static int ath11k_core_get_rproc(struct ath11k_base *ab)
0715 {
0716     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0717     struct device *dev = ab->dev;
0718     struct rproc *prproc;
0719     phandle rproc_phandle;
0720 
0721     if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
0722         ath11k_err(ab, "failed to get q6_rproc handle\n");
0723         return -ENOENT;
0724     }
0725 
0726     prproc = rproc_get_by_phandle(rproc_phandle);
0727     if (!prproc) {
0728         ath11k_err(ab, "failed to get rproc\n");
0729         return -EINVAL;
0730     }
0731     ab_ahb->tgt_rproc = prproc;
0732 
0733     return 0;
0734 }
0735 
0736 static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab)
0737 {
0738     struct platform_device *pdev = ab->pdev;
0739     phys_addr_t msi_addr_pa;
0740     dma_addr_t msi_addr_iova;
0741     struct resource *res;
0742     int int_prop;
0743     int ret;
0744     int i;
0745 
0746     ret = ath11k_pcic_init_msi_config(ab);
0747     if (ret) {
0748         ath11k_err(ab, "failed to init msi config: %d\n", ret);
0749         return ret;
0750     }
0751 
0752     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0753     if (!res) {
0754         ath11k_err(ab, "failed to fetch msi_addr\n");
0755         return -ENOENT;
0756     }
0757 
0758     msi_addr_pa = res->start;
0759     msi_addr_iova = dma_map_resource(ab->dev, msi_addr_pa, PAGE_SIZE,
0760                      DMA_FROM_DEVICE, 0);
0761     if (dma_mapping_error(ab->dev, msi_addr_iova))
0762         return -ENOMEM;
0763 
0764     ab->pci.msi.addr_lo = lower_32_bits(msi_addr_iova);
0765     ab->pci.msi.addr_hi = upper_32_bits(msi_addr_iova);
0766 
0767     ret = of_property_read_u32_index(ab->dev->of_node, "interrupts", 1, &int_prop);
0768     if (ret)
0769         return ret;
0770 
0771     ab->pci.msi.ep_base_data = int_prop + 32;
0772 
0773     for (i = 0; i < ab->pci.msi.config->total_vectors; i++) {
0774         res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
0775         if (!res)
0776             return -ENODEV;
0777 
0778         ab->pci.msi.irqs[i] = res->start;
0779     }
0780 
0781     set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
0782 
0783     return 0;
0784 }
0785 
0786 static int ath11k_ahb_setup_resources(struct ath11k_base *ab)
0787 {
0788     struct platform_device *pdev = ab->pdev;
0789     struct resource *mem_res;
0790     void __iomem *mem;
0791 
0792     if (ab->hw_params.hybrid_bus_type)
0793         return ath11k_ahb_setup_msi_resources(ab);
0794 
0795     mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res);
0796     if (IS_ERR(mem)) {
0797         dev_err(&pdev->dev, "ioremap error\n");
0798         return PTR_ERR(mem);
0799     }
0800 
0801     ab->mem = mem;
0802     ab->mem_len = resource_size(mem_res);
0803 
0804     return 0;
0805 }
0806 
0807 static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab)
0808 {
0809     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0810     struct device *dev = ab->dev;
0811     struct device_node *node;
0812     struct resource r;
0813     int ret;
0814 
0815     node = of_parse_phandle(dev->of_node, "memory-region", 0);
0816     if (!node)
0817         return -ENOENT;
0818 
0819     ret = of_address_to_resource(node, 0, &r);
0820     of_node_put(node);
0821     if (ret) {
0822         dev_err(dev, "failed to resolve msa fixed region\n");
0823         return ret;
0824     }
0825 
0826     ab_ahb->fw.msa_paddr = r.start;
0827     ab_ahb->fw.msa_size = resource_size(&r);
0828 
0829     node = of_parse_phandle(dev->of_node, "memory-region", 1);
0830     if (!node)
0831         return -ENOENT;
0832 
0833     ret = of_address_to_resource(node, 0, &r);
0834     of_node_put(node);
0835     if (ret) {
0836         dev_err(dev, "failed to resolve ce fixed region\n");
0837         return ret;
0838     }
0839 
0840     ab_ahb->fw.ce_paddr = r.start;
0841     ab_ahb->fw.ce_size = resource_size(&r);
0842 
0843     return 0;
0844 }
0845 
0846 static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab)
0847 {
0848     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0849     struct device *host_dev = ab->dev;
0850     struct platform_device_info info = {0};
0851     struct iommu_domain *iommu_dom;
0852     struct platform_device *pdev;
0853     struct device_node *node;
0854     int ret;
0855 
0856     /* Chipsets not requiring MSA need not initialize
0857      * MSA resources, return success in such cases.
0858      */
0859     if (!ab->hw_params.fixed_fw_mem)
0860         return 0;
0861 
0862     ret = ath11k_ahb_setup_msa_resources(ab);
0863     if (ret) {
0864         ath11k_err(ab, "failed to setup msa resources\n");
0865         return ret;
0866     }
0867 
0868     node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
0869     if (!node) {
0870         ab_ahb->fw.use_tz = true;
0871         return 0;
0872     }
0873 
0874     info.fwnode = &node->fwnode;
0875     info.parent = host_dev;
0876     info.name = node->name;
0877     info.dma_mask = DMA_BIT_MASK(32);
0878 
0879     pdev = platform_device_register_full(&info);
0880     if (IS_ERR(pdev)) {
0881         of_node_put(node);
0882         return PTR_ERR(pdev);
0883     }
0884 
0885     ret = of_dma_configure(&pdev->dev, node, true);
0886     if (ret) {
0887         ath11k_err(ab, "dma configure fail: %d\n", ret);
0888         goto err_unregister;
0889     }
0890 
0891     ab_ahb->fw.dev = &pdev->dev;
0892 
0893     iommu_dom = iommu_domain_alloc(&platform_bus_type);
0894     if (!iommu_dom) {
0895         ath11k_err(ab, "failed to allocate iommu domain\n");
0896         ret = -ENOMEM;
0897         goto err_unregister;
0898     }
0899 
0900     ret = iommu_attach_device(iommu_dom, ab_ahb->fw.dev);
0901     if (ret) {
0902         ath11k_err(ab, "could not attach device: %d\n", ret);
0903         goto err_iommu_free;
0904     }
0905 
0906     ret = iommu_map(iommu_dom, ab_ahb->fw.msa_paddr,
0907             ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size,
0908             IOMMU_READ | IOMMU_WRITE);
0909     if (ret) {
0910         ath11k_err(ab, "failed to map firmware region: %d\n", ret);
0911         goto err_iommu_detach;
0912     }
0913 
0914     ret = iommu_map(iommu_dom, ab_ahb->fw.ce_paddr,
0915             ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size,
0916             IOMMU_READ | IOMMU_WRITE);
0917     if (ret) {
0918         ath11k_err(ab, "failed to map firmware CE region: %d\n", ret);
0919         goto err_iommu_unmap;
0920     }
0921 
0922     ab_ahb->fw.use_tz = false;
0923     ab_ahb->fw.iommu_domain = iommu_dom;
0924     of_node_put(node);
0925 
0926     return 0;
0927 
0928 err_iommu_unmap:
0929     iommu_unmap(iommu_dom, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
0930 
0931 err_iommu_detach:
0932     iommu_detach_device(iommu_dom, ab_ahb->fw.dev);
0933 
0934 err_iommu_free:
0935     iommu_domain_free(iommu_dom);
0936 
0937 err_unregister:
0938     platform_device_unregister(pdev);
0939     of_node_put(node);
0940 
0941     return ret;
0942 }
0943 
0944 static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
0945 {
0946     struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
0947     struct iommu_domain *iommu;
0948     size_t unmapped_size;
0949 
0950     if (ab_ahb->fw.use_tz)
0951         return 0;
0952 
0953     iommu = ab_ahb->fw.iommu_domain;
0954 
0955     unmapped_size = iommu_unmap(iommu, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
0956     if (unmapped_size != ab_ahb->fw.msa_size)
0957         ath11k_err(ab, "failed to unmap firmware: %zu\n",
0958                unmapped_size);
0959 
0960     unmapped_size = iommu_unmap(iommu, ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size);
0961     if (unmapped_size != ab_ahb->fw.ce_size)
0962         ath11k_err(ab, "failed to unmap firmware CE memory: %zu\n",
0963                unmapped_size);
0964 
0965     iommu_detach_device(iommu, ab_ahb->fw.dev);
0966     iommu_domain_free(iommu);
0967 
0968     platform_device_unregister(to_platform_device(ab_ahb->fw.dev));
0969 
0970     return 0;
0971 }
0972 
0973 static int ath11k_ahb_probe(struct platform_device *pdev)
0974 {
0975     struct ath11k_base *ab;
0976     const struct of_device_id *of_id;
0977     const struct ath11k_hif_ops *hif_ops;
0978     const struct ath11k_pci_ops *pci_ops;
0979     enum ath11k_hw_rev hw_rev;
0980     int ret;
0981 
0982     of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev);
0983     if (!of_id) {
0984         dev_err(&pdev->dev, "failed to find matching device tree id\n");
0985         return -EINVAL;
0986     }
0987 
0988     hw_rev = (enum ath11k_hw_rev)of_id->data;
0989 
0990     switch (hw_rev) {
0991     case ATH11K_HW_IPQ8074:
0992     case ATH11K_HW_IPQ6018_HW10:
0993         hif_ops = &ath11k_ahb_hif_ops_ipq8074;
0994         pci_ops = NULL;
0995         break;
0996     case ATH11K_HW_WCN6750_HW10:
0997         hif_ops = &ath11k_ahb_hif_ops_wcn6750;
0998         pci_ops = &ath11k_ahb_pci_ops_wcn6750;
0999         break;
1000     default:
1001         dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev);
1002         return -EOPNOTSUPP;
1003     }
1004 
1005     ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1006     if (ret) {
1007         dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
1008         return ret;
1009     }
1010 
1011     ab = ath11k_core_alloc(&pdev->dev, sizeof(struct ath11k_ahb),
1012                    ATH11K_BUS_AHB);
1013     if (!ab) {
1014         dev_err(&pdev->dev, "failed to allocate ath11k base\n");
1015         return -ENOMEM;
1016     }
1017 
1018     ab->hif.ops = hif_ops;
1019     ab->pdev = pdev;
1020     ab->hw_rev = hw_rev;
1021     platform_set_drvdata(pdev, ab);
1022 
1023     ret = ath11k_pcic_register_pci_ops(ab, pci_ops);
1024     if (ret) {
1025         ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
1026         goto err_core_free;
1027     }
1028 
1029     ret = ath11k_core_pre_init(ab);
1030     if (ret)
1031         goto err_core_free;
1032 
1033     ret = ath11k_ahb_setup_resources(ab);
1034     if (ret)
1035         goto err_core_free;
1036 
1037     ret = ath11k_ahb_fw_resources_init(ab);
1038     if (ret)
1039         goto err_core_free;
1040 
1041     ret = ath11k_hal_srng_init(ab);
1042     if (ret)
1043         goto err_fw_deinit;
1044 
1045     ret = ath11k_ce_alloc_pipes(ab);
1046     if (ret) {
1047         ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
1048         goto err_hal_srng_deinit;
1049     }
1050 
1051     ath11k_ahb_init_qmi_ce_config(ab);
1052 
1053     ret = ath11k_core_get_rproc(ab);
1054     if (ret) {
1055         ath11k_err(ab, "failed to get rproc: %d\n", ret);
1056         goto err_ce_free;
1057     }
1058 
1059     ret = ath11k_core_init(ab);
1060     if (ret) {
1061         ath11k_err(ab, "failed to init core: %d\n", ret);
1062         goto err_ce_free;
1063     }
1064 
1065     ret = ath11k_ahb_config_irq(ab);
1066     if (ret) {
1067         ath11k_err(ab, "failed to configure irq: %d\n", ret);
1068         goto err_ce_free;
1069     }
1070 
1071     ath11k_ahb_fwreset_from_cold_boot(ab);
1072 
1073     return 0;
1074 
1075 err_ce_free:
1076     ath11k_ce_free_pipes(ab);
1077 
1078 err_hal_srng_deinit:
1079     ath11k_hal_srng_deinit(ab);
1080 
1081 err_fw_deinit:
1082     ath11k_ahb_fw_resource_deinit(ab);
1083 
1084 err_core_free:
1085     ath11k_core_free(ab);
1086     platform_set_drvdata(pdev, NULL);
1087 
1088     return ret;
1089 }
1090 
1091 static int ath11k_ahb_remove(struct platform_device *pdev)
1092 {
1093     struct ath11k_base *ab = platform_get_drvdata(pdev);
1094     unsigned long left;
1095 
1096     if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
1097         ath11k_ahb_power_down(ab);
1098         ath11k_debugfs_soc_destroy(ab);
1099         ath11k_qmi_deinit_service(ab);
1100         goto qmi_fail;
1101     }
1102 
1103     reinit_completion(&ab->driver_recovery);
1104 
1105     if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
1106         left = wait_for_completion_timeout(&ab->driver_recovery,
1107                            ATH11K_AHB_RECOVERY_TIMEOUT);
1108         if (!left)
1109             ath11k_warn(ab, "failed to receive recovery response completion\n");
1110     }
1111 
1112     set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
1113     cancel_work_sync(&ab->restart_work);
1114 
1115     ath11k_core_deinit(ab);
1116 qmi_fail:
1117     ath11k_ahb_free_irq(ab);
1118     ath11k_hal_srng_deinit(ab);
1119     ath11k_ahb_fw_resource_deinit(ab);
1120     ath11k_ce_free_pipes(ab);
1121     ath11k_core_free(ab);
1122     platform_set_drvdata(pdev, NULL);
1123 
1124     return 0;
1125 }
1126 
1127 static struct platform_driver ath11k_ahb_driver = {
1128     .driver         = {
1129         .name   = "ath11k",
1130         .of_match_table = ath11k_ahb_of_match,
1131     },
1132     .probe  = ath11k_ahb_probe,
1133     .remove = ath11k_ahb_remove,
1134 };
1135 
1136 static int ath11k_ahb_init(void)
1137 {
1138     return platform_driver_register(&ath11k_ahb_driver);
1139 }
1140 module_init(ath11k_ahb_init);
1141 
1142 static void ath11k_ahb_exit(void)
1143 {
1144     platform_driver_unregister(&ath11k_ahb_driver);
1145 }
1146 module_exit(ath11k_ahb_exit);
1147 
1148 MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN AHB devices");
1149 MODULE_LICENSE("Dual BSD/GPL");