1 // SPDX-License-Identifier: GPL-2.0-only
3 * QLogic FCoE Offload Driver
4 * Copyright (c) 2016-2018 QLogic Corporation
8 #include <linux/uaccess.h>
9 #include <linux/debugfs.h>
10 #include <linux/module.h>
11 #include <linux/vmalloc.h>
16 static struct dentry
*qedf_dbg_root
;
19 * qedf_dbg_host_init - setup the debugfs file for the pf
22 qedf_dbg_host_init(struct qedf_dbg_ctx
*qedf
,
23 const struct qedf_debugfs_ops
*dops
,
24 const struct file_operations
*fops
)
26 char host_dirname
[32];
28 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
, "Creating debugfs host node\n");
30 sprintf(host_dirname
, "host%u", qedf
->host_no
);
31 qedf
->bdf_dentry
= debugfs_create_dir(host_dirname
, qedf_dbg_root
);
33 /* create debugfs files */
38 debugfs_create_file(dops
->name
, 0600, qedf
->bdf_dentry
, qedf
,
46 * qedf_dbg_host_exit - clear out the pf's debugfs entries
49 qedf_dbg_host_exit(struct qedf_dbg_ctx
*qedf_dbg
)
51 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Destroying debugfs host "
53 /* remove debugfs entries of this PF */
54 debugfs_remove_recursive(qedf_dbg
->bdf_dentry
);
55 qedf_dbg
->bdf_dentry
= NULL
;
59 * qedf_dbg_init - start up debugfs for the driver
62 qedf_dbg_init(char *drv_name
)
64 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Creating debugfs root node\n");
66 /* create qed dir in root of debugfs. NULL means debugfs root */
67 qedf_dbg_root
= debugfs_create_dir(drv_name
, NULL
);
71 * qedf_dbg_exit - clean out the driver's debugfs entries
76 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Destroying debugfs root "
79 /* remove qed dir in root of debugfs */
80 debugfs_remove_recursive(qedf_dbg_root
);
84 const struct qedf_debugfs_ops qedf_debugfs_ops
[] = {
88 { "stop_io_on_error", NULL
},
89 { "driver_stats", NULL
},
90 { "clear_stats", NULL
},
91 { "offload_stats", NULL
},
92 /* This must be last */
96 DECLARE_PER_CPU(struct qedf_percpu_iothread_s
, qedf_percpu_iothreads
);
99 qedf_dbg_fp_int_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
106 struct qedf_fastpath
*fp
= NULL
;
107 struct qedf_dbg_ctx
*qedf_dbg
=
108 (struct qedf_dbg_ctx
*)filp
->private_data
;
109 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
110 struct qedf_ctx
, dbg_ctx
);
112 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
114 cbuf
= vmalloc(QEDF_DEBUGFS_LOG_LEN
);
118 cnt
+= scnprintf(cbuf
+ cnt
, QEDF_DEBUGFS_LOG_LEN
- cnt
, "\nFastpath I/O completions\n\n");
120 for (id
= 0; id
< qedf
->num_queues
; id
++) {
121 fp
= &(qedf
->fp_array
[id
]);
122 if (fp
->sb_id
== QEDF_SB_ID_NULL
)
124 cnt
+= scnprintf(cbuf
+ cnt
, QEDF_DEBUGFS_LOG_LEN
- cnt
,
125 "#%d: %lu\n", id
, fp
->completions
);
128 ret
= simple_read_from_buffer(buffer
, count
, ppos
, cbuf
, cnt
);
136 qedf_dbg_fp_int_cmd_write(struct file
*filp
, const char __user
*buffer
,
137 size_t count
, loff_t
*ppos
)
146 qedf_dbg_debug_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
151 struct qedf_dbg_ctx
*qedf_dbg
=
152 (struct qedf_dbg_ctx
*)filp
->private_data
;
154 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "debug mask=0x%x\n", qedf_debug
);
155 cnt
= scnprintf(cbuf
, sizeof(cbuf
), "debug mask = 0x%x\n", qedf_debug
);
157 return simple_read_from_buffer(buffer
, count
, ppos
, cbuf
, cnt
);
161 qedf_dbg_debug_cmd_write(struct file
*filp
, const char __user
*buffer
,
162 size_t count
, loff_t
*ppos
)
167 struct qedf_dbg_ctx
*qedf_dbg
=
168 (struct qedf_dbg_ctx
*)filp
->private_data
;
173 kern_buf
= memdup_user_nul(buffer
, count
);
174 if (IS_ERR(kern_buf
))
175 return PTR_ERR(kern_buf
);
177 rval
= kstrtouint(kern_buf
, 10, &val
);
183 qedf_debug
= QEDF_DEFAULT_LOG_MASK
;
187 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Setting debug=0x%x.\n", val
);
192 qedf_dbg_stop_io_on_error_cmd_read(struct file
*filp
, char __user
*buffer
,
193 size_t count
, loff_t
*ppos
)
197 struct qedf_dbg_ctx
*qedf_dbg
=
198 (struct qedf_dbg_ctx
*)filp
->private_data
;
199 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
200 struct qedf_ctx
, dbg_ctx
);
202 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
203 cnt
= scnprintf(cbuf
, sizeof(cbuf
), "%s\n",
204 qedf
->stop_io_on_error
? "true" : "false");
206 return simple_read_from_buffer(buffer
, count
, ppos
, cbuf
, cnt
);
210 qedf_dbg_stop_io_on_error_cmd_write(struct file
*filp
,
211 const char __user
*buffer
, size_t count
,
215 struct qedf_dbg_ctx
*qedf_dbg
=
216 (struct qedf_dbg_ctx
*)filp
->private_data
;
217 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
220 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
225 kern_buf
= memdup_user(buffer
, 6);
226 if (IS_ERR(kern_buf
))
227 return PTR_ERR(kern_buf
);
229 if (strncmp(kern_buf
, "false", 5) == 0)
230 qedf
->stop_io_on_error
= false;
231 else if (strncmp(kern_buf
, "true", 4) == 0)
232 qedf
->stop_io_on_error
= true;
233 else if (strncmp(kern_buf
, "now", 3) == 0)
234 /* Trigger from user to stop all I/O on this host */
235 set_bit(QEDF_DBG_STOP_IO
, &qedf
->flags
);
242 qedf_io_trace_show(struct seq_file
*s
, void *unused
)
245 struct qedf_ctx
*qedf
= s
->private;
246 struct qedf_dbg_ctx
*qedf_dbg
= &qedf
->dbg_ctx
;
247 struct qedf_io_log
*io_log
;
250 if (!qedf_io_tracing
) {
251 seq_puts(s
, "I/O tracing not enabled.\n");
255 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
257 spin_lock_irqsave(&qedf
->io_trace_lock
, flags
);
258 idx
= qedf
->io_trace_idx
;
259 for (i
= 0; i
< QEDF_IO_TRACE_SIZE
; i
++) {
260 io_log
= &qedf
->io_trace_buf
[idx
];
261 seq_printf(s
, "%d:", io_log
->direction
);
262 seq_printf(s
, "0x%x:", io_log
->task_id
);
263 seq_printf(s
, "0x%06x:", io_log
->port_id
);
264 seq_printf(s
, "%d:", io_log
->lun
);
265 seq_printf(s
, "0x%02x:", io_log
->op
);
266 seq_printf(s
, "0x%02x%02x%02x%02x:", io_log
->lba
[0],
267 io_log
->lba
[1], io_log
->lba
[2], io_log
->lba
[3]);
268 seq_printf(s
, "%d:", io_log
->bufflen
);
269 seq_printf(s
, "%d:", io_log
->sg_count
);
270 seq_printf(s
, "0x%08x:", io_log
->result
);
271 seq_printf(s
, "%lu:", io_log
->jiffies
);
272 seq_printf(s
, "%d:", io_log
->refcount
);
273 seq_printf(s
, "%d:", io_log
->req_cpu
);
274 seq_printf(s
, "%d:", io_log
->int_cpu
);
275 seq_printf(s
, "%d:", io_log
->rsp_cpu
);
276 seq_printf(s
, "%d\n", io_log
->sge_type
);
279 if (idx
== QEDF_IO_TRACE_SIZE
)
282 spin_unlock_irqrestore(&qedf
->io_trace_lock
, flags
);
289 qedf_dbg_io_trace_open(struct inode
*inode
, struct file
*file
)
291 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
292 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
293 struct qedf_ctx
, dbg_ctx
);
295 return single_open(file
, qedf_io_trace_show
, qedf
);
298 /* Based on fip_state enum from libfcoe.h */
299 static char *fip_state_names
[] = {
306 "FIP_ST_VNMP_PROBE1",
307 "FIP_ST_VNMP_PROBE2",
312 /* Based on fc_rport_state enum from libfc.h */
313 static char *fc_rport_state_names
[] = {
316 "RPORT_ST_PLOGI_WAIT",
326 qedf_driver_stats_show(struct seq_file
*s
, void *unused
)
328 struct qedf_ctx
*qedf
= s
->private;
329 struct qedf_rport
*fcport
;
330 struct fc_rport_priv
*rdata
;
332 seq_printf(s
, "Host WWNN/WWPN: %016llx/%016llx\n",
333 qedf
->wwnn
, qedf
->wwpn
);
334 seq_printf(s
, "Host NPortID: %06x\n", qedf
->lport
->port_id
);
335 seq_printf(s
, "Link State: %s\n", atomic_read(&qedf
->link_state
) ?
337 seq_printf(s
, "Logical Link State: %s\n", qedf
->lport
->link_up
?
339 seq_printf(s
, "FIP state: %s\n", fip_state_names
[qedf
->ctlr
.state
]);
340 seq_printf(s
, "FIP VLAN ID: %d\n", qedf
->vlan_id
& 0xfff);
341 seq_printf(s
, "FIP 802.1Q Priority: %d\n", qedf
->prio
);
342 if (qedf
->ctlr
.sel_fcf
) {
343 seq_printf(s
, "FCF WWPN: %016llx\n",
344 qedf
->ctlr
.sel_fcf
->switch_name
);
345 seq_printf(s
, "FCF MAC: %pM\n", qedf
->ctlr
.sel_fcf
->fcf_mac
);
347 seq_puts(s
, "FCF not selected\n");
350 seq_puts(s
, "\nSGE stats:\n\n");
351 seq_printf(s
, "cmg_mgr free io_reqs: %d\n",
352 atomic_read(&qedf
->cmd_mgr
->free_list_cnt
));
353 seq_printf(s
, "slow SGEs: %d\n", qedf
->slow_sge_ios
);
354 seq_printf(s
, "fast SGEs: %d\n\n", qedf
->fast_sge_ios
);
356 seq_puts(s
, "Offloaded ports:\n\n");
359 list_for_each_entry_rcu(fcport
, &qedf
->fcports
, peers
) {
360 rdata
= fcport
->rdata
;
363 seq_printf(s
, "%016llx/%016llx/%06x: state=%s, free_sqes=%d, num_active_ios=%d\n",
364 rdata
->rport
->node_name
, rdata
->rport
->port_name
,
366 fc_rport_state_names
[rdata
->rp_state
],
367 atomic_read(&fcport
->free_sqes
),
368 atomic_read(&fcport
->num_active_ios
));
376 qedf_dbg_driver_stats_open(struct inode
*inode
, struct file
*file
)
378 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
379 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
380 struct qedf_ctx
, dbg_ctx
);
382 return single_open(file
, qedf_driver_stats_show
, qedf
);
386 qedf_dbg_clear_stats_cmd_read(struct file
*filp
, char __user
*buffer
,
387 size_t count
, loff_t
*ppos
)
391 /* Essentially a read stub */
392 cnt
= min_t(int, count
, cnt
- *ppos
);
398 qedf_dbg_clear_stats_cmd_write(struct file
*filp
,
399 const char __user
*buffer
, size_t count
,
402 struct qedf_dbg_ctx
*qedf_dbg
=
403 (struct qedf_dbg_ctx
*)filp
->private_data
;
404 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
407 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Clearing stat counters.\n");
412 /* Clear stat counters exposed by 'stats' node */
413 qedf
->slow_sge_ios
= 0;
414 qedf
->fast_sge_ios
= 0;
420 qedf_offload_stats_show(struct seq_file
*s
, void *unused
)
422 struct qedf_ctx
*qedf
= s
->private;
423 struct qed_fcoe_stats
*fw_fcoe_stats
;
425 fw_fcoe_stats
= kmalloc(sizeof(struct qed_fcoe_stats
), GFP_KERNEL
);
426 if (!fw_fcoe_stats
) {
427 QEDF_ERR(&(qedf
->dbg_ctx
), "Could not allocate memory for "
432 /* Query firmware for offload stats */
433 qed_ops
->get_stats(qedf
->cdev
, fw_fcoe_stats
);
435 seq_printf(s
, "fcoe_rx_byte_cnt=%llu\n"
436 "fcoe_rx_data_pkt_cnt=%llu\n"
437 "fcoe_rx_xfer_pkt_cnt=%llu\n"
438 "fcoe_rx_other_pkt_cnt=%llu\n"
439 "fcoe_silent_drop_pkt_cmdq_full_cnt=%u\n"
440 "fcoe_silent_drop_pkt_crc_error_cnt=%u\n"
441 "fcoe_silent_drop_pkt_task_invalid_cnt=%u\n"
442 "fcoe_silent_drop_total_pkt_cnt=%u\n"
443 "fcoe_silent_drop_pkt_rq_full_cnt=%u\n"
444 "fcoe_tx_byte_cnt=%llu\n"
445 "fcoe_tx_data_pkt_cnt=%llu\n"
446 "fcoe_tx_xfer_pkt_cnt=%llu\n"
447 "fcoe_tx_other_pkt_cnt=%llu\n",
448 fw_fcoe_stats
->fcoe_rx_byte_cnt
,
449 fw_fcoe_stats
->fcoe_rx_data_pkt_cnt
,
450 fw_fcoe_stats
->fcoe_rx_xfer_pkt_cnt
,
451 fw_fcoe_stats
->fcoe_rx_other_pkt_cnt
,
452 fw_fcoe_stats
->fcoe_silent_drop_pkt_cmdq_full_cnt
,
453 fw_fcoe_stats
->fcoe_silent_drop_pkt_crc_error_cnt
,
454 fw_fcoe_stats
->fcoe_silent_drop_pkt_task_invalid_cnt
,
455 fw_fcoe_stats
->fcoe_silent_drop_total_pkt_cnt
,
456 fw_fcoe_stats
->fcoe_silent_drop_pkt_rq_full_cnt
,
457 fw_fcoe_stats
->fcoe_tx_byte_cnt
,
458 fw_fcoe_stats
->fcoe_tx_data_pkt_cnt
,
459 fw_fcoe_stats
->fcoe_tx_xfer_pkt_cnt
,
460 fw_fcoe_stats
->fcoe_tx_other_pkt_cnt
);
462 kfree(fw_fcoe_stats
);
468 qedf_dbg_offload_stats_open(struct inode
*inode
, struct file
*file
)
470 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
471 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
472 struct qedf_ctx
, dbg_ctx
);
474 return single_open(file
, qedf_offload_stats_show
, qedf
);
477 const struct file_operations qedf_dbg_fops
[] = {
478 qedf_dbg_fileops(qedf
, fp_int
),
479 qedf_dbg_fileops_seq(qedf
, io_trace
),
480 qedf_dbg_fileops(qedf
, debug
),
481 qedf_dbg_fileops(qedf
, stop_io_on_error
),
482 qedf_dbg_fileops_seq(qedf
, driver_stats
),
483 qedf_dbg_fileops(qedf
, clear_stats
),
484 qedf_dbg_fileops_seq(qedf
, offload_stats
),
485 /* This must be last */
489 #else /* CONFIG_DEBUG_FS */
490 void qedf_dbg_host_init(struct qedf_dbg_ctx
*);
491 void qedf_dbg_host_exit(struct qedf_dbg_ctx
*);
492 void qedf_dbg_init(char *);
493 void qedf_dbg_exit(void);
494 #endif /* CONFIG_DEBUG_FS */