Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebddd97a authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller
Browse files

cxgb4: add support to display DCB info



display Data Center bridging information in debug
fs.

Signed-off-by: default avatarCasey Leedom <leedom@chelsio.com>
Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e4ed2b9e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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__ */
+1 −1
Original line number Diff line number Diff line
@@ -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",
+193 −0
Original line number Diff line number Diff line
@@ -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 },
+2 −1
Original line number Diff line number Diff line
@@ -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);

@@ -5658,6 +5658,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);
	}