Skip to content

Commit b1746fb

Browse files
tirthendu-intelkuba-moo
authored andcommitted
i40e: allow toggling loopback mode via ndo_set_features callback
Add support for NETIF_F_LOOPBACK. This feature can be set via: $ ethtool -K eth0 loopback <on|off> This sets the MAC Tx->Rx loopback. This feature is used for the xsk selftests, and might have other uses too. Signed-off-by: Tirthendu Sarkar <[email protected]> Reviewed-by: Alexander Lobakin <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Tested-by: Magnus Karlsson <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 2a78dd2 commit b1746fb

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,9 +1795,11 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_an_advt_reg);
17951795
/* Set Loopback mode (0x0618) */
17961796
struct i40e_aqc_set_lb_mode {
17971797
__le16 lb_mode;
1798-
#define I40E_AQ_LB_PHY_LOCAL 0x01
1799-
#define I40E_AQ_LB_PHY_REMOTE 0x02
1800-
#define I40E_AQ_LB_MAC_LOCAL 0x04
1798+
#define I40E_LEGACY_LOOPBACK_NVM_VER 0x6000
1799+
#define I40E_AQ_LB_MAC_LOCAL 0x01
1800+
#define I40E_AQ_LB_PHY_LOCAL 0x05
1801+
#define I40E_AQ_LB_PHY_REMOTE 0x06
1802+
#define I40E_AQ_LB_MAC_LOCAL_LEGACY 0x04
18011803
u8 reserved[14];
18021804
};
18031805

drivers/net/ethernet/intel/i40e/i40e_common.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,32 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
18301830
return status;
18311831
}
18321832

1833+
/**
1834+
* i40e_aq_set_mac_loopback
1835+
* @hw: pointer to the HW struct
1836+
* @ena_lpbk: Enable or Disable loopback
1837+
* @cmd_details: pointer to command details structure or NULL
1838+
*
1839+
* Enable/disable loopback on a given port
1840+
*/
1841+
i40e_status i40e_aq_set_mac_loopback(struct i40e_hw *hw, bool ena_lpbk,
1842+
struct i40e_asq_cmd_details *cmd_details)
1843+
{
1844+
struct i40e_aq_desc desc;
1845+
struct i40e_aqc_set_lb_mode *cmd =
1846+
(struct i40e_aqc_set_lb_mode *)&desc.params.raw;
1847+
1848+
i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_lb_modes);
1849+
if (ena_lpbk) {
1850+
if (hw->nvm.version <= I40E_LEGACY_LOOPBACK_NVM_VER)
1851+
cmd->lb_mode = cpu_to_le16(I40E_AQ_LB_MAC_LOCAL_LEGACY);
1852+
else
1853+
cmd->lb_mode = cpu_to_le16(I40E_AQ_LB_MAC_LOCAL);
1854+
}
1855+
1856+
return i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1857+
}
1858+
18331859
/**
18341860
* i40e_aq_set_phy_debug
18351861
* @hw: pointer to the hw struct

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12937,6 +12937,29 @@ static void i40e_clear_rss_lut(struct i40e_vsi *vsi)
1293712937
}
1293812938
}
1293912939

12940+
/**
12941+
* i40e_set_loopback - turn on/off loopback mode on underlying PF
12942+
* @vsi: ptr to VSI
12943+
* @ena: flag to indicate the on/off setting
12944+
*/
12945+
static int i40e_set_loopback(struct i40e_vsi *vsi, bool ena)
12946+
{
12947+
bool if_running = netif_running(vsi->netdev) &&
12948+
!test_and_set_bit(__I40E_VSI_DOWN, vsi->state);
12949+
int ret;
12950+
12951+
if (if_running)
12952+
i40e_down(vsi);
12953+
12954+
ret = i40e_aq_set_mac_loopback(&vsi->back->hw, ena, NULL);
12955+
if (ret)
12956+
netdev_err(vsi->netdev, "Failed to toggle loopback state\n");
12957+
if (if_running)
12958+
i40e_up(vsi);
12959+
12960+
return ret;
12961+
}
12962+
1294012963
/**
1294112964
* i40e_set_features - set the netdev feature flags
1294212965
* @netdev: ptr to the netdev being adjusted
@@ -12977,6 +13000,9 @@ static int i40e_set_features(struct net_device *netdev,
1297713000
if (need_reset)
1297813001
i40e_do_reset(pf, I40E_PF_RESET_FLAG, true);
1297913002

13003+
if ((features ^ netdev->features) & NETIF_F_LOOPBACK)
13004+
return i40e_set_loopback(vsi, !!(features & NETIF_F_LOOPBACK));
13005+
1298013006
return 0;
1298113007
}
1298213008

@@ -13739,7 +13765,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
1373913765
if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
1374013766
hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
1374113767

13742-
netdev->hw_features |= hw_features;
13768+
netdev->hw_features |= hw_features | NETIF_F_LOOPBACK;
1374313769

1374413770
netdev->features |= hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
1374513771
netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;

drivers/net/ethernet/intel/i40e/i40e_prototype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
105105
struct i40e_asq_cmd_details *cmd_details);
106106
enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
107107
bool atomic_reset);
108+
i40e_status i40e_aq_set_mac_loopback(struct i40e_hw *hw,
109+
bool ena_lpbk,
110+
struct i40e_asq_cmd_details *cmd_details);
108111
i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask,
109112
struct i40e_asq_cmd_details *cmd_details);
110113
i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,

0 commit comments

Comments
 (0)