display Data Center bridging information in debug
fs.

Signed-off-by: Casey Leedom <lee...@chelsio.com>
Signed-off-by: Ganesh Goudar <ganes...@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h         |   1 +
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c     |   2 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 193 +++++++++++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c    |   3 +-
 4 files changed, 197 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 3da9299..76d1674 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1853,4 +1853,5 @@ void cxgb4_write_sgl(const struct sk_buff *skb, struct 
sge_txq *q,
 void cxgb4_ring_tx_db(struct adapter *adap, struct sge_txq *q, int n);
 int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
                    u16 vlan);
+int cxgb4_dcb_enabled(const struct net_device *dev);
 #endif /* __CXGB4_H__ */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index 4e7f72b..b34f0f0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -22,7 +22,7 @@
 
 /* DCBx version control
  */
-static const char * const dcb_ver_array[] = {
+const char * const dcb_ver_array[] = {
        "Unknown",
        "DCBx-CIN",
        "DCBx-CEE 1.01",
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 6f312e0..0f72f9c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2414,6 +2414,196 @@ static const struct file_operations 
rss_vf_config_debugfs_fops = {
        .release = seq_release_private
 };
 
+#ifdef CONFIG_CHELSIO_T4_DCB
+extern char *dcb_ver_array[];
+
+/* Data Center Briging information for each port.
+ */
+static int dcb_info_show(struct seq_file *seq, void *v)
+{
+       struct adapter *adap = seq->private;
+
+       if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Data Center Bridging Information\n");
+       } else {
+               int port = (uintptr_t)v - 2;
+               struct net_device *dev = adap->port[port];
+               struct port_info *pi = netdev2pinfo(dev);
+               struct port_dcb_info *dcb = &pi->dcb;
+
+               seq_puts(seq, "\n");
+               seq_printf(seq, "Port: %d (DCB negotiated: %s)\n",
+                          port,
+                          cxgb4_dcb_enabled(dev) ? "yes" : "no");
+
+               if (cxgb4_dcb_enabled(dev))
+                       seq_printf(seq, "[ DCBx Version %s ]\n",
+                                  dcb_ver_array[dcb->dcb_version]);
+
+               if (dcb->msgs) {
+                       int i;
+
+                       seq_puts(seq, "\n  Index\t\t\t  :\t");
+                       for (i = 0; i < 8; i++)
+                               seq_printf(seq, " %3d", i);
+                       seq_puts(seq, "\n\n");
+               }
+
+               if (dcb->msgs & CXGB4_DCB_FW_PGID) {
+                       int prio, pgid;
+
+                       seq_puts(seq, "  Priority Group IDs\t  :\t");
+                       for (prio = 0; prio < 8; prio++) {
+                               pgid = (dcb->pgid >> 4 * (7 - prio)) & 0xf;
+                               seq_printf(seq, " %3d", pgid);
+                       }
+                       seq_puts(seq, "\n");
+               }
+
+               if (dcb->msgs & CXGB4_DCB_FW_PGRATE) {
+                       int pg;
+
+                       seq_puts(seq, "  Priority Group BW(%)\t  :\t");
+                       for (pg = 0; pg < 8; pg++)
+                               seq_printf(seq, " %3d", dcb->pgrate[pg]);
+                       seq_puts(seq, "\n");
+
+                       if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
+                               seq_puts(seq, "  TSA Algorithm\t\t  :\t");
+                               for (pg = 0; pg < 8; pg++)
+                                       seq_printf(seq, " %3d", dcb->tsa[pg]);
+                               seq_puts(seq, "\n");
+                       }
+
+                       seq_printf(seq, "  Max PG Traffic Classes  [%3d  ]\n",
+                                  dcb->pg_num_tcs_supported);
+
+                       seq_puts(seq, "\n");
+               }
+
+               if (dcb->msgs & CXGB4_DCB_FW_PRIORATE) {
+                       int prio;
+
+                       seq_puts(seq, "  Priority Rate\t:\t");
+                       for (prio = 0; prio < 8; prio++)
+                               seq_printf(seq, " %3d", dcb->priorate[prio]);
+                       seq_puts(seq, "\n");
+               }
+
+               if (dcb->msgs & CXGB4_DCB_FW_PFC) {
+                       int prio;
+
+                       seq_puts(seq, "  Priority Flow Control   :\t");
+                       for (prio = 0; prio < 8; prio++) {
+                               int pfcen = (dcb->pfcen >> 1 * (7 - prio))
+                                           & 0x1;
+                               seq_printf(seq, " %3d", pfcen);
+                       }
+                       seq_puts(seq, "\n");
+
+                       seq_printf(seq, "  Max PFC Traffic Classes [%3d  ]\n",
+                                  dcb->pfc_num_tcs_supported);
+
+                       seq_puts(seq, "\n");
+               }
+
+               if (dcb->msgs & CXGB4_DCB_FW_APP_ID) {
+                       int app, napps;
+
+                       seq_puts(seq, "  Application Information:\n");
+                       seq_puts(seq, "  App    Priority    Selection         
Protocol\n");
+                       seq_puts(seq, "  Index  Map         Field             
ID\n");
+                       for (app = 0, napps = 0;
+                            app < CXGB4_MAX_DCBX_APP_SUPPORTED; app++) {
+                               struct app_priority *ap;
+                               static const char * const sel_names[] = {
+                                       "Ethertype",
+                                       "Socket TCP",
+                                       "Socket UDP",
+                                       "Socket All",
+                               };
+                               const char *sel_name;
+
+                               ap = &dcb->app_priority[app];
+                               /* skip empty slots */
+                               if (ap->protocolid == 0)
+                                       continue;
+                               napps++;
+
+                               if (ap->sel_field < ARRAY_SIZE(sel_names))
+                                       sel_name = sel_names[ap->sel_field];
+                               else
+                                       sel_name = "UNKNOWN";
+
+                               seq_printf(seq, "  %3d    %#04x        %-10s 
(%d)    %#06x (%d)\n",
+                                          app,
+                                          ap->user_prio_map,
+                                          sel_name, ap->sel_field,
+                                          ap->protocolid, ap->protocolid);
+                       }
+                       if (napps == 0)
+                               seq_puts(seq, "    --- None ---\n");
+               }
+       }
+       return 0;
+}
+
+static inline void *dcb_info_get_idx(struct adapter *adap, loff_t pos)
+{
+       return (pos <= adap->params.nports
+               ? (void *)((uintptr_t)pos + 1)
+               : NULL);
+}
+
+static void *dcb_info_start(struct seq_file *seq, loff_t *pos)
+{
+       struct adapter *adap = seq->private;
+
+       return (*pos
+               ? dcb_info_get_idx(adap, *pos)
+               : SEQ_START_TOKEN);
+}
+
+static void dcb_info_stop(struct seq_file *seq, void *v)
+{
+}
+
+static void *dcb_info_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct adapter *adap = seq->private;
+
+       (*pos)++;
+       return dcb_info_get_idx(adap, *pos);
+}
+
+static const struct seq_operations dcb_info_seq_ops = {
+       .start = dcb_info_start,
+       .next  = dcb_info_next,
+       .stop  = dcb_info_stop,
+       .show  = dcb_info_show
+};
+
+static int dcb_info_open(struct inode *inode, struct file *file)
+{
+       int res = seq_open(file, &dcb_info_seq_ops);
+
+       if (!res) {
+               struct seq_file *seq = file->private_data;
+
+               seq->private = inode->i_private;
+       }
+       return res;
+}
+
+static const struct file_operations dcb_info_debugfs_fops = {
+       .owner   = THIS_MODULE,
+       .open    = dcb_info_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+#endif /* CONFIG_CHELSIO_T4_DCB */
+
 static int resources_show(struct seq_file *seq, void *v)
 {
        struct adapter *adapter = seq->private;
@@ -3435,6 +3625,9 @@ int t4_setup_debugfs(struct adapter *adap)
                { "rss_pf_config", &rss_pf_config_debugfs_fops, 0400, 0 },
                { "rss_vf_config", &rss_vf_config_debugfs_fops, 0400, 0 },
                { "resources", &resources_debugfs_fops, 0400, 0 },
+#ifdef CONFIG_CHELSIO_T4_DCB
+               { "dcb_info", &dcb_info_debugfs_fops, 0400, 0 },
+#endif
                { "sge_qinfo", &sge_qinfo_debugfs_fops, 0400, 0 },
                { "ibq_tp0",  &cim_ibq_fops, 0400, 0 },
                { "ibq_tp1",  &cim_ibq_fops, 0400, 1 },
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 479a73d..53d5dad 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -267,7 +267,7 @@ static void dcb_tx_queue_prio_enable(struct net_device 
*dev, int enable)
        }
 }
 
-static int cxgb4_dcb_enabled(const struct net_device *dev)
+int cxgb4_dcb_enabled(const struct net_device *dev)
 {
        struct port_info *pi = netdev_priv(dev);
 
@@ -5659,6 +5659,7 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 #ifdef CONFIG_CHELSIO_T4_DCB
                netdev->dcbnl_ops = &cxgb4_dcb_ops;
                cxgb4_dcb_state_init(netdev);
+               cxgb4_dcb_version_init(netdev);
 #endif
                cxgb4_set_ethtool_ops(netdev);
        }
-- 
2.1.0

Reply via email to