Commit 5313794b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-next'



Huazhong Tan says:

====================
net: hns3: add some DFX info for HNS3 driver

This patch-set adds some DFX information to HNS3 driver, for easily
debug some problems, and fixes some related bugs.

[patch 1/12 - 4/12] adds debug info about reset & interrupt events

[patch 5/12 - 7/12] adds debug info about TX time out & fixes
related bugs

[patch 8/12] adds support for setting netif message level

[patch 9/12 - 10/12] adds debugfs command to dump NCL & MAC info

[patch 11/12] adds VF's queue statistics info updating

[patch 12/12] adds a check for debugfs help function to decide which
commands are supportable
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d7cc399e 97afd47b
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -392,7 +392,8 @@ struct hnae3_ae_ops {
	void (*update_stats)(struct hnae3_handle *handle,
	void (*update_stats)(struct hnae3_handle *handle,
			     struct net_device_stats *net_stats);
			     struct net_device_stats *net_stats);
	void (*get_stats)(struct hnae3_handle *handle, u64 *data);
	void (*get_stats)(struct hnae3_handle *handle, u64 *data);

	void (*get_mac_pause_stats)(struct hnae3_handle *handle, u64 *tx_cnt,
				    u64 *rx_cnt);
	void (*get_strings)(struct hnae3_handle *handle,
	void (*get_strings)(struct hnae3_handle *handle,
			    u32 stringset, u8 *data);
			    u32 stringset, u8 *data);
	int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
	int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
@@ -589,6 +590,9 @@ struct hnae3_handle {


	u8 netdev_flags;
	u8 netdev_flags;
	struct dentry *hnae3_dbgfs;
	struct dentry *hnae3_dbgfs;

	/* Network interface message level enabled bits */
	u32 msg_enable;
};
};


#define hnae3_set_field(origin, mask, shift, val) \
#define hnae3_set_field(origin, mask, shift, val) \
+9 −0
Original line number Original line Diff line number Diff line
@@ -239,6 +239,10 @@ static void hns3_dbg_help(struct hnae3_handle *h)
	dev_info(&h->pdev->dev, "queue info [number]\n");
	dev_info(&h->pdev->dev, "queue info [number]\n");
	dev_info(&h->pdev->dev, "queue map\n");
	dev_info(&h->pdev->dev, "queue map\n");
	dev_info(&h->pdev->dev, "bd info [q_num] <bd index>\n");
	dev_info(&h->pdev->dev, "bd info [q_num] <bd index>\n");

	if (!hns3_is_phys_func(h->pdev))
		return;

	dev_info(&h->pdev->dev, "dump fd tcam\n");
	dev_info(&h->pdev->dev, "dump fd tcam\n");
	dev_info(&h->pdev->dev, "dump tc\n");
	dev_info(&h->pdev->dev, "dump tc\n");
	dev_info(&h->pdev->dev, "dump tm map [q_num]\n");
	dev_info(&h->pdev->dev, "dump tm map [q_num]\n");
@@ -247,6 +251,9 @@ static void hns3_dbg_help(struct hnae3_handle *h)
	dev_info(&h->pdev->dev, "dump qos pri map\n");
	dev_info(&h->pdev->dev, "dump qos pri map\n");
	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
	dev_info(&h->pdev->dev, "dump mng tbl\n");
	dev_info(&h->pdev->dev, "dump mng tbl\n");
	dev_info(&h->pdev->dev, "dump reset info\n");
	dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n");
	dev_info(&h->pdev->dev, "dump mac tnl status\n");


	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
	strncat(printf_buf, "dump reg [[bios common] [ssu <prt_id>]",
	strncat(printf_buf, "dump reg [[bios common] [ssu <prt_id>]",
@@ -341,6 +348,8 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
		ret = hns3_dbg_bd_info(handle, cmd_buf);
		ret = hns3_dbg_bd_info(handle, cmd_buf);
	else if (handle->ae_algo->ops->dbg_run_cmd)
	else if (handle->ae_algo->ops->dbg_run_cmd)
		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
	else
		ret = -EOPNOTSUPP;


	if (ret)
	if (ret)
		hns3_dbg_help(handle);
		hns3_dbg_help(handle);
+91 −13
Original line number Original line Diff line number Diff line
@@ -35,6 +35,13 @@ static const char hns3_driver_string[] =
static const char hns3_copyright[] = "Copyright (c) 2017 Huawei Corporation.";
static const char hns3_copyright[] = "Copyright (c) 2017 Huawei Corporation.";
static struct hnae3_client client;
static struct hnae3_client client;


static int debug = -1;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, " Network interface message level setting");

#define DEFAULT_MSG_LEVEL (NETIF_MSG_PROBE | NETIF_MSG_LINK | \
			   NETIF_MSG_IFDOWN | NETIF_MSG_IFUP)

