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

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

qlcnic: update NIC partition interface routines



Refactor 82xx driver to support new adapter
Update routines to support variable number of NIC partitions

Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 22999798
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,7 @@ struct qlcnic_npar_info {
	u8	mac_anti_spoof;
	u8	promisc_mode;
	u8	offload_flags;
	u8      pci_func;
};

struct qlcnic_eswitch {
+32 −7
Original line number Diff line number Diff line
@@ -7,6 +7,18 @@

#include "qlcnic.h"

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)
{
@@ -817,11 +829,14 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
	qlcnic_issue_cmd(adapter, &cmd);
	err = cmd.rsp.cmd;

	adapter->ahw->act_pci_func = 0;
	if (err == QLCNIC_RCODE_SUCCESS) {
		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
			pci_info->id = le16_to_cpu(npar->id);
			pci_info->active = le16_to_cpu(npar->active);
			pci_info->type = le16_to_cpu(npar->type);
			if (pci_info->type == QLCNIC_TYPE_NIC)
				adapter->ahw->act_pci_func++;
			pci_info->default_port =
				le16_to_cpu(npar->default_port);
			pci_info->tx_min_bw =
@@ -1016,12 +1031,13 @@ 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 < QLCNIC_MAX_PCI_FUNC; i++) {
	for (i = 0; i < adapter->ahw->act_pci_func; i++) {
		if (adapter->npars[i].phy_port != eswitch)
			continue;

		memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
		if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
		if (qlcnic_get_port_stats(adapter, adapter->npars[i].pci_func,
					  rx_tx, &port_stats))
			continue;

		esw_stats->size = port_stats.size;
@@ -1120,7 +1136,7 @@ op_type = 1 for port vlan_id
int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
		struct qlcnic_esw_func_cfg *esw_cfg)
{
	int err = -EIO;
	int err = -EIO, index;
	u32 arg1, arg2 = 0;
	struct qlcnic_cmd_args cmd;
	u8 pci_func;
@@ -1128,7 +1144,10 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
		return err;
	pci_func = esw_cfg->pci_func;
	arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
	index = qlcnic_is_valid_nic_func(adapter, pci_func);
	if (index < 0)
		return err;
	arg1 = (adapter->npars[index].phy_port & BIT_0);
	arg1 |= (pci_func << 8);

	if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
@@ -1192,11 +1211,17 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
			struct qlcnic_esw_func_cfg *esw_cfg)
{
	u32 arg1, arg2;
	int index;
	u8 phy_port;
	if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
		phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
	else

	if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) {
		index = qlcnic_is_valid_nic_func(adapter, esw_cfg->pci_func);
		if (index < 0)
			return -EIO;
		phy_port = adapter->npars[index].phy_port;
	} else {
		phy_port = adapter->ahw->physical_port;
	}
	arg1 = phy_port;
	arg1 |= (esw_cfg->pci_func << 8);
	if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
+56 −41
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
static int qlcnic_vlan_rx_add(struct net_device *, u16);
static int qlcnic_vlan_rx_del(struct net_device *, u16);

#define QLCNIC_IS_TSO_CAPABLE(adapter)	\
	((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)

/*  PCI Device ID Table  */
#define ENTRY(device) \
	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
		iounmap(adapter->ahw->pci_base0);
}

static int
qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
	struct qlcnic_pci_info *pci_info;
	int i, ret = 0;
	int i, ret = 0, j = 0;
	u16 act_pci_func;
	u8 pfn;

	pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
	if (!pci_info)
		return -ENOMEM;

	ret = qlcnic_get_pci_info(adapter, pci_info);
	if (ret)
		goto err_pci_info;

	act_pci_func = adapter->ahw->act_pci_func;

	adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
				QLCNIC_MAX_PCI_FUNC, GFP_KERNEL);
				 act_pci_func, GFP_KERNEL);
	if (!adapter->npars) {
		ret = -ENOMEM;
		goto err_pci_info;
@@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
		goto err_npars;
	}

	ret = qlcnic_get_pci_info(adapter, pci_info);
	if (ret)
		goto err_eswitch;

	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
		pfn = pci_info[i].id;

		if (pfn >= QLCNIC_MAX_PCI_FUNC) {
			ret = QL_STATUS_INVALID_PARAM;
			goto err_eswitch;
		}
		adapter->npars[pfn].active = (u8)pci_info[i].active;
		adapter->npars[pfn].type = (u8)pci_info[i].type;
		adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port;
		adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
		adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;

		if (!pci_info[i].active ||
		    (pci_info[i].type != QLCNIC_TYPE_NIC))
			continue;

		adapter->npars[j].pci_func = pfn;
		adapter->npars[j].active = (u8)pci_info[i].active;
		adapter->npars[j].type = (u8)pci_info[i].type;
		adapter->npars[j].phy_port = (u8)pci_info[i].default_port;
		adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
		adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
		j++;
	}

	for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
