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>
15 static struct dentry
*qedf_dbg_root
;
18 * qedf_dbg_host_init - setup the debugfs file for the pf
19 * @pf: the pf that is starting up
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
47 * @pf: the pf that is stopping
50 qedf_dbg_host_exit(struct qedf_dbg_ctx
*qedf_dbg
)
52 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Destroying debugfs host "
54 /* remove debugfs entries of this PF */
55 debugfs_remove_recursive(qedf_dbg
->bdf_dentry
);
56 qedf_dbg
->bdf_dentry
= NULL
;
60 * qedf_dbg_init - start up debugfs for the driver
63 qedf_dbg_init(char *drv_name
)
65 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Creating debugfs root node\n");
67 /* create qed dir in root of debugfs. NULL means debugfs root */
68 qedf_dbg_root
= debugfs_create_dir(drv_name
, NULL
);
72 * qedf_dbg_exit - clean out the driver's debugfs entries
77 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Destroying debugfs root "
80 /* remove qed dir in root of debugfs */
81 debugfs_remove_recursive(qedf_dbg_root
);
85 const struct qedf_debugfs_ops qedf_debugfs_ops
[] = {
89 { "stop_io_on_error", NULL
},
90 { "driver_stats", NULL
},
91 { "clear_stats", NULL
},
92 { "offload_stats", NULL
},
93 /* This must be last */
97 DECLARE_PER_CPU(struct qedf_percpu_iothread_s
, qedf_percpu_iothreads
);
100 qedf_dbg_fp_int_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
105 struct qedf_fastpath
*fp
= NULL
;
106 struct qedf_dbg_ctx
*qedf_dbg
=
107 (struct qedf_dbg_ctx
*)filp
->private_data
;
108 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
109 struct qedf_ctx
, dbg_ctx
);
111 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
113 cnt
= sprintf(buffer
, "\nFastpath I/O completions\n\n");
115 for (id
= 0; id
< qedf
->num_queues
; id
++) {
116 fp
= &(qedf
->fp_array
[id
]);
117 if (fp
->sb_id
== QEDF_SB_ID_NULL
)
119 cnt
+= sprintf((buffer
+ cnt
), "#%d: %lu\n", id
,
123 cnt
= min_t(int, count
, cnt
- *ppos
);
129 qedf_dbg_fp_int_cmd_write(struct file
*filp
, const char __user
*buffer
,
130 size_t count
, loff_t
*ppos
)
139 qedf_dbg_debug_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
143 struct qedf_dbg_ctx
*qedf_dbg
=
144 (struct qedf_dbg_ctx
*)filp
->private_data
;
146 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "debug mask=0x%x\n", qedf_debug
);
147 cnt
= sprintf(buffer
, "debug mask = 0x%x\n", qedf_debug
);
149 cnt
= min_t(int, count
, cnt
- *ppos
);
155 qedf_dbg_debug_cmd_write(struct file
*filp
, const char __user
*buffer
,
156 size_t count
, loff_t
*ppos
)
161 struct qedf_dbg_ctx
*qedf_dbg
=
162 (struct qedf_dbg_ctx
*)filp
->private_data
;
167 kern_buf
= memdup_user(buffer
, count
);
168 if (IS_ERR(kern_buf
))
169 return PTR_ERR(kern_buf
);
171 rval
= kstrtouint(kern_buf
, 10, &val
);
177 qedf_debug
= QEDF_DEFAULT_LOG_MASK
;
181 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Setting debug=0x%x.\n", val
);
186 qedf_dbg_stop_io_on_error_cmd_read(struct file
*filp
, char __user
*buffer
,
187 size_t count
, loff_t
*ppos
)
190 struct qedf_dbg_ctx
*qedf_dbg
=
191 (struct qedf_dbg_ctx
*)filp
->private_data
;
192 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
193 struct qedf_ctx
, dbg_ctx
);
195 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
196 cnt
= sprintf(buffer
, "%s\n",
197 qedf
->stop_io_on_error
? "true" : "false");
199 cnt
= min_t(int, count
, cnt
- *ppos
);
205 qedf_dbg_stop_io_on_error_cmd_write(struct file
*filp
,
206 const char __user
*buffer
, size_t count
,
210 struct qedf_dbg_ctx
*qedf_dbg
=
211 (struct qedf_dbg_ctx
*)filp
->private_data
;
212 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
215 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
220 kern_buf
= memdup_user(buffer
, 6);
221 if (IS_ERR(kern_buf
))
222 return PTR_ERR(kern_buf
);
224 if (strncmp(kern_buf
, "false", 5) == 0)
225 qedf
->stop_io_on_error
= false;
226 else if (strncmp(kern_buf
, "true", 4) == 0)
227 qedf
->stop_io_on_error
= true;
228 else if (strncmp(kern_buf
, "now", 3) == 0)
229 /* Trigger from user to stop all I/O on this host */
230 set_bit(QEDF_DBG_STOP_IO
, &qedf
->flags
);
237 qedf_io_trace_show(struct seq_file
*s
, void *unused
)
240 struct qedf_ctx
*qedf
= s
->private;
241 struct qedf_dbg_ctx
*qedf_dbg
= &qedf
->dbg_ctx
;
242 struct qedf_io_log
*io_log
;
245 if (!qedf_io_tracing
) {
246 seq_puts(s
, "I/O tracing not enabled.\n");
250 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
252 spin_lock_irqsave(&qedf
->io_trace_lock
, flags
);
253 idx
= qedf
->io_trace_idx
;
254 for (i
= 0; i
< QEDF_IO_TRACE_SIZE
; i
++) {
255 io_log
= &qedf
->io_trace_buf
[idx
];
256 seq_printf(s
, "%d:", io_log
->direction
);
257 seq_printf(s
, "0x%x:", io_log
->task_id
);
258 seq_printf(s
, "0x%06x:", io_log
->port_id
);
259 seq_printf(s
, "%d:", io_log
->lun
);
260 seq_printf(s
, "0x%02x:", io_log
->op
);
261 seq_printf(s
, "0x%02x%02x%02x%02x:", io_log
->lba
[0],
262 io_log
->lba
[1], io_log
->lba
[2], io_log
->lba
[3]);
263 seq_printf(s
, "%d:", io_log
->bufflen
);
264 seq_printf(s
, "%d:", io_log
->sg_count
);
265 seq_printf(s
, "0x%08x:", io_log
->result
);
266 seq_printf(s
, "%lu:", io_log
->jiffies
);
267 seq_printf(s
, "%d:", io_log
->refcount
);
268 seq_printf(s
, "%d:", io_log
->req_cpu
);
269 seq_printf(s
, "%d:", io_log
->int_cpu
);
270 seq_printf(s
, "%d:", io_log
->rsp_cpu
);
271 seq_printf(s
, "%d\n", io_log
->sge_type
);
274 if (idx
== QEDF_IO_TRACE_SIZE
)
277 spin_unlock_irqrestore(&qedf
->io_trace_lock
, flags
);
284 qedf_dbg_io_trace_open(struct inode
*inode
, struct file
*file
)
286 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
287 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
288 struct qedf_ctx
, dbg_ctx
);
290 return single_open(file
, qedf_io_trace_show
, qedf
);
293 /* Based on fip_state enum from libfcoe.h */
294 static char *fip_state_names
[] = {
301 "FIP_ST_VNMP_PROBE1",
302 "FIP_ST_VNMP_PROBE2",
307 /* Based on fc_rport_state enum from libfc.h */
308 static char *fc_rport_state_names
[] = {
311 "RPORT_ST_PLOGI_WAIT",
321 qedf_driver_stats_show(struct seq_file
*s
, void *unused
)
323 struct qedf_ctx
*qedf
= s
->private;
324 struct qedf_rport
*fcport
;
325 struct fc_rport_priv
*rdata
;
327 seq_printf(s
, "Host WWNN/WWPN: %016llx/%016llx\n",
328 qedf
->wwnn
, qedf
->wwpn
);
329 seq_printf(s
, "Host NPortID: %06x\n", qedf
->lport
->port_id
);
330 seq_printf(s
, "Link State: %s\n", atomic_read(&qedf
->link_state
) ?
332 seq_printf(s
, "Logical Link State: %s\n", qedf
->lport
->link_up
?
334 seq_printf(s
, "FIP state: %s\n", fip_state_names
[qedf
->ctlr
.state
]);
335 seq_printf(s
, "FIP VLAN ID: %d\n", qedf
->vlan_id
& 0xfff);
336 seq_printf(s
, "FIP 802.1Q Priority: %d\n", qedf
->prio
);
337 if (qedf
->ctlr
.sel_fcf
) {
338 seq_printf(s
, "FCF WWPN: %016llx\n",
339 qedf
->ctlr
.sel_fcf
->switch_name
);
340 seq_printf(s
, "FCF MAC: %pM\n", qedf
->ctlr
.sel_fcf
->fcf_mac
);
342 seq_puts(s
, "FCF not selected\n");
345 seq_puts(s
, "\nSGE stats:\n\n");
346 seq_printf(s
, "cmg_mgr free io_reqs: %d\n",
347 atomic_read(&qedf
->cmd_mgr
->free_list_cnt
));
348 seq_printf(s
, "slow SGEs: %d\n", qedf
->slow_sge_ios
);
349 seq_printf(s
, "fast SGEs: %d\n\n", qedf
->fast_sge_ios
);
351 seq_puts(s
, "Offloaded ports:\n\n");
354 list_for_each_entry_rcu(fcport
, &qedf
->fcports
, peers
) {
355 rdata
= fcport
->rdata
;
358 seq_printf(s
, "%016llx/%016llx/%06x: state=%s, free_sqes=%d, num_active_ios=%d\n",
359 rdata
->rport
->node_name
, rdata
->rport
->port_name
,
361 fc_rport_state_names
[rdata
->rp_state
],
362 atomic_read(&fcport
->free_sqes
),
363 atomic_read(&fcport
->num_active_ios
));
371 qedf_dbg_driver_stats_open(struct inode
*inode
, struct file
*file
)
373 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
374 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
375 struct qedf_ctx
, dbg_ctx
);
377 return single_open(file
, qedf_driver_stats_show
, qedf
);
381 qedf_dbg_clear_stats_cmd_read(struct file
*filp
, char __user
*buffer
,
382 size_t count
, loff_t
*ppos
)
386 /* Essentially a read stub */
387 cnt
= min_t(int, count
, cnt
- *ppos
);
393 qedf_dbg_clear_stats_cmd_write(struct file
*filp
,
394 const char __user
*buffer
, size_t count
,
397 struct qedf_dbg_ctx
*qedf_dbg
=
398 (struct qedf_dbg_ctx
*)filp
->private_data
;
399 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
402 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Clearing stat counters.\n");
407 /* Clear stat counters exposed by 'stats' node */
408 qedf
->slow_sge_ios
= 0;
409 qedf
->fast_sge_ios
= 0;
415 qedf_offload_stats_show(struct seq_file
*s
, void *unused
)
417 struct qedf_ctx
*qedf
= s
->private;
418 struct qed_fcoe_stats
*fw_fcoe_stats
;
420 fw_fcoe_stats
= kmalloc(sizeof(struct qed_fcoe_stats
), GFP_KERNEL
);
421 if (!fw_fcoe_stats
) {
422 QEDF_ERR(&(qedf
->dbg_ctx
), "Could not allocate memory for "
427 /* Query firmware for offload stats */
428 qed_ops
->get_stats(qedf
->cdev
, fw_fcoe_stats
);
430 seq_printf(s
, "fcoe_rx_byte_cnt=%llu\n"
431 "fcoe_rx_data_pkt_cnt=%llu\n"
432 "fcoe_rx_xfer_pkt_cnt=%llu\n"
433 "fcoe_rx_other_pkt_cnt=%llu\n"
434 "fcoe_silent_drop_pkt_cmdq_full_cnt=%u\n"
435 "fcoe_silent_drop_pkt_crc_error_cnt=%u\n"
436 "fcoe_silent_drop_pkt_task_invalid_cnt=%u\n"
437 "fcoe_silent_drop_total_pkt_cnt=%u\n"
438 "fcoe_silent_drop_pkt_rq_full_cnt=%u\n"
439 "fcoe_tx_byte_cnt=%llu\n"
440 "fcoe_tx_data_pkt_cnt=%llu\n"
441 "fcoe_tx_xfer_pkt_cnt=%llu\n"
442 "fcoe_tx_other_pkt_cnt=%llu\n",
443 fw_fcoe_stats
->fcoe_rx_byte_cnt
,
444 fw_fcoe_stats
->fcoe_rx_data_pkt_cnt
,
445 fw_fcoe_stats
->fcoe_rx_xfer_pkt_cnt
,
446 fw_fcoe_stats
->fcoe_rx_other_pkt_cnt
,
447 fw_fcoe_stats
->fcoe_silent_drop_pkt_cmdq_full_cnt
,
448 fw_fcoe_stats
->fcoe_silent_drop_pkt_crc_error_cnt
,
449 fw_fcoe_stats
->fcoe_silent_drop_pkt_task_invalid_cnt
,
450 fw_fcoe_stats
->fcoe_silent_drop_total_pkt_cnt
,
451 fw_fcoe_stats
->fcoe_silent_drop_pkt_rq_full_cnt
,
452 fw_fcoe_stats
->fcoe_tx_byte_cnt
,
453 fw_fcoe_stats
->fcoe_tx_data_pkt_cnt
,
454 fw_fcoe_stats
->fcoe_tx_xfer_pkt_cnt
,
455 fw_fcoe_stats
->fcoe_tx_other_pkt_cnt
);
457 kfree(fw_fcoe_stats
);
463 qedf_dbg_offload_stats_open(struct inode
*inode
, struct file
*file
)
465 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
466 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
467 struct qedf_ctx
, dbg_ctx
);
469 return single_open(file
, qedf_offload_stats_show
, qedf
);
472 const struct file_operations qedf_dbg_fops
[] = {
473 qedf_dbg_fileops(qedf
, fp_int
),
474 qedf_dbg_fileops_seq(qedf
, io_trace
),
475 qedf_dbg_fileops(qedf
, debug
),
476 qedf_dbg_fileops(qedf
, stop_io_on_error
),
477 qedf_dbg_fileops_seq(qedf
, driver_stats
),
478 qedf_dbg_fileops(qedf
, clear_stats
),
479 qedf_dbg_fileops_seq(qedf
, offload_stats
),
480 /* This must be last */
484 #else /* CONFIG_DEBUG_FS */
485 void qedf_dbg_host_init(struct qedf_dbg_ctx
*);
486 void qedf_dbg_host_exit(struct qedf_dbg_ctx
*);
487 void qedf_dbg_init(char *);
488 void qedf_dbg_exit(void);
489 #endif /* CONFIG_DEBUG_FS */