Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 May 2017 02:00:37 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r318855 - stable/10/sys/dev/cxgbe
Message-ID:  <201705250200.v4P20bsZ043689@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Thu May 25 02:00:37 2017
New Revision: 318855
URL: https://svnweb.freebsd.org/changeset/base/318855

Log:
  MFC r318014, r318091, r318125, and r318263.
  
  r318014:
  cxgbe(4): Fixes related to the knob that controls link autonegotiation.
  
  - Do not leak the adapter lock in sysctl_autoneg.
  - Accept only 0 or 1 as valid settings for autonegotiation.
  - A fixed speed must be requested by the driver when autonegotiation is
    disabled otherwise the firmware will reject the l1cfg command.  Use
    the top speed supported by the port for now.
  
  r318091:
  cxgbe(4): Do not assume that if_qflush is always followed by inteface-down.
  
  r318125:
  Adjust whitespace and fix a comment.  No functional change.
  
  r318263:
  cxgbe(4): netmap-only interrupts for a VI do not have an associated rxq
  or ofld_rxq and should be ignored by vi_intr_iq.
  
  Sponsored by:	Chelsio Communications

Modified:
  stable/10/sys/dev/cxgbe/adapter.h
  stable/10/sys/dev/cxgbe/t4_main.c
  stable/10/sys/dev/cxgbe/t4_sge.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/cxgbe/adapter.h
