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

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

Merge branch 'hns3-fixes'



Salil Mehta says:

====================
Misc bug fixes for HNS3 Ethernet driver

This patch-set presents some miscellaneous bug fixs and cleanups for
HNS3 Ethernet Driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b086ff87 dbecc779
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -502,7 +502,7 @@ static int hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto,

	/* find outer header point */
	l3.hdr = skb_network_header(skb);
	l4_hdr = skb_inner_transport_header(skb);
	l4_hdr = skb_transport_header(skb);

	if (skb->protocol == htons(ETH_P_IPV6)) {
		exthdr = l3.hdr + sizeof(*l3.v6);
+19 −0
Original line number Diff line number Diff line
@@ -31,6 +31,17 @@ static int hclge_ring_space(struct hclge_cmq_ring *ring)
	return ring->desc_num - used - 1;
}

static int is_valid_csq_clean_head(struct hclge_cmq_ring *ring, int h)
{
	int u = ring->next_to_use;
	int c = ring->next_to_clean;

	if (unlikely(h >= ring->desc_num))
		return 0;

	return u > c ? (h > c && h <= u) : (h > c || h <= u);
}

static int hclge_alloc_cmd_desc(struct hclge_cmq_ring *ring)
{
	int size  = ring->desc_num * sizeof(struct hclge_desc);
@@ -141,6 +152,7 @@ static void hclge_cmd_init_regs(struct hclge_hw *hw)

static int hclge_cmd_csq_clean(struct hclge_hw *hw)
{
	struct hclge_dev *hdev = (struct hclge_dev *)hw->back;
	struct hclge_cmq_ring *csq = &hw->cmq.csq;
	u16 ntc = csq->next_to_clean;
	struct hclge_desc *desc;
@@ -149,6 +161,13 @@ static int hclge_cmd_csq_clean(struct hclge_hw *hw)

	desc = &csq->desc[ntc];
	head = hclge_read_dev(hw, HCLGE_NIC_CSQ_HEAD_REG);
	rmb(); /* Make sure head is ready before touch any data */

	if (!is_valid_csq_clean_head(csq, head)) {
		dev_warn(&hdev->pdev->dev, "wrong head (%d, %d-%d)\n", head,
			   csq->next_to_use, csq->next_to_clean);
		return 0;
	}

	while (head != ntc) {
		memset(desc, 0, sizeof(*desc));
+112 −55
Original line number Diff line number Diff line
@@ -304,8 +304,6 @@ static const struct hclge_comm_stats_str g_mac_stats_string[] = {
		HCLGE_MAC_STATS_FIELD_OFF(mac_tx_2048_4095_oct_pkt_num)},
	{"mac_tx_4096_8191_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_tx_4096_8191_oct_pkt_num)},
	{"mac_tx_8192_12287_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_tx_8192_12287_oct_pkt_num)},
	{"mac_tx_8192_9216_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_tx_8192_9216_oct_pkt_num)},
	{"mac_tx_9217_12287_oct_pkt_num",
@@ -356,8 +354,6 @@ static const struct hclge_comm_stats_str g_mac_stats_string[] = {
		HCLGE_MAC_STATS_FIELD_OFF(mac_rx_2048_4095_oct_pkt_num)},
	{"mac_rx_4096_8191_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_rx_4096_8191_oct_pkt_num)},
	{"mac_rx_8192_12287_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_rx_8192_12287_oct_pkt_num)},
	{"mac_rx_8192_9216_oct_pkt_num",
		HCLGE_MAC_STATS_FIELD_OFF(mac_rx_8192_9216_oct_pkt_num)},
	{"mac_rx_9217_12287_oct_pkt_num",
@@ -1459,8 +1455,11 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
	/* We need to alloc a vport for main NIC of PF */
	num_vport = hdev->num_vmdq_vport + hdev->num_req_vfs + 1;

	if (hdev->num_tqps < num_vport)
		num_vport = hdev->num_tqps;
	if (hdev->num_tqps < num_vport) {
		dev_err(&hdev->pdev->dev, "tqps(%d) is less than vports(%d)",
			hdev->num_tqps, num_vport);
		return -EINVAL;
	}

	/* Alloc the same number of TQPs for every vport */
	tqp_per_vport = hdev->num_tqps / num_vport;
@@ -4540,8 +4539,9 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
	hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, enable);
}

int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
			     bool is_kill, u16 vlan, u8 qos, __be16 proto)
static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
				    bool is_kill, u16 vlan, u8 qos,
				    __be16 proto)
{
#define HCLGE_MAX_VF_BYTES  16
	struct hclge_vlan_filter_vf_cfg_cmd *req0;
@@ -4599,12 +4599,9 @@ int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
	return -EIO;
}

static int hclge_set_port_vlan_filter(struct hnae3_handle *handle,
				      __be16 proto, u16 vlan_id,
				      bool is_kill)
static int hclge_set_port_vlan_filter(struct hclge_dev *hdev, __be16 proto,
				      u16 vlan_id, bool is_kill)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_vlan_filter_pf_cfg_cmd *req;
	struct hclge_desc desc;
	u8 vlan_offset_byte_val;
@@ -4624,22 +4621,66 @@ static int hclge_set_port_vlan_filter(struct hnae3_handle *handle,
	req->vlan_offset_bitmap[vlan_offset_byte] = vlan_offset_byte_val;

	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret) {
	if (ret)
		dev_err(&hdev->pdev->dev,
			"port vlan command, send fail, ret =%d.\n",
			ret);
			"port vlan command, send fail, ret =%d.\n", ret);
	return ret;
}

	ret = hclge_set_vf_vlan_common(hdev, 0, is_kill, vlan_id, 0, proto);
static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
				    u16 vport_id, u16 vlan_id, u8 qos,
				    bool is_kill)
{
	u16 vport_idx, vport_num = 0;
	int ret;

	ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id,
				       0, proto);
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"Set pf vlan filter config fail, ret =%d.\n",
			ret);
		return -EIO;
			"Set %d vport vlan filter config fail, ret =%d.\n",
			vport_id, ret);
		return ret;
	}

	/* vlan 0 may be added twice when 8021q module is enabled */
	if (!is_kill && !vlan_id &&
	    test_bit(vport_id, hdev->vlan_table[vlan_id]))
		return 0;

	if (!is_kill && test_and_set_bit(vport_id, hdev->vlan_table[vlan_id])) {
		dev_err(&hdev->pdev->dev,
			"Add port vlan failed, vport %d is already in vlan %d\n",
			vport_id, vlan_id);
		return -EINVAL;
	}

	if (is_kill &&
	    !test_and_clear_bit(vport_id, hdev->vlan_table[vlan_id])) {
		dev_err(&hdev->pdev->dev,
			"Delete port vlan failed, vport %d is not in vlan %d\n",
			vport_id, vlan_id);
		return -EINVAL;
	}

	for_each_set_bit(vport_idx, hdev->vlan_table[vlan_id], VLAN_N_VID)
		vport_num++;

	if ((is_kill && vport_num == 0) || (!is_kill && vport_num == 1))
		ret = hclge_set_port_vlan_filter(hdev, proto, vlan_id,
						 is_kill);

	return ret;
}

