Author: gnn
Date: Mon Apr 14 16:31:56 2014
New Revision: 264461
URL: http://svnweb.freebsd.org/changeset/base/264461

Log:
  Commit various fixes for the SolarFlare drivers, in particular
  this set of patches fixes support for systems with > 32 cores.
  
  Details include
  
  sfxge: RXQ index (not label) comes from FW in flush done/failed events
  
  Change the second argument name of the efx_rxq_flush_done_ev_t and
  efx_rxq_flush_failed_ev_t prototypes to highlight that RXQ index (not label)
  comes from FW in flush done and failed events.
  
  sfxge: TXQ index (not label) comes from FW in flush done event
  
  Change the second argument name of the efx_txq_flush_done_ev_t prototype to
  highlight that TXQ index (not label) comes from FW in flush done event.
  
  sfxge: use TXQ type as label to support more than 32 TXQs
  
  There are 3 TXQs in event queue 0 and 1 TXQ (with TCP/UDP checksum offload)
  in all other event queues.
  
  Submitted by: Andrew Rybchenko <Andrew.Rybchenko at oktetlabs.ru>
  Sponsored by:   Solarflare Communications, Inc.

Modified:
  head/sys/dev/sfxge/common/efx.h
  head/sys/dev/sfxge/common/efx_ev.c
  head/sys/dev/sfxge/common/efx_tx.c
  head/sys/dev/sfxge/sfxge_ev.c
  head/sys/dev/sfxge/sfxge_tx.c

