ath9k: consolidate arguments on hw reset

HW reset calls pass the same variables or structs
which we can obtain easily from ah. Although this also applies
during channel changes as we will keep around the ath9k_channel
passed as an argument for now.

We now also now propagate the hw reset errors down.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Luis R. Rodriguez 2008-12-23 15:58:40 -08:00 коммит произвёл John W. Linville
Родитель ce111badf5
Коммит ae8d2858c5
4 изменённых файлов: 74 добавлений и 127 удалений

Просмотреть файл

@ -843,11 +843,8 @@ void ath9k_hw_rfdetach(struct ath_hal *ah);
/* HW Reset */ /* HW Reset */
bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode, bool bChannelChange);
u8 txchainmask, u8 rxchainmask,
enum ath9k_ht_extprotspacing extprotspacing,
bool bChannelChange, int *status);
/* Key Cache Management */ /* Key Cache Management */

Просмотреть файл

@ -2222,23 +2222,20 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
} }
bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode, bool bChannelChange)
u8 txchainmask, u8 rxchainmask,
enum ath9k_ht_extprotspacing extprotspacing,
bool bChannelChange, int *status)
{ {
u32 saveLedState; u32 saveLedState;
struct ath_softc *sc = ah->ah_sc;
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_channel *curchan = ah->ah_curchan; struct ath9k_channel *curchan = ah->ah_curchan;
u32 saveDefAntenna; u32 saveDefAntenna;
u32 macStaId1; u32 macStaId1;
int ecode; int i, rx_chainmask, r;
int i, rx_chainmask;
ahp->ah_extprotspacing = extprotspacing; ahp->ah_extprotspacing = sc->sc_ht_extprotspacing;
ahp->ah_txchainmask = txchainmask; ahp->ah_txchainmask = sc->sc_tx_chainmask;
ahp->ah_rxchainmask = rxchainmask; ahp->ah_rxchainmask = sc->sc_rx_chainmask;
if (AR_SREV_9280(ah)) { if (AR_SREV_9280(ah)) {
ahp->ah_txchainmask &= 0x3; ahp->ah_txchainmask &= 0x3;
@ -2249,14 +2246,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"invalid channel %u/0x%x; no mapping\n", "invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags); chan->channel, chan->channelFlags);
ecode = -EINVAL; return -EINVAL;
goto bad;
} }
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
ecode = -EIO; return -EIO;
goto bad;
}
if (curchan) if (curchan)
ath9k_hw_getnf(ah, curchan); ath9k_hw_getnf(ah, curchan);
@ -2270,10 +2264,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
(!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
!IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) { !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
if (ath9k_hw_channel_change(ah, chan, macmode)) { if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
ath9k_hw_loadnf(ah, ah->ah_curchan); ath9k_hw_loadnf(ah, ah->ah_curchan);
ath9k_hw_start_nfcal(ah); ath9k_hw_start_nfcal(ah);
return true; return 0;
} }
} }
@ -2291,8 +2285,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
if (!ath9k_hw_chip_reset(ah, chan)) { if (!ath9k_hw_chip_reset(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
ecode = -EINVAL; return -EINVAL;
goto bad;
} }
if (AR_SREV_9280(ah)) { if (AR_SREV_9280(ah)) {
@ -2308,11 +2301,9 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
} }
ecode = ath9k_hw_process_ini(ah, chan, macmode); r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
if (ecode != 0) { if (r)
ecode = -EINVAL; return r;
goto bad;
}
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan); ath9k_hw_set_delta_slope(ah, chan);
@ -2325,8 +2316,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error setting board options\n"); "error setting board options\n");
ecode = -EIO; return -EIO;
goto bad;
} }
ath9k_hw_decrease_chain_power(ah, chan); ath9k_hw_decrease_chain_power(ah, chan);
@ -2354,15 +2344,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
if (AR_SREV_9280_10_OR_LATER(ah)) { if (AR_SREV_9280_10_OR_LATER(ah)) {
if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
ecode = -EIO; return -EIO;
goto bad;
}
} else { } else {
if (!(ath9k_hw_set_channel(ah, chan))) { if (!(ath9k_hw_set_channel(ah, chan)))
ecode = -EIO; return -EIO;
goto bad;
}
} }
for (i = 0; i < AR_NUM_DCU; i++) for (i = 0; i < AR_NUM_DCU; i++)
@ -2396,10 +2382,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
ath9k_hw_init_bb(ah, chan); ath9k_hw_init_bb(ah, chan);
if (!ath9k_hw_init_cal(ah, chan)){ if (!ath9k_hw_init_cal(ah, chan))
ecode = -EIO;; return -EIO;;
goto bad;
}
rx_chainmask = ahp->ah_rxchainmask; rx_chainmask = ahp->ah_rxchainmask;
if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
@ -2428,11 +2412,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
#endif #endif
} }
return true; return 0;
bad:
if (status)
*status = ecode;
return false;
} }
/************************/ /************************/

