Commit 72ef908b authored by Luo bin's avatar Luo bin Committed by Jakub Kicinski
Browse files

hinic: add three net_device_ops of vf



adds ndo_set_vf_rate/ndo_set_vf_spoofchk/ndo_set_vf_link_state
to configure netdev of virtual function

Signed-off-by: default avatarLuo bin <luobin9@huawei.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 0d5c56a2
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -849,6 +849,25 @@ err_init_cmdq:
	return err;
}

static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth)
{
	struct hinic_cmd_hw_ioctxt hw_ioctxt = { 0 };
	struct hinic_pfhwdev *pfhwdev;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);

	hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_ENABLE;
	hw_ioctxt.cmdq_depth = (u8)ilog2(cmdq_depth);

	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				 HINIC_COMM_CMD_HWCTXT_SET,
				 &hw_ioctxt, sizeof(hw_ioctxt), NULL,
				 NULL, HINIC_MGMT_MSG_SYNC);
}

/**
 * hinic_init_cmdqs - init all cmdqs
 * @cmdqs: cmdqs to init
@@ -899,8 +918,18 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,

	hinic_ceq_register_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ, cmdqs,
			      cmdq_ceq_handler);

	err = hinic_set_cmdq_depth(hwdev, CMDQ_DEPTH);
	if (err) {
		dev_err(&hwif->pdev->dev, "Failed to set cmdq depth\n");
		goto err_set_cmdq_depth;
	}

	return 0;

err_set_cmdq_depth:
	hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);

err_cmdq_ctxt:
	hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
			    HINIC_MAX_CMDQ_TYPES);
+31 −4
Original line number Diff line number Diff line
@@ -44,10 +44,6 @@ enum io_status {
	IO_RUNNING = 1,
};

enum hw_ioctxt_set_cmdq_depth {
	HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT,
};

/**
 * get_capability - convert device capabilities to NIC capabilities
 * @hwdev: the HW device to set and convert device capabilities for
@@ -667,6 +663,32 @@ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
	hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
}

static int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
{
	struct hinic_cmd_l2nic_reset l2nic_reset = {0};
	u16 out_size = sizeof(l2nic_reset);
	struct hinic_pfhwdev *pfhwdev;
	int err;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	l2nic_reset.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	/* 0 represents standard l2nic reset flow */
	l2nic_reset.reset_flag = 0;

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_L2NIC_RESET, &l2nic_reset,
				sizeof(l2nic_reset), &l2nic_reset,
				&out_size, HINIC_MGMT_MSG_SYNC);
	if (err || !out_size || l2nic_reset.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to reset L2NIC resources, err: %d, status: 0x%x, out_size: 0x%x\n",
			err, l2nic_reset.status, out_size);
		return -EIO;
	}

	return 0;
}

/**
 * hinic_init_hwdev - Initialize the NIC HW
 * @pdev: the NIC pci device
@@ -729,6 +751,10 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
		goto err_init_pfhwdev;
	}

	err = hinic_l2nic_reset(hwdev);
	if (err)
		goto err_l2nic_reset;

	err = get_dev_cap(hwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to get device capabilities\n");
@@ -759,6 +785,7 @@ err_resources_state:
err_init_fw_ctxt:
	hinic_vf_func_free(hwdev);
err_vf_func_init:
err_l2nic_reset:
err_dev_cap:
	free_pfhwdev(pfhwdev);

+21 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#define HINIC_PF_SET_VF_ALREADY				0x4
#define HINIC_MGMT_STATUS_EXIST				0x6
#define HINIC_MGMT_CMD_UNSUPPORTED			0xFF

struct hinic_cap {
	u16     max_qps;
@@ -33,6 +34,11 @@ struct hinic_cap {
	u16     max_vf_qps;
};

enum hw_ioctxt_set_cmdq_depth {
	HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT,
	HW_IOCTXT_SET_CMDQ_DEPTH_ENABLE,
};

enum hinic_port_cmd {
	HINIC_PORT_CMD_VF_REGISTER = 0x0,
	HINIC_PORT_CMD_VF_UNREGISTER = 0x1,
@@ -86,12 +92,16 @@ enum hinic_port_cmd {

	HINIC_PORT_CMD_FWCTXT_INIT      = 69,

	HINIC_PORT_CMD_ENABLE_SPOOFCHK = 78,

	HINIC_PORT_CMD_GET_MGMT_VERSION = 88,

	HINIC_PORT_CMD_SET_FUNC_STATE   = 93,

	HINIC_PORT_CMD_GET_GLOBAL_QPN   = 102,

	HINIC_PORT_CMD_SET_VF_RATE = 105,

	HINIC_PORT_CMD_SET_VF_VLAN	= 106,

	HINIC_PORT_CMD_CLR_VF_VLAN,
@@ -107,6 +117,8 @@ enum hinic_port_cmd {
	HINIC_PORT_CMD_GET_CAP          = 170,

	HINIC_PORT_CMD_SET_LRO_TIMER	= 244,

	HINIC_PORT_CMD_SET_VF_MAX_MIN_RATE = 249,
};

enum hinic_ucode_cmd {
@@ -247,6 +259,15 @@ struct hinic_cmd_hw_ci {
	u64     ci_addr;
};

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

	u16	func_id;
	u16	reset_flag;
};

struct hinic_hwdev {
	struct hinic_hwif               *hwif;
	struct msix_entry               *msix_entries;
+27 −5
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/delay.h>

#include "hinic_hw_csr.h"
#include "hinic_hw_if.h"
@@ -18,6 +19,8 @@

#define VALID_MSIX_IDX(attr, msix_index) ((msix_index) < (attr)->num_irqs)

#define WAIT_HWIF_READY_TIMEOUT	10000

/**
 * hinic_msix_attr_set - set message attribute for msix entry
 * @hwif: the HW interface of a pci function device
@@ -187,18 +190,37 @@ void hinic_set_msix_state(struct hinic_hwif *hwif, u16 msix_idx,
 **/
