Loading drivers/net/wireless/ath/ath10k/bmi.c +8 −5 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, return 0; } int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result) { struct bmi_cmd cmd; union bmi_resp resp; Loading @@ -184,7 +184,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", address, *param); address, param); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); Loading @@ -193,7 +193,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) cmd.id = __cpu_to_le32(BMI_EXECUTE); cmd.execute.addr = __cpu_to_le32(address); cmd.execute.param = __cpu_to_le32(*param); cmd.execute.param = __cpu_to_le32(param); ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); if (ret) { Loading @@ -204,10 +204,13 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) if (resplen < sizeof(resp.execute)) { ath10k_warn("invalid execute response length (%d)\n", resplen); return ret; return -EIO; } *param = __le32_to_cpu(resp.execute.result); *result = __le32_to_cpu(resp.execute.result); ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); return 0; } Loading drivers/net/wireless/ath/ath10k/bmi.h +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, ret; \ }) int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param); int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result); int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address); int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length); int ath10k_bmi_fast_download(struct ath10k *ar, u32 address, Loading drivers/net/wireless/ath/ath10k/ce.c +201 −155 Original line number Diff line number Diff line Loading @@ -840,35 +840,17 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, static int ath10k_ce_init_src_ring(struct ath10k *ar, unsigned int ce_id, struct ath10k_ce_pipe *ce_state, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *src_ring; unsigned int nentries = attr->src_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); dma_addr_t base_addr; char *ptr; nentries = roundup_pow_of_two(nentries); if (ce_state->src_ring) { WARN_ON(ce_state->src_ring->nentries != nentries); return 0; } struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce_ring *src_ring = ce_state->src_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; nentries = roundup_pow_of_two(attr->src_nentries); ce_state->src_ring = (struct ath10k_ce_ring *)ptr; src_ring = ce_state->src_ring; ptr += sizeof(struct ath10k_ce_ring); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; memset(src_ring->per_transfer_context, 0, nentries * sizeof(*src_ring->per_transfer_context)); src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index &= src_ring->nentries_mask; Loading @@ -878,21 +860,87 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ath10k_ce_src_ring_write_index_get(ar, ctrl_addr); src_ring->write_index &= src_ring->nentries_mask; src_ring->per_transfer_context = (void **)ptr; ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, src_ring->base_addr_ce_space); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot init ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; } static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); nentries = roundup_pow_of_two(attr->dest_nentries); memset(dest_ring->per_transfer_context, 0, nentries * sizeof(*dest_ring->per_transfer_context)); dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); dest_ring->write_index &= dest_ring->nentries_mask; ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, dest_ring->base_addr_ce_space); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } static struct ath10k_ce_ring * ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_ring *src_ring; u32 nentries = attr->src_nentries; dma_addr_t base_addr; nentries = roundup_pow_of_two(nentries); src_ring = kzalloc(sizeof(*src_ring) + (nentries * sizeof(*src_ring->per_transfer_context)), GFP_KERNEL); if (src_ring == NULL) return ERR_PTR(-ENOMEM); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; /* * Legacy platforms that do not support cache * coherent DMA are unsupported */ src_ring->base_addr_owner_space_unaligned = pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); &base_addr, GFP_KERNEL); if (!src_ring->base_addr_owner_space_unaligned) { kfree(ce_state->src_ring); ce_state->src_ring = NULL; return -ENOMEM; kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->base_addr_ce_space_unaligned = base_addr; Loading @@ -912,88 +960,54 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, kmalloc((nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), GFP_KERNEL); if (!src_ring->shadow_base_unaligned) { pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), src_ring->base_addr_owner_space, src_ring->base_addr_ce_space); kfree(ce_state->src_ring); ce_state->src_ring = NULL; return -ENOMEM; kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->shadow_base = PTR_ALIGN( src_ring->shadow_base_unaligned, CE_DESC_RING_ALIGN); ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, src_ring->base_addr_ce_space); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; return src_ring; } static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, struct ath10k_ce_pipe *ce_state, static struct ath10k_ce_ring * ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *dest_ring; unsigned int nentries = attr->dest_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); u32 nentries; dma_addr_t base_addr; char *ptr; nentries = roundup_pow_of_two(nentries); if (ce_state->dest_ring) { WARN_ON(ce_state->dest_ring->nentries != nentries); return 0; } nentries = roundup_pow_of_two(attr->dest_nentries); ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; dest_ring = kzalloc(sizeof(*dest_ring) + (nentries * sizeof(*dest_ring->per_transfer_context)), GFP_KERNEL); if (dest_ring == NULL) return ERR_PTR(-ENOMEM); ce_state->dest_ring = (struct ath10k_ce_ring *)ptr; dest_ring = ce_state->dest_ring; ptr += sizeof(struct ath10k_ce_ring); dest_ring->nentries = nentries; dest_ring->nentries_mask = nentries - 1; dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); dest_ring->write_index &= dest_ring->nentries_mask; dest_ring->per_transfer_context = (void **)ptr; /* * Legacy platforms that do not support cache * coherent DMA are unsupported */ dest_ring->base_addr_owner_space_unaligned = pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); &base_addr, GFP_KERNEL); if (!dest_ring->base_addr_owner_space_unaligned) { kfree(ce_state->dest_ring); ce_state->dest_ring = NULL; return -ENOMEM; kfree(dest_ring); return ERR_PTR(-ENOMEM); } dest_ring->base_addr_ce_space_unaligned = base_addr; Loading @@ -1012,39 +1026,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, dest_ring->base_addr_ce_space_unaligned, CE_DESC_RING_ALIGN); ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, dest_ring->base_addr_ce_space); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; u32 ctrl_addr = ath10k_ce_base_address(ce_id); spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; ce_state->ctrl_addr = ctrl_addr; ce_state->attr_flags = attr->flags; ce_state->src_sz_max = attr->src_sz_max; spin_unlock_bh(&ar_pci->ce_lock); return ce_state; return dest_ring; } /* Loading @@ -1054,11 +1036,11 @@ static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, * initialization. It may be that only one side or the other is * initialized by software/firmware. */ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_pipe *ce_state; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; /* Loading @@ -1074,49 +1056,113 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, ret = ath10k_pci_wake(ar); if (ret) return NULL; return ret; ce_state = ath10k_ce_init_state(ar, ce_id, attr); if (!ce_state) { ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id); goto out; } spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); ce_state->attr_flags = attr->flags; ce_state->src_sz_max = attr->src_sz_max; spin_unlock_bh(&ar_pci->ce_lock); if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr); ret = ath10k_ce_init_src_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); ce_state = NULL; goto out; } } if (attr->dest_nentries) { ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr); ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); ce_state = NULL; goto out; } } out: ath10k_pci_sleep(ar); return ce_state; return ret; } void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) { u32 ctrl_addr = ath10k_ce_base_address(ce_id); ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0); } static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) { u32 ctrl_addr = ath10k_ce_base_address(ce_id); ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0); } void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) { int ret; ret = ath10k_pci_wake(ar); if (ret) return; ath10k_ce_deinit_src_ring(ar, ce_id); ath10k_ce_deinit_dest_ring(ar, ce_id); ath10k_pci_sleep(ar); } int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; if (attr->src_nentries) { ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); if (IS_ERR(ce_state->src_ring)) { ret = PTR_ERR(ce_state->src_ring); ath10k_err("failed to allocate copy engine source ring %d: %d\n", ce_id, ret); ce_state->src_ring = NULL; return ret; } } if (attr->dest_nentries) { ce_state->dest_ring = ath10k_ce_alloc_dest_ring(ar, ce_id, attr); if (IS_ERR(ce_state->dest_ring)) { ret = PTR_ERR(ce_state->dest_ring); ath10k_err("failed to allocate copy engine destination ring %d: %d\n", ce_id, ret); ce_state->dest_ring = NULL; return ret; } } return 0; } void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; if (ce_state->src_ring) { kfree(ce_state->src_ring->shadow_base_unaligned); pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (ce_state->src_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), Loading @@ -1126,7 +1172,7 @@ void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) } if (ce_state->dest_ring) { pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (ce_state->dest_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), Loading drivers/net/wireless/ath/ath10k/ce.h +8 −7 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ struct ath10k_ce_ring { void *shadow_base_unaligned; struct ce_desc *shadow_base; void **per_transfer_context; /* keep last */ void *per_transfer_context[0]; }; struct ath10k_ce_pipe { Loading Loading @@ -210,10 +211,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, /*==================CE Engine Initialization=======================*/ /* Initialize an instance of a CE */ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr); void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr); void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); /*==================CE Engine Shutdown=======================*/ /* Loading @@ -236,8 +239,6 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, unsigned int *nbytesp, unsigned int *transfer_idp); void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state); /*==================CE Interrupt Handlers====================*/ void ath10k_ce_per_engine_service_any(struct ath10k *ar); void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); Loading drivers/net/wireless/ath/ath10k/core.c +54 −31 Original line number Diff line number Diff line Loading @@ -249,30 +249,40 @@ static int ath10k_download_board_data(struct ath10k *ar) static int ath10k_download_and_run_otp(struct ath10k *ar) { u32 address = ar->hw_params.patch_load_addr; u32 exec_param; u32 result, address = ar->hw_params.patch_load_addr; int ret; /* OTP is optional */ if (!ar->otp_data || !ar->otp_len) if (!ar->otp_data || !ar->otp_len) { ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", ar->otp_data, ar->otp_len); return 0; } ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", address, ar->otp_len); ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); if (ret) { ath10k_err("could not write otp (%d)\n", ret); goto exit; return ret; } exec_param = 0; ret = ath10k_bmi_execute(ar, address, &exec_param); ret = ath10k_bmi_execute(ar, address, 0, &result); if (ret) { ath10k_err("could not execute otp (%d)\n", ret); goto exit; return ret; } exit: return ret; ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); if (result != 0) { ath10k_err("otp calibration failed: %d", result); return -EINVAL; } return 0; } static int ath10k_download_fw(struct ath10k *ar) Loading Loading @@ -389,8 +399,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) /* first fetch the firmware file (firmware-*.bin) */ ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); if (IS_ERR(ar->firmware)) { ath10k_err("Could not fetch firmware file '%s': %ld\n", name, PTR_ERR(ar->firmware)); ath10k_err("could not fetch firmware file '%s/%s': %ld\n", ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware)); return PTR_ERR(ar->firmware); } Loading @@ -401,14 +411,14 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; if (len < magic_len) { ath10k_err("firmware image too small to contain magic: %zu\n", len); ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n", ar->hw_params.fw.dir, name, len); ret = -EINVAL; goto err; } if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { ath10k_err("Invalid firmware magic\n"); ath10k_err("invalid firmware magic\n"); ret = -EINVAL; goto err; } Loading @@ -430,7 +440,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) data += sizeof(*hdr); if (len < ie_len) { ath10k_err("Invalid length for FW IE %d (%zu < %zu)\n", ath10k_err("invalid length for FW IE %d (%zu < %zu)\n", ie_id, len, ie_len); ret = -EINVAL; goto err; Loading Loading @@ -513,8 +523,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) } if (!ar->firmware_data || !ar->firmware_len) { ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n", name); ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", ar->hw_params.fw.dir, name); ret = -ENOMEDIUM; goto err; } Loading @@ -531,7 +541,9 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) ar->hw_params.fw.board); if (IS_ERR(ar->board)) { ret = PTR_ERR(ar->board); ath10k_err("could not fetch board data (%d)\n", ret); ath10k_err("could not fetch board data '%s/%s' (%d)\n", ar->hw_params.fw.dir, ar->hw_params.fw.board, ret); goto err; } Loading @@ -549,19 +561,21 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) { int ret; ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); if (ret == 0) { ar->fw_api = 2; goto out; } ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); if (ret == 0) goto success; ar->fw_api = 1; ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); ret = ath10k_core_fetch_firmware_api_1(ar); if (ret) return ret; ar->fw_api = 1; out: success: ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); return 0; Loading @@ -572,16 +586,22 @@ static int ath10k_init_download_firmware(struct ath10k *ar) int ret; ret = ath10k_download_board_data(ar); if (ret) if (ret) { ath10k_err("failed to download board data: %d\n", ret); return ret; } ret = ath10k_download_and_run_otp(ar); if (ret) if (ret) { ath10k_err("failed to run otp: %d\n", ret); return ret; } ret = ath10k_download_fw(ar); if (ret) if (ret) { ath10k_err("failed to download firmware: %d\n", ret); return ret; } return ret; } Loading Loading @@ -835,9 +855,12 @@ int ath10k_core_start(struct ath10k *ar) INIT_LIST_HEAD(&ar->arvifs); if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n", ar->hw_params.name, ar->target_version, ar->hw->wiphy->fw_version, ar->fw_api, ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", ar->hw_params.name, ar->target_version, ar->chip_id, ar->hw->wiphy->fw_version, ar->fw_api, ar->htt.target_version_major, ar->htt.target_version_minor); Loading Loading
drivers/net/wireless/ath/ath10k/bmi.c +8 −5 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, return 0; } int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result) { struct bmi_cmd cmd; union bmi_resp resp; Loading @@ -184,7 +184,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", address, *param); address, param); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); Loading @@ -193,7 +193,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) cmd.id = __cpu_to_le32(BMI_EXECUTE); cmd.execute.addr = __cpu_to_le32(address); cmd.execute.param = __cpu_to_le32(*param); cmd.execute.param = __cpu_to_le32(param); ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); if (ret) { Loading @@ -204,10 +204,13 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) if (resplen < sizeof(resp.execute)) { ath10k_warn("invalid execute response length (%d)\n", resplen); return ret; return -EIO; } *param = __le32_to_cpu(resp.execute.result); *result = __le32_to_cpu(resp.execute.result); ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); return 0; } Loading
drivers/net/wireless/ath/ath10k/bmi.h +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, ret; \ }) int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param); int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result); int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address); int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length); int ath10k_bmi_fast_download(struct ath10k *ar, u32 address, Loading
drivers/net/wireless/ath/ath10k/ce.c +201 −155 Original line number Diff line number Diff line Loading @@ -840,35 +840,17 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, static int ath10k_ce_init_src_ring(struct ath10k *ar, unsigned int ce_id, struct ath10k_ce_pipe *ce_state, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *src_ring; unsigned int nentries = attr->src_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); dma_addr_t base_addr; char *ptr; nentries = roundup_pow_of_two(nentries); if (ce_state->src_ring) { WARN_ON(ce_state->src_ring->nentries != nentries); return 0; } struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce_ring *src_ring = ce_state->src_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; nentries = roundup_pow_of_two(attr->src_nentries); ce_state->src_ring = (struct ath10k_ce_ring *)ptr; src_ring = ce_state->src_ring; ptr += sizeof(struct ath10k_ce_ring); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; memset(src_ring->per_transfer_context, 0, nentries * sizeof(*src_ring->per_transfer_context)); src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index &= src_ring->nentries_mask; Loading @@ -878,21 +860,87 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ath10k_ce_src_ring_write_index_get(ar, ctrl_addr); src_ring->write_index &= src_ring->nentries_mask; src_ring->per_transfer_context = (void **)ptr; ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, src_ring->base_addr_ce_space); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot init ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; } static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); nentries = roundup_pow_of_two(attr->dest_nentries); memset(dest_ring->per_transfer_context, 0, nentries * sizeof(*dest_ring->per_transfer_context)); dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); dest_ring->write_index &= dest_ring->nentries_mask; ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, dest_ring->base_addr_ce_space); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } static struct ath10k_ce_ring * ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_ring *src_ring; u32 nentries = attr->src_nentries; dma_addr_t base_addr; nentries = roundup_pow_of_two(nentries); src_ring = kzalloc(sizeof(*src_ring) + (nentries * sizeof(*src_ring->per_transfer_context)), GFP_KERNEL); if (src_ring == NULL) return ERR_PTR(-ENOMEM); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; /* * Legacy platforms that do not support cache * coherent DMA are unsupported */ src_ring->base_addr_owner_space_unaligned = pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); &base_addr, GFP_KERNEL); if (!src_ring->base_addr_owner_space_unaligned) { kfree(ce_state->src_ring); ce_state->src_ring = NULL; return -ENOMEM; kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->base_addr_ce_space_unaligned = base_addr; Loading @@ -912,88 +960,54 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, kmalloc((nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), GFP_KERNEL); if (!src_ring->shadow_base_unaligned) { pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), src_ring->base_addr_owner_space, src_ring->base_addr_ce_space); kfree(ce_state->src_ring); ce_state->src_ring = NULL; return -ENOMEM; kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->shadow_base = PTR_ALIGN( src_ring->shadow_base_unaligned, CE_DESC_RING_ALIGN); ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, src_ring->base_addr_ce_space); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; return src_ring; } static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, struct ath10k_ce_pipe *ce_state, static struct ath10k_ce_ring * ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *dest_ring; unsigned int nentries = attr->dest_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); u32 nentries; dma_addr_t base_addr; char *ptr; nentries = roundup_pow_of_two(nentries); if (ce_state->dest_ring) { WARN_ON(ce_state->dest_ring->nentries != nentries); return 0; } nentries = roundup_pow_of_two(attr->dest_nentries); ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; dest_ring = kzalloc(sizeof(*dest_ring) + (nentries * sizeof(*dest_ring->per_transfer_context)), GFP_KERNEL); if (dest_ring == NULL) return ERR_PTR(-ENOMEM); ce_state->dest_ring = (struct ath10k_ce_ring *)ptr; dest_ring = ce_state->dest_ring; ptr += sizeof(struct ath10k_ce_ring); dest_ring->nentries = nentries; dest_ring->nentries_mask = nentries - 1; dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); dest_ring->write_index &= dest_ring->nentries_mask; dest_ring->per_transfer_context = (void **)ptr; /* * Legacy platforms that do not support cache * coherent DMA are unsupported */ dest_ring->base_addr_owner_space_unaligned = pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); &base_addr, GFP_KERNEL); if (!dest_ring->base_addr_owner_space_unaligned) { kfree(ce_state->dest_ring); ce_state->dest_ring = NULL; return -ENOMEM; kfree(dest_ring); return ERR_PTR(-ENOMEM); } dest_ring->base_addr_ce_space_unaligned = base_addr; Loading @@ -1012,39 +1026,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, dest_ring->base_addr_ce_space_unaligned, CE_DESC_RING_ALIGN); ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, dest_ring->base_addr_ce_space); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; u32 ctrl_addr = ath10k_ce_base_address(ce_id); spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; ce_state->ctrl_addr = ctrl_addr; ce_state->attr_flags = attr->flags; ce_state->src_sz_max = attr->src_sz_max; spin_unlock_bh(&ar_pci->ce_lock); return ce_state; return dest_ring; } /* Loading @@ -1054,11 +1036,11 @@ static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, * initialization. It may be that only one side or the other is * initialized by software/firmware. */ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_pipe *ce_state; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; /* Loading @@ -1074,49 +1056,113 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, ret = ath10k_pci_wake(ar); if (ret) return NULL; return ret; ce_state = ath10k_ce_init_state(ar, ce_id, attr); if (!ce_state) { ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id); goto out; } spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); ce_state->attr_flags = attr->flags; ce_state->src_sz_max = attr->src_sz_max; spin_unlock_bh(&ar_pci->ce_lock); if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr); ret = ath10k_ce_init_src_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); ce_state = NULL; goto out; } } if (attr->dest_nentries) { ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr); ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); ce_state = NULL; goto out; } } out: ath10k_pci_sleep(ar); return ce_state; return ret; } void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) { u32 ctrl_addr = ath10k_ce_base_address(ce_id); ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0); } static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) { u32 ctrl_addr = ath10k_ce_base_address(ce_id); ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0); } void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) { int ret; ret = ath10k_pci_wake(ar); if (ret) return; ath10k_ce_deinit_src_ring(ar, ce_id); ath10k_ce_deinit_dest_ring(ar, ce_id); ath10k_pci_sleep(ar); } int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; if (attr->src_nentries) { ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); if (IS_ERR(ce_state->src_ring)) { ret = PTR_ERR(ce_state->src_ring); ath10k_err("failed to allocate copy engine source ring %d: %d\n", ce_id, ret); ce_state->src_ring = NULL; return ret; } } if (attr->dest_nentries) { ce_state->dest_ring = ath10k_ce_alloc_dest_ring(ar, ce_id, attr); if (IS_ERR(ce_state->dest_ring)) { ret = PTR_ERR(ce_state->dest_ring); ath10k_err("failed to allocate copy engine destination ring %d: %d\n", ce_id, ret); ce_state->dest_ring = NULL; return ret; } } return 0; } void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; if (ce_state->src_ring) { kfree(ce_state->src_ring->shadow_base_unaligned); pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (ce_state->src_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), Loading @@ -1126,7 +1172,7 @@ void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) } if (ce_state->dest_ring) { pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev, (ce_state->dest_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), Loading
drivers/net/wireless/ath/ath10k/ce.h +8 −7 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ struct ath10k_ce_ring { void *shadow_base_unaligned; struct ce_desc *shadow_base; void **per_transfer_context; /* keep last */ void *per_transfer_context[0]; }; struct ath10k_ce_pipe { Loading Loading @@ -210,10 +211,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, /*==================CE Engine Initialization=======================*/ /* Initialize an instance of a CE */ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr); void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr); void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); /*==================CE Engine Shutdown=======================*/ /* Loading @@ -236,8 +239,6 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, unsigned int *nbytesp, unsigned int *transfer_idp); void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state); /*==================CE Interrupt Handlers====================*/ void ath10k_ce_per_engine_service_any(struct ath10k *ar); void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); Loading
drivers/net/wireless/ath/ath10k/core.c +54 −31 Original line number Diff line number Diff line Loading @@ -249,30 +249,40 @@ static int ath10k_download_board_data(struct ath10k *ar) static int ath10k_download_and_run_otp(struct ath10k *ar) { u32 address = ar->hw_params.patch_load_addr; u32 exec_param; u32 result, address = ar->hw_params.patch_load_addr; int ret; /* OTP is optional */ if (!ar->otp_data || !ar->otp_len) if (!ar->otp_data || !ar->otp_len) { ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", ar->otp_data, ar->otp_len); return 0; } ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", address, ar->otp_len); ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); if (ret) { ath10k_err("could not write otp (%d)\n", ret); goto exit; return ret; } exec_param = 0; ret = ath10k_bmi_execute(ar, address, &exec_param); ret = ath10k_bmi_execute(ar, address, 0, &result); if (ret) { ath10k_err("could not execute otp (%d)\n", ret); goto exit; return ret; } exit: return ret; ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); if (result != 0) { ath10k_err("otp calibration failed: %d", result); return -EINVAL; } return 0; } static int ath10k_download_fw(struct ath10k *ar) Loading Loading @@ -389,8 +399,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) /* first fetch the firmware file (firmware-*.bin) */ ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); if (IS_ERR(ar->firmware)) { ath10k_err("Could not fetch firmware file '%s': %ld\n", name, PTR_ERR(ar->firmware)); ath10k_err("could not fetch firmware file '%s/%s': %ld\n", ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware)); return PTR_ERR(ar->firmware); } Loading @@ -401,14 +411,14 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; if (len < magic_len) { ath10k_err("firmware image too small to contain magic: %zu\n", len); ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n", ar->hw_params.fw.dir, name, len); ret = -EINVAL; goto err; } if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { ath10k_err("Invalid firmware magic\n"); ath10k_err("invalid firmware magic\n"); ret = -EINVAL; goto err; } Loading @@ -430,7 +440,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) data += sizeof(*hdr); if (len < ie_len) { ath10k_err("Invalid length for FW IE %d (%zu < %zu)\n", ath10k_err("invalid length for FW IE %d (%zu < %zu)\n", ie_id, len, ie_len); ret = -EINVAL; goto err; Loading Loading @@ -513,8 +523,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) } if (!ar->firmware_data || !ar->firmware_len) { ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n", name); ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", ar->hw_params.fw.dir, name); ret = -ENOMEDIUM; goto err; } Loading @@ -531,7 +541,9 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) ar->hw_params.fw.board); if (IS_ERR(ar->board)) { ret = PTR_ERR(ar->board); ath10k_err("could not fetch board data (%d)\n", ret); ath10k_err("could not fetch board data '%s/%s' (%d)\n", ar->hw_params.fw.dir, ar->hw_params.fw.board, ret); goto err; } Loading @@ -549,19 +561,21 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) { int ret; ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); if (ret == 0) { ar->fw_api = 2; goto out; } ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); if (ret == 0) goto success; ar->fw_api = 1; ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); ret = ath10k_core_fetch_firmware_api_1(ar); if (ret) return ret; ar->fw_api = 1; out: success: ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); return 0; Loading @@ -572,16 +586,22 @@ static int ath10k_init_download_firmware(struct ath10k *ar) int ret; ret = ath10k_download_board_data(ar); if (ret) if (ret) { ath10k_err("failed to download board data: %d\n", ret); return ret; } ret = ath10k_download_and_run_otp(ar); if (ret) if (ret) { ath10k_err("failed to run otp: %d\n", ret); return ret; } ret = ath10k_download_fw(ar); if (ret) if (ret) { ath10k_err("failed to download firmware: %d\n", ret); return ret; } return ret; } Loading Loading @@ -835,9 +855,12 @@ int ath10k_core_start(struct ath10k *ar) INIT_LIST_HEAD(&ar->arvifs); if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n", ar->hw_params.name, ar->target_version, ar->hw->wiphy->fw_version, ar->fw_api, ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", ar->hw_params.name, ar->target_version, ar->chip_id, ar->hw->wiphy->fw_version, ar->fw_api, ar->htt.target_version_major, ar->htt.target_version_minor); Loading