Commit aa2092a9 authored by Venkateswara Naralasetty's avatar Venkateswara Naralasetty Committed by Kalle Valo
Browse files

ath11k: add raw mode and software crypto support



Adding raw mode tx/rx support. Also, adding support
for software crypto which depends on raw mode.

To enable raw mode tx/rx:
insmod ath11k.ko frame_mode=0

To enable software crypto:
insmod ath11k.ko crypto_mode=1

These modes could be helpful in debugging crypto related issues.

Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01228-QCAHKSWPL_SILICONZ-1

Signed-off-by: default avatarManikanta Pubbisetty <mpubbise@codeaurora.org>
Signed-off-by: default avatarVenkateswara Naralasetty <vnaralas@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/010101746c6a52d9-18302a2c-0d6d-4057-aa4b-95960c809646-000000@us-west-2.amazonses.com
parent b129699a
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -18,6 +18,16 @@ EXPORT_SYMBOL(ath11k_debug_mask);
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");

static unsigned int ath11k_crypto_mode;
module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");

/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
MODULE_PARM_DESC(frame_mode,
		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");

static const struct ath11k_hw_params ath11k_hw_params[] = {
	{
		.hw_rev = ATH11K_HW_IPQ8074,
@@ -617,6 +627,23 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
		return ret;
	}

	switch (ath11k_crypto_mode) {
	case ATH11K_CRYPT_MODE_SW:
		set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
		break;
	case ATH11K_CRYPT_MODE_HW:
		clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
		clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
		break;
	default:
		ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
		return -EINVAL;
	}

	if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);

	mutex_lock(&ab->core_lock);
	ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
	if (ret) {
+9 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@

#define ATH11K_INVALID_HW_MAC_ID	0xFF

extern unsigned int ath11k_frame_mode;

enum ath11k_supported_bw {
	ATH11K_BW_20	= 0,
	ATH11K_BW_40	= 1,
@@ -54,6 +56,13 @@ enum wme_ac {
#define ATH11K_VHT_MCS_MAX	9
#define ATH11K_HE_MCS_MAX	11

enum ath11k_crypt_mode {
	/* Only use hardware crypto engine */
	ATH11K_CRYPT_MODE_HW,
	/* Only use software crypto */
	ATH11K_CRYPT_MODE_SW,
};

static inline enum wme_ac ath11k_tid_to_ac(u32 tid)
{
	return (((tid == 0) || (tid == 3)) ? WME_AC_BE :
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ enum ath11k_debug_mask {
	ATH11K_DBG_TESTMODE	= 0x00000400,
	ATH11k_DBG_HAL		= 0x00000800,
	ATH11K_DBG_PCI		= 0x00001000,
	ATH11K_DBG_DP_TX	= 0x00001000,
	ATH11K_DBG_DP_RX	= 0x00002000,
	ATH11K_DBG_ANY		= 0xffffffff,
};

+5 −2
Original line number Diff line number Diff line
@@ -2133,8 +2133,6 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
	mcast = is_multicast_ether_addr(hdr->addr1);
	fill_crypto_hdr = mcast;

	is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);

	spin_lock_bh(&ar->ab->base_lock);
	peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
	if (peer) {
@@ -2148,6 +2146,8 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
	spin_unlock_bh(&ar->ab->base_lock);

	err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc);
	if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
		is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);

	/* Clear per-MPDU flags while leaving per-PPDU flags intact */
	rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
@@ -2350,6 +2350,9 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap
		   !!(status->flag & RX_FLAG_MMIC_ERROR),
		   !!(status->flag & RX_FLAG_AMSDU_MORE));

	ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
			msdu->data, msdu->len);

	/* TODO: trace rx packet */

	ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
+26 −11
Original line number Diff line number Diff line
@@ -13,6 +13,10 @@ static enum hal_tcl_encap_type
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
{
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ath11k_base *ab = arvif->ar->ab;

	if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
		return HAL_TCL_ENCAP_TYPE_RAW;

	if (tx_info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
		return HAL_TCL_ENCAP_TYPE_ETHERNET;
@@ -79,6 +83,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
	struct ath11k_dp *dp = &ab->dp;
	struct hal_tx_info ti = {0};
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_key_conf *key = info->control.hw_key;
	struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
	struct hal_srng *tcl_ring;
	struct ieee80211_hdr *hdr = (void *)skb->data;
@@ -142,11 +147,17 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
	ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
	ti.meta_data_flags = arvif->tcl_metadata;

	if (info->control.hw_key)
	if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
		if (key) {
			ti.encrypt_type =
			ath11k_dp_tx_get_encrypt_type(info->control.hw_key->cipher);
	else
				ath11k_dp_tx_get_encrypt_type(key->cipher);

			if (ieee80211_has_protected(hdr->frame_control))
				skb_put(skb, IEEE80211_CCMP_MIC_LEN);
		} else {
			ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
		}
	}

	ti.addr_search_flags = arvif->hal_addr_search_flags;
	ti.search_type = arvif->search_type;
@@ -156,7 +167,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
	ti.bss_ast_hash = arvif->ast_hash;
	ti.dscp_tid_tbl_idx = 0;

	if (skb->ip_summed == CHECKSUM_PARTIAL) {
	if (skb->ip_summed == CHECKSUM_PARTIAL &&
	    ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
		ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN, 1) |
@@ -176,10 +188,11 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
		ath11k_dp_tx_encap_nwifi(skb);
		break;
	case HAL_TCL_ENCAP_TYPE_RAW:
		/*  TODO: for CHECKSUM_PARTIAL case in raw mode, HW checksum offload
		 *	  is not applicable, hence manual checksum calculation using
		 *	  skb_checksum_help() is needed
		 */
		if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
			ret = -EINVAL;
			goto fail_remove_idr;
		}
		break;
	case HAL_TCL_ENCAP_TYPE_ETHERNET:
		/* no need to encap */
		break;
@@ -242,6 +255,9 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,

	spin_unlock_bh(&tcl_ring->lock);

	ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ",
			skb->data, skb->len);

	atomic_inc(&ar->dp.num_tx_pending);

	return 0;
@@ -352,7 +368,6 @@ ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab,

	wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
			       status_desc->info0);

	switch (wbm_status) {
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
Loading