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

Commit 35dafcb0 authored by Sony Chacko's avatar Sony Chacko Committed by David S. Miller
Browse files

qlcnic: Add support for per port eswitch configuration



There is an embedded switch per physical port on the adapter.
Add support for enabling and disabling the embedded switch
on per port basis.

Signed-off-by: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7000078a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -837,6 +837,7 @@ struct qlcnic_mac_list_s {
#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

/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT			1
@@ -1184,6 +1185,7 @@ struct qlcnic_pci_info {
};

struct qlcnic_npar_info {
	bool	eswitch_status;
	u16	pvid;
	u16	min_bw;
	u16	max_bw;
+1 −1
Original line number Diff line number Diff line
@@ -2331,7 +2331,7 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
					 pci_info->tx_max_bw, pci_info->mac);
		}
		if (ahw->op_mode == QLCNIC_MGMT_FUNC)
			dev_info(dev, "Max vNIC functions = %d, active vNIC functions = %d\n",
			dev_info(dev, "Max functions = %d, active functions = %d\n",
				 ahw->max_pci_func, ahw->act_pci_func);

	} else {
+2 −0
Original line number Diff line number Diff line
@@ -411,6 +411,7 @@ enum qlcnic_83xx_states {
#define QLC_83XX_GET_HW_LRO_CAPABILITY(val)		(val & 0x400)
#define QLC_83XX_GET_VLAN_ALIGN_CAPABILITY(val)	(val & 0x4000)
#define QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(val)	(val & 0x20000)
#define QLC_83XX_ESWITCH_CAPABILITY			BIT_23
#define QLC_83XX_VIRTUAL_NIC_MODE			0xFF
#define QLC_83XX_DEFAULT_MODE				0x0
#define QLC_83XX_SRIOV_MODE				0x1
@@ -625,6 +626,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
int qlcnic_83xx_get_vnic_vport_info(struct qlcnic_adapter *,
				    struct qlcnic_info *, u8);
int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *, int);

void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
+21 −46
Original line number Diff line number Diff line
@@ -2003,36 +2003,6 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter)
	return 0;
}

/**
* qlcnic_83xx_config_default_opmode
*
* @adapter: adapter structure
*
* Configure default driver operating mode
*
* Returns: Error code or Success(0)
* */
int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *adapter)
{
	u32 op_mode;
	struct qlcnic_hardware_context *ahw = adapter->ahw;

	qlcnic_get_func_no(adapter);
	op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE);

	if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state))
		op_mode = QLC_83XX_DEFAULT_OPMODE;

	if (op_mode == QLC_83XX_DEFAULT_OPMODE) {
		adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
	} else {
		return -EIO;
	}

	return 0;
}

int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
{
	int err;
@@ -2052,26 +2022,26 @@ int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
	ahw->max_mac_filters = nic_info.max_mac_filters;
	ahw->max_mtu = nic_info.max_mtu;

	/* VNIC mode is detected by BIT_23 in capabilities. This bit is also
	 * set in case device is SRIOV capable. VNIC and SRIOV are mutually
	 * exclusive. So in case of sriov capable device load driver in
	 * default mode
	/* eSwitch capability indicates vNIC mode.
	 * vNIC and SRIOV are mutually exclusive operational modes.
	 * If SR-IOV capability is detected, SR-IOV physical function
	 * will get initialized in default mode.
	 * SR-IOV virtual function initialization follows a
	 * different code path and opmode.
	 * SRIOV mode has precedence over vNIC mode.
	 */
	if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state)) {
		ahw->nic_mode = QLC_83XX_DEFAULT_MODE;
		return ahw->nic_mode;
	}
	if (test_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state))
		return QLC_83XX_DEFAULT_OPMODE;

	if (ahw->capabilities & BIT_23)
		ahw->nic_mode = QLC_83XX_VIRTUAL_NIC_MODE;
	else
		ahw->nic_mode = QLC_83XX_DEFAULT_MODE;
	if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
		return QLC_83XX_VIRTUAL_NIC_MODE;

	return ahw->nic_mode;
	return QLC_83XX_DEFAULT_OPMODE;
}

int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	int ret;

	ret = qlcnic_83xx_get_nic_configuration(adapter);
@@ -2079,10 +2049,15 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
		return -EIO;

	if (ret == QLC_83XX_VIRTUAL_NIC_MODE) {
		ahw->nic_mode = QLC_83XX_VIRTUAL_NIC_MODE;
		if (qlcnic_83xx_config_vnic_opmode(adapter))
			return -EIO;
	} else if (ret == QLC_83XX_DEFAULT_MODE) {
		if (qlcnic_83xx_config_default_opmode(adapter))

	} else if (ret == QLC_83XX_DEFAULT_OPMODE) {
		ahw->nic_mode = QLC_83XX_DEFAULT_MODE;
		adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
	} else {
		return -EIO;
	}

+39 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
		return -EIO;
	}

	if (ahw->capabilities & BIT_23)
	if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
		adapter->flags |= QLCNIC_ESWITCH_ENABLED;
	else
		adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
@@ -239,3 +239,41 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)

	return 0;
}

static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
					     int func, int *port_id)
{
	struct qlcnic_info nic_info;
	int err = 0;

	memset(&nic_info, 0, sizeof(struct qlcnic_info));

	err = qlcnic_get_nic_info(adapter, &nic_info, func);
	if (err)
		return err;

	if (nic_info.capabilities & QLC_83XX_ESWITCH_CAPABILITY)
		*port_id = nic_info.phys_port;
	else
		err = -EIO;

	return err;
}

int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *adapter, int func)
{
	int id, err = 0;

	err = qlcnic_83xx_get_eswitch_port_info(adapter, func, &id);
	if (err)
		return err;

	if (!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
		if (!qlcnic_enable_eswitch(adapter, id, 1))
			adapter->eswitch[id].flags |= QLCNIC_SWITCH_ENABLE;
		else
			err = -EIO;
	}

	return err;
}
Loading