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

Commit 4efac6ff authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2017-10-02

This series contains updates to i40e and i40evf.

Shannon Nelson fixes an issue where when a machine has more CPUs than
queue pairs, the counting gets a "little funky" and turns off Flow
Director.  So to correct it, limit the number of LAN queues initially
allocated to be sure there are some left for Flow Director and other
features.

Lihong cleans up dead code by removing a condition check which cannot
ever be true.

Christophe Jaillet fixes a potential NULL pointer dereference, which
could happen if kzalloc() fails.

Filip corrects the reporting of supported link modes, which was incorrect
for some NICs.  Added support for 'ethtool -m' command, which displays
information about QSFP+ modules.

Mariusz adds functions to read/write the LED registers to control the
LEDS, instead of accessing the registers directly whenever the LEDs
need to be controlled.

Jake fixes a regression where we introduced a scheduling while atomic,
so introduce a separate helper function which will manage its own need
for the mac_filter_hash_lock.  Also cleaned up the "PF" parameter in
i40e_vc_disable_vf() since it is never used and is not needed.  Fixed
a rare case where it is possible that a reset does not occur when
i40e_vc_disable_vf() is called, so modify i40e_reset_vf() to return a
bool to indicate whether it reset or not so that i40e_vc_disable_vf()
can wait until a reset actually occurs.

Alan adds the ability for the VF to request more or less underlying
allocated queues from the PF.  Fixes the incorrect method for clearing
the vf_states variable with a NULL assignment, when we should be
using atomic bitops since we don't actually want to clear all the
flags.  Fixed a resource leak, where the PF driver fails to inform
clients of a VF reset because we were incorrectly checking the
I40E_VF_STATE_PRE_ENABLE bit.

Mitch converts i40evf_map_rings_to_vectors() to a void function since
it cannot fail and allows us to clean up the checks for the function
return value.

Scott enables the driver(s) to pass traffic with VLAN tags using the
802.1ad Ethernet protocol.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d9601be1 ab243ec9
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -607,6 +607,18 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
			   &oem_lo);
	hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;

	if (hw->mac.type == I40E_MAC_XL710 &&
	    hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
	    hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
		hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE;
	}

	/* The ability to RX (not drop) 802.1ad frames was added in API 1.7 */
	if (hw->aq.api_maj_ver > 1 ||
	    (hw->aq.api_maj_ver == 1 &&
	     hw->aq.api_min_ver >= 7))
		hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE;

	if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
		goto init_adminq_free_arq;
