Loading arch/arm64/boot/dts/qcom/kona.dtsi +12 −4 Original line number Diff line number Diff line Loading @@ -3247,9 +3247,8 @@ qcom,cnss-qca6390@a0000000 { compatible = "qcom,cnss-qca6390"; reg = <0xa0000000 0x10000000>, <0xb0000000 0x10000>; reg-names = "smmu_iova_base", "smmu_iova_ipa"; reg = <0xb0000000 0x10000>; reg-names = "smmu_iova_ipa"; wlan-en-gpio = <&tlmm 20 0>; pinctrl-names = "wlan_en_active", "wlan_en_sleep"; pinctrl-0 = <&cnss_wlan_en_active>; Loading Loading @@ -3375,7 +3374,16 @@ cnss_pci: cnss_pci { reg = <0 0 0 0 0>; qcom,iommu-dma = "disabled"; qcom,iommu-group = <&cnss_pci_iommu_group>; #address-cells = <1>; #size-cells = <1>; cnss_pci_iommu_group: cnss_pci_iommu_group { qcom,iommu-dma-addr-pool = <0xa0000000 0x10000000>; qcom,iommu-dma = "fastmap"; qcom,iommu-pagetable = "coherent"; }; }; }; Loading drivers/net/wireless/cnss2/pci.c +50 −117 Original line number Diff line number Diff line Loading @@ -934,99 +934,6 @@ int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) return 0; } static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv) { int ret = 0; struct device *dev; struct dma_iommu_mapping *mapping; int atomic_ctx = 1, s1_bypass = 1, fast = 1, cb_stall_disable = 1, no_cfre = 1; cnss_pr_dbg("Initializing SMMU\n"); dev = &pci_priv->pci_dev->dev; mapping = __depr_arm_iommu_create_mapping(dev->bus, pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); if (IS_ERR(mapping)) { ret = PTR_ERR(mapping); cnss_pr_err("Failed to create SMMU mapping, err = %d\n", ret); goto out; } if (pci_priv->smmu_s1_enable) { cnss_pr_dbg("Enabling SMMU S1 stage\n"); ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_ATOMIC, &atomic_ctx); if (ret) { pr_err("Failed to set SMMU atomic_ctx attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_FAST, &fast); if (ret) { pr_err("Failed to set SMMU fast attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_CB_STALL_DISABLE, &cb_stall_disable); if (ret) { pr_err("Failed to set SMMU cb_stall_disable attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_NO_CFRE, &no_cfre); if (ret) { pr_err("Failed to set SMMU no_cfre attribute, err = %d\n", ret); goto release_mapping; } } else { ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (ret) { pr_err("Failed to set SMMU s1_bypass attribute, err = %d\n", ret); goto release_mapping; } } ret = __depr_arm_iommu_attach_device(dev, mapping); if (ret) { pr_err("Failed to attach SMMU device, err = %d\n", ret); goto release_mapping; } pci_priv->smmu_mapping = mapping; return ret; release_mapping: __depr_arm_iommu_release_mapping(mapping); out: return ret; } static void cnss_pci_deinit_smmu(struct cnss_pci_data *pci_priv) { __depr_arm_iommu_detach_device(&pci_priv->pci_dev->dev); __depr_arm_iommu_release_mapping(pci_priv->smmu_mapping); pci_priv->smmu_mapping = NULL; } static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { unsigned long flags; Loading Loading @@ -1709,10 +1616,21 @@ struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev) if (!pci_priv) return NULL; return pci_priv->smmu_mapping; return &pci_priv->smmu_mapping; } EXPORT_SYMBOL(cnss_smmu_get_mapping); struct iommu_domain *cnss_smmu_get_domain(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->iommu_domain; } EXPORT_SYMBOL(cnss_smmu_get_domain); int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size) { Loading Loading @@ -1742,7 +1660,7 @@ int cnss_smmu_map(struct device *dev, return -ENOMEM; } ret = iommu_map(pci_priv->smmu_mapping->domain, iova, ret = iommu_map(pci_priv->iommu_domain, iova, rounddown(paddr, PAGE_SIZE), len, IOMMU_READ | IOMMU_WRITE); if (ret) { Loading Loading @@ -2615,6 +2533,9 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, struct cnss_pci_data *pci_priv; struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL); struct resource *res; struct device_node *of_node; const char *iommu_dma_type; u32 addr_win[2]; cnss_pr_dbg("PCI is probing, vendor ID: 0x%x, device ID: 0x%x\n", id->vendor, pci_dev->device); Loading Loading @@ -2645,16 +2566,34 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, if (ret) goto unregister_subsys; res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM, "smmu_iova_base"); if (res) { if (of_property_read_bool(plat_priv->plat_dev->dev.of_node, "qcom,smmu-s1-enable")) of_node = of_parse_phandle(pci_priv->pci_dev->dev.of_node, "qcom,iommu-group", 0); if (of_node) { pci_priv->iommu_domain = iommu_get_domain_for_dev(&pci_dev->dev); pci_priv->smmu_mapping.domain = pci_priv->iommu_domain; ret = of_property_read_string(of_node, "qcom,iommu-dma", &iommu_dma_type); if (!ret) { if (!strcmp("fastmap", iommu_dma_type)) { cnss_pr_dbg("Enabling SMMU S1 stage\n"); pci_priv->smmu_s1_enable = true; } } pci_priv->smmu_iova_start = res->start; pci_priv->smmu_iova_len = resource_size(res); cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: %zu\n", ret = of_property_read_u32_array(of_node, "qcom,iommu-dma-addr-pool", addr_win, ARRAY_SIZE(addr_win)); if (ret) { cnss_pr_err("Invalid smmu size window, ret %d\n", ret); of_node_put(of_node); goto unregister_ramdump; } pci_priv->smmu_iova_start = addr_win[0]; pci_priv->smmu_iova_len = addr_win[1]; cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: 0x%zx\n", &pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); Loading @@ -2664,22 +2603,17 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, 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", cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: 0x%zx\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); goto unregister_ramdump; } of_node_put(of_node); } ret = cnss_reg_pci_event(pci_priv); if (ret) { cnss_pr_err("Failed to register PCI event, err = %d\n", ret); goto deinit_smmu; goto unregister_ramdump; } ret = cnss_pci_enable_bus(pci_priv); Loading Loading @@ -2733,10 +2667,9 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_disable_bus(pci_priv); dereg_pci_event: cnss_dereg_pci_event(pci_priv); deinit_smmu: if (pci_priv->smmu_mapping) cnss_pci_deinit_smmu(pci_priv); unregister_ramdump: pci_priv->iommu_domain = NULL; pci_priv->smmu_mapping.domain = NULL; cnss_unregister_ramdump(plat_priv); unregister_subsys: cnss_unregister_subsys(plat_priv); Loading Loading @@ -2770,8 +2703,8 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) cnss_pci_disable_bus(pci_priv); cnss_dereg_pci_event(pci_priv); if (pci_priv->smmu_mapping) cnss_pci_deinit_smmu(pci_priv); pci_priv->iommu_domain = NULL; pci_priv->smmu_mapping.domain = NULL; cnss_unregister_ramdump(plat_priv); cnss_unregister_subsys(plat_priv); plat_priv->bus_priv = NULL; Loading drivers/net/wireless/cnss2/pci.h +2 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ struct cnss_pci_data { struct msm_pcie_register_event msm_pci_event; atomic_t auto_suspended; u8 monitor_wake_intr; struct dma_iommu_mapping *smmu_mapping; struct dma_iommu_mapping smmu_mapping; struct iommu_domain *iommu_domain; u8 smmu_s1_enable; dma_addr_t smmu_iova_start; size_t smmu_iova_len; Loading include/net/cnss2.h +1 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ extern int cnss_get_fw_files_for_target(struct device *dev, 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 struct iommu_domain *cnss_smmu_get_domain(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); Loading Loading
arch/arm64/boot/dts/qcom/kona.dtsi +12 −4 Original line number Diff line number Diff line Loading @@ -3247,9 +3247,8 @@ qcom,cnss-qca6390@a0000000 { compatible = "qcom,cnss-qca6390"; reg = <0xa0000000 0x10000000>, <0xb0000000 0x10000>; reg-names = "smmu_iova_base", "smmu_iova_ipa"; reg = <0xb0000000 0x10000>; reg-names = "smmu_iova_ipa"; wlan-en-gpio = <&tlmm 20 0>; pinctrl-names = "wlan_en_active", "wlan_en_sleep"; pinctrl-0 = <&cnss_wlan_en_active>; Loading Loading @@ -3375,7 +3374,16 @@ cnss_pci: cnss_pci { reg = <0 0 0 0 0>; qcom,iommu-dma = "disabled"; qcom,iommu-group = <&cnss_pci_iommu_group>; #address-cells = <1>; #size-cells = <1>; cnss_pci_iommu_group: cnss_pci_iommu_group { qcom,iommu-dma-addr-pool = <0xa0000000 0x10000000>; qcom,iommu-dma = "fastmap"; qcom,iommu-pagetable = "coherent"; }; }; }; Loading
drivers/net/wireless/cnss2/pci.c +50 −117 Original line number Diff line number Diff line Loading @@ -934,99 +934,6 @@ int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) return 0; } static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv) { int ret = 0; struct device *dev; struct dma_iommu_mapping *mapping; int atomic_ctx = 1, s1_bypass = 1, fast = 1, cb_stall_disable = 1, no_cfre = 1; cnss_pr_dbg("Initializing SMMU\n"); dev = &pci_priv->pci_dev->dev; mapping = __depr_arm_iommu_create_mapping(dev->bus, pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); if (IS_ERR(mapping)) { ret = PTR_ERR(mapping); cnss_pr_err("Failed to create SMMU mapping, err = %d\n", ret); goto out; } if (pci_priv->smmu_s1_enable) { cnss_pr_dbg("Enabling SMMU S1 stage\n"); ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_ATOMIC, &atomic_ctx); if (ret) { pr_err("Failed to set SMMU atomic_ctx attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_FAST, &fast); if (ret) { pr_err("Failed to set SMMU fast attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_CB_STALL_DISABLE, &cb_stall_disable); if (ret) { pr_err("Failed to set SMMU cb_stall_disable attribute, err = %d\n", ret); goto release_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_NO_CFRE, &no_cfre); if (ret) { pr_err("Failed to set SMMU no_cfre attribute, err = %d\n", ret); goto release_mapping; } } else { ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (ret) { pr_err("Failed to set SMMU s1_bypass attribute, err = %d\n", ret); goto release_mapping; } } ret = __depr_arm_iommu_attach_device(dev, mapping); if (ret) { pr_err("Failed to attach SMMU device, err = %d\n", ret); goto release_mapping; } pci_priv->smmu_mapping = mapping; return ret; release_mapping: __depr_arm_iommu_release_mapping(mapping); out: return ret; } static void cnss_pci_deinit_smmu(struct cnss_pci_data *pci_priv) { __depr_arm_iommu_detach_device(&pci_priv->pci_dev->dev); __depr_arm_iommu_release_mapping(pci_priv->smmu_mapping); pci_priv->smmu_mapping = NULL; } static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { unsigned long flags; Loading Loading @@ -1709,10 +1616,21 @@ struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev) if (!pci_priv) return NULL; return pci_priv->smmu_mapping; return &pci_priv->smmu_mapping; } EXPORT_SYMBOL(cnss_smmu_get_mapping); struct iommu_domain *cnss_smmu_get_domain(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->iommu_domain; } EXPORT_SYMBOL(cnss_smmu_get_domain); int cnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size) { Loading Loading @@ -1742,7 +1660,7 @@ int cnss_smmu_map(struct device *dev, return -ENOMEM; } ret = iommu_map(pci_priv->smmu_mapping->domain, iova, ret = iommu_map(pci_priv->iommu_domain, iova, rounddown(paddr, PAGE_SIZE), len, IOMMU_READ | IOMMU_WRITE); if (ret) { Loading Loading @@ -2615,6 +2533,9 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, struct cnss_pci_data *pci_priv; struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL); struct resource *res; struct device_node *of_node; const char *iommu_dma_type; u32 addr_win[2]; cnss_pr_dbg("PCI is probing, vendor ID: 0x%x, device ID: 0x%x\n", id->vendor, pci_dev->device); Loading Loading @@ -2645,16 +2566,34 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, if (ret) goto unregister_subsys; res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM, "smmu_iova_base"); if (res) { if (of_property_read_bool(plat_priv->plat_dev->dev.of_node, "qcom,smmu-s1-enable")) of_node = of_parse_phandle(pci_priv->pci_dev->dev.of_node, "qcom,iommu-group", 0); if (of_node) { pci_priv->iommu_domain = iommu_get_domain_for_dev(&pci_dev->dev); pci_priv->smmu_mapping.domain = pci_priv->iommu_domain; ret = of_property_read_string(of_node, "qcom,iommu-dma", &iommu_dma_type); if (!ret) { if (!strcmp("fastmap", iommu_dma_type)) { cnss_pr_dbg("Enabling SMMU S1 stage\n"); pci_priv->smmu_s1_enable = true; } } pci_priv->smmu_iova_start = res->start; pci_priv->smmu_iova_len = resource_size(res); cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: %zu\n", ret = of_property_read_u32_array(of_node, "qcom,iommu-dma-addr-pool", addr_win, ARRAY_SIZE(addr_win)); if (ret) { cnss_pr_err("Invalid smmu size window, ret %d\n", ret); of_node_put(of_node); goto unregister_ramdump; } pci_priv->smmu_iova_start = addr_win[0]; pci_priv->smmu_iova_len = addr_win[1]; cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: 0x%zx\n", &pci_priv->smmu_iova_start, pci_priv->smmu_iova_len); Loading @@ -2664,22 +2603,17 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, 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", cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: 0x%zx\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); goto unregister_ramdump; } of_node_put(of_node); } ret = cnss_reg_pci_event(pci_priv); if (ret) { cnss_pr_err("Failed to register PCI event, err = %d\n", ret); goto deinit_smmu; goto unregister_ramdump; } ret = cnss_pci_enable_bus(pci_priv); Loading Loading @@ -2733,10 +2667,9 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_disable_bus(pci_priv); dereg_pci_event: cnss_dereg_pci_event(pci_priv); deinit_smmu: if (pci_priv->smmu_mapping) cnss_pci_deinit_smmu(pci_priv); unregister_ramdump: pci_priv->iommu_domain = NULL; pci_priv->smmu_mapping.domain = NULL; cnss_unregister_ramdump(plat_priv); unregister_subsys: cnss_unregister_subsys(plat_priv); Loading Loading @@ -2770,8 +2703,8 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) cnss_pci_disable_bus(pci_priv); cnss_dereg_pci_event(pci_priv); if (pci_priv->smmu_mapping) cnss_pci_deinit_smmu(pci_priv); pci_priv->iommu_domain = NULL; pci_priv->smmu_mapping.domain = NULL; cnss_unregister_ramdump(plat_priv); cnss_unregister_subsys(plat_priv); plat_priv->bus_priv = NULL; Loading
drivers/net/wireless/cnss2/pci.h +2 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ struct cnss_pci_data { struct msm_pcie_register_event msm_pci_event; atomic_t auto_suspended; u8 monitor_wake_intr; struct dma_iommu_mapping *smmu_mapping; struct dma_iommu_mapping smmu_mapping; struct iommu_domain *iommu_domain; u8 smmu_s1_enable; dma_addr_t smmu_iova_start; size_t smmu_iova_len; Loading
include/net/cnss2.h +1 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ extern int cnss_get_fw_files_for_target(struct device *dev, 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 struct iommu_domain *cnss_smmu_get_domain(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); Loading