int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
			  u16 vlan_id, bool is_kill)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;

	return hclge_set_vlan_filter_hw(hdev, proto, vport->vport_id, vlan_id,
					0, is_kill);
}

static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
@@ -4653,7 +4694,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
	if (proto != htons(ETH_P_8021Q))
		return -EPROTONOSUPPORT;

	return hclge_set_vf_vlan_common(hdev, vfid, false, vlan, qos, proto);
	return hclge_set_vlan_filter_hw(hdev, proto, vfid, vlan, qos, false);
}

static int hclge_set_vlan_tx_offload_cfg(struct hclge_vport *vport)
@@ -4818,7 +4859,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
	}

	handle = &hdev->vport[0].nic;
	return hclge_set_port_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
	return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}

static int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
@@ -5166,12 +5207,6 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
	struct phy_device *phydev = hdev->hw.mac.phydev;
	u32 fc_autoneg;

	/* Only support flow control negotiation for netdev with
	 * phy attached for now.
	 */
	if (!phydev)
		return -EOPNOTSUPP;

	fc_autoneg = hclge_get_autoneg(handle);
	if (auto_neg != fc_autoneg) {
		dev_info(&hdev->pdev->dev,
@@ -5190,6 +5225,12 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
	if (!fc_autoneg)
		return hclge_cfg_pauseparam(hdev, rx_en, tx_en);

	/* Only support flow control negotiation for netdev with
	 * phy attached for now.
	 */
	if (!phydev)
		return -EOPNOTSUPP;

	return phy_start_aneg(phydev);
}

@@ -5427,7 +5468,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
	hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL);
	if (!hdev) {
		ret = -ENOMEM;
		goto err_hclge_dev;
		goto out;
	}

	hdev->pdev = pdev;
