Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2013 - 2018 Intel Corporation. */
0003 
0004 #include "fm10k.h"
0005 
0006 #include <linux/debugfs.h>
0007 #include <linux/seq_file.h>
0008 
0009 static struct dentry *dbg_root;
0010 
0011 /* Descriptor Seq Functions */
0012 
0013 static void *fm10k_dbg_desc_seq_start(struct seq_file *s, loff_t *pos)
0014 {
0015     struct fm10k_ring *ring = s->private;
0016 
0017     return (*pos < ring->count) ? pos : NULL;
0018 }
0019 
0020 static void *fm10k_dbg_desc_seq_next(struct seq_file *s,
0021                      void __always_unused *v,
0022                      loff_t *pos)
0023 {
0024     struct fm10k_ring *ring = s->private;
0025 
0026     return (++(*pos) < ring->count) ? pos : NULL;
0027 }
0028 
0029 static void fm10k_dbg_desc_seq_stop(struct seq_file __always_unused *s,
0030                     void __always_unused *v)
0031 {
0032     /* Do nothing. */
0033 }
0034 
0035 static void fm10k_dbg_desc_break(struct seq_file *s, int i)
0036 {
0037     while (i--)
0038         seq_putc(s, '-');
0039 
0040     seq_putc(s, '\n');
0041 }
0042 
0043 static int fm10k_dbg_tx_desc_seq_show(struct seq_file *s, void *v)
0044 {
0045     struct fm10k_ring *ring = s->private;
0046     int i = *(loff_t *)v;
0047     static const char tx_desc_hdr[] =
0048         "DES BUFFER_ADDRESS     LENGTH VLAN   MSS    HDRLEN FLAGS\n";
0049 
0050     /* Generate header */
0051     if (!i) {
0052         seq_printf(s, tx_desc_hdr);
0053         fm10k_dbg_desc_break(s, sizeof(tx_desc_hdr) - 1);
0054     }
0055 
0056     /* Validate descriptor allocation */
0057     if (!ring->desc) {
0058         seq_printf(s, "%03X Descriptor ring not allocated.\n", i);
0059     } else {
0060         struct fm10k_tx_desc *txd = FM10K_TX_DESC(ring, i);
0061 
0062         seq_printf(s, "%03X %#018llx %#06x %#06x %#06x %#06x %#04x\n",
0063                i, txd->buffer_addr, txd->buflen, txd->vlan,
0064                txd->mss, txd->hdrlen, txd->flags);
0065     }
0066 
0067     return 0;
0068 }
0069 
0070 static int fm10k_dbg_rx_desc_seq_show(struct seq_file *s, void *v)
0071 {
0072     struct fm10k_ring *ring = s->private;
0073     int i = *(loff_t *)v;
0074     static const char rx_desc_hdr[] =
0075     "DES DATA       RSS        STATERR    LENGTH VLAN   DGLORT SGLORT TIMESTAMP\n";
0076 
0077     /* Generate header */
0078     if (!i) {
0079         seq_printf(s, rx_desc_hdr);
0080         fm10k_dbg_desc_break(s, sizeof(rx_desc_hdr) - 1);
0081     }
0082 
0083     /* Validate descriptor allocation */
0084     if (!ring->desc) {
0085         seq_printf(s, "%03X Descriptor ring not allocated.\n", i);
0086     } else {
0087         union fm10k_rx_desc *rxd = FM10K_RX_DESC(ring, i);
0088 
0089         seq_printf(s,
0090                "%03X %#010x %#010x %#010x %#06x %#06x %#06x %#06x %#018llx\n",
0091                i, rxd->d.data, rxd->d.rss, rxd->d.staterr,
0092                rxd->w.length, rxd->w.vlan, rxd->w.dglort,
0093                rxd->w.sglort, rxd->q.timestamp);
0094     }
0095 
0096     return 0;
0097 }
0098 
0099 static const struct seq_operations fm10k_dbg_tx_desc_seq_ops = {
0100     .start = fm10k_dbg_desc_seq_start,
0101     .next  = fm10k_dbg_desc_seq_next,
0102     .stop  = fm10k_dbg_desc_seq_stop,
0103     .show  = fm10k_dbg_tx_desc_seq_show,
0104 };
0105 
0106 static const struct seq_operations fm10k_dbg_rx_desc_seq_ops = {
0107     .start = fm10k_dbg_desc_seq_start,
0108     .next  = fm10k_dbg_desc_seq_next,
0109     .stop  = fm10k_dbg_desc_seq_stop,
0110     .show  = fm10k_dbg_rx_desc_seq_show,
0111 };
0112 
0113 static int fm10k_dbg_desc_open(struct inode *inode, struct file *filep)
0114 {
0115     struct fm10k_ring *ring = inode->i_private;
0116     struct fm10k_q_vector *q_vector = ring->q_vector;
0117     const struct seq_operations *desc_seq_ops;
0118     int err;
0119 
0120     if (ring < q_vector->rx.ring)
0121         desc_seq_ops = &fm10k_dbg_tx_desc_seq_ops;
0122     else
0123         desc_seq_ops = &fm10k_dbg_rx_desc_seq_ops;
0124 
0125     err = seq_open(filep, desc_seq_ops);
0126     if (err)
0127         return err;
0128 
0129     ((struct seq_file *)filep->private_data)->private = ring;
0130 
0131     return 0;
0132 }
0133 
0134 static const struct file_operations fm10k_dbg_desc_fops = {
0135     .owner   = THIS_MODULE,
0136     .open    = fm10k_dbg_desc_open,
0137     .read    = seq_read,
0138     .llseek  = seq_lseek,
0139     .release = seq_release,
0140 };
0141 
0142 /**
0143  * fm10k_dbg_q_vector_init - setup debugfs for the q_vectors
0144  * @q_vector: q_vector to allocate directories for
0145  *
0146  * A folder is created for each q_vector found. In each q_vector
0147  * folder, a debugfs file is created for each tx and rx ring
0148  * allocated to the q_vector.
0149  **/
0150 void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector)
0151 {
0152     struct fm10k_intfc *interface = q_vector->interface;
0153     char name[16];
0154     int i;
0155 
0156     if (!interface->dbg_intfc)
0157         return;
0158 
0159     /* Generate a folder for each q_vector */
0160     snprintf(name, sizeof(name), "q_vector.%03d", q_vector->v_idx);
0161 
0162     q_vector->dbg_q_vector = debugfs_create_dir(name, interface->dbg_intfc);
0163 
0164     /* Generate a file for each rx ring in the q_vector */
0165     for (i = 0; i < q_vector->tx.count; i++) {
0166         struct fm10k_ring *ring = &q_vector->tx.ring[i];
0167 
0168         snprintf(name, sizeof(name), "tx_ring.%03d", ring->queue_index);
0169 
0170         debugfs_create_file(name, 0600,
0171                     q_vector->dbg_q_vector, ring,
0172                     &fm10k_dbg_desc_fops);
0173     }
0174 
0175     /* Generate a file for each rx ring in the q_vector */
0176     for (i = 0; i < q_vector->rx.count; i++) {
0177         struct fm10k_ring *ring = &q_vector->rx.ring[i];
0178 
0179         snprintf(name, sizeof(name), "rx_ring.%03d", ring->queue_index);
0180 
0181         debugfs_create_file(name, 0600,
0182                     q_vector->dbg_q_vector, ring,
0183                     &fm10k_dbg_desc_fops);
0184     }
0185 }
0186 
0187 /**
0188  * fm10k_dbg_q_vector_exit - setup debugfs for the q_vectors
0189  * @q_vector: q_vector to allocate directories for
0190  **/
0191 void fm10k_dbg_q_vector_exit(struct fm10k_q_vector *q_vector)
0192 {
0193     struct fm10k_intfc *interface = q_vector->interface;
0194 
0195     if (interface->dbg_intfc)
0196         debugfs_remove_recursive(q_vector->dbg_q_vector);
0197     q_vector->dbg_q_vector = NULL;
0198 }
0199 
0200 /**
0201  * fm10k_dbg_intfc_init - setup the debugfs directory for the intferface
0202  * @interface: the interface that is starting up
0203  **/
0204 
0205 void fm10k_dbg_intfc_init(struct fm10k_intfc *interface)
0206 {
0207     const char *name = pci_name(interface->pdev);
0208 
0209     if (dbg_root)
0210         interface->dbg_intfc = debugfs_create_dir(name, dbg_root);
0211 }
0212 
0213 /**
0214  * fm10k_dbg_intfc_exit - clean out the interface's debugfs entries
0215  * @interface: the interface that is stopping
0216  **/
0217 void fm10k_dbg_intfc_exit(struct fm10k_intfc *interface)
0218 {
0219     if (dbg_root)
0220         debugfs_remove_recursive(interface->dbg_intfc);
0221     interface->dbg_intfc = NULL;
0222 }
0223 
0224 /**
0225  * fm10k_dbg_init - start up debugfs for the driver
0226  **/
0227 void fm10k_dbg_init(void)
0228 {
0229     dbg_root = debugfs_create_dir(fm10k_driver_name, NULL);
0230 }
0231 
0232 /**
0233  * fm10k_dbg_exit - clean out the driver's debugfs entries
0234  **/
0235 void fm10k_dbg_exit(void)
0236 {
0237     debugfs_remove_recursive(dbg_root);
0238     dbg_root = NULL;
0239 }