All files in this driver directory contain the following notice:
  See LICENSE.qlcnic for copyright and licensing details.
LICENSE.qlacnic can be found in
Documentation/networking/device_drivers/qlogic/. The file contains:
  - A copyright notice
    This copyright notice is redundant as all files contain the same
    copyright notice already
  - A license notice
    You may modify and redistribute the device driver code under the
    GNU General Public License (a copy of which is attached hereto as
    Exhibit A) published by the Free Software Foundation (version 2).
    This can be replaced with the corresponding SPDX license identifier
    (GPL-2.0-only) in the source files which reference this license
    file.
  - The full GPLv2 license text
    A redundant copy of LICENSES/preferred/GPL-2.0
Remove the notices and add the SPDX license identifier GPL-2.0-only to the
source files.
Finally remove the now redundant LICENSE.qlcnic file.
Reviewed-by: Richard Fontana <rfontana@redhat.com>
Reviewed-by: Jilayne Lovejoy <opensource@jilayne.com>
Reviewed-by: Alexios Zavras <alexios.zavras@intel.com>
Acked-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
		
	
			
		
			
				
	
	
		
			285 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0-only
 | 
						|
/*
 | 
						|
 * QLogic qlcnic NIC Driver
 | 
						|
 * Copyright (c) 2009-2013 QLogic Corporation
 | 
						|
 */
 | 
						|
 | 
						|
#include "qlcnic.h"
 | 
						|
#include "qlcnic_hw.h"
 | 
						|
 | 
						|
static int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
 | 
						|
{
 | 
						|
	if (lock) {
 | 
						|
		if (qlcnic_83xx_lock_driver(adapter))
 | 
						|
			return -EBUSY;
 | 
						|
	}
 | 
						|
	QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER);
 | 
						|
	if (lock)
 | 
						|
		qlcnic_83xx_unlock_driver(adapter);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
 | 
						|
{
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
 | 
						|
	if (lock) {
 | 
						|
		if (qlcnic_83xx_lock_driver(adapter))
 | 
						|
			return -EBUSY;
 | 
						|
	}
 | 
						|
 | 
						|
	QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER);
 | 
						|
	ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
 | 
						|
 | 
						|
	if (lock)
 | 
						|
		qlcnic_83xx_unlock_driver(adapter);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	u8 id;
 | 
						|
	int ret = -EBUSY;
 | 
						|
	u32 data = QLCNIC_MGMT_FUNC;
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
 | 
						|
	if (qlcnic_83xx_lock_driver(adapter))
 | 
						|
		return ret;
 | 
						|
 | 
						|
	id = ahw->pci_func;
 | 
						|
	data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
 | 
						|
	data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, id)) |
 | 
						|
	       QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC, id);
 | 
						|
 | 
						|
	QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);
 | 
						|
 | 
						|
	qlcnic_83xx_unlock_driver(adapter);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
 | 
						|
	if (ahw->port_type == QLCNIC_XGBE) {
 | 
						|
		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
 | 
						|
		adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
 | 
						|
		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 | 
						|
		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 | 
						|
 | 
						|
	} else if (ahw->port_type == QLCNIC_GBE) {
 | 
						|
		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
 | 
						|
		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
 | 
						|
		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
 | 
						|
		adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G;
 | 
						|
	}
 | 
						|
	adapter->num_txd = MAX_CMD_DESCRIPTORS;
 | 
						|
	adapter->max_rds_rings = MAX_RDS_RINGS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * qlcnic_83xx_init_mgmt_vnic
 | 
						|
 *
 | 
						|
 * @adapter: adapter structure
 | 
						|
 * Management virtual NIC sets the operational mode of other vNIC's and
 | 
						|
 * configures embedded switch (ESWITCH).
 | 
						|
 * Returns: Success(0) or error code.
 | 
						|
 *
 | 
						|
 **/
 | 
						|
