diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5cce894dc1f9..1547122e66fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -181,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /** | 183 | /** |
184 | * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed | 184 | * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed |
185 | * @priv: staging_rxon is compared to active_rxon | 185 | * @priv: staging_rxon is compared to active_rxon |
186 | * | 186 | * |
187 | * If the RXON structure is changing enough to require a new tune, | 187 | * If the RXON structure is changing enough to require a new tune, |
188 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 188 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
189 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 189 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
190 | */ | 190 | */ |
191 | static int iwl4965_full_rxon_required(struct iwl_priv *priv) | 191 | static int iwl_full_rxon_required(struct iwl_priv *priv) |
192 | { | 192 | { |
193 | 193 | ||
194 | /* These items are only settable from the full RXON command */ | 194 | /* These items are only settable from the full RXON command */ |
@@ -207,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
207 | priv->active_rxon.ofdm_ht_single_stream_basic_rates) || | 207 | priv->active_rxon.ofdm_ht_single_stream_basic_rates) || |
208 | (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != | 208 | (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != |
209 | priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || | 209 | priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || |
210 | (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) || | ||
211 | (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) | 210 | (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) |
212 | return 1; | 211 | return 1; |
213 | 212 | ||
@@ -263,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
263 | /* If we don't need to send a full RXON, we can use | 262 | /* If we don't need to send a full RXON, we can use |
264 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter | 263 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter |
265 | * and other flags for the current radio configuration. */ | 264 | * and other flags for the current radio configuration. */ |
266 | if (!iwl4965_full_rxon_required(priv)) { | 265 | if (!iwl_full_rxon_required(priv)) { |
267 | ret = iwl_send_rxon_assoc(priv); | 266 | ret = iwl_send_rxon_assoc(priv); |
268 | if (ret) { | 267 | if (ret) { |
269 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); | 268 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); |
@@ -587,8 +586,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
587 | iwl_conf->supported_chan_width = 0; | 586 | iwl_conf->supported_chan_width = 0; |
588 | } | 587 | } |
589 | 588 | ||
590 | iwl_conf->tx_mimo_ps_mode = | ||
591 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
592 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); | 589 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); |
593 | 590 | ||
594 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | 591 | iwl_conf->control_channel = ht_bss_conf->primary_channel; |
@@ -2190,7 +2187,10 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
2190 | udelay(5); | 2187 | udelay(5); |
2191 | 2188 | ||
2192 | /* FIXME: apm_ops.suspend(priv) */ | 2189 | /* FIXME: apm_ops.suspend(priv) */ |
2193 | priv->cfg->ops->lib->apm_ops.reset(priv); | 2190 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) |
2191 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
2192 | else | ||
2193 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
2194 | priv->cfg->ops->lib->free_shared_mem(priv); | 2194 | priv->cfg->ops->lib->free_shared_mem(priv); |
2195 | 2195 | ||
2196 | exit: | 2196 | exit: |
@@ -2604,6 +2604,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
2604 | { | 2604 | { |
2605 | struct iwl_priv *priv = hw->priv; | 2605 | struct iwl_priv *priv = hw->priv; |
2606 | int ret; | 2606 | int ret; |
2607 | u16 pci_cmd; | ||
2607 | 2608 | ||
2608 | IWL_DEBUG_MAC80211("enter\n"); | 2609 | IWL_DEBUG_MAC80211("enter\n"); |
2609 | 2610 | ||
@@ -2614,6 +2615,13 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
2614 | pci_restore_state(priv->pci_dev); | 2615 | pci_restore_state(priv->pci_dev); |
2615 | pci_enable_msi(priv->pci_dev); | 2616 | pci_enable_msi(priv->pci_dev); |
2616 | 2617 | ||
2618 | /* enable interrupts if needed: hw bug w/a */ | ||
2619 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||
2620 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
2621 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
2622 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||
2623 | } | ||
2624 | |||
2617 | ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, | 2625 | ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, |
2618 | DRV_NAME, priv); | 2626 | DRV_NAME, priv); |
2619 | if (ret) { | 2627 | if (ret) { |
@@ -3583,7 +3591,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
3583 | 3591 | ||
3584 | priv->assoc_id = 0; | 3592 | priv->assoc_id = 0; |
3585 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | 3593 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; |
3586 | priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); | 3594 | priv->timestamp = le64_to_cpu(timestamp); |
3587 | 3595 | ||
3588 | IWL_DEBUG_MAC80211("leave\n"); | 3596 | IWL_DEBUG_MAC80211("leave\n"); |
3589 | spin_unlock_irqrestore(&priv->lock, flags); | 3597 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -4385,15 +4393,18 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
4385 | iwl_dbgfs_unregister(priv); | 4393 | iwl_dbgfs_unregister(priv); |
4386 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 4394 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
4387 | 4395 | ||
4396 | /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to | ||
4397 | * to be called and iwl4965_down since we are removing the device | ||
4398 | * we need to set STATUS_EXIT_PENDING bit. | ||
4399 | */ | ||
4400 | set_bit(STATUS_EXIT_PENDING, &priv->status); | ||
4388 | if (priv->mac80211_registered) { | 4401 | if (priv->mac80211_registered) { |
4389 | ieee80211_unregister_hw(priv->hw); | 4402 | ieee80211_unregister_hw(priv->hw); |
4390 | priv->mac80211_registered = 0; | 4403 | priv->mac80211_registered = 0; |
4404 | } else { | ||
4405 | iwl4965_down(priv); | ||
4391 | } | 4406 | } |
4392 | 4407 | ||
4393 | set_bit(STATUS_EXIT_PENDING, &priv->status); | ||
4394 | |||
4395 | iwl4965_down(priv); | ||
4396 | |||
4397 | /* make sure we flush any pending irq or | 4408 | /* make sure we flush any pending irq or |
4398 | * tasklet for the driver | 4409 | * tasklet for the driver |
4399 | */ | 4410 | */ |