From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763422AbbA3WNz (ORCPT ); Fri, 30 Jan 2015 17:13:55 -0500 Received: from mga14.intel.com ([192.55.52.115]:40441 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750876AbbA3WNx (ORCPT ); Fri, 30 Jan 2015 17:13:53 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,494,1418112000"; d="scan'208";a="670529844" From: "Skidmore, Donald C" To: Hiroshi Shimamoto , Alexander Duyck , =?utf-8?B?QmrDuHJuIE1vcms=?= CC: "e1000-devel@lists.sourceforge.net" , "netdev@vger.kernel.org" , "Choi, Sy Jong" , "linux-kernel@vger.kernel.org" , David Laight , Hayato Momma Subject: RE: [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to enable MC promiscuous mode Thread-Topic: [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to enable MC promiscuous mode Thread-Index: AdA8gILJ9d8j0iGaQsK8UkGMtKROiQAWTkmw Date: Fri, 30 Jan 2015 22:13:49 +0000 Message-ID: References: <7F861DC0615E0C47A872E6F3C5FCDDBD05E1908D@BPXM14GP.gisp.nec.co.jp> In-Reply-To: <7F861DC0615E0C47A872E6F3C5FCDDBD05E1908D@BPXM14GP.gisp.nec.co.jp> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.138] Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by nfs id t0UME2rK026351 > -----Original Message----- > From: Hiroshi Shimamoto [mailto:h-shimamoto@ct.jp.nec.com] > Sent: Friday, January 30, 2015 3:37 AM > To: Alexander Duyck; Skidmore, Donald C; Bjørn Mork > Cc: e1000-devel@lists.sourceforge.net; netdev@vger.kernel.org; Choi, Sy > Jong; linux-kernel@vger.kernel.org; David Laight; Hayato Momma > Subject: [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to enable MC > promiscuous mode > > From: Hiroshi Shimamoto > > 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 interface. > > The easy way to solve this is enabling multicast promiscuous mode. > It is good to have a functionality to enable multicast promiscuous mode for > each VF from VF driver. > > This patch introduces the new mbox API, IXGBE_VF_SET_MC_PROMISC, to > enable/disable multicast promiscuous mode in VF. If multicast promiscuous > mode is enabled the VF can receive all multicast packets. > > With this patch, the ixgbevf driver automatically enable multicast > promiscuous mode when the number of multicast addresses is over than 30 > if possible. > > This also bump the API version up to 1.2 to check whether the API, > IXGBE_VF_SET_MC_PROMISC is available. > > Signed-off-by: Hiroshi Shimamoto > Reviewed-by: Hayato Momma > CC: Choi, Sy Jong > --- > drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 + > drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 4 + > drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 89 > ++++++++++++++++++++++- > drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 13 +++- > drivers/net/ethernet/intel/ixgbevf/mbx.h | 4 + > drivers/net/ethernet/intel/ixgbevf/vf.c | 29 +++++++- > drivers/net/ethernet/intel/ixgbevf/vf.h | 1 + > 7 files changed, 137 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h > b/drivers/net/ethernet/intel/ixgbe/ixgbe.h > index b6137be..bf3333e 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h > @@ -144,6 +144,7 @@ struct vf_data_storage { > u16 vlans_enabled; > bool clear_to_send; > bool pf_set_mac; > + bool mc_promisc; > u16 pf_vlan; /* When set, guest VLAN config not allowed. */ > u16 pf_qos; > u16 tx_rate; > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h > b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h > index a5cb755..2963557 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h > @@ -73,6 +73,7 @@ enum ixgbe_pfvf_api_rev { > ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ > ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ > ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ > + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ > /* This value should always be last */ > ixgbe_mbox_api_unknown, /* indicates that API version is not > known */ > }; > @@ -91,6 +92,9 @@ enum ixgbe_pfvf_api_rev { > /* mailbox API, version 1.1 VF requests */ > #define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ > > +/* mailbox API, version 1.2 VF requests */ > +#define IXGBE_VF_SET_MC_PROMISC 0x0a /* VF requests PF to set > MC promiscuous */ > + > /* GET_QUEUES return data indices within the mailbox */ > #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues > supported */ > #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues > supported */ > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c > b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c > index c76ba90..c19b7b8 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c > @@ -108,9 +108,12 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter > *adapter) > adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE | > IXGBE_FLAG2_RSC_ENABLED); > > - /* enable spoof checking for all VFs */ > - for (i = 0; i < adapter->num_vfs; i++) > + for (i = 0; i < adapter->num_vfs; i++) { > + /* Enable spoof checking for all VFs */ > adapter->vfinfo[i].spoofchk_enabled = true; > + /* Turn multicast promiscuous mode off for all VFs */ > + adapter->vfinfo[i].mc_promisc = false; > + } > return 0; > } > > @@ -311,6 +314,40 @@ int ixgbe_pci_sriov_configure(struct pci_dev *dev, > int num_vfs) > return ixgbe_pci_sriov_enable(dev, num_vfs); } > > +static int ixgbe_enable_vf_mc_promisc(struct ixgbe_adapter *adapter, > +u32 vf) { > + struct ixgbe_hw *hw; > + u32 vmolr; > + > + hw = &adapter->hw; > + vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); > + > + e_info(drv, "VF %u: enabling multicast promiscuous\n", vf); > + > + vmolr |= IXGBE_VMOLR_MPE; > + > + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); > + > + return 0; > +} > + > +static int ixgbe_disable_vf_mc_promisc(struct ixgbe_adapter *adapter, > +u32 vf) { > + struct ixgbe_hw *hw; > + u32 vmolr; > + > + hw = &adapter->hw; > + vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); > + > + e_info(drv, "VF %u: disabling multicast promiscuous\n", vf); > + > + vmolr &= ~IXGBE_VMOLR_MPE; > + > + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); > + > + return 0; > +} > + > static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, > u32 *msgbuf, u32 vf) > { > @@ -325,6 +362,12 @@ static int ixgbe_set_vf_multicasts(struct > ixgbe_adapter *adapter, > u32 mta_reg; > u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); > > + /* Disable multicast promiscuous first */ > + if (adapter->vfinfo[vf].mc_promisc) { > + ixgbe_disable_vf_mc_promisc(adapter, vf); > + adapter->vfinfo[vf].mc_promisc = false; > + } > + > /* only so many hash values supported */ > entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES); > > @@ -427,6 +470,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter > *adapter, u32 *msgbuf, u32 vf) #endif /* CONFIG_FCOE */ > switch (adapter->vfinfo[vf].vf_api) { > case ixgbe_mbox_api_11: > + case ixgbe_mbox_api_12: > /* > * Version 1.1 supports jumbo frames on VFs if PF has > * jumbo frames enabled which means legacy VFs are > @@ -710,6 +754,12 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter > *adapter, u32 vf) > IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBALn(q_per_pool, > vf, i), 0); > } > > + /* Disable multicast promiscuous at reset */ > + if (adapter->vfinfo[vf].mc_promisc) { > + ixgbe_disable_vf_mc_promisc(adapter, vf); > + adapter->vfinfo[vf].mc_promisc = false; > + } > + > /* reply to reset with ack and vf mac address */ > msgbuf[0] = IXGBE_VF_RESET; > if (!is_zero_ether_addr(vf_mac)) { > @@ -894,6 +944,12 @@ static int ixgbe_negotiate_vf_api(struct > ixgbe_adapter *adapter, > switch (api) { > case ixgbe_mbox_api_10: > case ixgbe_mbox_api_11: > + case ixgbe_mbox_api_12: > + e_info(drv, "VF %d requested api_version %s\n", vf, > + (api == ixgbe_mbox_api_12) ? "ixgbe_mbox_api_12" > : > + (api == ixgbe_mbox_api_11) ? "ixgbe_mbox_api_11" > : > + (api == ixgbe_mbox_api_10) ? "ixgbe_mbox_api_10" > : > + "unknown"); > adapter->vfinfo[vf].vf_api = api; > return 0; > default: > @@ -917,6 +973,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter > *adapter, > switch (adapter->vfinfo[vf].vf_api) { > case ixgbe_mbox_api_20: > case ixgbe_mbox_api_11: > + case ixgbe_mbox_api_12: > break; > default: > return -1; > @@ -944,6 +1001,31 @@ static int ixgbe_get_vf_queues(struct > ixgbe_adapter *adapter, > return 0; > } > > +static int ixgbe_set_vf_mc_promisc(struct ixgbe_adapter *adapter, > + u32 *msgbuf, u32 vf) > +{ > + bool enable = !!msgbuf[1]; /* msgbuf contains the flag to enable > */ > + > + switch (adapter->vfinfo[vf].vf_api) { > + case ixgbe_mbox_api_12: > + break; > + default: > + return -1; > + } > + > + /* nothing to do */ > + if (adapter->vfinfo[vf].mc_promisc == enable) > + return 0; > + > + adapter->vfinfo[vf].mc_promisc = enable; > + > + if (enable) > + return ixgbe_enable_vf_mc_promisc(adapter, vf); > + else > + return ixgbe_disable_vf_mc_promisc(adapter, vf); } > + > + > static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) { > u32 mbx_size = IXGBE_VFMAILBOX_SIZE; > @@ -1000,6 +1082,9 @@ static int ixgbe_rcv_msg_from_vf(struct > ixgbe_adapter *adapter, u32 vf) > case IXGBE_VF_GET_QUEUES: > retval = ixgbe_get_vf_queues(adapter, msgbuf, vf); > break; > + case IXGBE_VF_SET_MC_PROMISC: > + retval = ixgbe_set_vf_mc_promisc(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_main.c > b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c > index 62a0d8e..0403e1d 100644 > --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c > +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c > @@ -1880,7 +1880,8 @@ static void ixgbevf_init_last_counter_stats(struct > ixgbevf_adapter *adapter) static void ixgbevf_negotiate_api(struct > ixgbevf_adapter *adapter) { > struct ixgbe_hw *hw = &adapter->hw; > - int api[] = { ixgbe_mbox_api_11, > + int api[] = { ixgbe_mbox_api_12, > + ixgbe_mbox_api_11, > ixgbe_mbox_api_10, > ixgbe_mbox_api_unknown }; > int err = 0, idx = 0; > @@ -1894,6 +1895,12 @@ static void ixgbevf_negotiate_api(struct > ixgbevf_adapter *adapter) > idx++; > } > > + dev_info(&adapter->pdev->dev, "mbox api_version = %s\n", > + (hw->api_version == ixgbe_mbox_api_12) ? > "ixgbe_mbox_api_12" : > + (hw->api_version == ixgbe_mbox_api_11) ? > "ixgbe_mbox_api_11" : > + (hw->api_version == ixgbe_mbox_api_10) ? > "ixgbe_mbox_api_10" : > + "unknown"); > + > spin_unlock_bh(&adapter->mbx_lock); > } > > @@ -2072,6 +2079,9 @@ void ixgbevf_down(struct ixgbevf_adapter > *adapter) > > netif_carrier_off(netdev); > > + /* drop multicast promiscuous mode flag */ > + adapter->hw.mac.mc_promisc = false; > + > if (!pci_channel_offline(adapter->pdev)) > ixgbevf_reset(adapter); > > @@ -3525,6 +3535,7 @@ static int ixgbevf_change_mtu(struct net_device > *netdev, int new_mtu) > > switch (adapter->hw.api_version) { > case ixgbe_mbox_api_11: > + case ixgbe_mbox_api_12: > max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; > break; > default: > diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h > b/drivers/net/ethernet/intel/ixgbevf/mbx.h > index 0bc3005..62ef0d8 100644 > --- a/drivers/net/ethernet/intel/ixgbevf/mbx.h > +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h > @@ -86,6 +86,7 @@ enum ixgbe_pfvf_api_rev { > ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ > ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ > ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ > + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ > /* This value should always be last */ > ixgbe_mbox_api_unknown, /* indicates that API version is not > known */ > }; > @@ -104,6 +105,9 @@ enum ixgbe_pfvf_api_rev { > /* mailbox API, version 1.1 VF requests */ > #define IXGBE_VF_GET_QUEUE 0x09 /* get queue configuration */ > > +/* mailbox API, version 1.2 VF requests */ > +#define IXGBE_VF_SET_MC_PROMISC 0x0a /* VF requests PF to set > MC promiscuous */ > + > /* GET_QUEUES return data indices within the mailbox */ > #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues > supported */ > #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues > supported */ > diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c > b/drivers/net/ethernet/intel/ixgbevf/vf.c > index cdb53be..dfc87b0 100644 > --- a/drivers/net/ethernet/intel/ixgbevf/vf.c > +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c > @@ -120,6 +120,9 @@ static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw) > memcpy(hw->mac.perm_addr, addr, ETH_ALEN); > hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; > > + /* after reset, MC promiscuous mode is disabled */ > + hw->mac.mc_promisc = false; > + > return 0; > } > > @@ -327,8 +330,29 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct > ixgbe_hw *hw, > */ > > cnt = netdev_mc_count(netdev); > - if (cnt > 30) > + if (cnt > 30) { > + /* > + * If the API has the capability to handle MC promiscuous > + * mode, turn it on. > + */ > + if (hw->api_version == ixgbe_mbox_api_12) { > + if (!hw->mac.mc_promisc) { > + struct ixgbevf_adapter *adapter = hw->back; > + > + dev_info(&adapter->pdev->dev, "Request > MC PROMISC\n"); > + > + /* enabling multicast promiscuous */ > + msgbuf[0] = IXGBE_VF_SET_MC_PROMISC; > + msgbuf[1] = 1; > + ixgbevf_write_msg_read_ack(hw, msgbuf, > 2); > + > + hw->mac.mc_promisc = true; > + } > + > + return 0; > + } > cnt = 30; > + } > msgbuf[0] = IXGBE_VF_SET_MULTICAST; > msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT; > > @@ -344,6 +368,8 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct > ixgbe_hw *hw, > > ixgbevf_write_msg_read_ack(hw, msgbuf, > IXGBE_VFMAILBOX_SIZE); > > + hw->mac.mc_promisc = false; > + > return 0; > } > > @@ -545,6 +571,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, > unsigned int *num_tcs, > /* do nothing if API doesn't support ixgbevf_get_queues */ > switch (hw->api_version) { > case ixgbe_mbox_api_11: > + case ixgbe_mbox_api_12: > break; > default: > return 0; > diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h > b/drivers/net/ethernet/intel/ixgbevf/vf.h > index 5b17242..97790db 100644 > --- a/drivers/net/ethernet/intel/ixgbevf/vf.h > +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h > @@ -87,6 +87,7 @@ struct ixgbe_mac_info { > enum ixgbe_mac_type type; > > s32 mc_filter_type; > + bool mc_promisc; > > bool get_link_status; > u32 max_tx_queues; > -- > 1.9.0 Thanks Hiroshi, >>From a quick glance this looks good. Jeff will pull this into his queue so we can test it out. -Don Skidmore {.n++%ݶw{.n+{G{ayʇڙ,jfhz_(階ݢj"mG?&~iOzv^m ?I