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

Commit 6d508cce authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
This series contains updates to ixgbe.

Jacob provides a fix for 82599 devices where it can potentially keep link
lights up when the adapter has gone down.

Mark provides a fix to resolve the possible use of uninitialized memory
by checking the return value on EEPROM reads.

Don provides 2 patches, one to fix a issue where we were traversing the
Tx ring with the value of IXGBE_NUM_RX_QUEUES which currently happens
to have the correct value but this is misleading.  A change later, could
easily make this no longer correct so when traversing the Tx ring, use
netdev->num_tx_queues.  His second patch does some minor clean ups of log
messages.

Emil provides the remaining ixgbe patches.  First he fixes the link test
where forcing the laser before the link check can lead to inconsistent
results because it does not guarantee that the link will be negotiated
correctly.  Then he initializes the message buffer array to 0 in order
to avoid using random numbers from the memory as a MAC address for the
VF.  Emil also fixes the read loop for the I2C data to account for the
offset for SFP+ modules.  Lastly, Emil provides several patches to add
support for QSFP modules where 1Gbps support is added as well as support
for older QSFP active direct attach cables which pre-date SFF-8436 v3.6.

v2: Fixed patch 4 description and added blank line based on feedback from
    Sergei Shtylyov
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 322555f5 9a84fea2
Loading
Loading
Loading
Loading
+76 −17
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg_wait_to_complete);
static void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw);
static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
				      bool autoneg_wait_to_complete);
static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
@@ -141,11 +142,13 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
			goto setup_sfp_out;
		}

		hw->eeprom.ops.read(hw, ++data_offset, &data_value);
		if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
			goto setup_sfp_err;
		while (data_value != 0xffff) {
			IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
			IXGBE_WRITE_FLUSH(hw);
			hw->eeprom.ops.read(hw, ++data_offset, &data_value);
			if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
				goto setup_sfp_err;
		}

		/* Release the semaphore */
@@ -191,6 +194,17 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)

setup_sfp_out:
	return ret_val;

setup_sfp_err:
	/* Release the semaphore */
	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
	/* Delay obtaining semaphore again to allow FW access,
	 * semaphore_delay is in ms usleep_range needs us.
	 */
	usleep_range(hw->eeprom.semaphore_delay * 1000,
		     hw->eeprom.semaphore_delay * 2000);
	hw_err(hw, "eeprom read at offset %d failed\n", data_offset);
	return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
}

static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
@@ -366,6 +380,11 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
	if (hw->phy.multispeed_fiber) {
		*speed |= IXGBE_LINK_SPEED_10GB_FULL |
			  IXGBE_LINK_SPEED_1GB_FULL;

		/* QSFP must not enable auto-negotiation */
		if (hw->phy.media_type == ixgbe_media_type_fiber_qsfp)
			*autoneg = false;
		else
			*autoneg = true;
	}

@@ -431,6 +450,24 @@ out:
	return media_type;
}

/**
 * ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3
 * @hw: pointer to hardware structure
 *
 * Disables link, should be called during D3 power down sequence.
 *
 */
static void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw)
{
	u32 autoc2_reg;

	if (!hw->mng_fw_enabled && !hw->wol_enabled) {
		autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
		autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK;
		IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
	}
}

