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

Commit 9b59e39f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-hns3-some-code-optimizations-bugfixes-features'



Huazhong Tan says:

====================
net: hns3: some code optimizations & bugfixes & features

This patch-set includes code optimizations, bugfixes and features for
the HNS3 ethernet controller driver.

[patch 01/12] adds support for reporting link change event.

[patch 02/12] adds handler for NCSI error.

[patch 03/12] fixes bug related to debugfs.

[patch 04/12] adds a code optimization for setting ring parameters.

[patch 05/12 - 09/12] adds some cleanups.

[patch 10/12 - 12/12] adds some patches related to reset issue.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0ae9fce3 012fcb52
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_GET_MEDIA_TYPE,       /* (VF -> PF) get media type */

	HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
	HCLGE_MBX_PUSH_LINK_STATUS,	/* (M7 -> PF) get port link status */
	HCLGE_MBX_NCSI_ERROR,		/* (M7 -> PF) receive a NCSI error */
};

/* below are per-VF mac-vlan subcodes */
+10 −12
Original line number Diff line number Diff line
@@ -2909,24 +2909,22 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
		       void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *))
{
#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
	int recv_pkts, recv_bds, clean_count, err;
	int unused_count = hns3_desc_unused(ring);
	struct sk_buff *skb = ring->skb;
	int num;
	int recv_pkts = 0;
	int recv_bds = 0;
	int err, num;

	num = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG);
	rmb(); /* Make sure num taken effect before the other data is touched */

	recv_pkts = 0, recv_bds = 0, clean_count = 0;
	num -= unused_count;
	unused_count -= ring->pending_buf;

	while (recv_pkts < budget && recv_bds < num) {
		/* Reuse or realloc buffers */
		if (clean_count + unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
			hns3_nic_alloc_rx_buffers(ring,
						  clean_count + unused_count);
			clean_count = 0;
		if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
			hns3_nic_alloc_rx_buffers(ring, unused_count);
			unused_count = hns3_desc_unused(ring) -
					ring->pending_buf;
		}
@@ -2940,7 +2938,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
			goto out;
		} else if (unlikely(err)) {  /* Do jump the err */
			recv_bds += ring->pending_buf;
			clean_count += ring->pending_buf;
			unused_count += ring->pending_buf;
			ring->skb = NULL;
			ring->pending_buf = 0;
			continue;
@@ -2948,7 +2946,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,

		rx_fn(ring, skb);
		recv_bds += ring->pending_buf;
		clean_count += ring->pending_buf;
		unused_count += ring->pending_buf;
		ring->skb = NULL;
		ring->pending_buf = 0;

@@ -2957,8 +2955,8 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,

out:
	/* Make all data has been write before submit */
	if (clean_count + unused_count > 0)
		hns3_nic_alloc_rx_buffers(ring, clean_count + unused_count);
	if (unused_count > 0)
		hns3_nic_alloc_rx_buffers(ring, unused_count);

	return recv_pkts;
}
@@ -3588,7 +3586,7 @@ static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring)
	return ret;
}

static void hns3_fini_ring(struct hns3_enet_ring *ring)
void hns3_fini_ring(struct hns3_enet_ring *ring)
{
	hns3_free_desc(ring);
	devm_kfree(ring_to_dev(ring), ring->desc_cb);
+2 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ enum hns3_nic_state {
#define HNS3_TX_TIMEOUT (5 * HZ)
#define HNS3_RING_NAME_LEN			16
#define HNS3_BUFFER_SIZE_2048			2048
#define HNS3_RING_MAX_PENDING			32768
#define HNS3_RING_MAX_PENDING			32760
#define HNS3_RING_MIN_PENDING			24
#define HNS3_RING_BD_MULTIPLE			8
/* max frame size of mac */
@@ -642,6 +642,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring);
int hns3_init_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);
void hns3_fini_ring(struct hns3_enet_ring *ring);
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(
+62 −26
Original line number Diff line number Diff line
@@ -867,7 +867,7 @@ static int hns3_get_rxnfc(struct net_device *netdev,
	}
}

static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
					u32 tx_desc_num, u32 rx_desc_num)
{
	struct hnae3_handle *h = priv->ae_handle;
@@ -881,21 +881,29 @@ static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
		priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num =
			rx_desc_num;
	}
}

static struct hns3_enet_ring *hns3_backup_ringparam(struct hns3_nic_priv *priv)
{
	struct hnae3_handle *handle = priv->ae_handle;
	struct hns3_enet_ring *tmp_rings;
	int i;

	tmp_rings = kcalloc(handle->kinfo.num_tqps * 2,
			    sizeof(struct hns3_enet_ring), GFP_KERNEL);
	if (!tmp_rings)
		return NULL;

	for (i = 0; i < handle->kinfo.num_tqps * 2; i++)
		memcpy(&tmp_rings[i], priv->ring_data[i].ring,
		       sizeof(struct hns3_enet_ring));

	return hns3_init_all_ring(priv);
	return tmp_rings;
}

