Commit 31b606d0 authored by Carolyn Wyborny's avatar Carolyn Wyborny Committed by Jeff Kirsher

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: default avatarCarolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent fd077cd3
...@@ -111,6 +111,7 @@ ...@@ -111,6 +111,7 @@
#define I40E_OEM_VER_PATCH_MASK 0xff #define I40E_OEM_VER_PATCH_MASK 0xff
#define I40E_OEM_VER_BUILD_SHIFT 8 #define I40E_OEM_VER_BUILD_SHIFT 8
#define I40E_OEM_VER_SHIFT 24 #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*/ /* The values in here are decimal coded as hex as is the case in the NVM map*/
#define I40E_CURRENT_NVM_VERSION_HI 0x2 #define I40E_CURRENT_NVM_VERSION_HI 0x2
...@@ -355,6 +356,7 @@ struct i40e_pf { ...@@ -355,6 +356,7 @@ struct i40e_pf {
#define I40E_FLAG_NO_DCB_SUPPORT BIT_ULL(45) #define I40E_FLAG_NO_DCB_SUPPORT BIT_ULL(45)
#define I40E_FLAG_USE_SET_LLDP_MIB BIT_ULL(46) #define I40E_FLAG_USE_SET_LLDP_MIB BIT_ULL(46)
#define I40E_FLAG_STOP_FW_LLDP BIT_ULL(47) #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) #define I40E_FLAG_PF_MAC BIT_ULL(50)
/* tracks features that get auto disabled by errors */ /* tracks features that get auto disabled by errors */
...@@ -440,6 +442,7 @@ struct i40e_pf { ...@@ -440,6 +442,7 @@ struct i40e_pf {
u32 ioremap_len; u32 ioremap_len;
u32 fd_inv; u32 fd_inv;
u16 phy_led_val;
}; };
struct i40e_mac_filter { struct i40e_mac_filter {
......
...@@ -1887,6 +1887,32 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, ...@@ -1887,6 +1887,32 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
return status; 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 * i40e_aq_add_vsi
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
......
...@@ -1826,28 +1826,52 @@ static int i40e_set_phys_id(struct net_device *netdev, ...@@ -1826,28 +1826,52 @@ static int i40e_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state) enum ethtool_phys_id_state state)
{ {
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
i40e_status ret = 0;
struct i40e_pf *pf = np->vsi->back; struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
int blink_freq = 2; int blink_freq = 2;
u16 temp_status;
switch (state) { switch (state) {
case ETHTOOL_ID_ACTIVE: 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; return blink_freq;
case ETHTOOL_ID_ON: 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; break;
case ETHTOOL_ID_OFF: 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; break;
case ETHTOOL_ID_INACTIVE: 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; break;
default: default:
break; break;
} }
if (ret)
return 0; return -ENOENT;
else
return 0;
} }
/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt /* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
......
...@@ -11130,6 +11130,10 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -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, i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
pf->main_vsi_seid); 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 */ /* print a string summarizing features */
i40e_print_features(pf); i40e_print_features(pf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment