Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290643
b: refs/heads/master
c: 775ed8a
h: refs/heads/master
i:
  290641: 2ddf25f
  290639: d01f9b8
v: v3
  • Loading branch information
Stanislaw Gruszka authored and John W. Linville committed Feb 22, 2012
1 parent fbb5569 commit ee1fbed
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c37281a076604937ec2403f3cfec71362f93c7d8
refs/heads/master: 775ed8abde9420afc955ca7540aacdce721be6c1
17 changes: 13 additions & 4 deletions trunk/drivers/net/wireless/iwlegacy/3945-mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -2286,16 +2286,25 @@ __il3945_down(struct il_priv *il)
test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;

/*
* We disabled and synchronized interrupt, and priv->mutex is taken, so
* here is the only thread which will program device registers, but
* still have lockdep assertions, so we are taking reg_lock.
*/
spin_lock_irq(&il->reg_lock);
/* FIXME: il_grab_nic_access if rfkill is off ? */

il3945_hw_txq_ctx_stop(il);
il3945_hw_rxq_stop(il);

/* Power-down device's busmaster DMA clocks */
il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
_il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);

/* Stop the device, and put it in low power state */
il_apm_stop(il);
_il_apm_stop(il);

spin_unlock_irq(&il->reg_lock);

il3945_hw_txq_ctx_free(il);
exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp));

Expand Down
27 changes: 14 additions & 13 deletions trunk/drivers/net/wireless/iwlegacy/3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,18 +1016,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
int txq_id;

/* stop SCD */
il_wr_prph(il, ALM_SCD_MODE_REG, 0);
il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
_il_wr_prph(il, ALM_SCD_MODE_REG, 0);
_il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);

/* reset TFD queues */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
il_poll_bit(il, FH39_TSSR_TX_STATUS,
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
_il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
_il_poll_bit(il, FH39_TSSR_TX_STATUS,
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
}

il3945_hw_txq_ctx_free(il);
}

/**
Expand Down Expand Up @@ -2176,12 +2175,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
int
il3945_hw_rxq_stop(struct il_priv *il)
{
int rc;
int ret;

il_wr(il, FH39_RCSR_CONFIG(0), 0);
rc = il_poll_bit(il, FH39_RSSR_STATUS,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
_il_wr(il, FH39_RCSR_CONFIG(0), 0);
ret = _il_poll_bit(il, FH39_RSSR_STATUS,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");

return 0;
Expand Down
81 changes: 48 additions & 33 deletions trunk/drivers/net/wireless/iwlegacy/4965-mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
int
il4965_rxq_stop(struct il_priv *il)
{
int ret;

/* stop Rx DMA */
il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
_il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");

return 0;
}
Expand Down Expand Up @@ -2031,31 +2035,10 @@ il4965_txq_ctx_reset(struct il_priv *il)
}
}

/**
* il4965_txq_ctx_stop - Stop all Tx DMA channels
*/
void
il4965_txq_ctx_stop(struct il_priv *il)
il4965_txq_ctx_unmap(struct il_priv *il)
{
int ch, txq_id;
unsigned long flags;

/* Turn off all Tx DMA fifos */
spin_lock_irqsave(&il->lock, flags);

il4965_txq_set_sched(il, 0);

/* Stop each Tx DMA channel, and wait for it to be idle */
for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
if (il_poll_bit
(il, FH49_TSSR_TX_STATUS_REG,
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000))
IL_ERR("Failing on timeout while stopping"
" DMA channel %d [0x%08x]", ch,
il_rd(il, FH49_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&il->lock, flags);
int txq_id;

if (!il->txq)
return;
Expand All @@ -2068,6 +2051,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
il_tx_queue_unmap(il, txq_id);
}

/**
* il4965_txq_ctx_stop - Stop all Tx DMA channels
*/
void
il4965_txq_ctx_stop(struct il_priv *il)
{
int ch, ret;

_il_wr_prph(il, IL49_SCD_TXFACT, 0);

/* Stop each Tx DMA channel, and wait for it to be idle */
for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
_il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
ret =
_il_poll_bit(il, FH49_TSSR_TX_STATUS_REG,
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
1000);
if (ret < 0)
IL_ERR("Timeout stopping DMA channel %d [0x%08x]",
ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG));
}
}

/*
* Find first available (lowest unused) Tx Queue, mark it "active".
* Called only when finding queue for aggregation.
Expand Down Expand Up @@ -5398,19 +5405,27 @@ __il4965_down(struct il_priv *il)
test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;

/*
* We disabled and synchronized interrupt, and priv->mutex is taken, so
* here is the only thread which will program device registers, but
* still have lockdep assertions, so we are taking reg_lock.
*/
spin_lock_irq(&il->reg_lock);
/* FIXME: il_grab_nic_access if rfkill is off ? */

il4965_txq_ctx_stop(il);
il4965_rxq_stop(il);

/* Power-down device's busmaster DMA clocks */
il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
_il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);

/* Make sure (redundant) we've released our request to stay awake */
il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);

_il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
/* Stop the device, and put it in low power state */
il_apm_stop(il);
_il_apm_stop(il);

spin_unlock_irq(&il->reg_lock);

il4965_txq_ctx_unmap(il);
exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp));

Expand Down
25 changes: 19 additions & 6 deletions trunk/drivers/net/wireless/iwlegacy/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4126,12 +4126,12 @@ il_irq_handle_error(struct il_priv *il)
EXPORT_SYMBOL(il_irq_handle_error);

static int
il_apm_stop_master(struct il_priv *il)
_il_apm_stop_master(struct il_priv *il)
{
int ret = 0;

/* stop device's busmaster DMA activity */
il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
_il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);

ret =
_il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
Expand All @@ -4145,23 +4145,36 @@ il_apm_stop_master(struct il_priv *il)
}

void
il_apm_stop(struct il_priv *il)
_il_apm_stop(struct il_priv *il)
{
lockdep_assert_held(&il->reg_lock);

D_INFO("Stop card, put in low power state\n");

/* Stop device's DMA activity */
il_apm_stop_master(il);
_il_apm_stop_master(il);

/* Reset the entire device */
il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
_il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);

udelay(10);

/*
* Clear "initialization complete" bit to move adapter from
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
_il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
}
EXPORT_SYMBOL(_il_apm_stop);

void
il_apm_stop(struct il_priv *il)
{
unsigned long flags;

spin_lock_irqsave(&il->reg_lock, flags);
_il_apm_stop(il);
spin_unlock_irqrestore(&il->reg_lock, flags);
}
EXPORT_SYMBOL(il_apm_stop);

Expand Down
4 changes: 3 additions & 1 deletion trunk/drivers/net/wireless/iwlegacy/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1976,7 +1976,9 @@ il_is_ready_rf(struct il_priv *il)

extern void il_send_bt_config(struct il_priv *il);
extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear);
void il_apm_stop(struct il_priv *il);
extern void il_apm_stop(struct il_priv *il);
extern void _il_apm_stop(struct il_priv *il);

int il_apm_init(struct il_priv *il);

int il_send_rxon_timing(struct il_priv *il);
Expand Down

0 comments on commit ee1fbed

Please sign in to comment.