diff options
author | Bruno Randolf <br1@einfach.org> | 2010-03-25 01:49:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-31 14:39:09 -0400 |
commit | 495391d715a310a7cbf622850e372d40ac86ef6e (patch) | |
tree | 7da16c9d9fea88c9fdbeabc839d4d8380fc317ab /drivers/net/wireless | |
parent | 9d332c82b4cf2e4538450e4af40f073cc5e599ec (diff) |
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: Bruno Randolf <br1@einfach.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/pcu.c | 39 |
4 files changed, 32 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index cefd28d5deee..ec626905655b 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1173,8 +1173,7 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); | |||
1173 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); | 1173 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); |
1174 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); | 1174 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); |
1175 | enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); | 1175 | enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); |
1176 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | 1176 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); |
1177 | struct ieee80211_low_level_stats *stats); | ||
1178 | 1177 | ||
1179 | /* EEPROM access functions */ | 1178 | /* EEPROM access functions */ |
1180 | int ath5k_eeprom_init(struct ath5k_hw *ah); | 1179 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ba2fad23a7a5..ea33b993b28e 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2114,7 +2114,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
2114 | info->status.rates[ts.ts_final_idx].count++; | 2114 | info->status.rates[ts.ts_final_idx].count++; |
2115 | 2115 | ||
2116 | if (unlikely(ts.ts_status)) { | 2116 | if (unlikely(ts.ts_status)) { |
2117 | sc->ll_stats.dot11ACKFailureCount++; | 2117 | sc->stats.ack_fail++; |
2118 | if (ts.ts_status & AR5K_TXERR_FILT) { | 2118 | if (ts.ts_status & AR5K_TXERR_FILT) { |
2119 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 2119 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
2120 | sc->stats.txerr_filt++; | 2120 | sc->stats.txerr_filt++; |
@@ -2708,11 +2708,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2708 | /* TODO */ | 2708 | /* TODO */ |
2709 | } | 2709 | } |
2710 | if (status & AR5K_INT_MIB) { | 2710 | if (status & AR5K_INT_MIB) { |
2711 | /* | 2711 | ath5k_hw_update_mib_counters(ah); |
2712 | * These stats are also used for ANI i think | ||
2713 | * so how about updating them more often ? | ||
2714 | */ | ||
2715 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | ||
2716 | } | 2712 | } |
2717 | if (status & AR5K_INT_GPIO) | 2713 | if (status & AR5K_INT_GPIO) |
2718 | tasklet_schedule(&sc->rf_kill.toggleq); | 2714 | tasklet_schedule(&sc->rf_kill.toggleq); |
@@ -3234,12 +3230,14 @@ ath5k_get_stats(struct ieee80211_hw *hw, | |||
3234 | struct ieee80211_low_level_stats *stats) | 3230 | struct ieee80211_low_level_stats *stats) |
3235 | { | 3231 | { |
3236 | struct ath5k_softc *sc = hw->priv; | 3232 | struct ath5k_softc *sc = hw->priv; |
3237 | struct ath5k_hw *ah = sc->ah; | ||
3238 | 3233 | ||
3239 | /* Force update */ | 3234 | /* Force update */ |
3240 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | 3235 | ath5k_hw_update_mib_counters(sc->ah); |
3241 | 3236 | ||
3242 | memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); | 3237 | stats->dot11ACKFailureCount = sc->stats.ack_fail; |
3238 | stats->dot11RTSFailureCount = sc->stats.rts_fail; | ||
3239 | stats->dot11RTSSuccessCount = sc->stats.rts_ok; | ||
3240 | stats->dot11FCSErrorCount = sc->stats.fcs_error; | ||
3243 | 3241 | ||
3244 | return 0; | 3242 | return 0; |
3245 | } | 3243 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 33f1d8b87ee1..fe5dae517545 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -105,10 +105,13 @@ struct ath5k_rfkill { | |||
105 | struct tasklet_struct toggleq; | 105 | struct tasklet_struct toggleq; |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* statistics (only used for debugging now) */ | 108 | /* statistics */ |
109 | struct ath5k_statistics { | 109 | struct ath5k_statistics { |
110 | /* antenna use */ | ||
110 | unsigned int antenna_rx[5]; /* frames count per antenna RX */ | 111 | unsigned int antenna_rx[5]; /* frames count per antenna RX */ |
111 | unsigned int antenna_tx[5]; /* frames count per antenna TX */ | 112 | unsigned int antenna_tx[5]; /* frames count per antenna TX */ |
113 | |||
114 | /* frame errors */ | ||
112 | unsigned int rx_all_count; /* all RX frames, including errors */ | 115 | unsigned int rx_all_count; /* all RX frames, including errors */ |
113 | unsigned int tx_all_count; /* all TX frames, including errors */ | 116 | unsigned int tx_all_count; /* all TX frames, including errors */ |
114 | unsigned int rxerr_crc; | 117 | unsigned int rxerr_crc; |
@@ -121,6 +124,13 @@ struct ath5k_statistics { | |||
121 | unsigned int txerr_retry; | 124 | unsigned int txerr_retry; |
122 | unsigned int txerr_fifo; | 125 | unsigned int txerr_fifo; |
123 | unsigned int txerr_filt; | 126 | unsigned int txerr_filt; |
127 | |||
128 | /* MIB counters */ | ||
129 | unsigned int ack_fail; | ||
130 | unsigned int rts_fail; | ||
131 | unsigned int rts_ok; | ||
132 | unsigned int fcs_error; | ||
133 | unsigned int beacons; | ||
124 | }; | 134 | }; |
125 | 135 | ||
126 | #if CHAN_DEBUG | 136 | #if CHAN_DEBUG |
@@ -135,7 +145,6 @@ struct ath5k_softc { | |||
135 | struct pci_dev *pdev; /* for dma mapping */ | 145 | struct pci_dev *pdev; /* for dma mapping */ |
136 | void __iomem *iobase; /* address of the device */ | 146 | void __iomem *iobase; /* address of the device */ |
137 | struct mutex lock; /* dev-level lock */ | 147 | struct mutex lock; /* dev-level lock */ |
138 | struct ieee80211_low_level_stats ll_stats; | ||
139 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 148 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
140 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 149 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
141 | struct ieee80211_channel channels[ATH_CHAN_MAX]; | 150 | struct ieee80211_channel channels[ATH_CHAN_MAX]; |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 1b9fcb842167..c7c1fe023724 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * ath5k_hw_update - Update mib counters (mac layer statistics) | 116 | * ath5k_hw_update - Update MIB counters (mac layer statistics) |
117 | * | 117 | * |
118 | * @ah: The &struct ath5k_hw | 118 | * @ah: The &struct ath5k_hw |
119 | * @stats: The &struct ieee80211_low_level_stats we use to track | ||
120 | * statistics on the driver | ||
121 | * | 119 | * |
122 | * Reads MIB counters from PCU and updates sw statistics. Must be | 120 | * Reads MIB counters from PCU and updates sw statistics. Is called after a |
123 | * called after a MIB interrupt. | 121 | * MIB interrupt, because one of these counters might have reached their maximum |
122 | * and triggered the MIB interrupt, to let us read and clear the counter. | ||
123 | * | ||
124 | * Is called in interrupt context! | ||
124 | */ | 125 | */ |
125 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | 126 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) |
126 | struct ieee80211_low_level_stats *stats) | ||
127 | { | 127 | { |
128 | ATH5K_TRACE(ah->ah_sc); | 128 | struct ath5k_statistics *stats = &ah->ah_sc->stats; |
129 | 129 | ||
130 | /* Read-And-Clear */ | 130 | /* Read-And-Clear */ |
131 | stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); | 131 | stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); |
132 | stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); | 132 | stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); |
133 | stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); | 133 | stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK); |
134 | stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); | 134 | stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); |
135 | 135 | stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | |
136 | /* XXX: Should we use this to track beacon count ? | ||
137 | * -we read it anyway to clear the register */ | ||
138 | ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | ||
139 | |||
140 | /* Reset profile count registers on 5212*/ | ||
141 | if (ah->ah_version == AR5K_AR5212) { | ||
142 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | ||
143 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | ||
144 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
145 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
146 | } | ||
147 | |||
148 | /* TODO: Handle ANI stats */ | ||
149 | } | 136 | } |
150 | 137 | ||
151 | /** | 138 | /** |