aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2012-02-13 05:23:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-02-22 14:51:16 -0500
commit775ed8abde9420afc955ca7540aacdce721be6c1 (patch)
tree7ff55b22f75b9d694382514f6d59c490f5d1df1c /drivers/net/wireless
parentc37281a076604937ec2403f3cfec71362f93c7d8 (diff)
iwlegacy: do not grab nic access if rfkill
If rfkill is on il_grab_nic_access() fail and we can not write to the various registers during stop procedure. Write to those registers unconditionally instead. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c17
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c27
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c81
-rw-r--r--drivers/net/wireless/iwlegacy/common.c25
-rw-r--r--drivers/net/wireless/iwlegacy/common.h4
5 files changed, 97 insertions, 57 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 002cf4fd5a55..ee91ab2e3858 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -2286,16 +2286,25 @@ __il3945_down(struct il_priv *il)
2286 test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR | 2286 test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
2287 test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; 2287 test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
2288 2288
2289 /*
2290 * We disabled and synchronized interrupt, and priv->mutex is taken, so
2291 * here is the only thread which will program device registers, but
2292 * still have lockdep assertions, so we are taking reg_lock.
2293 */
2294 spin_lock_irq(&il->reg_lock);
2295 /* FIXME: il_grab_nic_access if rfkill is off ? */
2296
2289 il3945_hw_txq_ctx_stop(il); 2297 il3945_hw_txq_ctx_stop(il);
2290 il3945_hw_rxq_stop(il); 2298 il3945_hw_rxq_stop(il);
2291
2292 /* Power-down device's busmaster DMA clocks */ 2299 /* Power-down device's busmaster DMA clocks */
2293 il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); 2300 _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
2294 udelay(5); 2301 udelay(5);
2295
2296 /* Stop the device, and put it in low power state */ 2302 /* Stop the device, and put it in low power state */
2297 il_apm_stop(il); 2303 _il_apm_stop(il);
2298 2304
2305 spin_unlock_irq(&il->reg_lock);
2306
2307 il3945_hw_txq_ctx_free(il);
2299exit: 2308exit:
2300 memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); 2309 memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
2301 2310
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index 95ebd43ae537..103251dba459 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -1016,18 +1016,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
1016 int txq_id; 1016 int txq_id;
1017 1017
1018 /* stop SCD */ 1018 /* stop SCD */
1019 il_wr_prph(il, ALM_SCD_MODE_REG, 0); 1019 _il_wr_prph(il, ALM_SCD_MODE_REG, 0);
1020 il_wr_prph(il, ALM_SCD_TXFACT_REG, 0); 1020 _il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
1021 1021
1022 /* reset TFD queues */ 1022 /* reset TFD queues */
1023 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { 1023 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
1024 il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0); 1024 _il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
1025 il_poll_bit(il, FH39_TSSR_TX_STATUS, 1025 _il_poll_bit(il, FH39_TSSR_TX_STATUS,
1026 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), 1026 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1027 1000); 1027 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1028 1000);
1028 } 1029 }
1029
1030 il3945_hw_txq_ctx_free(il);
1031} 1030}
1032 1031
1033/** 1032/**
@@ -2176,12 +2175,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
2176int 2175int
2177il3945_hw_rxq_stop(struct il_priv *il) 2176il3945_hw_rxq_stop(struct il_priv *il)
2178{ 2177{
2179 int rc; 2178 int ret;
2180 2179
2181 il_wr(il, FH39_RCSR_CONFIG(0), 0); 2180 _il_wr(il, FH39_RCSR_CONFIG(0), 0);
2182 rc = il_poll_bit(il, FH39_RSSR_STATUS, 2181 ret = _il_poll_bit(il, FH39_RSSR_STATUS,
2183 FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); 2182 FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
2184 if (rc < 0) 2183 FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
2184 1000);
2185 if (ret < 0)
2185 IL_ERR("Can't stop Rx DMA.\n"); 2186 IL_ERR("Can't stop Rx DMA.\n");
2186 2187
2187 return 0; 2188 return 0;
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 8930e7aa13a7..5ebf7615808d 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -441,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
441int 441int
442il4965_rxq_stop(struct il_priv *il) 442il4965_rxq_stop(struct il_priv *il)
443{ 443{
444 int ret;
444 445
445 /* stop Rx DMA */ 446 _il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
446 il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0); 447 ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
447 il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG, 448 FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
448 FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); 449 FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
450 1000);
451 if (ret < 0)
452 IL_ERR("Can't stop Rx DMA.\n");
449 453
450 return 0; 454 return 0;
451} 455}
@@ -2031,31 +2035,10 @@ il4965_txq_ctx_reset(struct il_priv *il)
2031 } 2035 }
2032} 2036}
2033 2037
2034/**
2035 * il4965_txq_ctx_stop - Stop all Tx DMA channels
2036 */
2037void 2038void
2038il4965_txq_ctx_stop(struct il_priv *il) 2039il4965_txq_ctx_unmap(struct il_priv *il)
2039{ 2040{
2040 int ch, txq_id; 2041 int txq_id;
2041 unsigned long flags;
2042
2043 /* Turn off all Tx DMA fifos */
2044 spin_lock_irqsave(&il->lock, flags);
2045
2046 il4965_txq_set_sched(il, 0);
2047
2048 /* Stop each Tx DMA channel, and wait for it to be idle */
2049 for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
2050 il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
2051 if (il_poll_bit
2052 (il, FH49_TSSR_TX_STATUS_REG,
2053 FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000))
2054 IL_ERR("Failing on timeout while stopping"
2055 " DMA channel %d [0x%08x]", ch,
2056 il_rd(il, FH49_TSSR_TX_STATUS_REG));
2057 }
2058 spin_unlock_irqrestore(&il->lock, flags);
2059 2042
2060 if (!il->txq) 2043 if (!il->txq)
2061 return; 2044 return;
@@ -2068,6 +2051,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
2068 il_tx_queue_unmap(il, txq_id); 2051 il_tx_queue_unmap(il, txq_id);
2069} 2052}
2070 2053
2054/**
2055 * il4965_txq_ctx_stop - Stop all Tx DMA channels
2056 */
2057void
2058il4965_txq_ctx_stop(struct il_priv *il)
2059{
2060 int ch, ret;
2061
2062 _il_wr_prph(il, IL49_SCD_TXFACT, 0);
2063
2064 /* Stop each Tx DMA channel, and wait for it to be idle */
2065 for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
2066 _il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
2067 ret =
2068 _il_poll_bit(il, FH49_TSSR_TX_STATUS_REG,
2069 FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
2070 FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
2071 1000);
2072 if (ret < 0)
2073 IL_ERR("Timeout stopping DMA channel %d [0x%08x]",
2074 ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG));
2075 }
2076}
2077
2071/* 2078/*
2072 * Find first available (lowest unused) Tx Queue, mark it "active". 2079 * Find first available (lowest unused) Tx Queue, mark it "active".
2073 * Called only when finding queue for aggregation. 2080 * Called only when finding queue for aggregation.
@@ -5398,19 +5405,27 @@ __il4965_down(struct il_priv *il)
5398 test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR | 5405 test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
5399 test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; 5406 test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
5400 5407
5408 /*
5409 * We disabled and synchronized interrupt, and priv->mutex is taken, so
5410 * here is the only thread which will program device registers, but
5411 * still have lockdep assertions, so we are taking reg_lock.
5412 */
5413 spin_lock_irq(&il->reg_lock);
5414 /* FIXME: il_grab_nic_access if rfkill is off ? */
5415
5401 il4965_txq_ctx_stop(il); 5416 il4965_txq_ctx_stop(il);
5402 il4965_rxq_stop(il); 5417 il4965_rxq_stop(il);
5403
5404 /* Power-down device's busmaster DMA clocks */ 5418 /* Power-down device's busmaster DMA clocks */
5405 il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); 5419 _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
5406 udelay(5); 5420 udelay(5);
5407
5408 /* Make sure (redundant) we've released our request to stay awake */ 5421 /* Make sure (redundant) we've released our request to stay awake */
5409 il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 5422 _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
5410
5411 /* Stop the device, and put it in low power state */ 5423 /* Stop the device, and put it in low power state */
5412 il_apm_stop(il); 5424 _il_apm_stop(il);
5425
5426 spin_unlock_irq(&il->reg_lock);
5413 5427
5428 il4965_txq_ctx_unmap(il);
5414exit: 5429exit:
5415 memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); 5430 memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
5416 5431
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 0d1a643d8b91..f343f27e50af 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4126,12 +4126,12 @@ il_irq_handle_error(struct il_priv *il)
4126EXPORT_SYMBOL(il_irq_handle_error); 4126EXPORT_SYMBOL(il_irq_handle_error);
4127 4127
4128static int 4128static int
4129il_apm_stop_master(struct il_priv *il) 4129_il_apm_stop_master(struct il_priv *il)
4130{ 4130{
4131 int ret = 0; 4131 int ret = 0;
4132 4132
4133 /* stop device's busmaster DMA activity */ 4133 /* stop device's busmaster DMA activity */
4134 il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); 4134 _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
4135 4135
4136 ret = 4136 ret =
4137 _il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, 4137 _il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
@@ -4145,15 +4145,17 @@ il_apm_stop_master(struct il_priv *il)
4145} 4145}
4146 4146
4147void 4147void
4148il_apm_stop(struct il_priv *il) 4148_il_apm_stop(struct il_priv *il)
4149{ 4149{
4150 lockdep_assert_held(&il->reg_lock);
4151
4150 D_INFO("Stop card, put in low power state\n"); 4152 D_INFO("Stop card, put in low power state\n");
4151 4153
4152 /* Stop device's DMA activity */ 4154 /* Stop device's DMA activity */
4153 il_apm_stop_master(il); 4155 _il_apm_stop_master(il);
4154 4156
4155 /* Reset the entire device */ 4157 /* Reset the entire device */
4156 il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 4158 _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
4157 4159
4158 udelay(10); 4160 udelay(10);
4159 4161
@@ -4161,7 +4163,18 @@ il_apm_stop(struct il_priv *il)
4161 * Clear "initialization complete" bit to move adapter from 4163 * Clear "initialization complete" bit to move adapter from
4162 * D0A* (powered-up Active) --> D0U* (Uninitialized) state. 4164 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
4163 */ 4165 */
4164 il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 4166 _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
4167}
4168EXPORT_SYMBOL(_il_apm_stop);
4169
4170void
4171il_apm_stop(struct il_priv *il)
4172{
4173 unsigned long flags;
4174
4175 spin_lock_irqsave(&il->reg_lock, flags);
4176 _il_apm_stop(il);
4177 spin_unlock_irqrestore(&il->reg_lock, flags);
4165} 4178}
4166EXPORT_SYMBOL(il_apm_stop); 4179EXPORT_SYMBOL(il_apm_stop);
4167 4180
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index a7794459d747..13bfd4394f91 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1976,7 +1976,9 @@ il_is_ready_rf(struct il_priv *il)
1976 1976
1977extern void il_send_bt_config(struct il_priv *il); 1977extern void il_send_bt_config(struct il_priv *il);
1978extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); 1978extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear);
1979void il_apm_stop(struct il_priv *il); 1979extern void il_apm_stop(struct il_priv *il);
1980extern void _il_apm_stop(struct il_priv *il);
1981
1980int il_apm_init(struct il_priv *il); 1982int il_apm_init(struct il_priv *il);
1981 1983
1982int il_send_rxon_timing(struct il_priv *il); 1984int il_send_rxon_timing(struct il_priv *il);