Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci/ixgbe Update our ixg(4) driver up to FreeBSD r23...



details:   https://anonhg.NetBSD.org/src/rev/87ed3388288f
branches:  trunk
changeset: 807244:87ed3388288f
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Apr 02 09:26:55 2015 +0000

description:
Update our ixg(4) driver up to FreeBSD r238149:
- Add TSO6 support.
- The max size in dma tag is changed from 65535 to 262140 (IXGBE_TSO_SIZE).
  The value is the same as other *BSDs. The change might cause a address
  space shortage (ixgbe_dmamap_create() might fail) on some machines.
- Fix a lot of bugs.
- Improve performance.

diffstat:

 sys/dev/pci/ixgbe/ixgbe.c        |  229 +++++++---
 sys/dev/pci/ixgbe/ixgbe.h        |    6 +-
 sys/dev/pci/ixgbe/ixgbe_82598.c  |  104 ++--
 sys/dev/pci/ixgbe/ixgbe_82598.h  |    4 +-
 sys/dev/pci/ixgbe/ixgbe_82599.c  |   17 +-
 sys/dev/pci/ixgbe/ixgbe_api.c    |   26 +-
 sys/dev/pci/ixgbe/ixgbe_api.h    |    7 +-
 sys/dev/pci/ixgbe/ixgbe_common.c |  839 ++++++++++++++++++++------------------
 sys/dev/pci/ixgbe/ixgbe_common.h |   11 +-
 sys/dev/pci/ixgbe/ixgbe_mbx.c    |    2 +-
 sys/dev/pci/ixgbe/ixgbe_mbx.h    |    2 +-
 sys/dev/pci/ixgbe/ixgbe_osdep.h  |    5 +-
 sys/dev/pci/ixgbe/ixgbe_phy.c    |   69 ++-
 sys/dev/pci/ixgbe/ixgbe_phy.h    |    2 +-
 sys/dev/pci/ixgbe/ixgbe_type.h   |   97 +++-
 sys/dev/pci/ixgbe/ixgbe_vf.c     |   26 +-
 sys/dev/pci/ixgbe/ixgbe_vf.h     |    2 +-
 sys/dev/pci/ixgbe/ixgbe_x540.c   |    8 +-
 sys/dev/pci/ixgbe/ixv.c          |   12 +-
 sys/dev/pci/ixgbe/ixv.h          |    2 +-
 20 files changed, 844 insertions(+), 626 deletions(-)

diffs (truncated from 2680 to 300 lines):

diff -r e1cf2dd88964 -r 87ed3388288f sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Thu Apr 02 06:23:04 2015 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Thu Apr 02 09:26:55 2015 +0000
@@ -58,8 +58,8 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-/*$FreeBSD: src/sys/dev/ixgbe/ixgbe.c,v 1.51 2011/04/25 23:34:21 jfv Exp $*/
-/*$NetBSD: ixgbe.c,v 1.24 2015/03/27 05:57:28 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 238149 2012-07-05 20:51:44Z jfv $*/
+/*$NetBSD: ixgbe.c,v 1.25 2015/04/02 09:26:55 msaitoh Exp $*/
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -74,7 +74,7 @@
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.4.5";
+char ixgbe_driver_version[] = "2.4.8";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -111,6 +111,7 @@
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP, 0, 0, 0},
+       {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0},
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
        /* required last entry */
        {0, 0, 0, 0, 0}
@@ -198,7 +199,7 @@
 static void    ixgbe_add_rx_process_limit(struct adapter *, const char *,
                    const char *, int *, int);
 static u32     ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *);
-static bool    ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
+static bool    ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
 static void    ixgbe_set_ivar(struct adapter *, u8, u8, s8);
 static void    ixgbe_configure_ivars(struct adapter *);
 static u8 *    ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
@@ -357,7 +358,7 @@
  * be a reference on how to implement netmap support in a driver.
  * Additional comments are in ixgbe_netmap.h .
  *
- * <dev/netma/ixgbe_netmap.h> contains functions for netmap support
+ * <dev/netmap/ixgbe_netmap.h> contains functions for netmap support
  * that extend the standard driver.
  */
 #include <dev/netmap/ixgbe_netmap.h>
@@ -595,28 +596,25 @@
                goto err_late;
        }
 
-       /* Get Hardware Flow Control setting */
-       hw->fc.requested_mode = ixgbe_fc_full;
-       adapter->fc = hw->fc.requested_mode;
-       hw->fc.pause_time = IXGBE_FC_PAUSE;
-       hw->fc.low_water = IXGBE_FC_LO;
-       hw->fc.high_water[0] = IXGBE_FC_HI;
-       hw->fc.send_xon = TRUE;
-
        error = ixgbe_init_hw(hw);
