Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci/ixgbe Add support ALLMULTI on ixv(4):
details: https://anonhg.NetBSD.org/src/rev/8fafe1d4aed7
branches: trunk
changeset: 463818:8fafe1d4aed7
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Sep 12 12:25:46 2019 +0000
description:
Add support ALLMULTI on ixv(4):
- Negotiate API version up to 1.3.
- 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.
- Noy yet for PROMISC.
diffstat:
sys/dev/pci/ixgbe/ixgbe_type.h | 4 +-
sys/dev/pci/ixgbe/ixgbe_vf.c | 17 +++++++++-
sys/dev/pci/ixgbe/ixv.c | 74 +++++++++++++++++++++++++++++++++++------
3 files changed, 82 insertions(+), 13 deletions(-)
diffs (192 lines):
diff -r 414a3fe0dcaa -r 8fafe1d4aed7 sys/dev/pci/ixgbe/ixgbe_type.h
--- a/sys/dev/pci/ixgbe/ixgbe_type.h Thu Sep 12 11:48:44 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_type.h Thu Sep 12 12:25:46 2019 +0000
@@ -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.42 2019/09/12 12:25:46 msaitoh Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -4311,6 +4311,8 @@
#define IXGBE_ERR_FW_RESP_INVALID -39
#define IXGBE_ERR_TOKEN_RETRY -40
+#define IXGBE_ERR_NOT_TRUSTED -50 /* XXX NetBSD */
+
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
diff -r 414a3fe0dcaa -r 8fafe1d4aed7 sys/dev/pci/ixgbe/ixgbe_vf.c
--- a/sys/dev/pci/ixgbe/ixgbe_vf.c Thu Sep 12 11:48:44 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_vf.c Thu Sep 12 12:25:46 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_vf.c,v 1.20 2019/09/12 06:19:47 msaitoh Exp $ */
+/* $NetBSD: ixgbe_vf.c,v 1.21 2019/09/12 12:25:46 msaitoh Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -462,6 +462,21 @@
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK))
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;
}
diff -r 414a3fe0dcaa -r 8fafe1d4aed7 sys/dev/pci/ixgbe/ixv.c
--- a/sys/dev/pci/ixgbe/ixv.c Thu Sep 12 11:48:44 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixv.c Thu Sep 12 12:25:46 2019 +0000
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.133 2019/09/12 11:48:44 msaitoh Exp $*/
+/*$NetBSD: ixv.c,v 1.134 2019/09/12 12:25:46 msaitoh Exp $*/
/******************************************************************************
@@ -1085,7 +1085,9 @@
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;
@@ -1108,12 +1110,16 @@
static void
ixv_set_multi(struct adapter *adapter)
{
+ struct ixgbe_hw *hw = &adapter->hw;
struct ether_multi *enm;
struct ether_multistep step;
struct ethercom *ec = &adapter->osdep.ec;
u8 mta[IXGBE_MAX_VF_MC * IXGBE_ETH_LENGTH_OF_ADDRESS];
u8 *update_ptr;
int mcnt = 0;
+ bool overflow = false;
+ bool allmulti = false;
+ int error;
KASSERT(mutex_owned(&adapter->core_mtx));
IOCTL_DEBUGOUT("ixv_set_multi: begin");
@@ -1121,17 +1127,48 @@
ETHER_LOCK(ec);
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
+ if (mcnt >= IXGBE_MAX_VF_MC) {
+ 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 >= IXGBE_MAX_VF_MC)
- break;
ETHER_NEXT_MULTI(step, enm);
}
ETHER_UNLOCK(ec);
+ 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 = ENOSPC;
+ } 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 {
+ allmulti = true;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ }
+ }
+
+ if (!allmulti) {
+ error = hw->mac.ops.update_xcast_mode(hw,
+ IXGBEVF_XCAST_MODE_MULTI);
+ if (error) {
+ device_printf(adapter->dev,
+ "failed to set Ethernet multicast address "
+ "operation to normal. error = %d\n", error);
+ }
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
+ }
+
update_ptr = mta;
adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
@@ -2910,8 +2947,9 @@
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;
@@ -2924,6 +2962,7 @@
struct ether_multi *enm;
struct ether_multistep step;
struct ethercom *ec = &adapter->osdep.ec;
+ bool overflow = false;
int mcnt = 0;
/*
@@ -2941,16 +2980,29 @@
* at least.
*/
if (mcnt > (IXGBE_MAX_VF_MC - 1)) {
- device_printf(adapter->dev,
- "number of Ethernet multicast addresses "
- "exceeds the limit (%d)\n",
- IXGBE_MAX_VF_MC);
- error = ENOSPC;
+ 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 = ENOSPC;
+ } 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;
}
Home |
Main Index |
Thread Index |
Old Index