Ejemplo n.º 1
0
static int ath10k_init_hw_params(struct ath10k *ar)
{
	const struct ath10k_hw_params *uninitialized_var(hw_params);
	int i;

	for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
		hw_params = &ath10k_hw_params_list[i];

		if (hw_params->id == ar->target_version)
			break;
	}

	if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
		ath10k_err("Unsupported hardware version: 0x%x\n",
			   ar->target_version);
		return -EINVAL;
	}

	ar->hw_params = *hw_params;

	ath10k_info("Hardware name %s version 0x%x\n",
		    ar->hw_params.name, ar->target_version);

	return 0;
}
Ejemplo n.º 2
0
/* registered target arrival callback from the HIF layer */
int ath10k_htc_init(struct ath10k *ar)
{
	int status;
	struct ath10k_htc *htc = &ar->htc;
	struct ath10k_htc_svc_conn_req conn_req;
	struct ath10k_htc_svc_conn_resp conn_resp;

	spin_lock_init(&htc->tx_lock);

	ath10k_htc_reset_endpoint_states(htc);

	htc->ar = ar;

	/* setup our pseudo HTC control endpoint connection */
	memset(&conn_req, 0, sizeof(conn_req));
	memset(&conn_resp, 0, sizeof(conn_resp));
	conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
	conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
	conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
	conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;

	/* connect fake service */
	status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
	if (status) {
		ath10k_err(ar, "could not connect to htc service (%d)\n",
			   status);
		return status;
	}

	init_completion(&htc->ctl_resp);

	return 0;
}
Ejemplo n.º 3
0
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
				      size_t data_len)
{
	u32 board_data_size = ar->hw_params.fw.board_size;
	u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
	u32 board_ext_data_addr;
	int ret;

	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
	if (ret) {
		ath10k_err(ar, "could not read board ext data addr (%d)\n",
			   ret);
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot push board extended data addr 0x%x\n",
		   board_ext_data_addr);

	if (board_ext_data_addr == 0)
		return 0;

	if (data_len != (board_data_size + board_ext_data_size)) {
		ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
			   data_len, board_data_size, board_ext_data_size);
		return -EINVAL;
	}

	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
				      data + board_data_size,
				      board_ext_data_size);
	if (ret) {
		ath10k_err(ar, "could not write board ext data (%d)\n", ret);
		return ret;
	}

	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
				 (board_ext_data_size << 16) | 1);
	if (ret) {
		ath10k_err(ar, "could not write board ext data bit (%d)\n",
			   ret);
		return ret;
	}

	return 0;
}
Ejemplo n.º 4
0
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
	u32 result, address = ar->hw_params.patch_load_addr;
	u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
	int ret;

	ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
	if (ret) {
		ath10k_err(ar, "failed to download board data: %d\n", ret);
		return ret;
	}

	/* OTP is optional */

	if (!ar->otp_data || !ar->otp_len) {
		ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
			    ar->otp_data, ar->otp_len);
		return 0;
	}

	ath10k_dbg(ar, 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(ar, "could not write otp (%d)\n", ret);
		return ret;
	}

	ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
	if (ret) {
		ath10k_err(ar, "could not execute otp (%d)\n", ret);
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);

	if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
				   ar->fw_features))
	    && result != 0) {
		ath10k_err(ar, "otp calibration failed: %d", result);
		return -EINVAL;
	}

	return 0;
}
Ejemplo n.º 5
0
static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
{
	u32 address, data_len;
	const char *mode_name;
	const void *data;
	int ret;

	address = ar->hw_params.patch_load_addr;

	switch (mode) {
	case ATH10K_FIRMWARE_MODE_NORMAL:
		data = ar->firmware_data;
		data_len = ar->firmware_len;
		mode_name = "normal";
		ret = ath10k_swap_code_seg_configure(ar,
				ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
		if (ret) {
			ath10k_err(ar, "failed to configure fw code swap: %d\n",
				   ret);
			return ret;
		}
		break;
	case ATH10K_FIRMWARE_MODE_UTF:
		data = ar->testmode.utf->data;
		data_len = ar->testmode.utf->size;
		mode_name = "utf";
		break;
	default:
		ath10k_err(ar, "unknown firmware mode: %d\n", mode);
		return -EINVAL;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot uploading firmware image %p len %d mode %s\n",
		   data, data_len, mode_name);

	ret = ath10k_bmi_fast_download(ar, address, data, data_len);
	if (ret) {
		ath10k_err(ar, "failed to download %s firmware: %d\n",
			   mode_name, ret);
		return ret;
	}

	return ret;
}
Ejemplo n.º 6
0
Archivo: core.c Proyecto: 3null/linux
static int ath10k_push_board_ext_data(struct ath10k *ar)
{
	u32 board_data_size = QCA988X_BOARD_DATA_SZ;
	u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
	u32 board_ext_data_addr;
	int ret;

	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
	if (ret) {
		ath10k_err(ar, "could not read board ext data addr (%d)\n",
			   ret);
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot push board extended data addr 0x%x\n",
		   board_ext_data_addr);

	if (board_ext_data_addr == 0)
		return 0;

	if (ar->board_len != (board_data_size + board_ext_data_size)) {
		ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
			   ar->board_len, board_data_size, board_ext_data_size);
		return -EINVAL;
	}

	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
				      ar->board_data + board_data_size,
				      board_ext_data_size);
	if (ret) {
		ath10k_err(ar, "could not write board ext data (%d)\n", ret);
		return ret;
	}

	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
				 (board_ext_data_size << 16) | 1);
	if (ret) {
		ath10k_err(ar, "could not write board ext data bit (%d)\n",
			   ret);
		return ret;
	}

	return 0;
}
Ejemplo n.º 7
0
/*
 * Initialize a Copy Engine based on caller-supplied attributes.
 * This may be called once to initialize both source and destination
 * rings or it may be called twice for separate source and destination
 * 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,
				const struct ce_attr *attr)
{
	struct ath10k_ce_pipe *ce_state;
	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
	int ret;

	ret = ath10k_pci_wake(ar);
	if (ret)
		return NULL;

	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);
		return NULL;
	}

	if (attr->src_nentries) {
		ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr);
		if (ret) {
			ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
				   ce_id, ret);
			ath10k_ce_deinit(ce_state);
			return NULL;
		}
	}

	if (attr->dest_nentries) {
		ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr);
		if (ret) {
			ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
				   ce_id, ret);
			ath10k_ce_deinit(ce_state);
			return NULL;
		}
	}

	/* Enable CE error interrupts */
	ath10k_ce_error_intr_enable(ar, ctrl_addr);

	ath10k_pci_sleep(ar);

	return ce_state;
}
Ejemplo n.º 8
0
/*
 * Setup the driver side of the list allocations and insert them
 * all into the inactive list.
 */
