Commit 295ba232 authored by Guangbin Huang's avatar Guangbin Huang Committed by David S. Miller
Browse files

net: hns3: add device version to replace pci revision



To better identify the device version, struct hnae3_handle adds a
member dev_version to replace pci revision. The dev_version consists
of hardware version and PCI revision. The hardware version is queried
from firmware by an existing firmware version query command.

Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 090bc03b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -34,6 +34,13 @@

#define HNAE3_MIN_VECTOR_NUM	2 /* first one for misc, another for IO */

/* Device version */
#define HNAE3_DEVICE_VERSION_V1   0x00020
#define HNAE3_DEVICE_VERSION_V2   0x00021
#define HNAE3_DEVICE_VERSION_V3   0x00030

#define HNAE3_PCI_REVISION_BIT_SIZE		8

/* Device IDs */
#define HNAE3_DEV_ID_GE				0xA220
#define HNAE3_DEV_ID_25GE			0xA221
@@ -235,6 +242,7 @@ struct hnae3_ae_dev {
	struct list_head node;
	u32 flag;
	unsigned long hw_err_reset_req;
	u32 dev_version;
	void *priv;
};

+7 −3
Original line number Diff line number Diff line
@@ -629,9 +629,11 @@ void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
{
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	struct hnae3_handle *h = priv->ae_handle;
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
	bool last_state;

	if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 &&
	    h->ae_algo->ops->enable_vlan_filter) {
		last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
		if (enable != last_state) {
			netdev_info(netdev,
@@ -2265,6 +2267,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	struct pci_dev *pdev = h->pdev;
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);

	netdev->priv_flags |= IFF_UNICAST_FLT;

@@ -2302,7 +2305,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
		NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
		NETIF_F_FRAGLIST;

	if (pdev->revision >= 0x21) {
	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
		netdev->hw_features |= NETIF_F_GRO_HW;
		netdev->features |= NETIF_F_GRO_HW;

@@ -2801,8 +2804,9 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
{
	struct hnae3_handle *handle = ring->tqp->handle;
	struct pci_dev *pdev = ring->tqp->handle->pdev;
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);

	if (pdev->revision == 0x20) {
	if (unlikely(ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)) {
		*vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
		if (!(*vlan_tag & VLAN_VID_MASK))
			*vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
+15 −6
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ static const struct hns3_stats hns3_rxq_stats[] = {
static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
{
	struct hnae3_handle *h = hns3_get_handle(ndev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
	bool vlan_filter_enable;
	int ret;

@@ -96,7 +97,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
		break;
	}

	if (ret || h->pdev->revision >= 0x21)
	if (ret || ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)
		return ret;

	if (en) {
@@ -147,6 +148,7 @@ static void hns3_lp_setup_skb(struct sk_buff *skb)

	struct net_device *ndev = skb->dev;
	struct hnae3_handle *handle;
	struct hnae3_ae_dev *ae_dev;
	unsigned char *packet;
	struct ethhdr *ethh;
	unsigned int i;
@@ -163,7 +165,8 @@ static void hns3_lp_setup_skb(struct sk_buff *skb)
	 * the purpose of mac or serdes selftest.
	 */
	handle = hns3_get_handle(ndev);
	if (handle->pdev->revision == 0x20)
	ae_dev = pci_get_drvdata(handle->pdev);
	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
		ethh->h_dest[5] += HNS3_NIC_LB_DST_MAC_ADDR;
	eth_zero_addr(ethh->h_source);
	ethh->h_proto = htons(ETH_P_ARP);
@@ -761,6 +764,7 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
				   const struct ethtool_link_ksettings *cmd)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
	const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
	int ret;

@@ -782,7 +786,7 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
		return phy_ethtool_ksettings_set(netdev->phydev, cmd);
	}

	if (handle->pdev->revision == 0x20)
	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
		return -EOPNOTSUPP;

	ret = hns3_check_ksettings_param(netdev, cmd);
@@ -846,11 +850,12 @@ static int hns3_set_rss(struct net_device *netdev, const u32 *indir,
			const u8 *key, const u8 hfunc)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);

	if (!h->ae_algo->ops->set_rss)
		return -EOPNOTSUPP;

	if ((h->pdev->revision == 0x20 &&
	if ((ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 &&
	     hfunc != ETH_RSS_HASH_TOP) || (hfunc != ETH_RSS_HASH_NO_CHANGE &&
	     hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR)) {
		netdev_err(netdev, "hash func not supported\n");
@@ -1404,11 +1409,13 @@ static int hns3_get_module_info(struct net_device *netdev,
#define HNS3_SFF_8636_V1_3 0x03

	struct hnae3_handle *handle = hns3_get_handle(netdev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
	const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
	struct hns3_sfp_type sfp_type;
	int ret;

	if (handle->pdev->revision == 0x20 || !ops->get_module_eeprom)
	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 ||
	    !ops->get_module_eeprom)
		return -EOPNOTSUPP;

	memset(&sfp_type, 0, sizeof(sfp_type));
@@ -1452,9 +1459,11 @@ static int hns3_get_module_eeprom(struct net_device *netdev,
				  struct ethtool_eeprom *ee, u8 *data)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
	const struct hnae3_ae_ops *ops = handle->ae_algo->ops;

	if (handle->pdev->revision == 0x20 || !ops->get_module_eeprom)
	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 ||
	    !ops->get_module_eeprom)
		return -EOPNOTSUPP;

	if (!ee->len)
+17 −13
Original line number Diff line number Diff line
@@ -330,9 +330,9 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
	return retval;
}

static enum hclge_cmd_status hclge_cmd_query_firmware_version(
		struct hclge_hw *hw, u32 *version)
static enum hclge_cmd_status hclge_cmd_query_version(struct hclge_dev *hdev)
{
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
	struct hclge_query_version_cmd *resp;
	struct hclge_desc desc;
	int ret;
@@ -340,9 +340,15 @@ static enum hclge_cmd_status hclge_cmd_query_firmware_version(
	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_FW_VER, 1);
	resp = (struct hclge_query_version_cmd *)desc.data;

	ret = hclge_cmd_send(hw, &desc, 1);
	if (!ret)
		*version = le32_to_cpu(resp->firmware);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		return ret;

	hdev->fw_version = le32_to_cpu(resp->firmware);

	ae_dev->dev_version = le32_to_cpu(resp->hardware) <<
					 HNAE3_PCI_REVISION_BIT_SIZE;
	ae_dev->dev_version |= hdev->pdev->revision;

	return ret;
}
@@ -402,7 +408,6 @@ static int hclge_firmware_compat_config(struct hclge_dev *hdev)

int hclge_cmd_init(struct hclge_dev *hdev)
{
	u32 version;
	int ret;

	spin_lock_bh(&hdev->hw.cmq.csq.lock);
@@ -431,22 +436,21 @@ int hclge_cmd_init(struct hclge_dev *hdev)
		goto err_cmd_init;
	}

	ret = hclge_cmd_query_firmware_version(&hdev->hw, &version);
	ret = hclge_cmd_query_version(hdev);
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"firmware version query failed %d\n", ret);
			"failed to query version ret=%d\n", ret);
		goto err_cmd_init;
	}
	hdev->fw_version = version;

	dev_info(&hdev->pdev->dev, "The firmware version is %lu.%lu.%lu.%lu\n",
		 hnae3_get_field(version, HNAE3_FW_VERSION_BYTE3_MASK,
		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
				 HNAE3_FW_VERSION_BYTE3_SHIFT),
		 hnae3_get_field(version, HNAE3_FW_VERSION_BYTE2_MASK,
		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
				 HNAE3_FW_VERSION_BYTE2_SHIFT),
		 hnae3_get_field(version, HNAE3_FW_VERSION_BYTE1_MASK,
		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
				 HNAE3_FW_VERSION_BYTE1_SHIFT),
		 hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK,
		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
				 HNAE3_FW_VERSION_BYTE0_SHIFT));

	/* ask the firmware to enable some features, driver can work without
+2 −1
Original line number Diff line number Diff line
@@ -364,7 +364,8 @@ struct hclge_rx_priv_buff_cmd {

struct hclge_query_version_cmd {
	__le32 firmware;
	__le32 firmware_rsv[5];
	__le32 hardware;
	__le32 rsv[4];
};

#define HCLGE_RX_PRIV_EN_B	15
Loading