]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ixgbe, ixgbevf: Add new mbox API xcast mode
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Fri, 28 Aug 2015 06:59:03 +0000 (06:59 +0000)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 6 Jul 2016 23:39:59 +0000 (16:39 -0700)
Orabug: 23177316

The limitation of the number of multicast address for VF is not enough
for the large scale server with SR-IOV feature. IPv6 requires the multicast
MAC address for each IP address to handle the Neighbor Solicitation
message. We couldn't assign over 30 IPv6 addresses to a single VF.

This patch introduces the new mailbox API, IXGBE_VF_UPDATE_XCAST_MODE,
to update multicast mode of VF. This adds 3 modes;
  - NONE     only L2 exact match addresses or Flow Director enabled
  - MULTI    BAM and ROMPE set
  - ALLMULTI BAM, ROMPE and MPE set

If a guest VF user wants over 30 MAC multicast addresses, set IFF_ALLMULTI
to request PF to update xcast mode to enable VF multicast promiscuous mode.

On the other hand, enabling VF multicast promiscuous mode may affect
security and performance in the network of the NIC. Only trusted VF can
enable multicast promiscuous mode. The behavior of untrusted VF is the
same as previous version.

Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
(cherry picked from commit 8443c1a4b192089e62642d847ebac3e4d15134c3)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
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 dda0f678339ad88e02904787b446e7ad1db5c99b..1d2174526a4c909422ada878ac9dc13c60d7c513 100644 (file)
@@ -152,9 +152,17 @@ struct vf_data_storage {
        u16 vlan_count;
        u8 spoofchk_enabled;
        bool rss_query_enabled;
+       u8 trusted;
+       int xcast_mode;
        unsigned int vf_api;
 };
 
+enum ixgbevf_xcast_modes {
+       IXGBEVF_XCAST_MODE_NONE = 0,
+       IXGBEVF_XCAST_MODE_MULTI,
+       IXGBEVF_XCAST_MODE_ALLMULTI,
+};
+
 struct vf_macvlans {
        struct list_head l;
        int vf;
index b1e4703ff2a5949fc4c35db6c0c1cd1dceea6675..8daa95f74548857fbb44f9e05c724b9c09052db3 100644 (file)
@@ -102,6 +102,8 @@ enum ixgbe_pfvf_api_rev {
 #define IXGBE_VF_GET_RETA      0x0a    /* VF request for RETA */
 #define IXGBE_VF_GET_RSS_KEY   0x0b    /* get RSS key */
 
+#define IXGBE_VF_UPDATE_XCAST_MODE     0x0c
+
 /* 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 1d17b5872dd1f266625891b600d673c98a8cfa0f..0b9ef8dac69714b11343a497dcd26e3eff2fd57a 100644 (file)
@@ -116,6 +116,9 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
                         * we want to disable the querying by default.
                         */
                        adapter->vfinfo[i].rss_query_enabled = 0;
+
+                       /* set the default xcast mode */
+                       adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;
                }
 
                return 0;
@@ -1001,6 +1004,59 @@ static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter,
        return 0;
 }
 
