1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2003-2014, 2018-2022, 2024 Intel Corporation
4 * Copyright (C) 2015-2016 Intel Deutschland GmbH
6 #include <linux/delay.h>
7 #include <linux/device.h>
8 #include <linux/export.h>
13 #include "iwl-debug.h"
17 void iwl_write8(struct iwl_trans
*trans
, u32 ofs
, u8 val
)
19 trace_iwlwifi_dev_iowrite8(trans
->dev
, ofs
, val
);
20 iwl_trans_write8(trans
, ofs
, val
);
22 IWL_EXPORT_SYMBOL(iwl_write8
);
24 void iwl_write32(struct iwl_trans
*trans
, u32 ofs
, u32 val
)
26 trace_iwlwifi_dev_iowrite32(trans
->dev
, ofs
, val
);
27 iwl_trans_write32(trans
, ofs
, val
);
29 IWL_EXPORT_SYMBOL(iwl_write32
);
31 void iwl_write64(struct iwl_trans
*trans
, u64 ofs
, u64 val
)
33 trace_iwlwifi_dev_iowrite64(trans
->dev
, ofs
, val
);
34 iwl_trans_write32(trans
, ofs
, lower_32_bits(val
));
35 iwl_trans_write32(trans
, ofs
+ 4, upper_32_bits(val
));
37 IWL_EXPORT_SYMBOL(iwl_write64
);
39 u32
iwl_read32(struct iwl_trans
*trans
, u32 ofs
)
41 u32 val
= iwl_trans_read32(trans
, ofs
);
43 trace_iwlwifi_dev_ioread32(trans
->dev
, ofs
, val
);
46 IWL_EXPORT_SYMBOL(iwl_read32
);
48 #define IWL_POLL_INTERVAL 10 /* microseconds */
50 int iwl_poll_bit(struct iwl_trans
*trans
, u32 addr
,
51 u32 bits
, u32 mask
, int timeout
)
56 if ((iwl_read32(trans
, addr
) & mask
) == (bits
& mask
))
58 udelay(IWL_POLL_INTERVAL
);
59 t
+= IWL_POLL_INTERVAL
;
60 } while (t
< timeout
);
64 IWL_EXPORT_SYMBOL(iwl_poll_bit
);
66 u32
iwl_read_direct32(struct iwl_trans
*trans
, u32 reg
)
68 if (iwl_trans_grab_nic_access(trans
)) {
69 u32 value
= iwl_read32(trans
, reg
);
71 iwl_trans_release_nic_access(trans
);
75 /* return as if we have a HW timeout/failure */
78 IWL_EXPORT_SYMBOL(iwl_read_direct32
);
80 void iwl_write_direct32(struct iwl_trans
*trans
, u32 reg
, u32 value
)
82 if (iwl_trans_grab_nic_access(trans
)) {
83 iwl_write32(trans
, reg
, value
);
84 iwl_trans_release_nic_access(trans
);
87 IWL_EXPORT_SYMBOL(iwl_write_direct32
);
89 void iwl_write_direct64(struct iwl_trans
*trans
, u64 reg
, u64 value
)
91 if (iwl_trans_grab_nic_access(trans
)) {
92 iwl_write64(trans
, reg
, value
);
93 iwl_trans_release_nic_access(trans
);
96 IWL_EXPORT_SYMBOL(iwl_write_direct64
);
98 int iwl_poll_direct_bit(struct iwl_trans
*trans
, u32 addr
, u32 mask
,
104 if ((iwl_read_direct32(trans
, addr
) & mask
) == mask
)
106 udelay(IWL_POLL_INTERVAL
);
107 t
+= IWL_POLL_INTERVAL
;
108 } while (t
< timeout
);
112 IWL_EXPORT_SYMBOL(iwl_poll_direct_bit
);
114 u32
iwl_read_prph_no_grab(struct iwl_trans
*trans
, u32 ofs
)
116 u32 val
= iwl_trans_read_prph(trans
, ofs
);
117 trace_iwlwifi_dev_ioread_prph32(trans
->dev
, ofs
, val
);
120 IWL_EXPORT_SYMBOL(iwl_read_prph_no_grab
);
122 void iwl_write_prph_no_grab(struct iwl_trans
*trans
, u32 ofs
, u32 val
)
124 trace_iwlwifi_dev_iowrite_prph32(trans
->dev
, ofs
, val
);
125 iwl_trans_write_prph(trans
, ofs
, val
);
127 IWL_EXPORT_SYMBOL(iwl_write_prph_no_grab
);
129 void iwl_write_prph64_no_grab(struct iwl_trans
*trans
, u64 ofs
, u64 val
)
131 trace_iwlwifi_dev_iowrite_prph64(trans
->dev
, ofs
, val
);
132 iwl_write_prph_no_grab(trans
, ofs
, val
& 0xffffffff);
133 iwl_write_prph_no_grab(trans
, ofs
+ 4, val
>> 32);
135 IWL_EXPORT_SYMBOL(iwl_write_prph64_no_grab
);
137 u32
iwl_read_prph(struct iwl_trans
*trans
, u32 ofs
)
139 if (iwl_trans_grab_nic_access(trans
)) {
140 u32 val
= iwl_read_prph_no_grab(trans
, ofs
);
142 iwl_trans_release_nic_access(trans
);
147 /* return as if we have a HW timeout/failure */
150 IWL_EXPORT_SYMBOL(iwl_read_prph
);
152 void iwl_write_prph_delay(struct iwl_trans
*trans
, u32 ofs
, u32 val
, u32 delay_ms
)
154 if (iwl_trans_grab_nic_access(trans
)) {
156 iwl_write_prph_no_grab(trans
, ofs
, val
);
157 iwl_trans_release_nic_access(trans
);
160 IWL_EXPORT_SYMBOL(iwl_write_prph_delay
);
162 int iwl_poll_prph_bit(struct iwl_trans
*trans
, u32 addr
,
163 u32 bits
, u32 mask
, int timeout
)
168 if ((iwl_read_prph(trans
, addr
) & mask
) == (bits
& mask
))
170 udelay(IWL_POLL_INTERVAL
);
171 t
+= IWL_POLL_INTERVAL
;
172 } while (t
< timeout
);
177 void iwl_set_bits_prph(struct iwl_trans
*trans
, u32 ofs
, u32 mask
)
179 if (iwl_trans_grab_nic_access(trans
)) {
180 iwl_write_prph_no_grab(trans
, ofs
,
181 iwl_read_prph_no_grab(trans
, ofs
) |
183 iwl_trans_release_nic_access(trans
);
186 IWL_EXPORT_SYMBOL(iwl_set_bits_prph
);
188 void iwl_set_bits_mask_prph(struct iwl_trans
*trans
, u32 ofs
,
191 if (iwl_trans_grab_nic_access(trans
)) {
192 iwl_write_prph_no_grab(trans
, ofs
,
193 (iwl_read_prph_no_grab(trans
, ofs
) &
195 iwl_trans_release_nic_access(trans
);
198 IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph
);
200 void iwl_clear_bits_prph(struct iwl_trans
*trans
, u32 ofs
, u32 mask
)
204 if (iwl_trans_grab_nic_access(trans
)) {
205 val
= iwl_read_prph_no_grab(trans
, ofs
);
206 iwl_write_prph_no_grab(trans
, ofs
, (val
& ~mask
));
207 iwl_trans_release_nic_access(trans
);
210 IWL_EXPORT_SYMBOL(iwl_clear_bits_prph
);
212 void iwl_force_nmi(struct iwl_trans
*trans
)
214 if (trans
->trans_cfg
->device_family
< IWL_DEVICE_FAMILY_9000
)
215 iwl_write_prph_delay(trans
, DEVICE_SET_NMI_REG
,
216 DEVICE_SET_NMI_VAL_DRV
, 1);
217 else if (trans
->trans_cfg
->device_family
< IWL_DEVICE_FAMILY_AX210
)
218 iwl_write_umac_prph(trans
, UREG_NIC_SET_NMI_DRIVER
,
219 UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER
);
220 else if (trans
->trans_cfg
->device_family
< IWL_DEVICE_FAMILY_BZ
)
221 iwl_write_umac_prph(trans
, UREG_DOORBELL_TO_ISR6
,
222 UREG_DOORBELL_TO_ISR6_NMI_BIT
);
224 iwl_write32(trans
, CSR_DOORBELL_VECTOR
,
225 UREG_DOORBELL_TO_ISR6_NMI_BIT
);
227 IWL_EXPORT_SYMBOL(iwl_force_nmi
);
229 static const char *get_rfh_string(int cmd
)
231 #define IWL_CMD(x) case x: return #x
232 #define IWL_CMD_MQ(arg, reg, q) { if (arg == reg(q)) return #reg; }
236 for (i
= 0; i
< IWL_MAX_RX_HW_QUEUES
; i
++) {
237 IWL_CMD_MQ(cmd
, RFH_Q_FRBDCB_BA_LSB
, i
);
238 IWL_CMD_MQ(cmd
, RFH_Q_FRBDCB_WIDX
, i
);
239 IWL_CMD_MQ(cmd
, RFH_Q_FRBDCB_RIDX
, i
);
240 IWL_CMD_MQ(cmd
, RFH_Q_URBD_STTS_WPTR_LSB
, i
);
244 IWL_CMD(RFH_RXF_DMA_CFG
);
245 IWL_CMD(RFH_GEN_CFG
);
246 IWL_CMD(RFH_GEN_STATUS
);
247 IWL_CMD(FH_TSSR_TX_STATUS_REG
);
248 IWL_CMD(FH_TSSR_TX_ERROR_REG
);
260 static int iwl_dump_rfh(struct iwl_trans
*trans
, char **buf
)
263 int num_q
= trans
->num_rx_queues
;
264 static const u32 rfh_tbl
[] = {
268 FH_TSSR_TX_STATUS_REG
,
269 FH_TSSR_TX_ERROR_REG
,
271 static const struct reg rfh_mq_tbl
[] = {
272 { RFH_Q0_FRBDCB_BA_LSB
, true },
273 { RFH_Q0_FRBDCB_WIDX
, false },
274 { RFH_Q0_FRBDCB_RIDX
, false },
275 { RFH_Q0_URBD_STTS_WPTR_LSB
, true },
278 #ifdef CONFIG_IWLWIFI_DEBUGFS
282 * Register (up to 34 for name + 8 blank/q for MQ): 40 chars
283 * Colon + space: 2 characters
284 * 0X%08x: 10 characters
285 * New line: 1 character
286 * Total of 53 characters
288 size_t bufsz
= ARRAY_SIZE(rfh_tbl
) * 53 +
289 ARRAY_SIZE(rfh_mq_tbl
) * 53 * num_q
+ 40;
291 *buf
= kmalloc(bufsz
, GFP_KERNEL
);
295 pos
+= scnprintf(*buf
+ pos
, bufsz
- pos
,
296 "RFH register values:\n");
298 for (i
= 0; i
< ARRAY_SIZE(rfh_tbl
); i
++)
299 pos
+= scnprintf(*buf
+ pos
, bufsz
- pos
,
301 get_rfh_string(rfh_tbl
[i
]),
302 iwl_read_prph(trans
, rfh_tbl
[i
]));
304 for (i
= 0; i
< ARRAY_SIZE(rfh_mq_tbl
); i
++)
305 for (q
= 0; q
< num_q
; q
++) {
306 u32 addr
= rfh_mq_tbl
[i
].addr
;
308 addr
+= q
* (rfh_mq_tbl
[i
].is64
? 8 : 4);
309 pos
+= scnprintf(*buf
+ pos
, bufsz
- pos
,
310 "%34s(q %2d): 0X%08x\n",
311 get_rfh_string(addr
), q
,
312 iwl_read_prph(trans
, addr
));
319 IWL_ERR(trans
, "RFH register values:\n");
320 for (i
= 0; i
< ARRAY_SIZE(rfh_tbl
); i
++)
321 IWL_ERR(trans
, " %34s: 0X%08x\n",
322 get_rfh_string(rfh_tbl
[i
]),
323 iwl_read_prph(trans
, rfh_tbl
[i
]));
325 for (i
= 0; i
< ARRAY_SIZE(rfh_mq_tbl
); i
++)
326 for (q
= 0; q
< num_q
; q
++) {
327 u32 addr
= rfh_mq_tbl
[i
].addr
;
329 addr
+= q
* (rfh_mq_tbl
[i
].is64
? 8 : 4);
330 IWL_ERR(trans
, " %34s(q %d): 0X%08x\n",
331 get_rfh_string(addr
), q
,
332 iwl_read_prph(trans
, addr
));
338 static const char *get_fh_string(int cmd
)
341 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG
);
342 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG
);
343 IWL_CMD(FH_RSCSR_CHNL0_WPTR
);
344 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG
);
345 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG
);
346 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG
);
347 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV
);
348 IWL_CMD(FH_TSSR_TX_STATUS_REG
);
349 IWL_CMD(FH_TSSR_TX_ERROR_REG
);
356 int iwl_dump_fh(struct iwl_trans
*trans
, char **buf
)
359 static const u32 fh_tbl
[] = {
360 FH_RSCSR_CHNL0_STTS_WPTR_REG
,
361 FH_RSCSR_CHNL0_RBDCB_BASE_REG
,
363 FH_MEM_RCSR_CHNL0_CONFIG_REG
,
364 FH_MEM_RSSR_SHARED_CTRL_REG
,
365 FH_MEM_RSSR_RX_STATUS_REG
,
366 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV
,
367 FH_TSSR_TX_STATUS_REG
,
371 if (trans
->trans_cfg
->mq_rx_supported
)
372 return iwl_dump_rfh(trans
, buf
);
374 #ifdef CONFIG_IWLWIFI_DEBUGFS
377 size_t bufsz
= ARRAY_SIZE(fh_tbl
) * 48 + 40;
379 *buf
= kmalloc(bufsz
, GFP_KERNEL
);
383 pos
+= scnprintf(*buf
+ pos
, bufsz
- pos
,
384 "FH register values:\n");
386 for (i
= 0; i
< ARRAY_SIZE(fh_tbl
); i
++)
387 pos
+= scnprintf(*buf
+ pos
, bufsz
- pos
,
389 get_fh_string(fh_tbl
[i
]),
390 iwl_read_direct32(trans
, fh_tbl
[i
]));
396 IWL_ERR(trans
, "FH register values:\n");
397 for (i
= 0; i
< ARRAY_SIZE(fh_tbl
); i
++)
398 IWL_ERR(trans
, " %34s: 0X%08x\n",
399 get_fh_string(fh_tbl
[i
]),
400 iwl_read_direct32(trans
, fh_tbl
[i
]));
405 #define IWL_HOST_MON_BLOCK_PEMON 0x00
406 #define IWL_HOST_MON_BLOCK_HIPM 0x22
408 #define IWL_HOST_MON_BLOCK_PEMON_VEC0 0x00
409 #define IWL_HOST_MON_BLOCK_PEMON_VEC1 0x01
410 #define IWL_HOST_MON_BLOCK_PEMON_WFPM 0x06
412 static void iwl_dump_host_monitor_block(struct iwl_trans
*trans
,
413 u32 block
, u32 vec
, u32 iter
)
417 IWL_ERR(trans
, "Host monitor block 0x%x vector 0x%x\n", block
, vec
);
418 iwl_write32(trans
, CSR_MONITOR_CFG_REG
, (block
<< 8) | vec
);
419 for (i
= 0; i
< iter
; i
++)
420 IWL_ERR(trans
, " value [iter %d]: 0x%08x\n",
421 i
, iwl_read32(trans
, CSR_MONITOR_STATUS_REG
));
424 static void iwl_dump_host_monitor(struct iwl_trans
*trans
)
426 switch (trans
->trans_cfg
->device_family
) {
427 case IWL_DEVICE_FAMILY_22000
:
428 case IWL_DEVICE_FAMILY_AX210
:
429 IWL_ERR(trans
, "CSR_RESET = 0x%x\n",
430 iwl_read32(trans
, CSR_RESET
));
431 iwl_dump_host_monitor_block(trans
, IWL_HOST_MON_BLOCK_PEMON
,
432 IWL_HOST_MON_BLOCK_PEMON_VEC0
, 15);
433 iwl_dump_host_monitor_block(trans
, IWL_HOST_MON_BLOCK_PEMON
,
434 IWL_HOST_MON_BLOCK_PEMON_VEC1
, 15);
435 iwl_dump_host_monitor_block(trans
, IWL_HOST_MON_BLOCK_PEMON
,
436 IWL_HOST_MON_BLOCK_PEMON_WFPM
, 15);
437 iwl_dump_host_monitor_block(trans
, IWL_HOST_MON_BLOCK_HIPM
,
438 IWL_HOST_MON_BLOCK_PEMON_VEC0
, 1);
441 /* not supported yet */
446 int iwl_finish_nic_init(struct iwl_trans
*trans
)
448 const struct iwl_cfg_trans_params
*cfg_trans
= trans
->trans_cfg
;
452 if (cfg_trans
->bisr_workaround
) {
453 /* ensure the TOP FSM isn't still in previous reset */
458 * Set "initialization complete" bit to move adapter from
459 * D0U* --> D0A* (powered-up active) state.
461 if (cfg_trans
->device_family
>= IWL_DEVICE_FAMILY_BZ
) {
462 iwl_set_bit(trans
, CSR_GP_CNTRL
,
463 CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ
|
464 CSR_GP_CNTRL_REG_FLAG_MAC_INIT
);
465 poll_ready
= CSR_GP_CNTRL_REG_FLAG_MAC_STATUS
;
467 iwl_set_bit(trans
, CSR_GP_CNTRL
,
468 CSR_GP_CNTRL_REG_FLAG_INIT_DONE
);
469 poll_ready
= CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
;
472 if (cfg_trans
->device_family
== IWL_DEVICE_FAMILY_8000
)
476 * Wait for clock stabilization; once stabilized, access to
477 * device-internal resources is supported, e.g. iwl_write_prph()
478 * and accesses to uCode SRAM.
480 err
= iwl_poll_bit(trans
, CSR_GP_CNTRL
, poll_ready
, poll_ready
, 25000);
482 IWL_DEBUG_INFO(trans
, "Failed to wake NIC\n");
484 iwl_dump_host_monitor(trans
);
487 if (cfg_trans
->bisr_workaround
) {
488 /* ensure BISR shift has finished */
492 return err
< 0 ? err
: 0;
494 IWL_EXPORT_SYMBOL(iwl_finish_nic_init
);
496 void iwl_trans_sync_nmi_with_addr(struct iwl_trans
*trans
, u32 inta_addr
,
499 unsigned long timeout
= jiffies
+ IWL_TRANS_NMI_TIMEOUT
;
500 bool interrupts_enabled
= test_bit(STATUS_INT_ENABLED
, &trans
->status
);
502 /* if the interrupts were already disabled, there is no point in
503 * calling iwl_disable_interrupts
505 if (interrupts_enabled
)
506 iwl_trans_interrupts(trans
, false);
508 iwl_force_nmi(trans
);
509 while (time_after(timeout
, jiffies
)) {
510 u32 inta_hw
= iwl_read32(trans
, inta_addr
);
512 /* Error detected by uCode */
513 if (inta_hw
& sw_err_bit
) {
514 /* Clear causes register */
515 iwl_write32(trans
, inta_addr
, inta_hw
& sw_err_bit
);
522 /* enable interrupts only if there were already enabled before this
523 * function to avoid a case were the driver enable interrupts before
524 * proper configurations were made
526 if (interrupts_enabled
)
527 iwl_trans_interrupts(trans
, true);
529 iwl_trans_fw_error(trans
, false);