aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorBen Cahill <ben.m.cahill@intel.com>2009-10-23 16:42:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:49:59 -0400
commitfadb3582a38c33d0f7c58ab7905d4dbc67f4c4d9 (patch)
treeff8f1bfc9aca5e200b0387069a2500850e9891eb /drivers/net/wireless/iwlwifi
parent065e63b00cf13919010bbeff48f7a120033be448 (diff)
iwlwifi: consolidate apm_init() functions
Consolidate most iwlXXXX_apm_init() functions into single iwl_apm_init(). Keep iwl3945_apm_init(), but leverage iwl_apm_init() for most functionality. Update 4965 init sequence to follow most recent factory recommendations. Add following members to struct iwl_cfg to guide the init sequence: pll_cfg_val (replaces needs_pll_cfg), set_l0s, use_bsm Move L0S enable/disable from nic_config() functions to iwl_apm_init(). This satisifies the "FIXME: put here L1A -L0S w/a" notice, and complies with factory-recommended sequence. Add debug info message in iwl_apm_init(), and symmetrical message in iwl_apm_stop(). Signed-off-by: Ben Cahill <ben.m.cahill@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c114
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
8 files changed, 190 insertions, 183 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index a00f947bd59c..3da5913225e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -110,7 +110,7 @@ static struct iwl_lib_ops iwl1000_lib = {
110 .send_tx_power = iwl5000_send_tx_power, 110 .send_tx_power = iwl5000_send_tx_power,
111 .update_chain_flags = iwl_update_chain_flags, 111 .update_chain_flags = iwl_update_chain_flags,
112 .apm_ops = { 112 .apm_ops = {
113 .init = iwl5000_apm_init, 113 .init = iwl_apm_init,
114 .stop = iwl_apm_stop, 114 .stop = iwl_apm_stop,
115 .config = iwl1000_nic_config, 115 .config = iwl1000_nic_config,
116 .set_pwr_src = iwl_set_pwr_src, 116 .set_pwr_src = iwl_set_pwr_src,
@@ -163,7 +163,9 @@ struct iwl_cfg iwl1000_bgn_cfg = {
163 .mod_params = &iwl50_mod_params, 163 .mod_params = &iwl50_mod_params,
164 .valid_tx_ant = ANT_A, 164 .valid_tx_ant = ANT_A,
165 .valid_rx_ant = ANT_AB, 165 .valid_rx_ant = ANT_AB,
166 .need_pll_cfg = true, 166 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
167 .set_l0s = false,
168 .use_bsm = false,
167 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 169 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
168 .shadow_ram_support = false, 170 .shadow_ram_support = false,
169 .ht_greenfield_support = true, 171 .ht_greenfield_support = true,
@@ -186,7 +188,9 @@ struct iwl_cfg iwl1000_bg_cfg = {
186 .mod_params = &iwl50_mod_params, 188 .mod_params = &iwl50_mod_params,
187 .valid_tx_ant = ANT_A, 189 .valid_tx_ant = ANT_A,
188 .valid_rx_ant = ANT_AB, 190 .valid_rx_ant = ANT_AB,
189 .need_pll_cfg = true, 191 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
192 .set_l0s = false,
193 .use_bsm = false,
190 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 194 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
191 .shadow_ram_support = false, 195 .shadow_ram_support = false,
192 .ht_greenfield_support = true, 196 .ht_greenfield_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 9f18b4cba952..7142aa5dbdb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1013,55 +1013,15 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
1013 return rc; 1013 return rc;
1014} 1014}
1015 1015
1016
1016/* 1017/*
1017 * Start up NIC's basic functionality after it has been reset 1018 * Start up 3945's basic functionality after it has been reset
1018 * (e.g. after platform boot, or shutdown via iwl3945_apm_stop()) 1019 * (e.g. after platform boot, or shutdown via iwl_apm_stop())
1019 * NOTE: This does not load uCode nor start the embedded processor 1020 * NOTE: This does not load uCode nor start the embedded processor
1020 */ 1021 */
1021static int iwl3945_apm_init(struct iwl_priv *priv) 1022static int iwl3945_apm_init(struct iwl_priv *priv)
1022{ 1023{
1023 int ret; 1024 int ret = iwl_apm_init(priv);
1024
1025 /* Configure chip clock phase-lock-loop */
1026 iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
1027
1028 /*
1029 * Disable L0S exit timer (platform NMI Work/Around)
1030 * (does this do anything on 3945, or just 4965 and beyond?)
1031 */
1032 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
1033 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
1034
1035 /* Disable L0s without affecting L1; don't wait for ICH (L0s bug W/A) */
1036 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
1037 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
1038
1039 /* Set FH wait threshold to maximum (HW error during stress W/A) */
1040 iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
1041
1042 /*
1043 * Set "initialization complete" bit to move adapter from
1044 * D0U* --> D0A* (powered-up active) state.
1045 */
1046 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
1047
1048 /*
1049 * Wait for clock stabilization; once stabilized, access to
1050 * device-internal resources is supported, e.g. iwl_write_prph()
1051 * and accesses to uCode SRAM.
1052 */
1053 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
1054 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
1055 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
1056 if (ret < 0) {
1057 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
1058 goto out;
1059 }
1060
1061 /* Enable DMA and BSM clocks, wait for them to stabilize */
1062 iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
1063 APMG_CLK_VAL_BSM_CLK_RQT);
1064 udelay(20);
1065 1025
1066 /* Clear APMG (NIC's internal power management) interrupts */ 1026 /* Clear APMG (NIC's internal power management) interrupts */
1067 iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); 1027 iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
@@ -1072,11 +1032,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
1072 udelay(5); 1032 udelay(5);
1073 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); 1033 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
1074 1034
1075 /* Disable L1-Active */
1076 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
1077 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1078
1079out:
1080 return ret; 1035 return ret;
1081} 1036}
1082 1037
@@ -2876,6 +2831,9 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2876 .ops = &iwl3945_ops, 2831 .ops = &iwl3945_ops,
2877 .num_of_queues = IWL39_NUM_QUEUES, 2832 .num_of_queues = IWL39_NUM_QUEUES,
2878 .mod_params = &iwl3945_mod_params, 2833 .mod_params = &iwl3945_mod_params,
2834 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
2835 .set_l0s = false,
2836 .use_bsm = true,
2879 .use_isr_legacy = true, 2837 .use_isr_legacy = true,
2880 .ht_greenfield_support = false, 2838 .ht_greenfield_support = false,
2881 .led_compensation = 64, 2839 .led_compensation = 64,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1a622aa5a160..32d5f3de429f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -317,64 +317,13 @@ static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
317 iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); 317 iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
318} 318}
319 319
320static int iwl4965_apm_init(struct iwl_priv *priv)
321{
322 int ret = 0;
323
324 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
325 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
326
327 /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
328 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
329 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
330
331 /* set "initialization complete" bit to move adapter
332 * D0U* --> D0A* state */
333 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
334
335 /* wait for clock stabilization */
336 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
337 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
338 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
339 if (ret < 0) {
340 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
341 goto out;
342 }
343
344 /* enable DMA */
345 iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
346 APMG_CLK_VAL_BSM_CLK_RQT);
347
348 udelay(20);
349
350 /* disable L1-Active */
351 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
352 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
353
354out:
355 return ret;
356}
357
358
359static void iwl4965_nic_config(struct iwl_priv *priv) 320static void iwl4965_nic_config(struct iwl_priv *priv)
360{ 321{
361 unsigned long flags; 322 unsigned long flags;
362 u16 radio_cfg; 323 u16 radio_cfg;
363 u16 lctl;
364 324
365 spin_lock_irqsave(&priv->lock, flags); 325 spin_lock_irqsave(&priv->lock, flags);
366 326
367 lctl = iwl_pcie_link_ctl(priv);
368
369 /* HW bug W/A - negligible power consumption */
370 /* L1-ASPM is enabled by BIOS */
371 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
372 /* L1-ASPM enabled: disable L0S */
373 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
374 else
375 /* L1-ASPM disabled: enable L0S */
376 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
377
378 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 327 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
379 328
380 /* write radio config values to register */ 329 /* write radio config values to register */
@@ -2223,7 +2172,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2223 .dump_nic_event_log = iwl_dump_nic_event_log, 2172 .dump_nic_event_log = iwl_dump_nic_event_log,
2224 .dump_nic_error_log = iwl_dump_nic_error_log, 2173 .dump_nic_error_log = iwl_dump_nic_error_log,
2225 .apm_ops = { 2174 .apm_ops = {
2226 .init = iwl4965_apm_init, 2175 .init = iwl_apm_init,
2227 .stop = iwl_apm_stop, 2176 .stop = iwl_apm_stop,
2228 .config = iwl4965_nic_config, 2177 .config = iwl4965_nic_config,
2229 .set_pwr_src = iwl_set_pwr_src, 2178 .set_pwr_src = iwl_set_pwr_src,
@@ -2276,6 +2225,9 @@ struct iwl_cfg iwl4965_agn_cfg = {
2276 .num_of_queues = IWL49_NUM_QUEUES, 2225 .num_of_queues = IWL49_NUM_QUEUES,
2277 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, 2226 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2278 .mod_params = &iwl4965_mod_params, 2227 .mod_params = &iwl4965_mod_params,
2228 .pll_cfg_val = 0,
2229 .set_l0s = true,
2230 .use_bsm = true,
2279 .use_isr_legacy = true, 2231 .use_isr_legacy = true,
2280 .ht_greenfield_support = false, 2232 .ht_greenfield_support = false,
2281 .broken_powersave = true, 2233 .broken_powersave = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index afa88a304158..a6e347b9799a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -72,72 +72,14 @@ static const u16 iwl5000_default_queue_to_tx_fifo[] = {
72 IWL_TX_FIFO_HCCA_2 72 IWL_TX_FIFO_HCCA_2
73}; 73};
74 74
75int iwl5000_apm_init(struct iwl_priv *priv)
76{
77 int ret = 0;
78
79 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
80 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
81
82 /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
83 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
84 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
85
86 /* Set FH wait threshold to maximum (HW error during stress W/A) */
87 iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
88
89 /* enable HAP INTA to move device L1a -> L0s */
90 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
91 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
92
93 if (priv->cfg->need_pll_cfg)
94 iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
95
96 /* set "initialization complete" bit to move adapter
97 * D0U* --> D0A* state */
98 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
99
100 /* wait for clock stabilization */
101 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
102 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
103 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
104 if (ret < 0) {
105 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
106 return ret;
107 }
108
109 /* enable DMA */
110 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
111
112 udelay(20);
113
114 /* disable L1-Active */
115 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
116 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
117
118 return ret;
119}
120
121/* NIC configuration for 5000 series */ 75/* NIC configuration for 5000 series */
122void iwl5000_nic_config(struct iwl_priv *priv) 76void iwl5000_nic_config(struct iwl_priv *priv)
123{ 77{
124 unsigned long flags; 78 unsigned long flags;
125 u16 radio_cfg; 79 u16 radio_cfg;
126 u16 lctl;
127 80
128 spin_lock_irqsave(&priv->lock, flags); 81 spin_lock_irqsave(&priv->lock, flags);
129 82
130 lctl = iwl_pcie_link_ctl(priv);
131
132 /* HW bug W/A */
133 /* L1-ASPM is enabled by BIOS */
134 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
135 /* L1-APSM enabled: disable L0S */
136 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
137 else
138 /* L1-ASPM disabled: enable L0S */
139 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
140
141 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 83 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
142 84
143 /* write radio config values to register */ 85 /* write radio config values to register */
@@ -1488,7 +1430,7 @@ struct iwl_lib_ops iwl5000_lib = {
1488 .send_tx_power = iwl5000_send_tx_power, 1430 .send_tx_power = iwl5000_send_tx_power,
1489 .update_chain_flags = iwl_update_chain_flags, 1431 .update_chain_flags = iwl_update_chain_flags,
1490 .apm_ops = { 1432 .apm_ops = {
1491 .init = iwl5000_apm_init, 1433 .init = iwl_apm_init,
1492 .stop = iwl_apm_stop, 1434 .stop = iwl_apm_stop,
1493 .config = iwl5000_nic_config, 1435 .config = iwl5000_nic_config,
1494 .set_pwr_src = iwl_set_pwr_src, 1436 .set_pwr_src = iwl_set_pwr_src,
@@ -1539,7 +1481,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1539 .send_tx_power = iwl5000_send_tx_power, 1481 .send_tx_power = iwl5000_send_tx_power,
1540 .update_chain_flags = iwl_update_chain_flags, 1482 .update_chain_flags = iwl_update_chain_flags,
1541 .apm_ops = { 1483 .apm_ops = {
1542 .init = iwl5000_apm_init, 1484 .init = iwl_apm_init,
1543 .stop = iwl_apm_stop, 1485 .stop = iwl_apm_stop,
1544 .config = iwl5000_nic_config, 1486 .config = iwl5000_nic_config,
1545 .set_pwr_src = iwl_set_pwr_src, 1487 .set_pwr_src = iwl_set_pwr_src,
@@ -1607,7 +1549,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
1607 .mod_params = &iwl50_mod_params, 1549 .mod_params = &iwl50_mod_params,
1608 .valid_tx_ant = ANT_ABC, 1550 .valid_tx_ant = ANT_ABC,
1609 .valid_rx_ant = ANT_ABC, 1551 .valid_rx_ant = ANT_ABC,
1610 .need_pll_cfg = true, 1552 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1553 .set_l0s = true,
1554 .use_bsm = false,
1611 .ht_greenfield_support = true, 1555 .ht_greenfield_support = true,
1612 .led_compensation = 51, 1556 .led_compensation = 51,
1613 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1557 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1628,7 +1572,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
1628 .mod_params = &iwl50_mod_params, 1572 .mod_params = &iwl50_mod_params,
1629 .valid_tx_ant = ANT_B, 1573 .valid_tx_ant = ANT_B,
1630 .valid_rx_ant = ANT_AB, 1574 .valid_rx_ant = ANT_AB,
1631 .need_pll_cfg = true, 1575 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1576 .set_l0s = true,
1577 .use_bsm = false,
1632 .ht_greenfield_support = true, 1578 .ht_greenfield_support = true,
1633 .led_compensation = 51, 1579 .led_compensation = 51,
1634 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1580 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1649,7 +1595,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
1649 .mod_params = &iwl50_mod_params, 1595 .mod_params = &iwl50_mod_params,
1650 .valid_tx_ant = ANT_B, 1596 .valid_tx_ant = ANT_B,
1651 .valid_rx_ant = ANT_AB, 1597 .valid_rx_ant = ANT_AB,
1652 .need_pll_cfg = true, 1598 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1599 .set_l0s = true,
1600 .use_bsm = false,
1653 .ht_greenfield_support = true, 1601 .ht_greenfield_support = true,
1654 .led_compensation = 51, 1602 .led_compensation = 51,
1655 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1670,7 +1618,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
1670 .mod_params = &iwl50_mod_params, 1618 .mod_params = &iwl50_mod_params,
1671 .valid_tx_ant = ANT_B, 1619 .valid_tx_ant = ANT_B,
1672 .valid_rx_ant = ANT_AB, 1620 .valid_rx_ant = ANT_AB,
1673 .need_pll_cfg = true, 1621 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1622 .set_l0s = true,
1623 .use_bsm = false,
1674 .ht_greenfield_support = true, 1624 .ht_greenfield_support = true,
1675 .led_compensation = 51, 1625 .led_compensation = 51,
1676 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1626 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1691,7 +1641,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
1691 .mod_params = &iwl50_mod_params, 1641 .mod_params = &iwl50_mod_params,
1692 .valid_tx_ant = ANT_ABC, 1642 .valid_tx_ant = ANT_ABC,
1693 .valid_rx_ant = ANT_ABC, 1643 .valid_rx_ant = ANT_ABC,
1694 .need_pll_cfg = true, 1644 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1645 .set_l0s = true,
1646 .use_bsm = false,
1695 .ht_greenfield_support = true, 1647 .ht_greenfield_support = true,
1696 .led_compensation = 51, 1648 .led_compensation = 51,
1697 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1649 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1712,7 +1664,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
1712 .mod_params = &iwl50_mod_params, 1664 .mod_params = &iwl50_mod_params,
1713 .valid_tx_ant = ANT_A, 1665 .valid_tx_ant = ANT_A,
1714 .valid_rx_ant = ANT_AB, 1666 .valid_rx_ant = ANT_AB,
1715 .need_pll_cfg = true, 1667 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1668 .set_l0s = true,
1669 .use_bsm = false,
1716 .ht_greenfield_support = true, 1670 .ht_greenfield_support = true,
1717 .led_compensation = 51, 1671 .led_compensation = 51,
1718 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1672 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b53181324487..5211872da880 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -193,7 +193,7 @@ static struct iwl_lib_ops iwl6000_lib = {
193 .send_tx_power = iwl5000_send_tx_power, 193 .send_tx_power = iwl5000_send_tx_power,
194 .update_chain_flags = iwl_update_chain_flags, 194 .update_chain_flags = iwl_update_chain_flags,
195 .apm_ops = { 195 .apm_ops = {
196 .init = iwl5000_apm_init, 196 .init = iwl_apm_init,
197 .stop = iwl_apm_stop, 197 .stop = iwl_apm_stop,
198 .config = iwl6000_nic_config, 198 .config = iwl6000_nic_config,
199 .set_pwr_src = iwl_set_pwr_src, 199 .set_pwr_src = iwl_set_pwr_src,
@@ -266,7 +266,9 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
266 .mod_params = &iwl50_mod_params, 266 .mod_params = &iwl50_mod_params,
267 .valid_tx_ant = ANT_AB, 267 .valid_tx_ant = ANT_AB,
268 .valid_rx_ant = ANT_AB, 268 .valid_rx_ant = ANT_AB,
269 .need_pll_cfg = false, 269 .pll_cfg_val = 0,
270 .set_l0s = false,
271 .use_bsm = false,
270 .pa_type = IWL_PA_HYBRID, 272 .pa_type = IWL_PA_HYBRID,
271 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 273 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
272 .shadow_ram_support = true, 274 .shadow_ram_support = true,
@@ -292,7 +294,9 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
292 .mod_params = &iwl50_mod_params, 294 .mod_params = &iwl50_mod_params,
293 .valid_tx_ant = ANT_AB, 295 .valid_tx_ant = ANT_AB,
294 .valid_rx_ant = ANT_AB, 296 .valid_rx_ant = ANT_AB,
295 .need_pll_cfg = false, 297 .pll_cfg_val = 0,
298 .set_l0s = false,
299 .use_bsm = false,
296 .pa_type = IWL_PA_HYBRID, 300 .pa_type = IWL_PA_HYBRID,
297 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 301 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
298 .shadow_ram_support = true, 302 .shadow_ram_support = true,
@@ -317,7 +321,9 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
317 .mod_params = &iwl50_mod_params, 321 .mod_params = &iwl50_mod_params,
318 .valid_tx_ant = ANT_AB, 322 .valid_tx_ant = ANT_AB,
319 .valid_rx_ant = ANT_AB, 323 .valid_rx_ant = ANT_AB,
320 .need_pll_cfg = false, 324 .pll_cfg_val = 0,
325 .set_l0s = false,
326 .use_bsm = false,
321 .pa_type = IWL_PA_HYBRID, 327 .pa_type = IWL_PA_HYBRID,
322 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 328 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
323 .shadow_ram_support = true, 329 .shadow_ram_support = true,
@@ -345,7 +351,9 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
345 .mod_params = &iwl50_mod_params, 351 .mod_params = &iwl50_mod_params,
346 .valid_tx_ant = ANT_BC, 352 .valid_tx_ant = ANT_BC,
347 .valid_rx_ant = ANT_BC, 353 .valid_rx_ant = ANT_BC,
348 .need_pll_cfg = false, 354 .pll_cfg_val = 0,
355 .set_l0s = false,
356 .use_bsm = false,
349 .pa_type = IWL_PA_INTERNAL, 357 .pa_type = IWL_PA_INTERNAL,
350 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 358 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
351 .shadow_ram_support = true, 359 .shadow_ram_support = true,
@@ -371,7 +379,9 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
371 .mod_params = &iwl50_mod_params, 379 .mod_params = &iwl50_mod_params,
372 .valid_tx_ant = ANT_BC, 380 .valid_tx_ant = ANT_BC,
373 .valid_rx_ant = ANT_BC, 381 .valid_rx_ant = ANT_BC,
374 .need_pll_cfg = false, 382 .pll_cfg_val = 0,
383 .set_l0s = false,
384 .use_bsm = false,
375 .pa_type = IWL_PA_INTERNAL, 385 .pa_type = IWL_PA_INTERNAL,
376 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 386 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
377 .shadow_ram_support = true, 387 .shadow_ram_support = true,
@@ -396,7 +406,9 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
396 .mod_params = &iwl50_mod_params, 406 .mod_params = &iwl50_mod_params,
397 .valid_tx_ant = ANT_BC, 407 .valid_tx_ant = ANT_BC,
398 .valid_rx_ant = ANT_BC, 408 .valid_rx_ant = ANT_BC,
399 .need_pll_cfg = false, 409 .pll_cfg_val = 0,
410 .set_l0s = false,
411 .use_bsm = false,
400 .pa_type = IWL_PA_INTERNAL, 412 .pa_type = IWL_PA_INTERNAL,
401 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 413 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
402 .shadow_ram_support = true, 414 .shadow_ram_support = true,
@@ -421,7 +433,9 @@ struct iwl_cfg iwl6050_2agn_cfg = {
421 .mod_params = &iwl50_mod_params, 433 .mod_params = &iwl50_mod_params,
422 .valid_tx_ant = ANT_AB, 434 .valid_tx_ant = ANT_AB,
423 .valid_rx_ant = ANT_AB, 435 .valid_rx_ant = ANT_AB,
424 .need_pll_cfg = false, 436 .pll_cfg_val = 0,
437 .set_l0s = false,
438 .use_bsm = false,
425 .pa_type = IWL_PA_SYSTEM, 439 .pa_type = IWL_PA_SYSTEM,
426 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 440 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
427 .shadow_ram_support = true, 441 .shadow_ram_support = true,
@@ -447,7 +461,9 @@ struct iwl_cfg iwl6050_2abg_cfg = {
447 .mod_params = &iwl50_mod_params, 461 .mod_params = &iwl50_mod_params,
448 .valid_tx_ant = ANT_AB, 462 .valid_tx_ant = ANT_AB,
449 .valid_rx_ant = ANT_AB, 463 .valid_rx_ant = ANT_AB,
450 .need_pll_cfg = false, 464 .pll_cfg_val = 0,
465 .set_l0s = false,
466 .use_bsm = false,
451 .pa_type = IWL_PA_SYSTEM, 467 .pa_type = IWL_PA_SYSTEM,
452 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 468 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
453 .shadow_ram_support = true, 469 .shadow_ram_support = true,
@@ -472,7 +488,9 @@ struct iwl_cfg iwl6000_3agn_cfg = {
472 .mod_params = &iwl50_mod_params, 488 .mod_params = &iwl50_mod_params,
473 .valid_tx_ant = ANT_ABC, 489 .valid_tx_ant = ANT_ABC,
474 .valid_rx_ant = ANT_ABC, 490 .valid_rx_ant = ANT_ABC,
475 .need_pll_cfg = false, 491 .pll_cfg_val = 0,
492 .set_l0s = false,
493 .use_bsm = false,
476 .pa_type = IWL_PA_SYSTEM, 494 .pa_type = IWL_PA_SYSTEM,
477 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 495 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
478 .shadow_ram_support = true, 496 .shadow_ram_support = true,
@@ -498,7 +516,9 @@ struct iwl_cfg iwl6050_3agn_cfg = {
498 .mod_params = &iwl50_mod_params, 516 .mod_params = &iwl50_mod_params,
499 .valid_tx_ant = ANT_ABC, 517 .valid_tx_ant = ANT_ABC,
500 .valid_rx_ant = ANT_ABC, 518 .valid_rx_ant = ANT_ABC,
501 .need_pll_cfg = false, 519 .pll_cfg_val = 0,
520 .set_l0s = false,
521 .use_bsm = false,
502 .pa_type = IWL_PA_SYSTEM, 522 .pa_type = IWL_PA_SYSTEM,
503 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 523 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
504 .shadow_ram_support = true, 524 .shadow_ram_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7ce8663fdb7b..1d7248cd1969 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1369,6 +1369,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
1369{ 1369{
1370 unsigned long flags; 1370 unsigned long flags;
1371 1371
1372 IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
1373
1372 iwl_apm_stop_master(priv); 1374 iwl_apm_stop_master(priv);
1373 1375
1374 spin_lock_irqsave(&priv->lock, flags); 1376 spin_lock_irqsave(&priv->lock, flags);
@@ -1382,6 +1384,118 @@ void iwl_apm_stop(struct iwl_priv *priv)
1382} 1384}
1383EXPORT_SYMBOL(iwl_apm_stop); 1385EXPORT_SYMBOL(iwl_apm_stop);
1384 1386
1387
1388/*
1389 * Start up NIC's basic functionality after it has been reset
1390 * (e.g. after platform boot, or shutdown via iwl_apm_stop())
1391 * NOTE: This does not load uCode nor start the embedded processor
1392 */
1393int iwl_apm_init(struct iwl_priv *priv)
1394{
1395 int ret = 0;
1396 u16 lctl;
1397
1398 IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
1399
1400 /*
1401 * Use "set_bit" below rather than "write", to preserve any hardware
1402 * bits already set by default after reset.
1403 */
1404
1405 /* Disable L0S exit timer (platform NMI Work/Around) */
1406 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
1407 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
1408
1409 /*
1410 * Disable L0s without affecting L1;
1411 * don't wait for ICH L0s (ICH bug W/A)
1412 */
1413 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
1414 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
1415
1416 /* Set FH wait threshold to maximum (HW error during stress W/A) */
1417 iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
1418
1419 /*
1420 * Enable HAP INTA (interrupt from management bus) to
1421 * wake device's PCI Express link L1a -> L0s
1422 * NOTE: This is no-op for 3945 (non-existant bit)
1423 */
1424 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1425 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
1426
1427 /*
1428 * HW bug W/A - costs negligible power consumption ...
1429 * Check if BIOS (or OS) enabled L1-ASPM on this device
1430 */
1431 if (priv->cfg->set_l0s) {
1432 lctl = iwl_pcie_link_ctl(priv);
1433 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
1434 PCI_CFG_LINK_CTRL_VAL_L1_EN) {
1435 /* L1-ASPM enabled; disable(!) L0S */
1436 iwl_set_bit(priv, CSR_GIO_REG,
1437 CSR_GIO_REG_VAL_L0S_ENABLED);
1438 IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
1439 } else {
1440 /* L1-ASPM disabled; enable(!) L0S */
1441 iwl_clear_bit(priv, CSR_GIO_REG,
1442 CSR_GIO_REG_VAL_L0S_ENABLED);
1443 IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
1444 }
1445 }
1446
1447 /* Configure analog phase-lock-loop before activating to D0A */
1448 if (priv->cfg->pll_cfg_val)
1449 iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
1450
1451 /*
1452 * Set "initialization complete" bit to move adapter from
1453 * D0U* --> D0A* (powered-up active) state.
1454 */
1455 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
1456
1457 /*
1458 * Wait for clock stabilization; once stabilized, access to
1459 * device-internal resources is supported, e.g. iwl_write_prph()
1460 * and accesses to uCode SRAM.
1461 */
1462 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
1463 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
1464 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
1465 if (ret < 0) {
1466 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
1467 goto out;
1468 }
1469
1470 /*
1471 * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
1472 * BSM (Boostrap State Machine) is only in 3945 and 4965;
1473 * later devices (i.e. 5000 and later) have non-volatile SRAM,
1474 * and don't need BSM to restore data after power-saving sleep.
1475 *
1476 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1477 * do not disable clocks. This preserves any hardware bits already
1478 * set by default in "CLK_CTRL_REG" after reset.
1479 */
1480 if (priv->cfg->use_bsm)
1481 iwl_write_prph(priv, APMG_CLK_EN_REG,
1482 APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
1483 else
1484 iwl_write_prph(priv, APMG_CLK_EN_REG,
1485 APMG_CLK_VAL_DMA_CLK_RQT);
1486 udelay(20);
1487
1488 /* Disable L1-Active */
1489 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
1490 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1491
1492out:
1493 return ret;
1494}
1495EXPORT_SYMBOL(iwl_apm_init);
1496
1497
1498
1385void iwl_configure_filter(struct ieee80211_hw *hw, 1499void iwl_configure_filter(struct ieee80211_hw *hw,
1386 unsigned int changed_flags, 1500 unsigned int changed_flags,
1387 unsigned int *total_flags, 1501 unsigned int *total_flags,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a2a580df3d99..a2d526a7b4ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -262,7 +262,12 @@ struct iwl_cfg {
262 const struct iwl_mod_params *mod_params; 262 const struct iwl_mod_params *mod_params;
263 u8 valid_tx_ant; 263 u8 valid_tx_ant;
264 u8 valid_rx_ant; 264 u8 valid_rx_ant;
265 bool need_pll_cfg; 265
266 /* for iwl_apm_init() */
267 u32 pll_cfg_val;
268 bool set_l0s;
269 bool use_bsm;
270
266 bool use_isr_legacy; 271 bool use_isr_legacy;
267 enum iwl_pa_type pa_type; 272 enum iwl_pa_type pa_type;
268 const u16 max_ll_items; 273 const u16 max_ll_items;
@@ -663,6 +668,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
663 struct iwl_rx_mem_buffer *rxb); 668 struct iwl_rx_mem_buffer *rxb);
664void iwl_apm_stop(struct iwl_priv *priv); 669void iwl_apm_stop(struct iwl_priv *priv);
665int iwl_apm_stop_master(struct iwl_priv *priv); 670int iwl_apm_stop_master(struct iwl_priv *priv);
671int iwl_apm_init(struct iwl_priv *priv);
666 672
667void iwl_setup_rxon_timing(struct iwl_priv *priv); 673void iwl_setup_rxon_timing(struct iwl_priv *priv);
668static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 674static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6ba082d6ab16..1378654801ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -85,7 +85,6 @@ extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
85 __le32 *tx_flags); 85 __le32 *tx_flags);
86extern int iwl5000_calc_rssi(struct iwl_priv *priv, 86extern int iwl5000_calc_rssi(struct iwl_priv *priv,
87 struct iwl_rx_phy_res *rx_resp); 87 struct iwl_rx_phy_res *rx_resp);
88extern int iwl5000_apm_init(struct iwl_priv *priv);
89extern void iwl5000_nic_config(struct iwl_priv *priv); 88extern void iwl5000_nic_config(struct iwl_priv *priv);
90extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv); 89extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
91extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, 90extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,