Loading drivers/net/wireless/cnss2/pci.c +66 −0 Original line number Diff line number Diff line Loading @@ -1357,6 +1357,61 @@ void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv) CNSS_REASON_TIMEOUT); } struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); if (!pci_priv) return NULL; return pci_priv->smmu_mapping; } EXPORT_SYMBOL(cnss_smmu_get_mapping); int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); unsigned long iova; size_t len; int ret = 0; if (!pci_priv) return -ENODEV; if (!iova_addr) { cnss_pr_err("iova_addr is NULL, paddr %pa, size %zu\n", &paddr, size); return -EINVAL; } len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE); iova = roundup(pci_priv->smmu_iova_ipa_start, PAGE_SIZE); if (iova >= (pci_priv->smmu_iova_ipa_start + pci_priv->smmu_iova_ipa_len)) { cnss_pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n", iova, &pci_priv->smmu_iova_ipa_start, pci_priv->smmu_iova_ipa_len); return -ENOMEM; } ret = iommu_map(pci_priv->smmu_mapping->domain, iova, rounddown(paddr, PAGE_SIZE), len, IOMMU_READ | IOMMU_WRITE); if (ret) { cnss_pr_err("PA to IOVA mapping failed, ret %d\n", ret); return ret; } pci_priv->smmu_iova_ipa_start = iova + len; *iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE)); return 0; } EXPORT_SYMBOL(cnss_smmu_map); int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); Loading Loading @@ -2150,6 +2205,17 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, &pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM, "smmu_iova_ipa"); if (res) { pci_priv->smmu_iova_ipa_start = res->start; pci_priv->smmu_iova_ipa_len = resource_size(res); cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: %zu\n", &pci_priv->smmu_iova_ipa_start, pci_priv->smmu_iova_ipa_len); } ret = cnss_pci_init_smmu(pci_priv); if (ret) { cnss_pr_err("Failed to init SMMU, err = %d\n", ret); Loading drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ struct cnss_pci_data { bool smmu_s1_enable; dma_addr_t smmu_iova_start; size_t smmu_iova_len; dma_addr_t smmu_iova_ipa_start; size_t smmu_iova_ipa_len; void __iomem *bar; struct cnss_msi_config *msi_config; u32 msi_ep_base_data; Loading include/net/cnss2.h +3 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,9 @@ extern int cnss_get_fw_files_for_target(struct device *dev, u32 target_type, u32 target_version); extern int cnss_get_platform_cap(struct device *dev, struct cnss_platform_cap *cap); extern struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev); extern int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size); extern int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info); extern int cnss_request_bus_bandwidth(struct device *dev, int bandwidth); extern int cnss_power_up(struct device *dev); Loading Loading
drivers/net/wireless/cnss2/pci.c +66 −0 Original line number Diff line number Diff line Loading @@ -1357,6 +1357,61 @@ void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv) CNSS_REASON_TIMEOUT); } struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); if (!pci_priv) return NULL; return pci_priv->smmu_mapping; } EXPORT_SYMBOL(cnss_smmu_get_mapping); int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); unsigned long iova; size_t len; int ret = 0; if (!pci_priv) return -ENODEV; if (!iova_addr) { cnss_pr_err("iova_addr is NULL, paddr %pa, size %zu\n", &paddr, size); return -EINVAL; } len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE); iova = roundup(pci_priv->smmu_iova_ipa_start, PAGE_SIZE); if (iova >= (pci_priv->smmu_iova_ipa_start + pci_priv->smmu_iova_ipa_len)) { cnss_pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n", iova, &pci_priv->smmu_iova_ipa_start, pci_priv->smmu_iova_ipa_len); return -ENOMEM; } ret = iommu_map(pci_priv->smmu_mapping->domain, iova, rounddown(paddr, PAGE_SIZE), len, IOMMU_READ | IOMMU_WRITE); if (ret) { cnss_pr_err("PA to IOVA mapping failed, ret %d\n", ret); return ret; } pci_priv->smmu_iova_ipa_start = iova + len; *iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE)); return 0; } EXPORT_SYMBOL(cnss_smmu_map); int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info) { struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev)); Loading Loading @@ -2150,6 +2205,17 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, &pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM, "smmu_iova_ipa"); if (res) { pci_priv->smmu_iova_ipa_start = res->start; pci_priv->smmu_iova_ipa_len = resource_size(res); cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: %zu\n", &pci_priv->smmu_iova_ipa_start, pci_priv->smmu_iova_ipa_len); } ret = cnss_pci_init_smmu(pci_priv); if (ret) { cnss_pr_err("Failed to init SMMU, err = %d\n", ret); Loading
drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ struct cnss_pci_data { bool smmu_s1_enable; dma_addr_t smmu_iova_start; size_t smmu_iova_len; dma_addr_t smmu_iova_ipa_start; size_t smmu_iova_ipa_len; void __iomem *bar; struct cnss_msi_config *msi_config; u32 msi_ep_base_data; Loading
include/net/cnss2.h +3 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,9 @@ extern int cnss_get_fw_files_for_target(struct device *dev, u32 target_type, u32 target_version); extern int cnss_get_platform_cap(struct device *dev, struct cnss_platform_cap *cap); extern struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev); extern int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size); extern int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info); extern int cnss_request_bus_bandwidth(struct device *dev, int bandwidth); extern int cnss_power_up(struct device *dev); Loading