Module Name:    src
Committed By:   msaitoh
Date:           Tue Feb 27 04:58:27 UTC 2018

Modified Files:
        src/sys/dev/pci/ixgbe: ixv.c

Log Message:
 Add hw.ixvM.q[01].{interrupt_rate,[tr]xd_head,[tr]xd_tail} sysctls as ixg(4).


To generate a diff of this commit:
cvs rdiff -u -r1.82 -r1.83 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/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.82 src/sys/dev/pci/ixgbe/ixv.c:1.83
--- src/sys/dev/pci/ixgbe/ixv.c:1.82	Mon Feb 26 08:14:01 2018
+++ src/sys/dev/pci/ixgbe/ixv.c	Tue Feb 27 04:58:27 2018
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.82 2018/02/26 08:14:01 knakahara Exp $*/
+/*$NetBSD: ixv.c,v 1.83 2018/02/27 04:58:27 msaitoh Exp $*/
 
 /******************************************************************************
 
@@ -131,8 +131,16 @@ 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 *);
+
+
+/* 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_rdh_handler(SYSCTLFN_PROTO);
+static int      ixv_sysctl_rdt_handler(SYSCTLFN_PROTO);
+static int      ixv_sysctl_tdt_handler(SYSCTLFN_PROTO);
+static int      ixv_sysctl_tdh_handler(SYSCTLFN_PROTO);
 
 /* The MSI-X Interrupt handlers */
 static int	ixv_msix_que(void *);
@@ -181,6 +189,9 @@ TUNABLE_INT("hw.ixv.num_queues", &ixv_nu
 static bool ixv_enable_aim = false;
 TUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim);
 
+static int ixv_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY);
+TUNABLE_INT("hw.ixv.max_interrupt_rate", &ixv_max_interrupt_rate);
+
 /* How many packets rxeof tries to clean at a time */
 static int ixv_rx_process_limit = 256;
 TUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit);
@@ -1785,6 +1796,86 @@ ixv_initialize_receive_units(struct adap
 } /* ixv_initialize_receive_units */
 
 /************************************************************************
+ * ixv_sysctl_tdh_handler - Transmit Descriptor Head handler function
+ *
+ *   Retrieves the TDH value from the hardware
+ ************************************************************************/
+static int 
+ixv_sysctl_tdh_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
+	uint32_t val;
+
+	if (!txr)
+		return (0);
+
+	val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDH(txr->me));
+	node.sysctl_data = &val;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+} /* ixv_sysctl_tdh_handler */
+
+/************************************************************************
+ * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function
+ *
+ *   Retrieves the TDT value from the hardware
+ ************************************************************************/
+static int 
+ixv_sysctl_tdt_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
+	uint32_t val;
+
+	if (!txr)
+		return (0);
+
+	val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDT(txr->me));
+	node.sysctl_data = &val;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+} /* ixv_sysctl_tdt_handler */
+
+/************************************************************************
+ * ixv_sysctl_rdh_handler - Receive Descriptor Head handler function
+ *
+ *   Retrieves the RDH value from the hardware
+ ************************************************************************/
+static int 
+ixv_sysctl_rdh_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
+	uint32_t val;
+
+	if (!rxr)
+		return (0);
+
+	val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDH(rxr->me));
+	node.sysctl_data = &val;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+} /* ixv_sysctl_rdh_handler */
+
+/************************************************************************
+ * ixv_sysctl_rdt_handler - Receive Descriptor Tail handler function
+ *
+ *   Retrieves the RDT value from the hardware
+ ************************************************************************/
+static int 
+ixv_sysctl_rdt_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
+	uint32_t val;
+
+	if (!rxr)
+		return (0);
+
+	val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDT(rxr->me));
+	node.sysctl_data = &val;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+} /* ixv_sysctl_rdt_handler */
+
+/************************************************************************
  * ixv_setup_vlan_support
  ************************************************************************/
 static void
@@ -2111,6 +2202,55 @@ ixv_update_stats(struct adapter *adapter
 	 */
 } /* ixv_update_stats */
 
