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

Commit 94e92a7b authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge ath-next from ath.git. Major changes in ath10k:

* add support for qca99x0 family of devices
* improve performance of tx_lock
* add support for raw mode (802.11 frame format) and software crypto
  engine enabled via a module parameter

wil6210:

* implement TSO support
* support bootloader v1 and onwards
parents 94fdc2e6 e04cafbc
Loading
Loading
Loading
Loading
+53 −1
Original line number Original line Diff line number Diff line
@@ -31,16 +31,19 @@
#include "wmi-ops.h"
#include "wmi-ops.h"


unsigned int ath10k_debug_mask;
unsigned int ath10k_debug_mask;
static unsigned int ath10k_cryptmode_param;
static bool uart_print;
static bool uart_print;
static bool skip_otp;
static bool skip_otp;


module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
module_param(skip_otp, bool, 0644);


MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");


static const struct ath10k_hw_params ath10k_hw_params_list[] = {
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
	{
	{
@@ -1073,6 +1076,46 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
		return -EINVAL;
		return -EINVAL;
	}
	}


	ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
	switch (ath10k_cryptmode_param) {
	case ATH10K_CRYPT_MODE_HW:
		clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
		clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
		break;
	case ATH10K_CRYPT_MODE_SW:
		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
			      ar->fw_features)) {
			ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");
			return -EINVAL;
		}

		set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
		set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
		break;
	default:
		ath10k_info(ar, "invalid cryptmode: %d\n",
			    ath10k_cryptmode_param);
		return -EINVAL;
	}

	ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
	ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;

	if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
		ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;

		/* Workaround:
		 *
		 * Firmware A-MSDU aggregation breaks with RAW Tx encap mode
		 * and causes enormous performance issues (malformed frames,
		 * etc).
		 *
		 * Disabling A-MSDU makes RAW mode stable with heavy traffic
		 * albeit a bit slower compared to regular operation.
		 */
		ar->htt.max_num_amsdu = 1;
	}

	/* Backwards compatibility for firmwares without
	/* Backwards compatibility for firmwares without
	 * ATH10K_FW_IE_WMI_OP_VERSION.
	 * ATH10K_FW_IE_WMI_OP_VERSION.
	 */
	 */
@@ -1606,6 +1649,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
	if (!ar->workqueue)
	if (!ar->workqueue)
		goto err_free_mac;
		goto err_free_mac;


	ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");
	if (!ar->workqueue_aux)
		goto err_free_wq;

	mutex_init(&ar->conf_mutex);
	mutex_init(&ar->conf_mutex);
	spin_lock_init(&ar->data_lock);
	spin_lock_init(&ar->data_lock);


@@ -1626,10 +1673,12 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,


	ret = ath10k_debug_create(ar);
	ret = ath10k_debug_create(ar);
	if (ret)
	if (ret)
		goto err_free_wq;
		goto err_free_aux_wq;


	return ar;
	return ar;


err_free_aux_wq:
	destroy_workqueue(ar->workqueue_aux);
err_free_wq:
err_free_wq:
	destroy_workqueue(ar->workqueue);
	destroy_workqueue(ar->workqueue);


@@ -1645,6 +1694,9 @@ void ath10k_core_destroy(struct ath10k *ar)
	flush_workqueue(ar->workqueue);
	flush_workqueue(ar->workqueue);
	destroy_workqueue(ar->workqueue);
	destroy_workqueue(ar->workqueue);


	flush_workqueue(ar->workqueue_aux);
	destroy_workqueue(ar->workqueue_aux);

	ath10k_debug_destroy(ar);
	ath10k_debug_destroy(ar);
	ath10k_mac_destroy(ar);
	ath10k_mac_destroy(ar);
}
}
+31 −5
Original line number Original line Diff line number Diff line
@@ -92,6 +92,7 @@ struct ath10k_skb_cb {
		u8 tid;
		u8 tid;
		u16 freq;
		u16 freq;
		bool is_offchan;
		bool is_offchan;
		bool nohwcrypt;
		struct ath10k_htt_txbuf *txbuf;
		struct ath10k_htt_txbuf *txbuf;
		u32 txbuf_paddr;
		u32 txbuf_paddr;
	} __packed htt;
	} __packed htt;
@@ -152,6 +153,7 @@ struct ath10k_wmi {
	const struct wmi_ops *ops;
	const struct wmi_ops *ops;


	u32 num_mem_chunks;
	u32 num_mem_chunks;
	u32 rx_decap_mode;
	struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
	struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
};
};


