Commit 4a61abb1 authored by Xue Chaojing's avatar Xue Chaojing Committed by David S. Miller
Browse files

net-next/hinic:add rx checksum offload for HiNIC



In order to improve performance, this patch adds rx checksum offload
for the HiNIC driver. Performance test(Iperf) shows more than 80%
improvement in TCP streams.

Signed-off-by: default avatarXue Chaojing <xuechaojing@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ebda9b46
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ enum hinic_port_cmd {

	HINIC_PORT_CMD_GET_LINK_STATE   = 24,

	HINIC_PORT_CMD_SET_RX_CSUM	= 26,

	HINIC_PORT_CMD_SET_PORT_STATE   = 41,

	HINIC_PORT_CMD_FWCTXT_INIT      = 69,
+4 −0
Original line number Diff line number Diff line
@@ -170,6 +170,10 @@

#define HINIC_RQ_CQE_STATUS_RXDONE_MASK         0x1

#define HINIC_RQ_CQE_STATUS_CSUM_ERR_SHIFT	0

#define HINIC_RQ_CQE_STATUS_CSUM_ERR_MASK	0xFFFFU

#define HINIC_RQ_CQE_STATUS_GET(val, member)    \
		(((val) >> HINIC_RQ_CQE_STATUS_##member##_SHIFT) & \
		 HINIC_RQ_CQE_STATUS_##member##_MASK)
+6 −1
Original line number Diff line number Diff line
@@ -806,7 +806,8 @@ static const struct net_device_ops hinic_netdev_ops = {
static void netdev_features_init(struct net_device *netdev)
{
	netdev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM |
			      NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
			      NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |
			      NETIF_F_RXCSUM;

	netdev->vlan_features = netdev->hw_features;

@@ -869,12 +870,16 @@ static int set_features(struct hinic_dev *nic_dev,
			netdev_features_t features, bool force_change)
{
	netdev_features_t changed = force_change ? ~0 : pre_features ^ features;
	u32 csum_en = HINIC_RX_CSUM_OFFLOAD_EN;
	int err = 0;

	if (changed & NETIF_F_TSO)
		err = hinic_port_set_tso(nic_dev, (features & NETIF_F_TSO) ?
					 HINIC_TSO_ENABLE : HINIC_TSO_DISABLE);

	if (changed & NETIF_F_RXCSUM)
		err = hinic_set_rx_csum_offload(nic_dev, csum_en);

	return err;
}

+28 −0
Original line number Diff line number Diff line
@@ -409,3 +409,31 @@ int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)

	return 0;
}

int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
{
	struct hinic_checksum_offload rx_csum_cfg = {0};
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size;
	int err;

	if (!hwdev)
		return -EINVAL;

	rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rx_csum_cfg.rx_csum_offload = en;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
				 &rx_csum_cfg, sizeof(rx_csum_cfg),
				 &rx_csum_cfg, &out_size);
	if (err || !out_size || rx_csum_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set rx csum offload, ret = %d\n",
			rx_csum_cfg.status);
		return -EINVAL;
	}

	return 0;
}
+10 −0
Original line number Diff line number Diff line
@@ -183,6 +183,15 @@ struct hinic_tso_config {
	u8	resv2[3];
};

struct hinic_checksum_offload {
	u8	status;
	u8	version;
	u8	rsvd0[6];

	u16	func_id;
	u16	rsvd1;
	u32	rx_csum_offload;
};
int hinic_port_add_mac(struct hinic_dev *nic_dev, const u8 *addr,
		       u16 vlan_id);

@@ -213,4 +222,5 @@ int hinic_port_get_cap(struct hinic_dev *nic_dev,

int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state);

int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en);
#endif
Loading