aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2018-12-19 13:03:26 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-01-15 13:32:59 -0500
commitab4ab73fc1ec6dec548fa36c5e383ef5faa7b4c1 (patch)
tree8dcbc39d30188abbf54dfc20b8f8f52358c2316f
parentb6f934f027bbdb53b7e2653b23758e222f3dd65a (diff)
ice: Add ethtool private flag to make forcing link down optional
Add new infrastructure for implementing ethtool private flags using the existing pf->flags bitmap to store them, and add the link-down-on-close ethtool private flag to optionally bring down the PHY link when the interface is administratively downed. Signed-off-by: Bruce Allan <bruce.w.allan@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>
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c86
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c14
3 files changed, 95 insertions, 6 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index a385575600f6..8af882a2b070 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -270,6 +270,7 @@ enum ice_pf_flags {
270 ICE_FLAG_RSS_ENA, 270 ICE_FLAG_RSS_ENA,
271 ICE_FLAG_SRIOV_ENA, 271 ICE_FLAG_SRIOV_ENA,
272 ICE_FLAG_SRIOV_CAPABLE, 272 ICE_FLAG_SRIOV_CAPABLE,
273 ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
273 ICE_PF_FLAGS_NBITS /* must be last */ 274 ICE_PF_FLAGS_NBITS /* must be last */
274}; 275};
275 276
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 2a0bcd460d23..24c8aeaea2d5 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -114,6 +114,22 @@ static const u32 ice_regs_dump_list[] = {
114 QRX_ITR(0), 114 QRX_ITR(0),
115}; 115};
116 116
117struct ice_priv_flag {
118 char name[ETH_GSTRING_LEN];
119 u32 bitno; /* bit position in pf->flags */
120};
121
122#define ICE_PRIV_FLAG(_name, _bitno) { \
123 .name = _name, \
124 .bitno = _bitno, \
125}
126
127static const struct ice_priv_flag ice_gstrings_priv_flags[] = {
128 ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA),
129};
130
131#define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags)
132
117/** 133/**
118 * ice_nvm_version_str - format the NVM version strings 134 * ice_nvm_version_str - format the NVM version strings
119 * @hw: ptr to the hardware info 135 * @hw: ptr to the hardware info
@@ -152,6 +168,7 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
152 sizeof(drvinfo->fw_version)); 168 sizeof(drvinfo->fw_version));
153 strlcpy(drvinfo->bus_info, pci_name(pf->pdev), 169 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
154 sizeof(drvinfo->bus_info)); 170 sizeof(drvinfo->bus_info));
171 drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
155} 172}
156 173
157static int ice_get_regs_len(struct net_device __always_unused *netdev) 174static int ice_get_regs_len(struct net_device __always_unused *netdev)
@@ -293,6 +310,13 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
293 } 310 }
294 311
295 break; 312 break;
313 case ETH_SS_PRIV_FLAGS:
314 for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
315 snprintf(p, ETH_GSTRING_LEN, "%s",
316 ice_gstrings_priv_flags[i].name);
317 p += ETH_GSTRING_LEN;
318 }
319 break;
296 default: 320 default:
297 break; 321 break;
298 } 322 }
@@ -321,6 +345,64 @@ ice_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
321 return 0; 345 return 0;
322} 346}
323 347
348/**
349 * ice_get_priv_flags - report device private flags
350 * @netdev: network interface device structure
351 *
352 * The get string set count and the string set should be matched for each
353 * flag returned. Add new strings for each flag to the ice_gstrings_priv_flags
354 * array.
355 *
356 * Returns a u32 bitmap of flags.
357 */
358static u32 ice_get_priv_flags(struct net_device *netdev)
359{
360 struct ice_netdev_priv *np = netdev_priv(netdev);
361 struct ice_vsi *vsi = np->vsi;
362 struct ice_pf *pf = vsi->back;
363 u32 i, ret_flags = 0;
364
365 for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
366 const struct ice_priv_flag *priv_flag;
367
368 priv_flag = &ice_gstrings_priv_flags[i];
369
370 if (test_bit(priv_flag->bitno, pf->flags))
371 ret_flags |= BIT(i);
372 }
373
374 return ret_flags;
375}
376
377/**
378 * ice_set_priv_flags - set private flags
379 * @netdev: network interface device structure
380 * @flags: bit flags to be set
381 */
382static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
383{
384 struct ice_netdev_priv *np = netdev_priv(netdev);
385 struct ice_vsi *vsi = np->vsi;
386 struct ice_pf *pf = vsi->back;
387 u32 i;
388
389 if (flags > BIT(ICE_PRIV_FLAG_ARRAY_SIZE))
390 return -EINVAL;
391
392 for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
393 const struct ice_priv_flag *priv_flag;
394
395 priv_flag = &ice_gstrings_priv_flags[i];
396
397 if (flags & BIT(i))
398 set_bit(priv_flag->bitno, pf->flags);
399 else
400 clear_bit(priv_flag->bitno, pf->flags);
401 }
402
403 return 0;
404}
405
324static int ice_get_sset_count(struct net_device *netdev, int sset) 406static int ice_get_sset_count(struct net_device *netdev, int sset)
325{ 407{
326 switch (sset) { 408 switch (sset) {
@@ -344,6 +426,8 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
344 * not safe. 426 * not safe.
345 */ 427 */
346 return ICE_ALL_STATS_LEN(netdev); 428 return ICE_ALL_STATS_LEN(netdev);
429 case ETH_SS_PRIV_FLAGS:
430 return ICE_PRIV_FLAG_ARRAY_SIZE;
347 default: 431 default:
348 return -EOPNOTSUPP; 432 return -EOPNOTSUPP;
349 } 433 }
@@ -1753,6 +1837,8 @@ static const struct ethtool_ops ice_ethtool_ops = {
1753 .get_strings = ice_get_strings, 1837 .get_strings = ice_get_strings,
1754 .set_phys_id = ice_set_phys_id, 1838 .set_phys_id = ice_set_phys_id,
1755 .get_ethtool_stats = ice_get_ethtool_stats, 1839 .get_ethtool_stats = ice_get_ethtool_stats,
1840 .get_priv_flags = ice_get_priv_flags,
1841 .set_priv_flags = ice_set_priv_flags,
1756 .get_sset_count = ice_get_sset_count, 1842 .get_sset_count = ice_get_sset_count,
1757 .get_rxnfc = ice_get_rxnfc, 1843 .get_rxnfc = ice_get_rxnfc,
1758 .get_ringparam = ice_get_ringparam, 1844 .get_ringparam = ice_get_ringparam,
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index b27bc7d6d605..e36db981f047 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3029,7 +3029,7 @@ out:
3029 */ 3029 */
3030int ice_down(struct ice_vsi *vsi) 3030int ice_down(struct ice_vsi *vsi)
3031{ 3031{
3032 int i, tx_err, rx_err, link_err; 3032 int i, tx_err, rx_err, link_err = 0;
3033 3033
3034 /* Caller of this function is expected to set the 3034 /* Caller of this function is expected to set the
3035 * vsi->state __ICE_DOWN bit 3035 * vsi->state __ICE_DOWN bit
@@ -3054,11 +3054,13 @@ int ice_down(struct ice_vsi *vsi)
3054 3054
3055 ice_napi_disable_all(vsi); 3055 ice_napi_disable_all(vsi);
3056 3056
3057 link_err = ice_force_phys_link_state(vsi, false); 3057 if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
3058 if (link_err) 3058 link_err = ice_force_phys_link_state(vsi, false);
3059 netdev_err(vsi->netdev, 3059 if (link_err)
3060 "Failed to set physical link down, VSI %d error %d\n", 3060 netdev_err(vsi->netdev,
3061 vsi->vsi_num, link_err); 3061 "Failed to set physical link down, VSI %d error %d\n",
3062 vsi->vsi_num, link_err);
3063 }
3062 3064
3063 ice_for_each_txq(vsi, i) 3065 ice_for_each_txq(vsi, i)
3064 ice_clean_tx_ring(vsi->tx_rings[i]); 3066 ice_clean_tx_ring(vsi->tx_rings[i]);