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

Commit cbe1bc23 authored by John W. Linville's avatar John W. Linville
Browse files

Merge branch 'for-linville' of git://github.com/kvalo/ath

parents 992066c8 fe2407a8
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -799,6 +799,17 @@ static void ath10k_core_restart(struct work_struct *work)
	mutex_unlock(&ar->conf_mutex);
}

static void ath10k_core_init_max_sta_count(struct ath10k *ar)
{
	if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
		ar->max_num_peers = TARGET_10X_NUM_PEERS;
		ar->max_num_stations = TARGET_10X_NUM_STATIONS;
	} else {
		ar->max_num_peers = TARGET_NUM_PEERS;
		ar->max_num_stations = TARGET_NUM_STATIONS;
	}
}

int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
{
	int status;
@@ -1035,6 +1046,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
		return ret;
	}

	ath10k_core_init_max_sta_count(ar);

	mutex_lock(&ar->conf_mutex);

	ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
+11 −2
Original line number Diff line number Diff line
@@ -79,10 +79,12 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)

struct ath10k_skb_cb {
	dma_addr_t paddr;
	u8 eid;
	u8 vdev_id;

	struct {
		u8 tid;
		u16 freq;
		bool is_offchan;
		struct ath10k_htt_txbuf *txbuf;
		u32 txbuf_paddr;
@@ -122,6 +124,7 @@ struct ath10k_wmi {
	struct completion service_ready;
	struct completion unified_ready;
	wait_queue_head_t tx_credits_wq;
	DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
	struct wmi_cmd_map *cmd;
	struct wmi_vdev_param_map *vdev_param;
	struct wmi_pdev_param_map *pdev_param;
@@ -218,6 +221,8 @@ struct ath10k_peer {
	int vdev_id;
	u8 addr[ETH_ALEN];
	DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);

	/* protected by ar->data_lock */
	struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
};

@@ -310,7 +315,6 @@ struct ath10k_debug {
	struct ath10k_fw_stats fw_stats;
	struct completion fw_stats_complete;
	bool fw_stats_done;
	DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX);

	unsigned long htt_stats_mask;
	struct delayed_work htt_stats_dwork;
@@ -320,6 +324,7 @@ struct ath10k_debug {
	/* protected by conf_mutex */
	u32 fw_dbglog_mask;
	u32 pktlog_filter;
	u32 reg_addr;

	u8 htt_max_amsdu;
	u8 htt_max_ampdu;
@@ -560,8 +565,12 @@ struct ath10k {
	struct list_head peers;
	wait_queue_head_t peer_mapping_wq;

	/* number of created peers; protected by data_lock */
	/* protected by conf_mutex */
	int num_peers;
	int num_stations;

	int max_num_peers;
	int max_num_stations;

	struct work_struct offchan_tx_work;
	struct sk_buff_head offchan_tx_queue;
+248 −14
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@

#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/version.h>
#include <linux/vermagic.h>
#include <linux/vmalloc.h>
#include <linux/utsname.h>

#include "core.h"
#include "debug.h"
@@ -124,7 +123,7 @@ EXPORT_SYMBOL(ath10k_info);

void ath10k_print_driver_info(struct ath10k *ar)
{
	ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n",
	ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n",
		    ar->hw_params.name,
		    ar->target_version,
		    ar->chip_id,
@@ -136,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar)
		    ar->fw_version_minor,
		    ar->fw_version_release,
		    ar->fw_version_build,
		    ath10k_cal_mode_str(ar->cal_mode));
		    ath10k_cal_mode_str(ar->cal_mode),
		    ar->max_num_stations);
	ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
		    config_enabled(CONFIG_ATH10K_DEBUG),
		    config_enabled(CONFIG_ATH10K_DEBUGFS),
@@ -179,13 +179,6 @@ EXPORT_SYMBOL(ath10k_warn);

#ifdef CONFIG_ATH10K_DEBUGFS

void ath10k_debug_read_service_map(struct ath10k *ar,
				   const void *service_map,
				   size_t map_size)
{
	memcpy(ar->debug.wmi_service_bitmap, service_map, map_size);
}

static ssize_t ath10k_read_wmi_services(struct file *file,
					char __user *user_buf,
					size_t count, loff_t *ppos)
@@ -207,8 +200,9 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
	if (len > buf_len)
		len = buf_len;

	spin_lock_bh(&ar->data_lock);
	for (i = 0; i < WMI_SERVICE_MAX; i++) {
		enabled = test_bit(i, ar->debug.wmi_service_bitmap);
		enabled = test_bit(i, ar->wmi.svc_map);
		name = wmi_service_name(i);

		if (!name) {
@@ -224,6 +218,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
				 "%-40s %s\n",
				 name, enabled ? "enabled" : "-");
	}
	spin_unlock_bh(&ar->data_lock);

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

@@ -866,8 +861,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
	strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
		sizeof(dump_data->fw_ver));

	dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE);
	strlcpy(dump_data->kernel_ver, VERMAGIC_STRING,
	dump_data->kernel_ver_code = 0;
	strlcpy(dump_data->kernel_ver, init_utsname()->release,
		sizeof(dump_data->kernel_ver));

	dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
@@ -929,6 +924,236 @@ static const struct file_operations fops_fw_crash_dump = {
	.llseek = default_llseek,
};

static ssize_t ath10k_reg_addr_read(struct file *file,
				    char __user *user_buf,
				    size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u8 buf[32];
	unsigned int len = 0;
	u32 reg_addr;

	mutex_lock(&ar->conf_mutex);
	reg_addr = ar->debug.reg_addr;
	mutex_unlock(&ar->conf_mutex);

	len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr);

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

static ssize_t ath10k_reg_addr_write(struct file *file,
				     const char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u32 reg_addr;
	int ret;

	ret = kstrtou32_from_user(user_buf, count, 0, &reg_addr);
	if (ret)
		return ret;

	if (!IS_ALIGNED(reg_addr, 4))
		return -EFAULT;

	mutex_lock(&ar->conf_mutex);
	ar->debug.reg_addr = reg_addr;
	mutex_unlock(&ar->conf_mutex);

	return count;
}

static const struct file_operations fops_reg_addr = {
	.read = ath10k_reg_addr_read,
	.write = ath10k_reg_addr_write,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static ssize_t ath10k_reg_value_read(struct file *file,
				     char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u8 buf[48];
	unsigned int len;
	u32 reg_addr, reg_val;
	int ret;

	mutex_lock(&ar->conf_mutex);

	if (ar->state != ATH10K_STATE_ON &&
	    ar->state != ATH10K_STATE_UTF) {
		ret = -ENETDOWN;
		goto exit;
	}

	reg_addr = ar->debug.reg_addr;

	reg_val = ath10k_hif_read32(ar, reg_addr);
	len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val);

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

exit:
	mutex_unlock(&ar->conf_mutex);

	return ret;
}

static ssize_t ath10k_reg_value_write(struct file *file,
				      const char __user *user_buf,
				      size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u32 reg_addr, reg_val;
	int ret;

	mutex_lock(&ar->conf_mutex);

	if (ar->state != ATH10K_STATE_ON &&
	    ar->state != ATH10K_STATE_UTF) {
		ret = -ENETDOWN;
		goto exit;
	}

	reg_addr = ar->debug.reg_addr;

	ret = kstrtou32_from_user(user_buf, count, 0, &reg_val);
	if (ret)
		goto exit;

	ath10k_hif_write32(ar, reg_addr, reg_val);

	ret = count;

exit:
	mutex_unlock(&ar->conf_mutex);

	return ret;
}

static const struct file_operations fops_reg_value = {
	.read = ath10k_reg_value_read,
	.write = ath10k_reg_value_write,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static ssize_t ath10k_mem_value_read(struct file *file,
				     char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u8 *buf;
	int ret;

	if (*ppos < 0)
		return -EINVAL;

	if (!count)
		return 0;

	mutex_lock(&ar->conf_mutex);

	buf = vmalloc(count);
	if (!buf) {
		ret = -ENOMEM;
		goto exit;
	}

	if (ar->state != ATH10K_STATE_ON &&
	    ar->state != ATH10K_STATE_UTF) {
		ret = -ENETDOWN;
		goto exit;
	}

	ret = ath10k_hif_diag_read(ar, *ppos, buf, count);
	if (ret) {
		ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n",
			    (u32)(*ppos), ret);
		goto exit;
	}

	ret = copy_to_user(user_buf, buf, count);
	if (ret) {
		ret = -EFAULT;
		goto exit;
	}

	count -= ret;
	*ppos += count;
	ret = count;

exit:
	vfree(buf);
	mutex_unlock(&ar->conf_mutex);

	return ret;
}

static ssize_t ath10k_mem_value_write(struct file *file,
				      const char __user *user_buf,
				      size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	u8 *buf;
	int ret;

	if (*ppos < 0)
		return -EINVAL;

	if (!count)
		return 0;

	mutex_lock(&ar->conf_mutex);

	buf = vmalloc(count);
	if (!buf) {
		ret = -ENOMEM;
		goto exit;
	}

	if (ar->state != ATH10K_STATE_ON &&
	    ar->state != ATH10K_STATE_UTF) {
		ret = -ENETDOWN;
		goto exit;
	}

	ret = copy_from_user(buf, user_buf, count);
	if (ret) {
		ret = -EFAULT;
		goto exit;
	}

	ret = ath10k_hif_diag_write(ar, *ppos, buf, count);
	if (ret) {
		ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n",
			    (u32)(*ppos), ret);
		goto exit;
	}

	*ppos += count;
	ret = count;

exit:
	vfree(buf);
	mutex_unlock(&ar->conf_mutex);

	return ret;
}

