Module Name:    src
Committed By:   martin
Date:           Mon May 30 17:01:06 UTC 2022

Modified Files:
        src/sys/dev/pci/ixgbe [netbsd-9]: ix_txrx.c ixgbe.c ixv.c

Log Message:
Pull up the following revisions, requested by msaitoh:

        sys/dev/pci/ixgbe/ixgbe.c       1.270,1.280,1.307-1.311,
                                        1.313-1.314 via patch
        sys/dev/pci/ixgbe/ix_txrx.c     1.96-1.97
        sys/dev/pci/ixgbe/ixv.c         1.158,1.179-1.180 via patch

- ixg(4): Print Printed Board Assembly (PBA) number.
- ixg(4): Add IFF_RUNNING check in ixgbe_legacy_irq() again. this might
  fix small race but it's not so dangerous.
- Add value check for {tx,rx}_process_limit sysctl to avoid setting
  wrong value.
- Add missing num_tx_desc sysctl.
- No functional change:
  - KNF a bit.
  - Simplify setting of EIAC register.
  - Move the definition of eicr_mask variable.
  - Enclose flow director stuff in ixgbe_intr_admin_common() with
    IXGBE_FIR which is not defined in NetBSD.
  - Modify comment for consistency.
  - Use cached rx_copy_len in ixgbe_rxeof().