+52 −3
Original line number Diff line number Diff line
@@ -244,6 +244,8 @@ enum i40e_admin_queue_opc {
	i40e_aqc_opc_set_phy_debug		= 0x0622,
	i40e_aqc_opc_upload_ext_phy_fm		= 0x0625,
	i40e_aqc_opc_run_phy_activity		= 0x0626,
	i40e_aqc_opc_set_phy_register		= 0x0628,
	i40e_aqc_opc_get_phy_register		= 0x0629,

	/* NVM commands */
	i40e_aqc_opc_nvm_read			= 0x0701,
@@ -773,7 +775,22 @@ struct i40e_aqc_set_switch_config {
#define I40E_AQ_SET_SWITCH_CFG_PROMISC		0x0001
#define I40E_AQ_SET_SWITCH_CFG_L2_FILTER	0x0002
	__le16	valid_flags;
	u8	reserved[12];
	/* The ethertype in switch_tag is dropped on ingress and used
	 * internally by the switch. Set this to zero for the default
	 * of 0x88a8 (802.1ad). Should be zero for firmware API
	 * versions lower than 1.7.
	 */
	__le16	switch_tag;
	/* The ethertypes in first_tag and second_tag are used to
	 * match the outer and inner VLAN tags (respectively) when HW
	 * double VLAN tagging is enabled via the set port parameters
	 * AQ command. Otherwise these are both ignored. Set them to
	 * zero for their defaults of 0x8100 (802.1Q). Should be zero
	 * for firmware API versions lower than 1.7.
	 */
	__le16	first_tag;
	__le16	second_tag;
	u8	reserved[6];
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_set_switch_config);
@@ -1734,6 +1751,8 @@ enum i40e_aq_phy_type {
	I40E_PHY_TYPE_10GBASE_CR1_CU		= 0xB,
	I40E_PHY_TYPE_10GBASE_AOC		= 0xC,
	I40E_PHY_TYPE_40GBASE_AOC		= 0xD,
	I40E_PHY_TYPE_UNRECOGNIZED		= 0xE,
	I40E_PHY_TYPE_UNSUPPORTED		= 0xF,
	I40E_PHY_TYPE_100BASE_TX		= 0x11,
	I40E_PHY_TYPE_1000BASE_T		= 0x12,
	I40E_PHY_TYPE_10GBASE_T			= 0x13,
@@ -1752,6 +1771,8 @@ enum i40e_aq_phy_type {
	I40E_PHY_TYPE_25GBASE_CR		= 0x20,
	I40E_PHY_TYPE_25GBASE_SR		= 0x21,
	I40E_PHY_TYPE_25GBASE_LR		= 0x22,
	I40E_PHY_TYPE_EMPTY			= 0xFE,
	I40E_PHY_TYPE_DEFAULT			= 0xFF,
	I40E_PHY_TYPE_MAX
};

@@ -1942,12 +1963,18 @@ struct i40e_aqc_get_link_status {
#define I40E_AQ_25G_SERDES_UCODE_ERR	0X04
#define I40E_AQ_25G_NIMB_UCODE_ERR	0X05
	u8	loopback; /* use defines from i40e_aqc_set_lb_mode */
/* Since firmware API 1.7 loopback field keeps power class info as well */
#define I40E_AQ_LOOPBACK_MASK		0x07
#define I40E_AQ_PWR_CLASS_SHIFT_LB	6
#define I40E_AQ_PWR_CLASS_MASK_LB	(0x03 << I40E_AQ_PWR_CLASS_SHIFT_LB)
	__le16	max_frame_size;
	u8	config;
#define I40E_AQ_CONFIG_FEC_KR_ENA	0x01
#define I40E_AQ_CONFIG_FEC_RS_ENA	0x02
#define I40E_AQ_CONFIG_CRC_ENA		0x04
#define I40E_AQ_CONFIG_PACING_MASK	0x78
	union {
		struct {
			u8	power_desc;
#define I40E_AQ_LINK_POWER_CLASS_1	0x00
#define I40E_AQ_LINK_POWER_CLASS_2	0x01
@@ -1956,6 +1983,12 @@ struct i40e_aqc_get_link_status {
#define I40E_AQ_PWR_CLASS_MASK		0x03
			u8	reserved[4];
		};
		struct {
			u8	link_type[4];
			u8	link_type_ext;
		};
	};
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status);

@@ -2037,6 +2070,22 @@ struct i40e_aqc_run_phy_activity {

I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);

/* Set PHY Register command (0x0628) */
/* Get PHY Register command (0x0629) */
struct i40e_aqc_phy_register_access {
	u8	phy_interface;
#define I40E_AQ_PHY_REG_ACCESS_INTERNAL	0
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL	1
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE	2
	u8	dev_address;
	u8	reserved1[2];
	__le32	reg_address;
	__le32	reg_value;
	u8	reserved2[4];
};

I40E_CHECK_CMD_LENGTH(i40e_aqc_phy_register_access);

/* NVM Read command (indirect 0x0701)
 * NVM Erase commands (direct 0x0702)
 * NVM Update commands (indirect 0x0703)
+175 −26
Original line number Diff line number Diff line
@@ -1821,7 +1821,7 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
	hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
						 I40E_AQ_CONFIG_FEC_RS_ENA);
	hw_link_info->ext_info = resp->ext_info;
	hw_link_info->loopback = resp->loopback;
	hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
	hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
	hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;

@@ -1852,6 +1852,15 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
	     hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
		hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;

	if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
	    hw->aq.api_min_ver >= 7) {
		__le32 tmp;

		memcpy(&tmp, resp->link_type, sizeof(tmp));
		hw->phy.phy_types = le32_to_cpu(tmp);
		hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
	}

	/* save link status information */
	if (link)
		*link = *hw_link_info;
@@ -2393,7 +2402,11 @@ enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
					  i40e_aqc_opc_set_switch_config);
	scfg->flags = cpu_to_le16(flags);
	scfg->valid_flags = cpu_to_le16(valid_flags);

	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
		scfg->switch_tag = cpu_to_le16(hw->switch_tag);
		scfg->first_tag = cpu_to_le16(hw->first_tag);
		scfg->second_tag = cpu_to_le16(hw->second_tag);
	}
	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
@@ -4827,6 +4840,74 @@ i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
	return status;
}

/**
 * i40e_led_get_reg - read LED register
 * @hw: pointer to the HW structure
 * @led_addr: LED register address
 * @reg_val: read register value
 **/
