i40e: Fix led blink capability for 10GBaseT PHY

This patch fixes a problem where the ethtool identify adapter
functionality did not work for some copper PHY's.  Without this
patch, the blink led functionality fails on some parts.  This
patch adds PHY write code to blink led's on parts where this
functionality is contained in the PHY rather than the MAC.

Change-ID: Iee7b3453f61d5ffd0b3d03f720ee4f17f919fcc2
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Carolyn Wyborny 2016-02-17 16:12:12 -08:00 committed by Jeff Kirsher
parent fd077cd339
commit 31b606d0c4
4 changed files with 63 additions and 6 deletions

View File

@ -111,6 +111,7 @@
#define I40E_OEM_VER_PATCH_MASK 0xff
#define I40E_OEM_VER_BUILD_SHIFT 8
#define I40E_OEM_VER_SHIFT 24
#define I40E_PHY_DEBUG_PORT BIT(4)
/* The values in here are decimal coded as hex as is the case in the NVM map*/
#define I40E_CURRENT_NVM_VERSION_HI 0x2
@ -355,6 +356,7 @@ struct i40e_pf {
#define I40E_FLAG_NO_DCB_SUPPORT BIT_ULL(45)
#define I40E_FLAG_USE_SET_LLDP_MIB BIT_ULL(46)
#define I40E_FLAG_STOP_FW_LLDP BIT_ULL(47)
#define I40E_FLAG_HAVE_10GBASET_PHY BIT_ULL(48)
#define I40E_FLAG_PF_MAC BIT_ULL(50)
/* tracks features that get auto disabled by errors */
@ -440,6 +442,7 @@ struct i40e_pf {
u32 ioremap_len;
u32 fd_inv;
u16 phy_led_val;
};
struct i40e_mac_filter {

View File

@ -1887,6 +1887,32 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
return status;
}
/**
* i40e_aq_set_phy_debug
* @hw: pointer to the hw struct
* @cmd_flags: debug command flags
* @cmd_details: pointer to command details structure or NULL
*
* Reset the external PHY.
**/
enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_set_phy_debug *cmd =
(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
enum i40e_status_code status;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_set_phy_debug);
cmd->command_flags = cmd_flags;
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status;
}
/**
* i40e_aq_add_vsi
* @hw: pointer to the hw struct

View File

@ -1826,28 +1826,52 @@ static int i40e_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
i40e_status ret = 0;
struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw;
int blink_freq = 2;
u16 temp_status;
switch (state) {
case ETHTOOL_ID_ACTIVE:
pf->led_status = i40e_led_get(hw);
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
pf->led_status = i40e_led_get(hw);
} else {
i40e_aq_set_phy_debug(hw, I40E_PHY_DEBUG_PORT, NULL);
ret = i40e_led_get_phy(hw, &temp_status,
&pf->phy_led_val);
pf->led_status = temp_status;
}
return blink_freq;
case ETHTOOL_ID_ON:
i40e_led_set(hw, 0xF, false);
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
i40e_led_set(hw, 0xf, false);
else
ret = i40e_led_set_phy(hw, true, pf->led_status, 0);
break;
case ETHTOOL_ID_OFF:
i40e_led_set(hw, 0x0, false);
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
i40e_led_set(hw, 0x0, false);
else
ret = i40e_led_set_phy(hw, false, pf->led_status, 0);
break;
case ETHTOOL_ID_INACTIVE:
i40e_led_set(hw, pf->led_status, false);
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
i40e_led_set(hw, false, pf->led_status);
} else {
ret = i40e_led_set_phy(hw, false, pf->led_status,
(pf->phy_led_val |
I40E_PHY_LED_MODE_ORIG));
i40e_aq_set_phy_debug(hw, 0, NULL);
}
break;
default:
break;
}
return 0;
if (ret)
return -ENOENT;
else
return 0;
}
/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt

View File

@ -11130,6 +11130,10 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
pf->main_vsi_seid);
if ((pf->hw.device_id == I40E_DEV_ID_10G_BASE_T) ||
(pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))
pf->flags |= I40E_FLAG_HAVE_10GBASET_PHY;
/* print a string summarizing features */
i40e_print_features(pf);