diff options
Diffstat (limited to 'drivers/net/wireless/iwlegacy')
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-core.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-dev.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-hcmd.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-helpers.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-tx.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl3945-base.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl4965-base.c | 45 |
9 files changed, 82 insertions, 75 deletions
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index 5a8a3cce27bc..7e5e85a017b5 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c | |||
@@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
955 | if (priv->cfg->scan_rx_antennas[band]) | 955 | if (priv->cfg->scan_rx_antennas[band]) |
956 | rx_ant = priv->cfg->scan_rx_antennas[band]; | 956 | rx_ant = priv->cfg->scan_rx_antennas[band]; |
957 | 957 | ||
958 | if (priv->cfg->scan_tx_antennas[band]) | ||
959 | scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; | ||
960 | |||
961 | priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, | 958 | priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, |
962 | priv->scan_tx_ant[band], | 959 | priv->scan_tx_ant[band], |
963 | scan_tx_antennas); | 960 | scan_tx_antennas); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index c1511b14b239..d743373a9424 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c | |||
@@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) | |||
211 | if (!iwl_legacy_is_channel_valid(ch)) | 211 | if (!iwl_legacy_is_channel_valid(ch)) |
212 | continue; | 212 | continue; |
213 | 213 | ||
214 | if (iwl_legacy_is_channel_a_band(ch)) | 214 | sband = &priv->bands[ch->band]; |
215 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
216 | else | ||
217 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
218 | 215 | ||
219 | geo_ch = &sband->channels[sband->n_channels++]; | 216 | geo_ch = &sband->channels[sband->n_channels++]; |
220 | 217 | ||
@@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2117 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | 2114 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", |
2118 | channel->hw_value, changed); | 2115 | channel->hw_value, changed); |
2119 | 2116 | ||
2120 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | 2117 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { |
2121 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
2122 | scan_active = 1; | 2118 | scan_active = 1; |
2123 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 2119 | IWL_DEBUG_MAC80211(priv, "scan active\n"); |
2124 | } | 2120 | } |
2125 | 2121 | ||
2126 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | | 2122 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | |
@@ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
2433 | 2429 | ||
2434 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | 2430 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); |
2435 | 2431 | ||
2436 | if (!iwl_legacy_is_alive(priv)) | ||
2437 | return; | ||
2438 | |||
2439 | mutex_lock(&priv->mutex); | 2432 | mutex_lock(&priv->mutex); |
2440 | 2433 | ||
2434 | if (!iwl_legacy_is_alive(priv)) { | ||
2435 | mutex_unlock(&priv->mutex); | ||
2436 | return; | ||
2437 | } | ||
2438 | |||
2441 | if (changes & BSS_CHANGED_QOS) { | 2439 | if (changes & BSS_CHANGED_QOS) { |
2442 | unsigned long flags; | 2440 | unsigned long flags; |
2443 | 2441 | ||
@@ -2646,7 +2644,7 @@ unplugged: | |||
2646 | 2644 | ||
2647 | none: | 2645 | none: |
2648 | /* re-enable interrupts here since we don't have anything to service. */ | 2646 | /* re-enable interrupts here since we don't have anything to service. */ |
2649 | /* only Re-enable if diabled by irq */ | 2647 | /* only Re-enable if disabled by irq */ |
2650 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 2648 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
2651 | iwl_legacy_enable_interrupts(priv); | 2649 | iwl_legacy_enable_interrupts(priv); |
2652 | spin_unlock_irqrestore(&priv->lock, flags); | 2650 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index f03b463e4378..bc66c604106c 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h | |||
@@ -287,7 +287,6 @@ struct iwl_cfg { | |||
287 | struct iwl_base_params *base_params; | 287 | struct iwl_base_params *base_params; |
288 | /* params likely to change within a device family */ | 288 | /* params likely to change within a device family */ |
289 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 289 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
290 | u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; | ||
291 | enum iwl_led_mode led_mode; | 290 | enum iwl_led_mode led_mode; |
292 | }; | 291 | }; |
293 | 292 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index 9ee849d669f3..2d87dba2cfa3 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h | |||
@@ -134,7 +134,7 @@ struct iwl_queue { | |||
134 | * space more than this */ | 134 | * space more than this */ |
135 | int high_mark; /* high watermark, stop queue if free | 135 | int high_mark; /* high watermark, stop queue if free |
136 | * space less than this */ | 136 | * space less than this */ |
137 | } __packed; | 137 | }; |
138 | 138 | ||
139 | /* One for each TFD */ | 139 | /* One for each TFD */ |
140 | struct iwl_tx_info { | 140 | struct iwl_tx_info { |
@@ -290,6 +290,7 @@ enum { | |||
290 | CMD_SIZE_HUGE = (1 << 0), | 290 | CMD_SIZE_HUGE = (1 << 0), |
291 | CMD_ASYNC = (1 << 1), | 291 | CMD_ASYNC = (1 << 1), |
292 | CMD_WANT_SKB = (1 << 2), | 292 | CMD_WANT_SKB = (1 << 2), |
293 | CMD_MAPPED = (1 << 3), | ||
293 | }; | 294 | }; |
294 | 295 | ||
295 | #define DEF_CMD_PAYLOAD_SIZE 320 | 296 | #define DEF_CMD_PAYLOAD_SIZE 320 |
@@ -1076,7 +1077,6 @@ struct iwl_priv { | |||
1076 | spinlock_t hcmd_lock; /* protect hcmd */ | 1077 | spinlock_t hcmd_lock; /* protect hcmd */ |
1077 | spinlock_t reg_lock; /* protect hw register access */ | 1078 | spinlock_t reg_lock; /* protect hw register access */ |
1078 | struct mutex mutex; | 1079 | struct mutex mutex; |
1079 | struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ | ||
1080 | 1080 | ||
1081 | /* basic pci-network driver stuff */ | 1081 | /* basic pci-network driver stuff */ |
1082 | struct pci_dev *pci_dev; | 1082 | struct pci_dev *pci_dev; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/drivers/net/wireless/iwlegacy/iwl-hcmd.c index 9d721cbda5bb..62b4b09122cb 100644 --- a/drivers/net/wireless/iwlegacy/iwl-hcmd.c +++ b/drivers/net/wireless/iwlegacy/iwl-hcmd.c | |||
@@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
145 | int cmd_idx; | 145 | int cmd_idx; |
146 | int ret; | 146 | int ret; |
147 | 147 | ||
148 | lockdep_assert_held(&priv->mutex); | ||
149 | |||
148 | BUG_ON(cmd->flags & CMD_ASYNC); | 150 | BUG_ON(cmd->flags & CMD_ASYNC); |
149 | 151 | ||
150 | /* A synchronous command can not have a callback set. */ | 152 | /* A synchronous command can not have a callback set. */ |
@@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
152 | 154 | ||
153 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | 155 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
154 | iwl_legacy_get_cmd_string(cmd->id)); | 156 | iwl_legacy_get_cmd_string(cmd->id)); |
155 | mutex_lock(&priv->sync_cmd_mutex); | ||
156 | 157 | ||
157 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 158 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
158 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", | 159 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", |
@@ -224,7 +225,6 @@ fail: | |||
224 | cmd->reply_page = 0; | 225 | cmd->reply_page = 0; |
225 | } | 226 | } |
226 | out: | 227 | out: |
227 | mutex_unlock(&priv->sync_cmd_mutex); | ||
228 | return ret; | 228 | return ret; |
229 | } | 229 | } |
230 | EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); | 230 | EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h index 02132e755831..a6effdae63f9 100644 --- a/drivers/net/wireless/iwlegacy/iwl-helpers.h +++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h | |||
@@ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) | |||
149 | IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); | 149 | IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv) | ||
153 | { | ||
154 | IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); | ||
155 | iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
156 | } | ||
157 | |||
152 | static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) | 158 | static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) |
153 | { | 159 | { |
154 | IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); | 160 | IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c index a227773cb384..4fff995c6f3e 100644 --- a/drivers/net/wireless/iwlegacy/iwl-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-tx.c | |||
@@ -146,33 +146,32 @@ void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv) | |||
146 | { | 146 | { |
147 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 147 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
148 | struct iwl_queue *q = &txq->q; | 148 | struct iwl_queue *q = &txq->q; |
149 | bool huge = false; | ||
150 | int i; | 149 | int i; |
151 | 150 | ||
152 | if (q->n_bd == 0) | 151 | if (q->n_bd == 0) |
153 | return; | 152 | return; |
154 | 153 | ||
155 | while (q->read_ptr != q->write_ptr) { | 154 | while (q->read_ptr != q->write_ptr) { |
156 | /* we have no way to tell if it is a huge cmd ATM */ | ||
157 | i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); | 155 | i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); |
158 | 156 | ||
159 | if (txq->meta[i].flags & CMD_SIZE_HUGE) | 157 | if (txq->meta[i].flags & CMD_MAPPED) { |
160 | huge = true; | ||
161 | else | ||
162 | pci_unmap_single(priv->pci_dev, | 158 | pci_unmap_single(priv->pci_dev, |
163 | dma_unmap_addr(&txq->meta[i], mapping), | 159 | dma_unmap_addr(&txq->meta[i], mapping), |
164 | dma_unmap_len(&txq->meta[i], len), | 160 | dma_unmap_len(&txq->meta[i], len), |
165 | PCI_DMA_BIDIRECTIONAL); | 161 | PCI_DMA_BIDIRECTIONAL); |
162 | txq->meta[i].flags = 0; | ||
163 | } | ||
166 | 164 | ||
167 | q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); | 165 | q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); |
168 | } | 166 | } |
169 | 167 | ||
170 | if (huge) { | 168 | i = q->n_window; |
171 | i = q->n_window; | 169 | if (txq->meta[i].flags & CMD_MAPPED) { |
172 | pci_unmap_single(priv->pci_dev, | 170 | pci_unmap_single(priv->pci_dev, |
173 | dma_unmap_addr(&txq->meta[i], mapping), | 171 | dma_unmap_addr(&txq->meta[i], mapping), |
174 | dma_unmap_len(&txq->meta[i], len), | 172 | dma_unmap_len(&txq->meta[i], len), |
175 | PCI_DMA_BIDIRECTIONAL); | 173 | PCI_DMA_BIDIRECTIONAL); |
174 | txq->meta[i].flags = 0; | ||
176 | } | 175 | } |
177 | } | 176 | } |
178 | EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); | 177 | EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); |
@@ -467,29 +466,27 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
467 | return -EIO; | 466 | return -EIO; |
468 | } | 467 | } |
469 | 468 | ||
469 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
470 | |||
470 | if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 471 | if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
471 | IWL_ERR(priv, "No space in command queue\n"); | 472 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
472 | IWL_ERR(priv, "Restarting adapter due to queue full\n"); | 473 | |
474 | IWL_ERR(priv, "Restarting adapter due to command queue full\n"); | ||
473 | queue_work(priv->workqueue, &priv->restart); | 475 | queue_work(priv->workqueue, &priv->restart); |
474 | return -ENOSPC; | 476 | return -ENOSPC; |
475 | } | 477 | } |
476 | 478 | ||
477 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
478 | |||
479 | /* If this is a huge cmd, mark the huge flag also on the meta.flags | ||
480 | * of the _original_ cmd. This is used for DMA mapping clean up. | ||
481 | */ | ||
482 | if (cmd->flags & CMD_SIZE_HUGE) { | ||
483 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0); | ||
484 | txq->meta[idx].flags = CMD_SIZE_HUGE; | ||
485 | } | ||
486 | |||
487 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); | 479 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); |
488 | out_cmd = txq->cmd[idx]; | 480 | out_cmd = txq->cmd[idx]; |
489 | out_meta = &txq->meta[idx]; | 481 | out_meta = &txq->meta[idx]; |
490 | 482 | ||
483 | if (WARN_ON(out_meta->flags & CMD_MAPPED)) { | ||
484 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
485 | return -ENOSPC; | ||
486 | } | ||
487 | |||
491 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ | 488 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ |
492 | out_meta->flags = cmd->flags; | 489 | out_meta->flags = cmd->flags | CMD_MAPPED; |
493 | if (cmd->flags & CMD_WANT_SKB) | 490 | if (cmd->flags & CMD_WANT_SKB) |
494 | out_meta->source = cmd; | 491 | out_meta->source = cmd; |
495 | if (cmd->flags & CMD_ASYNC) | 492 | if (cmd->flags & CMD_ASYNC) |
@@ -610,6 +607,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
610 | struct iwl_device_cmd *cmd; | 607 | struct iwl_device_cmd *cmd; |
611 | struct iwl_cmd_meta *meta; | 608 | struct iwl_cmd_meta *meta; |
612 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 609 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
610 | unsigned long flags; | ||
613 | 611 | ||
614 | /* If a Tx command is being handled and it isn't in the actual | 612 | /* If a Tx command is being handled and it isn't in the actual |
615 | * command queue then there a command routing bug has been introduced | 613 | * command queue then there a command routing bug has been introduced |
@@ -623,14 +621,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
623 | return; | 621 | return; |
624 | } | 622 | } |
625 | 623 | ||
626 | /* If this is a huge cmd, clear the huge flag on the meta.flags | ||
627 | * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap | ||
628 | * the DMA buffer for the scan (huge) command. | ||
629 | */ | ||
630 | if (huge) { | ||
631 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0); | ||
632 | txq->meta[cmd_index].flags = 0; | ||
633 | } | ||
634 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); | 624 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); |
635 | cmd = txq->cmd[cmd_index]; | 625 | cmd = txq->cmd[cmd_index]; |
636 | meta = &txq->meta[cmd_index]; | 626 | meta = &txq->meta[cmd_index]; |
@@ -647,6 +637,8 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
647 | } else if (meta->callback) | 637 | } else if (meta->callback) |
648 | meta->callback(priv, cmd, pkt); | 638 | meta->callback(priv, cmd, pkt); |
649 | 639 | ||
640 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
641 | |||
650 | iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 642 | iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); |
651 | 643 | ||
652 | if (!(meta->flags & CMD_ASYNC)) { | 644 | if (!(meta->flags & CMD_ASYNC)) { |
@@ -655,6 +647,10 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
655 | iwl_legacy_get_cmd_string(cmd->hdr.cmd)); | 647 | iwl_legacy_get_cmd_string(cmd->hdr.cmd)); |
656 | wake_up_interruptible(&priv->wait_command_queue); | 648 | wake_up_interruptible(&priv->wait_command_queue); |
657 | } | 649 | } |
650 | |||
651 | /* Mark as unmapped */ | ||
658 | meta->flags = 0; | 652 | meta->flags = 0; |
653 | |||
654 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
659 | } | 655 | } |
660 | EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); | 656 | EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); |
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index cc7ebcee60e5..0ee6be6a9c5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c | |||
@@ -2748,11 +2748,12 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data) | |||
2748 | struct iwl_priv *priv = | 2748 | struct iwl_priv *priv = |
2749 | container_of(data, struct iwl_priv, init_alive_start.work); | 2749 | container_of(data, struct iwl_priv, init_alive_start.work); |
2750 | 2750 | ||
2751 | mutex_lock(&priv->mutex); | ||
2751 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2752 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2752 | return; | 2753 | goto out; |
2753 | 2754 | ||
2754 | mutex_lock(&priv->mutex); | ||
2755 | iwl3945_init_alive_start(priv); | 2755 | iwl3945_init_alive_start(priv); |
2756 | out: | ||
2756 | mutex_unlock(&priv->mutex); | 2757 | mutex_unlock(&priv->mutex); |
2757 | } | 2758 | } |
2758 | 2759 | ||
@@ -2761,11 +2762,12 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
2761 | struct iwl_priv *priv = | 2762 | struct iwl_priv *priv = |
2762 | container_of(data, struct iwl_priv, alive_start.work); | 2763 | container_of(data, struct iwl_priv, alive_start.work); |
2763 | 2764 | ||
2765 | mutex_lock(&priv->mutex); | ||
2764 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2766 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2765 | return; | 2767 | goto out; |
2766 | 2768 | ||
2767 | mutex_lock(&priv->mutex); | ||
2768 | iwl3945_alive_start(priv); | 2769 | iwl3945_alive_start(priv); |
2770 | out: | ||
2769 | mutex_unlock(&priv->mutex); | 2771 | mutex_unlock(&priv->mutex); |
2770 | } | 2772 | } |
2771 | 2773 | ||
@@ -2995,10 +2997,12 @@ static void iwl3945_bg_restart(struct work_struct *data) | |||
2995 | } else { | 2997 | } else { |
2996 | iwl3945_down(priv); | 2998 | iwl3945_down(priv); |
2997 | 2999 | ||
2998 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3000 | mutex_lock(&priv->mutex); |
3001 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
3002 | mutex_unlock(&priv->mutex); | ||
2999 | return; | 3003 | return; |
3004 | } | ||
3000 | 3005 | ||
3001 | mutex_lock(&priv->mutex); | ||
3002 | __iwl3945_up(priv); | 3006 | __iwl3945_up(priv); |
3003 | mutex_unlock(&priv->mutex); | 3007 | mutex_unlock(&priv->mutex); |
3004 | } | 3008 | } |
@@ -3009,11 +3013,12 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
3009 | struct iwl_priv *priv = | 3013 | struct iwl_priv *priv = |
3010 | container_of(data, struct iwl_priv, rx_replenish); | 3014 | container_of(data, struct iwl_priv, rx_replenish); |
3011 | 3015 | ||
3016 | mutex_lock(&priv->mutex); | ||
3012 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3017 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3013 | return; | 3018 | goto out; |
3014 | 3019 | ||
3015 | mutex_lock(&priv->mutex); | ||
3016 | iwl3945_rx_replenish(priv); | 3020 | iwl3945_rx_replenish(priv); |
3021 | out: | ||
3017 | mutex_unlock(&priv->mutex); | 3022 | mutex_unlock(&priv->mutex); |
3018 | } | 3023 | } |
3019 | 3024 | ||
@@ -3810,7 +3815,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3810 | INIT_LIST_HEAD(&priv->free_frames); | 3815 | INIT_LIST_HEAD(&priv->free_frames); |
3811 | 3816 | ||
3812 | mutex_init(&priv->mutex); | 3817 | mutex_init(&priv->mutex); |
3813 | mutex_init(&priv->sync_cmd_mutex); | ||
3814 | 3818 | ||
3815 | priv->ieee_channels = NULL; | 3819 | priv->ieee_channels = NULL; |
3816 | priv->ieee_rates = NULL; | 3820 | priv->ieee_rates = NULL; |
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index f8870543d68f..f781b7e225b4 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c | |||
@@ -1069,9 +1069,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | /* Re-enable all interrupts */ | 1071 | /* Re-enable all interrupts */ |
1072 | /* only Re-enable if diabled by irq */ | 1072 | /* only Re-enable if disabled by irq */ |
1073 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1073 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1074 | iwl_legacy_enable_interrupts(priv); | 1074 | iwl_legacy_enable_interrupts(priv); |
1075 | /* Re-enable RF_KILL if it occurred */ | ||
1076 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
1077 | iwl_legacy_enable_rfkill_int(priv); | ||
1075 | 1078 | ||
1076 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | 1079 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG |
1077 | if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { | 1080 | if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { |
@@ -2139,7 +2142,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); | |||
2139 | static void __iwl4965_down(struct iwl_priv *priv) | 2142 | static void __iwl4965_down(struct iwl_priv *priv) |
2140 | { | 2143 | { |
2141 | unsigned long flags; | 2144 | unsigned long flags; |
2142 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); | 2145 | int exit_pending; |
2143 | 2146 | ||
2144 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | 2147 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); |
2145 | 2148 | ||
@@ -2401,11 +2404,12 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) | |||
2401 | struct iwl_priv *priv = | 2404 | struct iwl_priv *priv = |
2402 | container_of(data, struct iwl_priv, init_alive_start.work); | 2405 | container_of(data, struct iwl_priv, init_alive_start.work); |
2403 | 2406 | ||
2407 | mutex_lock(&priv->mutex); | ||
2404 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2408 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2405 | return; | 2409 | goto out; |
2406 | 2410 | ||
2407 | mutex_lock(&priv->mutex); | ||
2408 | priv->cfg->ops->lib->init_alive_start(priv); | 2411 | priv->cfg->ops->lib->init_alive_start(priv); |
2412 | out: | ||
2409 | mutex_unlock(&priv->mutex); | 2413 | mutex_unlock(&priv->mutex); |
2410 | } | 2414 | } |
2411 | 2415 | ||
@@ -2414,11 +2418,12 @@ static void iwl4965_bg_alive_start(struct work_struct *data) | |||
2414 | struct iwl_priv *priv = | 2418 | struct iwl_priv *priv = |
2415 | container_of(data, struct iwl_priv, alive_start.work); | 2419 | container_of(data, struct iwl_priv, alive_start.work); |
2416 | 2420 | ||
2421 | mutex_lock(&priv->mutex); | ||
2417 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2422 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2418 | return; | 2423 | goto out; |
2419 | 2424 | ||
2420 | mutex_lock(&priv->mutex); | ||
2421 | iwl4965_alive_start(priv); | 2425 | iwl4965_alive_start(priv); |
2426 | out: | ||
2422 | mutex_unlock(&priv->mutex); | 2427 | mutex_unlock(&priv->mutex); |
2423 | } | 2428 | } |
2424 | 2429 | ||
@@ -2468,10 +2473,12 @@ static void iwl4965_bg_restart(struct work_struct *data) | |||
2468 | } else { | 2473 | } else { |
2469 | iwl4965_down(priv); | 2474 | iwl4965_down(priv); |
2470 | 2475 | ||
2471 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2476 | mutex_lock(&priv->mutex); |
2477 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2478 | mutex_unlock(&priv->mutex); | ||
2472 | return; | 2479 | return; |
2480 | } | ||
2473 | 2481 | ||
2474 | mutex_lock(&priv->mutex); | ||
2475 | __iwl4965_up(priv); | 2482 | __iwl4965_up(priv); |
2476 | mutex_unlock(&priv->mutex); | 2483 | mutex_unlock(&priv->mutex); |
2477 | } | 2484 | } |
@@ -2624,9 +2631,10 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
2624 | 2631 | ||
2625 | flush_workqueue(priv->workqueue); | 2632 | flush_workqueue(priv->workqueue); |
2626 | 2633 | ||
2627 | /* enable interrupts again in order to receive rfkill changes */ | 2634 | /* User space software may expect getting rfkill changes |
2635 | * even if interface is down */ | ||
2628 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 2636 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
2629 | iwl_legacy_enable_interrupts(priv); | 2637 | iwl_legacy_enable_rfkill_int(priv); |
2630 | 2638 | ||
2631 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2639 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2632 | } | 2640 | } |
@@ -2847,21 +2855,22 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2847 | 2855 | ||
2848 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2856 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2849 | 2857 | ||
2858 | mutex_lock(&priv->mutex); | ||
2859 | |||
2850 | if (iwl_legacy_is_rfkill(priv)) | 2860 | if (iwl_legacy_is_rfkill(priv)) |
2851 | goto out_exit; | 2861 | goto out; |
2852 | 2862 | ||
2853 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 2863 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
2854 | test_bit(STATUS_SCANNING, &priv->status)) | 2864 | test_bit(STATUS_SCANNING, &priv->status)) |
2855 | goto out_exit; | 2865 | goto out; |
2856 | 2866 | ||
2857 | if (!iwl_legacy_is_associated_ctx(ctx)) | 2867 | if (!iwl_legacy_is_associated_ctx(ctx)) |
2858 | goto out_exit; | 2868 | goto out; |
2859 | 2869 | ||
2860 | /* channel switch in progress */ | 2870 | /* channel switch in progress */ |
2861 | if (priv->switch_rxon.switch_in_progress == true) | 2871 | if (priv->switch_rxon.switch_in_progress == true) |
2862 | goto out_exit; | 2872 | goto out; |
2863 | 2873 | ||
2864 | mutex_lock(&priv->mutex); | ||
2865 | if (priv->cfg->ops->lib->set_channel_switch) { | 2874 | if (priv->cfg->ops->lib->set_channel_switch) { |
2866 | 2875 | ||
2867 | ch = channel->hw_value; | 2876 | ch = channel->hw_value; |
@@ -2917,7 +2926,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2917 | } | 2926 | } |
2918 | out: | 2927 | out: |
2919 | mutex_unlock(&priv->mutex); | 2928 | mutex_unlock(&priv->mutex); |
2920 | out_exit: | ||
2921 | if (!priv->switch_rxon.switch_in_progress) | 2929 | if (!priv->switch_rxon.switch_in_progress) |
2922 | ieee80211_chswitch_done(ctx->vif, false); | 2930 | ieee80211_chswitch_done(ctx->vif, false); |
2923 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2931 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -3116,7 +3124,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv) | |||
3116 | INIT_LIST_HEAD(&priv->free_frames); | 3124 | INIT_LIST_HEAD(&priv->free_frames); |
3117 | 3125 | ||
3118 | mutex_init(&priv->mutex); | 3126 | mutex_init(&priv->mutex); |
3119 | mutex_init(&priv->sync_cmd_mutex); | ||
3120 | 3127 | ||
3121 | priv->ieee_channels = NULL; | 3128 | priv->ieee_channels = NULL; |
3122 | priv->ieee_rates = NULL; | 3129 | priv->ieee_rates = NULL; |
@@ -3406,14 +3413,14 @@ iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3406 | * 8. Enable interrupts and read RFKILL state | 3413 | * 8. Enable interrupts and read RFKILL state |
3407 | *********************************************/ | 3414 | *********************************************/ |
3408 | 3415 | ||
3409 | /* enable interrupts if needed: hw bug w/a */ | 3416 | /* enable rfkill interrupt: hw bug w/a */ |
3410 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | 3417 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); |
3411 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | 3418 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { |
3412 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | 3419 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; |
3413 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | 3420 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); |
3414 | } | 3421 | } |
3415 | 3422 | ||
3416 | iwl_legacy_enable_interrupts(priv); | 3423 | iwl_legacy_enable_rfkill_int(priv); |
3417 | 3424 | ||
3418 | /* If platform's RF_KILL switch is NOT set to KILL */ | 3425 | /* If platform's RF_KILL switch is NOT set to KILL */ |
3419 | if (iwl_read32(priv, CSR_GP_CNTRL) & | 3426 | if (iwl_read32(priv, CSR_GP_CNTRL) & |