OSDN Git Service

ixgbevf: add disable link state
authorSlawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Tue, 1 Mar 2022 11:40:10 +0000 (11:40 +0000)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 8 Mar 2022 15:41:18 +0000 (07:41 -0800)
Add possibility to disable link state if it is administratively
disabled in PF.

It is part of the general functionality that allows the PF driver
to control the state of the virtual link VF devices.

Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/intel/ixgbevf/mbx.h
drivers/net/ethernet/intel/ixgbevf/vf.c
drivers/net/ethernet/intel/ixgbevf/vf.h

index e257390..149c733 100644 (file)
@@ -387,6 +387,8 @@ struct ixgbevf_adapter {
        u32 *rss_key;
        u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE];
        u32 flags;
+       bool link_state;
+
 #define IXGBEVF_FLAGS_LEGACY_RX                BIT(1)
 
 #ifdef CONFIG_XFRM
index 84222ec..55b87bc 100644 (file)
@@ -2298,7 +2298,9 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
 static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
        struct ixgbe_hw *hw = &adapter->hw;
+       bool state;
 
        ixgbevf_configure_msix(adapter);
 
@@ -2311,6 +2313,11 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
 
        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();
        clear_bit(__IXGBEVF_DOWN, &adapter->state);
        ixgbevf_napi_enable_all(adapter);
@@ -3081,6 +3088,8 @@ static int ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
        adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
        adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD;
 
+       adapter->link_state = true;
+
        set_bit(__IXGBEVF_DOWN, &adapter->state);
        return 0;
 
@@ -3313,7 +3322,7 @@ static void ixgbevf_watchdog_subtask(struct ixgbevf_adapter *adapter)
 
        ixgbevf_watchdog_update_link(adapter);
 
-       if (adapter->link_up)
+       if (adapter->link_up && adapter->link_state)
                ixgbevf_watchdog_link_is_up(adapter);
        else
                ixgbevf_watchdog_link_is_down(adapter);
index 7346ccf..835bbcc 100644 (file)
@@ -100,6 +100,8 @@ enum ixgbe_pfvf_api_rev {
 #define IXGBE_VF_IPSEC_ADD     0x0d
 #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 */
 #define IXGBE_VF_PERMADDR_MSG_LEN      4
 /* word in permanent address message with the current multicast type */
index 61d8970..68fc32e 100644 (file)
@@ -585,6 +585,46 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
 }
 
 /**
+ * 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
  *  @hw: pointer to the HW structure
  *  @vlan: 12 bit VLAN ID
@@ -968,6 +1008,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
        .set_rar                = ixgbevf_set_rar_vf,
        .update_mc_addr_list    = ixgbevf_update_mc_addr_list_vf,
        .update_xcast_mode      = ixgbevf_update_xcast_mode,
+       .get_link_state         = ixgbevf_get_link_state_vf,
        .set_uc_addr            = ixgbevf_set_uc_addr_vf,
        .set_vfta               = ixgbevf_set_vfta_vf,
        .set_rlpml              = ixgbevf_set_rlpml_vf,
@@ -985,6 +1026,7 @@ static const struct ixgbe_mac_operations ixgbevf_hv_mac_ops = {
        .set_rar                = ixgbevf_hv_set_rar_vf,
        .update_mc_addr_list    = ixgbevf_hv_update_mc_addr_list_vf,
        .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_vfta               = ixgbevf_hv_set_vfta_vf,
        .set_rlpml              = ixgbevf_hv_set_rlpml_vf,
index 54158da..b4eef5b 100644 (file)
@@ -39,6 +39,7 @@ struct ixgbe_mac_operations {
        s32 (*init_rx_addrs)(struct ixgbe_hw *);
        s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
        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 (*disable_mc)(struct ixgbe_hw *);
        s32 (*clear_vfta)(struct ixgbe_hw *);