Module Name: src
Committed By: martin
Date: Sat Oct 14 06:43:06 UTC 2023
Modified Files:
src/sys/arch/evbarm/conf [netbsd-10]: GENERIC64
src/sys/dev/pci [netbsd-10]: if_ixl.c
Log Message:
Pull up following revision(s) (requested by yamaguchi in ticket #409):
sys/dev/pci/if_ixl.c: revision 1.90
sys/dev/pci/if_ixl.c: revision 1.91
sys/dev/pci/if_ixl.c: revision 1.92
sys/dev/pci/if_ixl.c: revision 1.93
sys/arch/evbarm/conf/GENERIC64: revision 1.214
ixl(4): skip getting link status if the last command is running
ixl(4): use cv_broadcast to wakeup ioctl and workqueue context.
Commands may be issued at the same time from the both context.
ixl(4): update link status in workqueue
ixl(4): Print device info on attach
Without PCIVERBOSE option:
ixl0 at pci1 dev 0 function 0: vendor 8086 product 1572 (rev. 0x01)
With PCIVERBOSE option:
ixl0 at pci1 dev 0 function 0: Intel XL710 SFP+ Ethernet (SFI) (rev. 0x01)
OK yamaguchi@
aarch64/GENERIC64: Add ixl(4)
Works just fine for little-endian on LX2K with UEFI firmware.
Not tested for big-endian yet; attach fails on ROCKPro64 due to
host controller problem.
OK yamaguchi@
To generate a diff of this commit:
cvs rdiff -u -r1.206.2.2 -r1.206.2.3 src/sys/arch/evbarm/conf/GENERIC64
cvs rdiff -u -r1.88 -r1.88.4.1 src/sys/dev/pci/if_ixl.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.206.2.2 src/sys/arch/evbarm/conf/GENERIC64:1.206.2.3
--- src/sys/arch/evbarm/conf/GENERIC64:1.206.2.2 Sun Oct 8 13:19:33 2023
+++ src/sys/arch/evbarm/conf/GENERIC64 Sat Oct 14 06:43:06 2023
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.206.2.2 2023/10/08 13:19:33 martin Exp $
+# $NetBSD: GENERIC64,v 1.206.2.3 2023/10/14 06:43:06 martin Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -279,6 +279,7 @@ bge* at pci? dev ? function ? # Broadco
ena* at pci? dev ? function ? # Amazon.com Elastic Network Adapter
igc* at pci? dev ? function ? # Intel 22x 2.5 gigabit
ixg* at pci? dev ? function ? # Intel 8259x 10 gigabit
+ixl* at pci? dev ? function ? # Intel Ethernet 700 series
ixv* at pci? dev ? function ? # Intel 8259x 10G virtual function
mcx* at pci? dev ? function ? # Mellanox 5th generation Ethernet
mskc* at pci? dev ? function ? # Marvell Yukon 2 Gigabit Ethernet
Index: src/sys/dev/pci/if_ixl.c
diff -u src/sys/dev/pci/if_ixl.c:1.88 src/sys/dev/pci/if_ixl.c:1.88.4.1
--- src/sys/dev/pci/if_ixl.c:1.88 Fri Sep 16 03:12:03 2022
+++ src/sys/dev/pci/if_ixl.c Sat Oct 14 06:43:06 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ixl.c,v 1.88 2022/09/16 03:12:03 knakahara Exp $ */
+/* $NetBSD: if_ixl.c,v 1.88.4.1 2023/10/14 06:43:06 martin Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ixl.c,v 1.88 2022/09/16 03:12:03 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ixl.c,v 1.88.4.1 2023/10/14 06:43:06 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -446,6 +446,7 @@ struct ixl_atq {
struct ixl_aq_desc iatq_desc;
void (*iatq_fn)(struct ixl_softc *,
const struct ixl_aq_desc *);
+ bool iatq_inuse;
};
SIMPLEQ_HEAD(ixl_atq_list, ixl_atq);
@@ -650,6 +651,7 @@ struct ixl_softc {
unsigned int sc_arq_cons;
struct ixl_work sc_link_state_task;
+ struct ixl_work sc_link_state_done_task;
struct ixl_atq sc_link_state_atq;
struct ixl_dmamem sc_hmc_sd;
@@ -714,6 +716,11 @@ do { \
#define IXL_QUEUE_NUM 0
#endif
+enum ixl_link_flags {
+ IXL_LINK_NOFLAGS = 0,
+ IXL_LINK_FLAG_WAITDONE = __BIT(0),
+};
+
static bool ixl_param_nomsix = false;
static int ixl_param_stats_interval = IXL_STATS_INTERVAL_MSEC;
static int ixl_param_nqps_limit = IXL_QUEUE_NUM;
@@ -737,6 +744,7 @@ static int ixl_atq_poll(struct ixl_softc
unsigned int);
static void ixl_atq_set(struct ixl_atq *,
void (*)(struct ixl_softc *, const struct ixl_aq_desc *));
+static void ixl_wakeup(struct ixl_softc *, const struct ixl_aq_desc *);
static int ixl_atq_post_locked(struct ixl_softc *, struct ixl_atq *);
static void ixl_atq_done(struct ixl_softc *);
static int ixl_atq_exec(struct ixl_softc *, struct ixl_atq *);
@@ -758,10 +766,12 @@ static void ixl_hmc_free(struct ixl_soft
static int ixl_get_vsi(struct ixl_softc *);
static int ixl_set_vsi(struct ixl_softc *);
static void ixl_set_filter_control(struct ixl_softc *);
-static void ixl_get_link_status(void *);
+static int ixl_get_link_status(struct ixl_softc *, enum ixl_link_flags);
+static void ixl_get_link_status_work(void *);
static int ixl_get_link_status_poll(struct ixl_softc *, int *);
static void ixl_get_link_status_done(struct ixl_softc *,
const struct ixl_aq_desc *);
+static void ixl_get_link_status_done_work(void *);
static int ixl_set_link_status_locked(struct ixl_softc *,
const struct ixl_aq_desc *);
static uint64_t ixl_search_link_speed(uint8_t);
@@ -1029,6 +1039,8 @@ ixl_attach(device_t parent, device_t sel
ixl_pci_csr_setup(pa->pa_pc, pa->pa_tag);
+ pci_aprint_devinfo(pa, "Ethernet controller");
+
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IXL_PCIREG);
if (pci_mapreg_map(pa, IXL_PCIREG, memtype, 0,
&sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) {
@@ -1053,7 +1065,7 @@ ixl_attach(device_t parent, device_t sel
port &= I40E_PFGEN_PORTNUM_PORT_NUM_MASK;
port >>= I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
sc->sc_port = port;
- aprint_normal(": port %u", sc->sc_port);
+ aprint_normal_dev(self, "port %u", sc->sc_port);
ari = ixl_rd(sc, I40E_GLPCI_CAPSUP);
ari &= I40E_GLPCI_CAPSUP_ARI_EN_MASK;
@@ -1346,7 +1358,10 @@ ixl_attach(device_t parent, device_t sel
if_link_state_change(ifp, link);
ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done);
- ixl_work_set(&sc->sc_link_state_task, ixl_get_link_status, sc);
+ ixl_work_set(&sc->sc_link_state_task,
+ ixl_get_link_status_work, sc);
+ ixl_work_set(&sc->sc_link_state_done_task,
+ ixl_get_link_status_done_work, sc);
ixl_config_other_intr(sc);
ixl_enable_other_intr(sc);
@@ -2086,8 +2101,10 @@ ixl_init(struct ifnet *ifp)
error = ixl_init_locked(sc);
mutex_exit(&sc->sc_cfg_lock);
- if (error == 0)
- (void)ixl_get_link_status(sc);
+ if (error == 0) {
+ error = ixl_get_link_status(sc,
+ IXL_LINK_FLAG_WAITDONE);
+ }
return error;
}
@@ -3578,46 +3595,88 @@ ixl_other_intr(void *xsc)
}
static void
-ixl_get_link_status_done(struct ixl_softc *sc,
- const struct ixl_aq_desc *iaq)
+ixl_get_link_status_done_work(void *xsc)
{
- struct ixl_aq_desc iaq_buf;
-
- memcpy(&iaq_buf, iaq, sizeof(iaq_buf));
+ struct ixl_softc *sc = xsc;
+ struct ixl_aq_desc *iaq, iaq_buf;
- /*
- * The lock can be released here
- * because there is no post processing about ATQ
- */
+ mutex_enter(&sc->sc_atq_lock);
+ iaq = &sc->sc_link_state_atq.iatq_desc;
+ iaq_buf = *iaq;
mutex_exit(&sc->sc_atq_lock);
+
ixl_link_state_update(sc, &iaq_buf);
+
mutex_enter(&sc->sc_atq_lock);
+ CLR(iaq->iaq_flags, htole16(IXL_AQ_DD));
+ ixl_wakeup(sc, iaq);
+ mutex_exit(&sc->sc_atq_lock);
}
static void
-ixl_get_link_status(void *xsc)
+ixl_get_link_status_done(struct ixl_softc *sc,
+ const struct ixl_aq_desc *iaq)
{
- struct ixl_softc *sc = xsc;
+
+ ixl_work_add(sc->sc_workq, &sc->sc_link_state_done_task);
+}
+
+static int
+ixl_get_link_status(struct ixl_softc *sc, enum ixl_link_flags flags)
+{
+ struct ixl_atq *iatq;
struct ixl_aq_desc *iaq;
struct ixl_aq_link_param *param;
int error;
mutex_enter(&sc->sc_atq_lock);
- iaq = &sc->sc_link_state_atq.iatq_desc;
- memset(iaq, 0, sizeof(*iaq));
- iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS);
- param = (struct ixl_aq_link_param *)iaq->iaq_param;
- param->notify = IXL_AQ_LINK_NOTIFY;
+ iatq = &sc->sc_link_state_atq;
+ iaq = &iatq->iatq_desc;
- error = ixl_atq_exec_locked(sc, &sc->sc_link_state_atq);
- ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done);
+ if (!sc->sc_link_state_atq.iatq_inuse &&
+ !ISSET(iaq->iaq_flags, htole16(IXL_AQ_DD))) {
+ memset(iaq, 0, sizeof(*iaq));
+ iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS);
+ param = (struct ixl_aq_link_param *)iaq->iaq_param;
+ param->notify = IXL_AQ_LINK_NOTIFY;
- if (error == 0) {
- ixl_get_link_status_done(sc, iaq);
+ KASSERT(iatq->iatq_fn == ixl_get_link_status_done);
+ error = ixl_atq_post_locked(sc, iatq);
+ if (error != 0)
+ goto out;
+ } else {
+ /* the previous command is not completed */
+ error = EBUSY;
+ }
+
+ if (ISSET(flags, IXL_LINK_FLAG_WAITDONE)) {
+ do {
+ error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock,
+ IXL_ATQ_EXEC_TIMEOUT);
+ if (error == EWOULDBLOCK)
+ break;
+ } while (iatq->iatq_inuse ||
+ ISSET(iaq->iaq_flags, htole16(IXL_AQ_DD)));
}
+out:
mutex_exit(&sc->sc_atq_lock);
+
+ return error;
+}
+
+static void
+ixl_get_link_status_work(void *xsc)
+{
+ struct ixl_softc *sc = xsc;
+
+ /*
+ * IXL_LINK_FLAG_WAITDONE causes deadlock
+ * because of doing ixl_gt_link_status_done_work()
+ * in the same workqueue.
+ */
+ (void)ixl_get_link_status(sc, IXL_LINK_NOFLAGS);
}
static void
@@ -3766,6 +3825,7 @@ ixl_atq_post_locked(struct ixl_softc *sc
sc->sc_atq_prod = prod_next;
ixl_wr(sc, sc->sc_aq_regs->atq_tail, sc->sc_atq_prod);
+ iatq->iatq_inuse = true;
return 0;
}
@@ -3799,6 +3859,7 @@ ixl_atq_done_locked(struct ixl_softc *sc
iatq = (struct ixl_atq *)((intptr_t)slot->iaq_cookie);
iatq->iatq_desc = *slot;
+ iatq->iatq_inuse = false;
memset(slot, 0, sizeof(*slot));
@@ -3833,7 +3894,7 @@ ixl_wakeup(struct ixl_softc *sc, const s
KASSERT(mutex_owned(&sc->sc_atq_lock));
- cv_signal(&sc->sc_atq_cv);
+ cv_broadcast(&sc->sc_atq_cv);
}
static int
@@ -3862,8 +3923,12 @@ ixl_atq_exec_locked(struct ixl_softc *sc
if (error)
return error;
- error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock,
- IXL_ATQ_EXEC_TIMEOUT);
+ do {
+ error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock,
+ IXL_ATQ_EXEC_TIMEOUT);
+ if (error == EWOULDBLOCK)
+ break;
+ } while (iatq->iatq_inuse);
return error;
}