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

Commit 8e6f5aa2 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville
Browse files

ath9k: split out access to rx status information



This patch passes in a pointer to the ath_rx_status data structure for
functions that need it, instead of letting them grab it directly from
the ath_desc struct. This is useful for making it possible to allocate
the intermediate rx status data separately.

Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent db1a052b
Loading
Loading
Loading
Loading
+9 −10
Original line number Original line Diff line number Diff line
@@ -660,30 +660,29 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
#undef PHY_ERR
#undef PHY_ERR
}
}


void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf)
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
{
{
#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++


	struct ath_desc *ds = bf->bf_desc;
	u32 phyerr;
	u32 phyerr;


	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
	if (rs->rs_status & ATH9K_RXERR_CRC)
		RX_STAT_INC(crc_err);
		RX_STAT_INC(crc_err);
	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT)
	if (rs->rs_status & ATH9K_RXERR_DECRYPT)
		RX_STAT_INC(decrypt_crc_err);
		RX_STAT_INC(decrypt_crc_err);
	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC)
	if (rs->rs_status & ATH9K_RXERR_MIC)
		RX_STAT_INC(mic_err);
		RX_STAT_INC(mic_err);
	if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE)
	if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
		RX_STAT_INC(pre_delim_crc_err);
		RX_STAT_INC(pre_delim_crc_err);
	if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST)
	if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
		RX_STAT_INC(post_delim_crc_err);
		RX_STAT_INC(post_delim_crc_err);
	if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY)
	if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
		RX_STAT_INC(decrypt_busy_err);
		RX_STAT_INC(decrypt_busy_err);


	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
	if (rs->rs_status & ATH9K_RXERR_PHY) {
		RX_STAT_INC(phy_err);
		RX_STAT_INC(phy_err);
		phyerr = ds->ds_rxstat.rs_phyerr & 0x24;
		phyerr = rs->rs_phyerr & 0x24;
		RX_PHY_ERR_INC(phyerr);
		RX_PHY_ERR_INC(phyerr);
	}
	}


+1 −1
Original line number Original line Diff line number Diff line
@@ -168,7 +168,7 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
		       struct ath_buf *bf, struct ath_tx_status *ts);
		       struct ath_buf *bf, struct ath_tx_status *ts);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
			    int xretries, int retries, u8 per);
			    int xretries, int retries, u8 per);


+36 −36
Original line number Original line Diff line number Diff line
@@ -859,7 +859,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
EXPORT_SYMBOL(ath9k_hw_resettxqueue);
EXPORT_SYMBOL(ath9k_hw_resettxqueue);


