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

Commit ffc6ad74 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by Gerrit - the friendly Code Review server
Browse files

ath10k: Add support for the management over wmi



With the new chipset wcn3990 and new firmware HL-1.0, management
is supported via the WMI rather than legacy HTT.
Add support for the management over wmi for the ath10k driver.

CRs-Fixed: 2000484
Change-Id: Iaf387243d63870e063b3b5bf34cd7232dae921fc
Signed-off-by: default avatarRakesh Pillai <pillair@codeaurora.org>
parent 1e29e911
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
 * Copyright (c) 2011-2013, 2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -3444,7 +3444,9 @@ ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
		return ATH10K_MAC_TX_HTT;
	case ATH10K_HW_TXRX_MGMT:
		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
			     ar->running_fw->fw_file.fw_features))
			     ar->running_fw->fw_file.fw_features) ||
			     test_bit(WMI_SERVICE_MGMT_TX_WMI,
				      ar->wmi.svc_map))
			return ATH10K_MAC_TX_WMI_MGMT;
		else if (ar->htt.target_version_major >= 3)
			return ATH10K_MAC_TX_HTT;
+8 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
 * Copyright (c) 2011-2014, 2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -377,6 +377,7 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
	struct sk_buff *skb;
	int ret;
	u32 mgmt_tx_cmdid;

	if (!ar->wmi.ops->gen_mgmt_tx)
		return -EOPNOTSUPP;
@@ -385,7 +386,12 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid);
	if (QCA_REV_WCN3990(ar))
		mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_send_cmdid;
	else
		mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_cmdid;

	ret = ath10k_wmi_cmd_send(ar, skb, mgmt_tx_cmdid);
	if (ret)
		return ret;

+80 −0
Original line number Diff line number Diff line
@@ -2458,6 +2458,84 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
	return skb;
}

static struct sk_buff *
ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
{
	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
	struct wmi_tlv_mgmt_tx_cmd *cmd;
	struct wmi_tlv *tlv;
	struct ieee80211_hdr *hdr;
	struct sk_buff *skb;
	void *ptr;
	int len;
	u32 buf_len = (msdu->len < WMI_TX_DL_FRM_LEN) ? msdu->len :
					 WMI_TX_DL_FRM_LEN;
	u16 fc;
	struct ath10k_vif *arvif;
	dma_addr_t mgmt_frame_dma;
	u32 vdev_id;

	hdr = (struct ieee80211_hdr *)msdu->data;
	fc = le16_to_cpu(hdr->frame_control);

	if (cb->vif) {
		arvif = (void *)cb->vif->drv_priv;
		vdev_id = arvif->vdev_id;
	} else {
		return ERR_PTR(-EINVAL);
	}

	if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
		return ERR_PTR(-EINVAL);

	len = sizeof(*cmd) + buf_len;

	if ((ieee80211_is_action(hdr->frame_control) ||
	     ieee80211_is_deauth(hdr->frame_control) ||
	     ieee80211_is_disassoc(hdr->frame_control)) &&
	     ieee80211_has_protected(hdr->frame_control)) {
		len += IEEE80211_CCMP_MIC_LEN;
		buf_len += IEEE80211_CCMP_MIC_LEN;
	}

	len += sizeof(*tlv);
	len = round_up(len, 4);
	skb = ath10k_wmi_alloc_skb(ar, len);
	if (!skb)
		return ERR_PTR(-ENOMEM);

	ptr = (void *)skb->data;
	tlv = ptr;
	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD);
	tlv->len = __cpu_to_le16(sizeof(cmd->hdr));
	cmd = (void *)tlv->value;
	cmd->hdr.vdev_id = vdev_id;
	cmd->hdr.desc_id = 0;
	cmd->hdr.chanfreq = 0;
	cmd->hdr.buf_len = __cpu_to_le32(buf_len);
	cmd->hdr.frame_len = __cpu_to_le32(msdu->len);
	mgmt_frame_dma = dma_map_single(arvif->ar->dev, msdu->data,
					msdu->len, DMA_TO_DEVICE);
	if (!mgmt_frame_dma)
		return ERR_PTR(-ENOMEM);

	cmd->hdr.paddr_lo = (uint32_t)(mgmt_frame_dma & 0xffffffff);
	cmd->hdr.paddr_hi  = (uint32_t)(upper_32_bits(mgmt_frame_dma) &
						HTT_WCN3990_PADDR_MASK);
	cmd->data_len = buf_len;
	cmd->data_tag = 0x11;

	ptr += sizeof(*tlv);
	ptr += sizeof(*cmd);

	tlv = ptr;
	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
	tlv->len = __cpu_to_le16(sizeof(msdu->len));
	memcpy(cmd->buf, msdu->data, buf_len);

	return skb;
}