int
athp_alloc_list(struct ath10k *ar, struct athp_buf_ring *br, int count, int btype)
{
	int i;
	int ret;

	/* Allocate initial buffer list */
	br->br_list = malloc(sizeof(struct athp_buf) * count, M_ATHPDEV,
	    M_ZERO | M_NOWAIT);
	br->btype = btype;
	if (br->br_list == NULL) {
		ath10k_err(ar, "%s: malloc failed!\n", __func__);
		return (-1);
	}

	/* Setup initial state for each entry */
	for (i = 0; i < count; i++) {
		athp_dma_mbuf_setup(ar, &br->dh, &br->br_list[i].mb);
		br->br_list[i].btype = btype;
		if (btype == BUF_TYPE_TX) {
			ret = athp_descdma_alloc(ar,
			    &br->br_list[i].txbuf_dd,
			    "htt_txbuf",
			    4,
			    sizeof (struct ath10k_htt_txbuf));
			if (ret != 0) {
				ath10k_err(ar,
				    "%s: descdma alloc failed: %d\n",
				    __func__, ret);
				goto fail;
			}
		}
	}

	/* Lists */
	TAILQ_INIT(&br->br_inactive);

	for (i = 0; i < count; i++)
		TAILQ_INSERT_HEAD(&br->br_inactive, &br->br_list[i], next);

	return (0);
fail:
	athp_free_list(ar, br);
	return (ENXIO);
}
Ejemplo n.º 9
0
Archivo: ahb.c Proyecto: AK101111/linux
static int ath10k_ahb_clock_enable(struct ath10k *ar)
{
	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
	struct device *dev;
	int ret;

	dev = &ar_ahb->pdev->dev;

	if (IS_ERR_OR_NULL(ar_ahb->cmd_clk) ||
	    IS_ERR_OR_NULL(ar_ahb->ref_clk) ||
	    IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {
		ath10k_err(ar, "clock(s) is/are not initialized\n");
		ret = -EIO;
		goto out;
	}

	ret = clk_prepare_enable(ar_ahb->cmd_clk);
	if (ret) {
		ath10k_err(ar, "failed to enable cmd clk: %d\n", ret);
		goto out;
	}

	ret = clk_prepare_enable(ar_ahb->ref_clk);
	if (ret) {
		ath10k_err(ar, "failed to enable ref clk: %d\n", ret);
		goto err_cmd_clk_disable;
	}

	ret = clk_prepare_enable(ar_ahb->rtc_clk);
	if (ret) {
		ath10k_err(ar, "failed to enable rtc clk: %d\n", ret);
		goto err_ref_clk_disable;
	}

	return 0;

err_ref_clk_disable:
	clk_disable_unprepare(ar_ahb->ref_clk);

err_cmd_clk_disable:
	clk_disable_unprepare(ar_ahb->cmd_clk);

out:
	return ret;
}
Ejemplo n.º 10
0
Archivo: core.c Proyecto: 3null/linux
static void ath10k_core_register_work(struct work_struct *work)
{
	struct ath10k *ar = container_of(work, struct ath10k, register_work);
	int status;

	status = ath10k_core_probe_fw(ar);
	if (status) {
		ath10k_err(ar, "could not probe fw (%d)\n", status);
		goto err;
	}

	status = ath10k_mac_register(ar);
	if (status) {
		ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
		goto err_release_fw;
	}

	status = ath10k_debug_register(ar);
	if (status) {
		ath10k_err(ar, "unable to initialize debugfs\n");
		goto err_unregister_mac;
	}

	status = ath10k_spectral_create(ar);
	if (status) {
		ath10k_err(ar, "failed to initialize spectral\n");
		goto err_debug_destroy;
	}

	set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
	return;

err_debug_destroy:
	ath10k_debug_destroy(ar);
err_unregister_mac:
	ath10k_mac_unregister(ar);
err_release_fw:
	ath10k_core_free_firmware_files(ar);
err:
	/* TODO: It's probably a good idea to release device from the driver
	 * but calling device_release_driver() here will cause a deadlock.
	 */
	return;
}
Ejemplo n.º 11
0
static int ath10k_download_board_data(struct ath10k *ar)
{
	u32 board_data_size = QCA988X_BOARD_DATA_SZ;
	u32 address;
	const struct firmware *fw;
	int ret;

	fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
				  ar->hw_params.fw.board);
	if (IS_ERR(fw)) {
		ath10k_err("could not fetch board data fw file (%ld)\n",
			   PTR_ERR(fw));
		return PTR_ERR(fw);
	}

	ret = ath10k_push_board_ext_data(ar, fw);
	if (ret) {
		ath10k_err("could not push board ext data (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_read32(ar, hi_board_data, &address);
	if (ret) {
		ath10k_err("could not read board data addr (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_write_memory(ar, address, fw->data,
				      min_t(u32, board_data_size, fw->size));
	if (ret) {
		ath10k_err("could not write board data (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
	if (ret) {
		ath10k_err("could not write board data bit (%d)\n", ret);
		goto exit;
	}

exit:
	release_firmware(fw);
	return ret;
}
Ejemplo n.º 12
0
static int ath10k_push_board_ext_data(struct ath10k *ar,
				      const struct firmware *fw)
{
	u32 board_data_size = QCA988X_BOARD_DATA_SZ;
	u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
	u32 board_ext_data_addr;
	int ret;

	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
	if (ret) {
		ath10k_err("could not read board ext data addr (%d)\n", ret);
		return ret;
	}

	ath10k_dbg(ATH10K_DBG_CORE,
		   "ath10k: Board extended Data download addr: 0x%x\n",
		   board_ext_data_addr);

	if (board_ext_data_addr == 0)
		return 0;

	if (fw->size != (board_data_size + board_ext_data_size)) {
		ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n",
			   fw->size, board_data_size, board_ext_data_size);
		return -EINVAL;
	}

	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
				      fw->data + board_data_size,
				      board_ext_data_size);
	if (ret) {
		ath10k_err("could not write board ext data (%d)\n", ret);
		return ret;
	}

	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
				 (board_ext_data_size << 16) | 1);
	if (ret) {
		ath10k_err("could not write board ext data bit (%d)\n", ret);
		return ret;
	}

	return 0;
}
Ejemplo n.º 13
0
Archivo: ahb.c Proyecto: AK101111/linux
static int ath10k_ahb_clock_init(struct ath10k *ar)
{
	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
	struct device *dev;
	int ret;

	dev = &ar_ahb->pdev->dev;

	ar_ahb->cmd_clk = clk_get(dev, "wifi_wcss_cmd");
	if (IS_ERR_OR_NULL(ar_ahb->cmd_clk)) {
		ath10k_err(ar, "failed to get cmd clk: %ld\n",
			   PTR_ERR(ar_ahb->cmd_clk));
		ret = ar_ahb->cmd_clk ? PTR_ERR(ar_ahb->cmd_clk) : -ENODEV;
		goto out;
	}

	ar_ahb->ref_clk = clk_get(dev, "wifi_wcss_ref");
	if (IS_ERR_OR_NULL(ar_ahb->ref_clk)) {
		ath10k_err(ar, "failed to get ref clk: %ld\n",
			   PTR_ERR(ar_ahb->ref_clk));
		ret = ar_ahb->ref_clk ? PTR_ERR(ar_ahb->ref_clk) : -ENODEV;
		goto err_cmd_clk_put;
	}

	ar_ahb->rtc_clk = clk_get(dev, "wifi_wcss_rtc");
	if (IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {
		ath10k_err(ar, "failed to get rtc clk: %ld\n",
			   PTR_ERR(ar_ahb->rtc_clk));
		ret = ar_ahb->rtc_clk ? PTR_ERR(ar_ahb->rtc_clk) : -ENODEV;
		goto err_ref_clk_put;
	}

	return 0;

err_ref_clk_put:
	clk_put(ar_ahb->ref_clk);

err_cmd_clk_put:
	clk_put(ar_ahb->cmd_clk);

out:
	return ret;
}
Ejemplo n.º 14
0
static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
{
	int ret = 0;

	if (ar->hw_params.fw.fw == NULL) {
		ath10k_err(ar, "firmware file not defined\n");
		return -EINVAL;
	}

	ar->firmware = ath10k_fetch_fw_file(ar,
					    ar->hw_params.fw.dir,
					    ar->hw_params.fw.fw);
	if (IS_ERR(ar->firmware)) {
		ret = PTR_ERR(ar->firmware);
		ath10k_err(ar, "could not fetch firmware (%d)\n", ret);
		goto err;
	}

	ar->firmware_data = ar->firmware->data;
	ar->firmware_len = ar->firmware->size;

	/* OTP may be undefined. If so, don't fetch it at all */
	if (ar->hw_params.fw.otp == NULL)
		return 0;

	ar->otp = ath10k_fetch_fw_file(ar,
				       ar->hw_params.fw.dir,
				       ar->hw_params.fw.otp);
	if (IS_ERR(ar->otp)) {
		ret = PTR_ERR(ar->otp);
		ath10k_err(ar, "could not fetch otp (%d)\n", ret);
		goto err;
	}

	ar->otp_data = ar->otp->data;
	ar->otp_len = ar->otp->size;

	return 0;

err:
	ath10k_core_free_firmware_files(ar);
	return ret;
}
Ejemplo n.º 15
0
static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{
	int ret;

	/* calibration file is optional, don't check for any errors */
	ath10k_fetch_cal_file(ar);

	ret = ath10k_core_fetch_board_file(ar);
	if (ret) {
		ath10k_err(ar, "failed to fetch board file: %d\n", ret);
		return ret;
	}

	ar->fw_api = 5;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API5_FILE);
	if (ret == 0)
		goto success;

	ar->fw_api = 4;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
	if (ret == 0)
		goto success;

	ar->fw_api = 3;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE);
	if (ret == 0)
		goto success;

	ar->fw_api = 2;
	ath10k_dbg(ar, 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(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_1(ar);
	if (ret)
		return ret;

success:
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);

	return 0;
}
Ejemplo n.º 16
0
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
	const struct firmware *fw;
	u32 address;
	u32 exec_param;
	int ret;

	/* OTP is optional */

	if (ar->hw_params.fw.otp == NULL) {
		ath10k_info("otp file not defined\n");
		return 0;
	}

	address = ar->hw_params.patch_load_addr;

	fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
				  ar->hw_params.fw.otp);
	if (IS_ERR(fw)) {
		ath10k_warn("could not fetch otp (%ld)\n", PTR_ERR(fw));
		return 0;
	}

	ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
	if (ret) {
		ath10k_err("could not write otp (%d)\n", ret);
		goto exit;
	}

	exec_param = 0;
	ret = ath10k_bmi_execute(ar, address, &exec_param);
	if (ret) {
		ath10k_err("could not execute otp (%d)\n", ret);
		goto exit;
	}

exit:
	release_firmware(fw);
	return ret;
}
Ejemplo n.º 17
0
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
    u32 result, address = ar->hw_params.patch_load_addr;
    int ret;

    /* OTP is optional */

    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);
        return ret;
    }

    ret = ath10k_bmi_execute(ar, address, 0, &result);
    if (ret) {
        ath10k_err("could not execute otp (%d)\n", ret);
        return ret;
    }

    ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);

    if (result == 2) {
        ath10k_warn("otp stream is empty, using board.bin contents");
        return 0;
    } else if (result != 0) {
        ath10k_err("otp calibration failed: %d", result);
        return -EINVAL;
    }

    return 0;
}
Ejemplo n.º 18
0
Archivo: ahb.c Proyecto: Anjali05/linux
static int ath10k_ahb_release_reset(struct ath10k *ar)
{
	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
	int ret;

	if (IS_ERR_OR_NULL(ar_ahb->radio_cold_rst) ||
	    IS_ERR_OR_NULL(ar_ahb->radio_warm_rst) ||
	    IS_ERR_OR_NULL(ar_ahb->radio_srif_rst) ||
	    IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {
		ath10k_err(ar, "rst ctrl(s) is/are not initialized\n");
		return -EINVAL;
	}

	ret = reset_control_deassert(ar_ahb->radio_cold_rst);
	if (ret) {
		ath10k_err(ar, "failed to deassert radio cold rst: %d\n", ret);
		return ret;
	}

	ret = reset_control_deassert(ar_ahb->radio_warm_rst);
	if (ret) {
		ath10k_err(ar, "failed to deassert radio warm rst: %d\n", ret);
		return ret;
	}

	ret = reset_control_deassert(ar_ahb->radio_srif_rst);
	if (ret) {
		ath10k_err(ar, "failed to deassert radio srif rst: %d\n", ret);
		return ret;
	}

	ret = reset_control_deassert(ar_ahb->cpu_init_rst);
	if (ret) {
		ath10k_err(ar, "failed to deassert cpu init rst: %d\n", ret);
		return ret;
	}

	return 0;
}
Ejemplo n.º 19
0
Archivo: ce.c Proyecto: asmalldev/linux
void ath10k_ce_dump_registers(struct ath10k *ar,
			      struct ath10k_fw_crash_data *crash_data)
{
	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
	struct ath10k_ce_crash_data ce;
	u32 addr, id;

	lockdep_assert_held(&ar->data_lock);

	ath10k_err(ar, "Copy Engine register dump:\n");

	spin_lock_bh(&ar_pci->ce_lock);
	for (id = 0; id < CE_COUNT; id++) {
		addr = ath10k_ce_base_address(ar, id);
		ce.base_addr = cpu_to_le32(addr);

		ce.src_wr_idx =
			cpu_to_le32(ath10k_ce_src_ring_write_index_get(ar, addr));
		ce.src_r_idx =
			cpu_to_le32(ath10k_ce_src_ring_read_index_get(ar, addr));
		ce.dst_wr_idx =
			cpu_to_le32(ath10k_ce_dest_ring_write_index_get(ar, addr));
		ce.dst_r_idx =
			cpu_to_le32(ath10k_ce_dest_ring_read_index_get(ar, addr));

		if (crash_data)
			crash_data->ce_crash_data[id] = ce;

		ath10k_err(ar, "[%02d]: 0x%08x %3u %3u %3u %3u", id,
			   le32_to_cpu(ce.base_addr),
			   le32_to_cpu(ce.src_wr_idx),
			   le32_to_cpu(ce.src_r_idx),
			   le32_to_cpu(ce.dst_wr_idx),
			   le32_to_cpu(ce.dst_r_idx));
	}

	spin_unlock_bh(&ar_pci->ce_lock);
}
Ejemplo n.º 20
0
Archivo: ahb.c Proyecto: Anjali05/linux
static int ath10k_ahb_hif_power_up(struct ath10k *ar,
				   enum ath10k_firmware_mode fw_mode)
{
	int ret;

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif power up\n");

	ret = ath10k_ahb_chip_reset(ar);
	if (ret) {
		ath10k_err(ar, "failed to reset chip: %d\n", ret);
		goto out;
	}

	ret = ath10k_pci_init_pipes(ar);
	if (ret) {
		ath10k_err(ar, "failed to initialize CE: %d\n", ret);
		goto out;
	}

	ret = ath10k_pci_init_config(ar);
	if (ret) {
		ath10k_err(ar, "failed to setup init config: %d\n", ret);
		goto err_ce_deinit;
	}

	ret = ath10k_ahb_wake_target_cpu(ar);
	if (ret) {
		ath10k_err(ar, "could not wake up target CPU: %d\n", ret);
		goto err_ce_deinit;
	}

	return 0;

err_ce_deinit:
	ath10k_pci_ce_deinit(ar);
out:
	return ret;
}
Ejemplo n.º 21
0
int ath10k_core_register(struct ath10k *ar, u32 chip_id)
{
	int status;

	ar->chip_id = chip_id;

	status = ath10k_core_check_chip_id(ar);
	if (status) {
		ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id);
		return status;
	}

	status = ath10k_core_probe_fw(ar);
	if (status) {
		ath10k_err("could not probe fw (%d)\n", status);
		return status;
	}

	status = ath10k_mac_register(ar);
	if (status) {
		ath10k_err("could not register to mac80211 (%d)\n", status);
		goto err_release_fw;
	}

	status = ath10k_debug_create(ar);
	if (status) {
		ath10k_err("unable to initialize debugfs\n");
		goto err_unregister_mac;
	}

	return 0;

err_unregister_mac:
	ath10k_mac_unregister(ar);
err_release_fw:
	ath10k_core_free_firmware_files(ar);
	return status;
}
Ejemplo n.º 22
0
Archivo: htt.c Proyecto: 7799/linux
static int ath10k_htt_verify_version(struct ath10k_htt *htt)
{
	ath10k_dbg(ATH10K_DBG_BOOT, "htt target version %d.%d\n",
		   htt->target_version_major, htt->target_version_minor);

	if (htt->target_version_major != 2 &&
	    htt->target_version_major != 3) {
		ath10k_err("unsupported htt major version %d. supported versions are 2 and 3\n",
			   htt->target_version_major);
		return -ENOTSUPP;
	}

	return 0;
}
Ejemplo n.º 23
0
int
athp_ioctl_setup(struct ath10k *ar)
{

	ar->sc_cdev = make_dev(&athp_cdevsw, device_get_unit(ar->sc_dev),
	    UID_ROOT, GID_WHEEL, 0600, "%s", device_get_nameunit(ar->sc_dev));
	if (ar->sc_cdev == NULL) {
		ath10k_err(ar, "%s: failed to create ioctl node\n", __func__);
		return (-1);
	}

	ar->sc_cdev->si_drv1 = ar;
	return (0);
}
Ejemplo n.º 24
0
void
athp_freebuf(struct ath10k *ar, struct athp_buf_ring *br,
    struct athp_buf *bf)
{
	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(bf);

