Commit 495391d7 authored by Bruno Randolf's avatar Bruno Randolf Committed by John W. Linville
Browse files

ath5k: simplify MIB counters



Let's keep MIB counter statistics in our own statistics structure and only
convert it to ieee80211_low_level_stats when needed by mac80211. Also we don't
need to read profile count registers in the MIB interrupt (they don't trigger
MIB interrupts).

Signed-off-by: default avatarBruno Randolf <br1@einfach.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9d332c82
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1173,8 +1173,7 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
				  struct ieee80211_low_level_stats *stats);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);

/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
+7 −9
Original line number Diff line number Diff line
@@ -2114,7 +2114,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
		info->status.rates[ts.ts_final_idx].count++;

		if (unlikely(ts.ts_status)) {
			sc->ll_stats.dot11ACKFailureCount++;
			sc->stats.ack_fail++;
			if (ts.ts_status & AR5K_TXERR_FILT) {
				info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
				sc->stats.txerr_filt++;
@@ -2708,11 +2708,7 @@ ath5k_intr(int irq, void *dev_id)
				/* TODO */
			}
			if (status & AR5K_INT_MIB) {
				/*
				 * These stats are also used for ANI i think
				 * so how about updating them more often ?
				 */
				ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
				ath5k_hw_update_mib_counters(ah);
			}
			if (status & AR5K_INT_GPIO)
				tasklet_schedule(&sc->rf_kill.toggleq);
@@ -3234,12 +3230,14 @@ ath5k_get_stats(struct ieee80211_hw *hw,
		struct ieee80211_low_level_stats *stats)
{
	struct ath5k_softc *sc = hw->priv;
	struct ath5k_hw *ah = sc->ah;

	/* Force update */
	ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
	ath5k_hw_update_mib_counters(sc->ah);

	memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
	stats->dot11ACKFailureCount = sc->stats.ack_fail;
	stats->dot11RTSFailureCount = sc->stats.rts_fail;
	stats->dot11RTSSuccessCount = sc->stats.rts_ok;
	stats->dot11FCSErrorCount = sc->stats.fcs_error;

	return 0;
}
+11 −2
Original line number Diff line number Diff line
@@ -105,10 +105,13 @@ struct ath5k_rfkill {
	struct tasklet_struct toggleq;
};

/* statistics (only used for debugging now) */
/* statistics */
struct ath5k_statistics {
	/* antenna use */
	unsigned int antenna_rx[5];	/* frames count per antenna RX */
	unsigned int antenna_tx[5];	/* frames count per antenna TX */

	/* frame errors */
	unsigned int rx_all_count;	/* all RX frames, including errors */
	unsigned int tx_all_count;	/* all TX frames, including errors */
	unsigned int rxerr_crc;
@@ -121,6 +124,13 @@ struct ath5k_statistics {
	unsigned int txerr_retry;
	unsigned int txerr_fifo;
	unsigned int txerr_filt;

	/* MIB counters */
	unsigned int ack_fail;
	unsigned int rts_fail;
	unsigned int rts_ok;
	unsigned int fcs_error;
	unsigned int beacons;
};

#if CHAN_DEBUG
@@ -135,7 +145,6 @@ struct ath5k_softc {
	struct pci_dev		*pdev;		/* for dma mapping */
	void __iomem		*iobase;	/* address of the device */
	struct mutex		lock;		/* dev-level lock */
	struct ieee80211_low_level_stats ll_stats;
	struct ieee80211_hw	*hw;		/* IEEE 802.11 common */
	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
	struct ieee80211_channel channels[ATH_CHAN_MAX];
+13 −26
Original line number Diff line number Diff line
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
}

/**
 * ath5k_hw_update - Update mib counters (mac layer statistics)
 * ath5k_hw_update - Update MIB counters (mac layer statistics)
 *
 * @ah: The &struct ath5k_hw
 * @stats: The &struct ieee80211_low_level_stats we use to track
 * statistics on the driver
 *
 * Reads MIB counters from PCU and updates sw statistics. Must be
 * called after a MIB interrupt.
 * Reads MIB counters from PCU and updates sw statistics. Is called after a
 * MIB interrupt, because one of these counters might have reached their maximum
 * and triggered the MIB interrupt, to let us read and clear the counter.
 *
 * Is called in interrupt context!
 */
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
		struct ieee80211_low_level_stats  *stats)
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
{
	ATH5K_TRACE(ah->ah_sc);
	struct ath5k_statistics *stats = &ah->ah_sc->stats;

	/* Read-And-Clear */
	stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
	stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
	stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
	stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);

	/* XXX: Should we use this to track beacon count ?
	 * -we read it anyway to clear the register */
	ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);

	/* Reset profile count registers on 5212*/
	if (ah->ah_version == AR5K_AR5212) {
		ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
		ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
		ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
		ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
	}

	/* TODO: Handle ANI stats */
	stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
	stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
	stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
	stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
	stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
}

/**