Modified: head/sys/dev/sfxge/common/efx.h
==============================================================================
--- head/sys/dev/sfxge/common/efx.h     Mon Apr 14 16:15:11 2014        
(r264460)
+++ head/sys/dev/sfxge/common/efx.h     Mon Apr 14 16:31:56 2014        
(r264461)
@@ -1360,17 +1360,17 @@ typedef __checkReturn   boolean_t
 typedef        __checkReturn   boolean_t
 (*efx_rxq_flush_done_ev_t)(
        __in_opt        void *arg,
-       __in            uint32_t label);
+       __in            uint32_t rxq_index);
 
 typedef        __checkReturn   boolean_t
 (*efx_rxq_flush_failed_ev_t)(
        __in_opt        void *arg,
-       __in            uint32_t label);
+       __in            uint32_t rxq_index);
 
 typedef        __checkReturn   boolean_t
 (*efx_txq_flush_done_ev_t)(
        __in_opt        void *arg,
-       __in            uint32_t label);
+       __in            uint32_t txq_index);
 
 typedef        __checkReturn   boolean_t
 (*efx_software_ev_t)(

Modified: head/sys/dev/sfxge/common/efx_ev.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_ev.c  Mon Apr 14 16:15:11 2014        
(r264460)
+++ head/sys/dev/sfxge/common/efx_ev.c  Mon Apr 14 16:31:56 2014        
(r264461)
@@ -407,24 +407,24 @@ efx_ev_driver(
 
        switch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) {
        case FSE_AZ_TX_DESCQ_FLS_DONE_EV: {
-               uint32_t label;
+               uint32_t txq_index;
 
                EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
 
-               label = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
+               txq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
 
-               EFSYS_PROBE1(tx_descq_fls_done, uint32_t, label);
+               EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
 
                EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
-               should_abort = eecp->eec_txq_flush_done(arg, label);
+               should_abort = eecp->eec_txq_flush_done(arg, txq_index);
 
                break;
        }
        case FSE_AZ_RX_DESCQ_FLS_DONE_EV: {
-               uint32_t label;
+               uint32_t rxq_index;
                uint32_t failed;
 
-               label = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
+               rxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
                failed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
 
                EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
@@ -433,15 +433,15 @@ efx_ev_driver(
                if (failed) {
                        EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED);
 
-                       EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, label);
+                       EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);
 
-                       should_abort = eecp->eec_rxq_flush_failed(arg, label);
+                       should_abort = eecp->eec_rxq_flush_failed(arg, 
rxq_index);
                } else {
                        EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
 
-                       EFSYS_PROBE1(rx_descq_fls_done, uint32_t, label);
+                       EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
 
-                       should_abort = eecp->eec_rxq_flush_done(arg, label);
+                       should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
                }
 
                break;

Modified: head/sys/dev/sfxge/common/efx_tx.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_tx.c  Mon Apr 14 16:15:11 2014        
(r264460)
+++ head/sys/dev/sfxge/common/efx_tx.c  Mon Apr 14 16:31:56 2014        
(r264461)
@@ -290,7 +290,7 @@ efx_tx_qcreate(
        EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
 
        EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS == (1 << 
FRF_AZ_TX_DESCQ_LABEL_WIDTH));
-       EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
+       /*      EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);*/
        EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
 
        if (!ISP2(n) || !(n & EFX_TXQ_NDESCS_MASK)) {

Modified: head/sys/dev/sfxge/sfxge_ev.c
==============================================================================
--- head/sys/dev/sfxge/sfxge_ev.c       Mon Apr 14 16:15:11 2014        
(r264460)
+++ head/sys/dev/sfxge/sfxge_ev.c       Mon Apr 14 16:31:56 2014        
(r264461)
@@ -155,17 +155,18 @@ sfxge_ev_exception(void *arg, uint32_t c
 }
 
 static boolean_t
-sfxge_ev_rxq_flush_done(void *arg, uint32_t label)
+sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
 {
        struct sfxge_evq *evq;
        struct sfxge_softc *sc;
        struct sfxge_rxq *rxq;
        unsigned int index;
+       unsigned int label;
        uint16_t magic;
 
        evq = (struct sfxge_evq *)arg;
        sc = evq->sc;
-       rxq = sc->rxq[label];
+       rxq = sc->rxq[rxq_index];
 
        KASSERT(rxq != NULL, ("rxq == NULL"));
 
@@ -173,6 +174,7 @@ sfxge_ev_rxq_flush_done(void *arg, uint3
        index = rxq->index;
        evq = sc->evq[index];
 
+       label = rxq_index;
        KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
            ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != level"));
        magic = SFXGE_MAGIC_RX_QFLUSH_DONE | label;
@@ -185,17 +187,18 @@ sfxge_ev_rxq_flush_done(void *arg, uint3
 }
 
 static boolean_t
-sfxge_ev_rxq_flush_failed(void *arg, uint32_t label)
+sfxge_ev_rxq_flush_failed(void *arg, uint32_t rxq_index)
 {
        struct sfxge_evq *evq;
        struct sfxge_softc *sc;
        struct sfxge_rxq *rxq;
        unsigned int index;
+       unsigned int label;
        uint16_t magic;
 
        evq = (struct sfxge_evq *)arg;
        sc = evq->sc;
-       rxq = sc->rxq[label];
+       rxq = sc->rxq[rxq_index];
 
        KASSERT(rxq != NULL, ("rxq == NULL"));
 
@@ -203,6 +206,7 @@ sfxge_ev_rxq_flush_failed(void *arg, uin
        index = rxq->index;
        evq = sc->evq[index];
 
+       label = rxq_index;
        KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
            ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label"));
        magic = SFXGE_MAGIC_RX_QFLUSH_FAILED | label;
@@ -214,18 +218,27 @@ sfxge_ev_rxq_flush_failed(void *arg, uin
        return (B_FALSE);
 }
 
+static struct sfxge_txq *
+sfxge_get_txq_by_label(struct sfxge_evq *evq, enum sfxge_txq_type label)
+{
+       unsigned int index;
+
+       KASSERT((evq->index == 0 && label < SFXGE_TXQ_NTYPES) ||
+           (label == SFXGE_TXQ_IP_TCP_UDP_CKSUM), ("unexpected txq label"));
+       index = (evq->index == 0) ? label : (evq->index - 1 + SFXGE_TXQ_NTYPES);
+       return evq->sc->txq[index];
+}
+
 static boolean_t
 sfxge_ev_tx(void *arg, uint32_t label, uint32_t id)
 {
        struct sfxge_evq *evq;
-       struct sfxge_softc *sc;
        struct sfxge_txq *txq;
        unsigned int stop;
        unsigned int delta;
 
        evq = (struct sfxge_evq *)arg;
-       sc = evq->sc;
-       txq = sc->txq[label];
+       txq = sfxge_get_txq_by_label(evq, label);
 
        KASSERT(txq != NULL, ("txq == NULL"));
        KASSERT(evq->index == txq->evq_index,
@@ -256,16 +269,17 @@ done:
 }
 
 static boolean_t
-sfxge_ev_txq_flush_done(void *arg, uint32_t label)
+sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
 {
        struct sfxge_evq *evq;
        struct sfxge_softc *sc;
        struct sfxge_txq *txq;
+       unsigned int label;
        uint16_t magic;
 
        evq = (struct sfxge_evq *)arg;
        sc = evq->sc;
-       txq = sc->txq[label];
+       txq = sc->txq[txq_index];
 
        KASSERT(txq != NULL, ("txq == NULL"));
        KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
@@ -274,6 +288,7 @@ sfxge_ev_txq_flush_done(void *arg, uint3
        /* Resend a software event on the correct queue */
        evq = sc->evq[txq->evq_index];
 
+       label = txq->type;
        KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
            ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label"));
        magic = SFXGE_MAGIC_TX_QFLUSH_DONE | label;
@@ -330,7 +345,7 @@ sfxge_ev_software(void *arg, uint16_t ma
                break;
        }
        case SFXGE_MAGIC_TX_QFLUSH_DONE: {
-               struct sfxge_txq *txq = sc->txq[label];
+               struct sfxge_txq *txq = sfxge_get_txq_by_label(evq, label);
 
                KASSERT(txq != NULL, ("txq == NULL"));
                KASSERT(evq->index == txq->evq_index,

Modified: head/sys/dev/sfxge/sfxge_tx.c
==============================================================================
--- head/sys/dev/sfxge/sfxge_tx.c       Mon Apr 14 16:15:11 2014        
(r264460)
+++ head/sys/dev/sfxge/sfxge_tx.c       Mon Apr 14 16:31:56 2014        
(r264461)
@@ -27,6 +27,21 @@
  * SUCH DAMAGE.
  */
 
+/* Theory of operation:
+ *
+ * Tx queues allocation and mapping
+ *
+ * One Tx queue with enabled checksum offload is allocated per Rx channel
+ * (event queue).  Also 2 Tx queues (one without checksum offload and one
+ * with IP checksum offload only) are allocated and bound to event queue 0.
+ * sfxge_txq_type is used as Tx queue label.
+ *
+ * So, event queue plus label mapping to Tx queue index is:
+ *     if event queue index is 0, TxQ-index = TxQ-label * [0..SFXGE_TXQ_NTYPES)
+ *     else TxQ-index = SFXGE_TXQ_NTYPES + EvQ-index - 1
+ * See sfxge_get_txq_by_label() sfxge_ev.c
+ */
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -1179,7 +1194,7 @@ sfxge_tx_qstart(struct sfxge_softc *sc, 
        }
 
        /* Create the common code transmit queue. */
-       if ((rc = efx_tx_qcreate(sc->enp, index, index, esmp,
+       if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
            SFXGE_NDESCS, txq->buf_base_id, flags, evq->common,
            &txq->common)) != 0)
                goto fail;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to