Loading drivers/net/wireless/cnss/cnss_pci.c +56 −6 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ static DEFINE_SPINLOCK(pci_link_down_lock); #define FW_IMAGE_MISSION (0x02) #define FW_IMAGE_BDATA (0x03) #define FW_IMAGE_PRINT (0x04) #define FW_SETUP_DELAY 2000 #define SEG_METADATA (0x01) #define SEG_NON_PAGED (0x02) Loading Loading @@ -244,7 +245,7 @@ static struct cnss_data { struct pci_saved_state *saved_state; u16 revision_id; bool recovery_in_progress; bool fw_available; atomic_t fw_available; struct codeswap_codeseg_info *cnss_seg_info; /* Virtual Address of the DMA page */ void *codeseg_cpuaddr[CODESWAP_MAX_CODESEGS]; Loading Loading @@ -273,6 +274,10 @@ static struct cnss_data { u32 fw_dma_size; u32 fw_seg_count; struct segment_memory fw_seg_mem[MAX_NUM_OF_SEGMENTS]; atomic_t fw_store_in_progress; /* Firmware setup complete lock */ struct mutex fw_setup_stat_lock; struct completion fw_setup_complete; void *bdata_cpu; dma_addr_t bdata_dma; u32 bdata_dma_size; Loading Loading @@ -1369,10 +1374,21 @@ int cnss_get_fw_image(struct image_desc_info *image_desc_info) !penv->fw_seg_count || !penv->bdata_seg_count) return -EINVAL; /* Check for firmware setup trigger by usersapce is in progress * and wait for complition of firmware setup. */ if (atomic_read(&penv->fw_store_in_progress)) { wait_for_completion_timeout(&penv->fw_setup_complete, msecs_to_jiffies(FW_SETUP_DELAY)); } mutex_lock(&penv->fw_setup_stat_lock); image_desc_info->fw_addr = penv->fw_dma; image_desc_info->fw_size = penv->fw_dma_size; image_desc_info->bdata_addr = penv->bdata_dma; image_desc_info->bdata_size = penv->bdata_dma_size; mutex_unlock(&penv->fw_setup_stat_lock); return 0; } Loading Loading @@ -1552,7 +1568,7 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, penv->pdev = pdev; penv->id = id; penv->fw_available = false; atomic_set(&penv->fw_available, 0); penv->device_id = pdev->device; if (penv->smmu_iova_len) { Loading Loading @@ -1858,8 +1874,19 @@ static ssize_t fw_image_setup_store(struct device *dev, if (!penv) return -ENODEV; if (sscanf(buf, "%d", &val) != 1) if (atomic_read(&penv->fw_store_in_progress)) { pr_info("%s: Firmware setup in progress\n", __func__); return 0; } atomic_set(&penv->fw_store_in_progress, 1); init_completion(&penv->fw_setup_complete); if (kstrtoint(buf, 0, &val)) { atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return -EINVAL; } if (val == FW_IMAGE_FTM || val == FW_IMAGE_MISSION || val == FW_IMAGE_BDATA) { Loading @@ -1868,6 +1895,8 @@ static ssize_t fw_image_setup_store(struct device *dev, if (ret != 0) { pr_err("%s: Invalid parsing of FW image files %d", __func__, ret); atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return -EINVAL; } penv->fw_image_setup = val; Loading @@ -1877,6 +1906,9 @@ static ssize_t fw_image_setup_store(struct device *dev, penv->bmi_test = val; } atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return count; } Loading Loading @@ -1979,7 +2011,7 @@ int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg) swap_seg = NULL; return -ENOENT; } if (!penv->fw_available) { if (!atomic_read(&penv->fw_available)) { pr_debug("%s: fw is not available\n", __func__); return -ENOENT; } Loading @@ -2003,6 +2035,16 @@ static void cnss_wlan_memory_expansion(void) u_int32_t total_length = 0; struct pci_dev *pdev; /* Check for firmware setup trigger by usersapce is in progress * and wait for complition of firmware setup. */ if (atomic_read(&penv->fw_store_in_progress)) { wait_for_completion_timeout(&penv->fw_setup_complete, msecs_to_jiffies(FW_SETUP_DELAY)); } mutex_lock(&penv->fw_setup_stat_lock); filename = cnss_wlan_get_evicted_data_file(); pdev = penv->pdev; dev = &pdev->dev; Loading @@ -2010,21 +2052,25 @@ static void cnss_wlan_memory_expansion(void) if (!cnss_seg_info) { pr_debug("cnss: cnss_seg_info is NULL\n"); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (penv->fw_available) { if (atomic_read(&penv->fw_available)) { pr_debug("cnss: fw code already copied to host memory\n"); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (request_firmware(&fw_entry, filename, dev) != 0) { pr_debug("cnss: failed to get fw: %s\n", filename); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (!fw_entry || !fw_entry->data) { pr_err("%s: INVALID FW entries\n", __func__); mutex_unlock(&penv->fw_setup_stat_lock); goto release_fw; } Loading Loading @@ -2059,7 +2105,9 @@ static void cnss_wlan_memory_expansion(void) } pr_debug("cnss: total_bytes copied: %d\n", total_length); cnss_seg_info->codeseg_total_bytes = total_length; penv->fw_available = 1; atomic_set(&penv->fw_available, 1); mutex_unlock(&penv->fw_setup_stat_lock); release_fw: release_firmware(fw_entry); Loading Loading @@ -2968,6 +3016,8 @@ skip_ramdump: memset(phys_to_virt(0), 0, SZ_4K); #endif atomic_set(&penv->fw_store_in_progress, 0); mutex_init(&penv->fw_setup_stat_lock); ret = device_create_file(dev, &dev_attr_fw_image_setup); if (ret) { pr_err("cnss: fw_image_setup sys file creation failed\n"); Loading Loading
drivers/net/wireless/cnss/cnss_pci.c +56 −6 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ static DEFINE_SPINLOCK(pci_link_down_lock); #define FW_IMAGE_MISSION (0x02) #define FW_IMAGE_BDATA (0x03) #define FW_IMAGE_PRINT (0x04) #define FW_SETUP_DELAY 2000 #define SEG_METADATA (0x01) #define SEG_NON_PAGED (0x02) Loading Loading @@ -244,7 +245,7 @@ static struct cnss_data { struct pci_saved_state *saved_state; u16 revision_id; bool recovery_in_progress; bool fw_available; atomic_t fw_available; struct codeswap_codeseg_info *cnss_seg_info; /* Virtual Address of the DMA page */ void *codeseg_cpuaddr[CODESWAP_MAX_CODESEGS]; Loading Loading @@ -273,6 +274,10 @@ static struct cnss_data { u32 fw_dma_size; u32 fw_seg_count; struct segment_memory fw_seg_mem[MAX_NUM_OF_SEGMENTS]; atomic_t fw_store_in_progress; /* Firmware setup complete lock */ struct mutex fw_setup_stat_lock; struct completion fw_setup_complete; void *bdata_cpu; dma_addr_t bdata_dma; u32 bdata_dma_size; Loading Loading @@ -1369,10 +1374,21 @@ int cnss_get_fw_image(struct image_desc_info *image_desc_info) !penv->fw_seg_count || !penv->bdata_seg_count) return -EINVAL; /* Check for firmware setup trigger by usersapce is in progress * and wait for complition of firmware setup. */ if (atomic_read(&penv->fw_store_in_progress)) { wait_for_completion_timeout(&penv->fw_setup_complete, msecs_to_jiffies(FW_SETUP_DELAY)); } mutex_lock(&penv->fw_setup_stat_lock); image_desc_info->fw_addr = penv->fw_dma; image_desc_info->fw_size = penv->fw_dma_size; image_desc_info->bdata_addr = penv->bdata_dma; image_desc_info->bdata_size = penv->bdata_dma_size; mutex_unlock(&penv->fw_setup_stat_lock); return 0; } Loading Loading @@ -1552,7 +1568,7 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, penv->pdev = pdev; penv->id = id; penv->fw_available = false; atomic_set(&penv->fw_available, 0); penv->device_id = pdev->device; if (penv->smmu_iova_len) { Loading Loading @@ -1858,8 +1874,19 @@ static ssize_t fw_image_setup_store(struct device *dev, if (!penv) return -ENODEV; if (sscanf(buf, "%d", &val) != 1) if (atomic_read(&penv->fw_store_in_progress)) { pr_info("%s: Firmware setup in progress\n", __func__); return 0; } atomic_set(&penv->fw_store_in_progress, 1); init_completion(&penv->fw_setup_complete); if (kstrtoint(buf, 0, &val)) { atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return -EINVAL; } if (val == FW_IMAGE_FTM || val == FW_IMAGE_MISSION || val == FW_IMAGE_BDATA) { Loading @@ -1868,6 +1895,8 @@ static ssize_t fw_image_setup_store(struct device *dev, if (ret != 0) { pr_err("%s: Invalid parsing of FW image files %d", __func__, ret); atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return -EINVAL; } penv->fw_image_setup = val; Loading @@ -1877,6 +1906,9 @@ static ssize_t fw_image_setup_store(struct device *dev, penv->bmi_test = val; } atomic_set(&penv->fw_store_in_progress, 0); complete(&penv->fw_setup_complete); return count; } Loading Loading @@ -1979,7 +2011,7 @@ int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg) swap_seg = NULL; return -ENOENT; } if (!penv->fw_available) { if (!atomic_read(&penv->fw_available)) { pr_debug("%s: fw is not available\n", __func__); return -ENOENT; } Loading @@ -2003,6 +2035,16 @@ static void cnss_wlan_memory_expansion(void) u_int32_t total_length = 0; struct pci_dev *pdev; /* Check for firmware setup trigger by usersapce is in progress * and wait for complition of firmware setup. */ if (atomic_read(&penv->fw_store_in_progress)) { wait_for_completion_timeout(&penv->fw_setup_complete, msecs_to_jiffies(FW_SETUP_DELAY)); } mutex_lock(&penv->fw_setup_stat_lock); filename = cnss_wlan_get_evicted_data_file(); pdev = penv->pdev; dev = &pdev->dev; Loading @@ -2010,21 +2052,25 @@ static void cnss_wlan_memory_expansion(void) if (!cnss_seg_info) { pr_debug("cnss: cnss_seg_info is NULL\n"); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (penv->fw_available) { if (atomic_read(&penv->fw_available)) { pr_debug("cnss: fw code already copied to host memory\n"); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (request_firmware(&fw_entry, filename, dev) != 0) { pr_debug("cnss: failed to get fw: %s\n", filename); mutex_unlock(&penv->fw_setup_stat_lock); goto end; } if (!fw_entry || !fw_entry->data) { pr_err("%s: INVALID FW entries\n", __func__); mutex_unlock(&penv->fw_setup_stat_lock); goto release_fw; } Loading Loading @@ -2059,7 +2105,9 @@ static void cnss_wlan_memory_expansion(void) } pr_debug("cnss: total_bytes copied: %d\n", total_length); cnss_seg_info->codeseg_total_bytes = total_length; penv->fw_available = 1; atomic_set(&penv->fw_available, 1); mutex_unlock(&penv->fw_setup_stat_lock); release_fw: release_firmware(fw_entry); Loading Loading @@ -2968,6 +3016,8 @@ skip_ramdump: memset(phys_to_virt(0), 0, SZ_4K); #endif atomic_set(&penv->fw_store_in_progress, 0); mutex_init(&penv->fw_setup_stat_lock); ret = device_create_file(dev, &dev_attr_fw_image_setup); if (ret) { pr_err("cnss: fw_image_setup sys file creation failed\n"); Loading