/* hns3_pci_tbl - PCI Device ID Table
/* hns3_pci_tbl - PCI Device ID Table
 *
 *
 * Last entry must be all 0s
 * Last entry must be all 0s
@@ -1628,13 +1635,19 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
{
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hnae3_handle *h = hns3_get_handle(ndev);
	struct hns3_enet_ring *tx_ring = NULL;
	struct hns3_enet_ring *tx_ring = NULL;
	struct napi_struct *napi;
	int timeout_queue = 0;
	int timeout_queue = 0;
	int hw_head, hw_tail;
	int hw_head, hw_tail;
	int fbd_num, fbd_oft;
	int ebd_num, ebd_oft;
	int bd_num, bd_err;
	int ring_en, tc;
	int i;
	int i;


	/* Find the stopped queue the same way the stack does */
	/* Find the stopped queue the same way the stack does */
	for (i = 0; i < ndev->real_num_tx_queues; i++) {
	for (i = 0; i < ndev->num_tx_queues; i++) {
		struct netdev_queue *q;
		struct netdev_queue *q;
		unsigned long trans_start;
		unsigned long trans_start;


@@ -1655,21 +1668,66 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
		return false;
		return false;
	}
	}


	priv->tx_timeout_count++;

	tx_ring = priv->ring_data[timeout_queue].ring;
	tx_ring = priv->ring_data[timeout_queue].ring;
	napi = &tx_ring->tqp_vector->napi;

	netdev_info(ndev,
		    "tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, napi state: %lu\n",
		    priv->tx_timeout_count, timeout_queue, tx_ring->next_to_use,
		    tx_ring->next_to_clean, napi->state);

	netdev_info(ndev,
		    "tx_pkts: %llu, tx_bytes: %llu, io_err_cnt: %llu, sw_err_cnt: %llu\n",
		    tx_ring->stats.tx_pkts, tx_ring->stats.tx_bytes,
		    tx_ring->stats.io_err_cnt, tx_ring->stats.sw_err_cnt);

	netdev_info(ndev,
		    "seg_pkt_cnt: %llu, tx_err_cnt: %llu, restart_queue: %llu, tx_busy: %llu\n",
		    tx_ring->stats.seg_pkt_cnt, tx_ring->stats.tx_err_cnt,
		    tx_ring->stats.restart_queue, tx_ring->stats.tx_busy);

	/* When mac received many pause frames continuous, it's unable to send
	 * packets, which may cause tx timeout
	 */
	if (h->ae_algo->ops->update_stats &&
	    h->ae_algo->ops->get_mac_pause_stats) {
		u64 tx_pause_cnt, rx_pause_cnt;

		h->ae_algo->ops->update_stats(h, &ndev->stats);
		h->ae_algo->ops->get_mac_pause_stats(h, &tx_pause_cnt,
						     &rx_pause_cnt);
		netdev_info(ndev, "tx_pause_cnt: %llu, rx_pause_cnt: %llu\n",
			    tx_pause_cnt, rx_pause_cnt);
	}


	hw_head = readl_relaxed(tx_ring->tqp->io_base +
	hw_head = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_HEAD_REG);
				HNS3_RING_TX_RING_HEAD_REG);
	hw_tail = readl_relaxed(tx_ring->tqp->io_base +
	hw_tail = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_TAIL_REG);
				HNS3_RING_TX_RING_TAIL_REG);
	fbd_num = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_FBDNUM_REG);
	fbd_oft = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_OFFSET_REG);
	ebd_num = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_EBDNUM_REG);
	ebd_oft = readl_relaxed(tx_ring->tqp->io_base +
				HNS3_RING_TX_RING_EBD_OFFSET_REG);
	bd_num = readl_relaxed(tx_ring->tqp->io_base +
			       HNS3_RING_TX_RING_BD_NUM_REG);
	bd_err = readl_relaxed(tx_ring->tqp->io_base +
			       HNS3_RING_TX_RING_BD_ERR_REG);
	ring_en = readl_relaxed(tx_ring->tqp->io_base + HNS3_RING_EN_REG);
	tc = readl_relaxed(tx_ring->tqp->io_base + HNS3_RING_TX_RING_TC_REG);

	netdev_info(ndev,
	netdev_info(ndev,
		    "tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, HW_HEAD: 0x%x, HW_TAIL: 0x%x, INT: 0x%x\n",
		    "BD_NUM: 0x%x HW_HEAD: 0x%x, HW_TAIL: 0x%x, BD_ERR: 0x%x, INT: 0x%x\n",
		    priv->tx_timeout_count,
		    bd_num, hw_head, hw_tail, bd_err,
		    timeout_queue,
		    tx_ring->next_to_use,
		    tx_ring->next_to_clean,
		    hw_head,
		    hw_tail,
		    readl(tx_ring->tqp_vector->mask_addr));
		    readl(tx_ring->tqp_vector->mask_addr));
	netdev_info(ndev,
		    "RING_EN: 0x%x, TC: 0x%x, FBD_NUM: 0x%x FBD_OFT: 0x%x, EBD_NUM: 0x%x, EBD_OFT: 0x%x\n",
		    ring_en, tc, fbd_num, fbd_oft, ebd_num, ebd_oft);


	return true;
	return true;
}
}
@@ -1682,8 +1740,6 @@ static void hns3_nic_net_timeout(struct net_device *ndev)
	if (!hns3_get_tx_timeo_queue_info(ndev))
	if (!hns3_get_tx_timeo_queue_info(ndev))
		return;
		return;


	priv->tx_timeout_count++;

	/* request the reset, and let the hclge to determine
	/* request the reset, and let the hclge to determine
	 * which reset level should be done
	 * which reset level should be done
	 */
	 */