static struct sk_buff *
ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
				    enum wmi_force_fw_hang_type type,
@@ -3197,6 +3275,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = {
	.bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
	.prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
	.mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
	.mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD,
	.prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
	.addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
	.addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
@@ -3623,6 +3702,7 @@ static const struct wmi_ops wmi_hl_1_0_ops = {
	.gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
	.gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
	.gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
	.gen_mgmt_tx =  ath10k_wmi_tlv_op_gen_mgmt_tx,
	.gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
	.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
	.gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
+23 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
 * Copyright (c) 2011-2014, 2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -22,6 +22,7 @@
#define WMI_TLV_CMD_UNSUPPORTED 0
#define WMI_TLV_PDEV_PARAM_UNSUPPORTED 0
#define WMI_TLV_VDEV_PARAM_UNSUPPORTED 0
#define WMI_TX_DL_FRM_LEN	64

enum wmi_tlv_grp_id {
	WMI_TLV_GRP_START = 0x3,
@@ -132,6 +133,7 @@ enum wmi_tlv_cmd_id {
	WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
	WMI_TLV_MGMT_TX_CMDID,
	WMI_TLV_PRB_TMPL_CMDID,
	WMI_TLV_MGMT_TX_SEND_CMD,
	WMI_TLV_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BA_NEG),
	WMI_TLV_ADDBA_SEND_CMDID,
	WMI_TLV_ADDBA_STATUS_CMDID,
@@ -891,6 +893,8 @@ enum wmi_tlv_tag {
	WMI_TLV_TAG_STRUCT_APFIND_EVENT_HDR,
	WMI_TLV_TAG_STRUCT_HL_1_0_SVC_OFFSET = 176,

	WMI_TLV_TAG_STRUCT_MGMT_TX_CMD = 0x1A6,

	WMI_TLV_TAG_MAX
};

@@ -1152,6 +1156,8 @@ wmi_hl_1_0_svc_map(const __le32 *in, unsigned long *out, size_t len)
	       WMI_SERVICE_FORCE_FW_HANG, len);
	SVCMAP(WMI_HL_10_SERVICE_RX_FULL_REORDER,
	       WMI_SERVICE_RX_FULL_REORDER, len);
	SVCMAP(WMI_HL_10_SERVICE_MGMT_TX_WMI,
	       WMI_SERVICE_MGMT_TX_WMI, len);
}

static inline void
@@ -1827,4 +1833,20 @@ struct wmi_tlv_tx_pause_ev {

void ath10k_wmi_tlv_attach(struct ath10k *ar);
void ath10k_wmi_hl_1_0_attach(struct ath10k *ar);
struct wmi_tlv_mgmt_tx_hdr {
	__le32 vdev_id;
	__le32 desc_id;
	__le32 chanfreq;
	__le32 paddr_lo;
	__le32 paddr_hi;
	__le32 frame_len;
	__le32 buf_len;
} __packed;

struct wmi_tlv_mgmt_tx_cmd {
	struct wmi_tlv_mgmt_tx_hdr hdr;
	__le16 data_len;
	__le16 data_tag;
	u8 buf[0];
} __packed;
#endif
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
 * Copyright (c) 2011-2013, 2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -184,6 +184,7 @@ enum wmi_service {
	WMI_SERVICE_TX_MODE_PUSH_ONLY,
	WMI_SERVICE_TX_MODE_PUSH_PULL,
	WMI_SERVICE_TX_MODE_DYNAMIC,
	WMI_SERVICE_MGMT_TX_WMI,

	/* keep last */
	WMI_SERVICE_MAX,
@@ -720,6 +721,7 @@ struct wmi_cmd_map {
	u32 bcn_filter_rx_cmdid;
	u32 prb_req_filter_rx_cmdid;
	u32 mgmt_tx_cmdid;
	u32 mgmt_tx_send_cmdid;
	u32 prb_tmpl_cmdid;
	u32 addba_clear_resp_cmdid;
	u32 addba_send_cmdid;