@@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
	u32 ref_count;
	int i, ret = 1;
	u32 data = QLCNIC_MGMT_FUNC;
	void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
	struct qlcnic_hardware_context *ahw = adapter->ahw;

	/* If other drivers are not in use set their privilege level */
	ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
@@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
		goto err_lock;

	if (qlcnic_config_npars) {
		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
			id = i;
			if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
				id == adapter->ahw->pci_func)
		for (i = 0; i < ahw->act_pci_func; i++) {
			id = adapter->npars[i].pci_func;
			if (id == ahw->pci_func)
				continue;
			data |= (qlcnic_config_npars &
					QLC_DEV_SET_DRV(0xf, id));
		}
	} else {
		data = readl(priv_op);
		data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) |
		data = QLCRD32(adapter, QLCNIC_DRV_OP_MODE);
		data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_func)) |
			(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
			adapter->ahw->pci_func));
					 ahw->pci_func));
	}
	writel(data, priv_op);
	QLCWR32(adapter, QLCNIC_DRV_OP_MODE, data);
	qlcnic_api_unlock(adapter);
err_lock:
	return ret;
@@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
	int err;
	struct qlcnic_info nic_info;

	memset(&nic_info, 0, sizeof(struct qlcnic_info));
	err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
	if (err)
		return err;
@@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
	return err;
}

static int
qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
{
	struct qlcnic_esw_func_cfg esw_cfg;
	struct qlcnic_npar_info *npar;
@@ -808,16 +820,16 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
	if (adapter->need_fw_reset)
		return 0;

	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
		if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
			continue;
	for (i = 0; i < adapter->ahw->act_pci_func; i++) {
		memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
		esw_cfg.pci_func = i;
		esw_cfg.offload_flags = BIT_0;
		esw_cfg.pci_func = adapter->npars[i].pci_func;
		esw_cfg.mac_override = BIT_0;
		esw_cfg.promisc_mode = BIT_0;
		if (adapter->ahw->capabilities  & QLCNIC_FW_CAPABILITY_TSO)
		if (qlcnic_82xx_check(adapter)) {
			esw_cfg.offload_flags = BIT_0;
			if (QLCNIC_IS_TSO_CAPABLE(adapter))
				esw_cfg.offload_flags |= (BIT_1 | BIT_2);
		}
		if (qlcnic_config_switch_port(adapter, &esw_cfg))
			return -EIO;
		npar = &adapter->npars[i];
@@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
	return 0;
}

static int
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{
	int i, err;
	struct qlcnic_npar_info *npar;
	struct qlcnic_info nic_info;
	u8 pci_func;

	if (qlcnic_82xx_check(adapter))
		if (!adapter->need_fw_reset)
			return 0;

	/* Set the NPAR config data after FW reset */
	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
	for (i = 0; i < adapter->ahw->act_pci_func; i++) {
		npar = &adapter->npars[i];
		if (npar->type != QLCNIC_TYPE_NIC)
			continue;
		err = qlcnic_get_nic_info(adapter, &nic_info, i);
		pci_func = npar->pci_func;
		memset(&nic_info, 0, sizeof(struct qlcnic_info));
		err = qlcnic_get_nic_info(adapter,
					  &nic_info, pci_func);
		if (err)
			return err;
		nic_info.min_tx_bw = npar->min_bw;
@@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)

		if (npar->enable_pm) {
			err = qlcnic_config_port_mirroring(adapter,
							npar->dest_npar, 1, i);
							   npar->dest_npar, 1,
							   pci_func);
			if (err)
				return err;
		}
		err = qlcnic_reset_eswitch_config(adapter, npar, i);
		err = qlcnic_reset_eswitch_config(adapter, npar, pci_func);
		if (err)
			return err;
	}