@@ -1708,7 +1764,7 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
	.ndo_set_vf_vlan	= hns3_ndo_set_vf_vlan,
	.ndo_set_vf_vlan	= hns3_ndo_set_vf_vlan,
};
};


static bool hns3_is_phys_func(struct pci_dev *pdev)
bool hns3_is_phys_func(struct pci_dev *pdev)
{
{
	u32 dev_id = pdev->device;
	u32 dev_id = pdev->device;


@@ -3688,6 +3744,21 @@ static void hns3_client_stop(struct hnae3_handle *handle)
	handle->ae_algo->ops->client_stop(handle);
	handle->ae_algo->ops->client_stop(handle);
}
}


static void hns3_info_show(struct hns3_nic_priv *priv)
{
	struct hnae3_knic_private_info *kinfo = &priv->ae_handle->kinfo;

	dev_info(priv->dev, "MAC address: %pM\n", priv->netdev->dev_addr);
	dev_info(priv->dev, "Task queue pairs numbers: %d\n", kinfo->num_tqps);
	dev_info(priv->dev, "RSS size: %d\n", kinfo->rss_size);
	dev_info(priv->dev, "Allocated RSS size: %d\n", kinfo->req_rss_size);
	dev_info(priv->dev, "RX buffer length: %d\n", kinfo->rx_buf_len);
	dev_info(priv->dev, "Desc num per TX queue: %d\n", kinfo->num_tx_desc);
	dev_info(priv->dev, "Desc num per RX queue: %d\n", kinfo->num_rx_desc);
	dev_info(priv->dev, "Total number of enabled TCs: %d\n", kinfo->num_tc);
	dev_info(priv->dev, "Max mtu size: %d\n", priv->netdev->max_mtu);
}

