diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-02-06 14:45:53 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-06 14:45:53 -0500 |
commit | 8f0bb5ae3cc3b62a86e4319ee74cea5b602587f1 (patch) | |
tree | e8831d447a90b5fcce421e9271347dde8aed9e02 | |
parent | b9d905784784bbc2d0fd12e7f303d8c79d907b73 (diff) | |
parent | 6fe7dd0db0af18a8792d8551fd19a184f39a732c (diff) |
Merge branch 'wireless-next' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi
30 files changed, 1837 insertions, 1776 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cc04cce11567..8c1466c907ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -84,13 +84,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) | |||
84 | static void iwl1000_nic_config(struct iwl_priv *priv) | 84 | static void iwl1000_nic_config(struct iwl_priv *priv) |
85 | { | 85 | { |
86 | /* set CSR_HW_CONFIG_REG for uCode use */ | 86 | /* set CSR_HW_CONFIG_REG for uCode use */ |
87 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 87 | iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, |
88 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | 88 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | |
89 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | 89 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); |
90 | 90 | ||
91 | /* Setting digital SVR for 1000 card to 1.32V */ | 91 | /* Setting digital SVR for 1000 card to 1.32V */ |
92 | /* locking is acquired in iwl_set_bits_mask_prph() function */ | 92 | /* locking is acquired in iwl_set_bits_mask_prph() function */ |
93 | iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG, | 93 | iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG, |
94 | APMG_SVR_DIGITAL_VOLTAGE_1_32, | 94 | APMG_SVR_DIGITAL_VOLTAGE_1_32, |
95 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); | 95 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); |
96 | } | 96 | } |
@@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
128 | iwlagn_mod_params.num_of_queues; | 128 | iwlagn_mod_params.num_of_queues; |
129 | 129 | ||
130 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | 130 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
131 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
132 | |||
133 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 131 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
134 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; | 132 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; |
135 | 133 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 00db092d8cd0..d4f5f3b87578 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -87,7 +87,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv) | |||
87 | iwl_rf_config(priv); | 87 | iwl_rf_config(priv); |
88 | 88 | ||
89 | if (cfg(priv)->iq_invert) | 89 | if (cfg(priv)->iq_invert) |
90 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, | 90 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, |
91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
92 | } | 92 | } |
93 | 93 | ||
@@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
124 | iwlagn_mod_params.num_of_queues; | 124 | iwlagn_mod_params.num_of_queues; |
125 | 125 | ||
126 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | 126 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
127 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
128 | |||
129 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; | 127 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; |
130 | hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; | 128 | hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; |
131 | 129 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 47fd98b3652c..dc9317d0343e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -73,7 +73,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv) | |||
73 | * (PCIe power is lost before PERST# is asserted), | 73 | * (PCIe power is lost before PERST# is asserted), |
74 | * causing ME FW to lose ownership and not being able to obtain it back. | 74 | * causing ME FW to lose ownership and not being able to obtain it back. |
75 | */ | 75 | */ |
76 | iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG, | 76 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, |
77 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, | 77 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, |
78 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); | 78 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); |
79 | 79 | ||
@@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
170 | iwlagn_mod_params.num_of_queues; | 170 | iwlagn_mod_params.num_of_queues; |
171 | 171 | ||
172 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | 172 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
173 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
174 | |||
175 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 173 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
176 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; | 174 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; |
177 | 175 | ||
@@ -199,8 +197,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) | |||
199 | iwlagn_mod_params.num_of_queues; | 197 | iwlagn_mod_params.num_of_queues; |
200 | 198 | ||
201 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | 199 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
202 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
203 | |||
204 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 200 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
205 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; | 201 | hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; |
206 | 202 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ab62c018fcdb..c36fb858a45b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) | |||
82 | { | 82 | { |
83 | /* Indicate calibration version to uCode. */ | 83 | /* Indicate calibration version to uCode. */ |
84 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) | 84 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) |
85 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, | 85 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, |
86 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 86 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
87 | } | 87 | } |
88 | 88 | ||
@@ -90,9 +90,9 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) | |||
90 | { | 90 | { |
91 | /* Indicate calibration version to uCode. */ | 91 | /* Indicate calibration version to uCode. */ |
92 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) | 92 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) |
93 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, | 93 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, |
94 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 94 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
95 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, | 95 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, |
96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); | 96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); |
97 | } | 97 | } |
98 | 98 | ||
@@ -104,7 +104,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
104 | /* no locking required for register write */ | 104 | /* no locking required for register write */ |
105 | if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { | 105 | if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { |
106 | /* 2x2 IPA phy type */ | 106 | /* 2x2 IPA phy type */ |
107 | iwl_write32(bus(priv), CSR_GP_DRIVER_REG, | 107 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, |
108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | 108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); |
109 | } | 109 | } |
110 | /* do additional nic configuration if needed */ | 110 | /* do additional nic configuration if needed */ |
@@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
145 | iwlagn_mod_params.num_of_queues; | 145 | iwlagn_mod_params.num_of_queues; |
146 | 146 | ||
147 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | 147 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
148 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
149 | |||
150 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; | 148 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; |
151 | hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; | 149 | hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; |
152 | 150 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f127f913e5a6..a14ddab783ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -628,16 +628,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
628 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | 628 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | |
629 | CT_CARD_DISABLED)) { | 629 | CT_CARD_DISABLED)) { |
630 | 630 | ||
631 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | 631 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, |
632 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 632 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
633 | 633 | ||
634 | iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, | 634 | iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, |
635 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 635 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
636 | 636 | ||
637 | if (!(flags & RXON_CARD_DISABLED)) { | 637 | if (!(flags & RXON_CARD_DISABLED)) { |
638 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | 638 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
639 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 639 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
640 | iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, | 640 | iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, |
641 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 641 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
642 | } | 642 | } |
643 | if (flags & CT_CARD_DISABLED) | 643 | if (flags & CT_CARD_DISABLED) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56c6def015a4..c728ed75584e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c | |||
@@ -178,19 +178,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
178 | 178 | ||
179 | if (tt->state == IWL_TI_CT_KILL) { | 179 | if (tt->state == IWL_TI_CT_KILL) { |
180 | if (priv->thermal_throttle.ct_kill_toggle) { | 180 | if (priv->thermal_throttle.ct_kill_toggle) { |
181 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | 181 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
182 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 182 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
183 | priv->thermal_throttle.ct_kill_toggle = false; | 183 | priv->thermal_throttle.ct_kill_toggle = false; |
184 | } else { | 184 | } else { |
185 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | 185 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, |
186 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 186 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
187 | priv->thermal_throttle.ct_kill_toggle = true; | 187 | priv->thermal_throttle.ct_kill_toggle = true; |
188 | } | 188 | } |
189 | iwl_read32(bus(priv), CSR_UCODE_DRV_GP1); | 189 | iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); |
190 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | 190 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
191 | if (!iwl_grab_nic_access(bus(priv))) | 191 | if (!iwl_grab_nic_access(trans(priv))) |
192 | iwl_release_nic_access(bus(priv)); | 192 | iwl_release_nic_access(trans(priv)); |
193 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | 193 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); |
194 | 194 | ||
195 | /* Reschedule the ct_kill timer to occur in | 195 | /* Reschedule the ct_kill timer to occur in |
196 | * CT_KILL_EXIT_DURATION seconds to ensure we get a | 196 | * CT_KILL_EXIT_DURATION seconds to ensure we get a |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 90315c69cdf6..8837171ad553 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
36 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
37 | #include <linux/firmware.h> | ||
38 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
39 | #include <linux/if_arp.h> | 38 | #include <linux/if_arp.h> |
40 | 39 | ||
@@ -42,6 +41,7 @@ | |||
42 | 41 | ||
43 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
44 | 43 | ||
44 | #include "iwl-ucode.h" | ||
45 | #include "iwl-eeprom.h" | 45 | #include "iwl-eeprom.h" |
46 | #include "iwl-wifi.h" | 46 | #include "iwl-wifi.h" |
47 | #include "iwl-dev.h" | 47 | #include "iwl-dev.h" |
@@ -328,14 +328,14 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
328 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); | 328 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); |
329 | 329 | ||
330 | /* Make sure device is powered up for SRAM reads */ | 330 | /* Make sure device is powered up for SRAM reads */ |
331 | spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); | 331 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); |
332 | if (iwl_grab_nic_access(bus(priv))) { | 332 | if (iwl_grab_nic_access(trans(priv))) { |
333 | spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); | 333 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
334 | return; | 334 | return; |
335 | } | 335 | } |
336 | 336 | ||
337 | /* Set starting address; reads will auto-increment */ | 337 | /* Set starting address; reads will auto-increment */ |
338 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); | 338 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); |
339 | rmb(); | 339 | rmb(); |
340 | 340 | ||
341 | /* | 341 | /* |
@@ -352,19 +352,19 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
352 | * place event id # at far right for easier visual parsing. | 352 | * place event id # at far right for easier visual parsing. |
353 | */ | 353 | */ |
354 | for (i = 0; i < num_events; i++) { | 354 | for (i = 0; i < num_events; i++) { |
355 | ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 355 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
356 | time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 356 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
357 | if (mode == 0) { | 357 | if (mode == 0) { |
358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); | 358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); |
359 | } else { | 359 | } else { |
360 | data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 360 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, | 361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, |
362 | data, ev); | 362 | data, ev); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | /* Allow device to power down */ | 365 | /* Allow device to power down */ |
366 | iwl_release_nic_access(bus(priv)); | 366 | iwl_release_nic_access(trans(priv)); |
367 | spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); | 367 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
368 | } | 368 | } |
369 | 369 | ||
370 | static void iwl_continuous_event_trace(struct iwl_priv *priv) | 370 | static void iwl_continuous_event_trace(struct iwl_priv *priv) |
@@ -383,7 +383,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
383 | 383 | ||
384 | base = priv->shrd->device_pointers.log_event_table; | 384 | base = priv->shrd->device_pointers.log_event_table; |
385 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 385 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
386 | iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); | 386 | iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read)); |
387 | 387 | ||
388 | capacity = read.capacity; | 388 | capacity = read.capacity; |
389 | mode = read.mode; | 389 | mode = read.mode; |
@@ -490,7 +490,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
491 | } | 491 | } |
492 | 492 | ||
493 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 493 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
494 | { | 494 | { |
495 | int i; | 495 | int i; |
496 | 496 | ||
@@ -513,6 +513,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
513 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; | 513 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; |
514 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; | 514 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; |
515 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; | 515 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; |
516 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
516 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = | 517 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = |
517 | BIT(NL80211_IFTYPE_ADHOC); | 518 | BIT(NL80211_IFTYPE_ADHOC); |
518 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = | 519 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = |
@@ -547,609 +548,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
547 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 548 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
548 | } | 549 | } |
549 | 550 | ||
550 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
551 | |||
552 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
553 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
554 | |||
555 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | ||
556 | { | ||
557 | const char *name_pre = cfg(priv)->fw_name_pre; | ||
558 | char tag[8]; | ||
559 | |||
560 | if (first) { | ||
561 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
562 | priv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
563 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
564 | } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
565 | #endif | ||
566 | priv->fw_index = cfg(priv)->ucode_api_max; | ||
567 | sprintf(tag, "%d", priv->fw_index); | ||
568 | } else { | ||
569 | priv->fw_index--; | ||
570 | sprintf(tag, "%d", priv->fw_index); | ||
571 | } | ||
572 | |||
573 | if (priv->fw_index < cfg(priv)->ucode_api_min) { | ||
574 | IWL_ERR(priv, "no suitable firmware found!\n"); | ||
575 | return -ENOENT; | ||
576 | } | ||
577 | |||
578 | sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
579 | |||
580 | IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", | ||
581 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
582 | ? "EXPERIMENTAL " : "", | ||
583 | priv->firmware_name); | ||
584 | |||
585 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | ||
586 | bus(priv)->dev, | ||
587 | GFP_KERNEL, priv, iwl_ucode_callback); | ||
588 | } | ||
589 | |||
590 | struct iwlagn_firmware_pieces { | ||
591 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
592 | size_t inst_size, data_size, init_size, init_data_size, | ||
593 | wowlan_inst_size, wowlan_data_size; | ||
594 | |||
595 | u32 build; | ||
596 | |||
597 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
598 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
599 | }; | ||
600 | |||
601 | static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, | ||
602 | const struct firmware *ucode_raw, | ||
603 | struct iwlagn_firmware_pieces *pieces) | ||
604 | { | ||
605 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
606 | u32 api_ver, hdr_size; | ||
607 | const u8 *src; | ||
608 | |||
609 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
610 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
611 | |||
612 | switch (api_ver) { | ||
613 | default: | ||
614 | hdr_size = 28; | ||
615 | if (ucode_raw->size < hdr_size) { | ||
616 | IWL_ERR(priv, "File size too small!\n"); | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | pieces->build = le32_to_cpu(ucode->u.v2.build); | ||
620 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
621 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
622 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
623 | pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); | ||
624 | src = ucode->u.v2.data; | ||
625 | break; | ||
626 | case 0: | ||
627 | case 1: | ||
628 | case 2: | ||
629 | hdr_size = 24; | ||
630 | if (ucode_raw->size < hdr_size) { | ||
631 | IWL_ERR(priv, "File size too small!\n"); | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | pieces->build = 0; | ||
635 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
636 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
637 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
638 | pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); | ||
639 | src = ucode->u.v1.data; | ||
640 | break; | ||
641 | } | ||
642 | |||
643 | /* Verify size of file vs. image size info in file's header */ | ||
644 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
645 | pieces->data_size + pieces->init_size + | ||
646 | pieces->init_data_size) { | ||
647 | |||
648 | IWL_ERR(priv, | ||
649 | "uCode file size %d does not match expected size\n", | ||
650 | (int)ucode_raw->size); | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | |||
654 | pieces->inst = src; | ||
655 | src += pieces->inst_size; | ||
656 | pieces->data = src; | ||
657 | src += pieces->data_size; | ||
658 | pieces->init = src; | ||
659 | src += pieces->init_size; | ||
660 | pieces->init_data = src; | ||
661 | src += pieces->init_data_size; | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int iwlagn_load_firmware(struct iwl_priv *priv, | ||
667 | const struct firmware *ucode_raw, | ||
668 | struct iwlagn_firmware_pieces *pieces, | ||
669 | struct iwlagn_ucode_capabilities *capa) | ||
670 | { | ||
671 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
672 | struct iwl_ucode_tlv *tlv; | ||
673 | size_t len = ucode_raw->size; | ||
674 | const u8 *data; | ||
675 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
676 | int tmp; | ||
677 | u64 alternatives; | ||
678 | u32 tlv_len; | ||
679 | enum iwl_ucode_tlv_type tlv_type; | ||
680 | const u8 *tlv_data; | ||
681 | |||
682 | if (len < sizeof(*ucode)) { | ||
683 | IWL_ERR(priv, "uCode has invalid length: %zd\n", len); | ||
684 | return -EINVAL; | ||
685 | } | ||
686 | |||
687 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
688 | IWL_ERR(priv, "invalid uCode magic: 0X%x\n", | ||
689 | le32_to_cpu(ucode->magic)); | ||
690 | return -EINVAL; | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * Check which alternatives are present, and "downgrade" | ||
695 | * when the chosen alternative is not present, warning | ||
696 | * the user when that happens. Some files may not have | ||
697 | * any alternatives, so don't warn in that case. | ||
698 | */ | ||
699 | alternatives = le64_to_cpu(ucode->alternatives); | ||
700 | tmp = wanted_alternative; | ||
701 | if (wanted_alternative > 63) | ||
702 | wanted_alternative = 63; | ||
703 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
704 | wanted_alternative--; | ||
705 | if (wanted_alternative && wanted_alternative != tmp) | ||
706 | IWL_WARN(priv, | ||
707 | "uCode alternative %d not available, choosing %d\n", | ||
708 | tmp, wanted_alternative); | ||
709 | |||
710 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
711 | pieces->build = le32_to_cpu(ucode->build); | ||
712 | data = ucode->data; | ||
713 | |||
714 | len -= sizeof(*ucode); | ||
715 | |||
716 | while (len >= sizeof(*tlv)) { | ||
717 | u16 tlv_alt; | ||
718 | |||
719 | len -= sizeof(*tlv); | ||
720 | tlv = (void *)data; | ||
721 | |||
722 | tlv_len = le32_to_cpu(tlv->length); | ||
723 | tlv_type = le16_to_cpu(tlv->type); | ||
724 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
725 | tlv_data = tlv->data; | ||
726 | |||
727 | if (len < tlv_len) { | ||
728 | IWL_ERR(priv, "invalid TLV len: %zd/%u\n", | ||
729 | len, tlv_len); | ||
730 | return -EINVAL; | ||
731 | } | ||
732 | len -= ALIGN(tlv_len, 4); | ||
733 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
734 | |||
735 | /* | ||
736 | * Alternative 0 is always valid. | ||
737 | * | ||
738 | * Skip alternative TLVs that are not selected. | ||
739 | */ | ||
740 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
741 | continue; | ||
742 | |||
743 | switch (tlv_type) { | ||
744 | case IWL_UCODE_TLV_INST: | ||
745 | pieces->inst = tlv_data; | ||
746 | pieces->inst_size = tlv_len; | ||
747 | break; | ||
748 | case IWL_UCODE_TLV_DATA: | ||
749 | pieces->data = tlv_data; | ||
750 | pieces->data_size = tlv_len; | ||
751 | break; | ||
752 | case IWL_UCODE_TLV_INIT: | ||
753 | pieces->init = tlv_data; | ||
754 | pieces->init_size = tlv_len; | ||
755 | break; | ||
756 | case IWL_UCODE_TLV_INIT_DATA: | ||
757 | pieces->init_data = tlv_data; | ||
758 | pieces->init_data_size = tlv_len; | ||
759 | break; | ||
760 | case IWL_UCODE_TLV_BOOT: | ||
761 | IWL_ERR(priv, "Found unexpected BOOT ucode\n"); | ||
762 | break; | ||
763 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
764 | if (tlv_len != sizeof(u32)) | ||
765 | goto invalid_tlv_len; | ||
766 | capa->max_probe_length = | ||
767 | le32_to_cpup((__le32 *)tlv_data); | ||
768 | break; | ||
769 | case IWL_UCODE_TLV_PAN: | ||
770 | if (tlv_len) | ||
771 | goto invalid_tlv_len; | ||
772 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
773 | break; | ||
774 | case IWL_UCODE_TLV_FLAGS: | ||
775 | /* must be at least one u32 */ | ||
776 | if (tlv_len < sizeof(u32)) | ||
777 | goto invalid_tlv_len; | ||
778 | /* and a proper number of u32s */ | ||
779 | if (tlv_len % sizeof(u32)) | ||
780 | goto invalid_tlv_len; | ||
781 | /* | ||
782 | * This driver only reads the first u32 as | ||
783 | * right now no more features are defined, | ||
784 | * if that changes then either the driver | ||
785 | * will not work with the new firmware, or | ||
786 | * it'll not take advantage of new features. | ||
787 | */ | ||
788 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
789 | break; | ||
790 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
791 | if (tlv_len != sizeof(u32)) | ||
792 | goto invalid_tlv_len; | ||
793 | pieces->init_evtlog_ptr = | ||
794 | le32_to_cpup((__le32 *)tlv_data); | ||
795 | break; | ||
796 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
797 | if (tlv_len != sizeof(u32)) | ||
798 | goto invalid_tlv_len; | ||
799 | pieces->init_evtlog_size = | ||
800 | le32_to_cpup((__le32 *)tlv_data); | ||
801 | break; | ||
802 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
803 | if (tlv_len != sizeof(u32)) | ||
804 | goto invalid_tlv_len; | ||
805 | pieces->init_errlog_ptr = | ||
806 | le32_to_cpup((__le32 *)tlv_data); | ||
807 | break; | ||
808 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
809 | if (tlv_len != sizeof(u32)) | ||
810 | goto invalid_tlv_len; | ||
811 | pieces->inst_evtlog_ptr = | ||
812 | le32_to_cpup((__le32 *)tlv_data); | ||
813 | break; | ||
814 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
815 | if (tlv_len != sizeof(u32)) | ||
816 | goto invalid_tlv_len; | ||
817 | pieces->inst_evtlog_size = | ||
818 | le32_to_cpup((__le32 *)tlv_data); | ||
819 | break; | ||
820 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
821 | if (tlv_len != sizeof(u32)) | ||
822 | goto invalid_tlv_len; | ||
823 | pieces->inst_errlog_ptr = | ||
824 | le32_to_cpup((__le32 *)tlv_data); | ||
825 | break; | ||
826 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
827 | if (tlv_len) | ||
828 | goto invalid_tlv_len; | ||
829 | priv->enhance_sensitivity_table = true; | ||
830 | break; | ||
831 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
832 | pieces->wowlan_inst = tlv_data; | ||
833 | pieces->wowlan_inst_size = tlv_len; | ||
834 | break; | ||
835 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
836 | pieces->wowlan_data = tlv_data; | ||
837 | pieces->wowlan_data_size = tlv_len; | ||
838 | break; | ||
839 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
840 | if (tlv_len != sizeof(u32)) | ||
841 | goto invalid_tlv_len; | ||
842 | capa->standard_phy_calibration_size = | ||
843 | le32_to_cpup((__le32 *)tlv_data); | ||
844 | break; | ||
845 | default: | ||
846 | IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); | ||
847 | break; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | if (len) { | ||
852 | IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); | ||
853 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); | ||
854 | return -EINVAL; | ||
855 | } | ||
856 | |||
857 | return 0; | ||
858 | |||
859 | invalid_tlv_len: | ||
860 | IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
861 | iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); | ||
862 | |||
863 | return -EINVAL; | ||
864 | } | ||
865 | |||
866 | /** | ||
867 | * iwl_ucode_callback - callback when firmware was loaded | ||
868 | * | ||
869 | * If loaded successfully, copies the firmware into buffers | ||
870 | * for the card to fetch (via DMA). | ||
871 | */ | ||
872 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
873 | { | ||
874 | struct iwl_priv *priv = context; | ||
875 | struct iwl_ucode_header *ucode; | ||
876 | int err; | ||
877 | struct iwlagn_firmware_pieces pieces; | ||
878 | const unsigned int api_max = cfg(priv)->ucode_api_max; | ||
879 | unsigned int api_ok = cfg(priv)->ucode_api_ok; | ||
880 | const unsigned int api_min = cfg(priv)->ucode_api_min; | ||
881 | u32 api_ver; | ||
882 | char buildstr[25]; | ||
883 | u32 build; | ||
884 | struct iwlagn_ucode_capabilities ucode_capa = { | ||
885 | .max_probe_length = 200, | ||
886 | .standard_phy_calibration_size = | ||
887 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, | ||
888 | }; | ||
889 | |||
890 | if (!api_ok) | ||
891 | api_ok = api_max; | ||
892 | |||
893 | memset(&pieces, 0, sizeof(pieces)); | ||
894 | |||
895 | if (!ucode_raw) { | ||
896 | if (priv->fw_index <= api_ok) | ||
897 | IWL_ERR(priv, | ||
898 | "request for firmware file '%s' failed.\n", | ||
899 | priv->firmware_name); | ||
900 | goto try_again; | ||
901 | } | ||
902 | |||
903 | IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
904 | priv->firmware_name, ucode_raw->size); | ||
905 | |||
906 | /* Make sure that we got at least the API version number */ | ||
907 | if (ucode_raw->size < 4) { | ||
908 | IWL_ERR(priv, "File size way too small!\n"); | ||
909 | goto try_again; | ||
910 | } | ||
911 | |||
912 | /* Data from ucode file: header followed by uCode images */ | ||
913 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
914 | |||
915 | if (ucode->ver) | ||
916 | err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); | ||
917 | else | ||
918 | err = iwlagn_load_firmware(priv, ucode_raw, &pieces, | ||
919 | &ucode_capa); | ||
920 | |||
921 | if (err) | ||
922 | goto try_again; | ||
923 | |||
924 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
925 | build = pieces.build; | ||
926 | |||
927 | /* | ||
928 | * api_ver should match the api version forming part of the | ||
929 | * firmware filename ... but we don't check for that and only rely | ||
930 | * on the API version read from firmware header from here on forward | ||
931 | */ | ||
932 | /* no api version check required for experimental uCode */ | ||
933 | if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
934 | if (api_ver < api_min || api_ver > api_max) { | ||
935 | IWL_ERR(priv, | ||
936 | "Driver unable to support your firmware API. " | ||
937 | "Driver supports v%u, firmware is v%u.\n", | ||
938 | api_max, api_ver); | ||
939 | goto try_again; | ||
940 | } | ||
941 | |||
942 | if (api_ver < api_ok) { | ||
943 | if (api_ok != api_max) | ||
944 | IWL_ERR(priv, "Firmware has old API version, " | ||
945 | "expected v%u through v%u, got v%u.\n", | ||
946 | api_ok, api_max, api_ver); | ||
947 | else | ||
948 | IWL_ERR(priv, "Firmware has old API version, " | ||
949 | "expected v%u, got v%u.\n", | ||
950 | api_max, api_ver); | ||
951 | IWL_ERR(priv, "New firmware can be obtained from " | ||
952 | "http://www.intellinuxwireless.org/.\n"); | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (build) | ||
957 | sprintf(buildstr, " build %u%s", build, | ||
958 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
959 | ? " (EXP)" : ""); | ||
960 | else | ||
961 | buildstr[0] = '\0'; | ||
962 | |||
963 | IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", | ||
964 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
965 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
966 | IWL_UCODE_API(priv->ucode_ver), | ||
967 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
968 | buildstr); | ||
969 | |||
970 | snprintf(priv->hw->wiphy->fw_version, | ||
971 | sizeof(priv->hw->wiphy->fw_version), | ||
972 | "%u.%u.%u.%u%s", | ||
973 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
974 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
975 | IWL_UCODE_API(priv->ucode_ver), | ||
976 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
977 | buildstr); | ||
978 | |||
979 | /* | ||
980 | * For any of the failures below (before allocating pci memory) | ||
981 | * we will try to load a version with a smaller API -- maybe the | ||
982 | * user just got a corrupted version of the latest API. | ||
983 | */ | ||
984 | |||
985 | IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", | ||
986 | priv->ucode_ver); | ||
987 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", | ||
988 | pieces.inst_size); | ||
989 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", | ||
990 | pieces.data_size); | ||
991 | IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", | ||
992 | pieces.init_size); | ||
993 | IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", | ||
994 | pieces.init_data_size); | ||
995 | |||
996 | /* Verify that uCode images will fit in card's SRAM */ | ||
997 | if (pieces.inst_size > hw_params(priv).max_inst_size) { | ||
998 | IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", | ||
999 | pieces.inst_size); | ||
1000 | goto try_again; | ||
1001 | } | ||
1002 | |||
1003 | if (pieces.data_size > hw_params(priv).max_data_size) { | ||
1004 | IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", | ||
1005 | pieces.data_size); | ||
1006 | goto try_again; | ||
1007 | } | ||
1008 | |||
1009 | if (pieces.init_size > hw_params(priv).max_inst_size) { | ||
1010 | IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", | ||
1011 | pieces.init_size); | ||
1012 | goto try_again; | ||
1013 | } | ||
1014 | |||
1015 | if (pieces.init_data_size > hw_params(priv).max_data_size) { | ||
1016 | IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", | ||
1017 | pieces.init_data_size); | ||
1018 | goto try_again; | ||
1019 | } | ||
1020 | |||
1021 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
1022 | |||
1023 | /* Runtime instructions and 2 copies of data: | ||
1024 | * 1) unmodified from disk | ||
1025 | * 2) backup cache for save/restore during power-downs */ | ||
1026 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, | ||
1027 | pieces.inst, pieces.inst_size)) | ||
1028 | goto err_pci_alloc; | ||
1029 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, | ||
1030 | pieces.data, pieces.data_size)) | ||
1031 | goto err_pci_alloc; | ||
1032 | |||
1033 | /* Initialization instructions and data */ | ||
1034 | if (pieces.init_size && pieces.init_data_size) { | ||
1035 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, | ||
1036 | pieces.init, pieces.init_size)) | ||
1037 | goto err_pci_alloc; | ||
1038 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, | ||
1039 | pieces.init_data, pieces.init_data_size)) | ||
1040 | goto err_pci_alloc; | ||
1041 | } | ||
1042 | |||
1043 | /* WoWLAN instructions and data */ | ||
1044 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
1045 | if (iwl_alloc_fw_desc(bus(priv), | ||
1046 | &trans(priv)->ucode_wowlan.code, | ||
1047 | pieces.wowlan_inst, | ||
1048 | pieces.wowlan_inst_size)) | ||
1049 | goto err_pci_alloc; | ||
1050 | if (iwl_alloc_fw_desc(bus(priv), | ||
1051 | &trans(priv)->ucode_wowlan.data, | ||
1052 | pieces.wowlan_data, | ||
1053 | pieces.wowlan_data_size)) | ||
1054 | goto err_pci_alloc; | ||
1055 | } | ||
1056 | |||
1057 | /* Now that we can no longer fail, copy information */ | ||
1058 | |||
1059 | /* | ||
1060 | * The (size - 16) / 12 formula is based on the information recorded | ||
1061 | * for each event, which is of mode 1 (including timestamp) for all | ||
1062 | * new microcodes that include this information. | ||
1063 | */ | ||
1064 | priv->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
1065 | if (pieces.init_evtlog_size) | ||
1066 | priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
1067 | else | ||
1068 | priv->init_evtlog_size = | ||
1069 | cfg(priv)->base_params->max_event_log_size; | ||
1070 | priv->init_errlog_ptr = pieces.init_errlog_ptr; | ||
1071 | priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
1072 | if (pieces.inst_evtlog_size) | ||
1073 | priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
1074 | else | ||
1075 | priv->inst_evtlog_size = | ||
1076 | cfg(priv)->base_params->max_event_log_size; | ||
1077 | priv->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
1078 | #ifndef CONFIG_IWLWIFI_P2P | ||
1079 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1080 | #endif | ||
1081 | |||
1082 | priv->new_scan_threshold_behaviour = | ||
1083 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | ||
1084 | |||
1085 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | ||
1086 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1087 | |||
1088 | /* | ||
1089 | * if not PAN, then don't support P2P -- might be a uCode | ||
1090 | * packaging bug or due to the eeprom check above | ||
1091 | */ | ||
1092 | if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1093 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | ||
1094 | |||
1095 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1096 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1097 | priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1098 | } else { | ||
1099 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1100 | priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1101 | } | ||
1102 | /* | ||
1103 | * figure out the offset of chain noise reset and gain commands | ||
1104 | * base on the size of standard phy calibration commands table size | ||
1105 | */ | ||
1106 | if (ucode_capa.standard_phy_calibration_size > | ||
1107 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
1108 | ucode_capa.standard_phy_calibration_size = | ||
1109 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
1110 | |||
1111 | priv->phy_calib_chain_noise_reset_cmd = | ||
1112 | ucode_capa.standard_phy_calibration_size; | ||
1113 | priv->phy_calib_chain_noise_gain_cmd = | ||
1114 | ucode_capa.standard_phy_calibration_size + 1; | ||
1115 | |||
1116 | /* initialize all valid contexts */ | ||
1117 | iwl_init_context(priv, ucode_capa.flags); | ||
1118 | |||
1119 | /************************************************** | ||
1120 | * This is still part of probe() in a sense... | ||
1121 | * | ||
1122 | * 9. Setup and register with mac80211 and debugfs | ||
1123 | **************************************************/ | ||
1124 | err = iwlagn_mac_setup_register(priv, &ucode_capa); | ||
1125 | if (err) | ||
1126 | goto out_unbind; | ||
1127 | |||
1128 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
1129 | if (err) | ||
1130 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
1131 | |||
1132 | /* We have our copies now, allow OS release its copies */ | ||
1133 | release_firmware(ucode_raw); | ||
1134 | complete(&priv->firmware_loading_complete); | ||
1135 | return; | ||
1136 | |||
1137 | try_again: | ||
1138 | /* try next, if any */ | ||
1139 | if (iwl_request_firmware(priv, false)) | ||
1140 | goto out_unbind; | ||
1141 | release_firmware(ucode_raw); | ||
1142 | return; | ||
1143 | |||
1144 | err_pci_alloc: | ||
1145 | IWL_ERR(priv, "failed to allocate pci memory\n"); | ||
1146 | iwl_dealloc_ucode(trans(priv)); | ||
1147 | out_unbind: | ||
1148 | complete(&priv->firmware_loading_complete); | ||
1149 | device_release_driver(bus(priv)->dev); | ||
1150 | release_firmware(ucode_raw); | ||
1151 | } | ||
1152 | |||
1153 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 551 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) |
1154 | { | 552 | { |
1155 | struct iwl_ct_kill_config cmd; | 553 | struct iwl_ct_kill_config cmd; |
@@ -1158,7 +556,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
1158 | int ret = 0; | 556 | int ret = 0; |
1159 | 557 | ||
1160 | spin_lock_irqsave(&priv->shrd->lock, flags); | 558 | spin_lock_irqsave(&priv->shrd->lock, flags); |
1161 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | 559 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
1162 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 560 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
1163 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 561 | spin_unlock_irqrestore(&priv->shrd->lock, flags); |
1164 | priv->thermal_throttle.ct_kill_toggle = false; | 562 | priv->thermal_throttle.ct_kill_toggle = false; |
@@ -1243,9 +641,6 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1243 | int ret = 0; | 641 | int ret = 0; |
1244 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 642 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
1245 | 643 | ||
1246 | /*TODO: this should go to the transport layer */ | ||
1247 | iwl_reset_ict(trans(priv)); | ||
1248 | |||
1249 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 644 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
1250 | 645 | ||
1251 | /* After the ALIVE response, we can send host commands to the uCode */ | 646 | /* After the ALIVE response, we can send host commands to the uCode */ |
@@ -1692,13 +1087,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1692 | #endif | 1087 | #endif |
1693 | } | 1088 | } |
1694 | 1089 | ||
1695 | |||
1696 | |||
1697 | static u32 iwl_hw_detect(struct iwl_priv *priv) | ||
1698 | { | ||
1699 | return iwl_read32(bus(priv), CSR_HW_REV); | ||
1700 | } | ||
1701 | |||
1702 | /* Size of one Rx buffer in host DRAM */ | 1090 | /* Size of one Rx buffer in host DRAM */ |
1703 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | 1091 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) |
1704 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | 1092 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) |
@@ -1730,32 +1118,32 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
1730 | 1118 | ||
1731 | static void iwl_debug_config(struct iwl_priv *priv) | 1119 | static void iwl_debug_config(struct iwl_priv *priv) |
1732 | { | 1120 | { |
1733 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG " | 1121 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " |
1734 | #ifdef CONFIG_IWLWIFI_DEBUG | 1122 | #ifdef CONFIG_IWLWIFI_DEBUG |
1735 | "enabled\n"); | 1123 | "enabled\n"); |
1736 | #else | 1124 | #else |
1737 | "disabled\n"); | 1125 | "disabled\n"); |
1738 | #endif | 1126 | #endif |
1739 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " | 1127 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " |
1740 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1128 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1741 | "enabled\n"); | 1129 | "enabled\n"); |
1742 | #else | 1130 | #else |
1743 | "disabled\n"); | 1131 | "disabled\n"); |
1744 | #endif | 1132 | #endif |
1745 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " | 1133 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " |
1746 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | 1134 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
1747 | "enabled\n"); | 1135 | "enabled\n"); |
1748 | #else | 1136 | #else |
1749 | "disabled\n"); | 1137 | "disabled\n"); |
1750 | #endif | 1138 | #endif |
1751 | 1139 | ||
1752 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " | 1140 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " |
1753 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 1141 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
1754 | "enabled\n"); | 1142 | "enabled\n"); |
1755 | #else | 1143 | #else |
1756 | "disabled\n"); | 1144 | "disabled\n"); |
1757 | #endif | 1145 | #endif |
1758 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P " | 1146 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P " |
1759 | #ifdef CONFIG_IWLWIFI_P2P | 1147 | #ifdef CONFIG_IWLWIFI_P2P |
1760 | "enabled\n"); | 1148 | "enabled\n"); |
1761 | #else | 1149 | #else |
@@ -1770,7 +1158,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1770 | struct iwl_priv *priv; | 1158 | struct iwl_priv *priv; |
1771 | struct ieee80211_hw *hw; | 1159 | struct ieee80211_hw *hw; |
1772 | u16 num_mac; | 1160 | u16 num_mac; |
1773 | u32 hw_rev; | ||
1774 | 1161 | ||
1775 | /************************ | 1162 | /************************ |
1776 | * 1. Allocating HW data | 1163 | * 1. Allocating HW data |
@@ -1783,22 +1170,14 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1783 | } | 1170 | } |
1784 | 1171 | ||
1785 | priv = hw->priv; | 1172 | priv = hw->priv; |
1786 | priv->shrd = &priv->_shrd; | 1173 | priv->shrd = bus->shrd; |
1787 | bus->shrd = priv->shrd; | ||
1788 | priv->shrd->bus = bus; | ||
1789 | priv->shrd->priv = priv; | 1174 | priv->shrd->priv = priv; |
1790 | 1175 | ||
1791 | priv->shrd->trans = trans_ops->alloc(priv->shrd); | ||
1792 | if (priv->shrd->trans == NULL) { | ||
1793 | err = -ENOMEM; | ||
1794 | goto out_free_traffic_mem; | ||
1795 | } | ||
1796 | |||
1797 | /* At this point both hw and priv are allocated. */ | 1176 | /* At this point both hw and priv are allocated. */ |
1798 | 1177 | ||
1799 | SET_IEEE80211_DEV(hw, bus(priv)->dev); | 1178 | SET_IEEE80211_DEV(hw, trans(priv)->dev); |
1800 | 1179 | ||
1801 | /* what debugging capabilities we have */ | 1180 | /* show what debugging capabilities we have */ |
1802 | iwl_debug_config(priv); | 1181 | iwl_debug_config(priv); |
1803 | 1182 | ||
1804 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 1183 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
@@ -1821,41 +1200,29 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1821 | /* these spin locks will be used in apm_ops.init and EEPROM access | 1200 | /* these spin locks will be used in apm_ops.init and EEPROM access |
1822 | * we should init now | 1201 | * we should init now |
1823 | */ | 1202 | */ |
1824 | spin_lock_init(&bus(priv)->reg_lock); | 1203 | spin_lock_init(&trans(priv)->reg_lock); |
1825 | spin_lock_init(&priv->shrd->lock); | 1204 | spin_lock_init(&priv->shrd->lock); |
1826 | 1205 | ||
1827 | /* | ||
1828 | * stop and reset the on-board processor just in case it is in a | ||
1829 | * strange state ... like being left stranded by a primary kernel | ||
1830 | * and this is now the kdump kernel trying to start up | ||
1831 | */ | ||
1832 | iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1833 | |||
1834 | /*********************** | 1206 | /*********************** |
1835 | * 3. Read REV register | 1207 | * 3. Read REV register |
1836 | ***********************/ | 1208 | ***********************/ |
1837 | hw_rev = iwl_hw_detect(priv); | ||
1838 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1209 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
1839 | cfg(priv)->name, hw_rev); | 1210 | cfg(priv)->name, trans(priv)->hw_rev); |
1840 | 1211 | ||
1841 | err = iwl_trans_request_irq(trans(priv)); | 1212 | err = iwl_trans_start_hw(trans(priv)); |
1842 | if (err) | 1213 | if (err) |
1843 | goto out_free_trans; | 1214 | goto out_free_traffic_mem; |
1844 | |||
1845 | if (iwl_trans_prepare_card_hw(trans(priv))) { | ||
1846 | err = -EIO; | ||
1847 | IWL_WARN(priv, "Failed, HW not ready\n"); | ||
1848 | goto out_free_trans; | ||
1849 | } | ||
1850 | 1215 | ||
1851 | /***************** | 1216 | /***************** |
1852 | * 4. Read EEPROM | 1217 | * 4. Read EEPROM |
1853 | *****************/ | 1218 | *****************/ |
1854 | /* Read the EEPROM */ | 1219 | /* Read the EEPROM */ |
1855 | err = iwl_eeprom_init(priv, hw_rev); | 1220 | err = iwl_eeprom_init(priv, trans(priv)->hw_rev); |
1221 | /* Reset chip to save power until we load uCode during "up". */ | ||
1222 | iwl_trans_stop_hw(trans(priv)); | ||
1856 | if (err) { | 1223 | if (err) { |
1857 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 1224 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
1858 | goto out_free_trans; | 1225 | goto out_free_traffic_mem; |
1859 | } | 1226 | } |
1860 | err = iwl_eeprom_check_version(priv); | 1227 | err = iwl_eeprom_check_version(priv); |
1861 | if (err) | 1228 | if (err) |
@@ -1903,22 +1270,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1903 | iwl_setup_rx_handlers(priv); | 1270 | iwl_setup_rx_handlers(priv); |
1904 | iwl_testmode_init(priv); | 1271 | iwl_testmode_init(priv); |
1905 | 1272 | ||
1906 | /********************************************* | ||
1907 | * 8. Enable interrupts | ||
1908 | *********************************************/ | ||
1909 | |||
1910 | iwl_enable_rfkill_int(priv); | ||
1911 | |||
1912 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
1913 | if (iwl_read32(bus(priv), | ||
1914 | CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
1915 | clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | ||
1916 | else | ||
1917 | set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | ||
1918 | |||
1919 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | ||
1920 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | ||
1921 | |||
1922 | iwl_power_initialize(priv); | 1273 | iwl_power_initialize(priv); |
1923 | iwl_tt_initialize(priv); | 1274 | iwl_tt_initialize(priv); |
1924 | 1275 | ||
@@ -1936,8 +1287,6 @@ out_destroy_workqueue: | |||
1936 | iwl_uninit_drv(priv); | 1287 | iwl_uninit_drv(priv); |
1937 | out_free_eeprom: | 1288 | out_free_eeprom: |
1938 | iwl_eeprom_free(priv->shrd); | 1289 | iwl_eeprom_free(priv->shrd); |
1939 | out_free_trans: | ||
1940 | iwl_trans_free(trans(priv)); | ||
1941 | out_free_traffic_mem: | 1290 | out_free_traffic_mem: |
1942 | iwl_free_traffic_mem(priv); | 1291 | iwl_free_traffic_mem(priv); |
1943 | ieee80211_free_hw(priv->hw); | 1292 | ieee80211_free_hw(priv->hw); |
@@ -1981,8 +1330,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) | |||
1981 | priv->shrd->workqueue = NULL; | 1330 | priv->shrd->workqueue = NULL; |
1982 | iwl_free_traffic_mem(priv); | 1331 | iwl_free_traffic_mem(priv); |
1983 | 1332 | ||
1984 | iwl_trans_free(trans(priv)); | ||
1985 | |||
1986 | iwl_uninit_drv(priv); | 1333 | iwl_uninit_drv(priv); |
1987 | 1334 | ||
1988 | dev_kfree_skb(priv->beacon_skb); | 1335 | dev_kfree_skb(priv->beacon_skb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 39cbe1a1577c..37c325ff6e8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -73,8 +73,6 @@ struct iwlagn_ucode_capabilities { | |||
73 | 73 | ||
74 | extern struct ieee80211_ops iwlagn_hw_ops; | 74 | extern struct ieee80211_ops iwlagn_hw_ops; |
75 | 75 | ||
76 | int iwl_reset_ict(struct iwl_trans *trans); | ||
77 | |||
78 | static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) | 76 | static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) |
79 | { | 77 | { |
80 | hdr->op_code = cmd; | 78 | hdr->op_code = cmd; |
@@ -109,6 +107,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, | |||
109 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 107 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
110 | struct iwl_rx_mem_buffer *rxb, | 108 | struct iwl_rx_mem_buffer *rxb, |
111 | struct iwl_device_cmd *cmd); | 109 | struct iwl_device_cmd *cmd); |
110 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | ||
112 | 111 | ||
113 | /* lib */ | 112 | /* lib */ |
114 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 113 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 941b9cb23442..30965e0e8ab4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h | |||
@@ -119,87 +119,23 @@ struct iwl_shared; | |||
119 | struct iwl_bus; | 119 | struct iwl_bus; |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * struct iwl_bus_ops - bus specific operations | ||
123 | * @get_pm_support: must returns true if the bus can go to sleep | ||
124 | * @apm_config: will be called during the config of the APM | ||
125 | * @get_hw_id_string: prints the hw_id in the provided buffer | ||
126 | * @get_hw_id: get hw_id in u32 | ||
127 | * @write8: write a byte to register at offset ofs | ||
128 | * @write32: write a dword to register at offset ofs | ||
129 | * @wread32: read a dword at register at offset ofs | ||
130 | */ | ||
131 | struct iwl_bus_ops { | ||
132 | bool (*get_pm_support)(struct iwl_bus *bus); | ||
133 | void (*apm_config)(struct iwl_bus *bus); | ||
134 | void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); | ||
135 | u32 (*get_hw_id)(struct iwl_bus *bus); | ||
136 | void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); | ||
137 | void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); | ||
138 | u32 (*read32)(struct iwl_bus *bus, u32 ofs); | ||
139 | }; | ||
140 | |||
141 | /** | ||
142 | * struct iwl_bus - bus common data | 122 | * struct iwl_bus - bus common data |
143 | * | 123 | * |
144 | * This data is common to all bus layer implementations. | 124 | * This data is common to all bus layer implementations. |
145 | * | 125 | * |
146 | * @dev - pointer to struct device * that represents the device | ||
147 | * @ops - pointer to iwl_bus_ops | 126 | * @ops - pointer to iwl_bus_ops |
148 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 127 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
149 | * NB: for the time being this needs to be set by the upper layer since | 128 | * NB: for the time being this needs to be set by the upper layer since |
150 | * it allocates the shared data | 129 | * it allocates the shared data |
151 | * @irq - the irq number for the device | ||
152 | * @reg_lock - protect hw register access | ||
153 | */ | 130 | */ |
154 | struct iwl_bus { | 131 | struct iwl_bus { |
155 | struct device *dev; | ||
156 | const struct iwl_bus_ops *ops; | ||
157 | struct iwl_shared *shrd; | 132 | struct iwl_shared *shrd; |
158 | 133 | ||
159 | unsigned int irq; | ||
160 | spinlock_t reg_lock; | ||
161 | |||
162 | /* pointer to bus specific struct */ | 134 | /* pointer to bus specific struct */ |
163 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 135 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
164 | char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); | 136 | char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); |
165 | }; | 137 | }; |
166 | 138 | ||
167 | static inline bool bus_get_pm_support(struct iwl_bus *bus) | ||
168 | { | ||
169 | return bus->ops->get_pm_support(bus); | ||
170 | } | ||
171 | |||
172 | static inline void bus_apm_config(struct iwl_bus *bus) | ||
173 | { | ||
174 | bus->ops->apm_config(bus); | ||
175 | } | ||
176 | |||
177 | static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], | ||
178 | int buf_len) | ||
179 | { | ||
180 | bus->ops->get_hw_id_string(bus, buf, buf_len); | ||
181 | } | ||
182 | |||
183 | static inline u32 bus_get_hw_id(struct iwl_bus *bus) | ||
184 | { | ||
185 | return bus->ops->get_hw_id(bus); | ||
186 | } | ||
187 | |||
188 | static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) | ||
189 | { | ||
190 | bus->ops->write8(bus, ofs, val); | ||
191 | } | ||
192 | |||
193 | static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val) | ||
194 | { | ||
195 | bus->ops->write32(bus, ofs, val); | ||
196 | } | ||
197 | |||
198 | static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs) | ||
199 | { | ||
200 | return bus->ops->read32(bus, ofs); | ||
201 | } | ||
202 | |||
203 | /***************************************************** | 139 | /***************************************************** |
204 | * Bus layer registration functions | 140 | * Bus layer registration functions |
205 | ******************************************************/ | 141 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7d6eef96454a..0677b3dfbfb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -203,10 +203,9 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
203 | 203 | ||
204 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 204 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
205 | cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { | 205 | cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
206 | char buf[32]; | ||
207 | bus_get_hw_id_string(bus(priv), buf, sizeof(buf)); | ||
208 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 206 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
209 | "Please send your %s to maintainer.\n", buf); | 207 | "Please send your %s to maintainer.\n", |
208 | trans(priv)->hw_id_str); | ||
210 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | 209 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
211 | } | 210 | } |
212 | 211 | ||
@@ -883,129 +882,6 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
883 | } | 882 | } |
884 | } | 883 | } |
885 | 884 | ||
886 | static int iwl_apm_stop_master(struct iwl_priv *priv) | ||
887 | { | ||
888 | int ret = 0; | ||
889 | |||
890 | /* stop device's busmaster DMA activity */ | ||
891 | iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); | ||
892 | |||
893 | ret = iwl_poll_bit(bus(priv), CSR_RESET, | ||
894 | CSR_RESET_REG_FLAG_MASTER_DISABLED, | ||
895 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
896 | if (ret) | ||
897 | IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n"); | ||
898 | |||
899 | IWL_DEBUG_INFO(priv, "stop master\n"); | ||
900 | |||
901 | return ret; | ||
902 | } | ||
903 | |||
904 | void iwl_apm_stop(struct iwl_priv *priv) | ||
905 | { | ||
906 | IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); | ||
907 | |||
908 | clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); | ||
909 | |||
910 | /* Stop device's DMA activity */ | ||
911 | iwl_apm_stop_master(priv); | ||
912 | |||
913 | /* Reset the entire device */ | ||
914 | iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
915 | |||
916 | udelay(10); | ||
917 | |||
918 | /* | ||
919 | * Clear "initialization complete" bit to move adapter from | ||
920 | * D0A* (powered-up Active) --> D0U* (Uninitialized) state. | ||
921 | */ | ||
922 | iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
923 | } | ||
924 | |||
925 | |||
926 | /* | ||
927 | * Start up NIC's basic functionality after it has been reset | ||
928 | * (e.g. after platform boot, or shutdown via iwl_apm_stop()) | ||
929 | * NOTE: This does not load uCode nor start the embedded processor | ||
930 | */ | ||
931 | int iwl_apm_init(struct iwl_priv *priv) | ||
932 | { | ||
933 | int ret = 0; | ||
934 | IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); | ||
935 | |||
936 | /* | ||
937 | * Use "set_bit" below rather than "write", to preserve any hardware | ||
938 | * bits already set by default after reset. | ||
939 | */ | ||
940 | |||
941 | /* Disable L0S exit timer (platform NMI Work/Around) */ | ||
942 | iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, | ||
943 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
944 | |||
945 | /* | ||
946 | * Disable L0s without affecting L1; | ||
947 | * don't wait for ICH L0s (ICH bug W/A) | ||
948 | */ | ||
949 | iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, | ||
950 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
951 | |||
952 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ | ||
953 | iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); | ||
954 | |||
955 | /* | ||
956 | * Enable HAP INTA (interrupt from management bus) to | ||
957 | * wake device's PCI Express link L1a -> L0s | ||
958 | */ | ||
959 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | ||
960 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | ||
961 | |||
962 | bus_apm_config(bus(priv)); | ||
963 | |||
964 | /* Configure analog phase-lock-loop before activating to D0A */ | ||
965 | if (cfg(priv)->base_params->pll_cfg_val) | ||
966 | iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, | ||
967 | cfg(priv)->base_params->pll_cfg_val); | ||
968 | |||
969 | /* | ||
970 | * Set "initialization complete" bit to move adapter from | ||
971 | * D0U* --> D0A* (powered-up active) state. | ||
972 | */ | ||
973 | iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
974 | |||
975 | /* | ||
976 | * Wait for clock stabilization; once stabilized, access to | ||
977 | * device-internal resources is supported, e.g. iwl_write_prph() | ||
978 | * and accesses to uCode SRAM. | ||
979 | */ | ||
980 | ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, | ||
981 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
982 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
983 | if (ret < 0) { | ||
984 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
985 | goto out; | ||
986 | } | ||
987 | |||
988 | /* | ||
989 | * Enable DMA clock and wait for it to stabilize. | ||
990 | * | ||
991 | * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits | ||
992 | * do not disable clocks. This preserves any hardware bits already | ||
993 | * set by default in "CLK_CTRL_REG" after reset. | ||
994 | */ | ||
995 | iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
996 | udelay(20); | ||
997 | |||
998 | /* Disable L1-Active */ | ||
999 | iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG, | ||
1000 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
1001 | |||
1002 | set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); | ||
1003 | |||
1004 | out: | ||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | |||
1009 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | 885 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) |
1010 | { | 886 | { |
1011 | int ret; | 887 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 63f29111da13..8d60dcf6f2eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -297,12 +297,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | |||
297 | cfg(priv)->bt_params->advanced_bt_coexist; | 297 | cfg(priv)->bt_params->advanced_bt_coexist; |
298 | } | 298 | } |
299 | 299 | ||
300 | static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) | ||
301 | { | ||
302 | IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); | ||
303 | iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
304 | } | ||
305 | |||
306 | extern bool bt_siso_mode; | 300 | extern bool bt_siso_mode; |
307 | 301 | ||
308 | #endif /* __iwl_core_h__ */ | 302 | #endif /* __iwl_core_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 6f7612781e03..351b41d7f4fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -35,10 +35,10 @@ | |||
35 | struct iwl_priv; | 35 | struct iwl_priv; |
36 | 36 | ||
37 | /*No matter what is m (priv, bus, trans), this will work */ | 37 | /*No matter what is m (priv, bus, trans), this will work */ |
38 | #define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a) | 38 | #define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a) |
39 | #define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a) | 39 | #define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a) |
40 | #define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a) | 40 | #define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a) |
41 | #define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a) | 41 | #define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a) |
42 | 42 | ||
43 | #define iwl_print_hex_error(m, p, len) \ | 43 | #define iwl_print_hex_error(m, p, len) \ |
44 | do { \ | 44 | do { \ |
@@ -50,7 +50,7 @@ do { \ | |||
50 | #define IWL_DEBUG(m, level, fmt, ...) \ | 50 | #define IWL_DEBUG(m, level, fmt, ...) \ |
51 | do { \ | 51 | do { \ |
52 | if (iwl_get_debug_level((m)->shrd) & (level)) \ | 52 | if (iwl_get_debug_level((m)->shrd) & (level)) \ |
53 | dev_err(bus(m)->dev, "%c %s " fmt, \ | 53 | dev_err(trans(m)->dev, "%c %s " fmt, \ |
54 | in_interrupt() ? 'I' : 'U', __func__, \ | 54 | in_interrupt() ? 'I' : 'U', __func__, \ |
55 | ##__VA_ARGS__); \ | 55 | ##__VA_ARGS__); \ |
56 | } while (0) | 56 | } while (0) |
@@ -59,7 +59,7 @@ do { \ | |||
59 | do { \ | 59 | do { \ |
60 | if (iwl_get_debug_level((m)->shrd) & (level) && \ | 60 | if (iwl_get_debug_level((m)->shrd) & (level) && \ |
61 | net_ratelimit()) \ | 61 | net_ratelimit()) \ |
62 | dev_err(bus(m)->dev, "%c %s " fmt, \ | 62 | dev_err(trans(m)->dev, "%c %s " fmt, \ |
63 | in_interrupt() ? 'I' : 'U', __func__, \ | 63 | in_interrupt() ? 'I' : 'U', __func__, \ |
64 | ##__VA_ARGS__); \ | 64 | ##__VA_ARGS__); \ |
65 | } while (0) | 65 | } while (0) |
@@ -74,12 +74,12 @@ do { \ | |||
74 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \ | 74 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \ |
75 | do { \ | 75 | do { \ |
76 | if (!iwl_is_rfkill(p->shrd)) \ | 76 | if (!iwl_is_rfkill(p->shrd)) \ |
77 | dev_err(bus(p)->dev, "%s%c %s " fmt, \ | 77 | dev_err(trans(p)->dev, "%s%c %s " fmt, \ |
78 | "", \ | 78 | "", \ |
79 | in_interrupt() ? 'I' : 'U', __func__, \ | 79 | in_interrupt() ? 'I' : 'U', __func__, \ |
80 | ##__VA_ARGS__); \ | 80 | ##__VA_ARGS__); \ |
81 | else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ | 81 | else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ |
82 | dev_err(bus(p)->dev, "%s%c %s " fmt, \ | 82 | dev_err(trans(p)->dev, "%s%c %s " fmt, \ |
83 | "(RFKILL) ", \ | 83 | "(RFKILL) ", \ |
84 | in_interrupt() ? 'I' : 'U', __func__, \ | 84 | in_interrupt() ? 'I' : 'U', __func__, \ |
85 | ##__VA_ARGS__); \ | 85 | ##__VA_ARGS__); \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 978a1d4c6a0a..136de6fb3fa4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -263,7 +263,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
263 | sram = priv->dbgfs_sram_offset & ~0x3; | 263 | sram = priv->dbgfs_sram_offset & ~0x3; |
264 | 264 | ||
265 | /* read the first u32 from sram */ | 265 | /* read the first u32 from sram */ |
266 | val = iwl_read_targ_mem(bus(priv), sram); | 266 | val = iwl_read_targ_mem(trans(priv), sram); |
267 | 267 | ||
268 | for (; len; len--) { | 268 | for (; len; len--) { |
269 | /* put the address at the start of every line */ | 269 | /* put the address at the start of every line */ |
@@ -282,7 +282,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
282 | if (++offset == 4) { | 282 | if (++offset == 4) { |
283 | sram += 4; | 283 | sram += 4; |
284 | offset = 0; | 284 | offset = 0; |
285 | val = iwl_read_targ_mem(bus(priv), sram); | 285 | val = iwl_read_targ_mem(trans(priv), sram); |
286 | } | 286 | } |
287 | 287 | ||
288 | /* put in extra spaces and split lines for human readability */ | 288 | /* put in extra spaces and split lines for human readability */ |
@@ -2055,7 +2055,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, | |||
2055 | const size_t bufsz = sizeof(buf); | 2055 | const size_t bufsz = sizeof(buf); |
2056 | u32 pwrsave_status; | 2056 | u32 pwrsave_status; |
2057 | 2057 | ||
2058 | pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) & | 2058 | pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) & |
2059 | CSR_GP_REG_POWER_SAVE_STATUS_MSK; | 2059 | CSR_GP_REG_POWER_SAVE_STATUS_MSK; |
2060 | 2060 | ||
2061 | pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); | 2061 | pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index af846002150a..aa99457c3a52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -292,114 +292,6 @@ struct iwl_vif_priv { | |||
292 | u8 ibss_bssid_sta_id; | 292 | u8 ibss_bssid_sta_id; |
293 | }; | 293 | }; |
294 | 294 | ||
295 | /* v1/v2 uCode file layout */ | ||
296 | struct iwl_ucode_header { | ||
297 | __le32 ver; /* major/minor/API/serial */ | ||
298 | union { | ||
299 | struct { | ||
300 | __le32 inst_size; /* bytes of runtime code */ | ||
301 | __le32 data_size; /* bytes of runtime data */ | ||
302 | __le32 init_size; /* bytes of init code */ | ||
303 | __le32 init_data_size; /* bytes of init data */ | ||
304 | __le32 boot_size; /* bytes of bootstrap code */ | ||
305 | u8 data[0]; /* in same order as sizes */ | ||
306 | } v1; | ||
307 | struct { | ||
308 | __le32 build; /* build number */ | ||
309 | __le32 inst_size; /* bytes of runtime code */ | ||
310 | __le32 data_size; /* bytes of runtime data */ | ||
311 | __le32 init_size; /* bytes of init code */ | ||
312 | __le32 init_data_size; /* bytes of init data */ | ||
313 | __le32 boot_size; /* bytes of bootstrap code */ | ||
314 | u8 data[0]; /* in same order as sizes */ | ||
315 | } v2; | ||
316 | } u; | ||
317 | }; | ||
318 | |||
319 | /* | ||
320 | * new TLV uCode file layout | ||
321 | * | ||
322 | * The new TLV file format contains TLVs, that each specify | ||
323 | * some piece of data. To facilitate "groups", for example | ||
324 | * different instruction image with different capabilities, | ||
325 | * bundled with the same init image, an alternative mechanism | ||
326 | * is provided: | ||
327 | * When the alternative field is 0, that means that the item | ||
328 | * is always valid. When it is non-zero, then it is only | ||
329 | * valid in conjunction with items of the same alternative, | ||
330 | * in which case the driver (user) selects one alternative | ||
331 | * to use. | ||
332 | */ | ||
333 | |||
334 | enum iwl_ucode_tlv_type { | ||
335 | IWL_UCODE_TLV_INVALID = 0, /* unused */ | ||
336 | IWL_UCODE_TLV_INST = 1, | ||
337 | IWL_UCODE_TLV_DATA = 2, | ||
338 | IWL_UCODE_TLV_INIT = 3, | ||
339 | IWL_UCODE_TLV_INIT_DATA = 4, | ||
340 | IWL_UCODE_TLV_BOOT = 5, | ||
341 | IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ | ||
342 | IWL_UCODE_TLV_PAN = 7, | ||
343 | IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, | ||
344 | IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, | ||
345 | IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, | ||
346 | IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, | ||
347 | IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, | ||
348 | IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, | ||
349 | IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, | ||
350 | IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, | ||
351 | IWL_UCODE_TLV_WOWLAN_INST = 16, | ||
352 | IWL_UCODE_TLV_WOWLAN_DATA = 17, | ||
353 | IWL_UCODE_TLV_FLAGS = 18, | ||
354 | }; | ||
355 | |||
356 | /** | ||
357 | * enum iwl_ucode_tlv_flag - ucode API flags | ||
358 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
359 | * was a separate TLV but moved here to save space. | ||
360 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
361 | * treats good CRC threshold as a boolean | ||
362 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
363 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
364 | */ | ||
365 | enum iwl_ucode_tlv_flag { | ||
366 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
367 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
368 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
369 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
370 | }; | ||
371 | |||
372 | struct iwl_ucode_tlv { | ||
373 | __le16 type; /* see above */ | ||
374 | __le16 alternative; /* see comment */ | ||
375 | __le32 length; /* not including type/length fields */ | ||
376 | u8 data[0]; | ||
377 | } __packed; | ||
378 | |||
379 | #define IWL_TLV_UCODE_MAGIC 0x0a4c5749 | ||
380 | |||
381 | struct iwl_tlv_ucode_header { | ||
382 | /* | ||
383 | * The TLV style ucode header is distinguished from | ||
384 | * the v1/v2 style header by first four bytes being | ||
385 | * zero, as such is an invalid combination of | ||
386 | * major/minor/API/serial versions. | ||
387 | */ | ||
388 | __le32 zero; | ||
389 | __le32 magic; | ||
390 | u8 human_readable[64]; | ||
391 | __le32 ver; /* major/minor/API/serial */ | ||
392 | __le32 build; | ||
393 | __le64 alternatives; /* bitmask of valid alternatives */ | ||
394 | /* | ||
395 | * The data contained herein has a TLV layout, | ||
396 | * see above for the TLV header and types. | ||
397 | * Note that each TLV is padded to a length | ||
398 | * that is a multiple of 4 for alignment. | ||
399 | */ | ||
400 | u8 data[0]; | ||
401 | }; | ||
402 | |||
403 | struct iwl_sensitivity_ranges { | 295 | struct iwl_sensitivity_ranges { |
404 | u16 min_nrg_cck; | 296 | u16 min_nrg_cck; |
405 | u16 max_nrg_cck; | 297 | u16 max_nrg_cck; |
@@ -821,7 +713,6 @@ struct iwl_wipan_noa_data { | |||
821 | struct iwl_priv { | 713 | struct iwl_priv { |
822 | 714 | ||
823 | /*data shared among all the driver's layers */ | 715 | /*data shared among all the driver's layers */ |
824 | struct iwl_shared _shrd; | ||
825 | struct iwl_shared *shrd; | 716 | struct iwl_shared *shrd; |
826 | 717 | ||
827 | /* ieee device used by generic ieee processing code */ | 718 | /* ieee device used by generic ieee processing code */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index e27d9f55267b..d1fd1cdb29c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -156,16 +156,16 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) | |||
156 | 156 | ||
157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | 157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { |
158 | /* Request semaphore */ | 158 | /* Request semaphore */ |
159 | iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, | 159 | iwl_set_bit(trans(bus), CSR_HW_IF_CONFIG_REG, |
160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
161 | 161 | ||
162 | /* See if we got it */ | 162 | /* See if we got it */ |
163 | ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, | 163 | ret = iwl_poll_bit(trans(bus), CSR_HW_IF_CONFIG_REG, |
164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
166 | EEPROM_SEM_TIMEOUT); | 166 | EEPROM_SEM_TIMEOUT); |
167 | if (ret >= 0) { | 167 | if (ret >= 0) { |
168 | IWL_DEBUG_EEPROM(bus, | 168 | IWL_DEBUG_EEPROM(trans(bus), |
169 | "Acquired semaphore after %d tries.\n", | 169 | "Acquired semaphore after %d tries.\n", |
170 | count+1); | 170 | count+1); |
171 | return ret; | 171 | return ret; |
@@ -177,14 +177,15 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) | |||
177 | 177 | ||
178 | static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) | 178 | static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) |
179 | { | 179 | { |
180 | iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, | 180 | iwl_clear_bit(trans(bus), CSR_HW_IF_CONFIG_REG, |
181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
182 | 182 | ||
183 | } | 183 | } |
184 | 184 | ||
185 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans) | 185 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans) |
186 | { | 186 | { |
187 | u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | 187 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & |
188 | CSR_EEPROM_GP_VALID_MSK; | ||
188 | int ret = 0; | 189 | int ret = 0; |
189 | 190 | ||
190 | IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); | 191 | IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); |
@@ -305,13 +306,13 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) | |||
305 | 306 | ||
306 | static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) | 307 | static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) |
307 | { | 308 | { |
308 | iwl_read32(bus, CSR_OTP_GP_REG); | 309 | iwl_read32(trans(bus), CSR_OTP_GP_REG); |
309 | 310 | ||
310 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | 311 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) |
311 | iwl_clear_bit(bus, CSR_OTP_GP_REG, | 312 | iwl_clear_bit(trans(bus), CSR_OTP_GP_REG, |
312 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 313 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
313 | else | 314 | else |
314 | iwl_set_bit(bus, CSR_OTP_GP_REG, | 315 | iwl_set_bit(trans(bus), CSR_OTP_GP_REG, |
315 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 316 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
316 | } | 317 | } |
317 | 318 | ||
@@ -332,7 +333,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) | |||
332 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | 333 | nvm_type = NVM_DEVICE_TYPE_EEPROM; |
333 | break; | 334 | break; |
334 | default: | 335 | default: |
335 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); | 336 | otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); |
336 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | 337 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) |
337 | nvm_type = NVM_DEVICE_TYPE_OTP; | 338 | nvm_type = NVM_DEVICE_TYPE_OTP; |
338 | else | 339 | else |
@@ -347,22 +348,22 @@ static int iwl_init_otp_access(struct iwl_bus *bus) | |||
347 | int ret; | 348 | int ret; |
348 | 349 | ||
349 | /* Enable 40MHz radio clock */ | 350 | /* Enable 40MHz radio clock */ |
350 | iwl_write32(bus, CSR_GP_CNTRL, | 351 | iwl_write32(trans(bus), CSR_GP_CNTRL, |
351 | iwl_read32(bus, CSR_GP_CNTRL) | | 352 | iwl_read32(trans(bus), CSR_GP_CNTRL) | |
352 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 353 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
353 | 354 | ||
354 | /* wait for clock to be ready */ | 355 | /* wait for clock to be ready */ |
355 | ret = iwl_poll_bit(bus, CSR_GP_CNTRL, | 356 | ret = iwl_poll_bit(trans(bus), CSR_GP_CNTRL, |
356 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 357 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
357 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 358 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
358 | 25000); | 359 | 25000); |
359 | if (ret < 0) | 360 | if (ret < 0) |
360 | IWL_ERR(bus, "Time out access OTP\n"); | 361 | IWL_ERR(bus, "Time out access OTP\n"); |
361 | else { | 362 | else { |
362 | iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, | 363 | iwl_set_bits_prph(trans(bus), APMG_PS_CTRL_REG, |
363 | APMG_PS_CTRL_VAL_RESET_REQ); | 364 | APMG_PS_CTRL_VAL_RESET_REQ); |
364 | udelay(5); | 365 | udelay(5); |
365 | iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, | 366 | iwl_clear_bits_prph(trans(bus), APMG_PS_CTRL_REG, |
366 | APMG_PS_CTRL_VAL_RESET_REQ); | 367 | APMG_PS_CTRL_VAL_RESET_REQ); |
367 | 368 | ||
368 | /* | 369 | /* |
@@ -370,7 +371,7 @@ static int iwl_init_otp_access(struct iwl_bus *bus) | |||
370 | * this is only applicable for HW with OTP shadow RAM | 371 | * this is only applicable for HW with OTP shadow RAM |
371 | */ | 372 | */ |
372 | if (cfg(bus)->base_params->shadow_ram_support) | 373 | if (cfg(bus)->base_params->shadow_ram_support) |
373 | iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, | 374 | iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG, |
374 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | 375 | CSR_RESET_LINK_PWR_MGMT_DISABLED); |
375 | } | 376 | } |
376 | return ret; | 377 | return ret; |
@@ -382,9 +383,9 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) | |||
382 | u32 r; | 383 | u32 r; |
383 | u32 otpgp; | 384 | u32 otpgp; |
384 | 385 | ||
385 | iwl_write32(bus, CSR_EEPROM_REG, | 386 | iwl_write32(trans(bus), CSR_EEPROM_REG, |
386 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | 387 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); |
387 | ret = iwl_poll_bit(bus, CSR_EEPROM_REG, | 388 | ret = iwl_poll_bit(trans(bus), CSR_EEPROM_REG, |
388 | CSR_EEPROM_REG_READ_VALID_MSK, | 389 | CSR_EEPROM_REG_READ_VALID_MSK, |
389 | CSR_EEPROM_REG_READ_VALID_MSK, | 390 | CSR_EEPROM_REG_READ_VALID_MSK, |
390 | IWL_EEPROM_ACCESS_TIMEOUT); | 391 | IWL_EEPROM_ACCESS_TIMEOUT); |
@@ -392,13 +393,13 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) | |||
392 | IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); | 393 | IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); |
393 | return ret; | 394 | return ret; |
394 | } | 395 | } |
395 | r = iwl_read32(bus, CSR_EEPROM_REG); | 396 | r = iwl_read32(trans(bus), CSR_EEPROM_REG); |
396 | /* check for ECC errors: */ | 397 | /* check for ECC errors: */ |
397 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); | 398 | otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); |
398 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | 399 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { |
399 | /* stop in this case */ | 400 | /* stop in this case */ |
400 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | 401 | /* set the uncorrectable OTP ECC bit for acknowledgement */ |
401 | iwl_set_bit(bus, CSR_OTP_GP_REG, | 402 | iwl_set_bit(trans(bus), CSR_OTP_GP_REG, |
402 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 403 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
403 | IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); | 404 | IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); |
404 | return -EINVAL; | 405 | return -EINVAL; |
@@ -406,7 +407,7 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) | |||
406 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | 407 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { |
407 | /* continue in this case */ | 408 | /* continue in this case */ |
408 | /* set the correctable OTP ECC bit for acknowledgement */ | 409 | /* set the correctable OTP ECC bit for acknowledgement */ |
409 | iwl_set_bit(bus, CSR_OTP_GP_REG, | 410 | iwl_set_bit(trans(bus), CSR_OTP_GP_REG, |
410 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 411 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
411 | IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); | 412 | IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); |
412 | } | 413 | } |
@@ -656,7 +657,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
656 | { | 657 | { |
657 | struct iwl_shared *shrd = priv->shrd; | 658 | struct iwl_shared *shrd = priv->shrd; |
658 | __le16 *e; | 659 | __le16 *e; |
659 | u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP); | 660 | u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); |
660 | int sz; | 661 | int sz; |
661 | int ret; | 662 | int ret; |
662 | u16 addr; | 663 | u16 addr; |
@@ -676,8 +677,6 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
676 | } | 677 | } |
677 | e = (__le16 *)shrd->eeprom; | 678 | e = (__le16 *)shrd->eeprom; |
678 | 679 | ||
679 | iwl_apm_init(priv); | ||
680 | |||
681 | ret = iwl_eeprom_verify_signature(trans(priv)); | 680 | ret = iwl_eeprom_verify_signature(trans(priv)); |
682 | if (ret < 0) { | 681 | if (ret < 0) { |
683 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 682 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
@@ -701,11 +700,11 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
701 | ret = -ENOENT; | 700 | ret = -ENOENT; |
702 | goto done; | 701 | goto done; |
703 | } | 702 | } |
704 | iwl_write32(bus(priv), CSR_EEPROM_GP, | 703 | iwl_write32(trans(priv), CSR_EEPROM_GP, |
705 | iwl_read32(bus(priv), CSR_EEPROM_GP) & | 704 | iwl_read32(trans(priv), CSR_EEPROM_GP) & |
706 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | 705 | ~CSR_EEPROM_GP_IF_OWNER_MSK); |
707 | 706 | ||
708 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 707 | iwl_set_bit(trans(priv), CSR_OTP_GP_REG, |
709 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | 708 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | |
710 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 709 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
711 | /* traversing the linked list if no shadow ram supported */ | 710 | /* traversing the linked list if no shadow ram supported */ |
@@ -730,10 +729,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
730 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | 729 | for (addr = 0; addr < sz; addr += sizeof(u16)) { |
731 | u32 r; | 730 | u32 r; |
732 | 731 | ||
733 | iwl_write32(bus(priv), CSR_EEPROM_REG, | 732 | iwl_write32(trans(priv), CSR_EEPROM_REG, |
734 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | 733 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); |
735 | 734 | ||
736 | ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, | 735 | ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, |
737 | CSR_EEPROM_REG_READ_VALID_MSK, | 736 | CSR_EEPROM_REG_READ_VALID_MSK, |
738 | CSR_EEPROM_REG_READ_VALID_MSK, | 737 | CSR_EEPROM_REG_READ_VALID_MSK, |
739 | IWL_EEPROM_ACCESS_TIMEOUT); | 738 | IWL_EEPROM_ACCESS_TIMEOUT); |
@@ -741,7 +740,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
741 | IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); | 740 | IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); |
742 | goto done; | 741 | goto done; |
743 | } | 742 | } |
744 | r = iwl_read32(bus(priv), CSR_EEPROM_REG); | 743 | r = iwl_read32(trans(priv), CSR_EEPROM_REG); |
745 | e[addr / 2] = cpu_to_le16(r >> 16); | 744 | e[addr / 2] = cpu_to_le16(r >> 16); |
746 | } | 745 | } |
747 | } | 746 | } |
@@ -758,8 +757,6 @@ done: | |||
758 | err: | 757 | err: |
759 | if (ret) | 758 | if (ret) |
760 | iwl_eeprom_free(priv->shrd); | 759 | iwl_eeprom_free(priv->shrd); |
761 | /* Reset chip to save power until we load uCode during "up". */ | ||
762 | iwl_apm_stop(priv); | ||
763 | alloc_err: | 760 | alloc_err: |
764 | return ret; | 761 | return ret; |
765 | } | 762 | } |
@@ -1072,7 +1069,7 @@ void iwl_rf_config(struct iwl_priv *priv) | |||
1072 | 1069 | ||
1073 | /* write radio config values to register */ | 1070 | /* write radio config values to register */ |
1074 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | 1071 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { |
1075 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 1072 | iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, |
1076 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | 1073 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | |
1077 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | 1074 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | |
1078 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | 1075 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); |
@@ -1084,7 +1081,7 @@ void iwl_rf_config(struct iwl_priv *priv) | |||
1084 | WARN_ON(1); | 1081 | WARN_ON(1); |
1085 | 1082 | ||
1086 | /* set CSR_HW_CONFIG_REG for uCode use */ | 1083 | /* set CSR_HW_CONFIG_REG for uCode use */ |
1087 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 1084 | iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, |
1088 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | 1085 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | |
1089 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | 1086 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); |
1090 | } | 1087 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 83fdff381150..e2e3b5c9cf7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -34,41 +34,41 @@ | |||
34 | 34 | ||
35 | #define IWL_POLL_INTERVAL 10 /* microseconds */ | 35 | #define IWL_POLL_INTERVAL 10 /* microseconds */ |
36 | 36 | ||
37 | static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) | 37 | static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
38 | { | 38 | { |
39 | iwl_write32(bus, reg, iwl_read32(bus, reg) | mask); | 39 | iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) | 42 | static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
43 | { | 43 | { |
44 | iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask); | 44 | iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); |
45 | } | 45 | } |
46 | 46 | ||
47 | void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) | 47 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
48 | { | 48 | { |
49 | unsigned long flags; | 49 | unsigned long flags; |
50 | 50 | ||
51 | spin_lock_irqsave(&bus->reg_lock, flags); | 51 | spin_lock_irqsave(&trans->reg_lock, flags); |
52 | __iwl_set_bit(bus, reg, mask); | 52 | __iwl_set_bit(trans, reg, mask); |
53 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 53 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
54 | } | 54 | } |
55 | 55 | ||
56 | void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) | 56 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
57 | { | 57 | { |
58 | unsigned long flags; | 58 | unsigned long flags; |
59 | 59 | ||
60 | spin_lock_irqsave(&bus->reg_lock, flags); | 60 | spin_lock_irqsave(&trans->reg_lock, flags); |
61 | __iwl_clear_bit(bus, reg, mask); | 61 | __iwl_clear_bit(trans, reg, mask); |
62 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 62 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
63 | } | 63 | } |
64 | 64 | ||
65 | int iwl_poll_bit(struct iwl_bus *bus, u32 addr, | 65 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
66 | u32 bits, u32 mask, int timeout) | 66 | u32 bits, u32 mask, int timeout) |
67 | { | 67 | { |
68 | int t = 0; | 68 | int t = 0; |
69 | 69 | ||
70 | do { | 70 | do { |
71 | if ((iwl_read32(bus, addr) & mask) == (bits & mask)) | 71 | if ((iwl_read32(trans, addr) & mask) == (bits & mask)) |
72 | return t; | 72 | return t; |
73 | udelay(IWL_POLL_INTERVAL); | 73 | udelay(IWL_POLL_INTERVAL); |
74 | t += IWL_POLL_INTERVAL; | 74 | t += IWL_POLL_INTERVAL; |
@@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr, | |||
77 | return -ETIMEDOUT; | 77 | return -ETIMEDOUT; |
78 | } | 78 | } |
79 | 79 | ||
80 | int iwl_grab_nic_access_silent(struct iwl_bus *bus) | 80 | int iwl_grab_nic_access_silent(struct iwl_trans *trans) |
81 | { | 81 | { |
82 | int ret; | 82 | int ret; |
83 | 83 | ||
84 | lockdep_assert_held(&bus->reg_lock); | 84 | lockdep_assert_held(&trans->reg_lock); |
85 | 85 | ||
86 | /* this bit wakes up the NIC */ | 86 | /* this bit wakes up the NIC */ |
87 | __iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 87 | __iwl_set_bit(trans, CSR_GP_CNTRL, |
88 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
88 | 89 | ||
89 | /* | 90 | /* |
90 | * These bits say the device is running, and should keep running for | 91 | * These bits say the device is running, and should keep running for |
@@ -105,70 +106,70 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus) | |||
105 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | 106 | * 5000 series and later (including 1000 series) have non-volatile SRAM, |
106 | * and do not save/restore SRAM when power cycling. | 107 | * and do not save/restore SRAM when power cycling. |
107 | */ | 108 | */ |
108 | ret = iwl_poll_bit(bus, CSR_GP_CNTRL, | 109 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, |
109 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | 110 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, |
110 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | 111 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | |
111 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | 112 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); |
112 | if (ret < 0) { | 113 | if (ret < 0) { |
113 | iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | 114 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); |
114 | return -EIO; | 115 | return -EIO; |
115 | } | 116 | } |
116 | 117 | ||
117 | return 0; | 118 | return 0; |
118 | } | 119 | } |
119 | 120 | ||
120 | int iwl_grab_nic_access(struct iwl_bus *bus) | 121 | int iwl_grab_nic_access(struct iwl_trans *trans) |
121 | { | 122 | { |
122 | int ret = iwl_grab_nic_access_silent(bus); | 123 | int ret = iwl_grab_nic_access_silent(trans); |
123 | if (ret) { | 124 | if (ret) { |
124 | u32 val = iwl_read32(bus, CSR_GP_CNTRL); | 125 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); |
125 | IWL_ERR(bus, | 126 | IWL_ERR(trans, |
126 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | 127 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); |
127 | } | 128 | } |
128 | 129 | ||
129 | return ret; | 130 | return ret; |
130 | } | 131 | } |
131 | 132 | ||
132 | void iwl_release_nic_access(struct iwl_bus *bus) | 133 | void iwl_release_nic_access(struct iwl_trans *trans) |
133 | { | 134 | { |
134 | lockdep_assert_held(&bus->reg_lock); | 135 | lockdep_assert_held(&trans->reg_lock); |
135 | __iwl_clear_bit(bus, CSR_GP_CNTRL, | 136 | __iwl_clear_bit(trans, CSR_GP_CNTRL, |
136 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 137 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
137 | } | 138 | } |
138 | 139 | ||
139 | u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg) | 140 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
140 | { | 141 | { |
141 | u32 value; | 142 | u32 value; |
142 | unsigned long flags; | 143 | unsigned long flags; |
143 | 144 | ||
144 | spin_lock_irqsave(&bus->reg_lock, flags); | 145 | spin_lock_irqsave(&trans->reg_lock, flags); |
145 | iwl_grab_nic_access(bus); | 146 | iwl_grab_nic_access(trans); |
146 | value = iwl_read32(bus, reg); | 147 | value = iwl_read32(trans, reg); |
147 | iwl_release_nic_access(bus); | 148 | iwl_release_nic_access(trans); |
148 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 149 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
149 | 150 | ||
150 | return value; | 151 | return value; |
151 | } | 152 | } |
152 | 153 | ||
153 | void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value) | 154 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) |
154 | { | 155 | { |
155 | unsigned long flags; | 156 | unsigned long flags; |
156 | 157 | ||
157 | spin_lock_irqsave(&bus->reg_lock, flags); | 158 | spin_lock_irqsave(&trans->reg_lock, flags); |
158 | if (!iwl_grab_nic_access(bus)) { | 159 | if (!iwl_grab_nic_access(trans)) { |
159 | iwl_write32(bus, reg, value); | 160 | iwl_write32(trans, reg, value); |
160 | iwl_release_nic_access(bus); | 161 | iwl_release_nic_access(trans); |
161 | } | 162 | } |
162 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 163 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
163 | } | 164 | } |
164 | 165 | ||
165 | int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, | 166 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
166 | int timeout) | 167 | int timeout) |
167 | { | 168 | { |
168 | int t = 0; | 169 | int t = 0; |
169 | 170 | ||
170 | do { | 171 | do { |
171 | if ((iwl_read_direct32(bus, addr) & mask) == mask) | 172 | if ((iwl_read_direct32(trans, addr) & mask) == mask) |
172 | return t; | 173 | return t; |
173 | udelay(IWL_POLL_INTERVAL); | 174 | udelay(IWL_POLL_INTERVAL); |
174 | t += IWL_POLL_INTERVAL; | 175 | t += IWL_POLL_INTERVAL; |
@@ -177,135 +178,135 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, | |||
177 | return -ETIMEDOUT; | 178 | return -ETIMEDOUT; |
178 | } | 179 | } |
179 | 180 | ||
180 | static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg) | 181 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) |
181 | { | 182 | { |
182 | iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); | 183 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); |
183 | rmb(); | 184 | rmb(); |
184 | return iwl_read32(bus, HBUS_TARG_PRPH_RDAT); | 185 | return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); |
185 | } | 186 | } |
186 | 187 | ||
187 | static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) | 188 | static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) |
188 | { | 189 | { |
189 | iwl_write32(bus, HBUS_TARG_PRPH_WADDR, | 190 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, |
190 | ((addr & 0x0000FFFF) | (3 << 24))); | 191 | ((addr & 0x0000FFFF) | (3 << 24))); |
191 | wmb(); | 192 | wmb(); |
192 | iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val); | 193 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); |
193 | } | 194 | } |
194 | 195 | ||
195 | u32 iwl_read_prph(struct iwl_bus *bus, u32 reg) | 196 | u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) |
196 | { | 197 | { |
197 | unsigned long flags; | 198 | unsigned long flags; |
198 | u32 val; | 199 | u32 val; |
199 | 200 | ||
200 | spin_lock_irqsave(&bus->reg_lock, flags); | 201 | spin_lock_irqsave(&trans->reg_lock, flags); |
201 | iwl_grab_nic_access(bus); | 202 | iwl_grab_nic_access(trans); |
202 | val = __iwl_read_prph(bus, reg); | 203 | val = __iwl_read_prph(trans, reg); |
203 | iwl_release_nic_access(bus); | 204 | iwl_release_nic_access(trans); |
204 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 205 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
205 | return val; | 206 | return val; |
206 | } | 207 | } |
207 | 208 | ||
208 | void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) | 209 | void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) |
209 | { | 210 | { |
210 | unsigned long flags; | 211 | unsigned long flags; |
211 | 212 | ||
212 | spin_lock_irqsave(&bus->reg_lock, flags); | 213 | spin_lock_irqsave(&trans->reg_lock, flags); |
213 | if (!iwl_grab_nic_access(bus)) { | 214 | if (!iwl_grab_nic_access(trans)) { |
214 | __iwl_write_prph(bus, addr, val); | 215 | __iwl_write_prph(trans, addr, val); |
215 | iwl_release_nic_access(bus); | 216 | iwl_release_nic_access(trans); |
216 | } | 217 | } |
217 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 218 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
218 | } | 219 | } |
219 | 220 | ||
220 | void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) | 221 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) |
221 | { | 222 | { |
222 | unsigned long flags; | 223 | unsigned long flags; |
223 | 224 | ||
224 | spin_lock_irqsave(&bus->reg_lock, flags); | 225 | spin_lock_irqsave(&trans->reg_lock, flags); |
225 | iwl_grab_nic_access(bus); | 226 | iwl_grab_nic_access(trans); |
226 | __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask); | 227 | __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); |
227 | iwl_release_nic_access(bus); | 228 | iwl_release_nic_access(trans); |
228 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 229 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
229 | } | 230 | } |
230 | 231 | ||
231 | void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, | 232 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, |
232 | u32 bits, u32 mask) | 233 | u32 bits, u32 mask) |
233 | { | 234 | { |
234 | unsigned long flags; | 235 | unsigned long flags; |
235 | 236 | ||
236 | spin_lock_irqsave(&bus->reg_lock, flags); | 237 | spin_lock_irqsave(&trans->reg_lock, flags); |
237 | iwl_grab_nic_access(bus); | 238 | iwl_grab_nic_access(trans); |
238 | __iwl_write_prph(bus, reg, | 239 | __iwl_write_prph(trans, reg, |
239 | (__iwl_read_prph(bus, reg) & mask) | bits); | 240 | (__iwl_read_prph(trans, reg) & mask) | bits); |
240 | iwl_release_nic_access(bus); | 241 | iwl_release_nic_access(trans); |
241 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 242 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
242 | } | 243 | } |
243 | 244 | ||
244 | void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) | 245 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) |
245 | { | 246 | { |
246 | unsigned long flags; | 247 | unsigned long flags; |
247 | u32 val; | 248 | u32 val; |
248 | 249 | ||
249 | spin_lock_irqsave(&bus->reg_lock, flags); | 250 | spin_lock_irqsave(&trans->reg_lock, flags); |
250 | iwl_grab_nic_access(bus); | 251 | iwl_grab_nic_access(trans); |
251 | val = __iwl_read_prph(bus, reg); | 252 | val = __iwl_read_prph(trans, reg); |
252 | __iwl_write_prph(bus, reg, (val & ~mask)); | 253 | __iwl_write_prph(trans, reg, (val & ~mask)); |
253 | iwl_release_nic_access(bus); | 254 | iwl_release_nic_access(trans); |
254 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 255 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
255 | } | 256 | } |
256 | 257 | ||
257 | void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, | 258 | void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, |
258 | void *buf, int words) | 259 | void *buf, int words) |
259 | { | 260 | { |
260 | unsigned long flags; | 261 | unsigned long flags; |
261 | int offs; | 262 | int offs; |
262 | u32 *vals = buf; | 263 | u32 *vals = buf; |
263 | 264 | ||
264 | spin_lock_irqsave(&bus->reg_lock, flags); | 265 | spin_lock_irqsave(&trans->reg_lock, flags); |
265 | iwl_grab_nic_access(bus); | 266 | iwl_grab_nic_access(trans); |
266 | 267 | ||
267 | iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr); | 268 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); |
268 | rmb(); | 269 | rmb(); |
269 | 270 | ||
270 | for (offs = 0; offs < words; offs++) | 271 | for (offs = 0; offs < words; offs++) |
271 | vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT); | 272 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
272 | 273 | ||
273 | iwl_release_nic_access(bus); | 274 | iwl_release_nic_access(trans); |
274 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 275 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
275 | } | 276 | } |
276 | 277 | ||
277 | u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr) | 278 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) |
278 | { | 279 | { |
279 | u32 value; | 280 | u32 value; |
280 | 281 | ||
281 | _iwl_read_targ_mem_words(bus, addr, &value, 1); | 282 | _iwl_read_targ_mem_words(trans, addr, &value, 1); |
282 | 283 | ||
283 | return value; | 284 | return value; |
284 | } | 285 | } |
285 | 286 | ||
286 | int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, | 287 | int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, |
287 | void *buf, int words) | 288 | void *buf, int words) |
288 | { | 289 | { |
289 | unsigned long flags; | 290 | unsigned long flags; |
290 | int offs, result = 0; | 291 | int offs, result = 0; |
291 | u32 *vals = buf; | 292 | u32 *vals = buf; |
292 | 293 | ||
293 | spin_lock_irqsave(&bus->reg_lock, flags); | 294 | spin_lock_irqsave(&trans->reg_lock, flags); |
294 | if (!iwl_grab_nic_access(bus)) { | 295 | if (!iwl_grab_nic_access(trans)) { |
295 | iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); | 296 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); |
296 | wmb(); | 297 | wmb(); |
297 | 298 | ||
298 | for (offs = 0; offs < words; offs++) | 299 | for (offs = 0; offs < words; offs++) |
299 | iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]); | 300 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); |
300 | iwl_release_nic_access(bus); | 301 | iwl_release_nic_access(trans); |
301 | } else | 302 | } else |
302 | result = -EBUSY; | 303 | result = -EBUSY; |
303 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 304 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
304 | 305 | ||
305 | return result; | 306 | return result; |
306 | } | 307 | } |
307 | 308 | ||
308 | int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) | 309 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) |
309 | { | 310 | { |
310 | return _iwl_write_targ_mem_words(bus, addr, &val, 1); | 311 | return _iwl_write_targ_mem_words(trans, addr, &val, 1); |
311 | } | 312 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 427d065435c8..782486fc2f8f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -31,63 +31,63 @@ | |||
31 | 31 | ||
32 | #include "iwl-devtrace.h" | 32 | #include "iwl-devtrace.h" |
33 | #include "iwl-shared.h" | 33 | #include "iwl-shared.h" |
34 | #include "iwl-bus.h" | 34 | #include "iwl-trans.h" |
35 | 35 | ||
36 | static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) | 36 | static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
37 | { | 37 | { |
38 | trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); | 38 | trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); |
39 | bus_write8(bus, ofs, val); | 39 | iwl_trans_write8(trans, ofs, val); |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) | 42 | static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) |
43 | { | 43 | { |
44 | trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); | 44 | trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); |
45 | bus_write32(bus, ofs, val); | 45 | iwl_trans_write32(trans, ofs, val); |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) | 48 | static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) |
49 | { | 49 | { |
50 | u32 val = bus_read32(bus, ofs); | 50 | u32 val = iwl_trans_read32(trans, ofs); |
51 | trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); | 51 | trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); |
52 | return val; | 52 | return val; |
53 | } | 53 | } |
54 | 54 | ||
55 | void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask); | 55 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
56 | void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask); | 56 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
57 | 57 | ||
58 | int iwl_poll_bit(struct iwl_bus *bus, u32 addr, | 58 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
59 | u32 bits, u32 mask, int timeout); | 59 | u32 bits, u32 mask, int timeout); |
60 | int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, | 60 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
61 | int timeout); | 61 | int timeout); |
62 | 62 | ||
63 | int iwl_grab_nic_access_silent(struct iwl_bus *bus); | 63 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); |
64 | int iwl_grab_nic_access(struct iwl_bus *bus); | 64 | int iwl_grab_nic_access(struct iwl_trans *trans); |
65 | void iwl_release_nic_access(struct iwl_bus *bus); | 65 | void iwl_release_nic_access(struct iwl_trans *trans); |
66 | 66 | ||
67 | u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg); | 67 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); |
68 | void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value); | 68 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); |
69 | 69 | ||
70 | 70 | ||
71 | u32 iwl_read_prph(struct iwl_bus *bus, u32 reg); | 71 | u32 iwl_read_prph(struct iwl_trans *trans, u32 reg); |
72 | void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val); | 72 | void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val); |
73 | void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); | 73 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); |
74 | void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, | 74 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, |
75 | u32 bits, u32 mask); | 75 | u32 bits, u32 mask); |
76 | void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); | 76 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); |
77 | 77 | ||
78 | void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, | 78 | void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, |
79 | void *buf, int words); | 79 | void *buf, int words); |
80 | 80 | ||
81 | #define iwl_read_targ_mem_words(bus, addr, buf, bufsize) \ | 81 | #define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ |
82 | do { \ | 82 | do { \ |
83 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | 83 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ |
84 | _iwl_read_targ_mem_words(bus, addr, buf, \ | 84 | _iwl_read_targ_mem_words(trans, addr, buf, \ |
85 | (bufsize) / sizeof(u32));\ | 85 | (bufsize) / sizeof(u32));\ |
86 | } while (0) | 86 | } while (0) |
87 | 87 | ||
88 | int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, | 88 | int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, |
89 | void *buf, int words); | 89 | void *buf, int words); |
90 | 90 | ||
91 | u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); | 91 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); |
92 | int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); | 92 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); |
93 | #endif | 93 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 8761438f1532..5c7741f07aa0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { | |||
71 | /* Set led register off */ | 71 | /* Set led register off */ |
72 | void iwlagn_led_enable(struct iwl_priv *priv) | 72 | void iwlagn_led_enable(struct iwl_priv *priv) |
73 | { | 73 | { |
74 | iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); | 74 | iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); |
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
@@ -107,9 +107,10 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | |||
107 | }; | 107 | }; |
108 | u32 reg; | 108 | u32 reg; |
109 | 109 | ||
110 | reg = iwl_read32(bus(priv), CSR_LED_REG); | 110 | reg = iwl_read32(trans(priv), CSR_LED_REG); |
111 | if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) | 111 | if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) |
112 | iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); | 112 | iwl_write32(trans(priv), CSR_LED_REG, |
113 | reg & CSR_LED_BSM_CTRL_MSK); | ||
113 | 114 | ||
114 | return iwl_trans_send_cmd(trans(priv), &cmd); | 115 | return iwl_trans_send_cmd(trans(priv), &cmd); |
115 | } | 116 | } |
@@ -206,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv) | |||
206 | break; | 207 | break; |
207 | } | 208 | } |
208 | 209 | ||
209 | ret = led_classdev_register(bus(priv)->dev, &priv->led); | 210 | ret = led_classdev_register(trans(priv)->dev, &priv->led); |
210 | if (ret) { | 211 | if (ret) { |
211 | kfree(priv->led.name); | 212 | kfree(priv->led.name); |
212 | return; | 213 | return; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 965d0475affd..d8025fee7e0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/netdevice.h> | 37 | #include <linux/netdevice.h> |
38 | #include <linux/firmware.h> | ||
39 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
40 | #include <linux/if_arp.h> | 39 | #include <linux/if_arp.h> |
41 | 40 | ||
@@ -43,6 +42,7 @@ | |||
43 | 42 | ||
44 | #include <asm/div64.h> | 43 | #include <asm/div64.h> |
45 | 44 | ||
45 | #include "iwl-ucode.h" | ||
46 | #include "iwl-eeprom.h" | 46 | #include "iwl-eeprom.h" |
47 | #include "iwl-wifi.h" | 47 | #include "iwl-wifi.h" |
48 | #include "iwl-dev.h" | 48 | #include "iwl-dev.h" |
@@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
196 | WIPHY_FLAG_IBSS_RSN; | 196 | WIPHY_FLAG_IBSS_RSN; |
197 | 197 | ||
198 | if (trans(priv)->ucode_wowlan.code.len && | 198 | if (trans(priv)->ucode_wowlan.code.len && |
199 | device_can_wakeup(bus(priv)->dev)) { | 199 | device_can_wakeup(trans(priv)->dev)) { |
200 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 200 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
201 | WIPHY_WOWLAN_DISCONNECT | | 201 | WIPHY_WOWLAN_DISCONNECT | |
202 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | | 202 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | |
@@ -234,7 +234,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
234 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 234 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
235 | &priv->bands[IEEE80211_BAND_5GHZ]; | 235 | &priv->bands[IEEE80211_BAND_5GHZ]; |
236 | 236 | ||
237 | hw->wiphy->hw_version = bus_get_hw_id(bus(priv)); | 237 | hw->wiphy->hw_version = trans(priv)->hw_id; |
238 | 238 | ||
239 | iwl_leds_init(priv); | 239 | iwl_leds_init(priv); |
240 | 240 | ||
@@ -346,9 +346,10 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
346 | flush_workqueue(priv->shrd->workqueue); | 346 | flush_workqueue(priv->shrd->workqueue); |
347 | 347 | ||
348 | /* User space software may expect getting rfkill changes | 348 | /* User space software may expect getting rfkill changes |
349 | * even if interface is down */ | 349 | * even if interface is down, trans->down will leave the RF |
350 | iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); | 350 | * kill interrupt enabled |
351 | iwl_enable_rfkill_int(priv); | 351 | */ |
352 | iwl_trans_stop_hw(trans(priv)); | ||
352 | 353 | ||
353 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 354 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
354 | } | 355 | } |
@@ -405,10 +406,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
405 | if (ret) | 406 | if (ret) |
406 | goto error; | 407 | goto error; |
407 | 408 | ||
408 | device_set_wakeup_enable(bus(priv)->dev, true); | 409 | device_set_wakeup_enable(trans(priv)->dev, true); |
409 | 410 | ||
410 | /* Now let the ucode operate on its own */ | 411 | /* Now let the ucode operate on its own */ |
411 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | 412 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, |
412 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 413 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
413 | 414 | ||
414 | goto out; | 415 | goto out; |
@@ -436,19 +437,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
436 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 437 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
437 | mutex_lock(&priv->shrd->mutex); | 438 | mutex_lock(&priv->shrd->mutex); |
438 | 439 | ||
439 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | 440 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
440 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 441 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
441 | 442 | ||
442 | base = priv->shrd->device_pointers.error_event_table; | 443 | base = priv->shrd->device_pointers.error_event_table; |
443 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 444 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
444 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | 445 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
445 | ret = iwl_grab_nic_access_silent(bus(priv)); | 446 | ret = iwl_grab_nic_access_silent(trans(priv)); |
446 | if (ret == 0) { | 447 | if (ret == 0) { |
447 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); | 448 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); |
448 | status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 449 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
449 | iwl_release_nic_access(bus(priv)); | 450 | iwl_release_nic_access(trans(priv)); |
450 | } | 451 | } |
451 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | 452 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); |
452 | 453 | ||
453 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 454 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
454 | if (ret == 0) { | 455 | if (ret == 0) { |
@@ -460,7 +461,8 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
460 | 461 | ||
461 | if (priv->wowlan_sram) | 462 | if (priv->wowlan_sram) |
462 | _iwl_read_targ_mem_words( | 463 | _iwl_read_targ_mem_words( |
463 | bus(priv), 0x800000, priv->wowlan_sram, | 464 | trans(priv), 0x800000, |
465 | priv->wowlan_sram, | ||
464 | trans->ucode_wowlan.data.len / 4); | 466 | trans->ucode_wowlan.data.len / 4); |
465 | } | 467 | } |
466 | #endif | 468 | #endif |
@@ -471,7 +473,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
471 | 473 | ||
472 | priv->shrd->wowlan = false; | 474 | priv->shrd->wowlan = false; |
473 | 475 | ||
474 | device_set_wakeup_enable(bus(priv)->dev, false); | 476 | device_set_wakeup_enable(trans(priv)->dev, false); |
475 | 477 | ||
476 | iwlagn_prepare_restart(priv); | 478 | iwlagn_prepare_restart(priv); |
477 | 479 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 03702a2e913a..3e2fce4ce00c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -71,112 +71,6 @@ | |||
71 | #include "iwl-csr.h" | 71 | #include "iwl-csr.h" |
72 | #include "iwl-cfg.h" | 72 | #include "iwl-cfg.h" |
73 | 73 | ||
74 | /* PCI registers */ | ||
75 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
76 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 | ||
77 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 | ||
78 | |||
79 | struct iwl_pci_bus { | ||
80 | /* basic pci-network driver stuff */ | ||
81 | struct pci_dev *pci_dev; | ||
82 | |||
83 | /* pci hardware address support */ | ||
84 | void __iomem *hw_base; | ||
85 | }; | ||
86 | |||
87 | #define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ | ||
88 | ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) | ||
89 | |||
90 | #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ | ||
91 | ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) | ||
92 | |||
93 | static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) | ||
94 | { | ||
95 | int pos; | ||
96 | u16 pci_lnk_ctl; | ||
97 | |||
98 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
99 | |||
100 | pos = pci_pcie_cap(pci_dev); | ||
101 | pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); | ||
102 | return pci_lnk_ctl; | ||
103 | } | ||
104 | |||
105 | static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) | ||
106 | { | ||
107 | u16 lctl = iwl_pciexp_link_ctrl(bus); | ||
108 | |||
109 | return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); | ||
110 | } | ||
111 | |||
112 | static void iwl_pci_apm_config(struct iwl_bus *bus) | ||
113 | { | ||
114 | /* | ||
115 | * HW bug W/A for instability in PCIe bus L0S->L1 transition. | ||
116 | * Check if BIOS (or OS) enabled L1-ASPM on this device. | ||
117 | * If so (likely), disable L0S, so device moves directly L0->L1; | ||
118 | * costs negligible amount of power savings. | ||
119 | * If not (unlikely), enable L0S, so there is at least some | ||
120 | * power savings, even without L1. | ||
121 | */ | ||
122 | u16 lctl = iwl_pciexp_link_ctrl(bus); | ||
123 | |||
124 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | ||
125 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | ||
126 | /* L1-ASPM enabled; disable(!) L0S */ | ||
127 | iwl_set_bit(bus, CSR_GIO_REG, | ||
128 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
129 | dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); | ||
130 | } else { | ||
131 | /* L1-ASPM disabled; enable(!) L0S */ | ||
132 | iwl_clear_bit(bus, CSR_GIO_REG, | ||
133 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
134 | dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], | ||
139 | int buf_len) | ||
140 | { | ||
141 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
142 | |||
143 | snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, | ||
144 | pci_dev->subsystem_device); | ||
145 | } | ||
146 | |||
147 | static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) | ||
148 | { | ||
149 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
150 | |||
151 | return (pci_dev->device << 16) + pci_dev->subsystem_device; | ||
152 | } | ||
153 | |||
154 | static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) | ||
155 | { | ||
156 | iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
157 | } | ||
158 | |||
159 | static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) | ||
160 | { | ||
161 | iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
162 | } | ||
163 | |||
164 | static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) | ||
165 | { | ||
166 | u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
167 | return val; | ||
168 | } | ||
169 | |||
170 | static const struct iwl_bus_ops bus_ops_pci = { | ||
171 | .get_pm_support = iwl_pci_is_pm_supported, | ||
172 | .apm_config = iwl_pci_apm_config, | ||
173 | .get_hw_id_string = iwl_pci_get_hw_id_string, | ||
174 | .get_hw_id = iwl_pci_get_hw_id, | ||
175 | .write8 = iwl_pci_write8, | ||
176 | .write32 = iwl_pci_write32, | ||
177 | .read32 = iwl_pci_read32, | ||
178 | }; | ||
179 | |||
180 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 74 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
181 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ | 75 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ |
182 | .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ | 76 | .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ |
@@ -362,112 +256,61 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
362 | }; | 256 | }; |
363 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | 257 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); |
364 | 258 | ||
259 | /* PCI registers */ | ||
260 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
261 | |||
365 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 262 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
366 | { | 263 | { |
367 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 264 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
368 | struct iwl_bus *bus; | 265 | struct iwl_bus *bus; |
369 | struct iwl_pci_bus *pci_bus; | ||
370 | u16 pci_cmd; | ||
371 | int err; | 266 | int err; |
372 | 267 | ||
373 | bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); | 268 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); |
374 | if (!bus) { | 269 | if (!bus) { |
375 | dev_printk(KERN_ERR, &pdev->dev, | 270 | dev_printk(KERN_ERR, &pdev->dev, |
376 | "Couldn't allocate iwl_pci_bus"); | 271 | "Couldn't allocate iwl_pci_bus"); |
377 | err = -ENOMEM; | 272 | return -ENOMEM; |
378 | goto out_no_pci; | ||
379 | } | 273 | } |
380 | 274 | ||
381 | pci_bus = IWL_BUS_GET_PCI_BUS(bus); | 275 | bus->shrd = kzalloc(sizeof(*bus->shrd), GFP_KERNEL); |
382 | pci_bus->pci_dev = pdev; | 276 | if (!bus->shrd) { |
383 | 277 | dev_printk(KERN_ERR, &pdev->dev, | |
384 | pci_set_drvdata(pdev, bus); | 278 | "Couldn't allocate iwl_shared"); |
385 | 279 | err = -ENOMEM; | |
386 | /* W/A - seems to solve weird behavior. We need to remove this if we | 280 | goto out_free_bus; |
387 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
388 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
389 | PCIE_LINK_STATE_CLKPM); | ||
390 | |||
391 | if (pci_enable_device(pdev)) { | ||
392 | err = -ENODEV; | ||
393 | goto out_no_pci; | ||
394 | } | 281 | } |
395 | 282 | ||
396 | pci_set_master(pdev); | 283 | bus->shrd->bus = bus; |
397 | |||
398 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
399 | if (!err) | ||
400 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
401 | if (err) { | ||
402 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
403 | if (!err) | ||
404 | err = pci_set_consistent_dma_mask(pdev, | ||
405 | DMA_BIT_MASK(32)); | ||
406 | /* both attempts failed: */ | ||
407 | if (err) { | ||
408 | dev_printk(KERN_ERR, bus->dev, | ||
409 | "No suitable DMA available.\n"); | ||
410 | goto out_pci_disable_device; | ||
411 | } | ||
412 | } | ||
413 | 284 | ||
414 | err = pci_request_regions(pdev, DRV_NAME); | 285 | pci_set_drvdata(pdev, bus); |
415 | if (err) { | ||
416 | dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed"); | ||
417 | goto out_pci_disable_device; | ||
418 | } | ||
419 | 286 | ||
420 | pci_bus->hw_base = pci_iomap(pdev, 0, 0); | 287 | #ifdef CONFIG_IWLWIFI_IDI |
421 | if (!pci_bus->hw_base) { | 288 | trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); |
422 | dev_printk(KERN_ERR, bus->dev, "pci_iomap failed"); | 289 | if (trans(bus) == NULL) { |
423 | err = -ENODEV; | 290 | err = -ENOMEM; |
424 | goto out_pci_release_regions; | 291 | goto out_free_bus; |
425 | } | 292 | } |
426 | 293 | ||
427 | dev_printk(KERN_INFO, &pdev->dev, | 294 | err = iwl_probe(bus, &trans_ops_idi, cfg); |
428 | "pci_resource_len = 0x%08llx\n", | 295 | #else |
429 | (unsigned long long) pci_resource_len(pdev, 0)); | 296 | trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); |
430 | dev_printk(KERN_INFO, &pdev->dev, | 297 | if (trans(bus) == NULL) { |
431 | "pci_resource_base = %p\n", pci_bus->hw_base); | 298 | err = -ENOMEM; |
432 | 299 | goto out_free_bus; | |
433 | dev_printk(KERN_INFO, &pdev->dev, | ||
434 | "HW Revision ID = 0x%X\n", pdev->revision); | ||
435 | |||
436 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
437 | * PCI Tx retries from interfering with C3 CPU state */ | ||
438 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
439 | |||
440 | err = pci_enable_msi(pdev); | ||
441 | if (err) | ||
442 | dev_printk(KERN_ERR, &pdev->dev, | ||
443 | "pci_enable_msi failed(0X%x)", err); | ||
444 | |||
445 | /* TODO: Move this away, not needed if not MSI */ | ||
446 | /* enable rfkill interrupt: hw bug w/a */ | ||
447 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
448 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
449 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
450 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
451 | } | 300 | } |
452 | 301 | ||
453 | bus->dev = &pdev->dev; | ||
454 | bus->irq = pdev->irq; | ||
455 | bus->ops = &bus_ops_pci; | ||
456 | |||
457 | err = iwl_probe(bus, &trans_ops_pcie, cfg); | 302 | err = iwl_probe(bus, &trans_ops_pcie, cfg); |
303 | #endif | ||
458 | if (err) | 304 | if (err) |
459 | goto out_disable_msi; | 305 | goto out_free_trans; |
306 | |||
460 | return 0; | 307 | return 0; |
461 | 308 | ||
462 | out_disable_msi: | 309 | out_free_trans: |
463 | pci_disable_msi(pdev); | 310 | iwl_trans_free(trans(bus)); |
464 | pci_iounmap(pdev, pci_bus->hw_base); | ||
465 | out_pci_release_regions: | ||
466 | pci_set_drvdata(pdev, NULL); | 311 | pci_set_drvdata(pdev, NULL); |
467 | pci_release_regions(pdev); | 312 | out_free_bus: |
468 | out_pci_disable_device: | 313 | kfree(bus->shrd); |
469 | pci_disable_device(pdev); | ||
470 | out_no_pci: | ||
471 | kfree(bus); | 314 | kfree(bus); |
472 | return err; | 315 | return err; |
473 | } | 316 | } |
@@ -475,18 +318,14 @@ out_no_pci: | |||
475 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) | 318 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) |
476 | { | 319 | { |
477 | struct iwl_bus *bus = pci_get_drvdata(pdev); | 320 | struct iwl_bus *bus = pci_get_drvdata(pdev); |
478 | struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); | ||
479 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
480 | struct iwl_shared *shrd = bus->shrd; | 321 | struct iwl_shared *shrd = bus->shrd; |
481 | 322 | ||
482 | iwl_remove(shrd->priv); | 323 | iwl_remove(shrd->priv); |
324 | iwl_trans_free(shrd->trans); | ||
483 | 325 | ||
484 | pci_disable_msi(pci_dev); | 326 | pci_set_drvdata(pdev, NULL); |
485 | pci_iounmap(pci_dev, pci_bus->hw_base); | ||
486 | pci_release_regions(pci_dev); | ||
487 | pci_disable_device(pci_dev); | ||
488 | pci_set_drvdata(pci_dev, NULL); | ||
489 | 327 | ||
328 | kfree(bus->shrd); | ||
490 | kfree(bus); | 329 | kfree(bus); |
491 | } | 330 | } |
492 | 331 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c7394ef2e490..fd008c4e41fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
436 | /* initialize to default */ | 436 | /* initialize to default */ |
437 | void iwl_power_initialize(struct iwl_priv *priv) | 437 | void iwl_power_initialize(struct iwl_priv *priv) |
438 | { | 438 | { |
439 | priv->power_data.bus_pm = bus_get_pm_support(bus(priv)); | 439 | priv->power_data.bus_pm = trans(priv)->pm_support; |
440 | 440 | ||
441 | priv->power_data.debug_sleep_level_override = -1; | 441 | priv->power_data.debug_sleep_level_override = -1; |
442 | 442 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 04975b7b65b3..63d4a4fc5b9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -543,8 +543,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); | |||
543 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); | 543 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); |
544 | void iwl_nic_config(struct iwl_priv *priv); | 544 | void iwl_nic_config(struct iwl_priv *priv); |
545 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); | 545 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); |
546 | void iwl_apm_stop(struct iwl_priv *priv); | ||
547 | int iwl_apm_init(struct iwl_priv *priv); | ||
548 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); | 546 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); |
549 | const char *get_cmd_string(u8 cmd); | 547 | const char *get_cmd_string(u8 cmd); |
550 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | 548 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index a56a77b8f926..df7ab332c833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include "iwl-testmode.h" | 79 | #include "iwl-testmode.h" |
80 | #include "iwl-trans.h" | 80 | #include "iwl-trans.h" |
81 | #include "iwl-bus.h" | 81 | #include "iwl-bus.h" |
82 | #include "iwl-fh.h" | ||
82 | 83 | ||
83 | /* The TLVs used in the gnl message policy between the kernel module and | 84 | /* The TLVs used in the gnl message policy between the kernel module and |
84 | * user space application. iwl_testmode_gnl_msg_policy is to be carried | 85 | * user space application. iwl_testmode_gnl_msg_policy is to be carried |
@@ -208,7 +209,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) | |||
208 | if (priv->testmode_trace.trace_enabled) { | 209 | if (priv->testmode_trace.trace_enabled) { |
209 | if (priv->testmode_trace.cpu_addr && | 210 | if (priv->testmode_trace.cpu_addr && |
210 | priv->testmode_trace.dma_addr) | 211 | priv->testmode_trace.dma_addr) |
211 | dma_free_coherent(bus(priv)->dev, | 212 | dma_free_coherent(trans(priv)->dev, |
212 | priv->testmode_trace.total_size, | 213 | priv->testmode_trace.total_size, |
213 | priv->testmode_trace.cpu_addr, | 214 | priv->testmode_trace.cpu_addr, |
214 | priv->testmode_trace.dma_addr); | 215 | priv->testmode_trace.dma_addr); |
@@ -288,7 +289,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
288 | static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) | 289 | static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) |
289 | { | 290 | { |
290 | struct iwl_priv *priv = hw->priv; | 291 | struct iwl_priv *priv = hw->priv; |
291 | u32 ofs, val32; | 292 | u32 ofs, val32, cmd; |
292 | u8 val8; | 293 | u8 val8; |
293 | struct sk_buff *skb; | 294 | struct sk_buff *skb; |
294 | int status = 0; | 295 | int status = 0; |
@@ -300,9 +301,22 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) | |||
300 | ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); | 301 | ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); |
301 | IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); | 302 | IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); |
302 | 303 | ||
303 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 304 | /* Allow access only to FH/CSR/HBUS in direct mode. |
305 | Since we don't have the upper bounds for the CSR and HBUS segments, | ||
306 | we will use only the upper bound of FH for sanity check. */ | ||
307 | cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); | ||
308 | if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 || | ||
309 | cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 || | ||
310 | cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) && | ||
311 | (ofs >= FH_MEM_UPPER_BOUND)) { | ||
312 | IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n", | ||
313 | FH_MEM_UPPER_BOUND); | ||
314 | return -EINVAL; | ||
315 | } | ||
316 | |||
317 | switch (cmd) { | ||
304 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: | 318 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: |
305 | val32 = iwl_read_direct32(bus(priv), ofs); | 319 | val32 = iwl_read_direct32(trans(priv), ofs); |
306 | IWL_INFO(priv, "32bit value to read 0x%x\n", val32); | 320 | IWL_INFO(priv, "32bit value to read 0x%x\n", val32); |
307 | 321 | ||
308 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 322 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
@@ -324,7 +338,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) | |||
324 | } else { | 338 | } else { |
325 | val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); | 339 | val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); |
326 | IWL_INFO(priv, "32bit value to write 0x%x\n", val32); | 340 | IWL_INFO(priv, "32bit value to write 0x%x\n", val32); |
327 | iwl_write_direct32(bus(priv), ofs, val32); | 341 | iwl_write_direct32(trans(priv), ofs, val32); |
328 | } | 342 | } |
329 | break; | 343 | break; |
330 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: | 344 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: |
@@ -334,11 +348,11 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) | |||
334 | } else { | 348 | } else { |
335 | val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); | 349 | val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); |
336 | IWL_INFO(priv, "8bit value to write 0x%x\n", val8); | 350 | IWL_INFO(priv, "8bit value to write 0x%x\n", val8); |
337 | iwl_write8(bus(priv), ofs, val8); | 351 | iwl_write8(trans(priv), ofs, val8); |
338 | } | 352 | } |
339 | break; | 353 | break; |
340 | case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: | 354 | case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: |
341 | val32 = iwl_read_prph(bus(priv), ofs); | 355 | val32 = iwl_read_prph(trans(priv), ofs); |
342 | IWL_INFO(priv, "32bit value to read 0x%x\n", val32); | 356 | IWL_INFO(priv, "32bit value to read 0x%x\n", val32); |
343 | 357 | ||
344 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 358 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
@@ -360,7 +374,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) | |||
360 | } else { | 374 | } else { |
361 | val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); | 375 | val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); |
362 | IWL_INFO(priv, "32bit value to write 0x%x\n", val32); | 376 | IWL_INFO(priv, "32bit value to write 0x%x\n", val32); |
363 | iwl_write_prph(bus(priv), ofs, val32); | 377 | iwl_write_prph(trans(priv), ofs, val32); |
364 | } | 378 | } |
365 | break; | 379 | break; |
366 | default: | 380 | default: |
@@ -536,7 +550,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
536 | break; | 550 | break; |
537 | 551 | ||
538 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: | 552 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: |
539 | devid = bus_get_hw_id(bus(priv)); | 553 | devid = trans(priv)->hw_id; |
540 | IWL_INFO(priv, "hw version: 0x%x\n", devid); | 554 | IWL_INFO(priv, "hw version: 0x%x\n", devid); |
541 | 555 | ||
542 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 556 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
@@ -615,7 +629,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | |||
615 | struct iwl_priv *priv = hw->priv; | 629 | struct iwl_priv *priv = hw->priv; |
616 | struct sk_buff *skb; | 630 | struct sk_buff *skb; |
617 | int status = 0; | 631 | int status = 0; |
618 | struct device *dev = bus(priv)->dev; | 632 | struct device *dev = trans(priv)->dev; |
619 | 633 | ||
620 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 634 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
621 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | 635 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: |
@@ -814,7 +828,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) | |||
814 | IWL_ERR(priv, "Error allocating memory\n"); | 828 | IWL_ERR(priv, "Error allocating memory\n"); |
815 | return -ENOMEM; | 829 | return -ENOMEM; |
816 | } | 830 | } |
817 | _iwl_read_targ_mem_words(bus(priv), ofs, | 831 | _iwl_read_targ_mem_words(trans(priv), ofs, |
818 | priv->testmode_sram.buff_addr, | 832 | priv->testmode_sram.buff_addr, |
819 | priv->testmode_sram.buff_size / 4); | 833 | priv->testmode_sram.buff_size / 4); |
820 | priv->testmode_sram.num_chunks = | 834 | priv->testmode_sram.num_chunks = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0ac9b4d30271..561865f29d56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -201,6 +201,7 @@ struct iwl_tx_queue { | |||
201 | * @rxq: all the RX queue data | 201 | * @rxq: all the RX queue data |
202 | * @rx_replenish: work that will be called when buffers need to be allocated | 202 | * @rx_replenish: work that will be called when buffers need to be allocated |
203 | * @trans: pointer to the generic transport area | 203 | * @trans: pointer to the generic transport area |
204 | * @irq_requested: true when the irq has been requested | ||
204 | * @scd_base_addr: scheduler sram base address in SRAM | 205 | * @scd_base_addr: scheduler sram base address in SRAM |
205 | * @scd_bc_tbls: pointer to the byte count table of the scheduler | 206 | * @scd_bc_tbls: pointer to the byte count table of the scheduler |
206 | * @kw: keep warm address | 207 | * @kw: keep warm address |
@@ -211,6 +212,8 @@ struct iwl_tx_queue { | |||
211 | * @txq_ctx_active_msk: what queue is active | 212 | * @txq_ctx_active_msk: what queue is active |
212 | * queue_stopped: tracks what queue is stopped | 213 | * queue_stopped: tracks what queue is stopped |
213 | * queue_stop_count: tracks what SW queue is stopped | 214 | * queue_stop_count: tracks what SW queue is stopped |
215 | * @pci_dev: basic pci-network driver stuff | ||
216 | * @hw_base: pci hardware address support | ||
214 | */ | 217 | */ |
215 | struct iwl_trans_pcie { | 218 | struct iwl_trans_pcie { |
216 | struct iwl_rx_queue rxq; | 219 | struct iwl_rx_queue rxq; |
@@ -223,6 +226,7 @@ struct iwl_trans_pcie { | |||
223 | int ict_index; | 226 | int ict_index; |
224 | u32 inta; | 227 | u32 inta; |
225 | bool use_ict; | 228 | bool use_ict; |
229 | bool irq_requested; | ||
226 | struct tasklet_struct irq_tasklet; | 230 | struct tasklet_struct irq_tasklet; |
227 | struct isr_statistics isr_stats; | 231 | struct isr_statistics isr_stats; |
228 | 232 | ||
@@ -241,6 +245,10 @@ struct iwl_trans_pcie { | |||
241 | #define IWL_MAX_HW_QUEUES 32 | 245 | #define IWL_MAX_HW_QUEUES 32 |
242 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; | 246 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; |
243 | atomic_t queue_stop_count[4]; | 247 | atomic_t queue_stop_count[4]; |
248 | |||
249 | /* PCI bus related data */ | ||
250 | struct pci_dev *pci_dev; | ||
251 | void __iomem *hw_base; | ||
244 | }; | 252 | }; |
245 | 253 | ||
246 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 254 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
@@ -258,7 +266,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
258 | /***************************************************** | 266 | /***************************************************** |
259 | * ICT | 267 | * ICT |
260 | ******************************************************/ | 268 | ******************************************************/ |
261 | int iwl_reset_ict(struct iwl_trans *trans); | 269 | void iwl_reset_ict(struct iwl_trans *trans); |
262 | void iwl_disable_ict(struct iwl_trans *trans); | 270 | void iwl_disable_ict(struct iwl_trans *trans); |
263 | int iwl_alloc_isr_ict(struct iwl_trans *trans); | 271 | int iwl_alloc_isr_ict(struct iwl_trans *trans); |
264 | void iwl_free_isr_ict(struct iwl_trans *trans); | 272 | void iwl_free_isr_ict(struct iwl_trans *trans); |
@@ -311,12 +319,12 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) | |||
311 | clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 319 | clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); |
312 | 320 | ||
313 | /* disable interrupts from uCode/NIC to host */ | 321 | /* disable interrupts from uCode/NIC to host */ |
314 | iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); | 322 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
315 | 323 | ||
316 | /* acknowledge/clear/reset any interrupts still pending | 324 | /* acknowledge/clear/reset any interrupts still pending |
317 | * from uCode or flow handler (Rx/Tx DMA) */ | 325 | * from uCode or flow handler (Rx/Tx DMA) */ |
318 | iwl_write32(bus(trans), CSR_INT, 0xffffffff); | 326 | iwl_write32(trans, CSR_INT, 0xffffffff); |
319 | iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff); | 327 | iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff); |
320 | IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); | 328 | IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); |
321 | } | 329 | } |
322 | 330 | ||
@@ -327,7 +335,7 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans) | |||
327 | 335 | ||
328 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); | 336 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); |
329 | set_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 337 | set_bit(STATUS_INT_ENABLED, &trans->shrd->status); |
330 | iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask); | 338 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); |
331 | } | 339 | } |
332 | 340 | ||
333 | /* | 341 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2900db973aaa..3826852ec5f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -35,6 +35,10 @@ | |||
35 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
36 | #include "iwl-trans-pcie-int.h" | 36 | #include "iwl-trans-pcie-int.h" |
37 | 37 | ||
38 | #ifdef CONFIG_IWLWIFI_IDI | ||
39 | #include "iwl-amfh.h" | ||
40 | #endif | ||
41 | |||
38 | /****************************************************************************** | 42 | /****************************************************************************** |
39 | * | 43 | * |
40 | * RX path functions | 44 | * RX path functions |
@@ -140,30 +144,30 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
140 | /* shadow register enabled */ | 144 | /* shadow register enabled */ |
141 | /* Device expects a multiple of 8 */ | 145 | /* Device expects a multiple of 8 */ |
142 | q->write_actual = (q->write & ~0x7); | 146 | q->write_actual = (q->write & ~0x7); |
143 | iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual); | 147 | iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); |
144 | } else { | 148 | } else { |
145 | /* If power-saving is in use, make sure device is awake */ | 149 | /* If power-saving is in use, make sure device is awake */ |
146 | if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) { | 150 | if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) { |
147 | reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); | 151 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); |
148 | 152 | ||
149 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 153 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
150 | IWL_DEBUG_INFO(trans, | 154 | IWL_DEBUG_INFO(trans, |
151 | "Rx queue requesting wakeup," | 155 | "Rx queue requesting wakeup," |
152 | " GP1 = 0x%x\n", reg); | 156 | " GP1 = 0x%x\n", reg); |
153 | iwl_set_bit(bus(trans), CSR_GP_CNTRL, | 157 | iwl_set_bit(trans, CSR_GP_CNTRL, |
154 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 158 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
155 | goto exit_unlock; | 159 | goto exit_unlock; |
156 | } | 160 | } |
157 | 161 | ||
158 | q->write_actual = (q->write & ~0x7); | 162 | q->write_actual = (q->write & ~0x7); |
159 | iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, | 163 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, |
160 | q->write_actual); | 164 | q->write_actual); |
161 | 165 | ||
162 | /* Else device is assumed to be awake */ | 166 | /* Else device is assumed to be awake */ |
163 | } else { | 167 | } else { |
164 | /* Device expects a multiple of 8 */ | 168 | /* Device expects a multiple of 8 */ |
165 | q->write_actual = (q->write & ~0x7); | 169 | q->write_actual = (q->write & ~0x7); |
166 | iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, | 170 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, |
167 | q->write_actual); | 171 | q->write_actual); |
168 | } | 172 | } |
169 | } | 173 | } |
@@ -308,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
308 | BUG_ON(rxb->page); | 312 | BUG_ON(rxb->page); |
309 | rxb->page = page; | 313 | rxb->page = page; |
310 | /* Get physical address of the RB */ | 314 | /* Get physical address of the RB */ |
311 | rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0, | 315 | rxb->page_dma = dma_map_page(trans->dev, page, 0, |
312 | PAGE_SIZE << hw_params(trans).rx_page_order, | 316 | PAGE_SIZE << hw_params(trans).rx_page_order, |
313 | DMA_FROM_DEVICE); | 317 | DMA_FROM_DEVICE); |
314 | /* dma address must be no more than 36 bits */ | 318 | /* dma address must be no more than 36 bits */ |
@@ -414,7 +418,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
414 | 418 | ||
415 | rxq->queue[i] = NULL; | 419 | rxq->queue[i] = NULL; |
416 | 420 | ||
417 | dma_unmap_page(bus(trans)->dev, rxb->page_dma, | 421 | dma_unmap_page(trans->dev, rxb->page_dma, |
418 | PAGE_SIZE << hw_params(trans).rx_page_order, | 422 | PAGE_SIZE << hw_params(trans).rx_page_order, |
419 | DMA_FROM_DEVICE); | 423 | DMA_FROM_DEVICE); |
420 | pkt = rxb_addr(rxb); | 424 | pkt = rxb_addr(rxb); |
@@ -485,7 +489,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
485 | * rx_free list for reuse later. */ | 489 | * rx_free list for reuse later. */ |
486 | spin_lock_irqsave(&rxq->lock, flags); | 490 | spin_lock_irqsave(&rxq->lock, flags); |
487 | if (rxb->page != NULL) { | 491 | if (rxb->page != NULL) { |
488 | rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page, | 492 | rxb->page_dma = dma_map_page(trans->dev, rxb->page, |
489 | 0, PAGE_SIZE << | 493 | 0, PAGE_SIZE << |
490 | hw_params(trans).rx_page_order, | 494 | hw_params(trans).rx_page_order, |
491 | DMA_FROM_DEVICE); | 495 | DMA_FROM_DEVICE); |
@@ -612,7 +616,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
612 | return; | 616 | return; |
613 | } | 617 | } |
614 | 618 | ||
615 | iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table)); | 619 | iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table)); |
616 | 620 | ||
617 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { | 621 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { |
618 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); | 622 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); |
@@ -673,9 +677,9 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
673 | struct iwl_priv *priv = priv(trans); | 677 | struct iwl_priv *priv = priv(trans); |
674 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ | 678 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ |
675 | if (cfg(priv)->internal_wimax_coex && | 679 | if (cfg(priv)->internal_wimax_coex && |
676 | (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & | 680 | (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & |
677 | APMS_CLK_VAL_MRB_FUNC_MODE) || | 681 | APMS_CLK_VAL_MRB_FUNC_MODE) || |
678 | (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & | 682 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & |
679 | APMG_PS_CTRL_VAL_RESET_REQ))) { | 683 | APMG_PS_CTRL_VAL_RESET_REQ))) { |
680 | /* | 684 | /* |
681 | * Keep the restart process from trying to send host | 685 | * Keep the restart process from trying to send host |
@@ -741,18 +745,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
741 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | 745 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); |
742 | 746 | ||
743 | /* Make sure device is powered up for SRAM reads */ | 747 | /* Make sure device is powered up for SRAM reads */ |
744 | spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); | 748 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
745 | iwl_grab_nic_access(bus(trans)); | 749 | iwl_grab_nic_access(trans); |
746 | 750 | ||
747 | /* Set starting address; reads will auto-increment */ | 751 | /* Set starting address; reads will auto-increment */ |
748 | iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); | 752 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); |
749 | rmb(); | 753 | rmb(); |
750 | 754 | ||
751 | /* "time" is actually "data" for mode 0 (no timestamp). | 755 | /* "time" is actually "data" for mode 0 (no timestamp). |
752 | * place event id # at far right for easier visual parsing. */ | 756 | * place event id # at far right for easier visual parsing. */ |
753 | for (i = 0; i < num_events; i++) { | 757 | for (i = 0; i < num_events; i++) { |
754 | ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); | 758 | ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
755 | time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); | 759 | time = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
756 | if (mode == 0) { | 760 | if (mode == 0) { |
757 | /* data, ev */ | 761 | /* data, ev */ |
758 | if (bufsz) { | 762 | if (bufsz) { |
@@ -766,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
766 | time, ev); | 770 | time, ev); |
767 | } | 771 | } |
768 | } else { | 772 | } else { |
769 | data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); | 773 | data = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
770 | if (bufsz) { | 774 | if (bufsz) { |
771 | pos += scnprintf(*buf + pos, bufsz - pos, | 775 | pos += scnprintf(*buf + pos, bufsz - pos, |
772 | "EVT_LOGT:%010u:0x%08x:%04u\n", | 776 | "EVT_LOGT:%010u:0x%08x:%04u\n", |
@@ -781,8 +785,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
781 | } | 785 | } |
782 | 786 | ||
783 | /* Allow device to power down */ | 787 | /* Allow device to power down */ |
784 | iwl_release_nic_access(bus(trans)); | 788 | iwl_release_nic_access(trans); |
785 | spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); | 789 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
786 | return pos; | 790 | return pos; |
787 | } | 791 | } |
788 | 792 | ||
@@ -859,10 +863,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
859 | } | 863 | } |
860 | 864 | ||
861 | /* event log header */ | 865 | /* event log header */ |
862 | capacity = iwl_read_targ_mem(bus(trans), base); | 866 | capacity = iwl_read_targ_mem(trans, base); |
863 | mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); | 867 | mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); |
864 | num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); | 868 | num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); |
865 | next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); | 869 | next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); |
866 | 870 | ||
867 | if (capacity > logsize) { | 871 | if (capacity > logsize) { |
868 | IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " | 872 | IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " |
@@ -958,7 +962,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
958 | * hardware bugs here by ACKing all the possible interrupts so that | 962 | * hardware bugs here by ACKing all the possible interrupts so that |
959 | * interrupt coalescing can still be achieved. | 963 | * interrupt coalescing can still be achieved. |
960 | */ | 964 | */ |
961 | iwl_write32(bus(trans), CSR_INT, | 965 | iwl_write32(trans, CSR_INT, |
962 | trans_pcie->inta | ~trans_pcie->inta_mask); | 966 | trans_pcie->inta | ~trans_pcie->inta_mask); |
963 | 967 | ||
964 | inta = trans_pcie->inta; | 968 | inta = trans_pcie->inta; |
@@ -966,7 +970,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
966 | #ifdef CONFIG_IWLWIFI_DEBUG | 970 | #ifdef CONFIG_IWLWIFI_DEBUG |
967 | if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { | 971 | if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { |
968 | /* just for debug */ | 972 | /* just for debug */ |
969 | inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); | 973 | inta_mask = iwl_read32(trans, CSR_INT_MASK); |
970 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", | 974 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", |
971 | inta, inta_mask); | 975 | inta, inta_mask); |
972 | } | 976 | } |
@@ -1014,7 +1018,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1014 | /* HW RF KILL switch toggled */ | 1018 | /* HW RF KILL switch toggled */ |
1015 | if (inta & CSR_INT_BIT_RF_KILL) { | 1019 | if (inta & CSR_INT_BIT_RF_KILL) { |
1016 | int hw_rf_kill = 0; | 1020 | int hw_rf_kill = 0; |
1017 | if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & | 1021 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & |
1018 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1022 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) |
1019 | hw_rf_kill = 1; | 1023 | hw_rf_kill = 1; |
1020 | 1024 | ||
@@ -1078,12 +1082,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1078 | IWL_DEBUG_ISR(trans, "Rx interrupt\n"); | 1082 | IWL_DEBUG_ISR(trans, "Rx interrupt\n"); |
1079 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1083 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
1080 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1084 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1081 | iwl_write32(bus(trans), CSR_FH_INT_STATUS, | 1085 | iwl_write32(trans, CSR_FH_INT_STATUS, |
1082 | CSR_FH_INT_RX_MASK); | 1086 | CSR_FH_INT_RX_MASK); |
1083 | } | 1087 | } |
1084 | if (inta & CSR_INT_BIT_RX_PERIODIC) { | 1088 | if (inta & CSR_INT_BIT_RX_PERIODIC) { |
1085 | handled |= CSR_INT_BIT_RX_PERIODIC; | 1089 | handled |= CSR_INT_BIT_RX_PERIODIC; |
1086 | iwl_write32(bus(trans), | 1090 | iwl_write32(trans, |
1087 | CSR_INT, CSR_INT_BIT_RX_PERIODIC); | 1091 | CSR_INT, CSR_INT_BIT_RX_PERIODIC); |
1088 | } | 1092 | } |
1089 | /* Sending RX interrupt require many steps to be done in the | 1093 | /* Sending RX interrupt require many steps to be done in the |
@@ -1098,10 +1102,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1098 | */ | 1102 | */ |
1099 | 1103 | ||
1100 | /* Disable periodic interrupt; we use it as just a one-shot. */ | 1104 | /* Disable periodic interrupt; we use it as just a one-shot. */ |
1101 | iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, | 1105 | iwl_write8(trans, CSR_INT_PERIODIC_REG, |
1102 | CSR_INT_PERIODIC_DIS); | 1106 | CSR_INT_PERIODIC_DIS); |
1107 | #ifdef CONFIG_IWLWIFI_IDI | ||
1108 | iwl_amfh_rx_handler(); | ||
1109 | #else | ||
1103 | iwl_rx_handle(trans); | 1110 | iwl_rx_handle(trans); |
1104 | 1111 | #endif | |
1105 | /* | 1112 | /* |
1106 | * Enable periodic interrupt in 8 msec only if we received | 1113 | * Enable periodic interrupt in 8 msec only if we received |
1107 | * real RX interrupt (instead of just periodic int), to catch | 1114 | * real RX interrupt (instead of just periodic int), to catch |
@@ -1110,7 +1117,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1110 | * to extend the periodic interrupt; one-shot is enough. | 1117 | * to extend the periodic interrupt; one-shot is enough. |
1111 | */ | 1118 | */ |
1112 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | 1119 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) |
1113 | iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, | 1120 | iwl_write8(trans, CSR_INT_PERIODIC_REG, |
1114 | CSR_INT_PERIODIC_ENA); | 1121 | CSR_INT_PERIODIC_ENA); |
1115 | 1122 | ||
1116 | isr_stats->rx++; | 1123 | isr_stats->rx++; |
@@ -1118,7 +1125,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1118 | 1125 | ||
1119 | /* This "Tx" DMA channel is used only for loading uCode */ | 1126 | /* This "Tx" DMA channel is used only for loading uCode */ |
1120 | if (inta & CSR_INT_BIT_FH_TX) { | 1127 | if (inta & CSR_INT_BIT_FH_TX) { |
1121 | iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); | 1128 | iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); |
1122 | IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); | 1129 | IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); |
1123 | isr_stats->tx++; | 1130 | isr_stats->tx++; |
1124 | handled |= CSR_INT_BIT_FH_TX; | 1131 | handled |= CSR_INT_BIT_FH_TX; |
@@ -1142,8 +1149,10 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1142 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) | 1149 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) |
1143 | iwl_enable_interrupts(trans); | 1150 | iwl_enable_interrupts(trans); |
1144 | /* Re-enable RF_KILL if it occurred */ | 1151 | /* Re-enable RF_KILL if it occurred */ |
1145 | else if (handled & CSR_INT_BIT_RF_KILL) | 1152 | else if (handled & CSR_INT_BIT_RF_KILL) { |
1146 | iwl_enable_rfkill_int(priv(trans)); | 1153 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); |
1154 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
1155 | } | ||
1147 | } | 1156 | } |
1148 | 1157 | ||
1149 | /****************************************************************************** | 1158 | /****************************************************************************** |
@@ -1164,7 +1173,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) | |||
1164 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1173 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1165 | 1174 | ||
1166 | if (trans_pcie->ict_tbl) { | 1175 | if (trans_pcie->ict_tbl) { |
1167 | dma_free_coherent(bus(trans)->dev, ICT_SIZE, | 1176 | dma_free_coherent(trans->dev, ICT_SIZE, |
1168 | trans_pcie->ict_tbl, | 1177 | trans_pcie->ict_tbl, |
1169 | trans_pcie->ict_tbl_dma); | 1178 | trans_pcie->ict_tbl_dma); |
1170 | trans_pcie->ict_tbl = NULL; | 1179 | trans_pcie->ict_tbl = NULL; |
@@ -1184,7 +1193,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
1184 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1193 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1185 | 1194 | ||
1186 | trans_pcie->ict_tbl = | 1195 | trans_pcie->ict_tbl = |
1187 | dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, | 1196 | dma_alloc_coherent(trans->dev, ICT_SIZE, |
1188 | &trans_pcie->ict_tbl_dma, | 1197 | &trans_pcie->ict_tbl_dma, |
1189 | GFP_KERNEL); | 1198 | GFP_KERNEL); |
1190 | if (!trans_pcie->ict_tbl) | 1199 | if (!trans_pcie->ict_tbl) |
@@ -1213,7 +1222,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
1213 | /* Device is going up inform it about using ICT interrupt table, | 1222 | /* Device is going up inform it about using ICT interrupt table, |
1214 | * also we need to tell the driver to start using ICT interrupt. | 1223 | * also we need to tell the driver to start using ICT interrupt. |
1215 | */ | 1224 | */ |
1216 | int iwl_reset_ict(struct iwl_trans *trans) | 1225 | void iwl_reset_ict(struct iwl_trans *trans) |
1217 | { | 1226 | { |
1218 | u32 val; | 1227 | u32 val; |
1219 | unsigned long flags; | 1228 | unsigned long flags; |
@@ -1221,7 +1230,7 @@ int iwl_reset_ict(struct iwl_trans *trans) | |||
1221 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1230 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1222 | 1231 | ||
1223 | if (!trans_pcie->ict_tbl) | 1232 | if (!trans_pcie->ict_tbl) |
1224 | return 0; | 1233 | return; |
1225 | 1234 | ||
1226 | spin_lock_irqsave(&trans->shrd->lock, flags); | 1235 | spin_lock_irqsave(&trans->shrd->lock, flags); |
1227 | iwl_disable_interrupts(trans); | 1236 | iwl_disable_interrupts(trans); |
@@ -1235,14 +1244,12 @@ int iwl_reset_ict(struct iwl_trans *trans) | |||
1235 | 1244 | ||
1236 | IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); | 1245 | IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); |
1237 | 1246 | ||
1238 | iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); | 1247 | iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val); |
1239 | trans_pcie->use_ict = true; | 1248 | trans_pcie->use_ict = true; |
1240 | trans_pcie->ict_index = 0; | 1249 | trans_pcie->ict_index = 0; |
1241 | iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); | 1250 | iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); |
1242 | iwl_enable_interrupts(trans); | 1251 | iwl_enable_interrupts(trans); |
1243 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1252 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
1244 | |||
1245 | return 0; | ||
1246 | } | 1253 | } |
1247 | 1254 | ||
1248 | /* Device is going down disable ict interrupt usage */ | 1255 | /* Device is going down disable ict interrupt usage */ |
@@ -1280,11 +1287,11 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1280 | * back-to-back ISRs and sporadic interrupts from our NIC. | 1287 | * back-to-back ISRs and sporadic interrupts from our NIC. |
1281 | * If we have something to service, the tasklet will re-enable ints. | 1288 | * If we have something to service, the tasklet will re-enable ints. |
1282 | * If we *don't* have something, we'll re-enable before leaving here. */ | 1289 | * If we *don't* have something, we'll re-enable before leaving here. */ |
1283 | inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ | 1290 | inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ |
1284 | iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); | 1291 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
1285 | 1292 | ||
1286 | /* Discover which interrupts are active/pending */ | 1293 | /* Discover which interrupts are active/pending */ |
1287 | inta = iwl_read32(bus(trans), CSR_INT); | 1294 | inta = iwl_read32(trans, CSR_INT); |
1288 | 1295 | ||
1289 | /* Ignore interrupt if there's nothing in NIC to service. | 1296 | /* Ignore interrupt if there's nothing in NIC to service. |
1290 | * This may be due to IRQ shared with another device, | 1297 | * This may be due to IRQ shared with another device, |
@@ -1303,7 +1310,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1303 | 1310 | ||
1304 | #ifdef CONFIG_IWLWIFI_DEBUG | 1311 | #ifdef CONFIG_IWLWIFI_DEBUG |
1305 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 1312 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { |
1306 | inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS); | 1313 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); |
1307 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " | 1314 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " |
1308 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | 1315 | "fh 0x%08x\n", inta, inta_mask, inta_fh); |
1309 | } | 1316 | } |
@@ -1369,8 +1376,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1369 | * If we have something to service, the tasklet will re-enable ints. | 1376 | * If we have something to service, the tasklet will re-enable ints. |
1370 | * If we *don't* have something, we'll re-enable before leaving here. | 1377 | * If we *don't* have something, we'll re-enable before leaving here. |
1371 | */ | 1378 | */ |
1372 | inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ | 1379 | inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ |
1373 | iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); | 1380 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
1374 | 1381 | ||
1375 | 1382 | ||
1376 | /* Ignore interrupt if there's nothing in NIC to service. | 1383 | /* Ignore interrupt if there's nothing in NIC to service. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 30814b55705e..08e0a7da48a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -100,7 +100,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
100 | 100 | ||
101 | if (hw_params(trans).shadow_reg_enable) { | 101 | if (hw_params(trans).shadow_reg_enable) { |
102 | /* shadow register enabled */ | 102 | /* shadow register enabled */ |
103 | iwl_write32(bus(trans), HBUS_TARG_WRPTR, | 103 | iwl_write32(trans, HBUS_TARG_WRPTR, |
104 | txq->q.write_ptr | (txq_id << 8)); | 104 | txq->q.write_ptr | (txq_id << 8)); |
105 | } else { | 105 | } else { |
106 | /* if we're trying to save power */ | 106 | /* if we're trying to save power */ |
@@ -108,18 +108,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
108 | /* wake up nic if it's powered down ... | 108 | /* wake up nic if it's powered down ... |
109 | * uCode will wake up, and interrupt us again, so next | 109 | * uCode will wake up, and interrupt us again, so next |
110 | * time we'll skip this part. */ | 110 | * time we'll skip this part. */ |
111 | reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); | 111 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); |
112 | 112 | ||
113 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 113 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
114 | IWL_DEBUG_INFO(trans, | 114 | IWL_DEBUG_INFO(trans, |
115 | "Tx queue %d requesting wakeup," | 115 | "Tx queue %d requesting wakeup," |
116 | " GP1 = 0x%x\n", txq_id, reg); | 116 | " GP1 = 0x%x\n", txq_id, reg); |
117 | iwl_set_bit(bus(trans), CSR_GP_CNTRL, | 117 | iwl_set_bit(trans, CSR_GP_CNTRL, |
118 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 118 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
119 | return; | 119 | return; |
120 | } | 120 | } |
121 | 121 | ||
122 | iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, | 122 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
123 | txq->q.write_ptr | (txq_id << 8)); | 123 | txq->q.write_ptr | (txq_id << 8)); |
124 | 124 | ||
125 | /* | 125 | /* |
@@ -128,7 +128,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
128 | * trying to tx (during RFKILL, we're not trying to tx). | 128 | * trying to tx (during RFKILL, we're not trying to tx). |
129 | */ | 129 | */ |
130 | } else | 130 | } else |
131 | iwl_write32(bus(trans), HBUS_TARG_WRPTR, | 131 | iwl_write32(trans, HBUS_TARG_WRPTR, |
132 | txq->q.write_ptr | (txq_id << 8)); | 132 | txq->q.write_ptr | (txq_id << 8)); |
133 | } | 133 | } |
134 | txq->need_update = 0; | 134 | txq->need_update = 0; |
@@ -190,14 +190,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | |||
190 | 190 | ||
191 | /* Unmap tx_cmd */ | 191 | /* Unmap tx_cmd */ |
192 | if (num_tbs) | 192 | if (num_tbs) |
193 | dma_unmap_single(bus(trans)->dev, | 193 | dma_unmap_single(trans->dev, |
194 | dma_unmap_addr(meta, mapping), | 194 | dma_unmap_addr(meta, mapping), |
195 | dma_unmap_len(meta, len), | 195 | dma_unmap_len(meta, len), |
196 | DMA_BIDIRECTIONAL); | 196 | DMA_BIDIRECTIONAL); |
197 | 197 | ||
198 | /* Unmap chunks, if any. */ | 198 | /* Unmap chunks, if any. */ |
199 | for (i = 1; i < num_tbs; i++) | 199 | for (i = 1; i < num_tbs; i++) |
200 | dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i), | 200 | dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), |
201 | iwl_tfd_tb_get_len(tfd, i), dma_dir); | 201 | iwl_tfd_tb_get_len(tfd, i), dma_dir); |
202 | } | 202 | } |
203 | 203 | ||
@@ -383,14 +383,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, | |||
383 | tbl_dw_addr = trans_pcie->scd_base_addr + | 383 | tbl_dw_addr = trans_pcie->scd_base_addr + |
384 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); | 384 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
385 | 385 | ||
386 | tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr); | 386 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); |
387 | 387 | ||
388 | if (txq_id & 0x1) | 388 | if (txq_id & 0x1) |
389 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | 389 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); |
390 | else | 390 | else |
391 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | 391 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); |
392 | 392 | ||
393 | iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw); | 393 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); |
394 | 394 | ||
395 | return 0; | 395 | return 0; |
396 | } | 396 | } |
@@ -399,7 +399,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) | |||
399 | { | 399 | { |
400 | /* Simply stop the queue, but don't change any configuration; | 400 | /* Simply stop the queue, but don't change any configuration; |
401 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | 401 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ |
402 | iwl_write_prph(bus(trans), | 402 | iwl_write_prph(trans, |
403 | SCD_QUEUE_STATUS_BITS(txq_id), | 403 | SCD_QUEUE_STATUS_BITS(txq_id), |
404 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | 404 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| |
405 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | 405 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
@@ -409,9 +409,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, | |||
409 | int txq_id, u32 index) | 409 | int txq_id, u32 index) |
410 | { | 410 | { |
411 | IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); | 411 | IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); |
412 | iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, | 412 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
413 | (index & 0xff) | (txq_id << 8)); | 413 | (index & 0xff) | (txq_id << 8)); |
414 | iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); | 414 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); |
415 | } | 415 | } |
416 | 416 | ||
417 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | 417 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, |
@@ -423,7 +423,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
423 | int active = | 423 | int active = |
424 | test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0; | 424 | test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0; |
425 | 425 | ||
426 | iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id), | 426 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), |
427 | (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 427 | (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
428 | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | | 428 | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | |
429 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | | 429 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
@@ -431,9 +431,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
431 | 431 | ||
432 | txq->sched_retry = scd_retry; | 432 | txq->sched_retry = scd_retry; |
433 | 433 | ||
434 | IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", | 434 | if (active) |
435 | active ? "Activate" : "Deactivate", | 435 | IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n", |
436 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); | 436 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); |
437 | else | ||
438 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n", | ||
439 | scd_retry ? "BA" : "AC/CMD", txq_id); | ||
437 | } | 440 | } |
438 | 441 | ||
439 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, | 442 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, |
@@ -498,10 +501,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | |||
498 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); | 501 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); |
499 | 502 | ||
500 | /* Set this queue as a chain-building queue */ | 503 | /* Set this queue as a chain-building queue */ |
501 | iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<<txq_id)); | 504 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, (1<<txq_id)); |
502 | 505 | ||
503 | /* enable aggregations for the queue */ | 506 | /* enable aggregations for the queue */ |
504 | iwl_set_bits_prph(bus(trans), SCD_AGGR_SEL, (1<<txq_id)); | 507 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, (1<<txq_id)); |
505 | 508 | ||
506 | /* Place first TFD at index corresponding to start sequence number. | 509 | /* Place first TFD at index corresponding to start sequence number. |
507 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 510 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
@@ -510,7 +513,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | |||
510 | iwl_trans_set_wr_ptrs(trans, txq_id, ssn); | 513 | iwl_trans_set_wr_ptrs(trans, txq_id, ssn); |
511 | 514 | ||
512 | /* Set up Tx window size and frame limit for this queue */ | 515 | /* Set up Tx window size and frame limit for this queue */ |
513 | iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + | 516 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
514 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + | 517 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + |
515 | sizeof(u32), | 518 | sizeof(u32), |
516 | ((frame_limit << | 519 | ((frame_limit << |
@@ -520,7 +523,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | |||
520 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 523 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
521 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 524 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
522 | 525 | ||
523 | iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); | 526 | iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); |
524 | 527 | ||
525 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 528 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ |
526 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], | 529 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], |
@@ -584,7 +587,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) | |||
584 | 587 | ||
585 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); | 588 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); |
586 | 589 | ||
587 | iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); | 590 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id)); |
588 | 591 | ||
589 | trans_pcie->agg_txq[sta_id][tid] = 0; | 592 | trans_pcie->agg_txq[sta_id][tid] = 0; |
590 | trans_pcie->txq[txq_id].q.read_ptr = 0; | 593 | trans_pcie->txq[txq_id].q.read_ptr = 0; |
@@ -592,7 +595,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) | |||
592 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | 595 | /* supposes that ssn_idx is valid (!= 0xFFF) */ |
593 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); | 596 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); |
594 | 597 | ||
595 | iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); | 598 | iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); |
596 | iwl_txq_ctx_deactivate(trans_pcie, txq_id); | 599 | iwl_txq_ctx_deactivate(trans_pcie, txq_id); |
597 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); | 600 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); |
598 | return 0; | 601 | return 0; |
@@ -725,9 +728,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
725 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 728 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, |
726 | q->write_ptr, idx, trans->shrd->cmd_queue); | 729 | q->write_ptr, idx, trans->shrd->cmd_queue); |
727 | 730 | ||
728 | phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size, | 731 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
729 | DMA_BIDIRECTIONAL); | 732 | DMA_BIDIRECTIONAL); |
730 | if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { | 733 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { |
731 | idx = -ENOMEM; | 734 | idx = -ENOMEM; |
732 | goto out; | 735 | goto out; |
733 | } | 736 | } |
@@ -748,10 +751,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
748 | continue; | 751 | continue; |
749 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 752 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) |
750 | continue; | 753 | continue; |
751 | phys_addr = dma_map_single(bus(trans)->dev, | 754 | phys_addr = dma_map_single(trans->dev, |
752 | (void *)cmd->data[i], | 755 | (void *)cmd->data[i], |
753 | cmd->len[i], DMA_BIDIRECTIONAL); | 756 | cmd->len[i], DMA_BIDIRECTIONAL); |
754 | if (dma_mapping_error(bus(trans)->dev, phys_addr)) { | 757 | if (dma_mapping_error(trans->dev, phys_addr)) { |
755 | iwlagn_unmap_tfd(trans, out_meta, | 758 | iwlagn_unmap_tfd(trans, out_meta, |
756 | &txq->tfds[q->write_ptr], | 759 | &txq->tfds[q->write_ptr], |
757 | DMA_BIDIRECTIONAL); | 760 | DMA_BIDIRECTIONAL); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 5e6af4ba9652..836caf9c68b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -60,8 +60,11 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | #include <linux/pci.h> | ||
64 | #include <linux/pci-aspm.h> | ||
63 | #include <linux/interrupt.h> | 65 | #include <linux/interrupt.h> |
64 | #include <linux/debugfs.h> | 66 | #include <linux/debugfs.h> |
67 | #include <linux/sched.h> | ||
65 | #include <linux/bitops.h> | 68 | #include <linux/bitops.h> |
66 | #include <linux/gfp.h> | 69 | #include <linux/gfp.h> |
67 | 70 | ||
@@ -72,13 +75,14 @@ | |||
72 | #include "iwl-shared.h" | 75 | #include "iwl-shared.h" |
73 | #include "iwl-eeprom.h" | 76 | #include "iwl-eeprom.h" |
74 | #include "iwl-agn-hw.h" | 77 | #include "iwl-agn-hw.h" |
78 | #include "iwl-core.h" | ||
75 | 79 | ||
76 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | 80 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) |
77 | { | 81 | { |
78 | struct iwl_trans_pcie *trans_pcie = | 82 | struct iwl_trans_pcie *trans_pcie = |
79 | IWL_TRANS_GET_PCIE_TRANS(trans); | 83 | IWL_TRANS_GET_PCIE_TRANS(trans); |
80 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 84 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
81 | struct device *dev = bus(trans)->dev; | 85 | struct device *dev = trans->dev; |
82 | 86 | ||
83 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | 87 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); |
84 | 88 | ||
@@ -122,7 +126,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | |||
122 | /* In the reset function, these buffers may have been allocated | 126 | /* In the reset function, these buffers may have been allocated |
123 | * to an SKB, so we need to unmap and free potential storage */ | 127 | * to an SKB, so we need to unmap and free potential storage */ |
124 | if (rxq->pool[i].page != NULL) { | 128 | if (rxq->pool[i].page != NULL) { |
125 | dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma, | 129 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, |
126 | PAGE_SIZE << hw_params(trans).rx_page_order, | 130 | PAGE_SIZE << hw_params(trans).rx_page_order, |
127 | DMA_FROM_DEVICE); | 131 | DMA_FROM_DEVICE); |
128 | __free_pages(rxq->pool[i].page, | 132 | __free_pages(rxq->pool[i].page, |
@@ -146,17 +150,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | |||
146 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | 150 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; |
147 | 151 | ||
148 | /* Stop Rx DMA */ | 152 | /* Stop Rx DMA */ |
149 | iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | 153 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); |
150 | 154 | ||
151 | /* Reset driver's Rx queue write index */ | 155 | /* Reset driver's Rx queue write index */ |
152 | iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | 156 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); |
153 | 157 | ||
154 | /* Tell device where to find RBD circular buffer in DRAM */ | 158 | /* Tell device where to find RBD circular buffer in DRAM */ |
155 | iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG, | 159 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, |
156 | (u32)(rxq->bd_dma >> 8)); | 160 | (u32)(rxq->bd_dma >> 8)); |
157 | 161 | ||
158 | /* Tell device where in DRAM to update its Rx status */ | 162 | /* Tell device where in DRAM to update its Rx status */ |
159 | iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG, | 163 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, |
160 | rxq->rb_stts_dma >> 4); | 164 | rxq->rb_stts_dma >> 4); |
161 | 165 | ||
162 | /* Enable Rx DMA | 166 | /* Enable Rx DMA |
@@ -167,7 +171,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | |||
167 | * RB timeout 0x10 | 171 | * RB timeout 0x10 |
168 | * 256 RBDs | 172 | * 256 RBDs |
169 | */ | 173 | */ |
170 | iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, | 174 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, |
171 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | 175 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | |
172 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | 176 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | |
173 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | 177 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | |
@@ -177,7 +181,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | |||
177 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | 181 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); |
178 | 182 | ||
179 | /* Set interrupt coalescing timer to default (2048 usecs) */ | 183 | /* Set interrupt coalescing timer to default (2048 usecs) */ |
180 | iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | 184 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); |
181 | } | 185 | } |
182 | 186 | ||
183 | static int iwl_rx_init(struct iwl_trans *trans) | 187 | static int iwl_rx_init(struct iwl_trans *trans) |
@@ -242,13 +246,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) | |||
242 | iwl_trans_rxq_free_rx_bufs(trans); | 246 | iwl_trans_rxq_free_rx_bufs(trans); |
243 | spin_unlock_irqrestore(&rxq->lock, flags); | 247 | spin_unlock_irqrestore(&rxq->lock, flags); |
244 | 248 | ||
245 | dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE, | 249 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, |
246 | rxq->bd, rxq->bd_dma); | 250 | rxq->bd, rxq->bd_dma); |
247 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 251 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); |
248 | rxq->bd = NULL; | 252 | rxq->bd = NULL; |
249 | 253 | ||
250 | if (rxq->rb_stts) | 254 | if (rxq->rb_stts) |
251 | dma_free_coherent(bus(trans)->dev, | 255 | dma_free_coherent(trans->dev, |
252 | sizeof(struct iwl_rb_status), | 256 | sizeof(struct iwl_rb_status), |
253 | rxq->rb_stts, rxq->rb_stts_dma); | 257 | rxq->rb_stts, rxq->rb_stts_dma); |
254 | else | 258 | else |
@@ -261,8 +265,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) | |||
261 | { | 265 | { |
262 | 266 | ||
263 | /* stop Rx DMA */ | 267 | /* stop Rx DMA */ |
264 | iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | 268 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); |
265 | return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG, | 269 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, |
266 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | 270 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); |
267 | } | 271 | } |
268 | 272 | ||
@@ -272,7 +276,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, | |||
272 | if (WARN_ON(ptr->addr)) | 276 | if (WARN_ON(ptr->addr)) |
273 | return -EINVAL; | 277 | return -EINVAL; |
274 | 278 | ||
275 | ptr->addr = dma_alloc_coherent(bus(trans)->dev, size, | 279 | ptr->addr = dma_alloc_coherent(trans->dev, size, |
276 | &ptr->dma, GFP_KERNEL); | 280 | &ptr->dma, GFP_KERNEL); |
277 | if (!ptr->addr) | 281 | if (!ptr->addr) |
278 | return -ENOMEM; | 282 | return -ENOMEM; |
@@ -286,7 +290,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, | |||
286 | if (unlikely(!ptr->addr)) | 290 | if (unlikely(!ptr->addr)) |
287 | return; | 291 | return; |
288 | 292 | ||
289 | dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma); | 293 | dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); |
290 | memset(ptr, 0, sizeof(*ptr)); | 294 | memset(ptr, 0, sizeof(*ptr)); |
291 | } | 295 | } |
292 | 296 | ||
@@ -333,7 +337,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
333 | 337 | ||
334 | /* Circular buffer of transmit frame descriptors (TFDs), | 338 | /* Circular buffer of transmit frame descriptors (TFDs), |
335 | * shared with device */ | 339 | * shared with device */ |
336 | txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz, | 340 | txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, |
337 | &txq->q.dma_addr, GFP_KERNEL); | 341 | &txq->q.dma_addr, GFP_KERNEL); |
338 | if (!txq->tfds) { | 342 | if (!txq->tfds) { |
339 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); | 343 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); |
@@ -389,7 +393,7 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
389 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | 393 | * Tell nic where to find circular buffer of Tx Frame Descriptors for |
390 | * given Tx queue, and enable the DMA channel used for that queue. | 394 | * given Tx queue, and enable the DMA channel used for that queue. |
391 | * Circular buffer (TFD queue in DRAM) physical base address */ | 395 | * Circular buffer (TFD queue in DRAM) physical base address */ |
392 | iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id), | 396 | iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), |
393 | txq->q.dma_addr >> 8); | 397 | txq->q.dma_addr >> 8); |
394 | 398 | ||
395 | return 0; | 399 | return 0; |
@@ -443,7 +447,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
443 | { | 447 | { |
444 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 448 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
445 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 449 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
446 | struct device *dev = bus(trans)->dev; | 450 | struct device *dev = trans->dev; |
447 | int i; | 451 | int i; |
448 | if (WARN_ON(!txq)) | 452 | if (WARN_ON(!txq)) |
449 | return; | 453 | return; |
@@ -584,10 +588,10 @@ static int iwl_tx_init(struct iwl_trans *trans) | |||
584 | spin_lock_irqsave(&trans->shrd->lock, flags); | 588 | spin_lock_irqsave(&trans->shrd->lock, flags); |
585 | 589 | ||
586 | /* Turn off all Tx DMA fifos */ | 590 | /* Turn off all Tx DMA fifos */ |
587 | iwl_write_prph(bus(trans), SCD_TXFACT, 0); | 591 | iwl_write_prph(trans, SCD_TXFACT, 0); |
588 | 592 | ||
589 | /* Tell NIC where to find the "keep warm" buffer */ | 593 | /* Tell NIC where to find the "keep warm" buffer */ |
590 | iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG, | 594 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, |
591 | trans_pcie->kw.dma >> 4); | 595 | trans_pcie->kw.dma >> 4); |
592 | 596 | ||
593 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 597 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
@@ -619,26 +623,194 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) | |||
619 | * to set power to V_AUX, do: | 623 | * to set power to V_AUX, do: |
620 | 624 | ||
621 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) | 625 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) |
622 | iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, | 626 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
623 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, | 627 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, |
624 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 628 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
625 | */ | 629 | */ |
626 | 630 | ||
627 | iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, | 631 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
628 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, | 632 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, |
629 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 633 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
630 | } | 634 | } |
631 | 635 | ||
636 | /* PCI registers */ | ||
637 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
638 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 | ||
639 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 | ||
640 | |||
641 | static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) | ||
642 | { | ||
643 | int pos; | ||
644 | u16 pci_lnk_ctl; | ||
645 | struct iwl_trans_pcie *trans_pcie = | ||
646 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
647 | |||
648 | struct pci_dev *pci_dev = trans_pcie->pci_dev; | ||
649 | |||
650 | pos = pci_pcie_cap(pci_dev); | ||
651 | pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); | ||
652 | return pci_lnk_ctl; | ||
653 | } | ||
654 | |||
655 | static void iwl_apm_config(struct iwl_trans *trans) | ||
656 | { | ||
657 | /* | ||
658 | * HW bug W/A for instability in PCIe bus L0S->L1 transition. | ||
659 | * Check if BIOS (or OS) enabled L1-ASPM on this device. | ||
660 | * If so (likely), disable L0S, so device moves directly L0->L1; | ||
661 | * costs negligible amount of power savings. | ||
662 | * If not (unlikely), enable L0S, so there is at least some | ||
663 | * power savings, even without L1. | ||
664 | */ | ||
665 | u16 lctl = iwl_pciexp_link_ctrl(trans); | ||
666 | |||
667 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | ||
668 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | ||
669 | /* L1-ASPM enabled; disable(!) L0S */ | ||
670 | iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
671 | dev_printk(KERN_INFO, trans->dev, | ||
672 | "L1 Enabled; Disabling L0S\n"); | ||
673 | } else { | ||
674 | /* L1-ASPM disabled; enable(!) L0S */ | ||
675 | iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
676 | dev_printk(KERN_INFO, trans->dev, | ||
677 | "L1 Disabled; Enabling L0S\n"); | ||
678 | } | ||
679 | trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * Start up NIC's basic functionality after it has been reset | ||
684 | * (e.g. after platform boot, or shutdown via iwl_apm_stop()) | ||
685 | * NOTE: This does not load uCode nor start the embedded processor | ||
686 | */ | ||
687 | static int iwl_apm_init(struct iwl_trans *trans) | ||
688 | { | ||
689 | int ret = 0; | ||
690 | IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); | ||
691 | |||
692 | /* | ||
693 | * Use "set_bit" below rather than "write", to preserve any hardware | ||
694 | * bits already set by default after reset. | ||
695 | */ | ||
696 | |||
697 | /* Disable L0S exit timer (platform NMI Work/Around) */ | ||
698 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, | ||
699 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
700 | |||
701 | /* | ||
702 | * Disable L0s without affecting L1; | ||
703 | * don't wait for ICH L0s (ICH bug W/A) | ||
704 | */ | ||
705 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, | ||
706 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
707 | |||
708 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ | ||
709 | iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); | ||
710 | |||
711 | /* | ||
712 | * Enable HAP INTA (interrupt from management bus) to | ||
713 | * wake device's PCI Express link L1a -> L0s | ||
714 | */ | ||
715 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
716 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | ||
717 | |||
718 | iwl_apm_config(trans); | ||
719 | |||
720 | /* Configure analog phase-lock-loop before activating to D0A */ | ||
721 | if (cfg(trans)->base_params->pll_cfg_val) | ||
722 | iwl_set_bit(trans, CSR_ANA_PLL_CFG, | ||
723 | cfg(trans)->base_params->pll_cfg_val); | ||
724 | |||
725 | /* | ||
726 | * Set "initialization complete" bit to move adapter from | ||
727 | * D0U* --> D0A* (powered-up active) state. | ||
728 | */ | ||
729 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
730 | |||
731 | /* | ||
732 | * Wait for clock stabilization; once stabilized, access to | ||
733 | * device-internal resources is supported, e.g. iwl_write_prph() | ||
734 | * and accesses to uCode SRAM. | ||
735 | */ | ||
736 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
737 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
738 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
739 | if (ret < 0) { | ||
740 | IWL_DEBUG_INFO(trans, "Failed to init the card\n"); | ||
741 | goto out; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * Enable DMA clock and wait for it to stabilize. | ||
746 | * | ||
747 | * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits | ||
748 | * do not disable clocks. This preserves any hardware bits already | ||
749 | * set by default in "CLK_CTRL_REG" after reset. | ||
750 | */ | ||
751 | iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
752 | udelay(20); | ||
753 | |||
754 | /* Disable L1-Active */ | ||
755 | iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, | ||
756 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
757 | |||
758 | set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | ||
759 | |||
760 | out: | ||
761 | return ret; | ||
762 | } | ||
763 | |||
764 | static int iwl_apm_stop_master(struct iwl_trans *trans) | ||
765 | { | ||
766 | int ret = 0; | ||
767 | |||
768 | /* stop device's busmaster DMA activity */ | ||
769 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); | ||
770 | |||
771 | ret = iwl_poll_bit(trans, CSR_RESET, | ||
772 | CSR_RESET_REG_FLAG_MASTER_DISABLED, | ||
773 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
774 | if (ret) | ||
775 | IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); | ||
776 | |||
777 | IWL_DEBUG_INFO(trans, "stop master\n"); | ||
778 | |||
779 | return ret; | ||
780 | } | ||
781 | |||
782 | static void iwl_apm_stop(struct iwl_trans *trans) | ||
783 | { | ||
784 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); | ||
785 | |||
786 | clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | ||
787 | |||
788 | /* Stop device's DMA activity */ | ||
789 | iwl_apm_stop_master(trans); | ||
790 | |||
791 | /* Reset the entire device */ | ||
792 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
793 | |||
794 | udelay(10); | ||
795 | |||
796 | /* | ||
797 | * Clear "initialization complete" bit to move adapter from | ||
798 | * D0A* (powered-up Active) --> D0U* (Uninitialized) state. | ||
799 | */ | ||
800 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
801 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
802 | } | ||
803 | |||
632 | static int iwl_nic_init(struct iwl_trans *trans) | 804 | static int iwl_nic_init(struct iwl_trans *trans) |
633 | { | 805 | { |
634 | unsigned long flags; | 806 | unsigned long flags; |
635 | 807 | ||
636 | /* nic_init */ | 808 | /* nic_init */ |
637 | spin_lock_irqsave(&trans->shrd->lock, flags); | 809 | spin_lock_irqsave(&trans->shrd->lock, flags); |
638 | iwl_apm_init(priv(trans)); | 810 | iwl_apm_init(trans); |
639 | 811 | ||
640 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ | 812 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ |
641 | iwl_write8(bus(trans), CSR_INT_COALESCING, | 813 | iwl_write8(trans, CSR_INT_COALESCING, |
642 | IWL_HOST_INT_CALIB_TIMEOUT_DEF); | 814 | IWL_HOST_INT_CALIB_TIMEOUT_DEF); |
643 | 815 | ||
644 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 816 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
@@ -647,8 +819,10 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
647 | 819 | ||
648 | iwl_nic_config(priv(trans)); | 820 | iwl_nic_config(priv(trans)); |
649 | 821 | ||
822 | #ifndef CONFIG_IWLWIFI_IDI | ||
650 | /* Allocate the RX queue, or reset if it is already allocated */ | 823 | /* Allocate the RX queue, or reset if it is already allocated */ |
651 | iwl_rx_init(trans); | 824 | iwl_rx_init(trans); |
825 | #endif | ||
652 | 826 | ||
653 | /* Allocate or reset and init all Tx and Command queues */ | 827 | /* Allocate or reset and init all Tx and Command queues */ |
654 | if (iwl_tx_init(trans)) | 828 | if (iwl_tx_init(trans)) |
@@ -656,7 +830,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
656 | 830 | ||
657 | if (hw_params(trans).shadow_reg_enable) { | 831 | if (hw_params(trans).shadow_reg_enable) { |
658 | /* enable shadow regs in HW */ | 832 | /* enable shadow regs in HW */ |
659 | iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL, | 833 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, |
660 | 0x800FFFFF); | 834 | 0x800FFFFF); |
661 | } | 835 | } |
662 | 836 | ||
@@ -672,11 +846,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) | |||
672 | { | 846 | { |
673 | int ret; | 847 | int ret; |
674 | 848 | ||
675 | iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, | 849 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
676 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); | 850 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); |
677 | 851 | ||
678 | /* See if we got it */ | 852 | /* See if we got it */ |
679 | ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, | 853 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, |
680 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 854 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
681 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 855 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
682 | HW_READY_TIMEOUT); | 856 | HW_READY_TIMEOUT); |
@@ -686,21 +860,22 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) | |||
686 | } | 860 | } |
687 | 861 | ||
688 | /* Note: returns standard 0/-ERROR code */ | 862 | /* Note: returns standard 0/-ERROR code */ |
689 | static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) | 863 | static int iwl_prepare_card_hw(struct iwl_trans *trans) |
690 | { | 864 | { |
691 | int ret; | 865 | int ret; |
692 | 866 | ||
693 | IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); | 867 | IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); |
694 | 868 | ||
695 | ret = iwl_set_hw_ready(trans); | 869 | ret = iwl_set_hw_ready(trans); |
870 | /* If the card is ready, exit 0 */ | ||
696 | if (ret >= 0) | 871 | if (ret >= 0) |
697 | return 0; | 872 | return 0; |
698 | 873 | ||
699 | /* If HW is not ready, prepare the conditions to check again */ | 874 | /* If HW is not ready, prepare the conditions to check again */ |
700 | iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, | 875 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
701 | CSR_HW_IF_CONFIG_REG_PREPARE); | 876 | CSR_HW_IF_CONFIG_REG_PREPARE); |
702 | 877 | ||
703 | ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, | 878 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, |
704 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, | 879 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, |
705 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); | 880 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); |
706 | 881 | ||
@@ -767,7 +942,79 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
767 | 7, 6, 5, 4, | 942 | 7, 6, 5, 4, |
768 | }; | 943 | }; |
769 | 944 | ||
770 | static int iwl_trans_pcie_start_device(struct iwl_trans *trans) | 945 | /* |
946 | * ucode | ||
947 | */ | ||
948 | static int iwl_load_section(struct iwl_trans *trans, const char *name, | ||
949 | struct fw_desc *image, u32 dst_addr) | ||
950 | { | ||
951 | dma_addr_t phy_addr = image->p_addr; | ||
952 | u32 byte_cnt = image->len; | ||
953 | int ret; | ||
954 | |||
955 | trans->ucode_write_complete = 0; | ||
956 | |||
957 | iwl_write_direct32(trans, | ||
958 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
959 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | ||
960 | |||
961 | iwl_write_direct32(trans, | ||
962 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | ||
963 | |||
964 | iwl_write_direct32(trans, | ||
965 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | ||
966 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | ||
967 | |||
968 | iwl_write_direct32(trans, | ||
969 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | ||
970 | (iwl_get_dma_hi_addr(phy_addr) | ||
971 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | ||
972 | |||
973 | iwl_write_direct32(trans, | ||
974 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | ||
975 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | ||
976 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | ||
977 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | ||
978 | |||
979 | iwl_write_direct32(trans, | ||
980 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
981 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
982 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | ||
983 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | ||
984 | |||
985 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); | ||
986 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | ||
987 | trans->ucode_write_complete, 5 * HZ); | ||
988 | if (!ret) { | ||
989 | IWL_ERR(trans, "Could not load the %s uCode section\n", | ||
990 | name); | ||
991 | return -ETIMEDOUT; | ||
992 | } | ||
993 | |||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | ||
998 | { | ||
999 | int ret = 0; | ||
1000 | |||
1001 | ret = iwl_load_section(trans, "INST", &image->code, | ||
1002 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
1003 | if (ret) | ||
1004 | return ret; | ||
1005 | |||
1006 | ret = iwl_load_section(trans, "DATA", &image->data, | ||
1007 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
1008 | if (ret) | ||
1009 | return ret; | ||
1010 | |||
1011 | /* Remove all resets to allow NIC to operate */ | ||
1012 | iwl_write32(trans, CSR_RESET, 0); | ||
1013 | |||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | ||
771 | { | 1018 | { |
772 | int ret; | 1019 | int ret; |
773 | struct iwl_trans_pcie *trans_pcie = | 1020 | struct iwl_trans_pcie *trans_pcie = |
@@ -784,13 +1031,13 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) | |||
784 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; | 1031 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; |
785 | 1032 | ||
786 | if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && | 1033 | if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && |
787 | iwl_trans_pcie_prepare_card_hw(trans)) { | 1034 | iwl_prepare_card_hw(trans)) { |
788 | IWL_WARN(trans, "Exit HW not ready\n"); | 1035 | IWL_WARN(trans, "Exit HW not ready\n"); |
789 | return -EIO; | 1036 | return -EIO; |
790 | } | 1037 | } |
791 | 1038 | ||
792 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1039 | /* If platform's RF_KILL switch is NOT set to KILL */ |
793 | if (iwl_read32(bus(trans), CSR_GP_CNTRL) & | 1040 | if (iwl_read32(trans, CSR_GP_CNTRL) & |
794 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1041 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
795 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1042 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); |
796 | else | 1043 | else |
@@ -802,7 +1049,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) | |||
802 | return -ERFKILL; | 1049 | return -ERFKILL; |
803 | } | 1050 | } |
804 | 1051 | ||
805 | iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); | 1052 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
806 | 1053 | ||
807 | ret = iwl_nic_init(trans); | 1054 | ret = iwl_nic_init(trans); |
808 | if (ret) { | 1055 | if (ret) { |
@@ -811,17 +1058,20 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) | |||
811 | } | 1058 | } |
812 | 1059 | ||
813 | /* make sure rfkill handshake bits are cleared */ | 1060 | /* make sure rfkill handshake bits are cleared */ |
814 | iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1061 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
815 | iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, | 1062 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, |
816 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 1063 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
817 | 1064 | ||
818 | /* clear (again), then enable host interrupts */ | 1065 | /* clear (again), then enable host interrupts */ |
819 | iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); | 1066 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
820 | iwl_enable_interrupts(trans); | 1067 | iwl_enable_interrupts(trans); |
821 | 1068 | ||
822 | /* really make sure rfkill handshake bits are cleared */ | 1069 | /* really make sure rfkill handshake bits are cleared */ |
823 | iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1070 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
824 | iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1071 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1072 | |||
1073 | /* Load the given image to the HW */ | ||
1074 | iwl_load_given_ucode(trans, fw); | ||
825 | 1075 | ||
826 | return 0; | 1076 | return 0; |
827 | } | 1077 | } |
@@ -832,10 +1082,10 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) | |||
832 | */ | 1082 | */ |
833 | static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) | 1083 | static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) |
834 | { | 1084 | { |
835 | iwl_write_prph(bus(trans), SCD_TXFACT, mask); | 1085 | iwl_write_prph(trans, SCD_TXFACT, mask); |
836 | } | 1086 | } |
837 | 1087 | ||
838 | static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) | 1088 | static void iwl_tx_start(struct iwl_trans *trans) |
839 | { | 1089 | { |
840 | const struct queue_to_fifo_ac *queue_to_fifo; | 1090 | const struct queue_to_fifo_ac *queue_to_fifo; |
841 | struct iwl_trans_pcie *trans_pcie = | 1091 | struct iwl_trans_pcie *trans_pcie = |
@@ -848,46 +1098,46 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) | |||
848 | spin_lock_irqsave(&trans->shrd->lock, flags); | 1098 | spin_lock_irqsave(&trans->shrd->lock, flags); |
849 | 1099 | ||
850 | trans_pcie->scd_base_addr = | 1100 | trans_pcie->scd_base_addr = |
851 | iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR); | 1101 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); |
852 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | 1102 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; |
853 | /* reset conext data memory */ | 1103 | /* reset conext data memory */ |
854 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | 1104 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; |
855 | a += 4) | 1105 | a += 4) |
856 | iwl_write_targ_mem(bus(trans), a, 0); | 1106 | iwl_write_targ_mem(trans, a, 0); |
857 | /* reset tx status memory */ | 1107 | /* reset tx status memory */ |
858 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | 1108 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; |
859 | a += 4) | 1109 | a += 4) |
860 | iwl_write_targ_mem(bus(trans), a, 0); | 1110 | iwl_write_targ_mem(trans, a, 0); |
861 | for (; a < trans_pcie->scd_base_addr + | 1111 | for (; a < trans_pcie->scd_base_addr + |
862 | SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); | 1112 | SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); |
863 | a += 4) | 1113 | a += 4) |
864 | iwl_write_targ_mem(bus(trans), a, 0); | 1114 | iwl_write_targ_mem(trans, a, 0); |
865 | 1115 | ||
866 | iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR, | 1116 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
867 | trans_pcie->scd_bc_tbls.dma >> 10); | 1117 | trans_pcie->scd_bc_tbls.dma >> 10); |
868 | 1118 | ||
869 | /* Enable DMA channel */ | 1119 | /* Enable DMA channel */ |
870 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | 1120 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) |
871 | iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan), | 1121 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), |
872 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 1122 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
873 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | 1123 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); |
874 | 1124 | ||
875 | /* Update FH chicken bits */ | 1125 | /* Update FH chicken bits */ |
876 | reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG); | 1126 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); |
877 | iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG, | 1127 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, |
878 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1128 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
879 | 1129 | ||
880 | iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL, | 1130 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, |
881 | SCD_QUEUECHAIN_SEL_ALL(trans)); | 1131 | SCD_QUEUECHAIN_SEL_ALL(trans)); |
882 | iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0); | 1132 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); |
883 | 1133 | ||
884 | /* initiate the queues */ | 1134 | /* initiate the queues */ |
885 | for (i = 0; i < hw_params(trans).max_txq_num; i++) { | 1135 | for (i = 0; i < hw_params(trans).max_txq_num; i++) { |
886 | iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0); | 1136 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); |
887 | iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8)); | 1137 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); |
888 | iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + | 1138 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
889 | SCD_CONTEXT_QUEUE_OFFSET(i), 0); | 1139 | SCD_CONTEXT_QUEUE_OFFSET(i), 0); |
890 | iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + | 1140 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
891 | SCD_CONTEXT_QUEUE_OFFSET(i) + | 1141 | SCD_CONTEXT_QUEUE_OFFSET(i) + |
892 | sizeof(u32), | 1142 | sizeof(u32), |
893 | ((SCD_WIN_SIZE << | 1143 | ((SCD_WIN_SIZE << |
@@ -898,7 +1148,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) | |||
898 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 1148 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
899 | } | 1149 | } |
900 | 1150 | ||
901 | iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK, | 1151 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, |
902 | IWL_MASK(0, hw_params(trans).max_txq_num)); | 1152 | IWL_MASK(0, hw_params(trans).max_txq_num)); |
903 | 1153 | ||
904 | /* Activate all Tx DMA/FIFO channels */ | 1154 | /* Activate all Tx DMA/FIFO channels */ |
@@ -944,10 +1194,16 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) | |||
944 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1194 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
945 | 1195 | ||
946 | /* Enable L1-Active */ | 1196 | /* Enable L1-Active */ |
947 | iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG, | 1197 | iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, |
948 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 1198 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
949 | } | 1199 | } |
950 | 1200 | ||
1201 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | ||
1202 | { | ||
1203 | iwl_reset_ict(trans); | ||
1204 | iwl_tx_start(trans); | ||
1205 | } | ||
1206 | |||
951 | /** | 1207 | /** |
952 | * iwlagn_txq_ctx_stop - Stop all Tx DMA channels | 1208 | * iwlagn_txq_ctx_stop - Stop all Tx DMA channels |
953 | */ | 1209 | */ |
@@ -964,14 +1220,14 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
964 | 1220 | ||
965 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 1221 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
966 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 1222 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
967 | iwl_write_direct32(bus(trans), | 1223 | iwl_write_direct32(trans, |
968 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | 1224 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
969 | if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG, | 1225 | if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, |
970 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), | 1226 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), |
971 | 1000)) | 1227 | 1000)) |
972 | IWL_ERR(trans, "Failing on timeout while stopping" | 1228 | IWL_ERR(trans, "Failing on timeout while stopping" |
973 | " DMA channel %d [0x%08x]", ch, | 1229 | " DMA channel %d [0x%08x]", ch, |
974 | iwl_read_direct32(bus(trans), | 1230 | iwl_read_direct32(trans, |
975 | FH_TSSR_TX_STATUS_REG)); | 1231 | FH_TSSR_TX_STATUS_REG)); |
976 | } | 1232 | } |
977 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1233 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
@@ -1010,20 +1266,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1010 | */ | 1266 | */ |
1011 | if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { | 1267 | if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { |
1012 | iwl_trans_tx_stop(trans); | 1268 | iwl_trans_tx_stop(trans); |
1269 | #ifndef CONFIG_IWLWIFI_IDI | ||
1013 | iwl_trans_rx_stop(trans); | 1270 | iwl_trans_rx_stop(trans); |
1014 | 1271 | #endif | |
1015 | /* Power-down device's busmaster DMA clocks */ | 1272 | /* Power-down device's busmaster DMA clocks */ |
1016 | iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, | 1273 | iwl_write_prph(trans, APMG_CLK_DIS_REG, |
1017 | APMG_CLK_VAL_DMA_CLK_RQT); | 1274 | APMG_CLK_VAL_DMA_CLK_RQT); |
1018 | udelay(5); | 1275 | udelay(5); |
1019 | } | 1276 | } |
1020 | 1277 | ||
1021 | /* Make sure (redundant) we've released our request to stay awake */ | 1278 | /* Make sure (redundant) we've released our request to stay awake */ |
1022 | iwl_clear_bit(bus(trans), CSR_GP_CNTRL, | 1279 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
1023 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1280 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1024 | 1281 | ||
1025 | /* Stop the device, and put it in low power state */ | 1282 | /* Stop the device, and put it in low power state */ |
1026 | iwl_apm_stop(priv(trans)); | 1283 | iwl_apm_stop(trans); |
1027 | 1284 | ||
1028 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | 1285 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. |
1029 | * Clean again the interrupt here | 1286 | * Clean again the interrupt here |
@@ -1033,11 +1290,11 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1033 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1290 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
1034 | 1291 | ||
1035 | /* wait to make sure we flush pending tasklet*/ | 1292 | /* wait to make sure we flush pending tasklet*/ |
1036 | synchronize_irq(bus(trans)->irq); | 1293 | synchronize_irq(trans->irq); |
1037 | tasklet_kill(&trans_pcie->irq_tasklet); | 1294 | tasklet_kill(&trans_pcie->irq_tasklet); |
1038 | 1295 | ||
1039 | /* stop and reset the on-board processor */ | 1296 | /* stop and reset the on-board processor */ |
1040 | iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1297 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
1041 | } | 1298 | } |
1042 | 1299 | ||
1043 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1300 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
@@ -1134,10 +1391,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1134 | 1391 | ||
1135 | /* Physical address of this Tx command's header (not MAC header!), | 1392 | /* Physical address of this Tx command's header (not MAC header!), |
1136 | * within command buffer array. */ | 1393 | * within command buffer array. */ |
1137 | txcmd_phys = dma_map_single(bus(trans)->dev, | 1394 | txcmd_phys = dma_map_single(trans->dev, |
1138 | &dev_cmd->hdr, firstlen, | 1395 | &dev_cmd->hdr, firstlen, |
1139 | DMA_BIDIRECTIONAL); | 1396 | DMA_BIDIRECTIONAL); |
1140 | if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys))) | 1397 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) |
1141 | return -1; | 1398 | return -1; |
1142 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 1399 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); |
1143 | dma_unmap_len_set(out_meta, len, firstlen); | 1400 | dma_unmap_len_set(out_meta, len, firstlen); |
@@ -1153,10 +1410,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1153 | * if any (802.11 null frames have no payload). */ | 1410 | * if any (802.11 null frames have no payload). */ |
1154 | secondlen = skb->len - hdr_len; | 1411 | secondlen = skb->len - hdr_len; |
1155 | if (secondlen > 0) { | 1412 | if (secondlen > 0) { |
1156 | phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len, | 1413 | phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, |
1157 | secondlen, DMA_TO_DEVICE); | 1414 | secondlen, DMA_TO_DEVICE); |
1158 | if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { | 1415 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { |
1159 | dma_unmap_single(bus(trans)->dev, | 1416 | dma_unmap_single(trans->dev, |
1160 | dma_unmap_addr(out_meta, mapping), | 1417 | dma_unmap_addr(out_meta, mapping), |
1161 | dma_unmap_len(out_meta, len), | 1418 | dma_unmap_len(out_meta, len), |
1162 | DMA_BIDIRECTIONAL); | 1419 | DMA_BIDIRECTIONAL); |
@@ -1174,7 +1431,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1174 | offsetof(struct iwl_tx_cmd, scratch); | 1431 | offsetof(struct iwl_tx_cmd, scratch); |
1175 | 1432 | ||
1176 | /* take back ownership of DMA buffer to enable update */ | 1433 | /* take back ownership of DMA buffer to enable update */ |
1177 | dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen, | 1434 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, |
1178 | DMA_BIDIRECTIONAL); | 1435 | DMA_BIDIRECTIONAL); |
1179 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1436 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1180 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 1437 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
@@ -1188,7 +1445,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1188 | /* Set up entry for this TFD in Tx byte-count array */ | 1445 | /* Set up entry for this TFD in Tx byte-count array */ |
1189 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1446 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1190 | 1447 | ||
1191 | dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, | 1448 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
1192 | DMA_BIDIRECTIONAL); | 1449 | DMA_BIDIRECTIONAL); |
1193 | 1450 | ||
1194 | trace_iwlwifi_dev_tx(priv(trans), | 1451 | trace_iwlwifi_dev_tx(priv(trans), |
@@ -1218,13 +1475,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1218 | return 0; | 1475 | return 0; |
1219 | } | 1476 | } |
1220 | 1477 | ||
1221 | static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) | 1478 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) |
1222 | { | ||
1223 | /* Remove all resets to allow NIC to operate */ | ||
1224 | iwl_write32(bus(trans), CSR_RESET, 0); | ||
1225 | } | ||
1226 | |||
1227 | static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) | ||
1228 | { | 1479 | { |
1229 | struct iwl_trans_pcie *trans_pcie = | 1480 | struct iwl_trans_pcie *trans_pcie = |
1230 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1481 | IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -1232,21 +1483,62 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) | |||
1232 | 1483 | ||
1233 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | 1484 | trans_pcie->inta_mask = CSR_INI_SET_MASK; |
1234 | 1485 | ||
1235 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | 1486 | if (!trans_pcie->irq_requested) { |
1236 | iwl_irq_tasklet, (unsigned long)trans); | 1487 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) |
1488 | iwl_irq_tasklet, (unsigned long)trans); | ||
1237 | 1489 | ||
1238 | iwl_alloc_isr_ict(trans); | 1490 | iwl_alloc_isr_ict(trans); |
1491 | |||
1492 | err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, | ||
1493 | DRV_NAME, trans); | ||
1494 | if (err) { | ||
1495 | IWL_ERR(trans, "Error allocating IRQ %d\n", | ||
1496 | trans->irq); | ||
1497 | goto error; | ||
1498 | } | ||
1239 | 1499 | ||
1240 | err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, | 1500 | INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); |
1241 | DRV_NAME, trans); | 1501 | trans_pcie->irq_requested = true; |
1502 | } | ||
1503 | |||
1504 | err = iwl_prepare_card_hw(trans); | ||
1242 | if (err) { | 1505 | if (err) { |
1243 | IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq); | 1506 | IWL_ERR(trans, "Error while preparing HW: %d", err); |
1244 | iwl_free_isr_ict(trans); | 1507 | goto err_free_irq; |
1245 | return err; | ||
1246 | } | 1508 | } |
1247 | 1509 | ||
1248 | INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); | 1510 | iwl_apm_init(trans); |
1249 | return 0; | 1511 | |
1512 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
1513 | if (iwl_read32(trans, | ||
1514 | CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
1515 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1516 | else | ||
1517 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1518 | |||
1519 | iwl_set_hw_rfkill_state(priv(trans), | ||
1520 | test_bit(STATUS_RF_KILL_HW, | ||
1521 | &trans->shrd->status)); | ||
1522 | |||
1523 | return err; | ||
1524 | |||
1525 | err_free_irq: | ||
1526 | free_irq(trans->irq, trans); | ||
1527 | error: | ||
1528 | iwl_free_isr_ict(trans); | ||
1529 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
1530 | return err; | ||
1531 | } | ||
1532 | |||
1533 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) | ||
1534 | { | ||
1535 | iwl_apm_stop(trans); | ||
1536 | |||
1537 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | ||
1538 | |||
1539 | /* Even if we stop the HW, we still want the RF kill interrupt */ | ||
1540 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | ||
1541 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
1250 | } | 1542 | } |
1251 | 1543 | ||
1252 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | 1544 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, |
@@ -1288,13 +1580,42 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1288 | return 0; | 1580 | return 0; |
1289 | } | 1581 | } |
1290 | 1582 | ||
1583 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) | ||
1584 | { | ||
1585 | iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | ||
1586 | } | ||
1587 | |||
1588 | static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) | ||
1589 | { | ||
1590 | iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | ||
1591 | } | ||
1592 | |||
1593 | static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) | ||
1594 | { | ||
1595 | u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | ||
1596 | return val; | ||
1597 | } | ||
1598 | |||
1291 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1599 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
1292 | { | 1600 | { |
1601 | struct iwl_trans_pcie *trans_pcie = | ||
1602 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1603 | |||
1293 | iwl_calib_free_results(trans); | 1604 | iwl_calib_free_results(trans); |
1294 | iwl_trans_pcie_tx_free(trans); | 1605 | iwl_trans_pcie_tx_free(trans); |
1606 | #ifndef CONFIG_IWLWIFI_IDI | ||
1295 | iwl_trans_pcie_rx_free(trans); | 1607 | iwl_trans_pcie_rx_free(trans); |
1296 | free_irq(bus(trans)->irq, trans); | 1608 | #endif |
1297 | iwl_free_isr_ict(trans); | 1609 | if (trans_pcie->irq_requested == true) { |
1610 | free_irq(trans->irq, trans); | ||
1611 | iwl_free_isr_ict(trans); | ||
1612 | } | ||
1613 | |||
1614 | pci_disable_msi(trans_pcie->pci_dev); | ||
1615 | pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); | ||
1616 | pci_release_regions(trans_pcie->pci_dev); | ||
1617 | pci_disable_device(trans_pcie->pci_dev); | ||
1618 | |||
1298 | trans->shrd->trans = NULL; | 1619 | trans->shrd->trans = NULL; |
1299 | kfree(trans); | 1620 | kfree(trans); |
1300 | } | 1621 | } |
@@ -1314,10 +1635,10 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | |||
1314 | * things already :-) | 1635 | * things already :-) |
1315 | */ | 1636 | */ |
1316 | if (!trans->shrd->wowlan) { | 1637 | if (!trans->shrd->wowlan) { |
1317 | iwl_apm_stop(priv(trans)); | 1638 | iwl_apm_stop(trans); |
1318 | } else { | 1639 | } else { |
1319 | iwl_disable_interrupts(trans); | 1640 | iwl_disable_interrupts(trans); |
1320 | iwl_clear_bit(bus(trans), CSR_GP_CNTRL, | 1641 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
1321 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1642 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1322 | } | 1643 | } |
1323 | 1644 | ||
@@ -1330,7 +1651,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1330 | 1651 | ||
1331 | iwl_enable_interrupts(trans); | 1652 | iwl_enable_interrupts(trans); |
1332 | 1653 | ||
1333 | if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & | 1654 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & |
1334 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1655 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) |
1335 | hw_rfkill = true; | 1656 | hw_rfkill = true; |
1336 | 1657 | ||
@@ -1363,25 +1684,6 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | |||
1363 | } | 1684 | } |
1364 | } | 1685 | } |
1365 | 1686 | ||
1366 | const struct iwl_trans_ops trans_ops_pcie; | ||
1367 | |||
1368 | static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) | ||
1369 | { | ||
1370 | struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + | ||
1371 | sizeof(struct iwl_trans_pcie), | ||
1372 | GFP_KERNEL); | ||
1373 | if (iwl_trans) { | ||
1374 | struct iwl_trans_pcie *trans_pcie = | ||
1375 | IWL_TRANS_GET_PCIE_TRANS(iwl_trans); | ||
1376 | iwl_trans->ops = &trans_ops_pcie; | ||
1377 | iwl_trans->shrd = shrd; | ||
1378 | trans_pcie->trans = iwl_trans; | ||
1379 | spin_lock_init(&iwl_trans->hcmd_lock); | ||
1380 | } | ||
1381 | |||
1382 | return iwl_trans; | ||
1383 | } | ||
1384 | |||
1385 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, | 1687 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, |
1386 | const char *msg) | 1688 | const char *msg) |
1387 | { | 1689 | { |
@@ -1445,9 +1747,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) | |||
1445 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | 1747 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", |
1446 | q->read_ptr, q->write_ptr); | 1748 | q->read_ptr, q->write_ptr); |
1447 | IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", | 1749 | IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", |
1448 | iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt)) | 1750 | iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) |
1449 | & (TFD_QUEUE_SIZE_MAX - 1), | 1751 | & (TFD_QUEUE_SIZE_MAX - 1), |
1450 | iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt))); | 1752 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); |
1451 | return 1; | 1753 | return 1; |
1452 | } | 1754 | } |
1453 | 1755 | ||
@@ -1501,7 +1803,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | |||
1501 | pos += scnprintf(*buf + pos, bufsz - pos, | 1803 | pos += scnprintf(*buf + pos, bufsz - pos, |
1502 | " %34s: 0X%08x\n", | 1804 | " %34s: 0X%08x\n", |
1503 | get_fh_string(fh_tbl[i]), | 1805 | get_fh_string(fh_tbl[i]), |
1504 | iwl_read_direct32(bus(trans), fh_tbl[i])); | 1806 | iwl_read_direct32(trans, fh_tbl[i])); |
1505 | } | 1807 | } |
1506 | return pos; | 1808 | return pos; |
1507 | } | 1809 | } |
@@ -1510,7 +1812,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | |||
1510 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { | 1812 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { |
1511 | IWL_ERR(trans, " %34s: 0X%08x\n", | 1813 | IWL_ERR(trans, " %34s: 0X%08x\n", |
1512 | get_fh_string(fh_tbl[i]), | 1814 | get_fh_string(fh_tbl[i]), |
1513 | iwl_read_direct32(bus(trans), fh_tbl[i])); | 1815 | iwl_read_direct32(trans, fh_tbl[i])); |
1514 | } | 1816 | } |
1515 | return 0; | 1817 | return 0; |
1516 | } | 1818 | } |
@@ -1580,7 +1882,7 @@ void iwl_dump_csr(struct iwl_trans *trans) | |||
1580 | for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { | 1882 | for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { |
1581 | IWL_ERR(trans, " %25s: 0X%08x\n", | 1883 | IWL_ERR(trans, " %25s: 0X%08x\n", |
1582 | get_csr_string(csr_tbl[i]), | 1884 | get_csr_string(csr_tbl[i]), |
1583 | iwl_read32(bus(trans), csr_tbl[i])); | 1885 | iwl_read32(trans, csr_tbl[i])); |
1584 | } | 1886 | } |
1585 | } | 1887 | } |
1586 | 1888 | ||
@@ -1901,13 +2203,12 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | |||
1901 | #endif /*CONFIG_IWLWIFI_DEBUGFS */ | 2203 | #endif /*CONFIG_IWLWIFI_DEBUGFS */ |
1902 | 2204 | ||
1903 | const struct iwl_trans_ops trans_ops_pcie = { | 2205 | const struct iwl_trans_ops trans_ops_pcie = { |
1904 | .alloc = iwl_trans_pcie_alloc, | 2206 | .start_hw = iwl_trans_pcie_start_hw, |
1905 | .request_irq = iwl_trans_pcie_request_irq, | 2207 | .stop_hw = iwl_trans_pcie_stop_hw, |
1906 | .start_device = iwl_trans_pcie_start_device, | 2208 | .fw_alive = iwl_trans_pcie_fw_alive, |
1907 | .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, | 2209 | .start_fw = iwl_trans_pcie_start_fw, |
1908 | .stop_device = iwl_trans_pcie_stop_device, | 2210 | .stop_device = iwl_trans_pcie_stop_device, |
1909 | 2211 | ||
1910 | .tx_start = iwl_trans_pcie_tx_start, | ||
1911 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, | 2212 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, |
1912 | 2213 | ||
1913 | .send_cmd = iwl_trans_pcie_send_cmd, | 2214 | .send_cmd = iwl_trans_pcie_send_cmd, |
@@ -1919,8 +2220,6 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
1919 | .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc, | 2220 | .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc, |
1920 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2221 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, |
1921 | 2222 | ||
1922 | .kick_nic = iwl_trans_pcie_kick_nic, | ||
1923 | |||
1924 | .free = iwl_trans_pcie_free, | 2223 | .free = iwl_trans_pcie_free, |
1925 | .stop_queue = iwl_trans_pcie_stop_queue, | 2224 | .stop_queue = iwl_trans_pcie_stop_queue, |
1926 | 2225 | ||
@@ -1933,4 +2232,116 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
1933 | .suspend = iwl_trans_pcie_suspend, | 2232 | .suspend = iwl_trans_pcie_suspend, |
1934 | .resume = iwl_trans_pcie_resume, | 2233 | .resume = iwl_trans_pcie_resume, |
1935 | #endif | 2234 | #endif |
2235 | .write8 = iwl_trans_pcie_write8, | ||
2236 | .write32 = iwl_trans_pcie_write32, | ||
2237 | .read32 = iwl_trans_pcie_read32, | ||
1936 | }; | 2238 | }; |
2239 | |||
2240 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | ||
2241 | struct pci_dev *pdev, | ||
2242 | const struct pci_device_id *ent) | ||
2243 | { | ||
2244 | struct iwl_trans_pcie *trans_pcie; | ||
2245 | struct iwl_trans *trans; | ||
2246 | u16 pci_cmd; | ||
2247 | int err; | ||
2248 | |||
2249 | trans = kzalloc(sizeof(struct iwl_trans) + | ||
2250 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); | ||
2251 | |||
2252 | if (WARN_ON(!trans)) | ||
2253 | return NULL; | ||
2254 | |||
2255 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
2256 | |||
2257 | trans->ops = &trans_ops_pcie; | ||
2258 | trans->shrd = shrd; | ||
2259 | trans_pcie->trans = trans; | ||
2260 | spin_lock_init(&trans->hcmd_lock); | ||
2261 | |||
2262 | /* W/A - seems to solve weird behavior. We need to remove this if we | ||
2263 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
2264 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
2265 | PCIE_LINK_STATE_CLKPM); | ||
2266 | |||
2267 | if (pci_enable_device(pdev)) { | ||
2268 | err = -ENODEV; | ||
2269 | goto out_no_pci; | ||
2270 | } | ||
2271 | |||
2272 | pci_set_master(pdev); | ||
2273 | |||
2274 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
2275 | if (!err) | ||
2276 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
2277 | if (err) { | ||
2278 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
2279 | if (!err) | ||
2280 | err = pci_set_consistent_dma_mask(pdev, | ||
2281 | DMA_BIT_MASK(32)); | ||
2282 | /* both attempts failed: */ | ||
2283 | if (err) { | ||
2284 | dev_printk(KERN_ERR, &pdev->dev, | ||
2285 | "No suitable DMA available.\n"); | ||
2286 | goto out_pci_disable_device; | ||
2287 | } | ||
2288 | } | ||
2289 | |||
2290 | err = pci_request_regions(pdev, DRV_NAME); | ||
2291 | if (err) { | ||
2292 | dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); | ||
2293 | goto out_pci_disable_device; | ||
2294 | } | ||
2295 | |||
2296 | trans_pcie->hw_base = pci_iomap(pdev, 0, 0); | ||
2297 | if (!trans_pcie->hw_base) { | ||
2298 | dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); | ||
2299 | err = -ENODEV; | ||
2300 | goto out_pci_release_regions; | ||
2301 | } | ||
2302 | |||
2303 | dev_printk(KERN_INFO, &pdev->dev, | ||
2304 | "pci_resource_len = 0x%08llx\n", | ||
2305 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
2306 | dev_printk(KERN_INFO, &pdev->dev, | ||
2307 | "pci_resource_base = %p\n", trans_pcie->hw_base); | ||
2308 | |||
2309 | dev_printk(KERN_INFO, &pdev->dev, | ||
2310 | "HW Revision ID = 0x%X\n", pdev->revision); | ||
2311 | |||
2312 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
2313 | * PCI Tx retries from interfering with C3 CPU state */ | ||
2314 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
2315 | |||
2316 | err = pci_enable_msi(pdev); | ||
2317 | if (err) | ||
2318 | dev_printk(KERN_ERR, &pdev->dev, | ||
2319 | "pci_enable_msi failed(0X%x)", err); | ||
2320 | |||
2321 | trans->dev = &pdev->dev; | ||
2322 | trans->irq = pdev->irq; | ||
2323 | trans_pcie->pci_dev = pdev; | ||
2324 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | ||
2325 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | ||
2326 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), | ||
2327 | "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); | ||
2328 | |||
2329 | /* TODO: Move this away, not needed if not MSI */ | ||
2330 | /* enable rfkill interrupt: hw bug w/a */ | ||
2331 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
2332 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
2333 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
2334 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
2335 | } | ||
2336 | |||
2337 | return trans; | ||
2338 | |||
2339 | out_pci_release_regions: | ||
2340 | pci_release_regions(pdev); | ||
2341 | out_pci_disable_device: | ||
2342 | pci_disable_device(pdev); | ||
2343 | out_no_pci: | ||
2344 | kfree(trans); | ||
2345 | return NULL; | ||
2346 | } | ||
2347 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 42a9f303f543..ae68c51e5327 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -131,16 +131,26 @@ struct iwl_host_cmd { | |||
131 | u8 id; | 131 | u8 id; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
135 | struct fw_desc { | ||
136 | dma_addr_t p_addr; /* hardware address */ | ||
137 | void *v_addr; /* software address */ | ||
138 | u32 len; /* size in bytes */ | ||
139 | }; | ||
140 | |||
141 | struct fw_img { | ||
142 | struct fw_desc code; /* firmware code image */ | ||
143 | struct fw_desc data; /* firmware data image */ | ||
144 | }; | ||
145 | |||
134 | /** | 146 | /** |
135 | * struct iwl_trans_ops - transport specific operations | 147 | * struct iwl_trans_ops - transport specific operations |
136 | * @alloc: allocates the meta data (not the queues themselves) | 148 | * @start_hw: starts the HW- from that point on, the HW can send interrupts |
137 | * @request_irq: requests IRQ - will be called before the FW load in probe flow | 149 | * @stop_hw: stops the HW- from that point on, the HW will be in low power but |
138 | * @start_device: allocates and inits all the resources for the transport | 150 | * will still issue interrupt if the HW RF kill is triggered. |
139 | * layer. | 151 | * @start_fw: allocates and inits all the resources for the transport |
140 | * @prepare_card_hw: claim the ownership on the HW. Will be called during | 152 | * layer. Also kick a fw image. This handler may sleep. |
141 | * probe. | 153 | * @fw_alive: called when the fw sends alive notification |
142 | * @tx_start: starts and configures all the Tx fifo - usually done once the fw | ||
143 | * is alive. | ||
144 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* | 154 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* |
145 | * @stop_device:stops the whole device (embedded CPU put to reset) | 155 | * @stop_device:stops the whole device (embedded CPU put to reset) |
146 | * @send_cmd:send a host command | 156 | * @send_cmd:send a host command |
@@ -150,7 +160,6 @@ struct iwl_host_cmd { | |||
150 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 160 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is |
151 | * ready and a successful ADDBA response has been received. | 161 | * ready and a successful ADDBA response has been received. |
152 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 162 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs |
153 | * @kick_nic: remove the RESET from the embedded CPU and let it run | ||
154 | * @free: release all the ressource for the transport layer itself such as | 163 | * @free: release all the ressource for the transport layer itself such as |
155 | * irq, tasklet etc... | 164 | * irq, tasklet etc... |
156 | * @stop_queue: stop a specific queue | 165 | * @stop_queue: stop a specific queue |
@@ -160,15 +169,17 @@ struct iwl_host_cmd { | |||
160 | * automatically deleted. | 169 | * automatically deleted. |
161 | * @suspend: stop the device unless WoWLAN is configured | 170 | * @suspend: stop the device unless WoWLAN is configured |
162 | * @resume: resume activity of the device | 171 | * @resume: resume activity of the device |
172 | * @write8: write a u8 to a register at offset ofs from the BAR | ||
173 | * @write32: write a u32 to a register at offset ofs from the BAR | ||
174 | * @read32: read a u32 register at offset ofs from the BAR | ||
163 | */ | 175 | */ |
164 | struct iwl_trans_ops { | 176 | struct iwl_trans_ops { |
165 | 177 | ||
166 | struct iwl_trans *(*alloc)(struct iwl_shared *shrd); | 178 | int (*start_hw)(struct iwl_trans *iwl_trans); |
167 | int (*request_irq)(struct iwl_trans *iwl_trans); | 179 | void (*stop_hw)(struct iwl_trans *iwl_trans); |
168 | int (*start_device)(struct iwl_trans *trans); | 180 | int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); |
169 | int (*prepare_card_hw)(struct iwl_trans *trans); | 181 | void (*fw_alive)(struct iwl_trans *trans); |
170 | void (*stop_device)(struct iwl_trans *trans); | 182 | void (*stop_device)(struct iwl_trans *trans); |
171 | void (*tx_start)(struct iwl_trans *trans); | ||
172 | 183 | ||
173 | void (*wake_any_queue)(struct iwl_trans *trans, | 184 | void (*wake_any_queue)(struct iwl_trans *trans, |
174 | enum iwl_rxon_context_id ctx, | 185 | enum iwl_rxon_context_id ctx, |
@@ -191,8 +202,6 @@ struct iwl_trans_ops { | |||
191 | enum iwl_rxon_context_id ctx, int sta_id, int tid, | 202 | enum iwl_rxon_context_id ctx, int sta_id, int tid, |
192 | int frame_limit, u16 ssn); | 203 | int frame_limit, u16 ssn); |
193 | 204 | ||
194 | void (*kick_nic)(struct iwl_trans *trans); | ||
195 | |||
196 | void (*free)(struct iwl_trans *trans); | 205 | void (*free)(struct iwl_trans *trans); |
197 | 206 | ||
198 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); | 207 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); |
@@ -204,18 +213,9 @@ struct iwl_trans_ops { | |||
204 | int (*suspend)(struct iwl_trans *trans); | 213 | int (*suspend)(struct iwl_trans *trans); |
205 | int (*resume)(struct iwl_trans *trans); | 214 | int (*resume)(struct iwl_trans *trans); |
206 | #endif | 215 | #endif |
207 | }; | 216 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); |
208 | 217 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); | |
209 | /* one for each uCode image (inst/data, boot/init/runtime) */ | 218 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
210 | struct fw_desc { | ||
211 | dma_addr_t p_addr; /* hardware address */ | ||
212 | void *v_addr; /* software address */ | ||
213 | u32 len; /* size in bytes */ | ||
214 | }; | ||
215 | |||
216 | struct fw_img { | ||
217 | struct fw_desc code; /* firmware code image */ | ||
218 | struct fw_desc data; /* firmware data image */ | ||
219 | }; | 219 | }; |
220 | 220 | ||
221 | /* Opaque calibration results */ | 221 | /* Opaque calibration results */ |
@@ -231,17 +231,31 @@ struct iwl_calib_result { | |||
231 | * @ops - pointer to iwl_trans_ops | 231 | * @ops - pointer to iwl_trans_ops |
232 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 232 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
233 | * @hcmd_lock: protects HCMD | 233 | * @hcmd_lock: protects HCMD |
234 | * @reg_lock - protect hw register access | ||
235 | * @dev - pointer to struct device * that represents the device | ||
236 | * @irq - the irq number for the device | ||
237 | * @hw_id: a u32 with the ID of the device / subdevice. | ||
238 | * Set during transport alloaction. | ||
239 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | ||
234 | * @ucode_write_complete: indicates that the ucode has been copied. | 240 | * @ucode_write_complete: indicates that the ucode has been copied. |
235 | * @ucode_rt: run time ucode image | 241 | * @ucode_rt: run time ucode image |
236 | * @ucode_init: init ucode image | 242 | * @ucode_init: init ucode image |
237 | * @ucode_wowlan: wake on wireless ucode image (optional) | 243 | * @ucode_wowlan: wake on wireless ucode image (optional) |
238 | * @nvm_device_type: indicates OTP or eeprom | 244 | * @nvm_device_type: indicates OTP or eeprom |
245 | * @pm_support: set to true in start_hw if link pm is supported | ||
239 | * @calib_results: list head for init calibration results | 246 | * @calib_results: list head for init calibration results |
240 | */ | 247 | */ |
241 | struct iwl_trans { | 248 | struct iwl_trans { |
242 | const struct iwl_trans_ops *ops; | 249 | const struct iwl_trans_ops *ops; |
243 | struct iwl_shared *shrd; | 250 | struct iwl_shared *shrd; |
244 | spinlock_t hcmd_lock; | 251 | spinlock_t hcmd_lock; |
252 | spinlock_t reg_lock; | ||
253 | |||
254 | struct device *dev; | ||
255 | unsigned int irq; | ||
256 | u32 hw_rev; | ||
257 | u32 hw_id; | ||
258 | char hw_id_str[52]; | ||
245 | 259 | ||
246 | u8 ucode_write_complete; /* the image write is complete */ | 260 | u8 ucode_write_complete; /* the image write is complete */ |
247 | struct fw_img ucode_rt; | 261 | struct fw_img ucode_rt; |
@@ -250,6 +264,7 @@ struct iwl_trans { | |||
250 | 264 | ||
251 | /* eeprom related variables */ | 265 | /* eeprom related variables */ |
252 | int nvm_device_type; | 266 | int nvm_device_type; |
267 | bool pm_support; | ||
253 | 268 | ||
254 | /* init calibration results */ | 269 | /* init calibration results */ |
255 | struct list_head calib_results; | 270 | struct list_head calib_results; |
@@ -259,29 +274,31 @@ struct iwl_trans { | |||
259 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); | 274 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); |
260 | }; | 275 | }; |
261 | 276 | ||
262 | static inline int iwl_trans_request_irq(struct iwl_trans *trans) | 277 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
263 | { | 278 | { |
264 | return trans->ops->request_irq(trans); | 279 | return trans->ops->start_hw(trans); |
265 | } | 280 | } |
266 | 281 | ||
267 | static inline int iwl_trans_start_device(struct iwl_trans *trans) | 282 | static inline void iwl_trans_stop_hw(struct iwl_trans *trans) |
268 | { | 283 | { |
269 | return trans->ops->start_device(trans); | 284 | trans->ops->stop_hw(trans); |
270 | } | 285 | } |
271 | 286 | ||
272 | static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans) | 287 | static inline void iwl_trans_fw_alive(struct iwl_trans *trans) |
273 | { | 288 | { |
274 | return trans->ops->prepare_card_hw(trans); | 289 | trans->ops->fw_alive(trans); |
275 | } | 290 | } |
276 | 291 | ||
277 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | 292 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) |
278 | { | 293 | { |
279 | trans->ops->stop_device(trans); | 294 | might_sleep(); |
295 | |||
296 | return trans->ops->start_fw(trans, fw); | ||
280 | } | 297 | } |
281 | 298 | ||
282 | static inline void iwl_trans_tx_start(struct iwl_trans *trans) | 299 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
283 | { | 300 | { |
284 | trans->ops->tx_start(trans); | 301 | trans->ops->stop_device(trans); |
285 | } | 302 | } |
286 | 303 | ||
287 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 304 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, |
@@ -337,11 +354,6 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, | |||
337 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); | 354 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); |
338 | } | 355 | } |
339 | 356 | ||
340 | static inline void iwl_trans_kick_nic(struct iwl_trans *trans) | ||
341 | { | ||
342 | trans->ops->kick_nic(trans); | ||
343 | } | ||
344 | |||
345 | static inline void iwl_trans_free(struct iwl_trans *trans) | 357 | static inline void iwl_trans_free(struct iwl_trans *trans) |
346 | { | 358 | { |
347 | trans->ops->free(trans); | 359 | trans->ops->free(trans); |
@@ -380,13 +392,24 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) | |||
380 | } | 392 | } |
381 | #endif | 393 | #endif |
382 | 394 | ||
395 | static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val) | ||
396 | { | ||
397 | trans->ops->write8(trans, ofs, val); | ||
398 | } | ||
399 | |||
400 | static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val) | ||
401 | { | ||
402 | trans->ops->write32(trans, ofs, val); | ||
403 | } | ||
404 | |||
405 | static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) | ||
406 | { | ||
407 | return trans->ops->read32(trans, ofs); | ||
408 | } | ||
409 | |||
383 | /***************************************************** | 410 | /***************************************************** |
384 | * Transport layers implementations | 411 | * Utils functions |
385 | ******************************************************/ | 412 | ******************************************************/ |
386 | extern const struct iwl_trans_ops trans_ops_pcie; | ||
387 | |||
388 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | ||
389 | const void *data, size_t len); | ||
390 | void iwl_dealloc_ucode(struct iwl_trans *trans); | 413 | void iwl_dealloc_ucode(struct iwl_trans *trans); |
391 | 414 | ||
392 | int iwl_send_calib_results(struct iwl_trans *trans); | 415 | int iwl_send_calib_results(struct iwl_trans *trans); |
@@ -394,4 +417,18 @@ int iwl_calib_set(struct iwl_trans *trans, | |||
394 | const struct iwl_calib_hdr *cmd, int len); | 417 | const struct iwl_calib_hdr *cmd, int len); |
395 | void iwl_calib_free_results(struct iwl_trans *trans); | 418 | void iwl_calib_free_results(struct iwl_trans *trans); |
396 | 419 | ||
420 | /***************************************************** | ||
421 | * Transport layers implementations + their allocation function | ||
422 | ******************************************************/ | ||
423 | struct pci_dev; | ||
424 | struct pci_device_id; | ||
425 | extern const struct iwl_trans_ops trans_ops_pcie; | ||
426 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | ||
427 | struct pci_dev *pdev, | ||
428 | const struct pci_device_id *ent); | ||
429 | |||
430 | extern const struct iwl_trans_ops trans_ops_idi; | ||
431 | struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd, | ||
432 | void *pdev_void, | ||
433 | const void *ent_void); | ||
397 | #endif /* __iwl_trans_h__ */ | 434 | #endif /* __iwl_trans_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 2edf0ef65a5b..11b659ab261d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -32,7 +32,9 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/firmware.h> | ||
35 | 36 | ||
37 | #include "iwl-ucode.h" | ||
36 | #include "iwl-wifi.h" | 38 | #include "iwl-wifi.h" |
37 | #include "iwl-dev.h" | 39 | #include "iwl-dev.h" |
38 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
@@ -80,29 +82,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
80 | * | 82 | * |
81 | ******************************************************************************/ | 83 | ******************************************************************************/ |
82 | 84 | ||
83 | static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) | 85 | static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc) |
84 | { | 86 | { |
85 | if (desc->v_addr) | 87 | if (desc->v_addr) |
86 | dma_free_coherent(bus->dev, desc->len, | 88 | dma_free_coherent(trans->dev, desc->len, |
87 | desc->v_addr, desc->p_addr); | 89 | desc->v_addr, desc->p_addr); |
88 | desc->v_addr = NULL; | 90 | desc->v_addr = NULL; |
89 | desc->len = 0; | 91 | desc->len = 0; |
90 | } | 92 | } |
91 | 93 | ||
92 | static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) | 94 | static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img) |
93 | { | 95 | { |
94 | iwl_free_fw_desc(bus, &img->code); | 96 | iwl_free_fw_desc(trans, &img->code); |
95 | iwl_free_fw_desc(bus, &img->data); | 97 | iwl_free_fw_desc(trans, &img->data); |
96 | } | 98 | } |
97 | 99 | ||
98 | void iwl_dealloc_ucode(struct iwl_trans *trans) | 100 | void iwl_dealloc_ucode(struct iwl_trans *trans) |
99 | { | 101 | { |
100 | iwl_free_fw_img(bus(trans), &trans->ucode_rt); | 102 | iwl_free_fw_img(trans, &trans->ucode_rt); |
101 | iwl_free_fw_img(bus(trans), &trans->ucode_init); | 103 | iwl_free_fw_img(trans, &trans->ucode_init); |
102 | iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); | 104 | iwl_free_fw_img(trans, &trans->ucode_wowlan); |
103 | } | 105 | } |
104 | 106 | ||
105 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | 107 | static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, |
106 | const void *data, size_t len) | 108 | const void *data, size_t len) |
107 | { | 109 | { |
108 | if (!len) { | 110 | if (!len) { |
@@ -110,7 +112,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | |||
110 | return -EINVAL; | 112 | return -EINVAL; |
111 | } | 113 | } |
112 | 114 | ||
113 | desc->v_addr = dma_alloc_coherent(bus->dev, len, | 115 | desc->v_addr = dma_alloc_coherent(trans->dev, len, |
114 | &desc->p_addr, GFP_KERNEL); | 116 | &desc->p_addr, GFP_KERNEL); |
115 | if (!desc->v_addr) | 117 | if (!desc->v_addr) |
116 | return -ENOMEM; | 118 | return -ENOMEM; |
@@ -120,59 +122,6 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | |||
120 | return 0; | 122 | return 0; |
121 | } | 123 | } |
122 | 124 | ||
123 | /* | ||
124 | * ucode | ||
125 | */ | ||
126 | static int iwl_load_section(struct iwl_trans *trans, const char *name, | ||
127 | struct fw_desc *image, u32 dst_addr) | ||
128 | { | ||
129 | struct iwl_bus *bus = bus(trans); | ||
130 | dma_addr_t phy_addr = image->p_addr; | ||
131 | u32 byte_cnt = image->len; | ||
132 | int ret; | ||
133 | |||
134 | trans->ucode_write_complete = 0; | ||
135 | |||
136 | iwl_write_direct32(bus, | ||
137 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
138 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | ||
139 | |||
140 | iwl_write_direct32(bus, | ||
141 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | ||
142 | |||
143 | iwl_write_direct32(bus, | ||
144 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | ||
145 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | ||
146 | |||
147 | iwl_write_direct32(bus, | ||
148 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | ||
149 | (iwl_get_dma_hi_addr(phy_addr) | ||
150 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | ||
151 | |||
152 | iwl_write_direct32(bus, | ||
153 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | ||
154 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | ||
155 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | ||
156 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | ||
157 | |||
158 | iwl_write_direct32(bus, | ||
159 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
160 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
161 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | ||
162 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | ||
163 | |||
164 | IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); | ||
165 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | ||
166 | trans->ucode_write_complete, 5 * HZ); | ||
167 | if (!ret) { | ||
168 | IWL_ERR(trans, "Could not load the %s uCode section\n", | ||
169 | name); | ||
170 | return -ETIMEDOUT; | ||
171 | } | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, | 125 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, |
177 | enum iwl_ucode_type ucode_type) | 126 | enum iwl_ucode_type ucode_type) |
178 | { | 127 | { |
@@ -189,28 +138,6 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, | |||
189 | return NULL; | 138 | return NULL; |
190 | } | 139 | } |
191 | 140 | ||
192 | static int iwl_load_given_ucode(struct iwl_trans *trans, | ||
193 | enum iwl_ucode_type ucode_type) | ||
194 | { | ||
195 | int ret = 0; | ||
196 | struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); | ||
197 | |||
198 | |||
199 | if (!image) { | ||
200 | IWL_ERR(trans, "Invalid ucode requested (%d)\n", | ||
201 | ucode_type); | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | |||
205 | ret = iwl_load_section(trans, "INST", &image->code, | ||
206 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | |||
210 | return iwl_load_section(trans, "DATA", &image->data, | ||
211 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
212 | } | ||
213 | |||
214 | /* | 141 | /* |
215 | * Calibration | 142 | * Calibration |
216 | */ | 143 | */ |
@@ -447,7 +374,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) | |||
447 | if (!priv->tx_cmd_pool) | 374 | if (!priv->tx_cmd_pool) |
448 | return -ENOMEM; | 375 | return -ENOMEM; |
449 | 376 | ||
450 | iwl_trans_tx_start(trans); | 377 | iwl_trans_fw_alive(trans); |
451 | for_each_context(priv, ctx) | 378 | for_each_context(priv, ctx) |
452 | ctx->last_tx_rejected = false; | 379 | ctx->last_tx_rejected = false; |
453 | 380 | ||
@@ -470,7 +397,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) | |||
470 | * using sample data 100 bytes apart. If these sample points are good, | 397 | * using sample data 100 bytes apart. If these sample points are good, |
471 | * it's a pretty good bet that everything between them is good, too. | 398 | * it's a pretty good bet that everything between them is good, too. |
472 | */ | 399 | */ |
473 | static int iwl_verify_inst_sparse(struct iwl_bus *bus, | 400 | static int iwl_verify_inst_sparse(struct iwl_trans *trans, |
474 | struct fw_desc *fw_desc) | 401 | struct fw_desc *fw_desc) |
475 | { | 402 | { |
476 | __le32 *image = (__le32 *)fw_desc->v_addr; | 403 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -478,15 +405,15 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, | |||
478 | u32 val; | 405 | u32 val; |
479 | u32 i; | 406 | u32 i; |
480 | 407 | ||
481 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); | 408 | IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); |
482 | 409 | ||
483 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 410 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
484 | /* read data comes through single port, auto-incr addr */ | 411 | /* read data comes through single port, auto-incr addr */ |
485 | /* NOTE: Use the debugless read so we don't flood kernel log | 412 | /* NOTE: Use the debugless read so we don't flood kernel log |
486 | * if IWL_DL_IO is set */ | 413 | * if IWL_DL_IO is set */ |
487 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, | 414 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, |
488 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 415 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
489 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); | 416 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
490 | if (val != le32_to_cpu(*image)) | 417 | if (val != le32_to_cpu(*image)) |
491 | return -EIO; | 418 | return -EIO; |
492 | } | 419 | } |
@@ -494,7 +421,7 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, | |||
494 | return 0; | 421 | return 0; |
495 | } | 422 | } |
496 | 423 | ||
497 | static void iwl_print_mismatch_inst(struct iwl_bus *bus, | 424 | static void iwl_print_mismatch_inst(struct iwl_trans *trans, |
498 | struct fw_desc *fw_desc) | 425 | struct fw_desc *fw_desc) |
499 | { | 426 | { |
500 | __le32 *image = (__le32 *)fw_desc->v_addr; | 427 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -503,18 +430,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus, | |||
503 | u32 offs; | 430 | u32 offs; |
504 | int errors = 0; | 431 | int errors = 0; |
505 | 432 | ||
506 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); | 433 | IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); |
507 | 434 | ||
508 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, | 435 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, |
509 | IWLAGN_RTC_INST_LOWER_BOUND); | 436 | IWLAGN_RTC_INST_LOWER_BOUND); |
510 | 437 | ||
511 | for (offs = 0; | 438 | for (offs = 0; |
512 | offs < len && errors < 20; | 439 | offs < len && errors < 20; |
513 | offs += sizeof(u32), image++) { | 440 | offs += sizeof(u32), image++) { |
514 | /* read data comes through single port, auto-incr addr */ | 441 | /* read data comes through single port, auto-incr addr */ |
515 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); | 442 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
516 | if (val != le32_to_cpu(*image)) { | 443 | if (val != le32_to_cpu(*image)) { |
517 | IWL_ERR(bus, "uCode INST section at " | 444 | IWL_ERR(trans, "uCode INST section at " |
518 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 445 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
519 | offs, val, le32_to_cpu(*image)); | 446 | offs, val, le32_to_cpu(*image)); |
520 | errors++; | 447 | errors++; |
@@ -536,14 +463,14 @@ static int iwl_verify_ucode(struct iwl_trans *trans, | |||
536 | return -EINVAL; | 463 | return -EINVAL; |
537 | } | 464 | } |
538 | 465 | ||
539 | if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { | 466 | if (!iwl_verify_inst_sparse(trans, &img->code)) { |
540 | IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); | 467 | IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); |
541 | return 0; | 468 | return 0; |
542 | } | 469 | } |
543 | 470 | ||
544 | IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 471 | IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
545 | 472 | ||
546 | iwl_print_mismatch_inst(bus(trans), &img->code); | 473 | iwl_print_mismatch_inst(trans, &img->code); |
547 | return -EIO; | 474 | return -EIO; |
548 | } | 475 | } |
549 | 476 | ||
@@ -647,28 +574,27 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
647 | { | 574 | { |
648 | struct iwl_notification_wait alive_wait; | 575 | struct iwl_notification_wait alive_wait; |
649 | struct iwl_alive_data alive_data; | 576 | struct iwl_alive_data alive_data; |
577 | struct fw_img *fw; | ||
650 | int ret; | 578 | int ret; |
651 | enum iwl_ucode_type old_type; | 579 | enum iwl_ucode_type old_type; |
652 | 580 | ||
653 | ret = iwl_trans_start_device(trans); | ||
654 | if (ret) | ||
655 | return ret; | ||
656 | |||
657 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, | 581 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, |
658 | iwl_alive_fn, &alive_data); | 582 | iwl_alive_fn, &alive_data); |
659 | 583 | ||
660 | old_type = trans->shrd->ucode_type; | 584 | old_type = trans->shrd->ucode_type; |
661 | trans->shrd->ucode_type = ucode_type; | 585 | trans->shrd->ucode_type = ucode_type; |
586 | fw = iwl_get_ucode_image(trans, ucode_type); | ||
587 | |||
588 | if (!fw) | ||
589 | return -EINVAL; | ||
662 | 590 | ||
663 | ret = iwl_load_given_ucode(trans, ucode_type); | 591 | ret = iwl_trans_start_fw(trans, fw); |
664 | if (ret) { | 592 | if (ret) { |
665 | trans->shrd->ucode_type = old_type; | 593 | trans->shrd->ucode_type = old_type; |
666 | iwl_remove_notification(trans->shrd, &alive_wait); | 594 | iwl_remove_notification(trans->shrd, &alive_wait); |
667 | return ret; | 595 | return ret; |
668 | } | 596 | } |
669 | 597 | ||
670 | iwl_trans_kick_nic(trans); | ||
671 | |||
672 | /* | 598 | /* |
673 | * Some things may run in the background now, but we | 599 | * Some things may run in the background now, but we |
674 | * just wait for the ALIVE notification here. | 600 | * just wait for the ALIVE notification here. |
@@ -756,3 +682,609 @@ int iwl_run_init_ucode(struct iwl_trans *trans) | |||
756 | iwl_trans_stop_device(trans); | 682 | iwl_trans_stop_device(trans); |
757 | return ret; | 683 | return ret; |
758 | } | 684 | } |
685 | |||
686 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
687 | |||
688 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
689 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
690 | |||
691 | int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | ||
692 | { | ||
693 | const char *name_pre = cfg(priv)->fw_name_pre; | ||
694 | char tag[8]; | ||
695 | |||
696 | if (first) { | ||
697 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
698 | priv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
699 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
700 | } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
701 | #endif | ||
702 | priv->fw_index = cfg(priv)->ucode_api_max; | ||
703 | sprintf(tag, "%d", priv->fw_index); | ||
704 | } else { | ||
705 | priv->fw_index--; | ||
706 | sprintf(tag, "%d", priv->fw_index); | ||
707 | } | ||
708 | |||
709 | if (priv->fw_index < cfg(priv)->ucode_api_min) { | ||
710 | IWL_ERR(priv, "no suitable firmware found!\n"); | ||
711 | return -ENOENT; | ||
712 | } | ||
713 | |||
714 | sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
715 | |||
716 | IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", | ||
717 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
718 | ? "EXPERIMENTAL " : "", | ||
719 | priv->firmware_name); | ||
720 | |||
721 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | ||
722 | trans(priv)->dev, | ||
723 | GFP_KERNEL, priv, iwl_ucode_callback); | ||
724 | } | ||
725 | |||
726 | struct iwlagn_firmware_pieces { | ||
727 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
728 | size_t inst_size, data_size, init_size, init_data_size, | ||
729 | wowlan_inst_size, wowlan_data_size; | ||
730 | |||
731 | u32 build; | ||
732 | |||
733 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
734 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
735 | }; | ||
736 | |||
737 | static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, | ||
738 | const struct firmware *ucode_raw, | ||
739 | struct iwlagn_firmware_pieces *pieces) | ||
740 | { | ||
741 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
742 | u32 api_ver, hdr_size; | ||
743 | const u8 *src; | ||
744 | |||
745 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
746 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
747 | |||
748 | switch (api_ver) { | ||
749 | default: | ||
750 | hdr_size = 28; | ||
751 | if (ucode_raw->size < hdr_size) { | ||
752 | IWL_ERR(priv, "File size too small!\n"); | ||
753 | return -EINVAL; | ||
754 | } | ||
755 | pieces->build = le32_to_cpu(ucode->u.v2.build); | ||
756 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
757 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
758 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
759 | pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); | ||
760 | src = ucode->u.v2.data; | ||
761 | break; | ||
762 | case 0: | ||
763 | case 1: | ||
764 | case 2: | ||
765 | hdr_size = 24; | ||
766 | if (ucode_raw->size < hdr_size) { | ||
767 | IWL_ERR(priv, "File size too small!\n"); | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | pieces->build = 0; | ||
771 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
772 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
773 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
774 | pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); | ||
775 | src = ucode->u.v1.data; | ||
776 | break; | ||
777 | } | ||
778 | |||
779 | /* Verify size of file vs. image size info in file's header */ | ||
780 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
781 | pieces->data_size + pieces->init_size + | ||
782 | pieces->init_data_size) { | ||
783 | |||
784 | IWL_ERR(priv, | ||
785 | "uCode file size %d does not match expected size\n", | ||
786 | (int)ucode_raw->size); | ||
787 | return -EINVAL; | ||
788 | } | ||
789 | |||
790 | pieces->inst = src; | ||
791 | src += pieces->inst_size; | ||
792 | pieces->data = src; | ||
793 | src += pieces->data_size; | ||
794 | pieces->init = src; | ||
795 | src += pieces->init_size; | ||
796 | pieces->init_data = src; | ||
797 | src += pieces->init_data_size; | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | static int iwlagn_load_firmware(struct iwl_priv *priv, | ||
803 | const struct firmware *ucode_raw, | ||
804 | struct iwlagn_firmware_pieces *pieces, | ||
805 | struct iwlagn_ucode_capabilities *capa) | ||
806 | { | ||
807 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
808 | struct iwl_ucode_tlv *tlv; | ||
809 | size_t len = ucode_raw->size; | ||
810 | const u8 *data; | ||
811 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
812 | int tmp; | ||
813 | u64 alternatives; | ||
814 | u32 tlv_len; | ||
815 | enum iwl_ucode_tlv_type tlv_type; | ||
816 | const u8 *tlv_data; | ||
817 | |||
818 | if (len < sizeof(*ucode)) { | ||
819 | IWL_ERR(priv, "uCode has invalid length: %zd\n", len); | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
824 | IWL_ERR(priv, "invalid uCode magic: 0X%x\n", | ||
825 | le32_to_cpu(ucode->magic)); | ||
826 | return -EINVAL; | ||
827 | } | ||
828 | |||
829 | /* | ||
830 | * Check which alternatives are present, and "downgrade" | ||
831 | * when the chosen alternative is not present, warning | ||
832 | * the user when that happens. Some files may not have | ||
833 | * any alternatives, so don't warn in that case. | ||
834 | */ | ||
835 | alternatives = le64_to_cpu(ucode->alternatives); | ||
836 | tmp = wanted_alternative; | ||
837 | if (wanted_alternative > 63) | ||
838 | wanted_alternative = 63; | ||
839 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
840 | wanted_alternative--; | ||
841 | if (wanted_alternative && wanted_alternative != tmp) | ||
842 | IWL_WARN(priv, | ||
843 | "uCode alternative %d not available, choosing %d\n", | ||
844 | tmp, wanted_alternative); | ||
845 | |||
846 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
847 | pieces->build = le32_to_cpu(ucode->build); | ||
848 | data = ucode->data; | ||
849 | |||
850 | len -= sizeof(*ucode); | ||
851 | |||
852 | while (len >= sizeof(*tlv)) { | ||
853 | u16 tlv_alt; | ||
854 | |||
855 | len -= sizeof(*tlv); | ||
856 | tlv = (void *)data; | ||
857 | |||
858 | tlv_len = le32_to_cpu(tlv->length); | ||
859 | tlv_type = le16_to_cpu(tlv->type); | ||
860 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
861 | tlv_data = tlv->data; | ||
862 | |||
863 | if (len < tlv_len) { | ||
864 | IWL_ERR(priv, "invalid TLV len: %zd/%u\n", | ||
865 | len, tlv_len); | ||
866 | return -EINVAL; | ||
867 | } | ||
868 | len -= ALIGN(tlv_len, 4); | ||
869 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
870 | |||
871 | /* | ||
872 | * Alternative 0 is always valid. | ||
873 | * | ||
874 | * Skip alternative TLVs that are not selected. | ||
875 | */ | ||
876 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
877 | continue; | ||
878 | |||
879 | switch (tlv_type) { | ||
880 | case IWL_UCODE_TLV_INST: | ||
881 | pieces->inst = tlv_data; | ||
882 | pieces->inst_size = tlv_len; | ||
883 | break; | ||
884 | case IWL_UCODE_TLV_DATA: | ||
885 | pieces->data = tlv_data; | ||
886 | pieces->data_size = tlv_len; | ||
887 | break; | ||
888 | case IWL_UCODE_TLV_INIT: | ||
889 | pieces->init = tlv_data; | ||
890 | pieces->init_size = tlv_len; | ||
891 | break; | ||
892 | case IWL_UCODE_TLV_INIT_DATA: | ||
893 | pieces->init_data = tlv_data; | ||
894 | pieces->init_data_size = tlv_len; | ||
895 | break; | ||
896 | case IWL_UCODE_TLV_BOOT: | ||
897 | IWL_ERR(priv, "Found unexpected BOOT ucode\n"); | ||
898 | break; | ||
899 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
900 | if (tlv_len != sizeof(u32)) | ||
901 | goto invalid_tlv_len; | ||
902 | capa->max_probe_length = | ||
903 | le32_to_cpup((__le32 *)tlv_data); | ||
904 | break; | ||
905 | case IWL_UCODE_TLV_PAN: | ||
906 | if (tlv_len) | ||
907 | goto invalid_tlv_len; | ||
908 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
909 | break; | ||
910 | case IWL_UCODE_TLV_FLAGS: | ||
911 | /* must be at least one u32 */ | ||
912 | if (tlv_len < sizeof(u32)) | ||
913 | goto invalid_tlv_len; | ||
914 | /* and a proper number of u32s */ | ||
915 | if (tlv_len % sizeof(u32)) | ||
916 | goto invalid_tlv_len; | ||
917 | /* | ||
918 | * This driver only reads the first u32 as | ||
919 | * right now no more features are defined, | ||
920 | * if that changes then either the driver | ||
921 | * will not work with the new firmware, or | ||
922 | * it'll not take advantage of new features. | ||
923 | */ | ||
924 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
925 | break; | ||
926 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
927 | if (tlv_len != sizeof(u32)) | ||
928 | goto invalid_tlv_len; | ||
929 | pieces->init_evtlog_ptr = | ||
930 | le32_to_cpup((__le32 *)tlv_data); | ||
931 | break; | ||
932 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
933 | if (tlv_len != sizeof(u32)) | ||
934 | goto invalid_tlv_len; | ||
935 | pieces->init_evtlog_size = | ||
936 | le32_to_cpup((__le32 *)tlv_data); | ||
937 | break; | ||
938 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
939 | if (tlv_len != sizeof(u32)) | ||
940 | goto invalid_tlv_len; | ||
941 | pieces->init_errlog_ptr = | ||
942 | le32_to_cpup((__le32 *)tlv_data); | ||
943 | break; | ||
944 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
945 | if (tlv_len != sizeof(u32)) | ||
946 | goto invalid_tlv_len; | ||
947 | pieces->inst_evtlog_ptr = | ||
948 | le32_to_cpup((__le32 *)tlv_data); | ||
949 | break; | ||
950 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
951 | if (tlv_len != sizeof(u32)) | ||
952 | goto invalid_tlv_len; | ||
953 | pieces->inst_evtlog_size = | ||
954 | le32_to_cpup((__le32 *)tlv_data); | ||
955 | break; | ||
956 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
957 | if (tlv_len != sizeof(u32)) | ||
958 | goto invalid_tlv_len; | ||
959 | pieces->inst_errlog_ptr = | ||
960 | le32_to_cpup((__le32 *)tlv_data); | ||
961 | break; | ||
962 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
963 | if (tlv_len) | ||
964 | goto invalid_tlv_len; | ||
965 | priv->enhance_sensitivity_table = true; | ||
966 | break; | ||
967 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
968 | pieces->wowlan_inst = tlv_data; | ||
969 | pieces->wowlan_inst_size = tlv_len; | ||
970 | break; | ||
971 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
972 | pieces->wowlan_data = tlv_data; | ||
973 | pieces->wowlan_data_size = tlv_len; | ||
974 | break; | ||
975 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
976 | if (tlv_len != sizeof(u32)) | ||
977 | goto invalid_tlv_len; | ||
978 | capa->standard_phy_calibration_size = | ||
979 | le32_to_cpup((__le32 *)tlv_data); | ||
980 | break; | ||
981 | default: | ||
982 | IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); | ||
983 | break; | ||
984 | } | ||
985 | } | ||
986 | |||
987 | if (len) { | ||
988 | IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); | ||
989 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | |||
993 | return 0; | ||
994 | |||
995 | invalid_tlv_len: | ||
996 | IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
997 | iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); | ||
998 | |||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
1003 | * iwl_ucode_callback - callback when firmware was loaded | ||
1004 | * | ||
1005 | * If loaded successfully, copies the firmware into buffers | ||
1006 | * for the card to fetch (via DMA). | ||
1007 | */ | ||
1008 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
1009 | { | ||
1010 | struct iwl_priv *priv = context; | ||
1011 | struct iwl_ucode_header *ucode; | ||
1012 | int err; | ||
1013 | struct iwlagn_firmware_pieces pieces; | ||
1014 | const unsigned int api_max = cfg(priv)->ucode_api_max; | ||
1015 | unsigned int api_ok = cfg(priv)->ucode_api_ok; | ||
1016 | const unsigned int api_min = cfg(priv)->ucode_api_min; | ||
1017 | u32 api_ver; | ||
1018 | char buildstr[25]; | ||
1019 | u32 build; | ||
1020 | struct iwlagn_ucode_capabilities ucode_capa = { | ||
1021 | .max_probe_length = 200, | ||
1022 | .standard_phy_calibration_size = | ||
1023 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, | ||
1024 | }; | ||
1025 | |||
1026 | if (!api_ok) | ||
1027 | api_ok = api_max; | ||
1028 | |||
1029 | memset(&pieces, 0, sizeof(pieces)); | ||
1030 | |||
1031 | if (!ucode_raw) { | ||
1032 | if (priv->fw_index <= api_ok) | ||
1033 | IWL_ERR(priv, | ||
1034 | "request for firmware file '%s' failed.\n", | ||
1035 | priv->firmware_name); | ||
1036 | goto try_again; | ||
1037 | } | ||
1038 | |||
1039 | IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
1040 | priv->firmware_name, ucode_raw->size); | ||
1041 | |||
1042 | /* Make sure that we got at least the API version number */ | ||
1043 | if (ucode_raw->size < 4) { | ||
1044 | IWL_ERR(priv, "File size way too small!\n"); | ||
1045 | goto try_again; | ||
1046 | } | ||
1047 | |||
1048 | /* Data from ucode file: header followed by uCode images */ | ||
1049 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
1050 | |||
1051 | if (ucode->ver) | ||
1052 | err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); | ||
1053 | else | ||
1054 | err = iwlagn_load_firmware(priv, ucode_raw, &pieces, | ||
1055 | &ucode_capa); | ||
1056 | |||
1057 | if (err) | ||
1058 | goto try_again; | ||
1059 | |||
1060 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
1061 | build = pieces.build; | ||
1062 | |||
1063 | /* | ||
1064 | * api_ver should match the api version forming part of the | ||
1065 | * firmware filename ... but we don't check for that and only rely | ||
1066 | * on the API version read from firmware header from here on forward | ||
1067 | */ | ||
1068 | /* no api version check required for experimental uCode */ | ||
1069 | if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
1070 | if (api_ver < api_min || api_ver > api_max) { | ||
1071 | IWL_ERR(priv, | ||
1072 | "Driver unable to support your firmware API. " | ||
1073 | "Driver supports v%u, firmware is v%u.\n", | ||
1074 | api_max, api_ver); | ||
1075 | goto try_again; | ||
1076 | } | ||
1077 | |||
1078 | if (api_ver < api_ok) { | ||
1079 | if (api_ok != api_max) | ||
1080 | IWL_ERR(priv, "Firmware has old API version, " | ||
1081 | "expected v%u through v%u, got v%u.\n", | ||
1082 | api_ok, api_max, api_ver); | ||
1083 | else | ||
1084 | IWL_ERR(priv, "Firmware has old API version, " | ||
1085 | "expected v%u, got v%u.\n", | ||
1086 | api_max, api_ver); | ||
1087 | IWL_ERR(priv, "New firmware can be obtained from " | ||
1088 | "http://www.intellinuxwireless.org/.\n"); | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | if (build) | ||
1093 | sprintf(buildstr, " build %u%s", build, | ||
1094 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
1095 | ? " (EXP)" : ""); | ||
1096 | else | ||
1097 | buildstr[0] = '\0'; | ||
1098 | |||
1099 | IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", | ||
1100 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
1101 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
1102 | IWL_UCODE_API(priv->ucode_ver), | ||
1103 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
1104 | buildstr); | ||
1105 | |||
1106 | snprintf(priv->hw->wiphy->fw_version, | ||
1107 | sizeof(priv->hw->wiphy->fw_version), | ||
1108 | "%u.%u.%u.%u%s", | ||
1109 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
1110 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
1111 | IWL_UCODE_API(priv->ucode_ver), | ||
1112 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
1113 | buildstr); | ||
1114 | |||
1115 | /* | ||
1116 | * For any of the failures below (before allocating pci memory) | ||
1117 | * we will try to load a version with a smaller API -- maybe the | ||
1118 | * user just got a corrupted version of the latest API. | ||
1119 | */ | ||
1120 | |||
1121 | IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", | ||
1122 | priv->ucode_ver); | ||
1123 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", | ||
1124 | pieces.inst_size); | ||
1125 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", | ||
1126 | pieces.data_size); | ||
1127 | IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", | ||
1128 | pieces.init_size); | ||
1129 | IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", | ||
1130 | pieces.init_data_size); | ||
1131 | |||
1132 | /* Verify that uCode images will fit in card's SRAM */ | ||
1133 | if (pieces.inst_size > hw_params(priv).max_inst_size) { | ||
1134 | IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", | ||
1135 | pieces.inst_size); | ||
1136 | goto try_again; | ||
1137 | } | ||
1138 | |||
1139 | if (pieces.data_size > hw_params(priv).max_data_size) { | ||
1140 | IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", | ||
1141 | pieces.data_size); | ||
1142 | goto try_again; | ||
1143 | } | ||
1144 | |||
1145 | if (pieces.init_size > hw_params(priv).max_inst_size) { | ||
1146 | IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", | ||
1147 | pieces.init_size); | ||
1148 | goto try_again; | ||
1149 | } | ||
1150 | |||
1151 | if (pieces.init_data_size > hw_params(priv).max_data_size) { | ||
1152 | IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", | ||
1153 | pieces.init_data_size); | ||
1154 | goto try_again; | ||
1155 | } | ||
1156 | |||
1157 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
1158 | |||
1159 | /* Runtime instructions and 2 copies of data: | ||
1160 | * 1) unmodified from disk | ||
1161 | * 2) backup cache for save/restore during power-downs */ | ||
1162 | if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, | ||
1163 | pieces.inst, pieces.inst_size)) | ||
1164 | goto err_pci_alloc; | ||
1165 | if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, | ||
1166 | pieces.data, pieces.data_size)) | ||
1167 | goto err_pci_alloc; | ||
1168 | |||
1169 | /* Initialization instructions and data */ | ||
1170 | if (pieces.init_size && pieces.init_data_size) { | ||
1171 | if (iwl_alloc_fw_desc(trans(priv), | ||
1172 | &trans(priv)->ucode_init.code, | ||
1173 | pieces.init, pieces.init_size)) | ||
1174 | goto err_pci_alloc; | ||
1175 | if (iwl_alloc_fw_desc(trans(priv), | ||
1176 | &trans(priv)->ucode_init.data, | ||
1177 | pieces.init_data, pieces.init_data_size)) | ||
1178 | goto err_pci_alloc; | ||
1179 | } | ||
1180 | |||
1181 | /* WoWLAN instructions and data */ | ||
1182 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
1183 | if (iwl_alloc_fw_desc(trans(priv), | ||
1184 | &trans(priv)->ucode_wowlan.code, | ||
1185 | pieces.wowlan_inst, | ||
1186 | pieces.wowlan_inst_size)) | ||
1187 | goto err_pci_alloc; | ||
1188 | if (iwl_alloc_fw_desc(trans(priv), | ||
1189 | &trans(priv)->ucode_wowlan.data, | ||
1190 | pieces.wowlan_data, | ||
1191 | pieces.wowlan_data_size)) | ||
1192 | goto err_pci_alloc; | ||
1193 | } | ||
1194 | |||
1195 | /* Now that we can no longer fail, copy information */ | ||
1196 | |||
1197 | /* | ||
1198 | * The (size - 16) / 12 formula is based on the information recorded | ||
1199 | * for each event, which is of mode 1 (including timestamp) for all | ||
1200 | * new microcodes that include this information. | ||
1201 | */ | ||
1202 | priv->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
1203 | if (pieces.init_evtlog_size) | ||
1204 | priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
1205 | else | ||
1206 | priv->init_evtlog_size = | ||
1207 | cfg(priv)->base_params->max_event_log_size; | ||
1208 | priv->init_errlog_ptr = pieces.init_errlog_ptr; | ||
1209 | priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
1210 | if (pieces.inst_evtlog_size) | ||
1211 | priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
1212 | else | ||
1213 | priv->inst_evtlog_size = | ||
1214 | cfg(priv)->base_params->max_event_log_size; | ||
1215 | priv->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
1216 | #ifndef CONFIG_IWLWIFI_P2P | ||
1217 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1218 | #endif | ||
1219 | |||
1220 | priv->new_scan_threshold_behaviour = | ||
1221 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | ||
1222 | |||
1223 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | ||
1224 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1225 | |||
1226 | /* | ||
1227 | * if not PAN, then don't support P2P -- might be a uCode | ||
1228 | * packaging bug or due to the eeprom check above | ||
1229 | */ | ||
1230 | if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1231 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | ||
1232 | |||
1233 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1234 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1235 | priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1236 | } else { | ||
1237 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1238 | priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1239 | } | ||
1240 | /* | ||
1241 | * figure out the offset of chain noise reset and gain commands | ||
1242 | * base on the size of standard phy calibration commands table size | ||
1243 | */ | ||
1244 | if (ucode_capa.standard_phy_calibration_size > | ||
1245 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
1246 | ucode_capa.standard_phy_calibration_size = | ||
1247 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
1248 | |||
1249 | priv->phy_calib_chain_noise_reset_cmd = | ||
1250 | ucode_capa.standard_phy_calibration_size; | ||
1251 | priv->phy_calib_chain_noise_gain_cmd = | ||
1252 | ucode_capa.standard_phy_calibration_size + 1; | ||
1253 | |||
1254 | /* initialize all valid contexts */ | ||
1255 | iwl_init_context(priv, ucode_capa.flags); | ||
1256 | |||
1257 | /************************************************** | ||
1258 | * This is still part of probe() in a sense... | ||
1259 | * | ||
1260 | * 9. Setup and register with mac80211 and debugfs | ||
1261 | **************************************************/ | ||
1262 | err = iwlagn_mac_setup_register(priv, &ucode_capa); | ||
1263 | if (err) | ||
1264 | goto out_unbind; | ||
1265 | |||
1266 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
1267 | if (err) | ||
1268 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
1269 | |||
1270 | /* We have our copies now, allow OS release its copies */ | ||
1271 | release_firmware(ucode_raw); | ||
1272 | complete(&priv->firmware_loading_complete); | ||
1273 | return; | ||
1274 | |||
1275 | try_again: | ||
1276 | /* try next, if any */ | ||
1277 | if (iwl_request_firmware(priv, false)) | ||
1278 | goto out_unbind; | ||
1279 | release_firmware(ucode_raw); | ||
1280 | return; | ||
1281 | |||
1282 | err_pci_alloc: | ||
1283 | IWL_ERR(priv, "failed to allocate pci memory\n"); | ||
1284 | iwl_dealloc_ucode(trans(priv)); | ||
1285 | out_unbind: | ||
1286 | complete(&priv->firmware_loading_complete); | ||
1287 | device_release_driver(trans(priv)->dev); | ||
1288 | release_firmware(ucode_raw); | ||
1289 | } | ||
1290 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h new file mode 100644 index 000000000000..eccf92519a84 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.h | |||
@@ -0,0 +1,178 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | #ifndef __iwl_ucode_h__ | ||
64 | #define __iwl_ucode_h__ | ||
65 | |||
66 | /* v1/v2 uCode file layout */ | ||
67 | struct iwl_ucode_header { | ||
68 | __le32 ver; /* major/minor/API/serial */ | ||
69 | union { | ||
70 | struct { | ||
71 | __le32 inst_size; /* bytes of runtime code */ | ||
72 | __le32 data_size; /* bytes of runtime data */ | ||
73 | __le32 init_size; /* bytes of init code */ | ||
74 | __le32 init_data_size; /* bytes of init data */ | ||
75 | __le32 boot_size; /* bytes of bootstrap code */ | ||
76 | u8 data[0]; /* in same order as sizes */ | ||
77 | } v1; | ||
78 | struct { | ||
79 | __le32 build; /* build number */ | ||
80 | __le32 inst_size; /* bytes of runtime code */ | ||
81 | __le32 data_size; /* bytes of runtime data */ | ||
82 | __le32 init_size; /* bytes of init code */ | ||
83 | __le32 init_data_size; /* bytes of init data */ | ||
84 | __le32 boot_size; /* bytes of bootstrap code */ | ||
85 | u8 data[0]; /* in same order as sizes */ | ||
86 | } v2; | ||
87 | } u; | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * new TLV uCode file layout | ||
92 | * | ||
93 | * The new TLV file format contains TLVs, that each specify | ||
94 | * some piece of data. To facilitate "groups", for example | ||
95 | * different instruction image with different capabilities, | ||
96 | * bundled with the same init image, an alternative mechanism | ||
97 | * is provided: | ||
98 | * When the alternative field is 0, that means that the item | ||
99 | * is always valid. When it is non-zero, then it is only | ||
100 | * valid in conjunction with items of the same alternative, | ||
101 | * in which case the driver (user) selects one alternative | ||
102 | * to use. | ||
103 | */ | ||
104 | |||
105 | enum iwl_ucode_tlv_type { | ||
106 | IWL_UCODE_TLV_INVALID = 0, /* unused */ | ||
107 | IWL_UCODE_TLV_INST = 1, | ||
108 | IWL_UCODE_TLV_DATA = 2, | ||
109 | IWL_UCODE_TLV_INIT = 3, | ||
110 | IWL_UCODE_TLV_INIT_DATA = 4, | ||
111 | IWL_UCODE_TLV_BOOT = 5, | ||
112 | IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ | ||
113 | IWL_UCODE_TLV_PAN = 7, | ||
114 | IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, | ||
115 | IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, | ||
116 | IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, | ||
117 | IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, | ||
118 | IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, | ||
119 | IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, | ||
120 | IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, | ||
121 | IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, | ||
122 | IWL_UCODE_TLV_WOWLAN_INST = 16, | ||
123 | IWL_UCODE_TLV_WOWLAN_DATA = 17, | ||
124 | IWL_UCODE_TLV_FLAGS = 18, | ||
125 | }; | ||
126 | |||
127 | /** | ||
128 | * enum iwl_ucode_tlv_flag - ucode API flags | ||
129 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
130 | * was a separate TLV but moved here to save space. | ||
131 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
132 | * treats good CRC threshold as a boolean | ||
133 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
134 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
135 | */ | ||
136 | enum iwl_ucode_tlv_flag { | ||
137 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
138 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
139 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
140 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
141 | }; | ||
142 | |||
143 | struct iwl_ucode_tlv { | ||
144 | __le16 type; /* see above */ | ||
145 | __le16 alternative; /* see comment */ | ||
146 | __le32 length; /* not including type/length fields */ | ||
147 | u8 data[0]; | ||
148 | }; | ||
149 | |||
150 | #define IWL_TLV_UCODE_MAGIC 0x0a4c5749 | ||
151 | |||
152 | struct iwl_tlv_ucode_header { | ||
153 | /* | ||
154 | * The TLV style ucode header is distinguished from | ||
155 | * the v1/v2 style header by first four bytes being | ||
156 | * zero, as such is an invalid combination of | ||
157 | * major/minor/API/serial versions. | ||
158 | */ | ||
159 | __le32 zero; | ||
160 | __le32 magic; | ||
161 | u8 human_readable[64]; | ||
162 | __le32 ver; /* major/minor/API/serial */ | ||
163 | __le32 build; | ||
164 | __le64 alternatives; /* bitmask of valid alternatives */ | ||
165 | /* | ||
166 | * The data contained herein has a TLV layout, | ||
167 | * see above for the TLV header and types. | ||
168 | * Note that each TLV is padded to a length | ||
169 | * that is a multiple of 4 for alignment. | ||
170 | */ | ||
171 | u8 data[0]; | ||
172 | }; | ||
173 | |||
174 | struct iwl_priv; | ||
175 | |||
176 | int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first); | ||
177 | |||
178 | #endif /* __iwl_ucode_h__ */ | ||