> -----Original Message-----
> From: Hiroshi Shimamoto [mailto:h-shimam...@ct.jp.nec.com]
> Sent: Thursday, July 16, 2015 3:36 AM
> To: Alexander Duyck; Skidmore, Donald C; Rose, Gregory V; Kirsher, Jeffrey
> T; intel-wired-...@lists.osuosl.org
> Cc: nhor...@redhat.com; jogre...@redhat.com; Linux Netdev List; Choi,
> Sy Jong; Rony Efraim; Or Gerlitz; Edward Cree; David Miller;
> sassm...@redhat.com
> Subject: [PATCH v7 3/3] ixgbe, ixgbevf: Add new mbox API xcast mode
> 
> From: Hiroshi Shimamoto <h-shimam...@ct.jp.nec.com>
> 
> 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-shimam...@ct.jp.nec.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h          |  7 +++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h      |  2 +
>  drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c    | 59
> +++++++++++++++++++++++
>  drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |  6 +++
>  drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  8 +++
>  drivers/net/ethernet/intel/ixgbevf/mbx.h          |  2 +
>  drivers/net/ethernet/intel/ixgbevf/vf.c           | 41 ++++++++++++++++
>  drivers/net/ethernet/intel/ixgbevf/vf.h           |  1 +
>  8 files changed, 126 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index fb72622..17250ef 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -153,9 +153,16 @@ struct vf_data_storage {
>       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;
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
> index b1e4703..8daa95f 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
> @@ -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 */
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> index 65aeb58..ac071e5 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> @@ -119,6 +119,9 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter
> *adapter)
> 
>                       /* Untrust all VFs */
>                       adapter->vfinfo[i].trusted = false;
> +
> +                     /* set the default xcast mode */
> +                     adapter->vfinfo[i].xcast_mode =
> IXGBEVF_XCAST_MODE_NONE;
>               }
> 
>               return 0;
> @@ -1004,6 +1007,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 -1;

Shouldn't you 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 -1;
> +     }
> +
> +     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;
> @@ -1066,6 +1122,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;
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> index 04c7ec8..ec31472 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> @@ -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; diff --git
> a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> index 88298a3..a9fed92 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> @@ -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);
> 
> diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h
> b/drivers/net/ethernet/intel/ixgbevf/mbx.h
> index 82f44e0..340cdd4 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/mbx.h
> +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h
> @@ -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 */
> diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c
> b/drivers/net/ethernet/intel/ixgbevf/vf.c
> index d1339b0..427f360 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/vf.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
> @@ -469,6 +469,46 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct
> ixgbe_hw *hw,  }
> 
>  /**
> + *  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
>   *  @vlan: 12 bit VLAN ID
> @@ -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,
>  };
> diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h
> b/drivers/net/ethernet/intel/ixgbevf/vf.h
> index d40f036..ef9f773 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/vf.h
> +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
> @@ -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 *);
> --
> 1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to