static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
					      u32 *reg_val)
{
	enum i40e_status_code status;
	u8 phy_addr = 0;
	u8 port_num;
	u32 i;

	*reg_val = 0;
	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
		status =
		       i40e_aq_get_phy_register(hw,
						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
						I40E_PHY_COM_REG_PAGE,
						I40E_PHY_LED_PROV_REG_1,
						reg_val, NULL);
	} else {
		i = rd32(hw, I40E_PFGEN_PORTNUM);
		port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
		phy_addr = i40e_get_phy_address(hw, port_num);
		status = i40e_read_phy_register_clause45(hw,
							 I40E_PHY_COM_REG_PAGE,
							 led_addr, phy_addr,
							 (u16 *)reg_val);
	}
	return status;
}

/**
 * i40e_led_set_reg - write LED register
 * @hw: pointer to the HW structure
 * @led_addr: LED register address
 * @reg_val: register value to write
 **/
static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
					      u32 reg_val)
{
	enum i40e_status_code status;
	u8 phy_addr = 0;
	u8 port_num;
	u32 i;

	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
		status =
		       i40e_aq_set_phy_register(hw,
						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
						I40E_PHY_COM_REG_PAGE,
						I40E_PHY_LED_PROV_REG_1,
						reg_val, NULL);
	} else {
		i = rd32(hw, I40E_PFGEN_PORTNUM);
		port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
		phy_addr = i40e_get_phy_address(hw, port_num);
		status = i40e_write_phy_register_clause45(hw,
							  I40E_PHY_COM_REG_PAGE,
							  led_addr, phy_addr,
							  (u16)reg_val);
	}

	return status;
}

/**
 * i40e_led_get_phy - return current on/off mode
 * @hw: pointer to the hw struct
@@ -4844,7 +4925,19 @@ i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
	u16 temp_addr;
	u8 port_num;
	u32 i;
	u32 reg_val_aq;

	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
		status =
		      i40e_aq_get_phy_register(hw,
					       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
					       I40E_PHY_COM_REG_PAGE,
					       I40E_PHY_LED_PROV_REG_1,
					       &reg_val_aq, NULL);
		if (status == I40E_SUCCESS)
			*val = (u16)reg_val_aq;
		return status;
	}
	temp_addr = I40E_PHY_LED_PROV_REG_1;
	i = rd32(hw, I40E_PFGEN_PORTNUM);
	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
@@ -4879,51 +4972,38 @@ i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
			     u16 led_addr, u32 mode)
{
	i40e_status status = 0;
	u16 led_ctl = 0;
	u16 led_reg = 0;
	u8 phy_addr = 0;
	u8 port_num;
	u32 i;
	u32 led_ctl = 0;
	u32 led_reg = 0;

	i = rd32(hw, I40E_PFGEN_PORTNUM);
	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
	phy_addr = i40e_get_phy_address(hw, port_num);
	status = i40e_read_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
						 led_addr, phy_addr, &led_reg);
	status = i40e_led_get_reg(hw, led_addr, &led_reg);
	if (status)
		return status;
	led_ctl = led_reg;
	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
		led_reg = 0;
		status = i40e_write_phy_register_clause45(hw,
							  I40E_PHY_COM_REG_PAGE,
							  led_addr, phy_addr,
							  led_reg);
		status = i40e_led_set_reg(hw, led_addr, led_reg);
		if (status)
			return status;
	}
	status = i40e_read_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
						 led_addr, phy_addr, &led_reg);
	status = i40e_led_get_reg(hw, led_addr, &led_reg);
	if (status)
		goto restore_config;
	if (on)
		led_reg = I40E_PHY_LED_MANUAL_ON;
	else
		led_reg = 0;
	status = i40e_write_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
						  led_addr, phy_addr, led_reg);

	status = i40e_led_set_reg(hw, led_addr, led_reg);
	if (status)
		goto restore_config;
	if (mode & I40E_PHY_LED_MODE_ORIG) {
		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
		status = i40e_write_phy_register_clause45(hw,
						 I40E_PHY_COM_REG_PAGE,
						 led_addr, phy_addr, led_ctl);
		status = i40e_led_set_reg(hw, led_addr, led_ctl);
	}
	return status;

restore_config:
	status = i40e_write_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
						  led_addr, phy_addr, led_ctl);
	status = i40e_led_set_reg(hw, led_addr, led_ctl);
	return status;
}

@@ -5053,6 +5133,75 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
		wr32(hw, reg_addr, reg_val);
}

/**
 * i40e_aq_set_phy_register
 * @hw: pointer to the hw struct
 * @phy_select: select which phy should be accessed
 * @dev_addr: PHY device address
 * @reg_addr: PHY register address
 * @reg_val: new register value
 * @cmd_details: pointer to command details structure or NULL
 *
 * Write the external PHY register.
 **/
