Пример #1
0
static void wcn36xx_stop(struct ieee80211_hw *hw)
{
	struct wcn36xx *wcn = hw->priv;

	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop");

	wcn36xx_debugfs_exit(wcn);
	wcn36xx_smd_stop(wcn);
	wcn36xx_dxe_deinit(wcn);
	wcn36xx_smd_close(wcn);

	wcn36xx_dxe_free_mem_pools(wcn);
	wcn36xx_dxe_free_ctl_blks(wcn);

	kfree(wcn->smd_buf);
}
Пример #2
0
int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn)
{
    size_t s;
    void *cpu_addr;

    /* Allocate BD headers for MGMT frames */

    /* Where this come from ask QC */
    wcn->mgmt_mem_pool.chunk_size =	WCN36XX_BD_CHUNK_SIZE +
                                    16 - (WCN36XX_BD_CHUNK_SIZE % 8);

    s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H;
    cpu_addr = dma_alloc_coherent(NULL, s, &wcn->mgmt_mem_pool.phy_addr,
                                  GFP_KERNEL);
    if (!cpu_addr)
        goto out_err;

    wcn->mgmt_mem_pool.virt_addr = cpu_addr;
    memset(cpu_addr, 0, s);

    /* Allocate BD headers for DATA frames */

    /* Where this come from ask QC */
    wcn->data_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE +
                                    16 - (WCN36XX_BD_CHUNK_SIZE % 8);

    s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L;
    cpu_addr = dma_alloc_coherent(NULL, s, &wcn->data_mem_pool.phy_addr,
                                  GFP_KERNEL);
    if (!cpu_addr)
        goto out_err;

    wcn->data_mem_pool.virt_addr = cpu_addr;
    memset(cpu_addr, 0, s);

    return 0;

out_err:
    wcn36xx_dxe_free_mem_pools(wcn);
    wcn36xx_err("Failed to allocate BD mempool\n");
    return -ENOMEM;
}
Пример #3
0
static int wcn36xx_start(struct ieee80211_hw *hw)
{
	struct wcn36xx *wcn = hw->priv;
	int ret;

	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac start");

	/* SMD initialization */
	ret = wcn36xx_smd_open(wcn);
	if (ret) {
		wcn36xx_error("Failed to open smd channel: %d", ret);
		goto out_err;
	}

	/* Not to receive INT until the whole buf from SMD is read */
	smd_disable_read_intr(wcn->smd_ch);

	/* Allocate memory pools for Mgmt BD headers and Data BD headers */
	ret = wcn36xx_dxe_allocate_mem_pools(wcn);
	if (ret) {
		wcn36xx_error("Failed to alloc DXE mempool: %d", ret);
		goto out_smd_close;
	}

	wcn36xx_dxe_alloc_ctl_blks(wcn);
	if (ret) {
		wcn36xx_error("Failed to alloc DXE ctl blocks: %d", ret);
		goto out_free_dxe_pool;
	}

	INIT_WORK(&wcn->rx_ready_work, wcn36xx_rx_ready_work);

	/* Maximum SMD message size is 4k */
	wcn->smd_buf = kmalloc(4096, GFP_KERNEL);
	if (!wcn->smd_buf) {
		wcn36xx_error("Failed to allocate smd buf");
		ret = -ENOMEM;
		goto out_free_dxe_ctl;
	}

	/* TODO pass configuration to FW */
	ret = wcn36xx_smd_load_nv(wcn);
	if (ret) {
		wcn36xx_error("Failed to push NV to chip");
		goto out_free_smd_buf;
	}

	ret = wcn36xx_smd_start(wcn);
	if (ret) {
		wcn36xx_error("Failed to start chip");
		goto out_free_smd_buf;
	}

	/* DMA channel initialization */
	ret = wcn36xx_dxe_init(wcn);
	if (ret) {
		wcn36xx_error("DXE init failed");
		goto out_smd_stop;
	}

	wcn36xx_pmc_init(wcn);
	wcn36xx_debugfs_init(wcn);

	if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
		ret = wcn36xx_smd_feature_caps_exchange(wcn);
		if (ret)
			wcn36xx_warn("Exchange feature caps failed");
	}

	return 0;

out_smd_stop:
	wcn36xx_smd_stop(wcn);
out_free_smd_buf:
	kfree(wcn->smd_buf);
out_free_dxe_pool:
	wcn36xx_dxe_free_mem_pools(wcn);
out_free_dxe_ctl:
	wcn36xx_dxe_free_ctl_blks(wcn);
out_smd_close:
	wcn36xx_smd_close(wcn);
out_err:
	return ret;
}