	/* Complain if the buffer has a noderef left */
	if (cb->ni != NULL) {
		ath10k_err(ar, "%s: TODO: pbuf=%p, mbuf=%p, ni is not null (%p) !\n",
		    __func__,
		    bf,
		    bf->m,
		    cb->ni);
	}

	ATHP_BUF_LOCK(ar);

	if (br->btype != bf->btype) {
		ath10k_err(ar, "%s: ERROR: bf=%p, bf btype=%d, ring btype=%d\n",
		    __func__,
		    bf,
		    bf->btype,
		    br->btype);
	}

	ath10k_dbg(ar, ATH10K_DBG_PBUF,
	    "%s: br=%d, m=%p, bf=%p, paddr=0x%lx\n",
	    __func__, br->btype, bf->m, bf, bf->mb.paddr);

	/* if there's an mbuf - unmap (if needed) and free it */
	if (bf->m != NULL)
		_athp_free_buf(ar, br, bf);

	/* Push it into the inactive queue */
	TAILQ_INSERT_TAIL(&br->br_inactive, bf, next);
	ATHP_BUF_UNLOCK(ar);
}
Ejemplo n.º 25
0
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
				      size_t data_len)
{
	u32 board_data_size = ar->hw_params.fw.board_size;
	u32 address;
	int ret;

	ret = ath10k_push_board_ext_data(ar, data, data_len);
	if (ret) {
		ath10k_err(ar, "could not push board ext data (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_read32(ar, hi_board_data, &address);
	if (ret) {
		ath10k_err(ar, "could not read board data addr (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_write_memory(ar, address, data,
				      min_t(u32, board_data_size,
					    data_len));
	if (ret) {
		ath10k_err(ar, "could not write board data (%d)\n", ret);
		goto exit;
	}

	ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
	if (ret) {
		ath10k_err(ar, "could not write board data bit (%d)\n", ret);
		goto exit;
	}

exit:
	return ret;
}
Ejemplo n.º 26
0
Archivo: core.c Proyecto: muonn/ath
static int ath10k_init_download_firmware(struct ath10k *ar)
{
	int ret;

	ret = ath10k_download_board_data(ar);
	if (ret) {
		ath10k_err("failed to download board data: %d\n", ret);
		return ret;
	}

	ret = ath10k_download_and_run_otp(ar);
	if (ret) {
		ath10k_err("failed to run otp: %d\n", ret);
		return ret;
	}

	ret = ath10k_download_fw(ar);
	if (ret) {
		ath10k_err("failed to download firmware: %d\n", ret);
		return ret;
	}

	return ret;
}
Ejemplo n.º 27
0
Archivo: swap.c Proyecto: 020gzh/linux
static struct ath10k_swap_code_seg_info *
ath10k_swap_code_seg_alloc(struct ath10k *ar, size_t swap_bin_len)
{
	struct ath10k_swap_code_seg_info *seg_info;
	void *virt_addr;
	dma_addr_t paddr;

	swap_bin_len = roundup(swap_bin_len, 2);
	if (swap_bin_len > ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX) {
		ath10k_err(ar, "refusing code swap bin because it is too big %zu > %d\n",
			   swap_bin_len, ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX);
		return NULL;
	}

	seg_info = devm_kzalloc(ar->dev, sizeof(*seg_info), GFP_KERNEL);
	if (!seg_info)
		return NULL;

	virt_addr = dma_alloc_coherent(ar->dev, swap_bin_len, &paddr,
				       GFP_KERNEL);
	if (!virt_addr) {
		ath10k_err(ar, "failed to allocate dma coherent memory\n");
		return NULL;
	}

	seg_info->seg_hw_info.bus_addr[0] = __cpu_to_le32(paddr);
	seg_info->seg_hw_info.size = __cpu_to_le32(swap_bin_len);
	seg_info->seg_hw_info.swap_size = __cpu_to_le32(swap_bin_len);
	seg_info->seg_hw_info.num_segs =
			__cpu_to_le32(ATH10K_SWAP_CODE_SEG_NUM_SUPPORTED);
	seg_info->seg_hw_info.size_log2 = __cpu_to_le32(ilog2(swap_bin_len));
	seg_info->virt_address[0] = virt_addr;
	seg_info->paddr[0] = paddr;

	return seg_info;
}
Ejemplo n.º 28
0
Archivo: core.c Proyecto: 3null/linux
int ath10k_core_register(struct ath10k *ar, u32 chip_id)
{
	int status;

	ar->chip_id = chip_id;

	status = ath10k_core_check_chip_id(ar);
	if (status) {
		ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id);
		return status;
	}

	queue_work(ar->workqueue, &ar->register_work);

	return 0;
}
Ejemplo n.º 29
0
Archivo: core.c Proyecto: muonn/ath
static int ath10k_download_fw(struct ath10k *ar)
{
	u32 address;
	int ret;

	address = ar->hw_params.patch_load_addr;

	ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data,
				       ar->firmware_len);
	if (ret) {
		ath10k_err("could not write fw (%d)\n", ret);
		goto exit;
	}

exit:
	return ret;
}
Ejemplo n.º 30
0
static int ath10k_core_fetch_generic_board_file(struct ath10k *ar)
{
	if (!ar->hw_params.fw.board) {
		ath10k_err(ar, "failed to find board file fw entry\n");
		return -EINVAL;
	}

	ar->board = ath10k_fetch_fw_file(ar,
					 ar->hw_params.fw.dir,
					 ar->hw_params.fw.board);
	if (IS_ERR(ar->board))
		return PTR_ERR(ar->board);

	ar->board_data = ar->board->data;
	ar->board_len = ar->board->size;
	ar->spec_board_loaded = false;

	return 0;
}