Commit 728e26c3 authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for v5.17. Major changes:

ath10k

* fetch (pre-)calibration data via nvmem subsystem

ath11k

* enable 802.11 power save mode in station mode for qca6390 and wcn6855

* trace log support

* proper board file detection for WCN6855 based on PCI ids

* BSS color change support
parents 3b1abcf1 5125b9a9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -153,6 +153,10 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
			ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START");
			return;
		}
		if (!cmd->odata) {
			ar5523_err(ar, "Unexpected WDCMSG_TARGET_START reply");
			return;
		}
		memcpy(cmd->odata, hdr + 1, sizeof(u32));
		cmd->olen = sizeof(u32);
		cmd->res = 0;
+62 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/dmi.h>
#include <linux/ctype.h>
#include <linux/pm_qos.h>
#include <linux/nvmem-consumer.h>
#include <asm/byteorder.h>

#include "core.h"
@@ -935,7 +936,8 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
	}

	if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
		bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
	else
		bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
@@ -1726,7 +1728,8 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)

	/* As of now pre-cal is valid for 10_4 variants */
	if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
	    ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
		bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;

	ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
@@ -1853,6 +1856,39 @@ static int ath10k_download_cal_eeprom(struct ath10k *ar)
	return ret;
}

static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
{
	struct nvmem_cell *cell;
	void *buf;
	size_t len;
	int ret;

	cell = devm_nvmem_cell_get(ar->dev, cell_name);
	if (IS_ERR(cell)) {
		ret = PTR_ERR(cell);
		return ret;
	}

	buf = nvmem_cell_read(cell, &len);
	if (IS_ERR(buf))
		return PTR_ERR(buf);

	if (ar->hw_params.cal_data_len != len) {
		kfree(buf);
		ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
			    cell_name, len, ar->hw_params.cal_data_len);
		return -EMSGSIZE;
	}

	ret = ath10k_download_board_data(ar, buf, len);
	kfree(buf);
	if (ret)
		ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
			    cell_name, ret);

	return ret;
}