static int hns3_client_init(struct hnae3_handle *handle)
static int hns3_client_init(struct hnae3_handle *handle)
{
{
	struct pci_dev *pdev = handle->pdev;
	struct pci_dev *pdev = handle->pdev;
@@ -3709,6 +3780,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
	priv->tx_timeout_count = 0;
	priv->tx_timeout_count = 0;
	set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
	set_bit(HNS3_NIC_STATE_DOWN, &priv->state);


	handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);

	handle->kinfo.netdev = netdev;
	handle->kinfo.netdev = netdev;
	handle->priv = (void *)priv;
	handle->priv = (void *)priv;


@@ -3775,6 +3848,9 @@ static int hns3_client_init(struct hnae3_handle *handle)


	set_bit(HNS3_NIC_STATE_INITED, &priv->state);
	set_bit(HNS3_NIC_STATE_INITED, &priv->state);


	if (netif_msg_drv(handle))
		hns3_info_show(priv);

	return ret;
	return ret;


out_client_start:
out_client_start:
@@ -3849,10 +3925,12 @@ static void hns3_link_status_change(struct hnae3_handle *handle, bool linkup)
	if (linkup) {
	if (linkup) {
		netif_carrier_on(netdev);
		netif_carrier_on(netdev);
		netif_tx_wake_all_queues(netdev);
		netif_tx_wake_all_queues(netdev);
		if (netif_msg_link(handle))
			netdev_info(netdev, "link up\n");
			netdev_info(netdev, "link up\n");
	} else {
	} else {
		netif_carrier_off(netdev);
		netif_carrier_off(netdev);
		netif_tx_stop_all_queues(netdev);
		netif_tx_stop_all_queues(netdev);
		if (netif_msg_link(handle))
			netdev_info(netdev, "link down\n");
			netdev_info(netdev, "link down\n");
	}
	}
}
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -42,8 +42,10 @@ enum hns3_nic_state {
#define HNS3_RING_TX_RING_HEAD_REG		0x0005C
#define HNS3_RING_TX_RING_HEAD_REG		0x0005C
#define HNS3_RING_TX_RING_FBDNUM_REG		0x00060
#define HNS3_RING_TX_RING_FBDNUM_REG		0x00060
#define HNS3_RING_TX_RING_OFFSET_REG		0x00064
#define HNS3_RING_TX_RING_OFFSET_REG		0x00064
#define HNS3_RING_TX_RING_EBDNUM_REG		0x00068
#define HNS3_RING_TX_RING_PKTNUM_RECORD_REG	0x0006C
#define HNS3_RING_TX_RING_PKTNUM_RECORD_REG	0x0006C

#define HNS3_RING_TX_RING_EBD_OFFSET_REG	0x00070
#define HNS3_RING_TX_RING_BD_ERR_REG		0x00074
#define HNS3_RING_PREFETCH_EN_REG		0x0007C
#define HNS3_RING_PREFETCH_EN_REG		0x0007C
#define HNS3_RING_CFG_VF_NUM_REG		0x00080
#define HNS3_RING_CFG_VF_NUM_REG		0x00080
#define HNS3_RING_ASID_REG			0x0008C
#define HNS3_RING_ASID_REG			0x0008C
@@ -661,6 +663,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv);
int hns3_uninit_all_ring(struct hns3_nic_priv *priv);
int hns3_uninit_all_ring(struct hns3_nic_priv *priv);
int hns3_nic_reset_all_ring(struct hnae3_handle *h);
int hns3_nic_reset_all_ring(struct hnae3_handle *h);
netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
bool hns3_is_phys_func(struct pci_dev *pdev);
int hns3_clean_rx_ring(
int hns3_clean_rx_ring(
		struct hns3_enet_ring *ring, int budget,
		struct hns3_enet_ring *ring, int budget,
		void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *));
		void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *));
+18 −0
Original line number Original line Diff line number Diff line
@@ -1110,6 +1110,20 @@ static int hns3_set_phys_id(struct net_device *netdev,
	return h->ae_algo->ops->set_led_id(h, state);
	return h->ae_algo->ops->set_led_id(h, state);
}
}


static u32 hns3_get_msglevel(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	return h->msg_enable;
}

static void hns3_set_msglevel(struct net_device *netdev, u32 msg_level)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	h->msg_enable = msg_level;
}

static const struct ethtool_ops hns3vf_ethtool_ops = {
static const struct ethtool_ops hns3vf_ethtool_ops = {
	.get_drvinfo = hns3_get_drvinfo,
	.get_drvinfo = hns3_get_drvinfo,
	.get_ringparam = hns3_get_ringparam,
	.get_ringparam = hns3_get_ringparam,
@@ -1130,6 +1144,8 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
	.get_regs_len = hns3_get_regs_len,
	.get_regs_len = hns3_get_regs_len,
	.get_regs = hns3_get_regs,
	.get_regs = hns3_get_regs,
	.get_link = hns3_get_link,
	.get_link = hns3_get_link,
	.get_msglevel = hns3_get_msglevel,
	.set_msglevel = hns3_set_msglevel,
};
};


static const struct ethtool_ops hns3_ethtool_ops = {
static const struct ethtool_ops hns3_ethtool_ops = {
@@ -1159,6 +1175,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
	.get_regs_len = hns3_get_regs_len,
	.get_regs_len = hns3_get_regs_len,
	.get_regs = hns3_get_regs,
	.get_regs = hns3_get_regs,
	.set_phys_id = hns3_set_phys_id,
	.set_phys_id = hns3_set_phys_id,
	.get_msglevel = hns3_get_msglevel,
	.set_msglevel = hns3_set_msglevel,
};
};


void hns3_ethtool_set_ops(struct net_device *netdev)
void hns3_ethtool_set_ops(struct net_device *netdev)
Loading