+/************************************************************************
+ * ixv_sysctl_interrupt_rate_handler
+ ************************************************************************/
+static int
+ixv_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct ix_queue *que = (struct ix_queue *)node.sysctl_data;
+	struct adapter  *adapter = que->adapter;
+	uint32_t reg, usec, rate;
+	int error;
+
+	if (que == NULL)
+		return 0;
+	reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_VTEITR(que->msix));
+	usec = ((reg & 0x0FF8) >> 3);
+	if (usec > 0)
+		rate = 500000 / usec;
+	else
+		rate = 0;
+	node.sysctl_data = &rate;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+	reg &= ~0xfff; /* default, no limitation */
+	if (rate > 0 && rate < 500000) {
+		if (rate < 1000)
+			rate = 1000;
+		reg |= ((4000000/rate) & 0xff8);
+		/*
+		 * When RSC is used, ITR interval must be larger than
+		 * RSC_DELAY. Currently, we use 2us for RSC_DELAY.
+		 * The minimum value is always greater than 2us on 100M
+		 * (and 10M?(not documented)), but it's not on 1G and higher.
+		 */
+		if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
+		    && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
+			if ((adapter->num_queues > 1)
+			    && (reg < IXGBE_MIN_RSC_EITR_10G1G))
+				return EINVAL;
+		}
+		ixv_max_interrupt_rate = rate;
+	} else
+		ixv_max_interrupt_rate = 0;
+	ixv_eitr_write(que, reg);
+
+	return (0);
+} /* ixv_sysctl_interrupt_rate_handler */
+
 const struct sysctlnode *
 ixv_sysctl_instance(struct adapter *adapter)
 {
@@ -2173,7 +2313,7 @@ ixv_add_stats_sysctls(struct adapter *ad
 	struct rx_ring          *rxr = adapter->rx_rings;
 	struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
 	struct ixgbe_hw *hw = &adapter->hw;
-	const struct sysctlnode *rnode;
+	const struct sysctlnode *rnode, *cnode;
 	struct sysctllog **log = &adapter->sysctllog;
 	const char *xname = device_xname(dev);
 
@@ -2221,35 +2361,36 @@ ixv_add_stats_sysctls(struct adapter *ad
 		    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
 			break;
 
-#if 0 /* not yet */
 		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READWRITE, CTLTYPE_INT,
 		    "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"),
-		    ixgbe_sysctl_interrupt_rate_handler, 0,
+		    ixv_sysctl_interrupt_rate_handler, 0,
 		    (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0)
 			break;
 
+#if 0
 		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READONLY, CTLTYPE_QUAD,
 		    "irqs", SYSCTL_DESCR("irqs on this queue"),
 			NULL, 0, &(adapter->queues[i].irqs),
 		    0, CTL_CREATE, CTL_EOL) != 0)
 			break;
+#endif
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READONLY, CTLTYPE_INT,
 		    "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"),
-		    ixgbe_sysctl_tdh_handler, 0, (void *)txr,
+		    ixv_sysctl_tdh_handler, 0, (void *)txr,
 		    0, CTL_CREATE, CTL_EOL) != 0)
 			break;
 
 		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READONLY, CTLTYPE_INT,
 		    "txd_tail", SYSCTL_DESCR("Transmit Descriptor Tail"),
-		    ixgbe_sysctl_tdt_handler, 0, (void *)txr,
+		    ixv_sysctl_tdt_handler, 0, (void *)txr,
 		    0, CTL_CREATE, CTL_EOL) != 0)
 			break;
-#endif
+
 		evcnt_attach_dynamic(&adapter->queues[i].irqs, EVCNT_TYPE_INTR,
 		    NULL, adapter->queues[i].evnamebuf, "IRQs on queue");
 		evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC,
@@ -2270,12 +2411,11 @@ ixv_add_stats_sysctls(struct adapter *ad
 		struct lro_ctrl *lro = &rxr->lro;
 #endif /* LRO */
 
-#if 0 /* not yet */
 		if (sysctl_createv(log, 0, &rnode, &cnode,
 		    CTLFLAG_READONLY,
 		    CTLTYPE_INT,
 		    "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"),
-		    ixgbe_sysctl_rdh_handler, 0, (void *)rxr, 0,
+		    ixv_sysctl_rdh_handler, 0, (void *)rxr, 0,
 		    CTL_CREATE, CTL_EOL) != 0)
 			break;
 
@@ -2283,10 +2423,9 @@ ixv_add_stats_sysctls(struct adapter *ad
 		    CTLFLAG_READONLY,
 		    CTLTYPE_INT,
 		    "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"),
-		    ixgbe_sysctl_rdt_handler, 0, (void *)rxr, 0,
+		    ixv_sysctl_rdt_handler, 0, (void *)rxr, 0,
 		    CTL_CREATE, CTL_EOL) != 0)
 			break;
-#endif
 
 		evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC,
 		    NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");

Reply via email to