/**
 *  ixgbe_start_mac_link_82599 - Setup MAC link settings
 *  @hw: pointer to hardware structure
@@ -668,13 +705,18 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
			goto out;

		/* Set the module link speed */
		if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
			ixgbe_set_fiber_fixed_speed(hw,
					IXGBE_LINK_SPEED_10GB_FULL);
		} else {
		switch (hw->phy.media_type) {
		case ixgbe_media_type_fiber:
			esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
			IXGBE_WRITE_FLUSH(hw);
			break;
		case ixgbe_media_type_fiber_qsfp:
			/* QSFP module automatically detects MAC link speed */
			break;
		default:
			hw_dbg(hw, "Unexpected media type.\n");
			break;
		}

		/* Allow module to change analog characteristics (1G->10G) */
@@ -725,14 +767,23 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
			goto out;

		/* Set the module link speed */
		if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
		switch (hw->phy.media_type) {
		case ixgbe_media_type_fiber_fixed:
			ixgbe_set_fiber_fixed_speed(hw,
						IXGBE_LINK_SPEED_1GB_FULL);
		} else {
			break;
		case ixgbe_media_type_fiber:
			esdp_reg &= ~IXGBE_ESDP_SDP5;
			esdp_reg |= IXGBE_ESDP_SDP5_DIR;
			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
			IXGBE_WRITE_FLUSH(hw);
			break;
		case ixgbe_media_type_fiber_qsfp:
			/* QSFP module automatically detects MAC link speed */
			break;
		default:
			hw_dbg(hw, "Unexpected media type.\n");
			break;
		}

		/* Allow module to change analog characteristics (10G->1G) */
@@ -2161,6 +2212,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
{
	s32 status = IXGBE_ERR_EEPROM_VERSION;
	u16 fw_offset, fw_ptp_cfg_offset;
	u16 offset;
	u16 fw_version = 0;

	/* firmware check is only necessary for SFI devices */
@@ -2170,29 +2222,35 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
	}

	/* get the offset to the Firmware Module block */
	hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
	offset = IXGBE_FW_PTR;
	if (hw->eeprom.ops.read(hw, offset, &fw_offset))
		goto fw_version_err;

	if ((fw_offset == 0) || (fw_offset == 0xFFFF))
		goto fw_version_out;

	/* get the offset to the Pass Through Patch Configuration block */
	hw->eeprom.ops.read(hw, (fw_offset +
	                         IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR),
	                         &fw_ptp_cfg_offset);
	offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR;
	if (hw->eeprom.ops.read(hw, offset, &fw_ptp_cfg_offset))
		goto fw_version_err;

	if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
		goto fw_version_out;

	/* get the firmware version */
	hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
	                         IXGBE_FW_PATCH_VERSION_4),
	                         &fw_version);
	offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4;
	if (hw->eeprom.ops.read(hw, offset, &fw_version))
		goto fw_version_err;

	if (fw_version > 0x5)
		status = 0;

fw_version_out:
	return status;

fw_version_err:
	hw_err(hw, "eeprom read at offset %d failed\n", offset);
	return IXGBE_ERR_EEPROM_VERSION;
}

/**
@@ -2477,6 +2535,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
	.read_analog_reg8       = &ixgbe_read_analog_reg8_82599,
	.write_analog_reg8      = &ixgbe_write_analog_reg8_82599,
	.stop_link_on_d3	= &ixgbe_stop_mac_link_on_d3_82599,
	.setup_link             = &ixgbe_setup_mac_link_82599,
	.set_rxpba		= &ixgbe_set_rxpba_generic,
	.check_link             = &ixgbe_check_mac_link_generic,
+45 −22
Original line number Diff line number Diff line
@@ -2740,13 +2740,19 @@ out:
static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
                                        u16 *san_mac_offset)
{
	s32 ret_val;

	/*
	 * First read the EEPROM pointer to see if the MAC addresses are
	 * available.
	 */
	hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
	ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR,
				      san_mac_offset);
	if (ret_val)
		hw_err(hw, "eeprom read at offset %d failed\n",
		       IXGBE_SAN_MAC_ADDR_PTR);

	return 0;
	return ret_val;
}

/**
@@ -2763,23 +2769,16 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
{
	u16 san_mac_data, san_mac_offset;
	u8 i;
	s32 ret_val;

	/*
	 * First read the EEPROM pointer to see if the MAC addresses are
	 * available.  If they're not, no point in calling set_lan_id() here.
	 */
	ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
	ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
	if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)

	if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
		/*
		 * No addresses available in this EEPROM.  It's not an
		 * error though, so just wipe the local address and return.
		 */
		for (i = 0; i < 6; i++)
			san_mac_addr[i] = 0xFF;

		goto san_mac_addr_out;
	}
		goto san_mac_addr_clr;

	/* make sure we know which port we need to program */
	hw->mac.ops.set_lan_id(hw);