-       if (error == IXGBE_ERR_EEPROM_VERSION) {
+       switch (error) {
+       case IXGBE_ERR_EEPROM_VERSION:
                aprint_error_dev(dev, "This device is a pre-production adapter/"
                    "LOM.  Please be aware there may be issues associated "
                    "with your hardware.\n If you are experiencing problems "
                    "please contact your Intel or hardware representative "
                    "who provided you with this hardware.\n");
-       } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               break;
+       case IXGBE_ERR_SFP_NOT_SUPPORTED:
                aprint_error_dev(dev,"Unsupported SFP+ Module\n");
-
-       if (error) {
                error = EIO;
                aprint_error_dev(dev,"Hardware Initialization Failure\n");
                goto err_late;
+       case IXGBE_ERR_SFP_NOT_PRESENT:
+               device_printf(dev,"No SFP+ Module found\n");
+               /* falls thru */
+       default:
+               break;
        }
 
        /* Detect and set physical type */
@@ -1307,6 +1305,14 @@
                txdctl |= IXGBE_TXDCTL_ENABLE;
                /* Set WTHRESH to 8, burst writeback */
                txdctl |= (8 << 16);
+               /*
+                * When the internal queue falls below PTHRESH (32),
+                * start prefetching as long as there are at least
+                * HTHRESH (1) buffers ready. The values are taken
+                * from the Intel linux driver 3.8.21.
+                * Prefetching enables tx line rate even with 1 queue.
+                */
+               txdctl |= (32 << 0) | (1 << 8);
                IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), txdctl);
        }
 
@@ -1393,7 +1399,7 @@
 #ifdef IXGBE_FDIR
        /* Init Flow director */
        if (hw->mac.type != ixgbe_mac_82598EB) {
-               u32 hdrm = 64 << fdir_pballoc;
+               u32 hdrm = 32 << fdir_pballoc;
 
                hw->mac.ops.setup_rxpba(hw, 0, hdrm, PBA_STRATEGY_EQUAL);
                ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
@@ -1419,6 +1425,35 @@
        /* Config/Enable Link */
        ixgbe_config_link(adapter);
 
+       /* Hardware Packet Buffer & Flow Control setup */
+       {
+               u32 rxpb, frame, size, tmp;
+
+               frame = adapter->max_frame_size;
+
+               /* Calculate High Water */
+               if (hw->mac.type == ixgbe_mac_X540)
+                       tmp = IXGBE_DV_X540(frame, frame);
+               else
+                       tmp = IXGBE_DV(frame, frame);
+               size = IXGBE_BT2KB(tmp);
+               rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
+               hw->fc.high_water[0] = rxpb - size;
+
+               /* Now calculate Low Water */
+               if (hw->mac.type == ixgbe_mac_X540)
+                       tmp = IXGBE_LOW_DV_X540(frame);
+               else
+                       tmp = IXGBE_LOW_DV(frame);
+               hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
+               
+               adapter->fc = hw->fc.requested_mode = ixgbe_fc_full;
+               hw->fc.pause_time = IXGBE_FC_PAUSE;
+               hw->fc.send_xon = TRUE;
+       }
+       /* Initialize the FC settings */
+       ixgbe_start_hw(hw);
+
        /* And now turn on interrupts */
        ixgbe_enable_intr(adapter);
 
@@ -1527,7 +1562,7 @@
                        ixgbe_start_locked(txr, ifp);
 #endif
                IXGBE_TX_UNLOCK(txr);
-               if (more || (ifp->if_flags & IFF_OACTIVE)) {
+               if (more) {
                        adapter->req.ev_count++;
                        softint_schedule(que->que_si);
                        return;
@@ -1724,10 +1759,8 @@
                        /* This is probably overkill :) */
                        if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1))
                                return;
-                       /* Clear the interrupt */
-                       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
-                       /* Turn off the interface */
-                       adapter->ifp->if_flags &= ~IFF_RUNNING;
+                       /* Disable the interrupt */
+                       IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR);
                        softint_schedule(adapter->fdir_si);
                } else
 #endif