@@ -341,6 +343,7 @@ struct ath10k_vif {
	} u;
	} u;


	bool use_cts_prot;
	bool use_cts_prot;
	bool nohwcrypt;
	int num_legacy_stations;
	int num_legacy_stations;
	int txpower;
	int txpower;
	struct wmi_wmm_params_all_arg wmm_params;
	struct wmi_wmm_params_all_arg wmm_params;
@@ -382,9 +385,6 @@ struct ath10k_debug {
	u32 reg_addr;
	u32 reg_addr;
	u32 nf_cal_period;
	u32 nf_cal_period;


	u8 htt_max_amsdu;
	u8 htt_max_ampdu;

	struct ath10k_fw_crash_data *fw_crash_data;
	struct ath10k_fw_crash_data *fw_crash_data;
};
};


@@ -453,16 +453,21 @@ enum ath10k_fw_features {
	ATH10K_FW_FEATURE_WOWLAN_SUPPORT = 6,
	ATH10K_FW_FEATURE_WOWLAN_SUPPORT = 6,


	/* Don't trust error code from otp.bin */
	/* Don't trust error code from otp.bin */
	ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
	ATH10K_FW_FEATURE_IGNORE_OTP_RESULT = 7,


	/* Some firmware revisions pad 4th hw address to 4 byte boundary making
	/* Some firmware revisions pad 4th hw address to 4 byte boundary making
	 * it 8 bytes long in Native Wifi Rx decap.
	 * it 8 bytes long in Native Wifi Rx decap.
	 */
	 */
	ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING,
	ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING = 8,


	/* Firmware supports bypassing PLL setting on init. */
	/* Firmware supports bypassing PLL setting on init. */
	ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT = 9,
	ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT = 9,


	/* Raw mode support. If supported, FW supports receiving and trasmitting
	 * frames in raw mode.
	 */
	ATH10K_FW_FEATURE_RAW_MODE_SUPPORT = 10,

	/* keep last */
	/* keep last */
	ATH10K_FW_FEATURE_COUNT,
	ATH10K_FW_FEATURE_COUNT,
};
};
@@ -476,6 +481,15 @@ enum ath10k_dev_flags {
	 * waiters should immediately cancel instead of waiting for a time out.
	 * waiters should immediately cancel instead of waiting for a time out.
	 */
	 */
	ATH10K_FLAG_CRASH_FLUSH,
	ATH10K_FLAG_CRASH_FLUSH,

	/* Use Raw mode instead of native WiFi Tx/Rx encap mode.
	 * Raw mode supports both hardware and software crypto. Native WiFi only
	 * supports hardware crypto.
	 */
	ATH10K_FLAG_RAW_MODE,

	/* Disable HW crypto engine */
	ATH10K_FLAG_HW_CRYPTO_DISABLED,
};
};


