Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1b4b511 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge ath-next from ath.git

Major changes:

ath10k

* support Manegement Frame Protection (MFP)
* add thermal throttling support for 10.4 firmware
* add support for pktlog in QCA99X0
* add debugfs file to enable Bluetooth coexistence feature
* use firmware's native mesh interface type instead of raw mode
parents b31fa550 9e100c4d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ config ATH10K
        tristate "Atheros 802.11ac wireless cards support"
        depends on MAC80211 && HAS_DMA
	select ATH_COMMON
	select CRC32
        ---help---
          This module adds support for wireless adapters based on
          Atheros IEEE 802.11ac family of chipsets.
+13 −3
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
		.fw = {
			.dir = QCA988X_HW_2_0_FW_DIR,
			.fw = QCA988X_HW_2_0_FW_FILE,
@@ -75,6 +76,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
		.fw = {
			.dir = QCA6174_HW_2_1_FW_DIR,
			.fw = QCA6174_HW_2_1_FW_FILE,
@@ -92,6 +94,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
		.fw = {
			.dir = QCA6174_HW_3_0_FW_DIR,
			.fw = QCA6174_HW_3_0_FW_FILE,
@@ -109,6 +112,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
		.fw = {
			/* uses same binaries as hw3.0 */
			.dir = QCA6174_HW_3_0_FW_DIR,
@@ -128,6 +132,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
		.continuous_frag_desc = true,
		.channel_counters_freq_hz = 150000,
		.max_probe_resp_desc_thres = 24,
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
		.fw = {
			.dir = QCA99X0_HW_2_0_FW_DIR,
			.fw = QCA99X0_HW_2_0_FW_FILE,
@@ -167,6 +172,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
	[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
	[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
	[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
	[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
};

static unsigned int ath10k_core_get_fw_feature_str(char *buf,
@@ -843,7 +849,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
	if (!ar->board_data || !ar->board_len) {
		ath10k_err(ar,
			   "failed to fetch board data for %s from %s/%s\n",
			   ar->hw_params.fw.dir, boardname, filename);
			   boardname, ar->hw_params.fw.dir, filename);
		ret = -ENODATA;
		goto err;
	}
@@ -1745,9 +1751,11 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
		goto err_power_down;
	}

	ath10k_debug_print_hwfw_info(ar);

	ret = ath10k_core_get_board_id_from_otp(ar);
	if (ret && ret != -EOPNOTSUPP) {
		ath10k_err(ar, "failed to get board id from otp for qca99x0: %d\n",
		ath10k_err(ar, "failed to get board id from otp: %d\n",
			   ret);
		return ret;
	}
@@ -1758,6 +1766,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
		goto err_free_firmware_files;
	}

	ath10k_debug_print_board_info(ar);

	ret = ath10k_core_init_firmware_features(ar);
	if (ret) {
		ath10k_err(ar, "fatal problem with firmware features: %d\n",
@@ -1780,7 +1790,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
		goto err_unlock;
	}

	ath10k_print_driver_info(ar);
	ath10k_debug_print_boot_info(ar);
	ath10k_core_stop(ar);

	mutex_unlock(&ar->conf_mutex);
+21 −17
Original line number Diff line number Diff line
@@ -81,26 +81,20 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
	return "unknown";
}

enum ath10k_skb_flags {
	ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
	ATH10K_SKB_F_DTIM_ZERO = BIT(1),
	ATH10K_SKB_F_DELIVER_CAB = BIT(2),
	ATH10K_SKB_F_MGMT = BIT(3),
	ATH10K_SKB_F_QOS = BIT(4),
};

struct ath10k_skb_cb {
	dma_addr_t paddr;
	u8 flags;
	u8 eid;
	u8 vdev_id;
	enum ath10k_hw_txrx_mode txmode;
	bool is_protected;

	struct {
		u8 tid;
		u16 freq;
		bool is_offchan;
		bool nohwcrypt;
		struct ath10k_htt_txbuf *txbuf;
		u32 txbuf_paddr;
	} __packed htt;

	struct {
		bool dtim_zero;
		bool deliver_cab;
	} bcn;
	u16 msdu_id;
	struct ieee80211_vif *vif;
} __packed;

struct ath10k_skb_rxcb {
@@ -151,6 +145,7 @@ struct ath10k_wmi {
	struct wmi_vdev_param_map *vdev_param;
	struct wmi_pdev_param_map *pdev_param;
	const struct wmi_ops *ops;
	const struct wmi_peer_flags_map *peer_flags;

	u32 num_mem_chunks;
	u32 rx_decap_mode;
@@ -512,6 +507,9 @@ enum ath10k_fw_features {
	/* Firmware Supports Adaptive CCA*/
	ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA = 11,

	/* Firmware supports management frame protection */
	ATH10K_FW_FEATURE_MFP_SUPPORT = 12,

	/* keep last */
	ATH10K_FW_FEATURE_COUNT,
};
@@ -534,6 +532,9 @@ enum ath10k_dev_flags {

	/* Disable HW crypto engine */
	ATH10K_FLAG_HW_CRYPTO_DISABLED,

	/* Bluetooth coexistance enabled */
	ATH10K_FLAG_BTCOEX,
};

enum ath10k_cal_mode {
@@ -661,6 +662,9 @@ struct ath10k {
		 */
		u32 max_probe_resp_desc_thres;

		/* The padding bytes's location is different on various chips */
		enum ath10k_hw_4addr_pad hw_4addr_pad;

		struct ath10k_hw_params_fw {
			const char *dir;
			const char *fw;
+172 −25
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/debugfs.h>
#include <linux/vmalloc.h>
#include <linux/utsname.h>
#include <linux/crc32.h>
#include <linux/firmware.h>

#include "core.h"
#include "debug.h"
@@ -122,28 +124,51 @@ void ath10k_info(struct ath10k *ar, const char *fmt, ...)
}
EXPORT_SYMBOL(ath10k_info);

void ath10k_print_driver_info(struct ath10k *ar)
void ath10k_debug_print_hwfw_info(struct ath10k *ar)
{
	char fw_features[128] = {};
	char boardinfo[100];

	ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));

	if (ar->id.bmi_ids_valid)
		scnprintf(boardinfo, sizeof(boardinfo), "bmi %d:%d",
			  ar->id.bmi_chip_id, ar->id.bmi_board_id);
	else
		scnprintf(boardinfo, sizeof(boardinfo), "sub %04x:%04x",
			  ar->id.subsystem_vendor, ar->id.subsystem_device);

	ath10k_info(ar, "%s (0x%08x, 0x%08x %s) fw %s fwapi %d bdapi %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n",
	ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
		    ar->hw_params.name,
		    ar->target_version,
		    ar->chip_id,
		    boardinfo,
		    ar->id.subsystem_vendor, ar->id.subsystem_device);

	ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
		    config_enabled(CONFIG_ATH10K_DEBUG),
		    config_enabled(CONFIG_ATH10K_DEBUGFS),
		    config_enabled(CONFIG_ATH10K_TRACING),
		    config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
		    config_enabled(CONFIG_NL80211_TESTMODE));

	ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n",
		    ar->hw->wiphy->fw_version,
		    ar->fw_api,
		    fw_features,
		    crc32_le(0, ar->firmware->data, ar->firmware->size));
}

void ath10k_debug_print_board_info(struct ath10k *ar)
{
	char boardinfo[100];

	if (ar->id.bmi_ids_valid)
		scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
			  ar->id.bmi_chip_id, ar->id.bmi_board_id);
	else
		scnprintf(boardinfo, sizeof(boardinfo), "N/A");

	ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
		    ar->bd_api,
		    boardinfo,
		    crc32_le(0, ar->board->data, ar->board->size));
}

void ath10k_debug_print_boot_info(struct ath10k *ar)
{
	ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n",
		    ar->htt.target_version_major,
		    ar->htt.target_version_minor,
		    ar->wmi.op_version,
@@ -151,14 +176,14 @@ void ath10k_print_driver_info(struct ath10k *ar)
		    ath10k_cal_mode_str(ar->cal_mode),
		    ar->max_num_stations,
		    test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags),
		    !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags),
		    fw_features);
	ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
		    config_enabled(CONFIG_ATH10K_DEBUG),
		    config_enabled(CONFIG_ATH10K_DEBUGFS),
		    config_enabled(CONFIG_ATH10K_TRACING),
		    config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
		    config_enabled(CONFIG_NL80211_TESTMODE));
		    !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags));
}