==============================================================================
--- stable/10/sys/dev/cxgbe/adapter.h	Thu May 25 01:59:58 2017	(r318854)
+++ stable/10/sys/dev/cxgbe/adapter.h	Thu May 25 02:00:37 2017	(r318855)
@@ -198,11 +198,11 @@ struct vi_info {
 	int first_intr;
 
 	/* These need to be int as they are used in sysctl */
-	int ntxq;	/* # of tx queues */
-	int first_txq;	/* index of first tx queue */
-	int rsrv_noflowq; /* Reserve queue 0 for non-flowid packets */
-	int nrxq;	/* # of rx queues */
-	int first_rxq;	/* index of first rx queue */
+	int ntxq;		/* # of tx queues */
+	int first_txq;		/* index of first tx queue */
+	int rsrv_noflowq; 	/* Reserve queue 0 for non-flowid packets */
+	int nrxq;		/* # of rx queues */
+	int first_rxq;		/* index of first rx queue */
 	int nofldtxq;		/* # of offload tx queues */
 	int first_ofld_txq;	/* index of first offload tx queue */
 	int nofldrxq;		/* # of offload rx queues */
@@ -391,6 +391,7 @@ enum {
 	EQ_TYPEMASK	= 0x3,		/* 2 lsbits hold the type (see above) */
 	EQ_ALLOCATED	= (1 << 2),	/* firmware resources allocated */
 	EQ_ENABLED	= (1 << 3),	/* open for business */
+	EQ_QFLUSH	= (1 << 4),	/* if_qflush in progress */
 };
 
 /* Listed in order of preference.  Update t4_sysctls too if you change these */
@@ -696,7 +697,7 @@ struct sge_nm_txq {
 
 struct sge {
 	int nrxq;	/* total # of Ethernet rx queues */
-	int ntxq;	/* total # of Ethernet tx tx queues */
+	int ntxq;	/* total # of Ethernet tx queues */
 	int nofldrxq;	/* total # of TOE rx queues */
 	int nofldtxq;	/* total # of TOE tx queues */
 	int nnmrxq;	/* total # of netmap rx queues */
@@ -1078,6 +1079,24 @@ port_top_speed(const struct port_info *p
 }
 
 static inline int
+port_top_speed_raw(const struct port_info *pi)
+{
+
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
+		return (FW_PORT_CAP_SPEED_100G);
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
+		return (FW_PORT_CAP_SPEED_40G);
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
+		return (FW_PORT_CAP_SPEED_25G);
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+		return (FW_PORT_CAP_SPEED_10G);
+	if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+		return (FW_PORT_CAP_SPEED_1G);
+
+	return (0);
+}
+
+static inline int
 tx_resume_threshold(struct sge_eq *eq)
 {
 

Modified: stable/10/sys/dev/cxgbe/t4_main.c
==============================================================================
--- stable/10/sys/dev/cxgbe/t4_main.c	Thu May 25 01:59:58 2017	(r318854)
+++ stable/10/sys/dev/cxgbe/t4_main.c	Thu May 25 02:00:37 2017	(r318855)
@@ -983,6 +983,7 @@ t4_attach(device_t dev)
 			lc->autoneg = t4_autoneg ? AUTONEG_ENABLE :
 			    AUTONEG_DISABLE;
 		}
+		lc->requested_speed = port_top_speed_raw(pi);
 
 		rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
 		if (rc != 0) {
@@ -1794,12 +1795,15 @@ cxgbe_qflush(struct ifnet *ifp)
 	if (vi->flags & VI_INIT_DONE) {
 		for_each_txq(vi, i, txq) {
 			TXQ_LOCK(txq);
-			txq->eq.flags &= ~EQ_ENABLED;
+			txq->eq.flags |= EQ_QFLUSH;
 			TXQ_UNLOCK(txq);
 			while (!mp_ring_is_idle(txq->r)) {
 				mp_ring_check_drainage(txq->r, 0);
 				pause("qflush", 1);
 			}
+			TXQ_LOCK(txq);
+			txq->eq.flags &= ~EQ_QFLUSH;
+			TXQ_UNLOCK(txq);
 		}
 	}
 	if_qflush(ifp);
@@ -5738,7 +5742,12 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS)
 	if ((lc->supported & FW_PORT_CAP_ANEG) == 0)
 		return (ENOTSUP);
 
-	val = val ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	if (val == 0)
+		val = AUTONEG_DISABLE;
+	else if (val == 1)
+		val = AUTONEG_ENABLE;
+	else
+		return (EINVAL);
 	if (lc->autoneg == val)
 		return (0);	/* no change */
 
@@ -5751,6 +5760,7 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS)
 	rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
 	if (rc != 0)
 		lc->autoneg = old;
+	end_synchronized_op(sc, 0);
 	return (rc);
 }
 

Modified: stable/10/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- stable/10/sys/dev/cxgbe/t4_sge.c	Thu May 25 01:59:58 2017	(r318854)
+++ stable/10/sys/dev/cxgbe/t4_sge.c	Thu May 25 02:00:37 2017	(r318855)
@@ -947,6 +947,11 @@ vi_intr_iq(struct vi_info *vi, int idx)
 		return (&sc->sge.fwq);
 
 	nintr = vi->nintr;
+#ifdef DEV_NETMAP
+	/* Do not consider any netmap-only interrupts */
+	if (vi->flags & INTR_RXQ && vi->nnmrxq > vi->nrxq)
+		nintr -= vi->nnmrxq - vi->nrxq;
+#endif
 	KASSERT(nintr != 0,
 	    ("%s: vi %p has no exclusive interrupts, total interrupts = %d",
 	    __func__, vi, sc->intr_count));
@@ -2396,6 +2401,13 @@ cannot_use_txpkts(struct mbuf *m)
 	return (needs_tso(m));
 }
 
+static inline int
+discard_tx(struct sge_eq *eq)
+{
+
+	return ((eq->flags & (EQ_ENABLED | EQ_QFLUSH)) != EQ_ENABLED);
+}
+
 /*
  * r->items[cidx] to r->items[pidx], with a wraparound at r->size, are ready to
  * be consumed.  Return the actual number consumed.  0 indicates a stall.
@@ -2421,7 +2433,7 @@ eth_tx(struct mp_ring *r, u_int cidx, u_
 	total = 0;
 
 	TXQ_LOCK(txq);
-	if (__predict_false((eq->flags & EQ_ENABLED) == 0)) {
+	if (__predict_false(discard_tx(eq))) {
 		while (cidx != pidx) {
 			m0 = r->items[cidx];
 			m_freem(m0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705250200.v4P20bsZ043689>