@@ -2787,14 +2786,26 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
	                 (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
	for (i = 0; i < 3; i++) {
		hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
		ret_val = hw->eeprom.ops.read(hw, san_mac_offset,
					      &san_mac_data);
		if (ret_val) {
			hw_err(hw, "eeprom read at offset %d failed\n",
			       san_mac_offset);
			goto san_mac_addr_clr;
		}
		san_mac_addr[i * 2] = (u8)(san_mac_data);
		san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
		san_mac_offset++;
	}

san_mac_addr_out:
	return 0;

san_mac_addr_clr:
	/* No addresses available in this EEPROM.  It's not necessarily an
	 * error though, so just wipe the local address and return.
	 */
	for (i = 0; i < 6; i++)
		san_mac_addr[i] = 0xFF;
	return ret_val;
}

/**
@@ -3243,8 +3254,9 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
	*wwpn_prefix = 0xFFFF;

	/* check if alternative SAN MAC is supported */
	hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
	                    &alt_san_mac_blk_offset);
	offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR;
	if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset))
		goto wwn_prefix_err;

	if ((alt_san_mac_blk_offset == 0) ||
	    (alt_san_mac_blk_offset == 0xFFFF))
@@ -3252,19 +3264,26 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,

	/* check capability in alternative san mac address block */
	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
	hw->eeprom.ops.read(hw, offset, &caps);
	if (hw->eeprom.ops.read(hw, offset, &caps))
		goto wwn_prefix_err;
	if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
		goto wwn_prefix_out;

	/* get the corresponding prefix for WWNN/WWPN */
	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
	hw->eeprom.ops.read(hw, offset, wwnn_prefix);
	if (hw->eeprom.ops.read(hw, offset, wwnn_prefix))
		hw_err(hw, "eeprom read at offset %d failed\n", offset);

	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
	hw->eeprom.ops.read(hw, offset, wwpn_prefix);
	if (hw->eeprom.ops.read(hw, offset, wwpn_prefix))
		goto wwn_prefix_err;

wwn_prefix_out:
	return 0;

wwn_prefix_err:
	hw_err(hw, "eeprom read at offset %d failed\n", offset);
	return 0;
}

/**
@@ -3778,7 +3797,11 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
		u8  sensor_index;
		u8  sensor_location;

		hw->eeprom.ops.read(hw, (ets_offset + 1 + i), &ets_sensor);
		if (hw->eeprom.ops.read(hw, ets_offset + 1 + i, &ets_sensor)) {
			hw_err(hw, "eeprom read at offset %d failed\n",
			       ets_offset + 1 + i);
			continue;
		}
		sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
				IXGBE_ETS_DATA_INDEX_SHIFT);
		sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >>
+5 −1
Original line number Diff line number Diff line
@@ -143,8 +143,12 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);

#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)

#define ixgbe_hw_to_netdev(hw) (((struct ixgbe_adapter *)(hw)->back)->netdev)

#define hw_dbg(hw, format, arg...) \
	netdev_dbg(((struct ixgbe_adapter *)(hw->back))->netdev, format, ##arg)
	netdev_dbg(ixgbe_hw_to_netdev(hw), format, ## arg)
#define hw_err(hw, format, arg...) \
	netdev_err(ixgbe_hw_to_netdev(hw), format, ## arg)
#define e_dev_info(format, arg...) \
	dev_info(&adapter->pdev->dev, format, ## arg)
#define e_dev_warn(format, arg...) \
+15 −26
Original line number Diff line number Diff line
@@ -311,9 +311,6 @@ static int ixgbe_set_settings(struct net_device *netdev,
		 * this function does not support duplex forcing, but can
		 * limit the advertising of the adapter to the specified speed
		 */
		if (ecmd->autoneg == AUTONEG_DISABLE)
			return -EINVAL;

		if (ecmd->advertising & ~ecmd->supported)
			return -EINVAL;

