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

Commit dd75d067 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ath10k: Enable pktlog for WCN3990 target"

parents 14cda000 2e035860
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1924,6 +1924,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
		goto err_hif_stop;
	}

	status = ath10k_pktlog_connect(ar);
	if (status) {
		ath10k_err(ar, "could not connect pktlog: %d\n", status);
		goto err_hif_stop;
	}

	status = ath10k_htc_start(&ar->htc);
	if (status) {
		ath10k_err(ar, "failed to start htc: %d\n", status);
+1 −0
Original line number Diff line number Diff line
@@ -467,6 +467,7 @@ struct ath10k_debug {
	u64 fw_dbglog_mask;
	u32 fw_dbglog_level;
	u32 pktlog_filter;
	enum ath10k_htc_ep_id eid;
	u32 reg_addr;
	u32 nf_cal_period;
	void *cal_data;
+133 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "core.h"
#include "debug.h"
#include "hif.h"
#include "htt.h"
#include "wmi-ops.h"

/* ms */
@@ -2617,6 +2618,138 @@ static const struct file_operations fops_fw_checksums = {
	.llseek = default_llseek,
};

static struct txctl_frm_hdr frm_hdr;

static void ath10k_extract_frame_header(u8 *addr1, u8 *addr2, u8 *addr3)
{
	frm_hdr.bssid_tail = (addr1[IEEE80211_ADDR_LEN - 2] << BITS_PER_BYTE)
			      | (addr1[IEEE80211_ADDR_LEN - 1]);
	frm_hdr.sa_tail = (addr2[IEEE80211_ADDR_LEN - 2] << BITS_PER_BYTE)
			   | (addr2[IEEE80211_ADDR_LEN - 1]);
	frm_hdr.da_tail = (addr3[IEEE80211_ADDR_LEN - 2] << BITS_PER_BYTE)
			   | (addr3[IEEE80211_ADDR_LEN - 1]);
}

static void ath10k_process_ieee_hdr(void *data)
{
	u8 dir;
	struct ieee80211_frame *wh;

	if (!data)
		return;

	wh = (struct ieee80211_frame *)(data);
	frm_hdr.framectrl = *(u_int16_t *)(wh->i_fc);
	frm_hdr.seqctrl   = *(u_int16_t *)(wh->i_seq);
	dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK);

	if (dir == IEEE80211_FC1_DIR_TODS)
		ath10k_extract_frame_header(&wh->i_addr1, &wh->i_addr2,
					    &wh->i_addr3);
	else if (dir == IEEE80211_FC1_DIR_FROMDS)
		ath10k_extract_frame_header(&wh->i_addr2, &wh->i_addr3,
					    &wh->i_addr1);
	else
		ath10k_extract_frame_header(&wh->i_addr3, &wh->i_addr2,
					    &wh->i_addr1);
}

static void ath10k_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
{
	struct ath10k_pktlog_hdr *hdr = (void *)skb->data;
	struct ath_pktlog_txctl pktlog_tx_ctrl;

	switch (hdr->log_type) {
	case ATH10K_PKTLOG_TYPE_TX_CTRL: {
		spin_lock_bh(&ar->htt.tx_lock);

		memcpy((void *)(&pktlog_tx_ctrl.hdr), (void *)hdr,
		       sizeof(pktlog_tx_ctrl.hdr));
		pktlog_tx_ctrl.frm_hdr = frm_hdr;
		memcpy((void *)pktlog_tx_ctrl.txdesc_ctl, (void *)hdr->payload,
		       __le16_to_cpu(hdr->size));
		pktlog_tx_ctrl.hdr.size = sizeof(pktlog_tx_ctrl) -
			sizeof(pktlog_tx_ctrl.hdr);

		spin_unlock_bh(&ar->htt.tx_lock);

		trace_ath10k_htt_pktlog(ar, (void *)&pktlog_tx_ctrl,
					sizeof(pktlog_tx_ctrl));
		break;
		}
	case ATH10K_PKTLOG_TYPE_TX_MSDU_ID:
		break;
	case ATH10K_PKTLOG_TYPE_TX_FRM_HDR: {
		ath10k_process_ieee_hdr((void *)(hdr->payload));
		trace_ath10k_htt_pktlog(ar, hdr, sizeof(*hdr) +
					__le16_to_cpu(hdr->size));
		break;
		}
	case ATH10K_PKTLOG_TYPE_RX_STAT:
	case ATH10K_PKTLOG_TYPE_RC_FIND:
	case ATH10K_PKTLOG_TYPE_RC_UPDATE:
	case ATH10K_PKTLOG_TYPE_DBG_PRINT:
	case ATH10K_PKTLOG_TYPE_TX_STAT:
	case ATH10K_PKTLOG_TYPE_SW_EVENT:
		trace_ath10k_htt_pktlog(ar, hdr, sizeof(*hdr) +
					__le16_to_cpu(hdr->size));
		break;
	case ATH10K_PKTLOG_TYPE_TX_VIRT_ADDR: {
		u32 desc_id = (u32)*((u32 *)(hdr->payload));
		struct sk_buff *msdu;

		spin_lock_bh(&ar->htt.tx_lock);
		msdu = ath10k_htt_tx_find_msdu_by_id(&ar->htt, desc_id);

		if (!msdu) {
			ath10k_info(ar,
				    "Failed to get msdu, id: %d\n",
				    desc_id);
			spin_unlock_bh(&ar->htt.tx_lock);
			return;
		}
		ath10k_process_ieee_hdr((void *)msdu->data);
		spin_unlock_bh(&ar->htt.tx_lock);
		trace_ath10k_htt_pktlog(ar, hdr, sizeof(*hdr) +
					__le16_to_cpu(hdr->size));
		break;
		}
	}
}

static void ath10k_pktlog_htc_tx_complete(struct ath10k *ar,
					  struct sk_buff *skb)
{
	ath10k_info(ar, "PKTLOG htc completed\n");
}

int ath10k_pktlog_connect(struct ath10k *ar)
{
	int status;
	struct ath10k_htc_svc_conn_req conn_req;
	struct ath10k_htc_svc_conn_resp conn_resp;

	memset(&conn_req, 0, sizeof(conn_req));
	memset(&conn_resp, 0, sizeof(conn_resp));

	conn_req.ep_ops.ep_tx_complete = ath10k_pktlog_htc_tx_complete;
	conn_req.ep_ops.ep_rx_complete = ath10k_pktlog_process_rx;
	conn_req.ep_ops.ep_tx_credits = NULL;

	/* connect to control service */
	conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_LOG_MSG;
	status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
	if (status) {
		ath10k_warn(ar, "failed to connect to PKTLOG service: %d\n",
			    status);
		return status;
	}

	ar->debug.eid = conn_resp.eid;

	return 0;
}

int ath10k_debug_create(struct ath10k *ar)
{
	ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
+83 −0
Original line number Diff line number Diff line
@@ -57,6 +57,84 @@ enum ath10k_dbg_aggr_mode {
	ATH10K_DBG_AGGR_MODE_MAX,
};

#define IEEE80211_FC1_DIR_MASK              0x03
#define IEEE80211_FC1_DIR_NODS              0x00    /* STA->STA */
#define IEEE80211_FC1_DIR_TODS              0x01    /* STA->AP  */
#define IEEE80211_FC1_DIR_FROMDS            0x02    /* AP ->STA */
#define IEEE80211_FC1_DIR_DSTODS            0x03    /* AP ->AP  */
#define IEEE80211_ADDR_LEN  6                       /* size of 802.11 address */

#define MAX_PKT_INFO_MSDU_ID 192
#define MSDU_ID_INFO_ID_OFFSET  \
	((MAX_PKT_INFO_MSDU_ID >> 3) + 4)

#define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */
#define HTT_TX_MSDU_LEN_MASK 0xffff

struct txctl_frm_hdr {
	__le16 framectrl;       /* frame control field from header */
	__le16 seqctrl;         /* frame control field from header */
	__le16 bssid_tail;      /* last two octets of bssid */
	__le16 sa_tail;         /* last two octets of SA */
	__le16 da_tail;         /* last two octets of DA */
	__le16 resvd;
} __packed;

struct ath_pktlog_hdr {
	__le16 flags;
	__le16 missed_cnt;
	u8 log_type;
	u8 macId;
	__le16 size;
	__le32 timestamp;
	__le32 type_specific_data;
} __packed;

/* generic definitions for IEEE 802.11 frames */
struct ieee80211_frame {
	u8 i_fc[2];
	u8 i_dur[2];
	union {
		struct {
			u8 i_addr1[IEEE80211_ADDR_LEN];
			u8 i_addr2[IEEE80211_ADDR_LEN];
			u8 i_addr3[IEEE80211_ADDR_LEN];
		};
		u8 i_addr_all[3 * IEEE80211_ADDR_LEN];
	};
	u8 i_seq[2];
} __packed;

struct fw_pktlog_msdu_info {
	__le32 num_msdu;
	u8 bound_bmap[MAX_PKT_INFO_MSDU_ID >> 3];
	__le16 id[MAX_PKT_INFO_MSDU_ID];
} __packed;

struct ath_pktlog_txctl {
	struct ath_pktlog_hdr hdr;
	struct txctl_frm_hdr frm_hdr;
	__le32 txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS];
} __packed;

struct ath_pktlog_msdu_id {
	struct ath_pktlog_hdr hdr;
	struct fw_pktlog_msdu_info msdu_info;
} __packed;

struct ath_pktlog_rx_info {
	struct ath_pktlog_hdr pl_hdr;
	struct rx_attention attention;
	struct rx_frag_info frag_info;
	struct rx_mpdu_start mpdu_start;
	struct rx_msdu_start msdu_start;
	struct rx_msdu_end msdu_end;
	struct rx_mpdu_end mpdu_end;
	struct rx_ppdu_start ppdu_start;
	struct rx_ppdu_end ppdu_end;
	u8 rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
} __packed;

/* FIXME: How to calculate the buffer size sanely? */
#define ATH10K_FW_STATS_BUF_SIZE (1024 * 1024)
#define ATH10K_DATAPATH_BUF_SIZE (1024 * 1024)
@@ -98,6 +176,7 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
			       struct ethtool_stats *stats, u64 *data);
void fill_datapath_stats(struct ath10k *ar, struct ieee80211_rx_status *status);
size_t get_datapath_stat(char *buf, struct ath10k *ar);
int ath10k_pktlog_connect(struct ath10k *ar);
#else
static inline int ath10k_debug_start(struct ath10k *ar)
{
@@ -158,6 +237,10 @@ static inline size_t get_datapath_stat(char *buf, struct ath10k *ar)
	return 0;
}

static inline int ath10k_pktlog_connect(struct ath10k *ar)
{
	return 0;
}
#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)

#define ath10k_debug_get_et_strings NULL
+2 −0
Original line number Diff line number Diff line
@@ -1847,5 +1847,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt,
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
					     struct sk_buff *skb);
int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
struct sk_buff *ath10k_htt_tx_find_msdu_by_id(struct ath10k_htt *htt,
					      u16 msdu_id);

#endif
Loading