1
2
3
4
5
6#include "iwl-trans.h"
7#include "iwl-prph.h"
8#include "iwl-context-info.h"
9#include "iwl-context-info-gen3.h"
10#include "internal.h"
11#include "fw/dbg.h"
12
13#define FW_RESET_TIMEOUT (HZ / 5)
14
15
16
17
18
19
20int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
21{
22 int ret = 0;
23
24 IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
25
26
27
28
29
30
31
32
33
34
35 iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
36 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
37
38
39 iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
40
41
42
43
44
45 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
46 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
47
48 iwl_pcie_apm_config(trans);
49
50 ret = iwl_finish_nic_init(trans, trans->trans_cfg);
51 if (ret)
52 return ret;
53
54 set_bit(STATUS_DEVICE_ENABLED, &trans->status);
55
56 return 0;
57}
58
59static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
60{
61 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
62
63 if (op_mode_leave) {
64 if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
65 iwl_pcie_gen2_apm_init(trans);
66
67
68 iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
69 CSR_RESET_LINK_PWR_MGMT_DISABLED);
70 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
71 CSR_HW_IF_CONFIG_REG_PREPARE |
72 CSR_HW_IF_CONFIG_REG_ENABLE_PME);
73 mdelay(1);
74 iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
75 CSR_RESET_LINK_PWR_MGMT_DISABLED);
76 mdelay(5);
77 }
78
79 clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
80
81
82 iwl_pcie_apm_stop_master(trans);
83
84 iwl_trans_sw_reset(trans);
85
86
87
88
89
90 iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
91}
92
93static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
94{
95 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
96 int ret;
97
98 trans_pcie->fw_reset_done = false;
99
100 if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
101 iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER,
102 UREG_NIC_SET_NMI_DRIVER_RESET_HANDSHAKE);
103 else
104 iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
105 UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
106
107
108 ret = wait_event_timeout(trans_pcie->fw_reset_waitq,
109 trans_pcie->fw_reset_done, FW_RESET_TIMEOUT);
110 if (!ret)
111 IWL_ERR(trans,
112 "firmware didn't ACK the reset - continue anyway\n");
113}
114
115void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
116{
117 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
118
119 lockdep_assert_held(&trans_pcie->mutex);
120
121 if (trans_pcie->is_down)
122 return;
123
124 if (trans_pcie->fw_reset_handshake &&
125 trans->state >= IWL_TRANS_FW_STARTED)
126 iwl_trans_pcie_fw_reset_handshake(trans);
127
128 trans_pcie->is_down = true;
129
130
131 iwl_disable_interrupts(trans);
132
133
134 iwl_pcie_disable_ict(trans);
135
136
137
138
139
140
141
142
143 if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
144 IWL_DEBUG_INFO(trans,
145 "DEVICE_ENABLED bit was set and is now cleared\n");
146 iwl_txq_gen2_tx_stop(trans);
147 iwl_pcie_rx_stop(trans);
148 }
149
150 iwl_pcie_ctxt_info_free_paging(trans);
151 if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
152 iwl_pcie_ctxt_info_gen3_free(trans);
153 else
154 iwl_pcie_ctxt_info_free(trans);
155
156
157 iwl_clear_bit(trans, CSR_GP_CNTRL,
158 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
159
160
161 iwl_pcie_gen2_apm_stop(trans, false);
162
163 iwl_trans_sw_reset(trans);
164
165
166
167
168
169
170
171
172 iwl_pcie_conf_msix_hw(trans_pcie);
173
174
175
176
177
178
179
180
181 iwl_disable_interrupts(trans);
182
183
184 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
185 clear_bit(STATUS_INT_ENABLED, &trans->status);
186 clear_bit(STATUS_TPOWER_PMI, &trans->status);
187
188
189
190
191
192 iwl_enable_rfkill_int(trans);
193
194
195 iwl_pcie_prepare_card_hw(trans);
196}
197
198void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
199{
200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
201 bool was_in_rfkill;
202
203 iwl_op_mode_time_point(trans->op_mode,
204 IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE,
205 NULL);
206
207 mutex_lock(&trans_pcie->mutex);
208 trans_pcie->opmode_down = true;
209 was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
210 _iwl_trans_pcie_gen2_stop_device(trans);
211 iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
212 mutex_unlock(&trans_pcie->mutex);
213}
214
215static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
216{
217 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
218 int queue_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
219 trans->cfg->min_txq_size);
220
221
222 spin_lock_bh(&trans_pcie->irq_lock);
223 iwl_pcie_gen2_apm_init(trans);
224 spin_unlock_bh(&trans_pcie->irq_lock);
225
226 iwl_op_mode_nic_config(trans->op_mode);
227
228
229 if (iwl_pcie_gen2_rx_init(trans))
230 return -ENOMEM;
231
232
233 if (iwl_txq_gen2_init(trans, trans->txqs.cmd.q_id, queue_size))
234 return -ENOMEM;
235
236
237 iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF);
238 IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n");
239
240 return 0;
241}
242
243void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
244{
245 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
246
247 iwl_pcie_reset_ict(trans);
248
249
250 memset(trans->txqs.queue_stopped, 0,
251 sizeof(trans->txqs.queue_stopped));
252 memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used));
253
254
255
256
257 iwl_pcie_ctxt_info_free(trans);
258
259
260
261
262
263 iwl_enable_interrupts(trans);
264 mutex_lock(&trans_pcie->mutex);
265 iwl_pcie_check_hw_rf_kill(trans);
266 mutex_unlock(&trans_pcie->mutex);
267}
268
269static void iwl_pcie_set_ltr(struct iwl_trans *trans)
270{
271 u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
272 u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
273 CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
274 u32_encode_bits(250,
275 CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
276 CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
277 u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
278 CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
279 u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
280
281
282
283
284
285
286 if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
287 trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
288 !trans->trans_cfg->integrated) {
289 iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
290 } else if (trans->trans_cfg->integrated &&
291 trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
292 iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
293 iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
294 }
295}
296
297int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
298 const struct fw_img *fw, bool run_in_rfkill)
299{
300 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
301 bool hw_rfkill;
302 int ret;
303
304
305 if (iwl_pcie_prepare_card_hw(trans)) {
306 IWL_WARN(trans, "Exit HW not ready\n");
307 ret = -EIO;
308 goto out;
309 }
310
311 iwl_enable_rfkill_int(trans);
312
313 iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
314
315
316
317
318
319
320 iwl_disable_interrupts(trans);
321
322
323 iwl_pcie_synchronize_irqs(trans);
324
325 mutex_lock(&trans_pcie->mutex);
326
327
328 hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
329 if (hw_rfkill && !run_in_rfkill) {
330 ret = -ERFKILL;
331 goto out;
332 }
333
334
335 if (trans_pcie->is_down) {
336 IWL_WARN(trans,
337 "Can't start_fw since the HW hasn't been started\n");
338 ret = -EIO;
339 goto out;
340 }
341
342
343 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
344 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
345 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
346
347
348 iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
349
350 ret = iwl_pcie_gen2_nic_init(trans);
351 if (ret) {
352 IWL_ERR(trans, "Unable to init nic\n");
353 goto out;
354 }
355
356 if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
357 ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
358 else
359 ret = iwl_pcie_ctxt_info_init(trans, fw);
360 if (ret)
361 goto out;
362
363 iwl_pcie_set_ltr(trans);
364
365 if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
366 iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
367 else
368 iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
369
370
371 hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
372 if (hw_rfkill && !run_in_rfkill)
373 ret = -ERFKILL;
374
375out:
376 mutex_unlock(&trans_pcie->mutex);
377 return ret;
378}
379