Commit b57b44f7 authored by David S. Miller's avatar David S. Miller

Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next

-queue

Tony Nguyen says:

====================
10GbE Intel Wired LAN Driver Updates 2022-03-08

This series contains updates to ixgbe and ixgbevf drivers.

Slawomir adds an implementation for ndo_set_vf_link_state() to allow
for disabling of VF link state as well a mailbox implementation so
the VF can query the state. Additionally, for 82599, the option to
disable a VF after receiving several malicious driver detection (MDD)
events are encountered is added. For ixgbevf, the corresponding
implementation to query and report a disabled state is added.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d82a6c5e 443ebdd6
...@@ -177,11 +177,14 @@ struct vf_data_storage { ...@@ -177,11 +177,14 @@ struct vf_data_storage {
u16 pf_vlan; /* When set, guest VLAN config not allowed. */ u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos; u16 pf_qos;
u16 tx_rate; u16 tx_rate;
int link_enable;
int link_state;
u8 spoofchk_enabled; u8 spoofchk_enabled;
bool rss_query_enabled; bool rss_query_enabled;
u8 trusted; u8 trusted;
int xcast_mode; int xcast_mode;
unsigned int vf_api; unsigned int vf_api;
u8 primary_abort_count;
}; };
enum ixgbevf_xcast_modes { enum ixgbevf_xcast_modes {
...@@ -556,6 +559,8 @@ struct ixgbe_mac_addr { ...@@ -556,6 +559,8 @@ struct ixgbe_mac_addr {
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
#define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */ #define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */
#define IXGBE_PRIMARY_ABORT_LIMIT 5
/* board specific private data structure */ /* board specific private data structure */
struct ixgbe_adapter { struct ixgbe_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
...@@ -614,6 +619,7 @@ struct ixgbe_adapter { ...@@ -614,6 +619,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_RX_LEGACY BIT(16) #define IXGBE_FLAG2_RX_LEGACY BIT(16)
#define IXGBE_FLAG2_IPSEC_ENABLED BIT(17) #define IXGBE_FLAG2_IPSEC_ENABLED BIT(17)
#define IXGBE_FLAG2_VF_IPSEC_ENABLED BIT(18) #define IXGBE_FLAG2_VF_IPSEC_ENABLED BIT(18)
#define IXGBE_FLAG2_AUTO_DISABLE_VF BIT(19)
/* Tx fast path data */ /* Tx fast path data */
int num_tx_queues; int num_tx_queues;
......
...@@ -138,6 +138,8 @@ static const char ixgbe_priv_flags_strings[][ETH_GSTRING_LEN] = { ...@@ -138,6 +138,8 @@ static const char ixgbe_priv_flags_strings[][ETH_GSTRING_LEN] = {
"legacy-rx", "legacy-rx",
#define IXGBE_PRIV_FLAGS_VF_IPSEC_EN BIT(1) #define IXGBE_PRIV_FLAGS_VF_IPSEC_EN BIT(1)
"vf-ipsec", "vf-ipsec",
#define IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF BIT(2)
"mdd-disable-vf",
}; };
#define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings) #define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings)
...@@ -3510,6 +3512,9 @@ static u32 ixgbe_get_priv_flags(struct net_device *netdev) ...@@ -3510,6 +3512,9 @@ static u32 ixgbe_get_priv_flags(struct net_device *netdev)
if (adapter->flags2 & IXGBE_FLAG2_VF_IPSEC_ENABLED) if (adapter->flags2 & IXGBE_FLAG2_VF_IPSEC_ENABLED)
priv_flags |= IXGBE_PRIV_FLAGS_VF_IPSEC_EN; priv_flags |= IXGBE_PRIV_FLAGS_VF_IPSEC_EN;
if (adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF)
priv_flags |= IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF;
return priv_flags; return priv_flags;
} }
...@@ -3517,6 +3522,7 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags) ...@@ -3517,6 +3522,7 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
unsigned int flags2 = adapter->flags2; unsigned int flags2 = adapter->flags2;
unsigned int i;
flags2 &= ~IXGBE_FLAG2_RX_LEGACY; flags2 &= ~IXGBE_FLAG2_RX_LEGACY;
if (priv_flags & IXGBE_PRIV_FLAGS_LEGACY_RX) if (priv_flags & IXGBE_PRIV_FLAGS_LEGACY_RX)
...@@ -3526,6 +3532,21 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags) ...@@ -3526,6 +3532,21 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)
if (priv_flags & IXGBE_PRIV_FLAGS_VF_IPSEC_EN) if (priv_flags & IXGBE_PRIV_FLAGS_VF_IPSEC_EN)
flags2 |= IXGBE_FLAG2_VF_IPSEC_ENABLED; flags2 |= IXGBE_FLAG2_VF_IPSEC_ENABLED;
flags2 &= ~IXGBE_FLAG2_AUTO_DISABLE_VF;
if (priv_flags & IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF) {
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
/* Reset primary abort counter */
for (i = 0; i < adapter->num_vfs; i++)
adapter->vfinfo[i].primary_abort_count = 0;
flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;
} else {
e_info(probe,
"Cannot set private flags: Operation not supported\n");
return -EOPNOTSUPP;
}
}
if (flags2 != adapter->flags2) { if (flags2 != adapter->flags2) {
adapter->flags2 = flags2; adapter->flags2 = flags2;
......
...@@ -5687,6 +5687,9 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -5687,6 +5687,9 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
/* update setting rx tx for all active vfs */
ixgbe_set_all_vfs(adapter);
} }
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
...@@ -6144,11 +6147,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -6144,11 +6147,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
for (i = 0 ; i < adapter->num_vfs; i++) for (i = 0 ; i < adapter->num_vfs; i++)
adapter->vfinfo[i].clear_to_send = false; adapter->vfinfo[i].clear_to_send = false;
/* ping all the active vfs to let them know we are going down */ /* update setting rx tx for all active vfs */
ixgbe_ping_all_vfs(adapter); ixgbe_set_all_vfs(adapter);
/* Disable all VFTE/VFRE TX/RX */
ixgbe_disable_tx_rx(adapter);
} }
/* disable transmits in the hardware now that interrupts are off */ /* disable transmits in the hardware now that interrupts are off */
...@@ -7613,6 +7613,27 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) ...@@ -7613,6 +7613,27 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
} }
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
static void ixgbe_bad_vf_abort(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
if (adapter->hw.mac.type == ixgbe_mac_82599EB &&
adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) {
adapter->vfinfo[vf].primary_abort_count++;
if (adapter->vfinfo[vf].primary_abort_count ==
IXGBE_PRIMARY_ABORT_LIMIT) {
ixgbe_set_vf_link_state(adapter, vf,
IFLA_VF_LINK_STATE_DISABLE);
adapter->vfinfo[vf].primary_abort_count = 0;
e_info(drv,
"Malicious Driver Detection event detected on PF %d VF %d MAC: %pM mdd-disable-vf=on",
hw->bus.func, vf,
adapter->vfinfo[vf].vf_mac_addresses);
}
}
}
static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
...@@ -7644,9 +7665,11 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) ...@@ -7644,9 +7665,11 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
continue; continue;
pci_read_config_word(vfdev, PCI_STATUS, &status_reg); pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
if (status_reg != IXGBE_FAILED_READ_CFG_WORD && if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
status_reg & PCI_STATUS_REC_MASTER_ABORT) status_reg & PCI_STATUS_REC_MASTER_ABORT) {
ixgbe_bad_vf_abort(adapter, vf);
pcie_flr(vfdev); pcie_flr(vfdev);
} }
}
} }
static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
...@@ -10284,6 +10307,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { ...@@ -10284,6 +10307,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw, .ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk, .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
.ndo_set_vf_link_state = ixgbe_ndo_set_vf_link_state,
.ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en, .ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
.ndo_set_vf_trust = ixgbe_ndo_set_vf_trust, .ndo_set_vf_trust = ixgbe_ndo_set_vf_trust,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config, .ndo_get_vf_config = ixgbe_ndo_get_vf_config,
...@@ -10745,6 +10769,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -10745,6 +10769,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) if (err)
goto err_sw_init; goto err_sw_init;
if (adapter->hw.mac.type == ixgbe_mac_82599EB)
adapter->flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
......
...@@ -85,6 +85,8 @@ enum ixgbe_pfvf_api_rev { ...@@ -85,6 +85,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_IPSEC_ADD 0x0d #define IXGBE_VF_IPSEC_ADD 0x0d
#define IXGBE_VF_IPSEC_DEL 0x0e #define IXGBE_VF_IPSEC_DEL 0x0e
#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */
/* length of permanent address message returned from PF */ /* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4 #define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */ /* word in permanent address message with the current multicast type */
......
...@@ -96,6 +96,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter, ...@@ -96,6 +96,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
for (i = 0; i < num_vfs; i++) { for (i = 0; i < num_vfs; i++) {
/* enable spoof checking for all VFs */ /* enable spoof checking for all VFs */
adapter->vfinfo[i].spoofchk_enabled = true; adapter->vfinfo[i].spoofchk_enabled = true;
adapter->vfinfo[i].link_enable = true;
/* We support VF RSS querying only for 82599 and x540 /* We support VF RSS querying only for 82599 and x540
* devices at the moment. These devices share RSS * devices at the moment. These devices share RSS
...@@ -820,6 +821,57 @@ static inline void ixgbe_write_qde(struct ixgbe_adapter *adapter, u32 vf, ...@@ -820,6 +821,57 @@ static inline void ixgbe_write_qde(struct ixgbe_adapter *adapter, u32 vf,
} }
} }
/**
* ixgbe_set_vf_rx_tx - Set VF rx tx
* @adapter: Pointer to adapter struct
* @vf: VF identifier
*
* Set or reset correct transmit and receive for vf
**/
static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf)
{
u32 reg_cur_tx, reg_cur_rx, reg_req_tx, reg_req_rx;
struct ixgbe_hw *hw = &adapter->hw;
u32 reg_offset, vf_shift;
vf_shift = vf % 32;
reg_offset = vf / 32;
reg_cur_tx = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));
reg_cur_rx = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
if (adapter->vfinfo[vf].link_enable) {
reg_req_tx = reg_cur_tx | 1 << vf_shift;
reg_req_rx = reg_cur_rx | 1 << vf_shift;
} else {
reg_req_tx = reg_cur_tx & ~(1 << vf_shift);
reg_req_rx = reg_cur_rx & ~(1 << vf_shift);
}
/* The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs.
* For more info take a look at ixgbe_set_vf_lpe
*/
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
struct net_device *dev = adapter->netdev;
int pf_max_frame = dev->mtu + ETH_HLEN;
#if IS_ENABLED(CONFIG_FCOE)
if (dev->features & NETIF_F_FCOE_MTU)
pf_max_frame = max_t(int, pf_max_frame,
IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif /* CONFIG_FCOE */
if (pf_max_frame > ETH_FRAME_LEN)
reg_req_rx = reg_cur_rx & ~(1 << vf_shift);
}
/* Enable/Disable particular VF */
if (reg_cur_tx != reg_req_tx)
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg_req_tx);
if (reg_cur_rx != reg_req_rx)
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg_req_rx);
}
static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
{ {
struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
...@@ -845,11 +897,6 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) ...@@ -845,11 +897,6 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
vf_shift = vf % 32; vf_shift = vf % 32;
reg_offset = vf / 32; reg_offset = vf / 32;
/* enable transmit for vf */
reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));
reg |= BIT(vf_shift);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg);
/* force drop enable for all VF Rx queues */ /* force drop enable for all VF Rx queues */
reg = IXGBE_QDE_ENABLE; reg = IXGBE_QDE_ENABLE;
if (adapter->vfinfo[vf].pf_vlan) if (adapter->vfinfo[vf].pf_vlan)
...@@ -857,27 +904,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) ...@@ -857,27 +904,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
ixgbe_write_qde(adapter, vf, reg); ixgbe_write_qde(adapter, vf, reg);
/* enable receive for vf */ ixgbe_set_vf_rx_tx(adapter, vf);
reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
reg |= BIT(vf_shift);
/*
* The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs.
* For more info take a look at ixgbe_set_vf_lpe
*/
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
struct net_device *dev = adapter->netdev;
int pf_max_frame = dev->mtu + ETH_HLEN;
#ifdef CONFIG_FCOE
if (dev->features & NETIF_F_FCOE_MTU)
pf_max_frame = max_t(int, pf_max_frame,
IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif /* CONFIG_FCOE */
if (pf_max_frame > ETH_FRAME_LEN)
reg &= ~BIT(vf_shift);
}
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg);
/* enable VF mailbox for further messages */ /* enable VF mailbox for further messages */
adapter->vfinfo[vf].clear_to_send = true; adapter->vfinfo[vf].clear_to_send = true;
...@@ -1202,6 +1229,26 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter, ...@@ -1202,6 +1229,26 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
return 0; return 0;
} }
static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter,
u32 *msgbuf, u32 vf)
{
u32 *link_state = &msgbuf[1];
/* verify the PF is supporting the correct API */
switch (adapter->vfinfo[vf].vf_api) {
case ixgbe_mbox_api_12:
case ixgbe_mbox_api_13:
case ixgbe_mbox_api_14:
break;
default:
return -EOPNOTSUPP;
}
*link_state = adapter->vfinfo[vf].link_enable;
return 0;
}
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{ {
u32 mbx_size = IXGBE_VFMAILBOX_SIZE; u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
...@@ -1267,6 +1314,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) ...@@ -1267,6 +1314,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
case IXGBE_VF_UPDATE_XCAST_MODE: case IXGBE_VF_UPDATE_XCAST_MODE:
retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf); retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf);
break; break;
case IXGBE_VF_GET_LINK_STATE:
retval = ixgbe_get_vf_link_state(adapter, msgbuf, vf);
break;
case IXGBE_VF_IPSEC_ADD: case IXGBE_VF_IPSEC_ADD:
retval = ixgbe_ipsec_vf_add_sa(adapter, msgbuf, vf); retval = ixgbe_ipsec_vf_add_sa(adapter, msgbuf, vf);
break; break;
...@@ -1322,18 +1372,6 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter) ...@@ -1322,18 +1372,6 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
} }
} }
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
/* disable transmit and receive for all vfs */
IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
}
static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf) static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
...@@ -1359,6 +1397,21 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter) ...@@ -1359,6 +1397,21 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
} }
} }
/**
* ixgbe_set_all_vfs - update vfs queues
* @adapter: Pointer to adapter struct
*
* Update setting transmit and receive queues for all vfs
**/
void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter)
{
int i;
for (i = 0 ; i < adapter->num_vfs; i++)
ixgbe_set_vf_link_state(adapter, i,
adapter->vfinfo[i].link_state);
}
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
...@@ -1656,6 +1709,84 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) ...@@ -1656,6 +1709,84 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
return 0; return 0;
} }
/**
* ixgbe_set_vf_link_state - Set link state
* @adapter: Pointer to adapter struct
* @vf: VF identifier
* @state: required link state
*
* Set a link force state on/off a single vf
**/
void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state)
{
adapter->vfinfo[vf].link_state = state;
switch (state) {
case IFLA_VF_LINK_STATE_AUTO:
if (test_bit(__IXGBE_DOWN, &adapter->state))
adapter->vfinfo[vf].link_enable = false;
else
adapter->vfinfo[vf].link_enable = true;
break;
case IFLA_VF_LINK_STATE_ENABLE:
adapter->vfinfo[vf].link_enable = true;
break;
case IFLA_VF_LINK_STATE_DISABLE:
adapter->vfinfo[vf].link_enable = false;
break;
}
ixgbe_set_vf_rx_tx(adapter, vf);
/* restart the VF */
adapter->vfinfo[vf].clear_to_send = false;
ixgbe_ping_vf(adapter, vf);
}
/**
* ixgbe_ndo_set_vf_link_state - Set link state
* @netdev: network interface device structure
* @vf: VF identifier
* @state: required link state
*
* Set the link state of a specified VF, regardless of physical link state
**/
int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int ret = 0;
if (vf < 0 || vf >= adapter->num_vfs) {
dev_err(&adapter->pdev->dev,
"NDO set VF link - invalid VF identifier %d\n", vf);
return -EINVAL;
}
switch (state) {
case IFLA_VF_LINK_STATE_ENABLE:
dev_info(&adapter->pdev->dev,
"NDO set VF %d link state %d - not supported\n",
vf, state);
break;
case IFLA_VF_LINK_STATE_DISABLE:
dev_info(&adapter->pdev->dev,
"NDO set VF %d link state disable\n", vf);
ixgbe_set_vf_link_state(adapter, vf, state);
break;
case IFLA_VF_LINK_STATE_AUTO:
dev_info(&adapter->pdev->dev,
"NDO set VF %d link state auto\n", vf);
ixgbe_set_vf_link_state(adapter, vf, state);
break;
default:
dev_err(&adapter->pdev->dev,
"NDO set VF %d - invalid link state %d\n", vf, state);
ret = -EINVAL;
}
return ret;
}
int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
bool setting) bool setting)
{ {
......
...@@ -17,8 +17,8 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter); ...@@ -17,8 +17,8 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
#endif #endif
void ixgbe_msg_task(struct ixgbe_adapter *adapter); void ixgbe_msg_task(struct ixgbe_adapter *adapter);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter);
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
u8 qos, __be16 vlan_proto); u8 qos, __be16 vlan_proto);
...@@ -31,7 +31,9 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, ...@@ -31,7 +31,9 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting); int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting);
int ixgbe_ndo_get_vf_config(struct net_device *netdev, int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi); int vf, struct ifla_vf_info *ivi);
int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state);
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter); int ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs); void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs);
......
...@@ -387,6 +387,8 @@ struct ixgbevf_adapter { ...@@ -387,6 +387,8 @@ struct ixgbevf_adapter {
u32 *rss_key; u32 *rss_key;
u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE]; u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE];
u32 flags; u32 flags;
bool link_state;
#define IXGBEVF_FLAGS_LEGACY_RX BIT(1) #define IXGBEVF_FLAGS_LEGACY_RX BIT(1)
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
......
...@@ -2298,7 +2298,9 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) ...@@ -2298,7 +2298,9 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
bool state;
ixgbevf_configure_msix(adapter); ixgbevf_configure_msix(adapter);
...@@ -2311,6 +2313,11 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) ...@@ -2311,6 +2313,11 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
spin_unlock_bh(&adapter->mbx_lock); spin_unlock_bh(&adapter->mbx_lock);
state = adapter->link_state;
hw->mac.ops.get_link_state(hw, &adapter->link_state);
if (state && state != adapter->link_state)
dev_info(&pdev->dev, "VF is administratively disabled\n");
smp_mb__before_atomic(); smp_mb__before_atomic();
clear_bit(__IXGBEVF_DOWN, &adapter->state); clear_bit(__IXGBEVF_DOWN, &adapter->state);
ixgbevf_napi_enable_all(adapter); ixgbevf_napi_enable_all(adapter);
...@@ -3081,6 +3088,8 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter) ...@@ -3081,6 +3088,8 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD; adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD; adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD;
adapter->link_state = true;
set_bit(__IXGBEVF_DOWN, &adapter->state); set_bit(__IXGBEVF_DOWN, &adapter->state);
return 0; return 0;
...@@ -3313,7 +3322,7 @@ static void ixgbevf_watchdog_subtask(struct ixgbevf_adapter *adapter) ...@@ -3313,7 +3322,7 @@ static void ixgbevf_watchdog_subtask(struct ixgbevf_adapter *adapter)
ixgbevf_watchdog_update_link(adapter); ixgbevf_watchdog_update_link(adapter);
if (adapter->link_up) if (adapter->link_up && adapter->link_state)
ixgbevf_watchdog_link_is_up(adapter); ixgbevf_watchdog_link_is_up(adapter);
else else
ixgbevf_watchdog_link_is_down(adapter); ixgbevf_watchdog_link_is_down(adapter);
......
...@@ -100,6 +100,8 @@ enum ixgbe_pfvf_api_rev { ...@@ -100,6 +100,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_IPSEC_ADD 0x0d #define IXGBE_VF_IPSEC_ADD 0x0d
#define IXGBE_VF_IPSEC_DEL 0x0e #define IXGBE_VF_IPSEC_DEL 0x0e
#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */
/* length of permanent address message returned from PF */ /* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4 #define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */ /* word in permanent address message with the current multicast type */
......
...@@ -584,6 +584,46 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) ...@@ -584,6 +584,46 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
/**
* ixgbevf_get_link_state_vf - Get VF link state from PF
* @hw: pointer to the HW structure
* @link_state: link state storage
*
* Returns state of the operation error or success.
*/
static s32 ixgbevf_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state)
{
u32 msgbuf[2];
s32 ret_val;
s32 err;
msgbuf[0] = IXGBE_VF_GET_LINK_STATE;
msgbuf[1] = 0x0;
err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) {
ret_val = IXGBE_ERR_MBX;
} else {
ret_val = 0;
*link_state = msgbuf[1];
}
return ret_val;
}
/**
* ixgbevf_hv_get_link_state_vf - * Hyper-V variant - just a stub.
* @hw: unused
* @link_state: unused
*
* Hyper-V variant; there is no mailbox communication.
*/
static s32 ixgbevf_hv_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state)
{
return -EOPNOTSUPP;
}
/** /**
* ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address * ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
...@@ -968,6 +1008,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = { ...@@ -968,6 +1008,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
.set_rar = ixgbevf_set_rar_vf, .set_rar = ixgbevf_set_rar_vf,
.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
.update_xcast_mode = ixgbevf_update_xcast_mode, .update_xcast_mode = ixgbevf_update_xcast_mode,
.get_link_state = ixgbevf_get_link_state_vf,
.set_uc_addr = ixgbevf_set_uc_addr_vf, .set_uc_addr = ixgbevf_set_uc_addr_vf,
.set_vfta = ixgbevf_set_vfta_vf, .set_vfta = ixgbevf_set_vfta_vf,
.set_rlpml = ixgbevf_set_rlpml_vf, .set_rlpml = ixgbevf_set_rlpml_vf,
...@@ -985,6 +1026,7 @@ static const struct ixgbe_mac_operations ixgbevf_hv_mac_ops = { ...@@ -985,6 +1026,7 @@ static const struct ixgbe_mac_operations ixgbevf_hv_mac_ops = {
.set_rar = ixgbevf_hv_set_rar_vf, .set_rar = ixgbevf_hv_set_rar_vf,
.update_mc_addr_list = ixgbevf_hv_update_mc_addr_list_vf, .update_mc_addr_list = ixgbevf_hv_update_mc_addr_list_vf,
.update_xcast_mode = ixgbevf_hv_update_xcast_mode, .update_xcast_mode = ixgbevf_hv_update_xcast_mode,
.get_link_state = ixgbevf_hv_get_link_state_vf,
.set_uc_addr = ixgbevf_hv_set_uc_addr_vf, .set_uc_addr = ixgbevf_hv_set_uc_addr_vf,
.set_vfta = ixgbevf_hv_set_vfta_vf, .set_vfta = ixgbevf_hv_set_vfta_vf,
.set_rlpml = ixgbevf_hv_set_rlpml_vf, .set_rlpml = ixgbevf_hv_set_rlpml_vf,
......
...@@ -39,6 +39,7 @@ struct ixgbe_mac_operations { ...@@ -39,6 +39,7 @@ struct ixgbe_mac_operations {
s32 (*init_rx_addrs)(struct ixgbe_hw *); s32 (*init_rx_addrs)(struct ixgbe_hw *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
s32 (*update_xcast_mode)(struct ixgbe_hw *, int); s32 (*update_xcast_mode)(struct ixgbe_hw *, int);
s32 (*get_link_state)(struct ixgbe_hw *hw, bool *link_state);
s32 (*enable_mc)(struct ixgbe_hw *); s32 (*enable_mc)(struct ixgbe_hw *);
s32 (*disable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *);
s32 (*clear_vfta)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *);
......
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