[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