static int hwif_ready(struct hinic_hwif *hwif)
{
	struct pci_dev *pdev = hwif->pdev;
	u32 addr, attr1;

	addr   = HINIC_CSR_FUNC_ATTR1_ADDR;
	attr1  = hinic_hwif_read_reg(hwif, addr);

	if (!HINIC_FA1_GET(attr1, INIT_STATUS)) {
		dev_err(&pdev->dev, "hwif status is not ready\n");
		return -EFAULT;
	if (!HINIC_FA1_GET(attr1, MGMT_INIT_STATUS))
		return -EBUSY;

	if (HINIC_IS_VF(hwif)) {
		if (!HINIC_FA1_GET(attr1, PF_INIT_STATUS))
			return -EBUSY;
	}

	return 0;
}

static int wait_hwif_ready(struct hinic_hwif *hwif)
{
	unsigned long timeout = 0;

	do {
		if (!hwif_ready(hwif))
			return 0;

		usleep_range(999, 1000);
		timeout++;
	} while (timeout <= WAIT_HWIF_READY_TIMEOUT);

	dev_err(&hwif->pdev->dev, "Wait for hwif timeout\n");

	return -EBUSY;
}

/**
@@ -373,7 +395,7 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
		goto err_map_intr_bar;
	}

	err = hwif_ready(hwif);
	err = wait_hwif_ready(hwif);
	if (err) {
		dev_err(&pdev->dev, "HW interface is not ready\n");
		goto err_hwif_ready;
+4 −2
Original line number Diff line number Diff line
@@ -55,13 +55,15 @@
#define HINIC_FA1_IRQS_PER_FUNC_SHIFT                           20
#define HINIC_FA1_DMA_ATTR_PER_FUNC_SHIFT                       24
/* reserved members - off 27 */
#define HINIC_FA1_INIT_STATUS_SHIFT                             30
#define HINIC_FA1_MGMT_INIT_STATUS_SHIFT			30
#define HINIC_FA1_PF_INIT_STATUS_SHIFT				31

#define HINIC_FA1_AEQS_PER_FUNC_MASK                            0x3
#define HINIC_FA1_CEQS_PER_FUNC_MASK                            0x7
#define HINIC_FA1_IRQS_PER_FUNC_MASK                            0xF
#define HINIC_FA1_DMA_ATTR_PER_FUNC_MASK                        0x7
#define HINIC_FA1_INIT_STATUS_MASK                              0x1
#define HINIC_FA1_MGMT_INIT_STATUS_MASK                         0x1
#define HINIC_FA1_PF_INIT_STATUS_MASK				0x1

#define HINIC_FA1_GET(val, member)                              \
	(((val) >> HINIC_FA1_##member##_SHIFT) & HINIC_FA1_##member##_MASK)
Loading