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;
 }

Reply via email to