+static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
+                                     u32 *msgbuf, u32 vf)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       int xcast_mode = msgbuf[1];
+       u32 vmolr, disable, enable;
+
+       /* verify the PF is supporting the correct APIs */
+       switch (adapter->vfinfo[vf].vf_api) {
+       case ixgbe_mbox_api_12:
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       if (xcast_mode > IXGBEVF_XCAST_MODE_MULTI &&
+           !adapter->vfinfo[vf].trusted) {
+               xcast_mode = IXGBEVF_XCAST_MODE_MULTI;
+       }
+
+       if (adapter->vfinfo[vf].xcast_mode == xcast_mode)
+               goto out;
+
+       switch (xcast_mode) {
+       case IXGBEVF_XCAST_MODE_NONE:
+               disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE;
+               enable = 0;
+               break;
+       case IXGBEVF_XCAST_MODE_MULTI:
+               disable = IXGBE_VMOLR_MPE;
+               enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE;
+               break;
+       case IXGBEVF_XCAST_MODE_ALLMULTI:
+               disable = 0;
+               enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+       vmolr &= ~disable;
+       vmolr |= enable;
+       IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+
+       adapter->vfinfo[vf].xcast_mode = xcast_mode;
+
+out:
+       msgbuf[1] = xcast_mode;
+
+       return 0;
+}
+
 static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
 {
        u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -1063,6 +1119,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
        case IXGBE_VF_GET_RSS_KEY:
                retval = ixgbe_get_vf_rss_key(adapter, msgbuf, vf);
                break;
+       case IXGBE_VF_UPDATE_XCAST_MODE:
+               retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf);
+               break;
        default:
                e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
                retval = IXGBE_ERR_MBX;
index 04c7ec8446e0329c71eaee8eea346a4e92836b8e..ec31472796213197fe50d163ce0473a0d34df7fe 100644 (file)
@@ -471,6 +471,12 @@ enum ixgbevf_boards {
        board_X550EM_x_vf,
 };
 
+enum ixgbevf_xcast_modes {
+       IXGBEVF_XCAST_MODE_NONE = 0,
+       IXGBEVF_XCAST_MODE_MULTI,
+       IXGBEVF_XCAST_MODE_ALLMULTI,
+};
+
 extern const struct ixgbevf_info ixgbevf_82599_vf_info;
 extern const struct ixgbevf_info ixgbevf_X540_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550_vf_info;
index 35da2d74e73ecc74f567a528cb2ebffd9a25edcd..3bcfd78e2fb618e0147810d7f6a146cd8c1cb4ef 100644 (file)
@@ -1892,9 +1892,17 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
 {
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       unsigned int flags = netdev->flags;
+       int xcast_mode;
+
+       xcast_mode = (flags & IFF_ALLMULTI) ? IXGBEVF_XCAST_MODE_ALLMULTI :
+                    (flags & (IFF_BROADCAST | IFF_MULTICAST)) ?
+                    IXGBEVF_XCAST_MODE_MULTI : IXGBEVF_XCAST_MODE_NONE;
 
        spin_lock_bh(&adapter->mbx_lock);
 
+       hw->mac.ops.update_xcast_mode(hw, netdev, xcast_mode);
+
        /* reprogram multicast list */
        hw->mac.ops.update_mc_addr_list(hw, netdev);
 
index 82f44e06e5fca11ad86ec92930428fbbc130c93d..340cdd469455ef646f38b25bd0ecde62788976ce 100644 (file)
@@ -112,6 +112,8 @@ enum ixgbe_pfvf_api_rev {
 #define IXGBE_VF_GET_RETA      0x0a    /* VF request for RETA */
 #define IXGBE_VF_GET_RSS_KEY   0x0b    /* get RSS hash key */
 
+#define IXGBE_VF_UPDATE_XCAST_MODE     0x0c
+
 /* 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 d1339b0506274ce0acbfc1e642b1b7fa57c332e8..427f3605cbfc8035f03910d564eeb5e707a5c58c 100644 (file)
@@ -468,6 +468,46 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
        return 0;
 }
 
+/**
+ *  ixgbevf_update_xcast_mode - Update Multicast mode
+ *  @hw: pointer to the HW structure
+ *  @netdev: pointer to net device structure
+ *  @xcast_mode: new multicast mode
+ *
+ *  Updates the Multicast Mode of VF.
+ **/
+static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw,
+                                    struct net_device *netdev, int xcast_mode)
+{
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       u32 msgbuf[2];
+       s32 err;
+
+       switch (hw->api_version) {
+       case ixgbe_mbox_api_12:
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
+       msgbuf[1] = xcast_mode;
+
+       err = mbx->ops.write_posted(hw, msgbuf, 2);
+       if (err)
+               return err;
+
+       err = mbx->ops.read_posted(hw, msgbuf, 2);
+       if (err)
+               return err;
+
+       msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+       if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK))
+               return -EPERM;
+
+       return 0;
+}
+
 /**
  *  ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
  *  @hw: pointer to the HW structure
@@ -727,6 +767,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
        .check_link             = ixgbevf_check_mac_link_vf,
        .set_rar                = ixgbevf_set_rar_vf,
        .update_mc_addr_list    = ixgbevf_update_mc_addr_list_vf,
+       .update_xcast_mode      = ixgbevf_update_xcast_mode,
        .set_uc_addr            = ixgbevf_set_uc_addr_vf,
        .set_vfta               = ixgbevf_set_vfta_vf,
 };
index d40f036b6df0c828b5a3efe10ee90ba780b36a52..ef9f7736b4dc6524ea12ea96c31c2218c6600f76 100644 (file)
@@ -63,6 +63,7 @@ struct ixgbe_mac_operations {
        s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
        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 *, struct net_device *, int);
        s32 (*enable_mc)(struct ixgbe_hw *);
        s32 (*disable_mc)(struct ixgbe_hw *);
        s32 (*clear_vfta)(struct ixgbe_hw *);