Просмотреть файл

@ -260,6 +260,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
bool fastcc = true, stopped; bool fastcc = true, stopped;
struct ieee80211_hw *hw = sc->hw; struct ieee80211_hw *hw = sc->hw;
struct ieee80211_channel *channel = hw->conf.channel;
int r;
if (sc->sc_flags & SC_OP_INVALID) if (sc->sc_flags & SC_OP_INVALID)
return -EIO; return -EIO;
@ -268,7 +270,6 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
(sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
(sc->sc_flags & SC_OP_FULL_RESET)) { (sc->sc_flags & SC_OP_FULL_RESET)) {
int status;
/* /*
* This is only performed if the channel settings have * This is only performed if the channel settings have
* actually changed. * actually changed.
@ -290,22 +291,20 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
fastcc = false; fastcc = false;
DPRINTF(sc, ATH_DBG_CONFIG, DPRINTF(sc, ATH_DBG_CONFIG,
"(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", "(%u MHz) -> (%u MHz), chanwidth: %d\n",
sc->sc_ah->ah_curchan->channel, sc->sc_ah->ah_curchan->channel,
hchan->channel, hchan->channelFlags, sc->tx_chan_width); channel->center_freq, sc->tx_chan_width);
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
sc->sc_tx_chainmask, sc->sc_rx_chainmask, r = ath9k_hw_reset(ah, hchan, fastcc);
sc->sc_ht_extprotspacing, fastcc, &status)) { if (r) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) " "Unable to reset channel (%u Mhz) "
"flags 0x%x hal status %u\n", "reset status %u\n",
ath9k_hw_mhz2ieee(ah, hchan->channel, channel->center_freq, r);
hchan->channelFlags),
hchan->channel, hchan->channelFlags, status);
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
return -EIO; return r;
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
@ -1069,23 +1068,18 @@ fail:
static void ath_radio_enable(struct ath_softc *sc) static void ath_radio_enable(struct ath_softc *sc)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
int status; struct ieee80211_channel *channel = sc->hw->conf.channel;
int r;
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, ah->ah_curchan,
sc->tx_chan_width, r = ath9k_hw_reset(ah, ah->ah_curchan, false);
sc->sc_tx_chainmask,
sc->sc_rx_chainmask, if (r) {
sc->sc_ht_extprotspacing,
false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) " "Unable to reset channel %u (%uMhz) ",
"flags 0x%x hal status %u\n", "reset status %u\n",
ath9k_hw_mhz2ieee(ah, channel->center_freq, r);
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags),
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags, status);
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
@ -1113,8 +1107,8 @@ static void ath_radio_enable(struct ath_softc *sc)
static void ath_radio_disable(struct ath_softc *sc) static void ath_radio_disable(struct ath_softc *sc)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
int status; struct ieee80211_channel *channel = sc->hw->conf.channel;
int r;
ieee80211_stop_queues(sc->hw); ieee80211_stop_queues(sc->hw);
@ -1130,20 +1124,12 @@ static void ath_radio_disable(struct ath_softc *sc)
ath_flushrecv(sc); /* flush recv queue */ ath_flushrecv(sc); /* flush recv queue */
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, ah->ah_curchan, r = ath9k_hw_reset(ah, ah->ah_curchan, false);
sc->tx_chan_width, if (r) {
sc->sc_tx_chainmask,
sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing,
false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) " "Unable to reset channel %u (%uMhz) "
"flags 0x%x hal status %u\n", "reset status %u\n",
ath9k_hw_mhz2ieee(ah, channel->center_freq, r);
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags),
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags, status);
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
@ -1622,8 +1608,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
struct ieee80211_hw *hw = sc->hw; struct ieee80211_hw *hw = sc->hw;
int status; int r;
int error = 0;
ath9k_hw_set_interrupts(ah, 0); ath9k_hw_set_interrupts(ah, 0);
ath_draintxq(sc, retry_tx); ath_draintxq(sc, retry_tx);
@ -1631,14 +1616,10 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
ath_flushrecv(sc); ath_flushrecv(sc);
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false);
sc->tx_chan_width, if (r)
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset hardware; hal status %u\n", status); "Unable to reset hardware; reset status %u\n", r);
error = -EIO;
}
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0) if (ath_startrecv(sc) != 0)
@ -1669,7 +1650,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
} }
} }
return error; return r;
} }
/* /*
@ -1852,7 +1833,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ieee80211_channel *curchan = hw->conf.channel; struct ieee80211_channel *curchan = hw->conf.channel;
struct ath9k_channel *init_channel; struct ath9k_channel *init_channel;
int error = 0, pos, status; int r, pos;
DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
"initial channel: %d MHz\n", curchan->center_freq); "initial channel: %d MHz\n", curchan->center_freq);
@ -1862,8 +1843,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
pos = ath_get_channel(sc, curchan); pos = ath_get_channel(sc, curchan);
if (pos == -1) { if (pos == -1) {
DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
error = -EINVAL; return -EINVAL;
goto error;
} }
sc->tx_chan_width = ATH9K_HT_MACMODE_20; sc->tx_chan_width = ATH9K_HT_MACMODE_20;
@ -1882,17 +1862,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask. * and then setup of the interrupt mask.
*/ */
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(sc->sc_ah, init_channel, r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
sc->tx_chan_width, if (r) {
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset hardware; hal status %u " "Unable to reset hardware; reset status %u "
"(freq %u flags 0x%x)\n", status, "(freq %u MHz)\n", r,
init_channel->channel, init_channel->channelFlags); curchan->center_freq);
error = -EIO;
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
goto error; return r;
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
@ -1912,8 +1889,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ath_startrecv(sc) != 0) { if (ath_startrecv(sc) != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to start recv logic\n"); "Unable to start recv logic\n");
error = -EIO; return -EIO;
goto error;
} }
/* Setup our intr mask. */ /* Setup our intr mask. */
@ -1957,11 +1933,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(sc->hw); ieee80211_wake_queues(sc->hw);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
error = ath_start_rfkill_poll(sc); r = ath_start_rfkill_poll(sc);
#endif #endif
return r;
error:
return error;
} }
static int ath9k_tx(struct ieee80211_hw *hw, static int ath9k_tx(struct ieee80211_hw *hw,

Просмотреть файл

@ -1140,7 +1140,7 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
{ {
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
int i, status, npend = 0; int i, npend = 0;
if (!(sc->sc_flags & SC_OP_INVALID)) { if (!(sc->sc_flags & SC_OP_INVALID)) {
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
@ -1155,20 +1155,16 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
} }
if (npend) { if (npend) {
int r;
/* TxDMA not stopped, reset the hal */ /* TxDMA not stopped, reset the hal */
DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true);
sc->sc_ah->ah_curchan, if (r)
sc->tx_chan_width,
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, true, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset hardware; hal status %u\n", "Unable to reset hardware; reset status %u\n",
status); r);
}
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
} }