@@ -1049,7 +1046,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
		data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
		           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
	}
	for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
	for (j = 0; j < netdev->num_tx_queues; j++) {
		ring = adapter->tx_ring[j];
		if (!ring) {
			data[i] = 0;
@@ -1885,11 +1882,12 @@ static void ixgbe_diag_test(struct net_device *netdev,
                            struct ethtool_test *eth_test, u64 *data)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);
	struct ixgbe_hw *hw = &adapter->hw;
	bool if_running = netif_running(netdev);

	set_bit(__IXGBE_TESTING, &adapter->state);
	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
		struct ixgbe_hw *hw = &adapter->hw;

		if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
			int i;
			for (i = 0; i < adapter->num_vfs; i++) {
@@ -1913,21 +1911,18 @@ static void ixgbe_diag_test(struct net_device *netdev,
		/* Offline tests */
		e_info(hw, "offline testing starting\n");

		if (if_running)
			/* indicate we're in test mode */
			dev_close(netdev);

		/* bringing adapter down disables SFP+ optics */
		if (hw->mac.ops.enable_tx_laser)
			hw->mac.ops.enable_tx_laser(hw);

		/* Link test performed before hardware reset so autoneg doesn't
		 * interfere with test result
		 */
		if (ixgbe_link_test(adapter, &data[4]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		if (if_running)
			/* indicate we're in test mode */
			dev_close(netdev);
		else
			ixgbe_reset(adapter);

		e_info(hw, "register testing starting\n");
		if (ixgbe_reg_test(adapter, &data[0]))
			eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1964,13 +1959,11 @@ skip_loopback:
		clear_bit(__IXGBE_TESTING, &adapter->state);
		if (if_running)
			dev_open(netdev);
		else if (hw->mac.ops.disable_tx_laser)
			hw->mac.ops.disable_tx_laser(hw);
	} else {
		e_info(hw, "online testing starting\n");

		/* if adapter is down, SFP+ optics will be disabled */
		if (!if_running && hw->mac.ops.enable_tx_laser)
			hw->mac.ops.enable_tx_laser(hw);

		/* Online tests */
		if (ixgbe_link_test(adapter, &data[4]))
			eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1984,9 +1977,6 @@ skip_loopback:
		clear_bit(__IXGBE_TESTING, &adapter->state);
	}

	/* if adapter was down, ensure SFP+ optics are disabled again */
	if (!if_running && hw->mac.ops.disable_tx_laser)
		hw->mac.ops.disable_tx_laser(hw);
skip_ol_tests:
	msleep_interruptible(4 * 1000);
}
@@ -2953,12 +2943,11 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
	u32 status = IXGBE_ERR_PHY_ADDR_INVALID;
	u8 databyte = 0xFF;
	int i = 0;
	int ret_val = 0;

	if (ee->len == 0)
		return -EINVAL;

	for (i = ee->offset; i < ee->len; i++) {
	for (i = ee->offset; i < ee->offset + ee->len; i++) {
		/* I2C reads can take long time */
		if (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
			return -EBUSY;
@@ -2969,12 +2958,12 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
			status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);

		if (status != 0)
			ret_val = -EIO;
			return -EIO;

		data[i - ee->offset] = databyte;
	}

	return ret_val;
	return 0;
}

static const struct ethtool_ops ixgbe_ethtool_ops = {
+9 −4
Original line number Diff line number Diff line
@@ -4175,6 +4175,10 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
	case ixgbe_phy_sfp_passive_unknown:
	case ixgbe_phy_sfp_active_unknown:
	case ixgbe_phy_sfp_ftl_active:
	case ixgbe_phy_qsfp_passive_unknown:
	case ixgbe_phy_qsfp_active_unknown:
	case ixgbe_phy_qsfp_intel:
	case ixgbe_phy_qsfp_unknown:
		return true;
	case ixgbe_phy_nl:
		if (hw->mac.type == ixgbe_mac_82598EB)
@@ -5292,6 +5296,9 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
		return retval;

#endif
	if (hw->mac.ops.stop_link_on_d3)
		hw->mac.ops.stop_link_on_d3(hw);

	if (wufc) {
		ixgbe_set_rx_mode(netdev);

@@ -7602,10 +7609,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	    hw->mac.type == ixgbe_mac_82598EB) {
		err = 0;
	} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
		e_dev_err("failed to load because an unsupported SFP+ "
			  "module type was detected.\n");
		e_dev_err("Reload the driver after installing a supported "
			  "module.\n");
		e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n");
		e_dev_err("Reload the driver after installing a supported module.\n");
		goto err_sw_init;
	} else if (err) {
		e_dev_err("HW Init failed: %d\n", err);
Loading