X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fiwlwifi%2Fiwl4965-base.c;h=ba0f28945eb1f37c11241867545030a16dd676fb;hb=25b3f57c1f4572d9b2d5671d60e99f26d2a7a26b;hp=a87e870f96d0614408c6556cb9d8468f5e356af8;hpb=653fa4a07525e4cd9e7b90e6fc1f792119910636;p=linux-2.6 diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index a87e870f96..ba0f28945e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -344,16 +344,19 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) /* If we have set the ASSOC_MSK and we are in BSS mode then * add the IWL_AP_ID to the station rate table */ - if (new_assoc && (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { - if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) - == IWL_INVALID_STATION) { - IWL_ERROR("Error adding AP address for transmit.\n"); - return -EIO; + if (new_assoc) { + if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { + ret = iwl_rxon_add_station(priv, + priv->active_rxon.bssid_addr, 1); + if (ret == IWL_INVALID_STATION) { + IWL_ERROR("Error adding AP address for TX.\n"); + return -EIO; + } + priv->assoc_station_added = 1; + if (priv->default_wep_key && + iwl_send_static_wepkey_cmd(priv, 0)) + IWL_ERROR("Could not send WEP static key.\n"); } - priv->assoc_station_added = 1; - if (priv->default_wep_key && - iwl_send_static_wepkey_cmd(priv, 0)) - IWL_ERROR("Could not send WEP static key.\n"); /* Apply the new configuration * RXON assoc doesn't clear the station table in uCode, @@ -755,7 +758,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) #endif ch_info = iwl_get_channel_info(priv, priv->band, - le16_to_cpu(priv->staging_rxon.channel)); + le16_to_cpu(priv->active_rxon.channel)); if (!ch_info) ch_info = &priv->channel_info[0]; @@ -791,9 +794,6 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode) { priv->iw_mode = mode; - /* init channel/phymode to values given at driver init */ - iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); - iwl4965_connection_init_rx_config(priv); memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); @@ -1603,14 +1603,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", hw_rf_kill ? "disable radio":"enable radio"); - /* Queue restart only if RF_KILL switch was set to "kill" - * when we loaded driver, and is now set to "enable". - * After we're Alive, RF_KILL gets handled by - * iwl4965_rx_card_state_notif() */ - if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { + /* driver only loads ucode once setting the interface up. + * the driver as well won't allow loading if RFKILL is set + * therefore no need to restart the driver from this handler + */ + if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) clear_bit(STATUS_RF_KILL_HW, &priv->status); - queue_work(priv->workqueue, &priv->restart); - } handled |= CSR_INT_BIT_RF_KILL; } @@ -2100,7 +2098,9 @@ static void __iwl4965_down(struct iwl_priv *priv) test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << - STATUS_IN_SUSPEND; + STATUS_IN_SUSPEND | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; goto exit; } @@ -2115,7 +2115,9 @@ static void __iwl4965_down(struct iwl_priv *priv) test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << - STATUS_FW_ERROR; + STATUS_FW_ERROR | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; spin_lock_irqsave(&priv->lock, flags); iwl_clear_bit(priv, CSR_GP_CNTRL, @@ -2180,13 +2182,15 @@ static int __iwl4965_up(struct iwl_priv *priv) if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->status); - else { + else set_bit(STATUS_RF_KILL_HW, &priv->status); - if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { - iwl_rfkill_set_hw_state(priv); - IWL_WARNING("Radio disabled by HW RF Kill switch\n"); - return -ENODEV; - } + + if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && + iwl_is_rfkill(priv)) { + iwl_rfkill_set_hw_state(priv); + IWL_WARNING("Radio disabled by %s RF Kill switch\n", + test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); + return -ENODEV; } iwl_rfkill_set_hw_state(priv); @@ -2483,7 +2487,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) switch (priv->iw_mode) { case IEEE80211_IF_TYPE_STA: - iwl4965_rate_scale_init(priv->hw, IWL_AP_ID); break; case IEEE80211_IF_TYPE_IBSS: @@ -2492,7 +2495,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) priv->assoc_id = 1; iwl_rxon_add_station(priv, priv->bssid, 0); - iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); iwl4965_send_beacon_cmd(priv); break; @@ -2559,7 +2561,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) * *****************************************************************************/ -#define UCODE_READY_TIMEOUT (2 * HZ) +#define UCODE_READY_TIMEOUT (4 * HZ) static int iwl4965_mac_start(struct ieee80211_hw *hw) { @@ -2612,21 +2614,19 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from * mac80211 will not be run successfully. */ - if (priv->ucode_type == UCODE_RT) { - ret = wait_event_interruptible_timeout(priv->wait_command_queue, - test_bit(STATUS_READY, &priv->status), - UCODE_READY_TIMEOUT); - if (!ret) { - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_ERROR("START_ALIVE timeout after %dms.\n", - jiffies_to_msecs(UCODE_READY_TIMEOUT)); - ret = -ETIMEDOUT; - goto out_release_irq; - } + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + test_bit(STATUS_READY, &priv->status), + UCODE_READY_TIMEOUT); + if (!ret) { + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_ERROR("START_ALIVE timeout after %dms.\n", + jiffies_to_msecs(UCODE_READY_TIMEOUT)); + ret = -ETIMEDOUT; + goto out_release_irq; } - - priv->is_open = 1; } + + priv->is_open = 1; IWL_DEBUG_MAC80211("leave\n"); return 0; @@ -3022,26 +3022,18 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, int mc_count, struct dev_addr_list *mc_list) { - /* - * XXX: dummy - * see also iwl4965_connection_init_rx_config - */ struct iwl_priv *priv = hw->priv; - int new_flags = 0; - if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { - if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { - IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", - IEEE80211_IF_TYPE_MNTR, - changed_flags, *total_flags); - /* queue work 'cuz mac80211 is holding a lock which - * prevents us from issuing (synchronous) f/w cmds */ - queue_work(priv->workqueue, &priv->set_monitor); - new_flags &= FIF_PROMISC_IN_BSS | - FIF_OTHER_BSS | - FIF_ALLMULTI; - } + + if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { + IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", + IEEE80211_IF_TYPE_MNTR, + changed_flags, *total_flags); + /* queue work 'cuz mac80211 is holding a lock which + * prevents us from issuing (synchronous) f/w cmds */ + queue_work(priv->workqueue, &priv->set_monitor); } - *total_flags = new_flags; + *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | + FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, @@ -3406,17 +3398,6 @@ static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, return 0; } -static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv; - - priv = hw->priv; - IWL_DEBUG_MAC80211("enter\n"); - IWL_DEBUG_MAC80211("leave\n"); - - return 0; -} - static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -3425,7 +3406,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); - priv->lq_mngr.lq_ready = 0; spin_lock_irqsave(&priv->lock, flags); memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); spin_unlock_irqrestore(&priv->lock, flags); @@ -3488,6 +3468,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk { struct iwl_priv *priv = hw->priv; unsigned long flags; + __le64 timestamp; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); @@ -3512,6 +3493,8 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk priv->ibss_beacon = skb; priv->assoc_id = 0; + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); IWL_DEBUG_MAC80211("leave\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -4105,7 +4088,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { .get_stats = iwl4965_mac_get_stats, .get_tx_stats = iwl4965_mac_get_tx_stats, .conf_tx = iwl4965_mac_conf_tx, - .get_tsf = iwl4965_mac_get_tsf, .reset_tsf = iwl4965_mac_reset_tsf, .beacon_update = iwl4965_mac_beacon_update, .bss_info_changed = iwl4965_bss_info_changed, @@ -4234,8 +4216,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e /************************ * 5. Setup HW constants ************************/ - /* Device-specific setup */ - if (priv->cfg->ops->lib->set_hw_params(priv)) { + if (iwl_set_hw_params(priv)) { IWL_ERROR("failed to set hw parameters\n"); goto out_free_eeprom; }