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 e257390a4f6a109373bacd1e2f9713f952987c5e..149c733fcc2b340837e518983fbf63ad88e55753 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 84222ec2393c57a8912b3781a443a960be38c03f..55b87bc3a938b6af69fe3fcf920a33224508e0a4 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 7346ccf014a56b3bc2eaa9587e38579695a4c249..835bbcc5cc8e6339a2c999560606a8f990d8e859 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 61d8970c6d1de3165e37b08043b8fd73bf53bcd0..68fc32e36e880e07da72fbd4af757a206094d888 100644 (file)
@@ -584,6 +584,46 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
        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
  *  @hw: pointer to the HW structure
@@ -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 54158dac870728388ab22c26c458740a610e36df..b4eef5b6c172bd68b136c48e1e5d1d047099defc 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 *);