i40e_status i40e_aq_set_phy_register(struct i40e_hw *hw,
				     u8 phy_select, u8 dev_addr,
				     u32 reg_addr, u32 reg_val,
				     struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_phy_register_access *cmd =
		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
	i40e_status status;

	i40e_fill_default_direct_cmd_desc(&desc,
					  i40e_aqc_opc_set_phy_register);

	cmd->phy_interface = phy_select;
	cmd->dev_address = dev_addr;
	cmd->reg_address = cpu_to_le32(reg_addr);
	cmd->reg_value = cpu_to_le32(reg_val);

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	return status;
}

/**
 * i40e_aq_get_phy_register
 * @hw: pointer to the hw struct
 * @phy_select: select which phy should be accessed
 * @dev_addr: PHY device address
 * @reg_addr: PHY register address
 * @reg_val: read register value
 * @cmd_details: pointer to command details structure or NULL
 *
 * Read the external PHY register.
 **/
i40e_status i40e_aq_get_phy_register(struct i40e_hw *hw,
				     u8 phy_select, u8 dev_addr,
				     u32 reg_addr, u32 *reg_val,
				     struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
	struct i40e_aqc_phy_register_access *cmd =
		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
	i40e_status status;

	i40e_fill_default_direct_cmd_desc(&desc,
					  i40e_aqc_opc_get_phy_register);

	cmd->phy_interface = phy_select;
	cmd->dev_address = dev_addr;
	cmd->reg_address = cpu_to_le32(reg_addr);

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
	if (!status)
		*reg_val = le32_to_cpu(cmd->reg_value);

	return status;
}

/**
 * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
 * @hw: pointer to the hw struct
+154 −0
Original line number Diff line number Diff line
@@ -4196,6 +4196,158 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
	return 0;
}

/**
 * i40e_get_module_info - get (Q)SFP+ module type info
 * @netdev: network interface device structure
 * @modinfo: module EEPROM size and layout information structure
 **/
static int i40e_get_module_info(struct net_device *netdev,
				struct ethtool_modinfo *modinfo)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	struct i40e_hw *hw = &pf->hw;
	u32 sff8472_comp = 0;
	u32 sff8472_swap = 0;
	u32 sff8636_rev = 0;
	i40e_status status;
	u32 type = 0;

	/* Check if firmware supports reading module EEPROM. */
	if (!(hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE)) {
		netdev_err(vsi->netdev, "Module EEPROM memory read not supported. Please update the NVM image.\n");
		return -EINVAL;
	}

	status = i40e_update_link_info(hw);
	if (status)
		return -EIO;

	if (hw->phy.link_info.phy_type == I40E_PHY_TYPE_EMPTY) {
		netdev_err(vsi->netdev, "Cannot read module EEPROM memory. No module connected.\n");
		return -EINVAL;
	}

	type = hw->phy.link_info.module_type[0];

	switch (type) {
	case I40E_MODULE_TYPE_SFP:
		status = i40e_aq_get_phy_register(hw,
				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
				I40E_I2C_EEPROM_DEV_ADDR,
				I40E_MODULE_SFF_8472_COMP,
				&sff8472_comp, NULL);
		if (status)
			return -EIO;

		status = i40e_aq_get_phy_register(hw,
				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
				I40E_I2C_EEPROM_DEV_ADDR,
				I40E_MODULE_SFF_8472_SWAP,
				&sff8472_swap, NULL);
		if (status)
			return -EIO;

		/* Check if the module requires address swap to access
		 * the other EEPROM memory page.
		 */
		if (sff8472_swap & I40E_MODULE_SFF_ADDR_MODE) {
			netdev_warn(vsi->netdev, "Module address swap to access page 0xA2 is not supported.\n");
			modinfo->type = ETH_MODULE_SFF_8079;
			modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
		} else if (sff8472_comp == 0x00) {
			/* Module is not SFF-8472 compliant */
			modinfo->type = ETH_MODULE_SFF_8079;
			modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
		} else {
			modinfo->type = ETH_MODULE_SFF_8472;
			modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
		}
		break;
	case I40E_MODULE_TYPE_QSFP_PLUS:
		/* Read from memory page 0. */
		status = i40e_aq_get_phy_register(hw,
				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
				0,
				I40E_MODULE_REVISION_ADDR,
				&sff8636_rev, NULL);
		if (status)
			return -EIO;
		/* Determine revision compliance byte */
		if (sff8636_rev > 0x02) {
			/* Module is SFF-8636 compliant */
			modinfo->type = ETH_MODULE_SFF_8636;
			modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
		} else {
			modinfo->type = ETH_MODULE_SFF_8436;
			modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
		}
		break;
	case I40E_MODULE_TYPE_QSFP28:
		modinfo->type = ETH_MODULE_SFF_8636;
		modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
		break;
	default:
		netdev_err(vsi->netdev, "Module type unrecognized\n");
		return -EINVAL;
	}
	return 0;
}