@@ -5440,38 +5481,38 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
	ret = hclge_pci_init(hdev);
	if (ret) {
		dev_err(&pdev->dev, "PCI init failed\n");
		goto err_pci_init;
		goto out;
	}

	/* Firmware command queue initialize */
	ret = hclge_cmd_queue_init(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Cmd queue init failed, ret = %d.\n", ret);
		return ret;
		goto err_pci_uninit;
	}

	/* Firmware command initialize */
	ret = hclge_cmd_init(hdev);
	if (ret)
		goto err_cmd_init;
		goto err_cmd_uninit;

	ret = hclge_get_cap(hdev);
	if (ret) {
		dev_err(&pdev->dev, "get hw capability error, ret = %d.\n",
			ret);
		return ret;
		goto err_cmd_uninit;
	}

	ret = hclge_configure(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret);
		return ret;
		goto err_cmd_uninit;
	}

	ret = hclge_init_msi(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Init MSI/MSI-X error, ret = %d.\n", ret);
		return ret;
		goto err_cmd_uninit;
	}

	ret = hclge_misc_irq_init(hdev);
@@ -5479,69 +5520,71 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
		dev_err(&pdev->dev,
			"Misc IRQ(vector0) init error, ret = %d.\n",
			ret);
		return ret;
		goto err_msi_uninit;
	}

	ret = hclge_alloc_tqps(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Allocate TQPs error, ret = %d.\n", ret);
		return ret;
		goto err_msi_irq_uninit;
	}

	ret = hclge_alloc_vport(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Allocate vport error, ret = %d.\n", ret);
		return ret;
		goto err_msi_irq_uninit;
	}

	ret = hclge_map_tqp(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Map tqp error, ret = %d.\n", ret);
		return ret;
		goto err_sriov_disable;
	}

	if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) {
		ret = hclge_mac_mdio_config(hdev);
		if (ret) {
		dev_warn(&hdev->pdev->dev,
			dev_err(&hdev->pdev->dev,
				"mdio config fail ret=%d\n", ret);
		return ret;
			goto err_sriov_disable;
		}
	}

	ret = hclge_mac_init(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret);
		return ret;
		goto err_mdiobus_unreg;
	}

	ret = hclge_config_tso(hdev, HCLGE_TSO_MSS_MIN, HCLGE_TSO_MSS_MAX);
	if (ret) {
		dev_err(&pdev->dev, "Enable tso fail, ret =%d\n", ret);
		return ret;
		goto err_mdiobus_unreg;
	}

	ret = hclge_init_vlan_config(hdev);
	if (ret) {
		dev_err(&pdev->dev, "VLAN init fail, ret =%d\n", ret);
		return  ret;
		goto err_mdiobus_unreg;
	}

	ret = hclge_tm_schd_init(hdev);
	if (ret) {
		dev_err(&pdev->dev, "tm schd init fail, ret =%d\n", ret);
		return ret;
		goto err_mdiobus_unreg;
	}

	hclge_rss_init_cfg(hdev);
	ret = hclge_rss_init_hw(hdev);
	if (ret) {
		dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
		return ret;
		goto err_mdiobus_unreg;
	}

	ret = init_mgr_tbl(hdev);
	if (ret) {
		dev_err(&pdev->dev, "manager table init fail, ret =%d\n", ret);
		return ret;
		goto err_mdiobus_unreg;
	}

	hclge_dcb_ops_set(hdev);
@@ -5564,11 +5607,24 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
	pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME);
	return 0;

err_cmd_init:
err_mdiobus_unreg:
	if (hdev->hw.mac.phydev)
		mdiobus_unregister(hdev->hw.mac.mdio_bus);
err_sriov_disable:
	if (IS_ENABLED(CONFIG_PCI_IOV))
		hclge_disable_sriov(hdev);
err_msi_irq_uninit:
	hclge_misc_irq_uninit(hdev);
err_msi_uninit:
	pci_free_irq_vectors(pdev);
err_cmd_uninit:
	hclge_destroy_cmd_queue(&hdev->hw);
err_pci_uninit:
	pci_clear_master(pdev);
	pci_release_regions(pdev);
err_pci_init:
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
err_hclge_dev:
out:
	return ret;
}

