diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-02-13 05:23:24 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-22 14:51:16 -0500 |
commit | 775ed8abde9420afc955ca7540aacdce721be6c1 (patch) | |
tree | 7ff55b22f75b9d694382514f6d59c490f5d1df1c /drivers/net/wireless | |
parent | c37281a076604937ec2403f3cfec71362f93c7d8 (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.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-mac.c | 81 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.h | 4 |
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); | ||
2299 | exit: | 2308 | exit: |
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) | |||
2176 | int | 2175 | int |
2177 | il3945_hw_rxq_stop(struct il_priv *il) | 2176 | il3945_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) | |||
441 | int | 441 | int |
442 | il4965_rxq_stop(struct il_priv *il) | 442 | il4965_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 | */ | ||
2037 | void | 2038 | void |
2038 | il4965_txq_ctx_stop(struct il_priv *il) | 2039 | il4965_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 | */ | ||
2057 | void | ||
2058 | il4965_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); | ||
5414 | exit: | 5429 | exit: |
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) | |||
4126 | EXPORT_SYMBOL(il_irq_handle_error); | 4126 | EXPORT_SYMBOL(il_irq_handle_error); |
4127 | 4127 | ||
4128 | static int | 4128 | static int |
4129 | il_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 | ||
4147 | void | 4147 | void |
4148 | il_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 | } | ||
4168 | EXPORT_SYMBOL(_il_apm_stop); | ||
4169 | |||
4170 | void | ||
4171 | il_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 | } |
4166 | EXPORT_SYMBOL(il_apm_stop); | 4179 | EXPORT_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 | ||
1977 | extern void il_send_bt_config(struct il_priv *il); | 1977 | extern void il_send_bt_config(struct il_priv *il); |
1978 | extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); | 1978 | extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); |
1979 | void il_apm_stop(struct il_priv *il); | 1979 | extern void il_apm_stop(struct il_priv *il); |
1980 | extern void _il_apm_stop(struct il_priv *il); | ||
1981 | |||
1980 | int il_apm_init(struct il_priv *il); | 1982 | int il_apm_init(struct il_priv *il); |
1981 | 1983 | ||
1982 | int il_send_rxon_timing(struct il_priv *il); | 1984 | int il_send_rxon_timing(struct il_priv *il); |