void ath10k_print_driver_info(struct ath10k *ar)
{
	ath10k_debug_print_hwfw_info(ar);
	ath10k_debug_print_board_info(ar);
	ath10k_debug_print_boot_info(ar);
}
EXPORT_SYMBOL(ath10k_print_driver_info);

@@ -2074,6 +2099,121 @@ static const struct file_operations fops_quiet_period = {
	.open = simple_open
};

static ssize_t ath10k_write_btcoex(struct file *file,
				   const char __user *ubuf,
				   size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	char buf[32];
	size_t buf_size;
	bool val;

	buf_size = min(count, (sizeof(buf) - 1));
	if (copy_from_user(buf, ubuf, buf_size))
		return -EFAULT;

	buf[buf_size] = '\0';

	if (strtobool(buf, &val) != 0)
		return -EINVAL;

	mutex_lock(&ar->conf_mutex);

	if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
		goto exit;

	if (val)
		set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
	else
		clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);

	if (ar->state != ATH10K_STATE_ON)
		goto exit;

	ath10k_info(ar, "restarting firmware due to btcoex change");

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

exit:
	mutex_unlock(&ar->conf_mutex);

	return count;
}

static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
				  size_t count, loff_t *ppos)
{
	char buf[32];
	struct ath10k *ar = file->private_data;
	int len = 0;

	mutex_lock(&ar->conf_mutex);
	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
			test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
	mutex_unlock(&ar->conf_mutex);

	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
}