int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
				     struct ath10k_fw_file *fw_file)
{
@@ -2087,6 +2123,18 @@ static int ath10k_core_pre_cal_download(struct ath10k *ar)
{
	int ret;

	ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
	if (ret == 0) {
		ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
		goto success;
	} else if (ret == -EPROBE_DEFER) {
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
		   ret);

	ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
	if (ret == 0) {
		ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
@@ -2153,6 +2201,18 @@ static int ath10k_download_cal_data(struct ath10k *ar)
		   "pre cal download procedure failed, try cal file: %d\n",
		   ret);

	ret = ath10k_download_cal_nvmem(ar, "calibration");
	if (ret == 0) {
		ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
		goto done;
	} else if (ret == -EPROBE_DEFER) {
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot did not find a calibration nvmem-cell, try file next: %d\n",
		   ret);

	ret = ath10k_download_cal_file(ar, ar->cal_file);
	if (ret == 0) {
		ar->cal_mode = ATH10K_CAL_MODE_FILE;
+6 −0
Original line number Diff line number Diff line
@@ -877,8 +877,10 @@ enum ath10k_cal_mode {
	ATH10K_CAL_MODE_FILE,
	ATH10K_CAL_MODE_OTP,
	ATH10K_CAL_MODE_DT,
	ATH10K_CAL_MODE_NVMEM,
	ATH10K_PRE_CAL_MODE_FILE,
	ATH10K_PRE_CAL_MODE_DT,
	ATH10K_PRE_CAL_MODE_NVMEM,
	ATH10K_CAL_MODE_EEPROM,
};

@@ -898,10 +900,14 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
		return "otp";
	case ATH10K_CAL_MODE_DT:
		return "dt";
	case ATH10K_CAL_MODE_NVMEM:
		return "nvmem";
	case ATH10K_PRE_CAL_MODE_FILE:
		return "pre-cal-file";
	case ATH10K_PRE_CAL_MODE_DT:
		return "pre-cal-dt";
	case ATH10K_PRE_CAL_MODE_NVMEM:
		return "pre-cal-nvmem";
	case ATH10K_CAL_MODE_EEPROM:
		return "eeprom";
	}
+41 −14
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ const struct ce_attr ath11k_host_ce_config_ipq8074[] = {
		.src_nentries = 16,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE1: target->host HTT + HTC control */
@@ -40,6 +41,7 @@ const struct ce_attr ath11k_host_ce_config_ipq8074[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE4: host->target HTT */
@@ -73,11 +75,12 @@ const struct ce_attr ath11k_host_ce_config_ipq8074[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE8: target autonomous hif_memcpy */
	{
		.flags = CE_ATTR_FLAGS,
		.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
		.src_nentries = 0,
		.src_sz_max = 0,
		.dest_nentries = 0,
@@ -89,6 +92,7 @@ const struct ce_attr ath11k_host_ce_config_ipq8074[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE10: target->host HTT */
@@ -142,6 +146,7 @@ const struct ce_attr ath11k_host_ce_config_qca6390[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE4: host->target HTT */
@@ -175,6 +180,7 @@ const struct ce_attr ath11k_host_ce_config_qca6390[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE8: target autonomous hif_memcpy */
@@ -220,6 +226,7 @@ const struct ce_attr ath11k_host_ce_config_qcn9074[] = {
		.src_nentries = 32,
		.src_sz_max = 2048,
		.dest_nentries = 0,
		.send_cb = ath11k_htc_tx_completion_handler,
	},

	/* CE4: host->target HTT */
@@ -489,18 +496,32 @@ static struct sk_buff *ath11k_ce_completed_send_next(struct ath11k_ce_pipe *pipe
	return skb;
}

static void ath11k_ce_send_done_cb(struct ath11k_ce_pipe *pipe)
static void ath11k_ce_tx_process_cb(struct ath11k_ce_pipe *pipe)
{
	struct ath11k_base *ab = pipe->ab;
	struct sk_buff *skb;
	struct sk_buff_head list;

	__skb_queue_head_init(&list);
	while (!IS_ERR(skb = ath11k_ce_completed_send_next(pipe))) {
		if (!skb)
			continue;

		dma_unmap_single(ab->dev, ATH11K_SKB_CB(skb)->paddr, skb->len,
				 DMA_TO_DEVICE);

		if ((!pipe->send_cb) || ab->hw_params.credit_flow) {
			dev_kfree_skb_any(skb);
			continue;
		}

		__skb_queue_tail(&list, skb);
	}

	while ((skb = __skb_dequeue(&list))) {
		ath11k_dbg(ab, ATH11K_DBG_AHB, "tx ce pipe %d len %d\n",
			   pipe->pipe_num, skb->len);
		pipe->send_cb(ab, skb);
	}
}

@@ -636,7 +657,7 @@ static int ath11k_ce_alloc_pipe(struct ath11k_base *ab, int ce_id)
	pipe->attr_flags = attr->flags;

	if (attr->src_nentries) {
		pipe->send_cb = ath11k_ce_send_done_cb;
		pipe->send_cb = attr->send_cb;
		nentries = roundup_pow_of_two(attr->src_nentries);
		desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
		ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
@@ -667,9 +688,10 @@ static int ath11k_ce_alloc_pipe(struct ath11k_base *ab, int ce_id)
void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id)
{
	struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id];
	const struct ce_attr *attr = &ab->hw_params.host_ce_config[ce_id];

	if (pipe->send_cb)
		pipe->send_cb(pipe);
	if (attr->src_nentries)
		ath11k_ce_tx_process_cb(pipe);

	if (pipe->recv_cb)
		ath11k_ce_recv_process_cb(pipe);
@@ -678,9 +700,10 @@ void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id)
void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id)
{
	struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[pipe_id];
	const struct ce_attr *attr =  &ab->hw_params.host_ce_config[pipe_id];

	if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && pipe->send_cb)
		pipe->send_cb(pipe);
	if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && attr->src_nentries)
		ath11k_ce_tx_process_cb(pipe);
}
EXPORT_SYMBOL(ath11k_ce_per_engine_service);

@@ -953,6 +976,7 @@ int ath11k_ce_init_pipes(struct ath11k_base *ab)
void ath11k_ce_free_pipes(struct ath11k_base *ab)
{
	struct ath11k_ce_pipe *pipe;
	struct ath11k_ce_ring *ce_ring;
	int desc_sz;
	int i;

@@ -964,22 +988,24 @@ void ath11k_ce_free_pipes(struct ath11k_base *ab)

		if (pipe->src_ring) {
			desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
			ce_ring = pipe->src_ring;
			dma_free_coherent(ab->dev,
					  pipe->src_ring->nentries * desc_sz +
					  CE_DESC_RING_ALIGN,
					  pipe->src_ring->base_addr_owner_space,
					  pipe->src_ring->base_addr_ce_space);
					  ce_ring->base_addr_owner_space_unaligned,
					  ce_ring->base_addr_ce_space_unaligned);
			kfree(pipe->src_ring);
			pipe->src_ring = NULL;
		}

		if (pipe->dest_ring) {
			desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST);
			ce_ring = pipe->dest_ring;
			dma_free_coherent(ab->dev,
					  pipe->dest_ring->nentries * desc_sz +
					  CE_DESC_RING_ALIGN,
					  pipe->dest_ring->base_addr_owner_space,
					  pipe->dest_ring->base_addr_ce_space);
					  ce_ring->base_addr_owner_space_unaligned,
					  ce_ring->base_addr_ce_space_unaligned);
			kfree(pipe->dest_ring);
			pipe->dest_ring = NULL;
		}
@@ -987,11 +1013,12 @@ void ath11k_ce_free_pipes(struct ath11k_base *ab)
		if (pipe->status_ring) {
			desc_sz =
			  ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS);
			ce_ring = pipe->status_ring;
			dma_free_coherent(ab->dev,
					  pipe->status_ring->nentries * desc_sz +
					  CE_DESC_RING_ALIGN,
					  pipe->status_ring->base_addr_owner_space,
					  pipe->status_ring->base_addr_ce_space);
					  ce_ring->base_addr_owner_space_unaligned,
					  ce_ring->base_addr_ce_space_unaligned);
			kfree(pipe->status_ring);
			pipe->status_ring = NULL;
		}
+2 −1
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ struct ce_attr {
	unsigned int dest_nentries;

	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
	void (*send_cb)(struct ath11k_base *, struct sk_buff *);
};

#define CE_DESC_RING_ALIGN 8
@@ -154,7 +155,7 @@ struct ath11k_ce_pipe {
	unsigned int buf_sz;
	unsigned int rx_buf_needed;

	void (*send_cb)(struct ath11k_ce_pipe *);
	void (*send_cb)(struct ath11k_base *, struct sk_buff *);
	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);

	struct tasklet_struct intr_tq;
Loading