[Intel-wired-lan] [PATCH v7 3/3] ixgbe, ixgbevf: Add new mbox API xcast mode
Skidmore, Donald C
donald.c.skidmore at intel.com
Fri Jul 17 15:01:15 UTC 2015
> -----Original Message-----
> From: Hiroshi Shimamoto [mailto:h-shimamoto at 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-lan at lists.osuosl.org
> Cc: nhorman at redhat.com; jogreene at redhat.com; Linux Netdev List; Choi,
> Sy Jong; Rony Efraim; Or Gerlitz; Edward Cree; David Miller;
> sassmann at redhat.com
> Subject: [PATCH v7 3/3] ixgbe, ixgbevf: Add new mbox API xcast mode
>
> From: Hiroshi Shimamoto <h-shimamoto at 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-shimamoto at 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
More information about the Intel-wired-lan
mailing list