static int hns3_set_ringparam(struct net_device *ndev,
static int hns3_check_ringparam(struct net_device *ndev,
				struct ethtool_ringparam *param)
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hnae3_handle *h = priv->ae_handle;
	bool if_running = netif_running(ndev);
	u32 old_tx_desc_num, new_tx_desc_num;
	u32 old_rx_desc_num, new_rx_desc_num;
	int queue_num = h->kinfo.num_tqps;
	int ret;

	if (hns3_nic_resetting(ndev))
		return -EBUSY;

@@ -911,6 +919,25 @@ static int hns3_set_ringparam(struct net_device *ndev,
		return -EINVAL;
	}

	return 0;
}

static int hns3_set_ringparam(struct net_device *ndev,
			      struct ethtool_ringparam *param)
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hnae3_handle *h = priv->ae_handle;
	struct hns3_enet_ring *tmp_rings;
	bool if_running = netif_running(ndev);
	u32 old_tx_desc_num, new_tx_desc_num;
	u32 old_rx_desc_num, new_rx_desc_num;
	u16 queue_num = h->kinfo.num_tqps;
	int ret, i;

	ret = hns3_check_ringparam(ndev, param);
	if (ret)
		return ret;

	/* Hardware requires that its descriptors must be multiple of eight */
	new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE);
	new_rx_desc_num = ALIGN(param->rx_pending, HNS3_RING_BD_MULTIPLE);
@@ -920,6 +947,13 @@ static int hns3_set_ringparam(struct net_device *ndev,
	    old_rx_desc_num == new_rx_desc_num)
		return 0;

	tmp_rings = hns3_backup_ringparam(priv);
	if (!tmp_rings) {
		netdev_err(ndev,
			   "backup ring param failed by allocating memory fail\n");
		return -ENOMEM;
	}

	netdev_info(ndev,
		    "Changing Tx/Rx ring depth from %d/%d to %d/%d\n",
		    old_tx_desc_num, old_rx_desc_num,
@@ -928,22 +962,24 @@ static int hns3_set_ringparam(struct net_device *ndev,
	if (if_running)
		ndev->netdev_ops->ndo_stop(ndev);

	ret = hns3_uninit_all_ring(priv);
	if (ret)
		return ret;

	ret = hns3_change_all_ring_bd_num(priv, new_tx_desc_num,
					  new_rx_desc_num);
	hns3_change_all_ring_bd_num(priv, new_tx_desc_num, new_rx_desc_num);
	ret = hns3_init_all_ring(priv);
	if (ret) {
		ret = hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
		netdev_err(ndev, "Change bd num fail, revert to old value(%d)\n",
			   ret);

		hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
					    old_rx_desc_num);
		if (ret) {
			netdev_err(ndev,
				   "Revert to old bd num fail, ret=%d.\n", ret);
			return ret;
		}
		for (i = 0; i < h->kinfo.num_tqps * 2; i++)
			memcpy(priv->ring_data[i].ring, &tmp_rings[i],
			       sizeof(struct hns3_enet_ring));
	} else {
		for (i = 0; i < h->kinfo.num_tqps * 2; i++)
			hns3_fini_ring(&tmp_rings[i]);
	}

	kfree(tmp_rings);

	if (if_running)
		ret = ndev->netdev_ops->ndo_open(ndev);

+31 −2
Original line number Diff line number Diff line
@@ -103,14 +103,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
	dma_addr_t dma = ring->desc_dma_addr;
	struct hclge_dev *hdev = ring->dev;
	struct hclge_hw *hw = &hdev->hw;
	u32 reg_val;

	if (ring->ring_type == HCLGE_TYPE_CSQ) {
		hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG,
				lower_32_bits(dma));
		hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
				upper_32_bits(dma));
		hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG,
				ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
		reg_val = hclge_read_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG);
		reg_val &= HCLGE_NIC_SW_RST_RDY;
		reg_val |= ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S;
		hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
		hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
		hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
	} else {
@@ -383,6 +386,23 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev)
	return ret;
}

static int hclge_firmware_compat_config(struct hclge_dev *hdev)
{
	struct hclge_firmware_compat_cmd *req;
	struct hclge_desc desc;
	u32 compat = 0;

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_M7_COMPAT_CFG, false);

	req = (struct hclge_firmware_compat_cmd *)desc.data;

	hnae3_set_bit(compat, HCLGE_LINK_EVENT_REPORT_EN_B, 1);
	hnae3_set_bit(compat, HCLGE_NCSI_ERROR_REPORT_EN_B, 1);
	req->compat = cpu_to_le32(compat);

	return hclge_cmd_send(&hdev->hw, &desc, 1);
}

int hclge_cmd_init(struct hclge_dev *hdev)
{
	u32 version;
@@ -429,6 +449,15 @@ int hclge_cmd_init(struct hclge_dev *hdev)
		 hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK,
				 HNAE3_FW_VERSION_BYTE0_SHIFT));

	/* ask the firmware to enable some features, driver can work without
	 * it.
	 */
	ret = hclge_firmware_compat_config(hdev);
	if (ret)
		dev_warn(&hdev->pdev->dev,
			 "Firmware compatible features not enabled(%d).\n",
			 ret);

	return 0;

err_cmd_init:
Loading