Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/net-next

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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 29, 2013
2 parents 322555f + 9a84fea commit 6d508cc
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 90 deletions.
93 changes: 76 additions & 17 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -365,8 +379,13 @@ 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;
*autoneg = true;
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;
}

out:
Expand Down Expand Up @@ -431,6 +450,24 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
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
Expand Down Expand Up @@ -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) */
Expand Down Expand Up @@ -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) */
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
}

/**
Expand Down Expand Up @@ -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,
Expand Down
67 changes: 45 additions & 22 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2740,13 +2740,19 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
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;
}

/**
Expand All @@ -2763,38 +2769,43 @@ 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);
/* apply the port offset to the address offset */
(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;
}

/**
Expand Down Expand Up @@ -3243,28 +3254,36 @@ 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))
goto wwn_prefix_out;

/* 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;
}

/**
Expand Down Expand Up @@ -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) >>
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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...) \
Expand Down
Loading

0 comments on commit 6d508cc

Please sign in to comment.