static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
	struct device *dev = &adapter->pdev->dev;
 | 
						|
	struct qlcnic_npar_info *npar;
 | 
						|
	int i, err = -EIO;
 | 
						|
 | 
						|
	qlcnic_83xx_get_minidump_template(adapter);
 | 
						|
 | 
						|
	if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
 | 
						|
		if (qlcnic_init_pci_info(adapter))
 | 
						|
			return err;
 | 
						|
 | 
						|
		npar = adapter->npars;
 | 
						|
 | 
						|
		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,
 | 
						|
				 npar->mac);
 | 
						|
		}
 | 
						|
 | 
						|
		dev_info(dev, "Max functions = %d, active functions = %d\n",
 | 
						|
			 ahw->max_pci_func, ahw->total_nic_func);
 | 
						|
 | 
						|
		if (qlcnic_83xx_set_vnic_opmode(adapter))
 | 
						|
			return err;
 | 
						|
 | 
						|
		if (qlcnic_set_default_offload_settings(adapter))
 | 
						|
			return err;
 | 
						|
	} else {
 | 
						|
		if (qlcnic_reset_npar_config(adapter))
 | 
						|
			return err;
 | 
						|
	}
 | 
						|
 | 
						|
	if (qlcnic_83xx_get_port_info(adapter))
 | 
						|
		return err;
 | 
						|
 | 
						|
	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
 | 
						|
	ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0;
 | 
						|
	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
 | 
						|
	qlcnic_83xx_enable_vnic_mode(adapter, 1);
 | 
						|
 | 
						|
	dev_info(dev, "HAL Version: %d, Management function\n",
 | 
						|
		 ahw->fw_hal_version);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int qlcnic_83xx_init_privileged_vnic(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	int err = -EIO;
 | 
						|
 | 
						|
	qlcnic_83xx_get_minidump_template(adapter);
 | 
						|
	if (qlcnic_83xx_get_port_info(adapter))
 | 
						|
		return err;
 | 
						|
 | 
						|
	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
 | 
						|
	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
 | 
						|
	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
 | 
						|
 | 
						|
	dev_info(&adapter->pdev->dev,
 | 
						|
		 "HAL Version: %d, Privileged function\n",
 | 
						|
		 adapter->ahw->fw_hal_version);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int qlcnic_83xx_init_non_privileged_vnic(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	int err = -EIO;
 | 
						|
 | 
						|
	qlcnic_83xx_get_fw_version(adapter);
 | 
						|
	if (qlcnic_set_eswitch_port_config(adapter))
 | 
						|
		return err;
 | 
						|
 | 
						|
	if (qlcnic_83xx_get_port_info(adapter))
 | 
						|
		return err;
 | 
						|
 | 
						|
	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
 | 
						|
	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
 | 
						|
	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
 | 
						|
 | 
						|
	dev_info(&adapter->pdev->dev, "HAL Version: %d, Virtual function\n",
 | 
						|
		 adapter->ahw->fw_hal_version);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * qlcnic_83xx_vnic_opmode
 | 
						|
 *
 | 
						|
 * @adapter: adapter structure
 | 
						|
 * Identify virtual NIC operational modes.
 | 
						|
 *
 | 
						|
 * Returns: Success(0) or error code.
 | 
						|
 *
 | 
						|
 **/
 | 
						|
int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	u32 op_mode, priv_level;
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
	struct qlcnic_nic_template *nic_ops = adapter->nic_ops;
 | 
						|
 | 
						|
	qlcnic_get_func_no(adapter);
 | 
						|
	op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
 | 
						|
 | 
						|
	if (op_mode == QLC_83XX_DEFAULT_OPMODE)
 | 
						|
		priv_level = QLCNIC_MGMT_FUNC;
 | 
						|
	else
 | 
						|
		priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
 | 
						|
							 ahw->pci_func);
 | 
						|
	switch (priv_level) {
 | 
						|
	case QLCNIC_NON_PRIV_FUNC:
 | 
						|
		ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
 | 
						|
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
 | 
						|
		nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
 | 
						|
		break;
 | 
						|
	case QLCNIC_PRIV_FUNC:
 | 
						|
		ahw->op_mode = QLCNIC_PRIV_FUNC;
 | 
						|
		ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
 | 
						|
		nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
 | 
						|
		break;
 | 
						|
	case QLCNIC_MGMT_FUNC:
 | 
						|
		ahw->op_mode = QLCNIC_MGMT_FUNC;
 | 
						|
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
 | 
						|
		nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		dev_err(&adapter->pdev->dev, "Invalid Virtual NIC opmode\n");
 | 
						|
		return -EIO;
 | 
						|
	}
 | 
						|
 | 
						|
	if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) {
 | 
						|
		adapter->flags |= QLCNIC_ESWITCH_ENABLED;
 | 
						|
		if (adapter->drv_mac_learn)
 | 
						|
			adapter->rx_mac_learn = true;
 | 
						|
	} else {
 | 
						|
		adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
 | 
						|
		adapter->rx_mac_learn = false;
 | 
						|
	}
 | 
						|
 | 
						|
	ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
 | 
						|
	ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
 | 
						|
{
 | 
						|
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						|
	struct qlc_83xx_idc *idc = &ahw->idc;
 | 
						|
	u32 state;
 | 
						|
 | 
						|
	state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
 | 
						|
	while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit) {
 | 
						|
		idc->vnic_wait_limit--;
 | 
						|
		msleep(1000);
 | 
						|
		state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
 | 
						|
	}
 | 
						|
 | 
						|
	if (state != QLCNIC_DEV_NPAR_OPER) {
 | 
						|
		dev_err(&adapter->pdev->dev,
 | 
						|
			"vNIC mode not operational, state check timed out.\n");
 | 
						|
		return -EIO;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int qlcnic_83xx_set_port_eswitch_status(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;
 | 
						|
 | 
						|
	if (!err)
 | 
						|
		adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE;
 | 
						|
 | 
						|
	return err;
 | 
						|
}
 |