ia64/linux-2.6.18-xen.hg

view drivers/net/sfc/debugfs.c @ 847:ad4d307bf9ce

net sfc: Update sfc and sfc_resource driver to latest release

...and update sfc_netfront, sfc_netback, sfc_netutil for any API changes

sfc_netback: Fix asymmetric use of SFC buffer table alloc and free
sfc_netback: Clean up if no SFC accel device found
sfc_netback: Gracefully handle case where page grant fails
sfc_netback: Disable net acceleration if the physical link goes down
sfc_netfront: Less verbose error messages, more verbose counters for
rx discard errors
sfc_netfront: Gracefully handle case where SFC netfront fails during
initialisation

Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:59:10 2009 +0100 (2009-03-31)
parents fc90e9b2c12b
children
line source
1 /****************************************************************************
2 * Driver for Solarflare network controllers
3 * (including support for SFE4001 10GBT NIC)
4 *
5 * Copyright 2005-2006: Fen Systems Ltd.
6 * Copyright 2006-2008: Solarflare Communications Inc,
7 * 9501 Jeronimo Road, Suite 250,
8 * Irvine, CA 92618, USA
9 *
10 * Initially developed by Michael Brown <mbrown@fensystems.co.uk>
11 * Maintained by Solarflare Communications <linux-net-drivers@solarflare.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License version 2 as published
15 * by the Free Software Foundation, incorporated herein by reference.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 ****************************************************************************
26 */
28 #include <linux/module.h>
29 #include <linux/pci.h>
30 #include <linux/proc_fs.h>
31 #include <linux/dcache.h>
32 #include <linux/seq_file.h>
33 #include "net_driver.h"
34 #include "efx.h"
35 #include "debugfs.h"
36 #include "falcon.h"
38 #ifndef PRIu64
39 # if (BITS_PER_LONG == 64)
40 # define PRIu64 "lu"
41 # else
42 # define PRIu64 "llu"
43 # endif
44 #endif
46 static void efx_debugfs_remove(struct proc_dir_entry *entry)
47 {
48 if (entry)
49 remove_proc_entry(entry->name, entry->parent);
50 }
51 #define debugfs_remove efx_debugfs_remove
53 #define debugfs_create_dir proc_mkdir
54 #define debugfs_create_symlink proc_symlink
57 /* Parameter definition bound to a structure - each file has one of these */
58 struct efx_debugfs_bound_param {
59 const struct efx_debugfs_parameter *param;
60 void *structure;
61 };
64 /* Maximum length for a name component or symlink target */
65 #define EFX_DEBUGFS_NAME_LEN 32
68 /* Top-level debug directory ([/sys/kernel]/debug/sfc) */
69 static struct dentry *efx_debug_root;
71 /* "cards" directory ([/sys/kernel]/debug/sfc/cards) */
72 static struct dentry *efx_debug_cards;
75 /* Sequential file interface to bound parameters */
77 static int efx_debugfs_seq_show(struct seq_file *file, void *v)
78 {
79 struct proc_dir_entry *entry = (struct proc_dir_entry *)file->private;
80 struct efx_debugfs_parameter *param =
81 (struct efx_debugfs_parameter *)entry->data;
82 void *structure = (void *)entry->read_proc;
84 if (!structure)
85 return -EIO;
87 return param->reader(file, structure + param->offset);
88 }
90 static int efx_debugfs_open(struct inode *inode, struct file *file)
91 {
92 return single_open(file, efx_debugfs_seq_show, PROC_I(inode)->pde);
93 }
96 static struct file_operations efx_debugfs_file_ops = {
97 .owner = THIS_MODULE,
98 .open = efx_debugfs_open,
99 .read = seq_read,
100 .llseek = seq_lseek,
101 .release = seq_release
102 };
105 void efx_fini_debugfs_child(struct proc_dir_entry *dir, const char *name)
106 {
107 remove_proc_entry(name, dir);
108 }
110 /*
111 * Remove a debugfs directory.
112 *
113 * This removes the named parameter-files and sym-links from the
114 * directory, and the directory itself. It does not do any recursion
115 * to subdirectories.
116 */
117 static void efx_fini_debugfs_dir(struct dentry *dir,
118 struct efx_debugfs_parameter *params,
119 const char *const *symlink_names)
120 {
121 if (!dir)
122 return;
124 while (params->name) {
125 efx_fini_debugfs_child(dir, params->name);
126 params++;
127 }
128 while (symlink_names && *symlink_names) {
129 efx_fini_debugfs_child(dir, *symlink_names);
130 symlink_names++;
131 }
132 debugfs_remove(dir);
133 }
135 /* Functions for printing various types of parameter. */
137 int efx_debugfs_read_uint(struct seq_file *file, void *data)
138 {
139 return seq_printf(file, "%#x\n", *(unsigned int *)data);
140 }
142 int efx_debugfs_read_int(struct seq_file *file, void *data)
143 {
144 return seq_printf(file, "%d\n", *(int *)data);
145 }
147 int efx_debugfs_read_atomic(struct seq_file *file, void *data)
148 {
149 unsigned int value = atomic_read((atomic_t *) data);
151 return seq_printf(file, "%#x\n", value);
152 }
154 int efx_debugfs_read_dword(struct seq_file *file, void *data)
155 {
156 unsigned int value = EFX_DWORD_FIELD(*(efx_dword_t *) data,
157 EFX_DWORD_0);
159 return seq_printf(file, "%#x\n", value);
160 }
162 static int efx_debugfs_read_int_mode(struct seq_file *file, void *data)
163 {
164 unsigned int value = *(enum efx_int_mode *) data;
166 return seq_printf(file, "%d => %s\n", value,
167 STRING_TABLE_LOOKUP(value, efx_interrupt_mode));
168 }
170 #define EFX_INT_MODE_PARAMETER(container_type, parameter) \
171 EFX_PARAMETER(container_type, parameter, \
172 enum efx_int_mode, efx_debugfs_read_int_mode)
174 static int efx_debugfs_read_loop_mode(struct seq_file *file, void *data)
175 {
176 unsigned int value = *(enum efx_loopback_mode *)data;
178 return seq_printf(file, "%d => %s\n", value,
179 STRING_TABLE_LOOKUP(value, efx_loopback_mode));
180 }
182 #define EFX_LOOPBACK_MODE_PARAMETER(container_type, parameter) \
183 EFX_PARAMETER(container_type, parameter, \
184 enum efx_loopback_mode, efx_debugfs_read_loop_mode)
186 static int efx_debugfs_read_phy_type(struct seq_file *file, void *data)
187 {
188 unsigned int value = *(enum phy_type *) data;
190 return seq_printf(file, "%d => %s\n", value,
191 STRING_TABLE_LOOKUP(value, efx_phy_type));
192 }
194 #define EFX_PHY_TYPE_PARAMETER(container_type, parameter) \
195 EFX_PARAMETER(container_type, parameter, \
196 enum phy_type, efx_debugfs_read_phy_type)
198 int efx_debugfs_read_string(struct seq_file *file, void *data)
199 {
200 return seq_puts(file, (const char *)data);
201 }
204 /**
205 * efx_init_debugfs_files - create parameter-files in a debugfs directory
206 * @parent: Containing directory
207 * @params: Pointer to zero-terminated parameter definition array
208 * @structure: Structure containing parameters
209 *
210 * Add parameter-files to the given debugfs directory. Return a
211 * negative error code or 0 on success.
212 */
213 static int efx_init_debugfs_files(struct dentry *parent,
214 struct efx_debugfs_parameter *params,
215 void *structure)
216 {
217 struct efx_debugfs_parameter *param = params;
219 while (param->name) {
220 struct dentry *entry;
221 entry = create_proc_entry(param->name, S_IRUGO, parent);
222 if (!entry)
223 goto err;
224 /*
225 * We have no good way to free a binding created here.
226 * However, once we install our file_operations the
227 * read_proc pointer becomes redundant and we can
228 * abuse it as a structure pointer.
229 */
230 entry->data = param;
231 entry->read_proc = NULL;
232 smp_wmb();
233 entry->proc_fops = &efx_debugfs_file_ops;
234 smp_wmb();
235 entry->read_proc = (read_proc_t *) structure;
237 param++;
238 }
240 return 0;
242 err:
243 while (param != params) {
244 param--;
245 efx_fini_debugfs_child(parent, param->name);
246 }
247 return -ENOMEM;
248 }
250 /**
251 * efx_init_debugfs_netdev - create debugfs sym-links for net device
252 * @net_dev: Net device
253 *
254 * Create sym-links named after @net_dev to the debugfs directories for
255 * the corresponding NIC and port. Return a negative error code or 0 on
256 * success. The sym-links must be cleaned up using
257 * efx_fini_debugfs_netdev().
258 */
259 int efx_init_debugfs_netdev(struct net_device *net_dev)
260 {
261 struct efx_nic *efx = net_dev->priv;
262 char name[EFX_DEBUGFS_NAME_LEN];
263 char target[EFX_DEBUGFS_NAME_LEN];
264 size_t len;
266 if (snprintf(name, sizeof(name), "nic_%s", net_dev->name) >=
267 sizeof(name))
268 return -ENAMETOOLONG;
269 if (snprintf(target, sizeof(target), "cards/%s", pci_name(efx->pci_dev))
270 >= sizeof(target))
271 return -ENAMETOOLONG;
272 efx->debug_symlink = debugfs_create_symlink(name,
273 efx_debug_root, target);
274 if (!efx->debug_symlink)
275 return -ENOMEM;
277 if (snprintf(name, sizeof(name), "if_%s", net_dev->name) >=
278 sizeof(name))
279 return -ENAMETOOLONG;
280 len = snprintf(target, sizeof(target),
281 "cards/%s/port0", pci_name(efx->pci_dev));
282 if (len >= sizeof(target))
283 return -ENAMETOOLONG;
284 efx->debug_port_symlink = debugfs_create_symlink(name,
285 efx_debug_root,
286 target);
287 if (!efx->debug_port_symlink)
288 return -ENOMEM;
290 return 0;
291 }
293 /**
294 * efx_fini_debugfs_netdev - remove debugfs sym-links for net device
295 * @net_dev: Net device
296 *
297 * Remove sym-links created for @net_dev by efx_init_debugfs_netdev().
298 */
299 void efx_fini_debugfs_netdev(struct net_device *net_dev)
300 {
301 struct efx_nic *efx = net_dev->priv;
303 debugfs_remove(efx->debug_port_symlink);
304 efx->debug_port_symlink = NULL;
305 debugfs_remove(efx->debug_symlink);
306 efx->debug_symlink = NULL;
307 }
309 /* Per-port parameters */
310 static struct efx_debugfs_parameter efx_debugfs_port_parameters[] = {
311 EFX_NAMED_PARAMETER(enabled, struct efx_nic, port_enabled,
312 int, efx_debugfs_read_int),
313 EFX_INT_PARAMETER(struct efx_nic, rx_checksum_enabled),
314 EFX_ATOMIC_PARAMETER(struct efx_nic, netif_stop_count),
315 EFX_INT_PARAMETER(struct efx_nic, link_up),
316 EFX_UINT_PARAMETER(struct efx_nic, link_options),
317 EFX_INT_PARAMETER(struct efx_nic, promiscuous),
318 EFX_UINT_PARAMETER(struct efx_nic, loopback_modes),
319 EFX_LOOPBACK_MODE_PARAMETER(struct efx_nic, loopback_mode),
320 EFX_PHY_TYPE_PARAMETER(struct efx_nic, phy_type),
321 EFX_NAMED_PARAMETER(phy_id, struct efx_nic, mii.phy_id,
322 int, efx_debugfs_read_int),
323 EFX_UINT_PARAMETER(struct efx_nic, n_link_state_changes),
324 {NULL},
325 };
327 /**
328 * efx_init_debugfs_port - create debugfs directory for port
329 * @efx: Efx NIC
330 *
331 * Create a debugfs directory containing parameter-files for @efx.
332 * Return a negative error code or 0 on success. The directory must be
333 * cleaned up using efx_fini_debugfs_port().
334 */
335 int efx_init_debugfs_port(struct efx_nic *efx)
336 {
337 int rc;
339 /* Create directory */
340 efx->debug_port_dir = debugfs_create_dir("port0", efx->debug_dir);
341 if (!efx->debug_port_dir)
342 return -ENOMEM;
344 /* Create files */
345 rc = efx_init_debugfs_files(efx->debug_port_dir,
346 efx_debugfs_port_parameters,
347 (void *)efx);
348 if (rc)
349 efx_fini_debugfs_port(efx);
351 return rc;
352 }
354 /**
355 * efx_fini_debugfs_port - remove debugfs directory for port
356 * @efx: Efx NIC
357 *
358 * Remove directory created for @efx by efx_init_debugfs_port().
359 */
360 void efx_fini_debugfs_port(struct efx_nic *efx)
361 {
362 efx_fini_debugfs_dir(efx->debug_port_dir,
363 efx_debugfs_port_parameters, NULL);
364 efx->debug_port_dir = NULL;
365 }
367 /**
368 * efx_extend_debugfs_port - add parameter-files to directory for port
369 * @efx: Efx NIC
370 * @structure: Structure containing parameters
371 * @params: Pointer to zero-terminated parameter definition array
372 *
373 * Add parameter-files to the debugfs directory for @efx. Return
374 * a negative error code or 0 on success. This is intended for
375 * PHY-specific parameters. The files must be cleaned up using
376 * efx_trim_debugfs_port().
377 */
378 int efx_extend_debugfs_port(struct efx_nic *efx,
379 void *structure,
380 struct efx_debugfs_parameter *params)
381 {
382 return efx_init_debugfs_files(efx->debug_port_dir, params, structure);
383 }
385 /**
386 * efx_trim_debugfs_port - remove parameter-files from directory for port
387 * @efx: Efx NIC
388 * @params: Pointer to zero-terminated parameter definition array
389 *
390 * Remove parameter-files previously added to the debugfs directory
391 * for @efx using efx_extend_debugfs_port().
392 */
393 void efx_trim_debugfs_port(struct efx_nic *efx,
394 struct efx_debugfs_parameter *params)
395 {
396 struct dentry *dir = efx->debug_port_dir;
398 if (dir) {
399 struct efx_debugfs_parameter *field;
400 for (field = params; field->name; field++)
401 efx_fini_debugfs_child(dir, field->name);
402 }
403 }
405 /* Per-TX-queue parameters */
406 static struct efx_debugfs_parameter efx_debugfs_tx_queue_parameters[] = {
407 EFX_UINT_PARAMETER(struct efx_tx_queue, insert_count),
408 EFX_UINT_PARAMETER(struct efx_tx_queue, write_count),
409 EFX_UINT_PARAMETER(struct efx_tx_queue, read_count),
410 EFX_INT_PARAMETER(struct efx_tx_queue, stopped),
411 {NULL},
412 };
414 static void efx_fini_debugfs_tx_queue(struct efx_tx_queue *tx_queue);
416 /**
417 * efx_init_debugfs_tx_queue - create debugfs directory for TX queue
418 * @tx_queue: Efx TX queue
419 *
420 * Create a debugfs directory containing parameter-files for @tx_queue.
421 * Return a negative error code or 0 on success. The directory must be
422 * cleaned up using efx_fini_debugfs_tx_queue().
423 */
424 static int efx_init_debugfs_tx_queue(struct efx_tx_queue *tx_queue)
425 {
426 char name[EFX_DEBUGFS_NAME_LEN];
427 char target[EFX_DEBUGFS_NAME_LEN];
428 int rc;
430 /* Create directory */
431 if (snprintf(name, sizeof(name), EFX_TX_QUEUE_NAME(tx_queue))
432 >= sizeof(name))
433 goto err_len;
434 tx_queue->debug_dir = debugfs_create_dir(name,
435 tx_queue->efx->debug_dir);
436 if (!tx_queue->debug_dir)
437 goto err_mem;
439 /* Create files */
440 rc = efx_init_debugfs_files(tx_queue->debug_dir,
441 efx_debugfs_tx_queue_parameters,
442 (void *)tx_queue);
443 if (rc)
444 goto err;
446 /* Create symlink to channel */
447 if (snprintf(target, sizeof(target),
448 "../" EFX_CHANNEL_NAME(tx_queue->channel)) >=
449 sizeof(target))
450 goto err_len;
451 if (!debugfs_create_symlink("channel", tx_queue->debug_dir, target))
452 goto err_mem;
454 /* Create symlink to port */
455 if (!debugfs_create_symlink("port", tx_queue->debug_dir, "../port0"))
456 goto err_mem;
458 return 0;
460 err_len:
461 rc = -ENAMETOOLONG;
462 goto err;
463 err_mem:
464 rc = -ENOMEM;
465 err:
466 efx_fini_debugfs_tx_queue(tx_queue);
467 return rc;
468 }
470 /**
471 * efx_fini_debugfs_tx_queue - remove debugfs directory for TX queue
472 * @tx_queue: Efx TX queue
473 *
474 * Remove directory created for @tx_queue by efx_init_debugfs_tx_queue().
475 */
476 static void efx_fini_debugfs_tx_queue(struct efx_tx_queue *tx_queue)
477 {
478 static const char *const symlink_names[] = {
479 "channel", "port", NULL
480 };
482 efx_fini_debugfs_dir(tx_queue->debug_dir,
483 efx_debugfs_tx_queue_parameters, symlink_names);
484 tx_queue->debug_dir = NULL;
485 }
487 /* Per-RX-queue parameters */
488 static struct efx_debugfs_parameter efx_debugfs_rx_queue_parameters[] = {
489 EFX_INT_PARAMETER(struct efx_rx_queue, added_count),
490 EFX_INT_PARAMETER(struct efx_rx_queue, removed_count),
491 EFX_UINT_PARAMETER(struct efx_rx_queue, max_fill),
492 EFX_UINT_PARAMETER(struct efx_rx_queue, fast_fill_trigger),
493 EFX_UINT_PARAMETER(struct efx_rx_queue, fast_fill_limit),
494 EFX_UINT_PARAMETER(struct efx_rx_queue, min_fill),
495 EFX_UINT_PARAMETER(struct efx_rx_queue, min_overfill),
496 EFX_UINT_PARAMETER(struct efx_rx_queue, alloc_page_count),
497 EFX_UINT_PARAMETER(struct efx_rx_queue, alloc_skb_count),
498 EFX_UINT_PARAMETER(struct efx_rx_queue, slow_fill_count),
499 {NULL},
500 };
502 static void efx_fini_debugfs_rx_queue(struct efx_rx_queue *rx_queue);
504 /**
505 * efx_init_debugfs_rx_queue - create debugfs directory for RX queue
506 * @rx_queue: Efx RX queue
507 *
508 * Create a debugfs directory containing parameter-files for @rx_queue.
509 * Return a negative error code or 0 on success. The directory must be
510 * cleaned up using efx_fini_debugfs_rx_queue().
511 */
512 static int efx_init_debugfs_rx_queue(struct efx_rx_queue *rx_queue)
513 {
514 char name[EFX_DEBUGFS_NAME_LEN];
515 char target[EFX_DEBUGFS_NAME_LEN];
516 int rc;
518 /* Create directory */
519 if (snprintf(name, sizeof(name), EFX_RX_QUEUE_NAME(rx_queue))
520 >= sizeof(name))
521 goto err_len;
522 rx_queue->debug_dir = debugfs_create_dir(name,
523 rx_queue->efx->debug_dir);
524 if (!rx_queue->debug_dir)
525 goto err_mem;
527 /* Create files */
528 rc = efx_init_debugfs_files(rx_queue->debug_dir,
529 efx_debugfs_rx_queue_parameters,
530 (void *)rx_queue);
531 if (rc)
532 goto err;
534 /* Create symlink to channel */
535 if (snprintf(target, sizeof(target),
536 "../" EFX_CHANNEL_NAME(rx_queue->channel)) >=
537 sizeof(target))
538 goto err_len;
539 if (!debugfs_create_symlink("channel", rx_queue->debug_dir, target))
540 goto err_mem;
542 return 0;
544 err_len:
545 rc = -ENAMETOOLONG;
546 goto err;
547 err_mem:
548 rc = -ENOMEM;
549 err:
550 efx_fini_debugfs_rx_queue(rx_queue);
551 return rc;
552 }
554 /**
555 * efx_fini_debugfs_rx_queue - remove debugfs directory for RX queue
556 * @rx_queue: Efx RX queue
557 *
558 * Remove directory created for @rx_queue by efx_init_debugfs_rx_queue().
559 */
560 static void efx_fini_debugfs_rx_queue(struct efx_rx_queue *rx_queue)
561 {
562 const char *const symlink_names[] = {
563 "channel", NULL
564 };
566 efx_fini_debugfs_dir(rx_queue->debug_dir,
567 efx_debugfs_rx_queue_parameters, symlink_names);
568 rx_queue->debug_dir = NULL;
569 }
571 /* Per-channel parameters */
572 static struct efx_debugfs_parameter efx_debugfs_channel_parameters[] = {
573 EFX_INT_PARAMETER(struct efx_channel, enabled),
574 EFX_INT_PARAMETER(struct efx_channel, irq),
575 EFX_UINT_PARAMETER(struct efx_channel, has_interrupt),
576 EFX_UINT_PARAMETER(struct efx_channel, irq_moderation),
577 EFX_UINT_PARAMETER(struct efx_channel, eventq_read_ptr),
578 EFX_UINT_PARAMETER(struct efx_channel, n_rx_tobe_disc),
579 EFX_UINT_PARAMETER(struct efx_channel, n_rx_ip_frag_err),
580 EFX_UINT_PARAMETER(struct efx_channel, n_rx_ip_hdr_chksum_err),
581 EFX_UINT_PARAMETER(struct efx_channel, n_rx_tcp_udp_chksum_err),
582 EFX_UINT_PARAMETER(struct efx_channel, n_rx_frm_trunc),
583 EFX_UINT_PARAMETER(struct efx_channel, n_rx_overlength),
584 EFX_UINT_PARAMETER(struct efx_channel, n_skbuff_leaks),
585 EFX_INT_PARAMETER(struct efx_channel, rx_alloc_level),
586 EFX_INT_PARAMETER(struct efx_channel, rx_alloc_push_pages),
587 EFX_INT_PARAMETER(struct efx_channel, rx_alloc_pop_pages),
588 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_merges),
589 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_bursts),
590 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_slow_start),
591 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_misorder),
592 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_too_many),
593 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_new_stream),
594 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_drop_idle),
595 EFX_UINT_PARAMETER(struct efx_channel, ssr.n_drop_closed),
596 {NULL},
597 };
599 static void efx_fini_debugfs_channel(struct efx_channel *channel);
601 /**
602 * efx_init_debugfs_channel - create debugfs directory for channel
603 * @channel: Efx channel
604 *
605 * Create a debugfs directory containing parameter-files for @channel.
606 * Return a negative error code or 0 on success. The directory must be
607 * cleaned up using efx_fini_debugfs_channel().
608 */
609 static int efx_init_debugfs_channel(struct efx_channel *channel)
610 {
611 char name[EFX_DEBUGFS_NAME_LEN];
612 int rc;
614 /* Create directory */
615 if (snprintf(name, sizeof(name), EFX_CHANNEL_NAME(channel))
616 >= sizeof(name))
617 goto err_len;
618 channel->debug_dir = debugfs_create_dir(name, channel->efx->debug_dir);
619 if (!channel->debug_dir)
620 goto err_mem;
622 /* Create files */
623 rc = efx_init_debugfs_files(channel->debug_dir,
624 efx_debugfs_channel_parameters,
625 (void *)channel);
626 if (rc)
627 goto err;
629 return 0;
631 err_len:
632 rc = -ENAMETOOLONG;
633 goto err;
634 err_mem:
635 rc = -ENOMEM;
636 err:
637 efx_fini_debugfs_channel(channel);
638 return rc;
639 }
641 /**
642 * efx_fini_debugfs_channel - remove debugfs directory for channel
643 * @channel: Efx channel
644 *
645 * Remove directory created for @channel by efx_init_debugfs_channel().
646 */
647 static void efx_fini_debugfs_channel(struct efx_channel *channel)
648 {
649 efx_fini_debugfs_dir(channel->debug_dir,
650 efx_debugfs_channel_parameters, NULL);
651 channel->debug_dir = NULL;
652 }
654 /* Per-NIC parameters */
655 static struct efx_debugfs_parameter efx_debugfs_nic_parameters[] = {
656 EFX_INT_PARAMETER(struct efx_nic, legacy_irq),
657 EFX_INT_PARAMETER(struct efx_nic, rss_queues),
658 EFX_UINT_PARAMETER(struct efx_nic, rx_buffer_len),
659 EFX_INT_MODE_PARAMETER(struct efx_nic, interrupt_mode),
660 {.name = "hardware_desc",
661 .offset = 0,
662 .reader = falcon_debugfs_read_hardware_desc},
663 {NULL},
664 };
666 /* Per-NIC error counts */
667 static struct efx_debugfs_parameter efx_debugfs_nic_error_parameters[] = {
668 EFX_ATOMIC_PARAMETER(struct efx_nic_errors, missing_event),
669 EFX_ATOMIC_PARAMETER(struct efx_nic_errors, rx_reset),
670 EFX_ATOMIC_PARAMETER(struct efx_nic_errors, rx_desc_fetch),
671 EFX_ATOMIC_PARAMETER(struct efx_nic_errors, tx_desc_fetch),
672 EFX_ATOMIC_PARAMETER(struct efx_nic_errors, spurious_tx),
673 {NULL},
674 };
676 /**
677 * efx_init_debugfs_channels - create debugfs directories for NIC channels
678 * @efx: Efx NIC
679 *
680 * Create subdirectories of @efx's debugfs directory for all the
681 * channels, RX queues and TX queues used by this driver. Return a
682 * negative error code or 0 on success. The subdirectories must be
683 * cleaned up using efx_fini_debugfs_channels().
684 */
685 int efx_init_debugfs_channels(struct efx_nic *efx)
686 {
687 struct efx_channel *channel;
688 struct efx_rx_queue *rx_queue;
689 struct efx_tx_queue *tx_queue;
690 int rc;
692 efx_for_each_channel(channel, efx) {
693 rc = efx_init_debugfs_channel(channel);
694 if (rc)
695 goto err;
696 }
698 efx_for_each_rx_queue(rx_queue, efx) {
699 rc = efx_init_debugfs_rx_queue(rx_queue);
700 if (rc)
701 goto err;
702 }
704 efx_for_each_tx_queue(tx_queue, efx) {
705 rc = efx_init_debugfs_tx_queue(tx_queue);
706 if (rc)
707 goto err;
708 }
710 return 0;
712 err:
713 efx_fini_debugfs_channels(efx);
714 return rc;
715 }
717 /**
718 * efx_fini_debugfs_channels - remove debugfs directories for NIC queues
719 * @efx: Efx NIC
720 *
721 * Remove subdirectories of @efx's debugfs directory created by
722 * efx_init_debugfs_channels().
723 */
724 void efx_fini_debugfs_channels(struct efx_nic *efx)
725 {
726 struct efx_channel *channel;
727 struct efx_rx_queue *rx_queue;
728 struct efx_tx_queue *tx_queue;
730 efx_for_each_tx_queue(tx_queue, efx)
731 efx_fini_debugfs_tx_queue(tx_queue);
733 efx_for_each_rx_queue(rx_queue, efx)
734 efx_fini_debugfs_rx_queue(rx_queue);
736 efx_for_each_channel(channel, efx)
737 efx_fini_debugfs_channel(channel);
738 }
740 /**
741 * efx_init_debugfs_nic - create debugfs directory for NIC
742 * @efx: Efx NIC
743 *
744 * Create debugfs directory containing parameter-files for @efx,
745 * and a subdirectory "errors" containing per-NIC error counts.
746 * Return a negative error code or 0 on success. The directories
747 * must be cleaned up using efx_fini_debugfs_nic().
748 */
749 int efx_init_debugfs_nic(struct efx_nic *efx)
750 {
751 int rc;
753 /* Create directory */
754 efx->debug_dir = debugfs_create_dir(pci_name(efx->pci_dev),
755 efx_debug_cards);
756 if (!efx->debug_dir)
757 goto err_mem;
759 /* Create errors directory */
760 efx->errors.debug_dir = debugfs_create_dir("errors", efx->debug_dir);
761 if (!efx->errors.debug_dir)
762 goto err_mem;
764 /* Create files */
765 rc = efx_init_debugfs_files(efx->debug_dir,
766 efx_debugfs_nic_parameters, (void *)efx);
767 if (rc)
768 goto err;
769 rc = efx_init_debugfs_files(efx->errors.debug_dir,
770 efx_debugfs_nic_error_parameters,
771 (void *)&efx->errors);
772 if (rc)
773 goto err;
775 return 0;
777 err_mem:
778 rc = -ENOMEM;
779 err:
780 efx_fini_debugfs_nic(efx);
781 return rc;
782 }
784 /**
785 * efx_fini_debugfs_nic - remove debugfs directories for NIC
786 * @efx: Efx NIC
787 *
788 * Remove debugfs directories created for @efx by efx_init_debugfs_nic().
789 */
790 void efx_fini_debugfs_nic(struct efx_nic *efx)
791 {
792 efx_fini_debugfs_dir(efx->errors.debug_dir,
793 efx_debugfs_nic_error_parameters, NULL);
794 efx->errors.debug_dir = NULL;
795 efx_fini_debugfs_dir(efx->debug_dir, efx_debugfs_nic_parameters, NULL);
796 efx->debug_dir = NULL;
797 }
799 /**
800 * efx_init_debugfs - create debugfs directories for sfc driver
801 *
802 * Create debugfs directories "sfc" and "sfc/cards". This must be
803 * called before any of the other functions that create debugfs
804 * directories. Return a negative error code or 0 on success. The
805 * directories must be cleaned up using efx_fini_debugfs().
806 */
807 int efx_init_debugfs(void)
808 {
809 /* Create top-level directory */
810 efx_debug_root = proc_mkdir("sfc", proc_root_driver);
811 if (!efx_debug_root)
812 goto err;
814 /* Create "cards" directory */
815 efx_debug_cards = debugfs_create_dir("cards", efx_debug_root);
816 if (!efx_debug_cards)
817 goto err;
819 return 0;
821 err:
822 efx_fini_debugfs();
823 return -ENOMEM;
824 }
826 /**
827 * efx_fini_debugfs - remove debugfs directories for sfc driver
828 *
829 * Remove directories created by efx_init_debugfs().
830 */
831 void efx_fini_debugfs(void)
832 {
833 remove_proc_entry("sfc", proc_root_driver);
834 debugfs_remove(efx_debug_cards);
835 efx_debug_cards = NULL;
836 debugfs_remove(efx_debug_root);
837 efx_debug_root = NULL;
838 }