@@ -5586,6 +5642,7 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
	set_bit(HCLGE_STATE_DOWN, &hdev->state);

	hclge_stats_clear(hdev);
	memset(hdev->vlan_table, 0, sizeof(hdev->vlan_table));

	ret = hclge_cmd_init(hdev);
	if (ret) {
@@ -6203,7 +6260,7 @@ static const struct hnae3_ae_ops hclge_ops = {
	.get_fw_version = hclge_get_fw_version,
	.get_mdix_mode = hclge_get_mdix_mode,
	.enable_vlan_filter = hclge_enable_vlan_filter,
	.set_vlan_filter = hclge_set_port_vlan_filter,
	.set_vlan_filter = hclge_set_vlan_filter,
	.set_vf_vlan_filter = hclge_set_vf_vlan_filter,
	.enable_hw_strip_rxvtag = hclge_en_hw_strip_rxvtag,
	.reset_event = hclge_reset_event,
+12 −8
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/phy.h>
#include <linux/if_vlan.h>

#include "hclge_cmd.h"
#include "hnae3.h"

@@ -406,9 +408,9 @@ struct hclge_mac_stats {
	u64 mac_tx_1519_2047_oct_pkt_num;
	u64 mac_tx_2048_4095_oct_pkt_num;
	u64 mac_tx_4096_8191_oct_pkt_num;
	u64 mac_tx_8192_12287_oct_pkt_num; /* valid for GE MAC only */
	u64 mac_tx_8192_9216_oct_pkt_num; /* valid for LGE & CGE MAC only */
	u64 mac_tx_9217_12287_oct_pkt_num; /* valid for LGE & CGE MAC */
	u64 rsv0;
	u64 mac_tx_8192_9216_oct_pkt_num;
	u64 mac_tx_9217_12287_oct_pkt_num;
	u64 mac_tx_12288_16383_oct_pkt_num;
	u64 mac_tx_1519_max_good_oct_pkt_num;
	u64 mac_tx_1519_max_bad_oct_pkt_num;
@@ -433,9 +435,9 @@ struct hclge_mac_stats {
	u64 mac_rx_1519_2047_oct_pkt_num;
	u64 mac_rx_2048_4095_oct_pkt_num;
	u64 mac_rx_4096_8191_oct_pkt_num;
	u64 mac_rx_8192_12287_oct_pkt_num;/* valid for GE MAC only */
	u64 mac_rx_8192_9216_oct_pkt_num; /* valid for LGE & CGE MAC only */
	u64 mac_rx_9217_12287_oct_pkt_num; /* valid for LGE & CGE MAC only */
	u64 rsv1;
	u64 mac_rx_8192_9216_oct_pkt_num;
	u64 mac_rx_9217_12287_oct_pkt_num;
	u64 mac_rx_12288_16383_oct_pkt_num;
	u64 mac_rx_1519_max_good_oct_pkt_num;
	u64 mac_rx_1519_max_bad_oct_pkt_num;
@@ -471,6 +473,7 @@ struct hclge_vlan_type_cfg {
	u16 tx_in_vlan_type;
};

#define HCLGE_VPORT_NUM 256
struct hclge_dev {
	struct pci_dev *pdev;
	struct hnae3_ae_dev *ae_dev;
@@ -562,6 +565,7 @@ struct hclge_dev {

	u64 rx_pkts_for_led;
	u64 tx_pkts_for_led;
	unsigned long vlan_table[VLAN_N_VID][BITS_TO_LONGS(HCLGE_VPORT_NUM)];
};

/* VPort level vlan tag configuration for TX direction */
@@ -646,8 +650,8 @@ static inline int hclge_get_queue_id(struct hnae3_queue *queue)
}

int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex);
int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid,
			     bool is_kill, u16 vlan, u8 qos, __be16 proto);
int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
			  u16 vlan_id, bool is_kill);

int hclge_buffer_alloc(struct hclge_dev *hdev);
int hclge_rss_init_hw(struct hclge_dev *hdev);
+3 −4
Original line number Diff line number Diff line
@@ -264,19 +264,18 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
				 struct hclge_mbx_vf_to_pf_cmd *mbx_req,
				 bool gen_resp)
{
	struct hclge_dev *hdev = vport->back;
	int status = 0;

	if (mbx_req->msg[1] == HCLGE_MBX_VLAN_FILTER) {
		struct hnae3_handle *handle = &vport->nic;
		u16 vlan, proto;
		bool is_kill;

		is_kill = !!mbx_req->msg[2];
		memcpy(&vlan, &mbx_req->msg[3], sizeof(vlan));
		memcpy(&proto, &mbx_req->msg[5], sizeof(proto));
		status = hclge_set_vf_vlan_common(hdev, vport->vport_id,
						  is_kill, vlan, 0,
						  cpu_to_be16(proto));
		status = hclge_set_vlan_filter(handle, cpu_to_be16(proto),
					       vlan, is_kill);
	}

	if (gen_resp)
Loading