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

Commit 2f514c52 authored by Jitendra Kalsaria's avatar Jitendra Kalsaria Committed by David S. Miller
Browse files

qlcnic: Support for 16 virtual NIC functions.



Extend virtual NIC functions from 8 to 16 for 84xx adapter.

Signed-off-by: default avatarJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 154d0c81
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -115,6 +115,10 @@ enum qlcnic_queue_type {
#define QLCNIC_VNIC_MODE	0xFF
#define QLCNIC_DEFAULT_MODE	0x0

/* Virtual NIC function count */
#define QLC_DEFAULT_VNIC_COUNT	8
#define QLC_84XX_VNIC_COUNT	16

/*
 * Following are the states of the Phantom. Phantom will set them and
 * Host will read to check if the fields are correct.
@@ -374,7 +378,7 @@ struct qlcnic_rx_buffer {

#define QLCNIC_INTR_DEFAULT			0x04
#define QLCNIC_CONFIG_INTR_COALESCE		3
#define QLCNIC_DEV_INFO_SIZE			1
#define QLCNIC_DEV_INFO_SIZE			2

struct qlcnic_nic_intr_coalesce {
	u8	type;
@@ -462,8 +466,10 @@ struct qlcnic_hardware_context {
	u16 max_rx_ques;
	u16 max_mtu;
	u32 msg_enable;
	u16 act_pci_func;
	u16 total_nic_func;
	u16 max_pci_func;
	u32 max_vnic_func;
	u32 total_pci_func;

	u32 capabilities;
	u32 extra_capability[3];
@@ -857,7 +863,7 @@ struct qlcnic_mac_vlan_list {
#define QLCNIC_FW_CAP2_HW_LRO_IPV6		BIT_3
#define QLCNIC_FW_CAPABILITY_SET_DRV_VER	BIT_5
#define QLCNIC_FW_CAPABILITY_2_BEACON		BIT_7
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG	BIT_8
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG	BIT_9

/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT			1
@@ -1638,6 +1644,9 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *,
				struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *);
int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8);
int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *,
			     u16 *);

/*
 * QLOGIC Board information
@@ -2150,4 +2159,12 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter)

	return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false;
}

static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
{
	if (qlcnic_84xx_check(adapter))
		return QLC_84XX_VNIC_COUNT;
	else
		return QLC_DEFAULT_VNIC_COUNT;
}
#endif				/* __QLCNIC_H_ */
+44 −6
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

#define RSS_HASHTYPE_IP_TCP		0x3
#define QLC_83XX_FW_MBX_CMD		0
#define QLC_SKIP_INACTIVE_PCI_REGS	7

static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
	{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
@@ -34,7 +35,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
	{QLCNIC_CMD_READ_MAX_MTU, 4, 2},
	{QLCNIC_CMD_READ_MAX_LRO, 4, 2},
	{QLCNIC_CMD_MAC_ADDRESS, 4, 3},
	{QLCNIC_CMD_GET_PCI_INFO, 1, 66},
	{QLCNIC_CMD_GET_PCI_INFO, 1, 129},
	{QLCNIC_CMD_GET_NIC_INFO, 2, 19},
	{QLCNIC_CMD_SET_NIC_INFO, 32, 1},
	{QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
@@ -637,7 +638,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	u16 act_pci_fn = ahw->act_pci_func;
	u16 act_pci_fn = ahw->total_nic_func;
	u16 count;

	ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
@@ -2293,11 +2294,37 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
	return err;
}

int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
			     u16 *nic, u16 *fcoe, u16 *iscsi)
{
	struct device *dev = &adapter->pdev->dev;
	int err = 0;

	switch (type) {
	case QLCNIC_TYPE_NIC:
		(*nic)++;
		break;
	case QLCNIC_TYPE_FCOE:
		(*fcoe)++;
		break;
	case QLCNIC_TYPE_ISCSI:
		(*iscsi)++;
		break;
	default:
		dev_err(dev, "%s: Unknown PCI type[%x]\n",
			__func__, type);
		err = -EIO;
	}

	return err;
}

int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
			     struct qlcnic_pci_info *pci_info)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct device *dev = &adapter->pdev->dev;
	u16 nic = 0, fcoe = 0, iscsi = 0;
	struct qlcnic_cmd_args cmd;
	int i, err = 0, j = 0;
	u32 temp;
@@ -2308,16 +2335,20 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,

	err = qlcnic_issue_cmd(adapter, &cmd);

	ahw->act_pci_func = 0;
	ahw->total_nic_func = 0;
	if (err == QLCNIC_RCODE_SUCCESS) {
		ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
		for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
		for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
			pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
			pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
			i++;
			if (!pci_info->active) {
				i += QLC_SKIP_INACTIVE_PCI_REGS;
				continue;
			}
			pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
			if (pci_info->type == QLCNIC_TYPE_NIC)
				ahw->act_pci_func++;
			err = qlcnic_get_pci_func_type(adapter, pci_info->type,
						       &nic, &fcoe, &iscsi);
			temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
			pci_info->default_port = temp;
			i++;
@@ -2335,6 +2366,13 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
		err = -EIO;
	}

	ahw->total_nic_func = nic;
	ahw->total_pci_func = nic + fcoe + iscsi;
	if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
		dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
			__func__, ahw->total_nic_func, ahw->total_pci_func);
		err = -EIO;
	}
	qlcnic_free_mbx_args(&cmd);

	return err;
