Module Name: src
Committed By: martin
Date: Thu Sep 26 19:07:23 UTC 2019
Modified Files:
src/share/man/man4 [netbsd-9]: ixv.4
src/sys/dev/pci/ixgbe [netbsd-9]: ixgbe.c ixgbe.h ixgbe_type.h
ixgbe_vf.c ixgbe_vf.h ixgbe_x550.c ixv.c
Log Message:
Pull up the following revisions, requested by msaitoh in ticket #246:
sys/dev/pci/ixgbe/ixgbe_type.h 1.42-1.43
sys/dev/pci/ixgbe/ixgbe.c 1.209-1.213
sys/dev/pci/ixgbe/ixgbe_x550.c 1.16
sys/dev/pci/ixgbe/ixv.c 1.131-1.138
sys/dev/pci/ixgbe/ixgbe_vf.c 1.19-1.22
sys/dev/pci/ixgbe/ixgbe_vf.h 1.14
sys/dev/pci/ixgbe/ixgbe.h 1.57-1.58
share/man/man4/ixv.4 1.5
- Fix a bug that MBSDC (Bad SFD Count) isn't counted on X550EM_X and
X550EM_A. The register is for X550 and newer.
- ixv(4): Make SIOCADDMULTI returns ENOSPC and print error message
when the Ethernet multicast address list exceeds the limit(30) and
can't be ALLMULTI.
- ixv(4): SIOCZIFDATA clear the event counters as ixgbe.c.
- Reduce ixv(4)'s multicast table array size in ixv_set_multi from
MAX_NUM_MULTICAST_ADDRESSES(128) to IXGBE_MAX_VF_MC(30).
- ixv(4): Add support ALLMULTI and PROMISC.
- if_flags is neither int nor short. It's unsigned short.
- ixg(4): Fix a bug that the multicast filter isn't correctly
initialized when the total number of the Ethernet multicast
addresses is just 128.
- Make ixv_set_multi() work correctly (especially for PROMISC) when the
function is called from if_init().
- Remove *_set_promisc() and use *_set_multi(). And then, rename
*_set_multi() to *_set_rxfilter().
- ixv(4): If a multicast entry has range, use ALLMULTI like others.
- Fix typo in comment. Found by Wataru Ashihara.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.4.2.1 src/share/man/man4/ixv.4
cvs rdiff -u -r1.199.2.4 -r1.199.2.5 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.56 -r1.56.2.1 src/sys/dev/pci/ixgbe/ixgbe.h
cvs rdiff -u -r1.41 -r1.41.2.1 src/sys/dev/pci/ixgbe/ixgbe_type.h
cvs rdiff -u -r1.18 -r1.18.2.1 src/sys/dev/pci/ixgbe/ixgbe_vf.c
cvs rdiff -u -r1.13 -r1.13.8.1 src/sys/dev/pci/ixgbe/ixgbe_vf.h
cvs rdiff -u -r1.15 -r1.15.2.1 src/sys/dev/pci/ixgbe/ixgbe_x550.c
cvs rdiff -u -r1.125.2.3 -r1.125.2.4 src/sys/dev/pci/ixgbe/ixv.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man4/ixv.4
diff -u src/share/man/man4/ixv.4:1.4 src/share/man/man4/ixv.4:1.4.2.1
--- src/share/man/man4/ixv.4:1.4 Thu Jul 18 03:52:26 2019
+++ src/share/man/man4/ixv.4 Thu Sep 26 19:07:23 2019
@@ -1,4 +1,4 @@
-.\" $NetBSD: ixv.4,v 1.4 2019/07/18 03:52:26 msaitoh Exp $
+.\" $NetBSD: ixv.4,v 1.4.2.1 2019/09/26 19:07:23 martin Exp $
.\"
.\" Copyright (c) 2018 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 18, 2019
+.Dd September 5, 2019
.Dt IXV 4
.Os
.Sh NAME
@@ -61,3 +61,20 @@ The
.Nm
driver was written by
.An Intel Corporation Aq Mt [email protected] .
+.Sh BUGS
+The following event counters are not cleared by
+.Dv SIOCZIFDATA
+because the corresponding registers are read only and not cleared on read:
+.Pp
+.Bl -item -offset indent -compact
+.It
+Good Packets Received
+.It
+Good Octets Received
+.It
+Multicast Packets Received
+.It
+Good Packets Transmitted
+.It
+Good Octets Transmitted
+.El
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.4 src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.5
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.4 Thu Sep 5 09:11:03 2019
+++ src/sys/dev/pci/ixgbe/ixgbe.c Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.199.2.4 2019/09/05 09:11:03 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.199.2.5 2019/09/26 19:07:22 martin Exp $ */
/******************************************************************************
@@ -211,8 +211,7 @@ static void ixgbe_initialize_rss_mapping
static void ixgbe_enable_intr(struct adapter *);
static void ixgbe_disable_intr(struct adapter *);
static void ixgbe_update_stats_counters(struct adapter *);
-static void ixgbe_set_promisc(struct adapter *);
-static void ixgbe_set_multi(struct adapter *);
+static void ixgbe_set_rxfilter(struct adapter *);
static void ixgbe_update_link_status(struct adapter *);
static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
static void ixgbe_configure_ivars(struct adapter *);
@@ -1571,7 +1570,7 @@ ixgbe_update_stats_counters(struct adapt
stats->illerrc.ev_count += IXGBE_READ_REG(hw, IXGBE_ILLERRC);
stats->errbc.ev_count += IXGBE_READ_REG(hw, IXGBE_ERRBC);
stats->mspdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MSPDC);
- if (hw->mac.type == ixgbe_mac_X550)
+ if (hw->mac.type >= ixgbe_mac_X550)
stats->mbsdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MBSDC);
/* 16 registers exist */
@@ -2126,7 +2125,8 @@ ixgbe_clear_evcnt(struct adapter *adapte
stats->illerrc.ev_count = 0;
stats->errbc.ev_count = 0;
stats->mspdc.ev_count = 0;
- stats->mbsdc.ev_count = 0;
+ if (hw->mac.type >= ixgbe_mac_X550)
+ stats->mbsdc.ev_count = 0;
stats->mpctotal.ev_count = 0;
stats->mlfc.ev_count = 0;
stats->mrfc.ev_count = 0;
@@ -3041,49 +3041,6 @@ invalid:
} /* ixgbe_media_change */
/************************************************************************
- * ixgbe_set_promisc
- ************************************************************************/
-static void
-ixgbe_set_promisc(struct adapter *adapter)
-{
- struct ifnet *ifp = adapter->ifp;
- int mcnt = 0;
- u32 rctl;
- struct ether_multi *enm;
- struct ether_multistep step;
- struct ethercom *ec = &adapter->osdep.ec;
-
- KASSERT(mutex_owned(&adapter->core_mtx));
- rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- rctl &= (~IXGBE_FCTRL_UPE);
- ETHER_LOCK(ec);
- if (ec->ec_flags & ETHER_F_ALLMULTI)
- mcnt = MAX_NUM_MULTICAST_ADDRESSES;
- else {
- ETHER_FIRST_MULTI(step, ec, enm);
- while (enm != NULL) {
- if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
- break;
- mcnt++;
- ETHER_NEXT_MULTI(step, enm);
- }
- }
- if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
- rctl &= (~IXGBE_FCTRL_MPE);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
-
- if (ifp->if_flags & IFF_PROMISC) {
- rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
- } else if (ec->ec_flags & ETHER_F_ALLMULTI) {
- rctl |= IXGBE_FCTRL_MPE;
- rctl &= ~IXGBE_FCTRL_UPE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
- }
- ETHER_UNLOCK(ec);
-} /* ixgbe_set_promisc */
-
-/************************************************************************
* ixgbe_msix_link - Link status change ISR (MSI/MSI-X)
************************************************************************/
static int
@@ -3993,7 +3950,7 @@ ixgbe_init_locked(struct adapter *adapte
ixgbe_initialize_transmit_units(adapter);
/* Setup Multicast table */
- ixgbe_set_multi(adapter);
+ ixgbe_set_rxfilter(adapter);
/* Determine the correct mbuf pool, based on frame size */
if (adapter->max_frame_size <= MCLBYTES)
@@ -4382,12 +4339,12 @@ ixgbe_config_delay_values(struct adapter
} /* ixgbe_config_delay_values */
/************************************************************************
- * ixgbe_set_multi - Multicast Update
+ * ixgbe_set_rxfilter - Multicast Update
*
* Called whenever multicast address list is updated.
************************************************************************/
static void
-ixgbe_set_multi(struct adapter *adapter)
+ixgbe_set_rxfilter(struct adapter *adapter)
{
struct ixgbe_mc_addr *mta;
struct ifnet *ifp = adapter->ifp;
@@ -4399,7 +4356,7 @@ ixgbe_set_multi(struct adapter *adapter)
struct ether_multistep step;
KASSERT(mutex_owned(&adapter->core_mtx));
- IOCTL_DEBUGOUT("ixgbe_set_multi: begin");
+ IOCTL_DEBUGOUT("ixgbe_set_rxfilter: begin");
mta = adapter->mta;
bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES);
@@ -4422,30 +4379,32 @@ ixgbe_set_multi(struct adapter *adapter)
}
fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
if (ifp->if_flags & IFF_PROMISC)
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
else if (ec->ec_flags & ETHER_F_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
- }
- ETHER_UNLOCK(ec);
+ fctrl &= ~IXGBE_FCTRL_UPE;
+ } else
+ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
- if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) {
+ /* Update multicast filter entries only when it's not ALLMULTI */
+ if ((ec->ec_flags & ETHER_F_ALLMULTI) == 0) {
+ ETHER_UNLOCK(ec);
update_ptr = (u8 *)mta;
ixgbe_update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
ixgbe_mc_array_itr, TRUE);
- }
-
-} /* ixgbe_set_multi */
+ } else
+ ETHER_UNLOCK(ec);
+} /* ixgbe_set_rxfilter */
/************************************************************************
* ixgbe_mc_array_itr
*
* An iterator function needed by the multicast shared code.
* It feeds the shared code routine the addresses in the
- * array of ixgbe_set_multi() one by one.
+ * array of ixgbe_set_rxfilter() one by one.
************************************************************************/
static u8 *
ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
@@ -6203,7 +6162,8 @@ ixgbe_ifflags_cb(struct ethercom *ec)
{
struct ifnet *ifp = &ec->ec_if;
struct adapter *adapter = ifp->if_softc;
- int change, rv = 0;
+ u_short change;
+ int rv = 0;
IXGBE_CORE_LOCK(adapter);
@@ -6215,7 +6175,7 @@ ixgbe_ifflags_cb(struct ethercom *ec)
rv = ENETRESET;
goto out;
} else if ((change & IFF_PROMISC) != 0)
- ixgbe_set_promisc(adapter);
+ ixgbe_set_rxfilter(adapter);
/* Check for ec_capenable. */
change = ec->ec_capenable ^ adapter->ec_capenable;
@@ -6373,7 +6333,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
*/
IXGBE_CORE_LOCK(adapter);
ixgbe_disable_intr(adapter);
- ixgbe_set_multi(adapter);
+ ixgbe_set_rxfilter(adapter);
ixgbe_enable_intr(adapter);
IXGBE_CORE_UNLOCK(adapter);
}
Index: src/sys/dev/pci/ixgbe/ixgbe.h
diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.56 src/sys/dev/pci/ixgbe/ixgbe.h:1.56.2.1
--- src/sys/dev/pci/ixgbe/ixgbe.h:1.56 Wed Jul 17 03:26:24 2019
+++ src/sys/dev/pci/ixgbe/ixgbe.h Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.56 2019/07/17 03:26:24 msaitoh Exp $ */
+/* $NetBSD: ixgbe.h,v 1.56.2.1 2019/09/26 19:07:22 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -436,8 +436,6 @@ struct rx_ring {
u64 flm;
};
-#define IXGBE_MAX_VF_MC 30 /* Max number of multicast entries */
-
struct ixgbe_vf {
u_int pool;
u_int rar_index;
@@ -475,7 +473,7 @@ struct adapter {
struct ifmedia media;
callout_t timer;
- int if_flags; /* saved ifp->if_flags */
+ u_short if_flags; /* saved ifp->if_flags */
int ec_capenable; /* saved ec->ec_capenable */
kmutex_t core_mtx;
Index: src/sys/dev/pci/ixgbe/ixgbe_type.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41 src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41.2.1
--- src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41 Wed Jul 24 06:07:58 2019
+++ src/sys/dev/pci/ixgbe/ixgbe_type.h Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_type.h,v 1.41 2019/07/24 06:07:58 msaitoh Exp $ */
+/* $NetBSD: ixgbe_type.h,v 1.41.2.1 2019/09/26 19:07:22 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -4311,6 +4311,9 @@ struct ixgbe_hw {
#define IXGBE_ERR_FW_RESP_INVALID -39
#define IXGBE_ERR_TOKEN_RETRY -40
+#define IXGBE_ERR_NOT_TRUSTED -50 /* XXX NetBSD */
+#define IXGBE_ERR_NOT_IN_PROMISC -51 /* XXX NetBSD */
+
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
Index: src/sys/dev/pci/ixgbe/ixgbe_vf.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_vf.c:1.18 src/sys/dev/pci/ixgbe/ixgbe_vf.c:1.18.2.1
--- src/sys/dev/pci/ixgbe/ixgbe_vf.c:1.18 Tue Jul 2 04:09:03 2019
+++ src/sys/dev/pci/ixgbe/ixgbe_vf.c Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_vf.c,v 1.18 2019/07/02 04:09:03 msaitoh Exp $ */
+/* $NetBSD: ixgbe_vf.c,v 1.18.2.1 2019/09/26 19:07:22 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -409,7 +409,13 @@ s32 ixgbe_update_mc_addr_list_vf(struct
DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count);
- cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
+ if (mc_addr_count > IXGBE_MAX_VF_MC) {
+ device_printf(ixgbe_dev_from_hw(hw),
+ "number of Ethernet multicast addresses exceeded "
+ "the limit (%u > %d)\n", mc_addr_count, IXGBE_MAX_VF_MC);
+ cnt = IXGBE_MAX_VF_MC;
+ } else
+ cnt = mc_addr_count;
msgbuf[0] = IXGBE_VF_SET_MULTICAST;
msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
@@ -454,8 +460,32 @@ s32 ixgbevf_update_xcast_mode(struct ixg
return err;
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
- if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK))
- return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
+ if (msgbuf[0] ==
+ (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK)) {
+ if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC) {
+ /*
+ * If the API version matched and the reply was NACK,
+ * assume the PF was not in PROMISC mode.
+ */
+ return IXGBE_ERR_NOT_IN_PROMISC;
+ } else
+ return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
+ }
+ /*
+ * On linux's PF driver implementation, the PF replies VF's
+ * XCAST_MODE_ALLMULTI message not with NACK but with ACK even if the
+ * virtual function is NOT marked "trust" and act as
+ * XCAST_MODE_"MULTI". If ixv(4) simply check the return vaule of
+ * update_xcast_mode(XCAST_MODE_ALLMULTI), SIOCSADDMULTI success and
+ * the user may have trouble with some addresses. Fortunately, the
+ * Linux's PF driver's "ACK" message has not XCAST_MODE_"ALL"MULTI but
+ * XCAST_MODE_MULTI, so we can check this state by checking if the
+ * send message's argument and the reply message's argument are
+ * different.
+ */
+ if ((xcast_mode > IXGBEVF_XCAST_MODE_MULTI)
+ && (xcast_mode != msgbuf[1]))
+ return IXGBE_ERR_NOT_TRUSTED;
return IXGBE_SUCCESS;
}
Index: src/sys/dev/pci/ixgbe/ixgbe_vf.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_vf.h:1.13 src/sys/dev/pci/ixgbe/ixgbe_vf.h:1.13.8.1
--- src/sys/dev/pci/ixgbe/ixgbe_vf.h:1.13 Wed Apr 4 08:13:07 2018
+++ src/sys/dev/pci/ixgbe/ixgbe_vf.h Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_vf.h,v 1.13 2018/04/04 08:13:07 msaitoh Exp $ */
+/* $NetBSD: ixgbe_vf.h,v 1.13.8.1 2019/09/26 19:07:22 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -42,6 +42,8 @@
#define IXGBE_VF_MAX_TX_QUEUES 8
#define IXGBE_VF_MAX_RX_QUEUES 8
+#define IXGBE_MAX_VF_MC 30 /* Max number of multicast entries */
+
/* DCB define */
#define IXGBE_VF_MAX_TRAFFIC_CLASS 8
Index: src/sys/dev/pci/ixgbe/ixgbe_x550.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15 src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15.2.1
--- src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15 Thu Jun 27 06:00:11 2019
+++ src/sys/dev/pci/ixgbe/ixgbe_x550.c Thu Sep 26 19:07:22 2019
@@ -875,7 +875,7 @@ static s32 ixgbe_setup_fw_link(struct ix
* Broken firmware sets BMCR register incorrectly if
* FW_PHY_ACT_SETUP_LINK_AN isn't set.
* a) FDX may not be set.
- * b) BMCR_SPEED1 (bit 6) is always cleard.
+ * b) BMCR_SPEED1 (bit 6) is always cleared.
* + -------+------+-----------+-----+--------------------------+
* |request | BMCR | BMCR spd | BMCR | |
* | | (HEX)| (in bits)| FDX | |
Index: src/sys/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.125.2.3 src/sys/dev/pci/ixgbe/ixv.c:1.125.2.4
--- src/sys/dev/pci/ixgbe/ixv.c:1.125.2.3 Thu Sep 5 09:11:03 2019
+++ src/sys/dev/pci/ixgbe/ixv.c Thu Sep 26 19:07:22 2019
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.125.2.3 2019/09/05 09:11:03 martin Exp $*/
+/*$NetBSD: ixv.c,v 1.125.2.4 2019/09/26 19:07:22 martin Exp $*/
/******************************************************************************
@@ -112,7 +112,7 @@ static s32 ixv_check_link(struct adapter
static void ixv_enable_intr(struct adapter *);
static void ixv_disable_intr(struct adapter *);
-static void ixv_set_multi(struct adapter *);
+static int ixv_set_rxfilter(struct adapter *);
static void ixv_update_link_status(struct adapter *);
static int ixv_sysctl_debug(SYSCTLFN_PROTO);
static void ixv_set_ivar(struct adapter *, u8, u8, s8);
@@ -131,6 +131,7 @@ static void ixv_save_stats(struct adapte
static void ixv_init_stats(struct adapter *);
static void ixv_update_stats(struct adapter *);
static void ixv_add_stats_sysctls(struct adapter *);
+static void ixv_clear_evcnt(struct adapter *);
/* Sysctl handlers */
static void ixv_set_sysctl_value(struct adapter *, const char *,
@@ -741,7 +742,7 @@ ixv_init_locked(struct adapter *adapter)
ixv_initialize_transmit_units(adapter);
/* Setup Multicast table */
- ixv_set_multi(adapter);
+ ixv_set_rxfilter(adapter);
/*
* Determine the correct mbuf pool
@@ -1073,7 +1074,6 @@ ixv_media_change(struct ifnet *ifp)
return (0);
} /* ixv_media_change */
-
/************************************************************************
* ixv_negotiate_api
*
@@ -1084,7 +1084,9 @@ static int
ixv_negotiate_api(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- int mbx_api[] = { ixgbe_mbox_api_11,
+ int mbx_api[] = { ixgbe_mbox_api_13,
+ ixgbe_mbox_api_12,
+ ixgbe_mbox_api_11,
ixgbe_mbox_api_10,
ixgbe_mbox_api_unknown };
int i = 0;
@@ -1104,45 +1106,128 @@ ixv_negotiate_api(struct adapter *adapte
*
* Called whenever multicast address list is updated.
************************************************************************/
-static void
-ixv_set_multi(struct adapter *adapter)
+static int
+ixv_set_rxfilter(struct adapter *adapter)
{
- struct ether_multi *enm;
- struct ether_multistep step;
- struct ethercom *ec = &adapter->osdep.ec;
- u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
- u8 *update_ptr;
- int mcnt = 0;
+ u8 mta[IXGBE_MAX_VF_MC * IXGBE_ETH_LENGTH_OF_ADDRESS];
+ struct ifnet *ifp = adapter->ifp;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 *update_ptr;
+ int mcnt = 0;
+ struct ethercom *ec = &adapter->osdep.ec;
+ struct ether_multi *enm;
+ struct ether_multistep step;
+ bool overflow = false;
+ int error, rc = 0;
KASSERT(mutex_owned(&adapter->core_mtx));
- IOCTL_DEBUGOUT("ixv_set_multi: begin");
+ IOCTL_DEBUGOUT("ixv_set_rxfilter: begin");
+ /* 1: For PROMISC */
+ if (ifp->if_flags & IFF_PROMISC) {
+ error = hw->mac.ops.update_xcast_mode(hw,
+ IXGBEVF_XCAST_MODE_PROMISC);
+ if (error == IXGBE_ERR_NOT_TRUSTED) {
+ device_printf(adapter->dev,
+ "this interface is not trusted\n");
+ error = EPERM;
+ } else if (error == IXGBE_ERR_FEATURE_NOT_SUPPORTED) {
+ device_printf(adapter->dev,
+ "the PF doesn't support promisc mode\n");
+ error = EOPNOTSUPP;
+ } else if (error == IXGBE_ERR_NOT_IN_PROMISC) {
+ device_printf(adapter->dev,
+ "the PF may not in promisc mode\n");
+ error = EINVAL;
+ } else if (error) {
+ device_printf(adapter->dev,
+ "failed to set promisc mode. error = %d\n",
+ error);
+ error = EIO;
+ } else
+ return 0;
+ rc = error;
+ }
+
+ /* 2: For ALLMULTI or normal */
ETHER_LOCK(ec);
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
+ if ((mcnt >= IXGBE_MAX_VF_MC) ||
+ (memcmp(enm->enm_addrlo, enm->enm_addrhi,
+ ETHER_ADDR_LEN) != 0)) {
+ overflow = true;
+ break;
+ }
bcopy(enm->enm_addrlo,
&mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
IXGBE_ETH_LENGTH_OF_ADDRESS);
mcnt++;
- /* XXX This might be required --msaitoh */
- if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES)
- break;
ETHER_NEXT_MULTI(step, enm);
}
ETHER_UNLOCK(ec);
+ /* 3: For ALLMULTI */
+ if (overflow) {
+ error = hw->mac.ops.update_xcast_mode(hw,
+ IXGBEVF_XCAST_MODE_ALLMULTI);
+ if (error == IXGBE_ERR_NOT_TRUSTED) {
+ device_printf(adapter->dev,
+ "this interface is not trusted\n");
+ error = EPERM;
+ } else if (error == IXGBE_ERR_FEATURE_NOT_SUPPORTED) {
+ device_printf(adapter->dev,
+ "the PF doesn't support allmulti mode\n");
+ error = EOPNOTSUPP;
+ } else if (error) {
+ device_printf(adapter->dev,
+ "number of Ethernet multicast addresses "
+ "exceeds the limit (%d). error = %d\n",
+ IXGBE_MAX_VF_MC, error);
+ error = ENOSPC;
+ } else {
+ ETHER_LOCK(ec);
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
+ return rc; /* Promisc might failed */
+ }
+
+ if (rc == 0)
+ rc = error;
+
+ /* Continue to update the multicast table as many as we can */
+ }
+
+ /* 4: For normal operation */
+ error = hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_MULTI);
+ if ((error == IXGBE_ERR_FEATURE_NOT_SUPPORTED) || (error == 0)) {
+ /* Normal operation */
+ ETHER_LOCK(ec);
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
+ error = 0;
+ } else if (error) {
+ device_printf(adapter->dev,
+ "failed to set Ethernet multicast address "
+ "operation to normal. error = %d\n", error);
+ }
+
update_ptr = mta;
- adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
- ixv_mc_array_itr, TRUE);
-} /* ixv_set_multi */
+ error = adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw,
+ update_ptr, mcnt, ixv_mc_array_itr, TRUE);
+ if (rc == 0)
+ rc = error;
+
+ return rc;
+} /* ixv_set_rxfilter */
/************************************************************************
* ixv_mc_array_itr
*
* An iterator function needed by the multicast shared code.
* It feeds the shared code routine the addresses in the
- * array of ixv_set_multi() one by one.
+ * array of ixv_set_rxfilter() one by one.
************************************************************************/
static u8 *
ixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
@@ -2630,6 +2715,76 @@ ixv_add_stats_sysctls(struct adapter *ad
} /* ixv_add_stats_sysctls */
+static void
+ixv_clear_evcnt(struct adapter *adapter)
+{
+ struct tx_ring *txr = adapter->tx_rings;
+ struct rx_ring *rxr = adapter->rx_rings;
+ struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ /* Driver Statistics */
+ adapter->efbig_tx_dma_setup.ev_count = 0;
+ adapter->mbuf_defrag_failed.ev_count = 0;
+ adapter->efbig2_tx_dma_setup.ev_count = 0;
+ adapter->einval_tx_dma_setup.ev_count = 0;
+ adapter->other_tx_dma_setup.ev_count = 0;
+ adapter->eagain_tx_dma_setup.ev_count = 0;
+ adapter->enomem_tx_dma_setup.ev_count = 0;
+ adapter->watchdog_events.ev_count = 0;
+ adapter->tso_err.ev_count = 0;
+ adapter->link_irq.ev_count = 0;
+
+ for (i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
+ adapter->queues[i].irqs.ev_count = 0;
+ adapter->queues[i].handleq.ev_count = 0;
+ adapter->queues[i].req.ev_count = 0;
+ txr->tso_tx.ev_count = 0;
+ txr->no_desc_avail.ev_count = 0;
+ txr->total_packets.ev_count = 0;
+#ifndef IXGBE_LEGACY_TX
+ txr->pcq_drops.ev_count = 0;
+#endif
+ txr->q_efbig_tx_dma_setup = 0;
+ txr->q_mbuf_defrag_failed = 0;
+ txr->q_efbig2_tx_dma_setup = 0;
+ txr->q_einval_tx_dma_setup = 0;
+ txr->q_other_tx_dma_setup = 0;
+ txr->q_eagain_tx_dma_setup = 0;
+ txr->q_enomem_tx_dma_setup = 0;
+ txr->q_tso_err = 0;
+
+ rxr->rx_packets.ev_count = 0;
+ rxr->rx_bytes.ev_count = 0;
+ rxr->rx_copies.ev_count = 0;
+ rxr->no_jmbuf.ev_count = 0;
+ rxr->rx_discarded.ev_count = 0;
+ }
+
+ /* MAC stats get their own sub node */
+
+ stats->ipcs.ev_count = 0;
+ stats->l4cs.ev_count = 0;
+ stats->ipcs_bad.ev_count = 0;
+ stats->l4cs_bad.ev_count = 0;
+
+ /* Packet Reception Stats */
+ stats->vfgprc.ev_count = 0;
+ stats->vfgorc.ev_count = 0;
+ stats->vfmprc.ev_count = 0;
+ stats->vfgptc.ev_count = 0;
+ stats->vfgotc.ev_count = 0;
+
+ /* Mailbox Stats */
+ hw->mbx.stats.msgs_tx.ev_count = 0;
+ hw->mbx.stats.msgs_rx.ev_count = 0;
+ hw->mbx.stats.acks.ev_count = 0;
+ hw->mbx.stats.reqs.ev_count = 0;
+ hw->mbx.stats.rsts.ev_count = 0;
+
+} /* ixv_clear_evcnt */
+
/************************************************************************
* ixv_set_sysctl_value
************************************************************************/
@@ -2790,10 +2945,13 @@ ixv_ifflags_cb(struct ethercom *ec)
{
struct ifnet *ifp = &ec->ec_if;
struct adapter *adapter = ifp->if_softc;
- int change, rv = 0;
+ u_short saved_flags;
+ u_short change;
+ int rv = 0;
IXGBE_CORE_LOCK(adapter);
+ saved_flags = adapter->if_flags;
change = ifp->if_flags ^ adapter->if_flags;
if (change != 0)
adapter->if_flags = ifp->if_flags;
@@ -2801,6 +2959,13 @@ ixv_ifflags_cb(struct ethercom *ec)
if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
rv = ENETRESET;
goto out;
+ } else if ((change & IFF_PROMISC) != 0) {
+ rv = ixv_set_rxfilter(adapter);
+ if (rv != 0) {
+ /* Restore previous */
+ adapter->if_flags = saved_flags;
+ goto out;
+ }
}
/* Check for ec_capenable. */
@@ -2839,8 +3004,9 @@ static int
ixv_ioctl(struct ifnet *ifp, u_long command, void *data)
{
struct adapter *adapter = ifp->if_softc;
+ struct ixgbe_hw *hw = &adapter->hw;
struct ifcapreq *ifcr = data;
- int error = 0;
+ int error;
int l4csum_en;
const int l4csum = IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
@@ -2849,7 +3015,59 @@ ixv_ioctl(struct ifnet *ifp, u_long comm
case SIOCSIFFLAGS:
IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
break;
- case SIOCADDMULTI:
+ case SIOCADDMULTI: {
+ struct ether_multi *enm;
+ struct ether_multistep step;
+ struct ethercom *ec = &adapter->osdep.ec;
+ bool overflow = false;
+ int mcnt = 0;
+
+ /*
+ * Check the number of multicast address. If it exceeds,
+ * return ENOSPC.
+ * Update this code when we support API 1.3.
+ */
+ ETHER_LOCK(ec);
+ ETHER_FIRST_MULTI(step, ec, enm);
+ while (enm != NULL) {
+ mcnt++;
+
+ /*
+ * This code is before adding, so one room is required
+ * at least.
+ */
+ if (mcnt > (IXGBE_MAX_VF_MC - 1)) {
+ overflow = true;
+ break;
+ }
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ ETHER_UNLOCK(ec);
+ error = 0;
+ if (overflow && ((ec->ec_flags & ETHER_F_ALLMULTI) == 0)) {
+ error = hw->mac.ops.update_xcast_mode(hw,
+ IXGBEVF_XCAST_MODE_ALLMULTI);
+ if (error == IXGBE_ERR_NOT_TRUSTED) {
+ device_printf(adapter->dev,
+ "this interface is not trusted\n");
+ error = EPERM;
+ } else if (error == IXGBE_ERR_FEATURE_NOT_SUPPORTED) {
+ device_printf(adapter->dev,
+ "the PF doesn't support allmulti mode\n");
+ error = EOPNOTSUPP;
+ } else if (error) {
+ device_printf(adapter->dev,
+ "number of Ethernet multicast addresses "
+ "exceeds the limit (%d). error = %d\n",
+ IXGBE_MAX_VF_MC, error);
+ error = ENOSPC;
+ } else
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ }
+ if (error)
+ return error;
+ }
+ /*FALLTHROUGH*/
case SIOCDELMULTI:
IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
break;
@@ -2863,6 +3081,11 @@ ixv_ioctl(struct ifnet *ifp, u_long comm
case SIOCSIFMTU:
IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
break;
+ case SIOCZIFDATA:
+ IOCTL_DEBUGOUT("ioctl: SIOCZIFDATA (Zero counter)");
+ ixv_update_stats(adapter);
+ ixv_clear_evcnt(adapter);
+ break;
default:
IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)", (int)command);
break;
@@ -2897,7 +3120,7 @@ ixv_ioctl(struct ifnet *ifp, u_long comm
*/
IXGBE_CORE_LOCK(adapter);
ixv_disable_intr(adapter);
- ixv_set_multi(adapter);
+ ixv_set_rxfilter(adapter);
ixv_enable_intr(adapter);
IXGBE_CORE_UNLOCK(adapter);
}