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

Commit 0e472252 authored by Bob Copeland's avatar Bob Copeland Committed by John W. Linville
Browse files

ath5k: use tracing for packet tx/rx dump



This adds a few tracepoints to ath5k driver transmit and
receive callbacks in order to record packet traffic.
We record the entire packet in the trace buffer so that
the data can be extracted with trace-cmd and external
plugins.

Compared to the previous debugging calls, this approach
removes an out-of-line function call from the tx and rx
paths in the compiled-in-but-disabled case, while
improving the ability to process the logged data.

A new option, CONFIG_ATH5K_TRACER, is added so that one
may disable the tracepoints completely.

Signed-off-by: default avatarBob Copeland <me@bobcopeland.com>
Acked-by: default avatarBruno Randolf <br1@einfach.org>
Acked-by: default avatarNick Kossifidis <mickflemm@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b453175d
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,17 @@ config ATH5K_DEBUG


	  modprobe ath5k debug=0x00000400
	  modprobe ath5k debug=0x00000400


config ATH5K_TRACER
	bool "Atheros 5xxx tracer"
	depends on ATH5K
	depends on EVENT_TRACING
	---help---
	  Say Y here to enable tracepoints for the ath5k driver
	  using the kernel tracing infrastructure.  Select this
	  option if you are interested in debugging the driver.

	  If unsure, say N.

config ATH5K_AHB
config ATH5K_AHB
	bool "Atheros 5xxx AHB bus support"
	bool "Atheros 5xxx AHB bus support"
	depends on (ATHEROS_AR231X && !PCI)
	depends on (ATHEROS_AR231X && !PCI)
+10 −6
Original line number Original line Diff line number Diff line
@@ -61,6 +61,9 @@
#include "debug.h"
#include "debug.h"
#include "ani.h"
#include "ani.h"


#define CREATE_TRACE_POINTS
#include "trace.h"

int ath5k_modparam_nohwcrypt;
int ath5k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -1379,7 +1382,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
	    sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
	    sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
		rxs->flag |= RX_FLAG_SHORTPRE;
		rxs->flag |= RX_FLAG_SHORTPRE;


	ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
	trace_ath5k_rx(sc, skb);


	ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
	ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);


@@ -1524,7 +1527,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
	unsigned long flags;
	unsigned long flags;
	int padsize;
	int padsize;


	ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
	trace_ath5k_tx(sc, skb, txq);


	/*
	/*
	 * The hardware expects the header padded to 4 byte boundaries.
	 * The hardware expects the header padded to 4 byte boundaries.
@@ -1573,7 +1576,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,


static void
static void
ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
			 struct ath5k_tx_status *ts)
			 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
{
{
	struct ieee80211_tx_info *info;
	struct ieee80211_tx_info *info;
	int i;
	int i;
@@ -1625,6 +1628,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
	else
	else
		sc->stats.antenna_tx[0]++; /* invalid */
		sc->stats.antenna_tx[0]++; /* invalid */


	trace_ath5k_tx_complete(sc, skb, txq, ts);
	ieee80211_tx_status(sc->hw, skb);
	ieee80211_tx_status(sc->hw, skb);
}
}


@@ -1661,7 +1665,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)


			dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
			dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
					DMA_TO_DEVICE);
					DMA_TO_DEVICE);
			ath5k_tx_frame_completed(sc, skb, &ts);
			ath5k_tx_frame_completed(sc, skb, txq, &ts);
		}
		}


		/*
		/*
@@ -1803,8 +1807,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
		goto out;
		goto out;
	}
	}


	ath5k_debug_dump_skb(sc, skb, "BC  ", 1);

	ath5k_txbuf_free_skb(sc, avf->bbuf);
	ath5k_txbuf_free_skb(sc, avf->bbuf);
	avf->bbuf->skb = skb;
	avf->bbuf->skb = skb;
	ret = ath5k_beacon_setup(sc, avf->bbuf);
	ret = ath5k_beacon_setup(sc, avf->bbuf);
@@ -1899,6 +1901,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
			sc->opmode == NL80211_IFTYPE_MESH_POINT)
			sc->opmode == NL80211_IFTYPE_MESH_POINT)
		ath5k_beacon_update(sc->hw, vif);
		ath5k_beacon_update(sc->hw, vif);


	trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]);

	ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
	ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
	ath5k_hw_start_tx_dma(ah, sc->bhalq);
	ath5k_hw_start_tx_dma(ah, sc->bhalq);
	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
+107 −0
Original line number Original line Diff line number Diff line
#if !defined(__TRACE_ATH5K_H) || defined(TRACE_HEADER_MULTI_READ)
#define __TRACE_ATH5K_H

#include <linux/tracepoint.h>
#include "base.h"

#ifndef CONFIG_ATH5K_TRACER
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
#endif

struct sk_buff;

#define PRIV_ENTRY  __field(struct ath5k_softc *, priv)
#define PRIV_ASSIGN __entry->priv = priv

#undef TRACE_SYSTEM
#define TRACE_SYSTEM ath5k

TRACE_EVENT(ath5k_rx,
	TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb),
	TP_ARGS(priv, skb),
	TP_STRUCT__entry(
		PRIV_ENTRY
		__field(unsigned long, skbaddr)
		__dynamic_array(u8, frame, skb->len)
	),
	TP_fast_assign(
		PRIV_ASSIGN;
		__entry->skbaddr = (unsigned long) skb;
		memcpy(__get_dynamic_array(frame), skb->data, skb->len);
	),
	TP_printk(
		"[%p] RX skb=%lx", __entry->priv, __entry->skbaddr
	)
);

TRACE_EVENT(ath5k_tx,
	TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
		 struct ath5k_txq *q),

	TP_ARGS(priv, skb, q),

	TP_STRUCT__entry(
		PRIV_ENTRY
		__field(unsigned long, skbaddr)
		__field(u8, qnum)
		__dynamic_array(u8, frame, skb->len)
	),

	TP_fast_assign(
		PRIV_ASSIGN;
		__entry->skbaddr = (unsigned long) skb;
		__entry->qnum = (u8) q->qnum;
		memcpy(__get_dynamic_array(frame), skb->data, skb->len);
	),

	TP_printk(
		"[%p] TX skb=%lx q=%d", __entry->priv, __entry->skbaddr,
		__entry->qnum
	)
);

TRACE_EVENT(ath5k_tx_complete,
	TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
		 struct ath5k_txq *q, struct ath5k_tx_status *ts),

	TP_ARGS(priv, skb, q, ts),

	TP_STRUCT__entry(
		PRIV_ENTRY
		__field(unsigned long, skbaddr)
		__field(u8, qnum)
		__field(u8, ts_status)
		__field(s8, ts_rssi)
		__field(u8, ts_antenna)
	),

	TP_fast_assign(
		PRIV_ASSIGN;
		__entry->skbaddr = (unsigned long) skb;
		__entry->qnum = (u8) q->qnum;
		__entry->ts_status = ts->ts_status;
		__entry->ts_rssi =  ts->ts_rssi;
		__entry->ts_antenna = ts->ts_antenna;
	),

	TP_printk(
		"[%p] TX end skb=%lx q=%d stat=%x rssi=%d ant=%x",
		__entry->priv, __entry->skbaddr, __entry->qnum,
		__entry->ts_status, __entry->ts_rssi, __entry->ts_antenna
	)
);

#endif /* __TRACE_ATH5K_H */

#ifdef CONFIG_ATH5K_TRACER

#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace

#include <trace/define_trace.h>

#endif