diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-helpers.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 96 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 94 |
9 files changed, 162 insertions, 93 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 6e01873..571815d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -373,7 +373,7 @@ struct iwl3945_eeprom { #define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */ #define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */ #define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ -#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */ +#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */ #define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 76c4ed1..8d4d91d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -238,9 +238,10 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b priv->last_statistics_time = jiffies; } -void iwl3945_add_radiotap(struct iwl3945_priv *priv, struct sk_buff *skb, - struct iwl3945_rx_frame_hdr *rx_hdr, - struct ieee80211_rx_status *stats) +static void iwl3945_add_radiotap(struct iwl3945_priv *priv, + struct sk_buff *skb, + struct iwl3945_rx_frame_hdr *rx_hdr, + struct ieee80211_rx_status *stats) { /* First cache any information we need before we overwrite * the information provided in the skb from the hardware */ @@ -2369,18 +2370,4 @@ struct pci_device_id iwl3945_hw_card_ids[] = { {0} }; -/* - * Clear the OWNER_MSK, to establish driver (instead of uCode running on - * embedded controller) as EEPROM reader; each read is a series of pulses - * to/from the EEPROM chip, not a single event, so even reads could conflict - * if they weren't arbitrated by some ownership mechanism. Here, the driver - * simply claims ownership, which should be safe when this function is called - * (i.e. before loading uCode!). - */ -inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) -{ - _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); - return 0; -} - MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 20b925f..1da14f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -671,7 +671,6 @@ extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel); /* * Forward declare iwl-3945.c functions for iwl-base.c */ -extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv); extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv); extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv); extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv); @@ -791,7 +790,6 @@ struct iwl3945_priv { u16 active_rate_basic; u8 call_post_assoc_from_beacon; - u8 assoc_station_added; /* Rate scaling data */ s8 data_retry_limit; u8 retry_rate; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index ff71c09..ffe1e9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -465,7 +465,7 @@ struct iwl4965_eeprom { #define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */ #define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */ #define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ -#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */ +#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */ #define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 04db34b..d727de8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -4658,17 +4658,30 @@ void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, struct ieee80211_ht_info *sta_ht_inf) { __le32 sta_flags; + u8 mimo_ps_mode; if (!sta_ht_inf || !sta_ht_inf->ht_supported) goto done; + mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2; + sta_flags = priv->stations[index].sta.station_flags; - if (((sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS >> 2)) - == IWL_MIMO_PS_DYNAMIC) + sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); + + switch (mimo_ps_mode) { + case WLAN_HT_CAP_MIMO_PS_STATIC: + sta_flags |= STA_FLG_MIMO_DIS_MSK; + break; + case WLAN_HT_CAP_MIMO_PS_DYNAMIC: sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; - else - sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK; + break; + case WLAN_HT_CAP_MIMO_PS_DISABLED: + break; + default: + IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode); + break; + } sta_flags |= cpu_to_le32( (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); @@ -4679,7 +4692,7 @@ void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) sta_flags |= STA_FLG_FAT_EN_MSK; else - sta_flags &= (~STA_FLG_FAT_EN_MSK); + sta_flags &= ~STA_FLG_FAT_EN_MSK; priv->stations[index].sta.station_flags = sta_flags; done: @@ -4961,11 +4974,4 @@ int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv) return rc; } -inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv) -{ - iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); -} - - MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 78bc148..9cb82be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -750,7 +750,6 @@ struct iwl4965_priv; * Forward declare iwl-4965.c functions for iwl-base.c */ extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv); -extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv); extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq, diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index cd2eb18..8993cca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -147,9 +147,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf( #define QOS_CONTROL_LEN 2 -#define IEEE80211_STYPE_BACK_REQ 0x0080 -#define IEEE80211_STYPE_BACK 0x0090 - static inline int ieee80211_is_management(u16 fc) { @@ -246,10 +243,10 @@ static inline int iwl_check_bits(unsigned long field, unsigned long mask) static inline unsigned long elapsed_jiffies(unsigned long start, unsigned long end) { - if (end > start) + if (end >= start) return end - start; - return end + (MAX_JIFFY_OFFSET - start); + return end + (MAX_JIFFY_OFFSET - start) + 1; } static inline u8 iwl_get_dma_hi_address(dma_addr_t addr) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 748ac12..f55c757 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1557,6 +1557,20 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac) memcpy(mac, priv->eeprom.mac_address, 6); } +/* + * Clear the OWNER_MSK, to establish driver (instead of uCode running on + * embedded controller) as EEPROM reader; each read is a series of pulses + * to/from the EEPROM chip, not a single event, so even reads could conflict + * if they weren't arbitrated by some ownership mechanism. Here, the driver + * simply claims ownership, which should be safe when this function is called + * (i.e. before loading uCode!). + */ +static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) +{ + _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); + return 0; +} + /** * iwl3945_eeprom_init - read EEPROM contents * @@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, #endif /* drop all data frame if we are not associated */ - if (!iwl3945_is_associated(priv) && !priv->assoc_id && + if ((!iwl3945_is_associated(priv) || !priv->assoc_id) && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; @@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) #ifdef CONFIG_IWL3945_DEBUG if (iwl3945_debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_MAC_CLK_ACTV) - IWL_DEBUG_ISR("Microcode started or stopped.\n"); + if (inta & CSR_INT_BIT_SCD) + IWL_DEBUG_ISR("Scheduler finished to transmit " + "the frame/frames.\n"); /* Alive notification via Rx interrupt will do the real work */ if (inta & CSR_INT_BIT_ALIVE) @@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) } #endif /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); + inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); /* HW RF KILL switch toggled (4965 only) */ if (inta & CSR_INT_BIT_RF_KILL) { @@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data) IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); + inta &= ~CSR_INT_BIT_SCD; + /* iwl3945_irq_tasklet() will service interrupts and re-enable them */ - tasklet_schedule(&priv->irq_tasklet); + if (likely(inta || inta_fh)) + tasklet_schedule(&priv->irq_tasklet); unplugged: spin_unlock(&priv->lock); @@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) return 0; } +/* + * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map + */ +static void iwl3945_free_channel_map(struct iwl3945_priv *priv) +{ + kfree(priv->channel_info); + priv->channel_count = 0; +} + /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after * sending probe req. This should be set long enough to hear probe responses * from more than one AP. */ @@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) return 0; } +/* + * iwl3945_free_geos - undo allocations in iwl3945_init_geos + */ +static void iwl3945_free_geos(struct iwl3945_priv *priv) +{ + kfree(priv->modes); + kfree(priv->ieee_channels); + kfree(priv->ieee_rates); + clear_bit(STATUS_GEO_CONFIGURED, &priv->status); +} + /****************************************************************************** * * uCode download functions @@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) /* Clear out the uCode error bit if it is set */ clear_bit(STATUS_FW_ERROR, &priv->status); - rc = iwl3945_init_channel_map(priv); - if (rc) { - IWL_ERROR("initializing regulatory failed: %d\n", rc); - return; - } - - iwl3945_init_geos(priv); - iwl3945_reset_channel_flag(priv); - if (iwl3945_is_rfkill(priv)) return; @@ -6301,6 +6330,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv) return -ENODEV; } + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { + IWL_ERROR("ucode not available for device bringup\n"); + return -EIO; + } + /* If platform's RF_KILL switch is NOT set to KILL */ if (iwl3945_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) @@ -6313,11 +6347,6 @@ static int __iwl3945_up(struct iwl3945_priv *priv) } } - if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { - IWL_ERROR("ucode not available for device bringup\n"); - return -EIO; - } - iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); rc = iwl3945_hw_nic_init(priv); @@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) * that based on the direct_mask added to each channel entry */ scan->tx_cmd.len = cpu_to_le16( iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); + IWL_MAX_SCAN_SIZE - sizeof(*scan), 0)); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; @@ -7120,7 +7149,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) { int rc = 0; - if (priv->status & STATUS_EXIT_PENDING) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ @@ -8614,11 +8643,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); + err = iwl3945_init_channel_map(priv); + if (err) { + IWL_ERROR("initializing regulatory failed: %d\n", err); + goto out_remove_sysfs; + } + + err = iwl3945_init_geos(priv); + if (err) { + IWL_ERROR("initializing geos failed: %d\n", err); + goto out_free_channel_map; + } + iwl3945_reset_channel_flag(priv); + iwl3945_rate_control_register(priv->hw); err = ieee80211_register_hw(priv->hw); if (err) { IWL_ERROR("Failed to register network device (error %d)\n", err); - goto out_remove_sysfs; + goto out_free_geos; } priv->hw->conf.beacon_int = 100; @@ -8628,6 +8670,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e return 0; + out_free_geos: + iwl3945_free_geos(priv); + out_free_channel_map: + iwl3945_free_channel_map(priv); out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); @@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev) pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); - kfree(priv->channel_info); - - kfree(priv->ieee_channels); - kfree(priv->ieee_rates); + iwl3945_free_channel_map(priv); + iwl3945_free_geos(priv); if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index c86da5c..f423241 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1639,6 +1639,12 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac) memcpy(mac, priv->eeprom.mac_address, 6); } +static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv) +{ + iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); +} + /** * iwl4965_eeprom_init - read EEPROM contents * @@ -2927,8 +2933,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, #endif /* drop all data frame if we are not associated */ - if (!iwl4965_is_associated(priv) && !priv->assoc_id && - ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { + if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && + (!iwl4965_is_associated(priv) || + !priv->assoc_id || + !priv->assoc_station_added)) { IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); goto drop_unlock; } @@ -5131,8 +5139,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv) #ifdef CONFIG_IWL4965_DEBUG if (iwl4965_debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_MAC_CLK_ACTV) - IWL_DEBUG_ISR("Microcode started or stopped.\n"); + if (inta & CSR_INT_BIT_SCD) + IWL_DEBUG_ISR("Scheduler finished to transmit " + "the frame/frames.\n"); /* Alive notification via Rx interrupt will do the real work */ if (inta & CSR_INT_BIT_ALIVE) @@ -5140,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv) } #endif /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); + inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { @@ -5269,8 +5278,11 @@ static irqreturn_t iwl4965_isr(int irq, void *data) IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); + inta &= ~CSR_INT_BIT_SCD; + /* iwl4965_irq_tasklet() will service interrupts and re-enable them */ - tasklet_schedule(&priv->irq_tasklet); + if (likely(inta || inta_fh)) + tasklet_schedule(&priv->irq_tasklet); unplugged: spin_unlock(&priv->lock); @@ -5576,6 +5588,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) return 0; } +/* + * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map + */ +static void iwl4965_free_channel_map(struct iwl4965_priv *priv) +{ + kfree(priv->channel_info); + priv->channel_count = 0; +} + /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after * sending probe req. This should be set long enough to hear probe responses * from more than one AP. */ @@ -5909,6 +5930,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) return 0; } +/* + * iwl4965_free_geos - undo allocations in iwl4965_init_geos + */ +static void iwl4965_free_geos(struct iwl4965_priv *priv) +{ + kfree(priv->modes); + kfree(priv->ieee_channels); + kfree(priv->ieee_rates); + clear_bit(STATUS_GEO_CONFIGURED, &priv->status); +} + /****************************************************************************** * * uCode download functions @@ -6560,15 +6592,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv) /* Clear out the uCode error bit if it is set */ clear_bit(STATUS_FW_ERROR, &priv->status); - rc = iwl4965_init_channel_map(priv); - if (rc) { - IWL_ERROR("initializing regulatory failed: %d\n", rc); - return; - } - - iwl4965_init_geos(priv); - iwl4965_reset_channel_flag(priv); - if (iwl4965_is_rfkill(priv)) return; @@ -6732,6 +6755,11 @@ static int __iwl4965_up(struct iwl4965_priv *priv) return -ENODEV; } + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { + IWL_ERROR("ucode not available for device bringup\n"); + return -EIO; + } + /* If platform's RF_KILL switch is NOT set to KILL */ if (iwl4965_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) @@ -6744,11 +6772,6 @@ static int __iwl4965_up(struct iwl4965_priv *priv) } } - if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { - IWL_ERROR("ucode not available for device bringup\n"); - return -EIO; - } - iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF); rc = iwl4965_hw_nic_init(priv); @@ -7023,7 +7046,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) * that based on the direct_mask added to each channel entry */ scan->tx_cmd.len = cpu_to_le16( iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); + IWL_MAX_SCAN_SIZE - sizeof(*scan), 0)); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; @@ -7448,7 +7471,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, if (priv->vif) { IWL_DEBUG_MAC80211("leave - vif != NULL\n"); - return 0; + return -EOPNOTSUPP; } spin_lock_irqsave(&priv->lock, flags); @@ -7580,7 +7603,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv) { int rc = 0; - if (priv->status & STATUS_EXIT_PENDING) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ @@ -9198,11 +9221,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); + err = iwl4965_init_channel_map(priv); + if (err) { + IWL_ERROR("initializing regulatory failed: %d\n", err); + goto out_remove_sysfs; + } + + err = iwl4965_init_geos(priv); + if (err) { + IWL_ERROR("initializing geos failed: %d\n", err); + goto out_free_channel_map; + } + iwl4965_reset_channel_flag(priv); + iwl4965_rate_control_register(priv->hw); err = ieee80211_register_hw(priv->hw); if (err) { IWL_ERROR("Failed to register network device (error %d)\n", err); - goto out_remove_sysfs; + goto out_free_geos; } priv->hw->conf.beacon_int = 100; @@ -9212,6 +9248,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e return 0; + out_free_geos: + iwl4965_free_geos(priv); + out_free_channel_map: + iwl4965_free_channel_map(priv); out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); @@ -9286,10 +9326,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev) pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); - kfree(priv->channel_info); - - kfree(priv->ieee_channels); - kfree(priv->ieee_rates); + iwl4965_free_channel_map(priv); + iwl4965_free_geos(priv); if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); |