aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c86
1 files changed, 65 insertions, 21 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 748ac1222abb..33239f197984 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)
1557 memcpy(mac, priv->eeprom.mac_address, 6); 1557 memcpy(mac, priv->eeprom.mac_address, 6);
1558} 1558}
1559 1559
1560/*
1561 * Clear the OWNER_MSK, to establish driver (instead of uCode running on
1562 * embedded controller) as EEPROM reader; each read is a series of pulses
1563 * to/from the EEPROM chip, not a single event, so even reads could conflict
1564 * if they weren't arbitrated by some ownership mechanism. Here, the driver
1565 * simply claims ownership, which should be safe when this function is called
1566 * (i.e. before loading uCode!).
1567 */
1568static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
1569{
1570 _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
1571 return 0;
1572}
1573
1560/** 1574/**
1561 * iwl3945_eeprom_init - read EEPROM contents 1575 * iwl3945_eeprom_init - read EEPROM contents
1562 * 1576 *
@@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
2792#endif 2806#endif
2793 2807
2794 /* drop all data frame if we are not associated */ 2808 /* drop all data frame if we are not associated */
2795 if (!iwl3945_is_associated(priv) && !priv->assoc_id && 2809 if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
2796 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { 2810 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
2797 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); 2811 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
2798 goto drop_unlock; 2812 goto drop_unlock;
@@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
4745#ifdef CONFIG_IWL3945_DEBUG 4759#ifdef CONFIG_IWL3945_DEBUG
4746 if (iwl3945_debug_level & (IWL_DL_ISR)) { 4760 if (iwl3945_debug_level & (IWL_DL_ISR)) {
4747 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 4761 /* NIC fires this, but we don't use it, redundant with WAKEUP */
4748 if (inta & CSR_INT_BIT_MAC_CLK_ACTV) 4762 if (inta & CSR_INT_BIT_SCD)
4749 IWL_DEBUG_ISR("Microcode started or stopped.\n"); 4763 IWL_DEBUG_ISR("Scheduler finished to transmit "
4764 "the frame/frames.\n");
4750 4765
4751 /* Alive notification via Rx interrupt will do the real work */ 4766 /* Alive notification via Rx interrupt will do the real work */
4752 if (inta & CSR_INT_BIT_ALIVE) 4767 if (inta & CSR_INT_BIT_ALIVE)
@@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
4754 } 4769 }
4755#endif 4770#endif
4756 /* Safely ignore these bits for debug checks below */ 4771 /* Safely ignore these bits for debug checks below */
4757 inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); 4772 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
4758 4773
4759 /* HW RF KILL switch toggled (4965 only) */ 4774 /* HW RF KILL switch toggled (4965 only) */
4760 if (inta & CSR_INT_BIT_RF_KILL) { 4775 if (inta & CSR_INT_BIT_RF_KILL) {
@@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
4890 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 4905 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
4891 inta, inta_mask, inta_fh); 4906 inta, inta_mask, inta_fh);
4892 4907
4908 inta &= ~CSR_INT_BIT_SCD;
4909
4893 /* iwl3945_irq_tasklet() will service interrupts and re-enable them */ 4910 /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
4894 tasklet_schedule(&priv->irq_tasklet); 4911 if (likely(inta || inta_fh))
4912 tasklet_schedule(&priv->irq_tasklet);
4895unplugged: 4913unplugged:
4896 spin_unlock(&priv->lock); 4914 spin_unlock(&priv->lock);
4897 4915
@@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
5146 return 0; 5164 return 0;
5147} 5165}
5148 5166
5167/*
5168 * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
5169 */
5170static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
5171{
5172 kfree(priv->channel_info);
5173 priv->channel_count = 0;
5174}
5175
5149/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 5176/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
5150 * sending probe req. This should be set long enough to hear probe responses 5177 * sending probe req. This should be set long enough to hear probe responses
5151 * from more than one AP. */ 5178 * from more than one AP. */
@@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5471 return 0; 5498 return 0;
5472} 5499}
5473 5500
5501/*
5502 * iwl3945_free_geos - undo allocations in iwl3945_init_geos
5503 */
5504static void iwl3945_free_geos(struct iwl3945_priv *priv)
5505{
5506 kfree(priv->modes);
5507 kfree(priv->ieee_channels);
5508 kfree(priv->ieee_rates);
5509 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
5510}
5511
5474/****************************************************************************** 5512/******************************************************************************
5475 * 5513 *
5476 * uCode download functions 5514 * uCode download functions
@@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
6130 /* Clear out the uCode error bit if it is set */ 6168 /* Clear out the uCode error bit if it is set */
6131 clear_bit(STATUS_FW_ERROR, &priv->status); 6169 clear_bit(STATUS_FW_ERROR, &priv->status);
6132 6170
6133 rc = iwl3945_init_channel_map(priv);
6134 if (rc) {
6135 IWL_ERROR("initializing regulatory failed: %d\n", rc);
6136 return;
6137 }
6138
6139 iwl3945_init_geos(priv);
6140 iwl3945_reset_channel_flag(priv);
6141
6142 if (iwl3945_is_rfkill(priv)) 6171 if (iwl3945_is_rfkill(priv))
6143 return; 6172 return;
6144 6173
@@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6599 * that based on the direct_mask added to each channel entry */ 6628 * that based on the direct_mask added to each channel entry */
6600 scan->tx_cmd.len = cpu_to_le16( 6629 scan->tx_cmd.len = cpu_to_le16(
6601 iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, 6630 iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
6602 IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); 6631 IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
6603 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 6632 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
6604 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; 6633 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
6605 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 6634 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)
7120{ 7149{
7121 int rc = 0; 7150 int rc = 0;
7122 7151
7123 if (priv->status & STATUS_EXIT_PENDING) 7152 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
7124 return; 7153 return;
7125 7154
7126 /* The following should be done only at AP bring up */ 7155 /* 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
8614 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); 8643 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
8615 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 8644 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
8616 8645
8646 err = iwl3945_init_channel_map(priv);
8647 if (err) {
8648 IWL_ERROR("initializing regulatory failed: %d\n", err);
8649 goto out_remove_sysfs;
8650 }
8651
8652 err = iwl3945_init_geos(priv);
8653 if (err) {
8654 IWL_ERROR("initializing geos failed: %d\n", err);
8655 goto out_free_channel_map;
8656 }
8657 iwl3945_reset_channel_flag(priv);
8658
8617 iwl3945_rate_control_register(priv->hw); 8659 iwl3945_rate_control_register(priv->hw);
8618 err = ieee80211_register_hw(priv->hw); 8660 err = ieee80211_register_hw(priv->hw);
8619 if (err) { 8661 if (err) {
8620 IWL_ERROR("Failed to register network device (error %d)\n", err); 8662 IWL_ERROR("Failed to register network device (error %d)\n", err);
8621 goto out_remove_sysfs; 8663 goto out_free_geos;
8622 } 8664 }
8623 8665
8624 priv->hw->conf.beacon_int = 100; 8666 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
8628 8670
8629 return 0; 8671 return 0;
8630 8672
8673 out_free_geos:
8674 iwl3945_free_geos(priv);
8675 out_free_channel_map:
8676 iwl3945_free_channel_map(priv);
8631 out_remove_sysfs: 8677 out_remove_sysfs:
8632 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 8678 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
8633 8679
@@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
8702 pci_disable_device(pdev); 8748 pci_disable_device(pdev);
8703 pci_set_drvdata(pdev, NULL); 8749 pci_set_drvdata(pdev, NULL);
8704 8750
8705 kfree(priv->channel_info); 8751 iwl3945_free_channel_map(priv);
8706 8752 iwl3945_free_geos(priv);
8707 kfree(priv->ieee_channels);
8708 kfree(priv->ieee_rates);
8709 8753
8710 if (priv->ibss_beacon) 8754 if (priv->ibss_beacon)
8711 dev_kfree_skb(priv->ibss_beacon); 8755 dev_kfree_skb(priv->ibss_beacon);