aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_main.c
diff options
context:
space:
mode:
authorBrett Creeley <brett.creeley@intel.com>2018-12-19 13:03:25 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-01-15 13:27:18 -0500
commitb6f934f027bbdb53b7e2653b23758e222f3dd65a (patch)
treeb7604f22da64538ef337d5cf59ec6dc6b90fed2d /drivers/net/ethernet/intel/ice/ice_main.c
parent4c98ab550cc624eb94b0cdb32f5deb1ebbb4f593 (diff)
ice: Set physical link up/down when an interface is set up/down
When a netdev is set up/down we need to set the phsyical link state accordingly. This patch adds that functionality by calling ice_force_phys_link_state(vsi, link_up) in both the ice_stop() and ice_open() paths. In order to force link, ice_force_phys_link_state(vsi, link_up) will first determine the current phy capabilities. If link has not changed there is nothing to do. If link has changed, previous PHY capabilities are saved and the "Enable Automatic Link Update" and "Link Establishment State Machine (LESM)" enable bits are set. Then the new PHY config is saved. The "Enable Automatic Link Update" will force the FW to execute Setup link and restart auto-negotiation. This *should* then result in a "Link Status Event (LSE)" which will cause the driver to get the current link status. Signed-off-by: Brett Creeley <brett.creeley@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_main.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c97
1 files changed, 94 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 90773b477d19..b27bc7d6d605 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2945,12 +2945,91 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
2945} 2945}
2946 2946
2947/** 2947/**
2948 * ice_force_phys_link_state - Force the physical link state
2949 * @vsi: VSI to force the physical link state to up/down
2950 * @link_up: true/false indicates to set the physical link to up/down
2951 *
2952 * Force the physical link state by getting the current PHY capabilities from
2953 * hardware and setting the PHY config based on the determined capabilities. If
2954 * link changes a link event will be triggered because both the Enable Automatic
2955 * Link Update and LESM Enable bits are set when setting the PHY capabilities.
2956 *
2957 * Returns 0 on success, negative on failure
2958 */
2959static int ice_force_phys_link_state(struct ice_vsi *vsi, bool link_up)
2960{
2961 struct ice_aqc_get_phy_caps_data *pcaps;
2962 struct ice_aqc_set_phy_cfg_data *cfg;
2963 struct ice_port_info *pi;
2964 struct device *dev;
2965 int retcode;
2966
2967 if (!vsi || !vsi->port_info || !vsi->back)
2968 return -EINVAL;
2969 if (vsi->type != ICE_VSI_PF)
2970 return 0;
2971
2972 dev = &vsi->back->pdev->dev;
2973
2974 pi = vsi->port_info;
2975
2976 pcaps = devm_kzalloc(dev, sizeof(*pcaps), GFP_KERNEL);
2977 if (!pcaps)
2978 return -ENOMEM;
2979
2980 retcode = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
2981 NULL);
2982 if (retcode) {
2983 dev_err(dev,
2984 "Failed to get phy capabilities, VSI %d error %d\n",
2985 vsi->vsi_num, retcode);
2986 retcode = -EIO;
2987 goto out;
2988 }
2989
2990 /* No change in link */
2991 if (link_up == !!(pcaps->caps & ICE_AQC_PHY_EN_LINK) &&
2992 link_up == !!(pi->phy.link_info.link_info & ICE_AQ_LINK_UP))
2993 goto out;
2994
2995 cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
2996 if (!cfg) {
2997 retcode = -ENOMEM;
2998 goto out;
2999 }
3000
3001 cfg->phy_type_low = pcaps->phy_type_low;
3002 cfg->phy_type_high = pcaps->phy_type_high;
3003 cfg->caps = pcaps->caps | ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
3004 cfg->low_power_ctrl = pcaps->low_power_ctrl;
3005 cfg->eee_cap = pcaps->eee_cap;
3006 cfg->eeer_value = pcaps->eeer_value;
3007 cfg->link_fec_opt = pcaps->link_fec_options;
3008 if (link_up)
3009 cfg->caps |= ICE_AQ_PHY_ENA_LINK;
3010 else
3011 cfg->caps &= ~ICE_AQ_PHY_ENA_LINK;
3012
3013 retcode = ice_aq_set_phy_cfg(&vsi->back->hw, pi->lport, cfg, NULL);
3014 if (retcode) {
3015 dev_err(dev, "Failed to set phy config, VSI %d error %d\n",
3016 vsi->vsi_num, retcode);
3017 retcode = -EIO;
3018 }
3019
3020 devm_kfree(dev, cfg);
3021out:
3022 devm_kfree(dev, pcaps);
3023 return retcode;
3024}
3025
3026/**
2948 * ice_down - Shutdown the connection 3027 * ice_down - Shutdown the connection
2949 * @vsi: The VSI being stopped 3028 * @vsi: The VSI being stopped
2950 */ 3029 */
2951int ice_down(struct ice_vsi *vsi) 3030int ice_down(struct ice_vsi *vsi)
2952{ 3031{
2953 int i, tx_err, rx_err; 3032 int i, tx_err, rx_err, link_err;
2954 3033
2955 /* Caller of this function is expected to set the 3034 /* Caller of this function is expected to set the
2956 * vsi->state __ICE_DOWN bit 3035 * vsi->state __ICE_DOWN bit
@@ -2975,13 +3054,19 @@ int ice_down(struct ice_vsi *vsi)
2975 3054
2976 ice_napi_disable_all(vsi); 3055 ice_napi_disable_all(vsi);
2977 3056
3057 link_err = ice_force_phys_link_state(vsi, false);
3058 if (link_err)
3059 netdev_err(vsi->netdev,
3060 "Failed to set physical link down, VSI %d error %d\n",
3061 vsi->vsi_num, link_err);
3062
2978 ice_for_each_txq(vsi, i) 3063 ice_for_each_txq(vsi, i)
2979 ice_clean_tx_ring(vsi->tx_rings[i]); 3064 ice_clean_tx_ring(vsi->tx_rings[i]);
2980 3065
2981 ice_for_each_rxq(vsi, i) 3066 ice_for_each_rxq(vsi, i)
2982 ice_clean_rx_ring(vsi->rx_rings[i]); 3067 ice_clean_rx_ring(vsi->rx_rings[i]);
2983 3068
2984 if (tx_err || rx_err) { 3069 if (tx_err || rx_err || link_err) {
2985 netdev_err(vsi->netdev, 3070 netdev_err(vsi->netdev,
2986 "Failed to close VSI 0x%04X on switch 0x%04X\n", 3071 "Failed to close VSI 0x%04X on switch 0x%04X\n",
2987 vsi->vsi_num, vsi->vsw->sw_id); 3072 vsi->vsi_num, vsi->vsw->sw_id);
@@ -3815,8 +3900,14 @@ static int ice_open(struct net_device *netdev)
3815 3900
3816 netif_carrier_off(netdev); 3901 netif_carrier_off(netdev);
3817 3902
3818 err = ice_vsi_open(vsi); 3903 err = ice_force_phys_link_state(vsi, true);
3904 if (err) {
3905 netdev_err(netdev,
3906 "Failed to set physical link up, error %d\n", err);
3907 return err;
3908 }
3819 3909
3910 err = ice_vsi_open(vsi);
3820 if (err) 3911 if (err)
3821 netdev_err(netdev, "Failed to open VSI 0x%04X on switch 0x%04X\n", 3912 netdev_err(netdev, "Failed to open VSI 0x%04X on switch 0x%04X\n",
3822 vsi->vsi_num, vsi->vsw->sw_id); 3913 vsi->vsi_num, vsi->vsw->sw_id);