Skip to content

Commit

Permalink
ath9k: consolidate arguments on hw reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed Jan 29, 2009
1 parent ce111ba commit ae8d285
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 127 deletions.
7 changes: 2 additions & 5 deletions drivers/net/wireless/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -843,11 +843,8 @@ void ath9k_hw_rfdetach(struct ath_hal *ah);

/* HW Reset */

bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode,
u8 txchainmask, u8 rxchainmask,
enum ath9k_ht_extprotspacing extprotspacing,
bool bChannelChange, int *status);
int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
bool bChannelChange);

/* Key Cache Management */

Expand Down
68 changes: 24 additions & 44 deletions drivers/net/wireless/ath9k/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode,
u8 txchainmask, u8 rxchainmask,
enum ath9k_ht_extprotspacing extprotspacing,
bool bChannelChange, int *status)
int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
bool bChannelChange)
{
u32 saveLedState;
struct ath_softc *sc = ah->ah_sc;
struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_channel *curchan = ah->ah_curchan;
u32 saveDefAntenna;
u32 macStaId1;
int ecode;
int i, rx_chainmask;
int i, rx_chainmask, r;

ahp->ah_extprotspacing = extprotspacing;
ahp->ah_txchainmask = txchainmask;
ahp->ah_rxchainmask = rxchainmask;
ahp->ah_extprotspacing = sc->sc_ht_extprotspacing;
ahp->ah_txchainmask = sc->sc_tx_chainmask;
ahp->ah_rxchainmask = sc->sc_rx_chainmask;

if (AR_SREV_9280(ah)) {
ahp->ah_txchainmask &= 0x3;
Expand All @@ -2249,14 +2246,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags);
ecode = -EINVAL;
goto bad;
return -EINVAL;
}

if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
ecode = -EIO;
goto bad;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;

if (curchan)
ath9k_hw_getnf(ah, curchan);
Expand All @@ -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) &&
!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_start_nfcal(ah);
return true;
return 0;
}
}

Expand All @@ -2291,8 +2285,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,

if (!ath9k_hw_chip_reset(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
ecode = -EINVAL;
goto bad;
return -EINVAL;
}

if (AR_SREV_9280(ah)) {
Expand All @@ -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);
}

ecode = ath9k_hw_process_ini(ah, chan, macmode);
if (ecode != 0) {
ecode = -EINVAL;
goto bad;
}
r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
if (r)
return r;

if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
Expand All @@ -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)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error setting board options\n");
ecode = -EIO;
goto bad;
return -EIO;
}

ath9k_hw_decrease_chain_power(ah, chan);
Expand Down Expand Up @@ -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);

if (AR_SREV_9280_10_OR_LATER(ah)) {
if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
ecode = -EIO;
goto bad;
}
if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
return -EIO;
} else {
if (!(ath9k_hw_set_channel(ah, chan))) {
ecode = -EIO;
goto bad;
}
if (!(ath9k_hw_set_channel(ah, chan)))
return -EIO;
}

for (i = 0; i < AR_NUM_DCU; i++)
Expand Down Expand Up @@ -2396,10 +2382,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,

ath9k_hw_init_bb(ah, chan);

if (!ath9k_hw_init_cal(ah, chan)){
ecode = -EIO;;
goto bad;
}
if (!ath9k_hw_init_cal(ah, chan))
return -EIO;;

rx_chainmask = ahp->ah_rxchainmask;
if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
Expand Down Expand Up @@ -2428,11 +2412,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
#endif
}

return true;
bad:
if (status)
*status = ecode;
return false;
return 0;
}

/************************/
Expand Down
110 changes: 42 additions & 68 deletions drivers/net/wireless/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
struct ath_hal *ah = sc->sc_ah;
bool fastcc = true, stopped;
struct ieee80211_hw *hw = sc->hw;
struct ieee80211_channel *channel = hw->conf.channel;
int r;

if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
Expand All @@ -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 ||
(sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
(sc->sc_flags & SC_OP_FULL_RESET)) {
int status;
/*
* This is only performed if the channel settings have
* actually changed.
Expand All @@ -290,22 +291,20 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
fastcc = false;

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,
hchan->channel, hchan->channelFlags, sc->tx_chan_width);
channel->center_freq, sc->tx_chan_width);

spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, fastcc, &status)) {

r = ath9k_hw_reset(ah, hchan, fastcc);
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
"flags 0x%x hal status %u\n",
ath9k_hw_mhz2ieee(ah, hchan->channel,
hchan->channelFlags),
hchan->channel, hchan->channelFlags, status);
"Unable to reset channel (%u Mhz) "
"reset status %u\n",
channel->center_freq, r);
spin_unlock_bh(&sc->sc_resetlock);
return -EIO;
return r;
}
spin_unlock_bh(&sc->sc_resetlock);

Expand Down Expand Up @@ -1069,23 +1068,18 @@ static void ath_init_leds(struct ath_softc *sc)
static void ath_radio_enable(struct ath_softc *sc)
{
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);
if (!ath9k_hw_reset(ah, ah->ah_curchan,
sc->tx_chan_width,
sc->sc_tx_chainmask,
sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing,
false, &status)) {

r = ath9k_hw_reset(ah, ah->ah_curchan, false);

if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
"flags 0x%x hal status %u\n",
ath9k_hw_mhz2ieee(ah,
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags),
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags, status);
"Unable to reset channel %u (%uMhz) ",
"reset status %u\n",
channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);

Expand Down Expand Up @@ -1113,8 +1107,8 @@ static void ath_radio_enable(struct ath_softc *sc)
static void ath_radio_disable(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
int status;

struct ieee80211_channel *channel = sc->hw->conf.channel;
int r;

ieee80211_stop_queues(sc->hw);

Expand All @@ -1130,20 +1124,12 @@ static void ath_radio_disable(struct ath_softc *sc)
ath_flushrecv(sc); /* flush recv queue */

spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, ah->ah_curchan,
sc->tx_chan_width,
sc->sc_tx_chainmask,
sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing,
false, &status)) {
r = ath9k_hw_reset(ah, ah->ah_curchan, false);
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
"flags 0x%x hal status %u\n",
ath9k_hw_mhz2ieee(ah,
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags),
ah->ah_curchan->channel,
ah->ah_curchan->channelFlags, status);
"reset status %u\n",
channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);

Expand Down Expand Up @@ -1622,23 +1608,18 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
{
struct ath_hal *ah = sc->sc_ah;
struct ieee80211_hw *hw = sc->hw;
int status;
int error = 0;
int r;

ath9k_hw_set_interrupts(ah, 0);
ath_draintxq(sc, retry_tx);
ath_stoprecv(sc);
ath_flushrecv(sc);

spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
sc->tx_chan_width,
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false);
if (r)
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset hardware; hal status %u\n", status);
error = -EIO;
}
"Unable to reset hardware; reset status %u\n", r);
spin_unlock_bh(&sc->sc_resetlock);

if (ath_startrecv(sc) != 0)
Expand Down Expand Up @@ -1669,7 +1650,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
}
}

return error;
return r;
}

/*
Expand Down Expand Up @@ -1852,7 +1833,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv;
struct ieee80211_channel *curchan = hw->conf.channel;
struct ath9k_channel *init_channel;
int error = 0, pos, status;
int r, pos;

DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
"initial channel: %d MHz\n", curchan->center_freq);
Expand All @@ -1862,8 +1843,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
pos = ath_get_channel(sc, curchan);
if (pos == -1) {
DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
error = -EINVAL;
goto error;
return -EINVAL;
}

sc->tx_chan_width = ATH9K_HT_MACMODE_20;
Expand All @@ -1882,17 +1862,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(sc->sc_ah, init_channel,
sc->tx_chan_width,
sc->sc_tx_chainmask, sc->sc_rx_chainmask,
sc->sc_ht_extprotspacing, false, &status)) {
r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset hardware; hal status %u "
"(freq %u flags 0x%x)\n", status,
init_channel->channel, init_channel->channelFlags);
error = -EIO;
"Unable to reset hardware; reset status %u "
"(freq %u MHz)\n", r,
curchan->center_freq);
spin_unlock_bh(&sc->sc_resetlock);
goto error;
return r;
}
spin_unlock_bh(&sc->sc_resetlock);

Expand All @@ -1912,8 +1889,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ath_startrecv(sc) != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to start recv logic\n");
error = -EIO;
goto error;
return -EIO;
}

/* Setup our intr mask. */
Expand Down Expand Up @@ -1957,11 +1933,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(sc->hw);

#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
error = ath_start_rfkill_poll(sc);
r = ath_start_rfkill_poll(sc);
#endif

error:
return error;
return r;
}

static int ath9k_tx(struct ieee80211_hw *hw,
Expand Down
Loading

0 comments on commit ae8d285

Please sign in to comment.