enum ath10k_cal_mode {
enum ath10k_cal_mode {
@@ -484,6 +498,13 @@ enum ath10k_cal_mode {
	ATH10K_CAL_MODE_DT,
	ATH10K_CAL_MODE_DT,
};
};


enum ath10k_crypt_mode {
	/* Only use hardware crypto engine */
	ATH10K_CRYPT_MODE_HW,
	/* Only use software crypto engine */
	ATH10K_CRYPT_MODE_SW,
};

static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
{
{
	switch (mode) {
	switch (mode) {
@@ -673,6 +694,8 @@ struct ath10k {
	struct completion vdev_setup_done;
	struct completion vdev_setup_done;


	struct workqueue_struct *workqueue;
	struct workqueue_struct *workqueue;
	/* Auxiliary workqueue */
	struct workqueue_struct *workqueue_aux;


	/* prevents concurrent FW reconfiguration */
	/* prevents concurrent FW reconfiguration */
	struct mutex conf_mutex;
	struct mutex conf_mutex;
@@ -695,6 +718,9 @@ struct ath10k {
	int num_active_peers;
	int num_active_peers;
	int num_tids;
	int num_tids;


	struct work_struct svc_rdy_work;
	struct sk_buff *svc_rdy_skb;

	struct work_struct offchan_tx_work;
	struct work_struct offchan_tx_work;
	struct sk_buff_head offchan_tx_queue;
	struct sk_buff_head offchan_tx_queue;
	struct completion offchan_tx_completed;
	struct completion offchan_tx_completed;
+8 −13
Original line number Original line Diff line number Diff line
@@ -124,11 +124,11 @@ EXPORT_SYMBOL(ath10k_info);


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


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


	ath10k_info(ar, "%s (0x%08x, 0x%08x%s%s%s) fw %s api %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d features %s\n",
	ath10k_info(ar, "%s (0x%08x, 0x%08x%s%s%s) fw %s api %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n",
		    ar->hw_params.name,
		    ar->hw_params.name,
		    ar->target_version,
		    ar->target_version,
		    ar->chip_id,
		    ar->chip_id,
@@ -144,6 +144,8 @@ void ath10k_print_driver_info(struct ath10k *ar)
		    ar->htt.op_version,
		    ar->htt.op_version,
		    ath10k_cal_mode_str(ar->cal_mode),
		    ath10k_cal_mode_str(ar->cal_mode),
		    ar->max_num_stations,
		    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);
		    fw_features);
	ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
	ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
		    config_enabled(CONFIG_ATH10K_DEBUG),
		    config_enabled(CONFIG_ATH10K_DEBUG),
@@ -1363,12 +1365,8 @@ static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,


	mutex_lock(&ar->conf_mutex);
	mutex_lock(&ar->conf_mutex);


	if (ar->debug.htt_max_amsdu)
	amsdu = ar->htt.max_num_amsdu;
		amsdu = ar->debug.htt_max_amsdu;
	ampdu = ar->htt.max_num_ampdu;

	if (ar->debug.htt_max_ampdu)
		ampdu = ar->debug.htt_max_ampdu;

	mutex_unlock(&ar->conf_mutex);
	mutex_unlock(&ar->conf_mutex);


	len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
	len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
@@ -1402,8 +1400,8 @@ static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
		goto out;
		goto out;


	res = count;
	res = count;
	ar->debug.htt_max_amsdu = amsdu;
	ar->htt.max_num_amsdu = amsdu;
	ar->debug.htt_max_ampdu = ampdu;
	ar->htt.max_num_ampdu = ampdu;


out:
out:
	mutex_unlock(&ar->conf_mutex);
	mutex_unlock(&ar->conf_mutex);
@@ -1905,9 +1903,6 @@ void ath10k_debug_stop(struct ath10k *ar)
	if (ar->debug.htt_stats_mask != 0)
	if (ar->debug.htt_stats_mask != 0)
		cancel_delayed_work(&ar->debug.htt_stats_dwork);
		cancel_delayed_work(&ar->debug.htt_stats_dwork);


	ar->debug.htt_max_amsdu = 0;
	ar->debug.htt_max_ampdu = 0;

	ath10k_wmi_pdev_pktlog_disable(ar);
	ath10k_wmi_pdev_pktlog_disable(ar);
}
}


+21 −2
Original line number Original line Diff line number Diff line
@@ -246,12 +246,31 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
	}
	}


	status = ath10k_htt_verify_version(htt);
	status = ath10k_htt_verify_version(htt);
	if (status)
	if (status) {
		ath10k_warn(ar, "failed to verify htt version: %d\n",
			    status);
		return status;
		return status;
	}


	status = ath10k_htt_send_frag_desc_bank_cfg(htt);
	status = ath10k_htt_send_frag_desc_bank_cfg(htt);
	if (status)
	if (status)
		return status;
		return status;


	return ath10k_htt_send_rx_ring_cfg_ll(htt);
	status = ath10k_htt_send_rx_ring_cfg_ll(htt);
	if (status) {
		ath10k_warn(ar, "failed to setup rx ring: %d\n",
			    status);
		return status;
	}

	status = ath10k_htt_h2t_aggr_cfg_msg(htt,
					     htt->max_num_ampdu,
					     htt->max_num_amsdu);
	if (status) {
		ath10k_warn(ar, "failed to setup amsdu/ampdu limit: %d\n",
			    status);
		return status;
	}

	return 0;
}
}
+41 −3
Original line number Original line Diff line number Diff line
@@ -83,15 +83,39 @@ struct htt_ver_req {
 * around the mask + shift defs.
 * around the mask + shift defs.
 */
 */
struct htt_data_tx_desc_frag {
struct htt_data_tx_desc_frag {
	union {
		struct double_word_addr {
			__le32 paddr;
			__le32 paddr;
			__le32 len;
			__le32 len;
		} __packed dword_addr;
		struct triple_word_addr {
			__le32 paddr_lo;
			__le16 paddr_hi;
			__le16 len_16;
		} __packed tword_addr;
	} __packed;
} __packed;
} __packed;


struct htt_msdu_ext_desc {
struct htt_msdu_ext_desc {
	__le32 tso_flag[4];
	__le32 tso_flag[3];
	__le16 ip_identification;
	u8 flags;
	u8 reserved;
	struct htt_data_tx_desc_frag frags[6];
	struct htt_data_tx_desc_frag frags[6];
};
};


#define	HTT_MSDU_EXT_DESC_FLAG_IPV4_CSUM_ENABLE		BIT(0)
#define	HTT_MSDU_EXT_DESC_FLAG_UDP_IPV4_CSUM_ENABLE	BIT(1)
#define	HTT_MSDU_EXT_DESC_FLAG_UDP_IPV6_CSUM_ENABLE	BIT(2)
#define	HTT_MSDU_EXT_DESC_FLAG_TCP_IPV4_CSUM_ENABLE	BIT(3)
#define	HTT_MSDU_EXT_DESC_FLAG_TCP_IPV6_CSUM_ENABLE	BIT(4)

#define HTT_MSDU_CHECKSUM_ENABLE (HTT_MSDU_EXT_DESC_FLAG_IPV4_CSUM_ENABLE \
				 | HTT_MSDU_EXT_DESC_FLAG_UDP_IPV4_CSUM_ENABLE \
				 | HTT_MSDU_EXT_DESC_FLAG_UDP_IPV6_CSUM_ENABLE \
				 | HTT_MSDU_EXT_DESC_FLAG_TCP_IPV4_CSUM_ENABLE \
				 | HTT_MSDU_EXT_DESC_FLAG_TCP_IPV6_CSUM_ENABLE)

enum htt_data_tx_desc_flags0 {
enum htt_data_tx_desc_flags0 {
	HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0,
	HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0,
	HTT_DATA_TX_DESC_FLAGS0_NO_AGGR         = 1 << 1,
	HTT_DATA_TX_DESC_FLAGS0_NO_AGGR         = 1 << 1,
@@ -260,6 +284,9 @@ struct htt_aggr_conf {
} __packed;
} __packed;


#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
struct htt_mgmt_tx_desc_qca99x0 {
	__le32 rate;
} __packed;


struct htt_mgmt_tx_desc {
struct htt_mgmt_tx_desc {
	u8 pad[sizeof(u32) - sizeof(struct htt_cmd_hdr)];
	u8 pad[sizeof(u32) - sizeof(struct htt_cmd_hdr)];
@@ -268,6 +295,9 @@ struct htt_mgmt_tx_desc {
	__le32 len;
	__le32 len;
	__le32 vdev_id;
	__le32 vdev_id;
	u8 hdr[HTT_MGMT_FRM_HDR_DOWNLOAD_LEN];
	u8 hdr[HTT_MGMT_FRM_HDR_DOWNLOAD_LEN];
	union {
		struct htt_mgmt_tx_desc_qca99x0 qca99x0;
	} __packed;
} __packed;
} __packed;


enum htt_mgmt_tx_status {
enum htt_mgmt_tx_status {
@@ -1366,6 +1396,8 @@ struct ath10k_htt {
	u8 target_version_minor;
	u8 target_version_minor;
	struct completion target_version_received;
	struct completion target_version_received;
	enum ath10k_fw_htt_op_version op_version;
	enum ath10k_fw_htt_op_version op_version;
	u8 max_num_amsdu;
	u8 max_num_ampdu;


	const enum htt_t2h_msg_type *t2h_msg_types;
	const enum htt_t2h_msg_type *t2h_msg_types;
	u32 t2h_msg_types_max;
	u32 t2h_msg_types_max;
@@ -1528,6 +1560,12 @@ struct htt_rx_desc {
#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7	/* 2^7 = 128 */
#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7	/* 2^7 = 128 */
#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1)
#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1)


/* These values are default in most firmware revisions and apparently are a
 * sweet spot performance wise.
 */
#define ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT 3
#define ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT 64

int ath10k_htt_connect(struct ath10k_htt *htt);
int ath10k_htt_connect(struct ath10k_htt *htt);
int ath10k_htt_init(struct ath10k *ar);
int ath10k_htt_init(struct ath10k *ar);
int ath10k_htt_setup(struct ath10k_htt *htt);
int ath10k_htt_setup(struct ath10k_htt *htt);
Loading