.. | .. |
---|
6 | 6 | * GPL LICENSE SUMMARY |
---|
7 | 7 | * |
---|
8 | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
---|
9 | | - * Copyright(c) 2018 Intel Corporation |
---|
| 9 | + * Copyright(c) 2018 - 2020 Intel Corporation |
---|
10 | 10 | * |
---|
11 | 11 | * This program is free software; you can redistribute it and/or modify |
---|
12 | 12 | * it under the terms of version 2 of the GNU General Public License as |
---|
.. | .. |
---|
20 | 20 | * BSD LICENSE |
---|
21 | 21 | * |
---|
22 | 22 | * Copyright(c) 2017 Intel Deutschland GmbH |
---|
23 | | - * Copyright(c) 2018 Intel Corporation |
---|
| 23 | + * Copyright(c) 2018 - 2020 Intel Corporation |
---|
24 | 24 | * All rights reserved. |
---|
25 | 25 | * |
---|
26 | 26 | * Redistribution and use in source and binary forms, with or without |
---|
.. | .. |
---|
55 | 55 | #include "iwl-context-info.h" |
---|
56 | 56 | #include "iwl-context-info-gen3.h" |
---|
57 | 57 | #include "internal.h" |
---|
| 58 | +#include "fw/dbg.h" |
---|
58 | 59 | |
---|
59 | 60 | /* |
---|
60 | 61 | * Start up NIC's basic functionality after it has been reset |
---|
61 | 62 | * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) |
---|
62 | 63 | * NOTE: This does not load uCode nor start the embedded processor |
---|
63 | 64 | */ |
---|
64 | | -static int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) |
---|
| 65 | +int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) |
---|
65 | 66 | { |
---|
66 | 67 | int ret = 0; |
---|
67 | 68 | |
---|
.. | .. |
---|
91 | 92 | |
---|
92 | 93 | iwl_pcie_apm_config(trans); |
---|
93 | 94 | |
---|
94 | | - /* |
---|
95 | | - * Set "initialization complete" bit to move adapter from |
---|
96 | | - * D0U* --> D0A* (powered-up active) state. |
---|
97 | | - */ |
---|
98 | | - iwl_set_bit(trans, CSR_GP_CNTRL, |
---|
99 | | - BIT(trans->cfg->csr->flag_init_done)); |
---|
100 | | - |
---|
101 | | - /* |
---|
102 | | - * Wait for clock stabilization; once stabilized, access to |
---|
103 | | - * device-internal resources is supported, e.g. iwl_write_prph() |
---|
104 | | - * and accesses to uCode SRAM. |
---|
105 | | - */ |
---|
106 | | - ret = iwl_poll_bit(trans, CSR_GP_CNTRL, |
---|
107 | | - BIT(trans->cfg->csr->flag_mac_clock_ready), |
---|
108 | | - BIT(trans->cfg->csr->flag_mac_clock_ready), |
---|
109 | | - 25000); |
---|
110 | | - if (ret < 0) { |
---|
111 | | - IWL_DEBUG_INFO(trans, "Failed to init the card\n"); |
---|
| 95 | + ret = iwl_finish_nic_init(trans, trans->trans_cfg); |
---|
| 96 | + if (ret) |
---|
112 | 97 | return ret; |
---|
113 | | - } |
---|
114 | 98 | |
---|
115 | 99 | set_bit(STATUS_DEVICE_ENABLED, &trans->status); |
---|
116 | 100 | |
---|
.. | .. |
---|
148 | 132 | * Clear "initialization complete" bit to move adapter from |
---|
149 | 133 | * D0A* (powered-up Active) --> D0U* (Uninitialized) state. |
---|
150 | 134 | */ |
---|
151 | | - iwl_clear_bit(trans, CSR_GP_CNTRL, |
---|
152 | | - BIT(trans->cfg->csr->flag_init_done)); |
---|
| 135 | + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
---|
153 | 136 | } |
---|
154 | 137 | |
---|
155 | | -void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) |
---|
| 138 | +void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) |
---|
156 | 139 | { |
---|
157 | 140 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
---|
158 | 141 | |
---|
.. | .. |
---|
162 | 145 | return; |
---|
163 | 146 | |
---|
164 | 147 | trans_pcie->is_down = true; |
---|
165 | | - |
---|
166 | | - /* Stop dbgc before stopping device */ |
---|
167 | | - iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); |
---|
168 | | - udelay(100); |
---|
169 | | - iwl_write_prph(trans, DBGC_OUT_CTRL, 0); |
---|
170 | 148 | |
---|
171 | 149 | /* tell the device to stop sending interrupts */ |
---|
172 | 150 | iwl_disable_interrupts(trans); |
---|
.. | .. |
---|
184 | 162 | if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { |
---|
185 | 163 | IWL_DEBUG_INFO(trans, |
---|
186 | 164 | "DEVICE_ENABLED bit was set and is now cleared\n"); |
---|
187 | | - iwl_pcie_gen2_tx_stop(trans); |
---|
| 165 | + iwl_txq_gen2_tx_stop(trans); |
---|
188 | 166 | iwl_pcie_rx_stop(trans); |
---|
189 | 167 | } |
---|
190 | 168 | |
---|
191 | 169 | iwl_pcie_ctxt_info_free_paging(trans); |
---|
192 | | - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) |
---|
| 170 | + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) |
---|
193 | 171 | iwl_pcie_ctxt_info_gen3_free(trans); |
---|
194 | 172 | else |
---|
195 | 173 | iwl_pcie_ctxt_info_free(trans); |
---|
196 | 174 | |
---|
197 | 175 | /* Make sure (redundant) we've released our request to stay awake */ |
---|
198 | 176 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
---|
199 | | - BIT(trans->cfg->csr->flag_mac_access_req)); |
---|
| 177 | + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
---|
200 | 178 | |
---|
201 | 179 | /* Stop the device, and put it in low power state */ |
---|
202 | 180 | iwl_pcie_gen2_apm_stop(trans, false); |
---|
.. | .. |
---|
236 | 214 | iwl_pcie_prepare_card_hw(trans); |
---|
237 | 215 | } |
---|
238 | 216 | |
---|
239 | | -void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) |
---|
| 217 | +void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) |
---|
240 | 218 | { |
---|
241 | 219 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
---|
242 | 220 | bool was_in_rfkill; |
---|
.. | .. |
---|
244 | 222 | mutex_lock(&trans_pcie->mutex); |
---|
245 | 223 | trans_pcie->opmode_down = true; |
---|
246 | 224 | was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); |
---|
247 | | - _iwl_trans_pcie_gen2_stop_device(trans, low_power); |
---|
| 225 | + _iwl_trans_pcie_gen2_stop_device(trans); |
---|
248 | 226 | iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); |
---|
249 | 227 | mutex_unlock(&trans_pcie->mutex); |
---|
250 | 228 | } |
---|
.. | .. |
---|
252 | 230 | static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) |
---|
253 | 231 | { |
---|
254 | 232 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
---|
| 233 | + int queue_size = max_t(u32, IWL_CMD_QUEUE_SIZE, |
---|
| 234 | + trans->cfg->min_txq_size); |
---|
255 | 235 | |
---|
256 | 236 | /* TODO: most of the logic can be removed in A0 - but not in Z0 */ |
---|
257 | 237 | spin_lock(&trans_pcie->irq_lock); |
---|
.. | .. |
---|
265 | 245 | return -ENOMEM; |
---|
266 | 246 | |
---|
267 | 247 | /* Allocate or reset and init all Tx and Command queues */ |
---|
268 | | - if (iwl_pcie_gen2_tx_init(trans)) |
---|
| 248 | + if (iwl_txq_gen2_init(trans, trans->txqs.cmd.q_id, queue_size)) |
---|
269 | 249 | return -ENOMEM; |
---|
270 | 250 | |
---|
271 | 251 | /* enable shadow regs in HW */ |
---|
.. | .. |
---|
282 | 262 | iwl_pcie_reset_ict(trans); |
---|
283 | 263 | |
---|
284 | 264 | /* make sure all queue are not stopped/used */ |
---|
285 | | - memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); |
---|
286 | | - memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); |
---|
| 265 | + memset(trans->txqs.queue_stopped, 0, |
---|
| 266 | + sizeof(trans->txqs.queue_stopped)); |
---|
| 267 | + memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used)); |
---|
287 | 268 | |
---|
288 | 269 | /* now that we got alive we can free the fw image & the context info. |
---|
289 | 270 | * paging memory cannot be freed included since FW will still use it |
---|
290 | 271 | */ |
---|
291 | | - iwl_pcie_ctxt_info_free(trans); |
---|
| 272 | + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) |
---|
| 273 | + iwl_pcie_ctxt_info_free(trans); |
---|
292 | 274 | |
---|
293 | 275 | /* |
---|
294 | 276 | * Re-enable all the interrupts, including the RF-Kill one, now that |
---|
.. | .. |
---|
298 | 280 | mutex_lock(&trans_pcie->mutex); |
---|
299 | 281 | iwl_pcie_check_hw_rf_kill(trans); |
---|
300 | 282 | mutex_unlock(&trans_pcie->mutex); |
---|
| 283 | +} |
---|
| 284 | + |
---|
| 285 | +static void iwl_pcie_set_ltr(struct iwl_trans *trans) |
---|
| 286 | +{ |
---|
| 287 | + u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | |
---|
| 288 | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, |
---|
| 289 | + CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | |
---|
| 290 | + u32_encode_bits(250, |
---|
| 291 | + CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | |
---|
| 292 | + CSR_LTR_LONG_VAL_AD_SNOOP_REQ | |
---|
| 293 | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, |
---|
| 294 | + CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | |
---|
| 295 | + u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); |
---|
| 296 | + |
---|
| 297 | + /* |
---|
| 298 | + * To workaround hardware latency issues during the boot process, |
---|
| 299 | + * initialize the LTR to ~250 usec (see ltr_val above). |
---|
| 300 | + * The firmware initializes this again later (to a smaller value). |
---|
| 301 | + */ |
---|
| 302 | + if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || |
---|
| 303 | + trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) && |
---|
| 304 | + !trans->trans_cfg->integrated) { |
---|
| 305 | + iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val); |
---|
| 306 | + } else if (trans->trans_cfg->integrated && |
---|
| 307 | + trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) { |
---|
| 308 | + iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL); |
---|
| 309 | + iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val); |
---|
| 310 | + } |
---|
301 | 311 | } |
---|
302 | 312 | |
---|
303 | 313 | int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, |
---|
.. | .. |
---|
358 | 368 | goto out; |
---|
359 | 369 | } |
---|
360 | 370 | |
---|
361 | | - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) |
---|
| 371 | + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) |
---|
362 | 372 | ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); |
---|
363 | 373 | else |
---|
364 | 374 | ret = iwl_pcie_ctxt_info_init(trans, fw); |
---|
365 | 375 | if (ret) |
---|
366 | 376 | goto out; |
---|
367 | 377 | |
---|
| 378 | + iwl_pcie_set_ltr(trans); |
---|
| 379 | + |
---|
| 380 | + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) |
---|
| 381 | + iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); |
---|
| 382 | + else |
---|
| 383 | + iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1); |
---|
| 384 | + |
---|
368 | 385 | /* re-check RF-Kill state since we may have missed the interrupt */ |
---|
369 | 386 | hw_rfkill = iwl_pcie_check_hw_rf_kill(trans); |
---|
370 | 387 | if (hw_rfkill && !run_in_rfkill) |
---|