static const struct file_operations fops_btcoex = {
	.read = ath10k_read_btcoex,
	.write = ath10k_write_btcoex,
	.open = simple_open
};

static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
					      char __user *user_buf,
					      size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	unsigned int len = 0, buf_len = 4096;
	ssize_t ret_cnt;
	char *buf;

	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	mutex_lock(&ar->conf_mutex);

	if (len > buf_len)
		len = buf_len;

	len += scnprintf(buf + len, buf_len - len,
			 "firmware-N.bin\t\t%08x\n",
			 crc32_le(0, ar->firmware->data, ar->firmware->size));
	len += scnprintf(buf + len, buf_len - len,
			 "athwlan\t\t\t%08x\n",
			 crc32_le(0, ar->firmware_data, ar->firmware_len));
	len += scnprintf(buf + len, buf_len - len,
			 "otp\t\t\t%08x\n",
			 crc32_le(0, ar->otp_data, ar->otp_len));
	len += scnprintf(buf + len, buf_len - len,
			 "codeswap\t\t%08x\n",
			 crc32_le(0, ar->swap.firmware_codeswap_data,
				  ar->swap.firmware_codeswap_len));
	len += scnprintf(buf + len, buf_len - len,
			 "board-N.bin\t\t%08x\n",
			 crc32_le(0, ar->board->data, ar->board->size));
	len += scnprintf(buf + len, buf_len - len,
			 "board\t\t\t%08x\n",
			 crc32_le(0, ar->board_data, ar->board_len));

	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);

	mutex_unlock(&ar->conf_mutex);

	kfree(buf);
	return ret_cnt;
}

static const struct file_operations fops_fw_checksums = {
	.read = ath10k_debug_fw_checksums_read,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

int ath10k_debug_create(struct ath10k *ar)
{
	ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
@@ -2123,8 +2263,8 @@ int ath10k_debug_register(struct ath10k *ar)
	debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
			    &fops_wmi_services);

	debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_simulate_fw_crash);
	debugfs_create_file("simulate_fw_crash", S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar, &fops_simulate_fw_crash);

	debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_fw_crash_dump);
@@ -2141,15 +2281,15 @@ int ath10k_debug_register(struct ath10k *ar)
	debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_chip_id);

	debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_htt_stats_mask);
	debugfs_create_file("htt_stats_mask", S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar, &fops_htt_stats_mask);

	debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar,
			    &fops_htt_max_amsdu_ampdu);

	debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_fw_dbglog);
	debugfs_create_file("fw_dbglog", S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar, &fops_fw_dbglog);

	debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_cal_data);
@@ -2183,6 +2323,13 @@ int ath10k_debug_register(struct ath10k *ar)
	debugfs_create_file("tpc_stats", S_IRUSR,
			    ar->debug.debugfs_phy, ar, &fops_tpc_stats);

	if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
		debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
				    ar->debug.debugfs_phy, ar, &fops_btcoex);

	debugfs_create_file("fw_checksums", S_IRUSR,
			    ar->debug.debugfs_phy, ar, &fops_fw_checksums);

	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ extern unsigned int ath10k_debug_mask;
__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
__printf(2, 3) void ath10k_err(struct ath10k *ar, const char *fmt, ...);
__printf(2, 3) void ath10k_warn(struct ath10k *ar, const char *fmt, ...);

void ath10k_debug_print_hwfw_info(struct ath10k *ar);
void ath10k_debug_print_board_info(struct ath10k *ar);
void ath10k_debug_print_boot_info(struct ath10k *ar);
void ath10k_print_driver_info(struct ath10k *ar);

#ifdef CONFIG_ATH10K_DEBUGFS
Loading