@@ -1925,9 +1958,8 @@
        ** a packet.
        */
        if (m_head->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6)) {
-               if (ixgbe_tso_setup(txr, m_head, &paylen)) {
+               if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) {
                        cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
-                       olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
                        olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
                        olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
                        ++adapter->tso_tx.ev_count;
@@ -2220,6 +2252,8 @@
                                    ((adapter->link_speed == 128)? 10:1),
                                    "Full Duplex");
                        adapter->link_active = TRUE;
+                       /* Update any Flow Control changes */
+                       ixgbe_fc_enable(&adapter->hw);
                        if_link_state_change(ifp, LINK_STATE_UP);
                }
        } else { /* Link down */
@@ -2783,7 +2817,7 @@
         */
        ifp->if_hdrlen = sizeof(struct ether_vlan_header);
 
-       ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSOv4;
+       ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSOv4 | IFCAP_TSOv6;
        ifp->if_capenable = 0;
 
        ec->ec_capabilities |= ETHERCAP_VLAN_HWCSUM;
@@ -3152,7 +3186,8 @@
        for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) {
                error = ixgbe_dmamap_create(txr->txtag, 0, &txbuf->map);
                if (error != 0) {
-                       aprint_error_dev(dev, "Unable to create TX DMA map\n");
+                       aprint_error_dev(dev,
+                           "Unable to create TX DMA map (%d)\n", error);
                        goto fail;
                }
        }
@@ -3214,14 +3249,11 @@
                 * Slots in the netmap ring (indexed by "si") are
                 * kring->nkr_hwofs positions "ahead" wrt the
                 * corresponding slot in the NIC ring. In some drivers
-                * (not here) nkr_hwofs can be negative. When computing
-                * si = i + kring->nkr_hwofs make sure to handle wraparounds.
+                * (not here) nkr_hwofs can be negative. Function
+                * netmap_idx_n2k() handles wraparounds properly.
                 */
                if (slot) {
-                       int si = i + na->tx_rings[txr->me].nkr_hwofs;
-
-                       if (si >= na->num_tx_desc)
-                               si -= na->num_tx_desc;
+                       int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
                        netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
                }
 #endif /* DEV_NETMAP */
@@ -3301,7 +3333,7 @@
                        txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
                        break;
                 }
-               txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+               txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
                switch (hw->mac.type) {
                case ixgbe_mac_82598EB:
                        IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
@@ -3478,6 +3510,7 @@
        case ETHERTYPE_IPV6:
                m_copydata(mp, ehdrlen, sizeof(ip6), &ip6);
                ip_hlen = sizeof(ip6);
+               /* XXX-BZ this will go badly in case of ext hdrs. */
                ipproto = ip6.ip6_nxt;
                type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
                break;
@@ -3526,7 +3559,8 @@
  *
  **********************************************************************/
 static bool
-ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
+ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
+    u32 *olinfo_status)
 {
        struct m_tag *mtag;
        struct adapter *adapter = txr->adapter;
@@ -3534,11 +3568,16 @@
        struct ixgbe_adv_tx_context_desc *TXD;
        struct ixgbe_tx_buf        *tx_buffer;
        u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
-       u32 mss_l4len_idx = 0;
-       u16 vtag = 0;
-       int ctxd, ehdrlen,  hdrlen, ip_hlen, tcp_hlen;
+       u32 mss_l4len_idx = 0, len;
+       u16 vtag = 0, eh_type;
+       int ctxd, ehdrlen, ip_hlen, tcp_hlen;
        struct ether_vlan_header *eh;
+#ifdef INET6
+       struct ip6_hdr *ip6;
+#endif
+#ifdef INET
        struct ip *ip;
+#endif
        struct tcphdr *th;
 
 
@@ -3547,33 +3586,63 @@
         * Jump over vlan headers if already present
         */
        eh = mtod(mp, struct ether_vlan_header *);
-       if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) 
+       if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
                ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
-       else
+               eh_type = eh->evl_proto;
+       } else {
                ehdrlen = ETHER_HDR_LEN;
+               eh_type = eh->evl_encap_proto;
+       }
 
         /* Ensure we have at least the IP+TCP header in the first mbuf. */
-        if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr))
-               return FALSE;
+       len = ehdrlen + sizeof(struct tcphdr);
+       switch (ntohs(eh_type)) {
+#ifdef INET6
+       case ETHERTYPE_IPV6:
+               if (mp->m_len < len + sizeof(struct ip6_hdr))
+                       return FALSE;
+               ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+               /* XXX-BZ For now we do not pretend to support ext. hdrs. */
+               if (ip6->ip6_nxt != IPPROTO_TCP)
+                       return FALSE;



Home | Main Index | Thread Index | Old Index