To generate a diff of this commit:
cvs rdiff -u -r1.54.2.9 -r1.54.2.10 src/sys/dev/pci/ixgbe/ix_txrx.c
cvs rdiff -u -r1.199.2.20 -r1.199.2.21 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.125.2.17 -r1.125.2.18 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/sys/dev/pci/ixgbe/ix_txrx.c
diff -u src/sys/dev/pci/ixgbe/ix_txrx.c:1.54.2.9 src/sys/dev/pci/ixgbe/ix_txrx.c:1.54.2.10
--- src/sys/dev/pci/ixgbe/ix_txrx.c:1.54.2.9	Fri May 13 11:18:40 2022
+++ src/sys/dev/pci/ixgbe/ix_txrx.c	Mon May 30 17:01:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.54.2.9 2022/05/13 11:18:40 martin Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.54.2.10 2022/05/30 17:01:06 martin Exp $ */
 
 /******************************************************************************
 
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ix_txrx.c,v 1.54.2.9 2022/05/13 11:18:40 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ix_txrx.c,v 1.54.2.10 2022/05/30 17:01:06 martin Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -1819,6 +1819,7 @@ ixgbe_rxeof(struct ix_queue *que)
 	u32			staterr = 0;
 	u32			loopcount = 0, numdesc;
 	u32			limit = adapter->rx_process_limit;
+	u32			rx_copy_len = adapter->rx_copy_len;
 	bool			discard_multidesc = rxr->discard_multidesc;
 	bool			wraparound = false;
 	unsigned int		syncremain;
@@ -1929,7 +1930,7 @@ ixgbe_rxeof(struct ix_queue *que)
 			/* Pre-alloc new mbuf. */
 
 			if ((rbuf->fmp == NULL) &&
-			    eop && (len <= adapter->rx_copy_len)) {
+			    eop && (len <= rx_copy_len)) {
 				/* For short packet. See below. */
 				sendmp = m_gethdr(M_NOWAIT, MT_DATA);
 				if (__predict_false(sendmp == NULL)) {
@@ -2035,7 +2036,7 @@ ixgbe_rxeof(struct ix_queue *que)
 			 * packet.
 			 */
 
-			if (eop && (len <= adapter->rx_copy_len)) {
+			if (eop && (len <= rx_copy_len)) {
 				/*
 				 * Optimize.  This might be a small packet, may
 				 * be just a TCP ACK. Copy into a new mbuf, and
@@ -2047,7 +2048,7 @@ ixgbe_rxeof(struct ix_queue *que)
 				IXGBE_EVC_ADD(&rxr->rx_copies, 1);
 				rbuf->flags |= IXGBE_RX_COPY;
 			} else {
-				/* Non short packet */
+				/* For long packet */
 
 				/* Update new (used in future) mbuf */
 				newmp->m_pkthdr.len = newmp->m_len

Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.20 src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.21
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.20	Wed Feb  2 14:25:49 2022
+++ src/sys/dev/pci/ixgbe/ixgbe.c	Mon May 30 17:01:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.199.2.20 2022/02/02 14:25:49 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.199.2.21 2022/05/30 17:01:06 martin Exp $ */
 
 /******************************************************************************
 
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ixgbe.c,v 1.199.2.20 2022/02/02 14:25:49 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixgbe.c,v 1.199.2.21 2022/05/30 17:01:06 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -235,8 +235,6 @@ static int	ixgbe_set_advertise(struct ad
 static int	ixgbe_get_default_advertise(struct adapter *);
 
 /* Sysctl handlers */
-static void	ixgbe_set_sysctl_value(struct adapter *, const char *,
-		     const char *, int *, int);
 static int	ixgbe_sysctl_flowcntl(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_advertise(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
@@ -256,6 +254,8 @@ static int	ixgbe_sysctl_tdh_handler(SYSC
 static int	ixgbe_sysctl_eee_state(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_debug(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_rx_copy_len(SYSCTLFN_PROTO);
+static int	ixgbe_sysctl_tx_process_limit(SYSCTLFN_PROTO);
+static int	ixgbe_sysctl_rx_process_limit(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_wol_enable(SYSCTLFN_PROTO);
 static int	ixgbe_sysctl_wufc(SYSCTLFN_PROTO);
 
@@ -922,15 +922,6 @@ ixgbe_attach(device_t parent, device_t d
 	/* Set an initial default flow control value */
 	hw->fc.requested_mode = ixgbe_flow_control;
 
-	/* Sysctls for limiting the amount of work done in the taskqueues */
-	ixgbe_set_sysctl_value(adapter, "rx_processing_limit",
-	    "max number of rx packets to process",
-	    &adapter->rx_process_limit, ixgbe_rx_process_limit);
-
-	ixgbe_set_sysctl_value(adapter, "tx_processing_limit",
-	    "max number of tx packets to process",
-	    &adapter->tx_process_limit, ixgbe_tx_process_limit);
-
 	/* Do descriptor calc and sanity checks */
 	if (((ixgbe_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
 	    ixgbe_txd < MIN_TXD || ixgbe_txd > MAX_TXD) {
@@ -946,6 +937,14 @@ ixgbe_attach(device_t parent, device_t d
 	} else
 		adapter->num_rx_desc = ixgbe_rxd;
 
+	/* Sysctls for limiting the amount of work done in the taskqueues */
+	adapter->rx_process_limit
+	    = (ixgbe_rx_process_limit <= adapter->num_rx_desc)
+	    ? ixgbe_rx_process_limit : adapter->num_rx_desc;
+	adapter->tx_process_limit
+	    = (ixgbe_tx_process_limit <= adapter->num_tx_desc)
+	    ? ixgbe_tx_process_limit : adapter->num_tx_desc;
+
 	/* Set default high limit of copying mbuf in rxeof */
 	adapter->rx_copy_len = IXGBE_RX_COPY_LEN_MAX;
 
@@ -1086,6 +1085,10 @@ ixgbe_attach(device_t parent, device_t d
 	hw->eeprom.ops.read(hw, IXGBE_ETRACKID_L, &low);
 	aprint_normal(" ETrackID %08x\n", ((uint32_t)high << 16) | low);
 
+	/* Printed Board Assembly number */
+	error = ixgbe_read_pba_string(hw, buf, IXGBE_PBANUM_LENGTH);
+	aprint_normal_dev(dev, "PBA number %s\n", error ? "unknown" : buf);
+
 	if (adapter->feat_en & IXGBE_FEATURE_MSIX) {
 		error = ixgbe_allocate_msix(adapter, pa);
 		if (error) {
@@ -1105,6 +1108,7 @@ ixgbe_attach(device_t parent, device_t d
 			}
 		}
 	}
+
 	/* Recovery mode */
 	switch (adapter->hw.mac.type) {
 	case ixgbe_mac_X550:
@@ -2487,7 +2491,7 @@ ixgbe_setup_vlan_hw_support(struct adapt
 	struct vlanid_list *vlanidp;
 
 	/*
-	 *  This function is called from both if_init and ifflags_cb()
+	 * This function is called from both if_init and ifflags_cb()
 	 * on NetBSD.
 	 */
 
@@ -3103,7 +3107,7 @@ ixgbe_msix_link(void *arg)
 {
 	struct adapter	*adapter = arg;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32		eicr, eicr_mask;
+	u32		eicr;
 	s32		retval;
 
 	IXGBE_EVC_ADD(&adapter->link_irq, 1);
@@ -3125,6 +3129,8 @@ ixgbe_msix_link(void *arg)
 	IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
 
 	if (ixgbe_is_sfp(hw)) {
+		u32 eicr_mask;
+
 		/* Pluggable optics-related interrupt */
 		if (hw->mac.type >= ixgbe_mac_X540)
 			eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
@@ -3159,6 +3165,7 @@ ixgbe_msix_link(void *arg)
 	}
 
 	if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
+#ifdef IXGBE_FDIR
 		if ((adapter->feat_en & IXGBE_FEATURE_FDIR) &&
 		    (eicr & IXGBE_EICR_FLOW_DIR)) {
 			/* This is probably overkill :) */
@@ -3168,6 +3175,7 @@ ixgbe_msix_link(void *arg)
 			IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
 			softint_schedule(adapter->fdir_si);
 		}
+#endif
 
 		if (eicr & IXGBE_EICR_ECC) {
 			device_printf(adapter->dev,
@@ -3200,8 +3208,11 @@ ixgbe_msix_link(void *arg)
 				retval = hw->phy.ops.check_overtemp(hw);
 				if (retval != IXGBE_ERR_OVERTEMP)
 					break;
-				device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n");
-				device_printf(adapter->dev, "System shutdown required!\n");
+				device_printf(adapter->dev,
+				    "CRITICAL: OVER TEMP!! "
+				    "PHY IS SHUT DOWN!!\n");
+				device_printf(adapter->dev,
+				    "System shutdown required!\n");
 				IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
 				break;
 			}
@@ -3359,11 +3370,31 @@ ixgbe_add_device_sysctls(struct adapter 
 
 	if (sysctl_createv(log, 0, &rnode, &cnode,
 	    CTLFLAG_READONLY, CTLTYPE_INT,
-	    "num_rx_desc", SYSCTL_DESCR("Number of rx descriptors"),
+	    "num_tx_desc", SYSCTL_DESCR("Number of TX descriptors"),
+	    NULL, 0, &adapter->num_tx_desc, 0, CTL_CREATE, CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READONLY, CTLTYPE_INT,
+	    "num_rx_desc", SYSCTL_DESCR("Number of RX descriptors"),
 	    NULL, 0, &adapter->num_rx_desc, 0, CTL_CREATE, CTL_EOL) != 0)
 		aprint_error_dev(dev, "could not create sysctl\n");
 
 	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "rx_process_limit",
+	    SYSCTL_DESCR("max number of RX packets to process"),
+	    ixgbe_sysctl_rx_process_limit, 0, (void *)adapter, 0, CTL_CREATE,
+	    CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "tx_process_limit",
+	    SYSCTL_DESCR("max number of TX packets to process"),
+	    ixgbe_sysctl_tx_process_limit, 0, (void *)adapter, 0, CTL_CREATE,
+	    CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
 	    CTLFLAG_READONLY, CTLTYPE_INT,
 	    "num_queues", SYSCTL_DESCR("Number of queues"),
 	    NULL, 0, &adapter->num_queues, 0, CTL_CREATE, CTL_EOL) != 0)
@@ -5024,13 +5055,12 @@ ixgbe_enable_intr(struct adapter *adapte
 
 	/* With MSI-X we use auto clear */
 	if (adapter->msix_mem) {
-		mask = IXGBE_EIMS_ENABLE_MASK;
-		/* Don't autoclear Link */
-		mask &= ~IXGBE_EIMS_OTHER;
-		mask &= ~IXGBE_EIMS_LSC;
-		if (adapter->feat_cap & IXGBE_FEATURE_SRIOV)
-			mask &= ~IXGBE_EIMS_MAILBOX;
-		IXGBE_WRITE_REG(hw, IXGBE_EIAC, mask);
+		/*
+		 * We use auto clear for RTX_QUEUE only. Don't use other
+		 * interrupts (e.g. link interrupt). BTW, we don't use
+		 *  TCP_TIMER interrupt itself.
+		 */
+		IXGBE_WRITE_REG(hw, IXGBE_EIAC, IXGBE_EIMS_RTX_QUEUE);
 	}
 
 	/*
@@ -5095,9 +5125,10 @@ ixgbe_legacy_irq(void *arg)
 	struct ix_queue *que = arg;
 	struct adapter	*adapter = que->adapter;
 	struct ixgbe_hw	*hw = &adapter->hw;
+	struct ifnet	*ifp = adapter->ifp;
 	struct		tx_ring *txr = adapter->tx_rings;
 	bool		more = false;
-	u32		eicr, eicr_mask;
+	u32		eicr;
 	u32		eims_orig;
 
 	eims_orig = IXGBE_READ_REG(hw, IXGBE_EIMS);
@@ -5117,7 +5148,8 @@ ixgbe_legacy_irq(void *arg)
 	IXGBE_EVC_ADD(&adapter->stats.pf.legint, 1);
 
 	/* Queue (0) intr */
-	if ((eicr & IXGBE_EIMC_RTX_QUEUE) != 0) {
+	if (((ifp->if_flags & IFF_RUNNING) != 0) &&
+	    (eicr & IXGBE_EIMC_RTX_QUEUE) != 0) {
 		IXGBE_EVC_ADD(&que->irqs, 1);
 
 		/*
@@ -5153,6 +5185,8 @@ ixgbe_legacy_irq(void *arg)
 		softint_schedule(adapter->link_si);
 
 	if (ixgbe_is_sfp(hw)) {
+		u32 eicr_mask;
+
 		/* Pluggable optics-related interrupt */
 		if (hw->mac.type >= ixgbe_mac_X540)
 			eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
@@ -5243,35 +5277,6 @@ ixgbe_free_pci_resources(struct adapter 
 } /* ixgbe_free_pci_resources */
 
 /************************************************************************
- * ixgbe_set_sysctl_value
- ************************************************************************/
-static void
-ixgbe_set_sysctl_value(struct adapter *adapter, const char *name,
-    const char *description, int *limit, int value)
-{
-	device_t dev =	adapter->dev;
-	struct sysctllog **log;
-	const struct sysctlnode *rnode, *cnode;
-
-	/*
-	 * It's not required to check recovery mode because this function never
-	 * touches hardware.
-	 */
-
-	log = &adapter->sysctllog;
-	if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL) {
-		aprint_error_dev(dev, "could not create sysctl root\n");
-		return;
-	}
-	if (sysctl_createv(log, 0, &rnode, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_INT,
-	    name, SYSCTL_DESCR(description),
-		NULL, 0, limit, 0, CTL_CREATE, CTL_EOL) != 0)
-		aprint_error_dev(dev, "could not create sysctl\n");
-	*limit = value;
-} /* ixgbe_set_sysctl_value */
-
-/************************************************************************
  * ixgbe_sysctl_flowcntl
  *
  *   SYSCTL wrapper around setting Flow Control
@@ -6108,6 +6113,56 @@ ixgbe_sysctl_rx_copy_len(SYSCTLFN_ARGS)
 } /* ixgbe_sysctl_rx_copy_len */
 
 /************************************************************************
+ * ixgbe_sysctl_tx_process_limit
+ ************************************************************************/
+static int
+ixgbe_sysctl_tx_process_limit(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct adapter *adapter = (struct adapter *)node.sysctl_data;
+	int error;
+	int result = adapter->tx_process_limit;
+
+	node.sysctl_data = &result;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+	if ((result <= 0) || (result > adapter->num_tx_desc))
+		return EINVAL;
+
+	adapter->tx_process_limit = result;
+
+	return 0;
+} /* ixgbe_sysctl_tx_process_limit */
+
+/************************************************************************
+ * ixgbe_sysctl_rx_process_limit
+ ************************************************************************/
+static int
+ixgbe_sysctl_rx_process_limit(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct adapter *adapter = (struct adapter *)node.sysctl_data;
+	int error;
+	int result = adapter->rx_process_limit;
+
+	node.sysctl_data = &result;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+	if ((result <= 0) || (result > adapter->num_rx_desc))
+		return EINVAL;
+
+	adapter->rx_process_limit = result;
+
+	return 0;
+} /* ixgbe_sysctl_rx_process_limit */
+
+/************************************************************************
  * ixgbe_init_device_features
  ************************************************************************/
 static void

Index: src/sys/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.125.2.17 src/sys/dev/pci/ixgbe/ixv.c:1.125.2.18
--- src/sys/dev/pci/ixgbe/ixv.c:1.125.2.17	Wed Feb  2 14:25:49 2022
+++ src/sys/dev/pci/ixgbe/ixv.c	Mon May 30 17:01:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: ixv.c,v 1.125.2.17 2022/02/02 14:25:49 martin Exp $ */
+/* $NetBSD: ixv.c,v 1.125.2.18 2022/05/30 17:01:06 martin Exp $ */
 
 /******************************************************************************
 
@@ -35,7 +35,7 @@
 /*$FreeBSD: head/sys/dev/ixgbe/if_ixv.c 331224 2018-03-19 20:55:05Z erj $*/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ixv.c,v 1.125.2.17 2022/02/02 14:25:49 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixv.c,v 1.125.2.18 2022/05/30 17:01:06 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -136,8 +136,6 @@ static void	ixv_add_stats_sysctls(struct
 static void	ixv_clear_evcnt(struct adapter *);
 
 /* Sysctl handlers */
-static void	ixv_set_sysctl_value(struct adapter *, const char *,
-		    const char *, int *, int);
 static int	ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
 static int	ixv_sysctl_next_to_check_handler(SYSCTLFN_PROTO);
 static int	ixv_sysctl_next_to_refresh_handler(SYSCTLFN_PROTO);
@@ -145,6 +143,8 @@ static int	ixv_sysctl_rdh_handler(SYSCTL
 static int	ixv_sysctl_rdt_handler(SYSCTLFN_PROTO);
 static int	ixv_sysctl_tdt_handler(SYSCTLFN_PROTO);
 static int	ixv_sysctl_tdh_handler(SYSCTLFN_PROTO);
+static int	ixv_sysctl_tx_process_limit(SYSCTLFN_PROTO);
+static int	ixv_sysctl_rx_process_limit(SYSCTLFN_PROTO);
 static int	ixv_sysctl_rx_copy_len(SYSCTLFN_PROTO);
 
 /* The MSI-X Interrupt handlers */
@@ -485,15 +485,6 @@ ixv_attach(device_t parent, device_t dev
 	/* Register for VLAN events */
 	ether_set_vlan_cb(&adapter->osdep.ec, ixv_vlan_cb);
 
-	/* Sysctls for limiting the amount of work done in the taskqueues */
-	ixv_set_sysctl_value(adapter, "rx_processing_limit",
-	    "max number of rx packets to process",
-	    &adapter->rx_process_limit, ixv_rx_process_limit);
-
-	ixv_set_sysctl_value(adapter, "tx_processing_limit",
-	    "max number of tx packets to process",
-	    &adapter->tx_process_limit, ixv_tx_process_limit);
-
 	/* Do descriptor calc and sanity checks */
 	if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
 	    ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) {
@@ -509,6 +500,14 @@ ixv_attach(device_t parent, device_t dev
 	} else
 		adapter->num_rx_desc = ixv_rxd;
 
+	/* Sysctls for limiting the amount of work done in the taskqueues */
+	adapter->rx_process_limit
+	    = (ixv_rx_process_limit <= adapter->num_rx_desc)
+	    ? ixv_rx_process_limit : adapter->num_rx_desc;
+	adapter->tx_process_limit
+	    = (ixv_tx_process_limit <= adapter->num_tx_desc)
+	    ? ixv_tx_process_limit : adapter->num_tx_desc;
+
 	/* Set default high limit of copying mbuf in rxeof */
 	adapter->rx_copy_len = IXGBE_RX_COPY_LEN_MAX;
 
@@ -2092,7 +2091,7 @@ ixv_setup_vlan_support(struct adapter *a
 	int rv, error = 0;
 
 	/*
-	 *  This function is called from both if_init and ifflags_cb()
+	 * This function is called from both if_init and ifflags_cb()
 	 * on NetBSD.
 	 */
 
@@ -2503,8 +2502,8 @@ ixv_add_device_sysctls(struct adapter *a
 	}
 
 	if (sysctl_createv(log, 0, &rnode, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_INT,
-	    "debug", SYSCTL_DESCR("Debug Info"),
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
+	    SYSCTL_DESCR("Debug Info"),
 	    ixv_sysctl_debug, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL) != 0)
 		aprint_error_dev(dev, "could not create sysctl\n");
 
@@ -2516,15 +2515,42 @@ ixv_add_device_sysctls(struct adapter *a
 		aprint_error_dev(dev, "could not create sysctl\n");
 
 	if (sysctl_createv(log, 0, &rnode, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_BOOL,
-	    "enable_aim", SYSCTL_DESCR("Interrupt Moderation"),
+	    CTLFLAG_READONLY, CTLTYPE_INT,
+	    "num_tx_desc", SYSCTL_DESCR("Number of TX descriptors"),
+	    NULL, 0, &adapter->num_tx_desc, 0, CTL_CREATE, CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READONLY, CTLTYPE_INT,
+	    "num_rx_desc", SYSCTL_DESCR("Number of RX descriptors"),
+	    NULL, 0, &adapter->num_rx_desc, 0, CTL_CREATE, CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "rx_process_limit",
+	    SYSCTL_DESCR("max number of RX packets to process"),
+	    ixv_sysctl_rx_process_limit, 0, (void *)adapter, 0, CTL_CREATE,
+	    CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "tx_process_limit",
+	    SYSCTL_DESCR("max number of TX packets to process"),
+	    ixv_sysctl_tx_process_limit, 0, (void *)adapter, 0, CTL_CREATE,
+	    CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "enable_aim",
+	    SYSCTL_DESCR("Interrupt Moderation"),
 	    NULL, 0, &adapter->enable_aim, 0, CTL_CREATE, CTL_EOL) != 0)
 		aprint_error_dev(dev, "could not create sysctl\n");
 
 	if (sysctl_createv(log, 0, &rnode, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_BOOL,
-	    "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"),
-		NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL) != 0)
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue",
+	    SYSCTL_DESCR("Use workqueue for packet processing"),
+	    NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL)
+	    != 0)
 		aprint_error_dev(dev, "could not create sysctl\n");
 }
 
@@ -2630,10 +2656,9 @@ ixv_add_stats_sysctls(struct adapter *ad
 #endif /* LRO */
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
-		    CTLFLAG_READONLY,
-		    CTLTYPE_INT,
-		    "rxd_nxck", SYSCTL_DESCR("Receive Descriptor next to check"),
-			ixv_sysctl_next_to_check_handler, 0, (void *)rxr, 0,
+		    CTLFLAG_READONLY, CTLTYPE_INT, "rxd_nxck",
+		    SYSCTL_DESCR("Receive Descriptor next to check"),
+		    ixv_sysctl_next_to_check_handler, 0, (void *)rxr, 0,
 		    CTL_CREATE, CTL_EOL) != 0)
 			break;
 
@@ -2645,25 +2670,25 @@ ixv_add_stats_sysctls(struct adapter *ad
 			break;
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
-		    CTLFLAG_READONLY,
-		    CTLTYPE_INT,
-		    "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"),
+		    CTLFLAG_READONLY, CTLTYPE_INT, "rxd_head",
+		    SYSCTL_DESCR("Receive Descriptor Head"),
 		    ixv_sysctl_rdh_handler, 0, (void *)rxr, 0,
 		    CTL_CREATE, CTL_EOL) != 0)
 			break;
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
-		    CTLFLAG_READONLY,
-		    CTLTYPE_INT,
-		    "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"),
+		    CTLFLAG_READONLY, CTLTYPE_INT, "rxd_tail",
+		    SYSCTL_DESCR("Receive Descriptor Tail"),
 		    ixv_sysctl_rdt_handler, 0, (void *)rxr, 0,
 		    CTL_CREATE, CTL_EOL) != 0)
 			break;
 
 		evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC,
-		    NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");
+		    NULL, adapter->queues[i].evnamebuf,
+		    "Queue Packets Received");
 		evcnt_attach_dynamic(&rxr->rx_bytes, EVCNT_TYPE_MISC,
-		    NULL, adapter->queues[i].evnamebuf, "Queue Bytes Received");
+		    NULL, adapter->queues[i].evnamebuf,
+		    "Queue Bytes Received");
 		evcnt_attach_dynamic(&rxr->rx_copies, EVCNT_TYPE_MISC,
 		    NULL, adapter->queues[i].evnamebuf, "Copied RX Frames");
 		evcnt_attach_dynamic(&rxr->no_mbuf, EVCNT_TYPE_MISC,
@@ -2794,30 +2819,6 @@ ixv_clear_evcnt(struct adapter *adapter)
 
 } /* ixv_clear_evcnt */
 
-/************************************************************************
- * ixv_set_sysctl_value
- ************************************************************************/
-static void
-ixv_set_sysctl_value(struct adapter *adapter, const char *name,
-	const char *description, int *limit, int value)
-{
-	device_t dev =	adapter->dev;
-	struct sysctllog **log;
-	const struct sysctlnode *rnode, *cnode;
-
-	log = &adapter->sysctllog;
-	if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
-		aprint_error_dev(dev, "could not create sysctl root\n");
-		return;
-	}
-	if (sysctl_createv(log, 0, &rnode, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_INT,
-	    name, SYSCTL_DESCR(description),
-	    NULL, 0, limit, 0, CTL_CREATE, CTL_EOL) != 0)
-		aprint_error_dev(dev, "could not create sysctl\n");
-	*limit = value;
-} /* ixv_set_sysctl_value */
-
 #define PRINTQS(adapter, regname)					\
 	do {								\
 		struct ixgbe_hw	*_hw = &(adapter)->hw;			\
@@ -2909,7 +2910,57 @@ ixv_sysctl_rx_copy_len(SYSCTLFN_ARGS)
 	adapter->rx_copy_len = result;
 
 	return 0;
-} /* ixgbe_sysctl_rx_copy_len */
+} /* ixv_sysctl_rx_copy_len */
+
+/************************************************************************
+ * ixv_sysctl_tx_process_limit
+ ************************************************************************/
+static int
+ixv_sysctl_tx_process_limit(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct adapter *adapter = (struct adapter *)node.sysctl_data;
+	int error;
+	int result = adapter->tx_process_limit;
+
+	node.sysctl_data = &result;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+	if ((result <= 0) || (result > adapter->num_tx_desc))
+		return EINVAL;
+
+	adapter->tx_process_limit = result;
+
+	return 0;
+} /* ixv_sysctl_tx_process_limit */
+
+/************************************************************************
+ * ixv_sysctl_rx_process_limit
+ ************************************************************************/
+static int
+ixv_sysctl_rx_process_limit(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct adapter *adapter = (struct adapter *)node.sysctl_data;
+	int error;
+	int result = adapter->rx_process_limit;
+
+	node.sysctl_data = &result;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+	if ((result <= 0) || (result > adapter->num_rx_desc))
+		return EINVAL;
+
+	adapter->rx_process_limit = result;
+
+	return 0;
+} /* ixv_sysctl_rx_process_limit */
 
 /************************************************************************
  * ixv_init_device_features
@@ -3327,7 +3378,8 @@ ixv_allocate_msix(struct adapter *adapte
 	    ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
 	    IXGBE_WORKQUEUE_FLAGS);
 	if (error) {
-		aprint_error_dev(dev, "couldn't create workqueue for deferred Tx\n");
+		aprint_error_dev(dev,
+		    "couldn't create workqueue for deferred Tx\n");
 	}
 	adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
 
@@ -3336,8 +3388,7 @@ ixv_allocate_msix(struct adapter *adapte
 	    ixv_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
 	    IXGBE_WORKQUEUE_FLAGS);
 	if (error) {
-		aprint_error_dev(dev,
-		    "couldn't create workqueue for Tx/Rx\n");
+		aprint_error_dev(dev, "couldn't create workqueue for Tx/Rx\n");
 	}
 
 	/* and Mailbox */

Reply via email to