static const struct file_operations fops_mem_value = {
	.read = ath10k_mem_value_read,
	.write = ath10k_mem_value_write,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static int ath10k_debug_htt_stats_req(struct ath10k *ar)
{
	u64 cookie;
@@ -1630,6 +1855,15 @@ int ath10k_debug_register(struct ath10k *ar)
	debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_fw_crash_dump);

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

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

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

	debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
			    ar, &fops_chip_id);

+1 −9
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ enum ath10k_debug_mask {
	ATH10K_DBG_BMI		= 0x00000400,
	ATH10K_DBG_REGULATORY	= 0x00000800,
	ATH10K_DBG_TESTMODE	= 0x00001000,
	ATH10K_DBG_WMI_PRINT	= 0x00002000,
	ATH10K_DBG_ANY		= 0xffffffff,
};

@@ -61,9 +62,6 @@ int ath10k_debug_create(struct ath10k *ar);
void ath10k_debug_destroy(struct ath10k *ar);
int ath10k_debug_register(struct ath10k *ar);
void ath10k_debug_unregister(struct ath10k *ar);
void ath10k_debug_read_service_map(struct ath10k *ar,
				   const void *service_map,
				   size_t map_size);
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
@@ -108,12 +106,6 @@ static inline void ath10k_debug_unregister(struct ath10k *ar)
{
}

static inline void ath10k_debug_read_service_map(struct ath10k *ar,
						 const void *service_map,
						 size_t map_size)
{
}

static inline void ath10k_debug_fw_stats_process(struct ath10k *ar,
						 struct sk_buff *skb)
{
+39 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <linux/kernel.h>
#include "core.h"
#include "debug.h"

struct ath10k_hif_sg_item {
	u16 transfer_id;
@@ -31,11 +32,9 @@ struct ath10k_hif_sg_item {

struct ath10k_hif_cb {
	int (*tx_completion)(struct ath10k *ar,
			     struct sk_buff *wbuf,
			     unsigned transfer_id);
			     struct sk_buff *wbuf);
	int (*rx_completion)(struct ath10k *ar,
			     struct sk_buff *wbuf,
			     u8 pipe_id);
			     struct sk_buff *wbuf);
};

struct ath10k_hif_ops {
@@ -47,6 +46,8 @@ struct ath10k_hif_ops {
	int (*diag_read)(struct ath10k *ar, u32 address, void *buf,
			 size_t buf_len);

	int (*diag_write)(struct ath10k *ar, u32 address, const void *data,
			  int nbytes);
	/*
	 * API to handle HIF-specific BMI message exchanges, this API is
	 * synchronous and only allowed to be called from a context that
@@ -84,6 +85,10 @@ struct ath10k_hif_ops {

	u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id);

	u32 (*read32)(struct ath10k *ar, u32 address);

	void (*write32)(struct ath10k *ar, u32 address, u32 value);

	/* Power up the device and enter BMI transfer mode for FW download */
	int (*power_up)(struct ath10k *ar);

@@ -108,6 +113,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf
	return ar->hif.ops->diag_read(ar, address, buf, buf_len);
}

static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address,
					const void *data, int nbytes)
{
	if (!ar->hif.ops->diag_write)
		return -EOPNOTSUPP;

	return ar->hif.ops->diag_write(ar, address, data, nbytes);
}

static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar,
					      void *request, u32 request_len,
					      void *response, u32 *response_len)
@@ -187,4 +201,25 @@ static inline int ath10k_hif_resume(struct ath10k *ar)
	return ar->hif.ops->resume(ar);
}

static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address)
{
	if (!ar->hif.ops->read32) {
		ath10k_warn(ar, "hif read32 not supported\n");
		return 0xdeaddead;
	}

	return ar->hif.ops->read32(ar, address);
}

static inline void ath10k_hif_write32(struct ath10k *ar,
				      u32 address, u32 data)
{
	if (!ar->hif.ops->write32) {
		ath10k_warn(ar, "hif write32 not supported\n");
		return;
	}

	ar->hif.ops->write32(ar, address, data);
}

#endif /* _HIF_H_ */
Loading