Loading drivers/firmware/qcom_scm-32.c +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2010,2015,2020 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -579,6 +579,13 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) return ret ? : le32_to_cpu(scm_ret); } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz) { return -ENODEV; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { Loading drivers/firmware/qcom_scm-64.c +28 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -382,6 +382,33 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) return ret ? : res.a1; } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz) { int ret; struct qcom_scm_desc desc = {0}; struct arm_smccc_res res; desc.args[0] = mem_region; desc.args[1] = mem_sz; desc.args[2] = src; desc.args[3] = src_sz; desc.args[4] = dest; desc.args[5] = dest_sz; desc.args[6] = 0; desc.arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_MEM_PROT_ASSIGN_ID, &desc, &res); return ret ? : res.a1; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { struct qcom_scm_desc desc = {0}; Loading drivers/firmware/qcom_scm.c +96 −1 Original line number Diff line number Diff line /* * Qualcomm SCM driver * * Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. * Copyright (c) 2010,2015,2020 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -40,6 +40,19 @@ struct qcom_scm { struct reset_controller_dev reset; }; struct qcom_scm_current_perm_info { __le32 vmid; __le32 perm; __le64 ctx; __le32 ctx_size; __le32 unused; }; struct qcom_scm_mem_map_info { __le64 mem_addr; __le64 mem_size; }; static struct qcom_scm *__scm; static int qcom_scm_clk_enable(void) Loading Loading @@ -348,6 +361,88 @@ int qcom_scm_set_remote_state(u32 state, u32 id) } EXPORT_SYMBOL(qcom_scm_set_remote_state); /** * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership * @mem_addr: mem region whose ownership need to be reassigned * @mem_sz: size of the region. * @srcvm: vmid for current set of owners, each set bit in * flag indicate a unique owner * @newvm: array having new owners and corrsponding permission * flags * @dest_cnt: number of owners in next set. * * Return negative errno on failure, 0 on success, with @srcvm updated. */ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *srcvm, struct qcom_scm_vmperm *newvm, int dest_cnt) { struct qcom_scm_current_perm_info *destvm; struct qcom_scm_mem_map_info *mem_to_map; phys_addr_t mem_to_map_phys; phys_addr_t dest_phys; phys_addr_t ptr_phys; size_t mem_to_map_sz; size_t dest_sz; size_t src_sz; size_t ptr_sz; int next_vm; __le32 *src; void *ptr; int ret; int len; int i; src_sz = hweight_long(*srcvm) * sizeof(*src); mem_to_map_sz = sizeof(*mem_to_map); dest_sz = dest_cnt * sizeof(*destvm); ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(dest_sz, SZ_64); ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL); if (!ptr) return -ENOMEM; /* Fill source vmid detail */ src = ptr; len = hweight_long(*srcvm); for (i = 0; i < len; i++) { src[i] = cpu_to_le32(ffs(*srcvm) - 1); *srcvm ^= 1 << (ffs(*srcvm) - 1); } /* Fill details of mem buff to map */ mem_to_map = ptr + ALIGN(src_sz, SZ_64); mem_to_map_phys = ptr_phys + ALIGN(src_sz, SZ_64); mem_to_map[0].mem_addr = cpu_to_le64(mem_addr); mem_to_map[0].mem_size = cpu_to_le64(mem_sz); next_vm = 0; /* Fill details of next vmid detail */ destvm = ptr + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); dest_phys = ptr_phys + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); for (i = 0; i < dest_cnt; i++) { destvm[i].vmid = cpu_to_le32(newvm[i].vmid); destvm[i].perm = cpu_to_le32(newvm[i].perm); destvm[i].ctx = 0; destvm[i].ctx_size = 0; next_vm |= BIT(newvm[i].vmid); } ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, ptr_phys, src_sz, dest_phys, dest_sz); dma_free_coherent(__scm->dev, ALIGN(ptr_sz, SZ_64), ptr, ptr_phys); if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d.\n", ret); return -EINVAL; } *srcvm = next_vm; return 0; } EXPORT_SYMBOL(qcom_scm_assign_mem); static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; Loading drivers/firmware/qcom_scm.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2015,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -95,5 +95,10 @@ extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size); extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare); #define QCOM_MEM_PROT_ASSIGN_ID 0x16 extern int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz); #endif drivers/net/wireless/ath/ath10k/debug.c +14 −7 Original line number Diff line number Diff line Loading @@ -1708,7 +1708,9 @@ int ath10k_debug_start(struct ath10k *ar) ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); } if (ar->debug.nf_cal_period) { if (ar->debug.nf_cal_period && !test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) { ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period, ar->debug.nf_cal_period); Loading @@ -1725,6 +1727,8 @@ void ath10k_debug_stop(struct ath10k *ar) { lockdep_assert_held(&ar->conf_mutex); if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) ath10k_debug_cal_data_fetch(ar); /* Must not use _sync to avoid deadlock, we do that in Loading Loading @@ -2217,14 +2221,17 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar, &fops_fw_dbglog); if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) { debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar, &fops_cal_data); debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar, &fops_ani_enable); debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar, &fops_nf_cal_period); } debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar, &fops_ani_enable); if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) { debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy, Loading Loading
drivers/firmware/qcom_scm-32.c +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2010,2015,2020 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -579,6 +579,13 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) return ret ? : le32_to_cpu(scm_ret); } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz) { return -ENODEV; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { Loading
drivers/firmware/qcom_scm-64.c +28 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -382,6 +382,33 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) return ret ? : res.a1; } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz) { int ret; struct qcom_scm_desc desc = {0}; struct arm_smccc_res res; desc.args[0] = mem_region; desc.args[1] = mem_sz; desc.args[2] = src; desc.args[3] = src_sz; desc.args[4] = dest; desc.args[5] = dest_sz; desc.args[6] = 0; desc.arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_MEM_PROT_ASSIGN_ID, &desc, &res); return ret ? : res.a1; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { struct qcom_scm_desc desc = {0}; Loading
drivers/firmware/qcom_scm.c +96 −1 Original line number Diff line number Diff line /* * Qualcomm SCM driver * * Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. * Copyright (c) 2010,2015,2020 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -40,6 +40,19 @@ struct qcom_scm { struct reset_controller_dev reset; }; struct qcom_scm_current_perm_info { __le32 vmid; __le32 perm; __le64 ctx; __le32 ctx_size; __le32 unused; }; struct qcom_scm_mem_map_info { __le64 mem_addr; __le64 mem_size; }; static struct qcom_scm *__scm; static int qcom_scm_clk_enable(void) Loading Loading @@ -348,6 +361,88 @@ int qcom_scm_set_remote_state(u32 state, u32 id) } EXPORT_SYMBOL(qcom_scm_set_remote_state); /** * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership * @mem_addr: mem region whose ownership need to be reassigned * @mem_sz: size of the region. * @srcvm: vmid for current set of owners, each set bit in * flag indicate a unique owner * @newvm: array having new owners and corrsponding permission * flags * @dest_cnt: number of owners in next set. * * Return negative errno on failure, 0 on success, with @srcvm updated. */ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *srcvm, struct qcom_scm_vmperm *newvm, int dest_cnt) { struct qcom_scm_current_perm_info *destvm; struct qcom_scm_mem_map_info *mem_to_map; phys_addr_t mem_to_map_phys; phys_addr_t dest_phys; phys_addr_t ptr_phys; size_t mem_to_map_sz; size_t dest_sz; size_t src_sz; size_t ptr_sz; int next_vm; __le32 *src; void *ptr; int ret; int len; int i; src_sz = hweight_long(*srcvm) * sizeof(*src); mem_to_map_sz = sizeof(*mem_to_map); dest_sz = dest_cnt * sizeof(*destvm); ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(dest_sz, SZ_64); ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL); if (!ptr) return -ENOMEM; /* Fill source vmid detail */ src = ptr; len = hweight_long(*srcvm); for (i = 0; i < len; i++) { src[i] = cpu_to_le32(ffs(*srcvm) - 1); *srcvm ^= 1 << (ffs(*srcvm) - 1); } /* Fill details of mem buff to map */ mem_to_map = ptr + ALIGN(src_sz, SZ_64); mem_to_map_phys = ptr_phys + ALIGN(src_sz, SZ_64); mem_to_map[0].mem_addr = cpu_to_le64(mem_addr); mem_to_map[0].mem_size = cpu_to_le64(mem_sz); next_vm = 0; /* Fill details of next vmid detail */ destvm = ptr + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); dest_phys = ptr_phys + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64); for (i = 0; i < dest_cnt; i++) { destvm[i].vmid = cpu_to_le32(newvm[i].vmid); destvm[i].perm = cpu_to_le32(newvm[i].perm); destvm[i].ctx = 0; destvm[i].ctx_size = 0; next_vm |= BIT(newvm[i].vmid); } ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, ptr_phys, src_sz, dest_phys, dest_sz); dma_free_coherent(__scm->dev, ALIGN(ptr_sz, SZ_64), ptr, ptr_phys); if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d.\n", ret); return -EINVAL; } *srcvm = next_vm; return 0; } EXPORT_SYMBOL(qcom_scm_assign_mem); static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; Loading
drivers/firmware/qcom_scm.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2015,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -95,5 +95,10 @@ extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size); extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare); #define QCOM_MEM_PROT_ASSIGN_ID 0x16 extern int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz); #endif
drivers/net/wireless/ath/ath10k/debug.c +14 −7 Original line number Diff line number Diff line Loading @@ -1708,7 +1708,9 @@ int ath10k_debug_start(struct ath10k *ar) ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); } if (ar->debug.nf_cal_period) { if (ar->debug.nf_cal_period && !test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) { ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period, ar->debug.nf_cal_period); Loading @@ -1725,6 +1727,8 @@ void ath10k_debug_stop(struct ath10k *ar) { lockdep_assert_held(&ar->conf_mutex); if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) ath10k_debug_cal_data_fetch(ar); /* Must not use _sync to avoid deadlock, we do that in Loading Loading @@ -2217,14 +2221,17 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar, &fops_fw_dbglog); if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, ar->normal_mode_fw.fw_file.fw_features)) { debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar, &fops_cal_data); debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar, &fops_ani_enable); debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar, &fops_nf_cal_period); } debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar, &fops_ani_enable); if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) { debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy, Loading