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

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

Merge branch 'hns3-next'



Salil Mehta says:

====================
Misc. bug fixes and cleanup for HNS3 driver

This patch-set presents miscellaneous bug fixes and cleanups found
during internal review, system testing and cleanup.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 52f8560e eddf0462
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -285,3 +285,4 @@ EXPORT_SYMBOL(hnae3_unregister_ae_dev);
MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
MODULE_VERSION(HNAE3_MOD_VERSION);
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#include <linux/pci.h>
#include <linux/types.h>

#define HNAE3_MOD_VERSION "1.0"

/* Device IDs */
#define HNAE3_DEV_ID_GE				0xA220
#define HNAE3_DEV_ID_25GE			0xA221
+8 −103
Original line number Diff line number Diff line
@@ -1579,7 +1579,7 @@ static void hns3_remove(struct pci_dev *pdev)
 * Enable or change the number of VFs. Called when the user updates the number
 * of VFs in sysfs.
 **/
int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
static int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
{
	int ret;

@@ -1592,6 +1592,8 @@ int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
		ret = pci_enable_sriov(pdev, num_vfs);
		if (ret)
			dev_err(&pdev->dev, "SRIOV enable failed %d\n", ret);
		else
			return num_vfs;
	} else if (!pci_vfs_assigned(pdev)) {
		pci_disable_sriov(pdev);
	} else {
@@ -1952,106 +1954,6 @@ hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring, int cleand_count)
	writel_relaxed(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG);
}

/* hns3_nic_get_headlen - determine size of header for LRO/GRO
 * @data: pointer to the start of the headers
 * @max: total length of section to find headers in
 *
 * This function is meant to determine the length of headers that will
 * be recognized by hardware for LRO, GRO, and RSC offloads.  The main
 * motivation of doing this is to only perform one pull for IPv4 TCP
 * packets so that we can do basic things like calculating the gso_size
 * based on the average data per packet.
 */
static unsigned int hns3_nic_get_headlen(unsigned char *data, u32 flag,
					 unsigned int max_size)
{
	unsigned char *network;
	u8 hlen;

	/* This should never happen, but better safe than sorry */
	if (max_size < ETH_HLEN)
		return max_size;

	/* Initialize network frame pointer */
	network = data;

	/* Set first protocol and move network header forward */
	network += ETH_HLEN;

	/* Handle any vlan tag if present */
	if (hnae_get_field(flag, HNS3_RXD_VLAN_M, HNS3_RXD_VLAN_S)
		== HNS3_RX_FLAG_VLAN_PRESENT) {
		if ((typeof(max_size))(network - data) > (max_size - VLAN_HLEN))
			return max_size;

		network += VLAN_HLEN;
	}

	/* Handle L3 protocols */
	if (hnae_get_field(flag, HNS3_RXD_L3ID_M, HNS3_RXD_L3ID_S)
		== HNS3_RX_FLAG_L3ID_IPV4) {
		if ((typeof(max_size))(network - data) >
		    (max_size - sizeof(struct iphdr)))
			return max_size;

		/* Access ihl as a u8 to avoid unaligned access on ia64 */
		hlen = (network[0] & 0x0F) << 2;

		/* Verify hlen meets minimum size requirements */
		if (hlen < sizeof(struct iphdr))
			return network - data;

		/* Record next protocol if header is present */
	} else if (hnae_get_field(flag, HNS3_RXD_L3ID_M, HNS3_RXD_L3ID_S)
		== HNS3_RX_FLAG_L3ID_IPV6) {
		if ((typeof(max_size))(network - data) >
		    (max_size - sizeof(struct ipv6hdr)))
			return max_size;

		/* Record next protocol */
		hlen = sizeof(struct ipv6hdr);
	} else {
		return network - data;
	}

	/* Relocate pointer to start of L4 header */
	network += hlen;

	/* Finally sort out TCP/UDP */
	if (hnae_get_field(flag, HNS3_RXD_L4ID_M, HNS3_RXD_L4ID_S)
		== HNS3_RX_FLAG_L4ID_TCP) {
		if ((typeof(max_size))(network - data) >
		    (max_size - sizeof(struct tcphdr)))
			return max_size;

		/* Access doff as a u8 to avoid unaligned access on ia64 */
		hlen = (network[12] & 0xF0) >> 2;

		/* Verify hlen meets minimum size requirements */
		if (hlen < sizeof(struct tcphdr))
			return network - data;

		network += hlen;
	} else if (hnae_get_field(flag, HNS3_RXD_L4ID_M, HNS3_RXD_L4ID_S)
		== HNS3_RX_FLAG_L4ID_UDP) {
		if ((typeof(max_size))(network - data) >
		    (max_size - sizeof(struct udphdr)))
			return max_size;

		network += sizeof(struct udphdr);
	}

	/* If everything has gone correctly network should be the
	 * data section of the packet and will be the end of the header.
	 * If not then it probably represents the end of the last recognized
	 * header.
	 */
	if ((typeof(max_size))(network - data) < max_size)
		return network - data;
	else
		return max_size;
}

static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
				struct hns3_enet_ring *ring, int pull_len,
				struct hns3_desc_cb *desc_cb)
@@ -2251,8 +2153,8 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
		ring->stats.seg_pkt_cnt++;
		u64_stats_update_end(&ring->syncp);

		pull_len = hns3_nic_get_headlen(va, l234info,
						HNS3_RX_HEAD_SIZE);
		pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE);

		memcpy(__skb_put(skb, pull_len), va,
		       ALIGN(pull_len, sizeof(long)));

@@ -3607,6 +3509,8 @@ static int __init hns3_init_module(void)

	client.ops = &client_ops;

	INIT_LIST_HEAD(&client.node);

	ret = hnae3_register_client(&client);
	if (ret)
		return ret;
@@ -3634,3 +3538,4 @@ MODULE_DESCRIPTION("HNS3: Hisilicon Ethernet Driver");
MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
MODULE_LICENSE("GPL");
MODULE_ALIAS("pci:hns-nic");
MODULE_VERSION(HNS3_MOD_VERSION);
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

#include "hnae3.h"

#define HNS3_MOD_VERSION "1.0"

extern const char hns3_driver_version[];

enum hns3_nic_state {
+7 −3
Original line number Diff line number Diff line
@@ -190,7 +190,11 @@ static int hclge_cmd_csq_done(struct hclge_hw *hw)

static bool hclge_is_special_opcode(u16 opcode)
{
	u16 spec_opcode[3] = {0x0030, 0x0031, 0x0032};
	/* these commands have several descriptors,
	 * and use the first one to save opcode and return value
	 */
	u16 spec_opcode[3] = {HCLGE_OPC_STATS_64_BIT,
		HCLGE_OPC_STATS_32_BIT, HCLGE_OPC_STATS_MAC};
	int i;

	for (i = 0; i < ARRAY_SIZE(spec_opcode); i++) {
@@ -381,9 +385,9 @@ int hclge_cmd_init(struct hclge_dev *hdev)

static void hclge_destroy_queue(struct hclge_cmq_ring *ring)
{
	spin_lock_bh(&ring->lock);
	spin_lock(&ring->lock);
	hclge_free_cmd_desc(ring);
	spin_unlock_bh(&ring->lock);
	spin_unlock(&ring->lock);
}

void hclge_destroy_cmd_queue(struct hclge_hw *hw)
Loading