+2 −2
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)

		npar = adapter->npars;

		for (i = 0; i < ahw->act_pci_func; i++, npar++) {
		for (i = 0; i < ahw->total_nic_func; i++, npar++) {
			dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n",
				 npar->pci_func, npar->active, npar->type,
				 npar->phy_port, npar->min_bw, npar->max_bw,
@@ -115,7 +115,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
		}

		dev_info(dev, "Max functions = %d, active functions = %d\n",
			 ahw->max_pci_func, ahw->act_pci_func);
			 ahw->max_pci_func, ahw->total_nic_func);

		if (qlcnic_83xx_set_vnic_opmode(adapter))
			return err;
+25 −24
Original line number Diff line number Diff line
@@ -91,18 +91,6 @@ void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd)
	cmd->rsp.arg = NULL;
}

static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
{
	int i;

	for (i = 0; i < adapter->ahw->act_pci_func; i++) {
		if (adapter->npars[i].pci_func == pci_func)
			return i;
	}

	return -1;
}

static u32
qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
{
@@ -966,13 +954,15 @@ int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter,
int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
			     struct qlcnic_pci_info *pci_info)
{
	int err = 0, i;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	size_t npar_size = sizeof(struct qlcnic_pci_info_le);
	size_t pci_size = npar_size * ahw->max_vnic_func;
	u16 nic = 0, fcoe = 0, iscsi = 0;
	struct qlcnic_pci_info_le *npar;
	struct qlcnic_cmd_args cmd;
	dma_addr_t pci_info_dma_t;
	struct qlcnic_pci_info_le *npar;
	void *pci_info_addr;
	size_t npar_size = sizeof(struct qlcnic_pci_info_le);
	size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;
	int err = 0, i;

	pci_info_addr = dma_zalloc_coherent(&adapter->pdev->dev, pci_size,
					    &pci_info_dma_t, GFP_KERNEL);
@@ -989,14 +979,16 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
	cmd.req.arg[3] = pci_size;
	err = qlcnic_issue_cmd(adapter, &cmd);

	adapter->ahw->act_pci_func = 0;
	ahw->total_nic_func = 0;
	if (err == QLCNIC_RCODE_SUCCESS) {
		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
		for (i = 0; i < ahw->max_vnic_func; i++, npar++, pci_info++) {
			pci_info->id = le16_to_cpu(npar->id);
			pci_info->active = le16_to_cpu(npar->active);
			if (!pci_info->active)
				continue;
			pci_info->type = le16_to_cpu(npar->type);
			if (pci_info->type == QLCNIC_TYPE_NIC)
				adapter->ahw->act_pci_func++;
			err = qlcnic_get_pci_func_type(adapter, pci_info->type,
						       &nic, &fcoe, &iscsi);
			pci_info->default_port =
				le16_to_cpu(npar->default_port);
			pci_info->tx_min_bw =
@@ -1011,6 +1003,14 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
		err = -EIO;
	}

	ahw->total_nic_func = nic;
	ahw->total_pci_func = nic + fcoe + iscsi;
	if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
		dev_err(&adapter->pdev->dev,
			"%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
			__func__, ahw->total_nic_func, ahw->total_pci_func);
		err = -EIO;
	}
	qlcnic_free_mbx_args(&cmd);
out_free_dma:
	dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
@@ -1203,7 +1203,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
	esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL;
	esw_stats->context_id = eswitch;

	for (i = 0; i < adapter->ahw->act_pci_func; i++) {
	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
		if (adapter->npars[i].phy_port != eswitch)
			continue;

@@ -1236,15 +1236,16 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
		const u8 port, const u8 rx_tx)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_cmd_args cmd;
	int err;
	u32 arg1;
	struct qlcnic_cmd_args cmd;

	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
	if (ahw->op_mode != QLCNIC_MGMT_FUNC)
		return -EIO;

	if (func_esw == QLCNIC_STATS_PORT) {
		if (port >= QLCNIC_MAX_PCI_FUNC)
		if (port >= ahw->max_vnic_func)
			goto err_ret;
	} else if (func_esw == QLCNIC_STATS_ESWITCH) {
		if (port >= QLCNIC_NIU_MAX_XG_PORTS)
+4 −1
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ static const u32 ext_diag_registers[] = {
	-1
};

#define QLCNIC_MGMT_API_VERSION	2
#define QLCNIC_MGMT_API_VERSION	3
#define QLCNIC_ETHTOOL_REGS_VER	4

static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
@@ -519,6 +519,9 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
	regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
	regs_buff[1] = QLCNIC_MGMT_API_VERSION;

	if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
		regs_buff[2] = adapter->ahw->max_vnic_func;

	if (qlcnic_82xx_check(adapter))
		i = qlcnic_82xx_get_registers(adapter, regs_buff);
	else
Loading