int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
			u32 pa, struct ath_desc *nds, u64 tsf)
			struct ath_rx_status *rs, u64 tsf)
{
{
	struct ar5416_desc ads;
	struct ar5416_desc ads;
	struct ar5416_desc *adsp = AR5416DESC(ds);
	struct ar5416_desc *adsp = AR5416DESC(ds);
@@ -870,70 +870,70 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,


	ads.u.rx = adsp->u.rx;
	ads.u.rx = adsp->u.rx;


	ds->ds_rxstat.rs_status = 0;
	rs->rs_status = 0;
	ds->ds_rxstat.rs_flags = 0;
	rs->rs_flags = 0;


	ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
	rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
	ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
	rs->rs_tstamp = ads.AR_RcvTimestamp;


	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
		ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD;
		rs->rs_rssi = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
		ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD;
		rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
	} else {
	} else {
		ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
		rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
		ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
		rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
						AR_RxRSSIAnt00);
						AR_RxRSSIAnt00);
		ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
		rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
						AR_RxRSSIAnt01);
						AR_RxRSSIAnt01);
		ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
		rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
						AR_RxRSSIAnt02);
						AR_RxRSSIAnt02);
		ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4,
		rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
						AR_RxRSSIAnt10);
						AR_RxRSSIAnt10);
		ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4,
		rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
						AR_RxRSSIAnt11);
						AR_RxRSSIAnt11);
		ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4,
		rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
						AR_RxRSSIAnt12);
						AR_RxRSSIAnt12);
	}
	}
	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
		ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
		rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
	else
	else
		ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
		rs->rs_keyix = ATH9K_RXKEYIX_INVALID;


	ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
	rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
	ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
	rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;


	ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
	rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
	ds->ds_rxstat.rs_moreaggr =
	rs->rs_moreaggr =
		(ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
		(ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
	ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
	rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
	ds->ds_rxstat.rs_flags =
	rs->rs_flags =
		(ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
		(ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
	ds->ds_rxstat.rs_flags |=
	rs->rs_flags |=
		(ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
		(ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;


	if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
	if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
		ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
		rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
		ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
		rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
	if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
	if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
		ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
		rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;


	if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
	if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
		if (ads.ds_rxstatus8 & AR_CRCErr)
		if (ads.ds_rxstatus8 & AR_CRCErr)
			ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
			rs->rs_status |= ATH9K_RXERR_CRC;
		else if (ads.ds_rxstatus8 & AR_PHYErr) {
		else if (ads.ds_rxstatus8 & AR_PHYErr) {
			ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
			rs->rs_status |= ATH9K_RXERR_PHY;
			phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
			phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
			ds->ds_rxstat.rs_phyerr = phyerr;
			rs->rs_phyerr = phyerr;
		} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
		} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
			ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
			rs->rs_status |= ATH9K_RXERR_DECRYPT;
		else if (ads.ds_rxstatus8 & AR_MichaelErr)
		else if (ads.ds_rxstatus8 & AR_MichaelErr)
			ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
			rs->rs_status |= ATH9K_RXERR_MIC;
	}
	}


	return 0;
	return 0;
+1 −4
Original line number Original line Diff line number Diff line
@@ -241,9 +241,6 @@ struct ath_desc {
	void *ds_vdata;
	void *ds_vdata;
} __packed;
} __packed;


#define	ds_rxstat	ds_us.rx
#define ds_stat		ds_us.stats

#define ATH9K_TXDESC_CLRDMASK		0x0001
#define ATH9K_TXDESC_CLRDMASK		0x0001
#define ATH9K_TXDESC_NOACK		0x0002
#define ATH9K_TXDESC_NOACK		0x0002
#define ATH9K_TXDESC_RTSENA		0x0004
#define ATH9K_TXDESC_RTSENA		0x0004
@@ -732,7 +729,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
			u32 pa, struct ath_desc *nds, u64 tsf);
			struct ath_rx_status *rs, u64 tsf);
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
			  u32 size, u32 flags);
			  u32 size, u32 flags);
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+5 −9
Original line number Original line Diff line number Diff line
@@ -506,6 +506,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)


		bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
		bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
		ds = bf->bf_desc;
		ds = bf->bf_desc;
		rx_stats = &ds->ds_us.rx;


		/*
		/*
		 * Must provide the virtual address of the current
		 * Must provide the virtual address of the current
@@ -518,10 +519,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
		 * on.  All this is necessary because of our use of
		 * on.  All this is necessary because of our use of
		 * a self-linked list to avoid rx overruns.
		 * a self-linked list to avoid rx overruns.
		 */
		 */
		retval = ath9k_hw_rxprocdesc(ah, ds,
		retval = ath9k_hw_rxprocdesc(ah, ds, rx_stats, 0);
					     bf->bf_daddr,
					     PA2DESC(sc, ds->ds_link),
					     0);
		if (retval == -EINPROGRESS) {
		if (retval == -EINPROGRESS) {
			struct ath_buf *tbf;
			struct ath_buf *tbf;
			struct ath_desc *tds;
			struct ath_desc *tds;
@@ -545,8 +543,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
			 */
			 */


			tds = tbf->bf_desc;
			tds = tbf->bf_desc;
			retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
			retval = ath9k_hw_rxprocdesc(ah, tds, &tds->ds_us.rx, 0);
					     PA2DESC(sc, tds->ds_link), 0);
			if (retval == -EINPROGRESS) {
			if (retval == -EINPROGRESS) {
				break;
				break;
			}
			}
@@ -569,9 +566,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
		rxs =  IEEE80211_SKB_RXCB(skb);
		rxs =  IEEE80211_SKB_RXCB(skb);


		hw = ath_get_virt_hw(sc, hdr);
		hw = ath_get_virt_hw(sc, hdr);
		rx_stats = &ds->ds_rxstat;


		ath_debug_stat_rx(sc, bf);
		ath_debug_stat_rx(sc, rx_stats);


		/*
		/*
		 * If we're asked to flush receive queue, directly
		 * If we're asked to flush receive queue, directly
@@ -626,7 +622,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
		 * change the default rx antenna if rx diversity chooses the
		 * change the default rx antenna if rx diversity chooses the
		 * other antenna 3 times in a row.
		 * other antenna 3 times in a row.
		 */
		 */
		if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
		if (sc->rx.defant != rx_stats->rs_antenna) {
			if (++sc->rx.rxotherant >= 3)
			if (++sc->rx.rxotherant >= 3)
				ath_setdefantenna(sc, rx_stats->rs_antenna);
				ath_setdefantenna(sc, rx_stats->rs_antenna);
		} else {
		} else {