/**
 * i40e_get_module_eeprom - fills buffer with (Q)SFP+ module memory contents
 * @netdev: network interface device structure
 * @ee: EEPROM dump request structure
 * @data: buffer to be filled with EEPROM contents
 **/
static int i40e_get_module_eeprom(struct net_device *netdev,
				  struct ethtool_eeprom *ee,
				  u8 *data)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	struct i40e_hw *hw = &pf->hw;
	bool is_sfp = false;
	i40e_status status;
	u32 value = 0;
	int i;

	if (!ee || !ee->len || !data)
		return -EINVAL;

	if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP)
		is_sfp = true;

	for (i = 0; i < ee->len; i++) {
		u32 offset = i + ee->offset;
		u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0;

		/* Check if we need to access the other memory page */
		if (is_sfp) {
			if (offset >= ETH_MODULE_SFF_8079_LEN) {
				offset -= ETH_MODULE_SFF_8079_LEN;
				addr = I40E_I2C_EEPROM_DEV_ADDR2;
			}
		} else {
			while (offset >= ETH_MODULE_SFF_8436_LEN) {
				/* Compute memory page number and offset. */
				offset -= ETH_MODULE_SFF_8436_LEN / 2;
				addr++;
			}
		}

		status = i40e_aq_get_phy_register(hw,
				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
				addr, offset, &value, NULL);
		if (status)
			return -EIO;
		data[i] = value;
	}
	return 0;
}

static const struct ethtool_ops i40e_ethtool_ops = {
	.get_drvinfo		= i40e_get_drvinfo,
	.get_regs_len		= i40e_get_regs_len,
@@ -4228,6 +4380,8 @@ static const struct ethtool_ops i40e_ethtool_ops = {
	.set_rxfh		= i40e_set_rxfh,
	.get_channels		= i40e_get_channels,
	.set_channels		= i40e_set_channels,
	.get_module_info	= i40e_get_module_info,
	.get_module_eeprom	= i40e_get_module_eeprom,
	.get_ts_info		= i40e_get_ts_info,
	.get_priv_flags		= i40e_get_priv_flags,
	.set_priv_flags		= i40e_set_priv_flags,
+14 −4
Original line number Diff line number Diff line
@@ -11093,6 +11093,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
static void i40e_determine_queue_usage(struct i40e_pf *pf)
{
	int queues_left;
	int q_max;

	pf->num_lan_qps = 0;

@@ -11139,10 +11140,12 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
					I40E_FLAG_DCB_ENABLED);
			dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n");
		}
		pf->num_lan_qps = max_t(int, pf->rss_size_max,
					num_online_cpus());
		pf->num_lan_qps = min_t(int, pf->num_lan_qps,
					pf->hw.func_caps.num_tx_qp);

		/* limit lan qps to the smaller of qps, cpus or msix */
		q_max = max_t(int, pf->rss_size_max, num_online_cpus());
		q_max = min_t(int, q_max, pf->hw.func_caps.num_tx_qp);
		q_max = min_t(int, q_max, pf->hw.func_caps.num_msix_vectors);
		pf->num_lan_qps = q_max;

		queues_left -= pf->num_lan_qps;
	}
@@ -11358,6 +11361,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	hw->bus.bus_id = pdev->bus->number;
	pf->instance = pfs_found;

	/* Select something other than the 802.1ad ethertype for the
	 * switch to use internally and drop on ingress.
	 */
	hw->switch_tag = 0xffff;
	hw->first_tag = ETH_P_8021AD;
	hw->second_tag = ETH_P_8021Q;

	INIT_LIST_HEAD(&pf->l3_flex_pit_list);
	INIT_LIST_HEAD(&pf->l4_flex_pit_list);

Loading