Author: np
Date: Fri Feb 26 07:08:44 2010
New Revision: 204348
URL: http://svn.freebsd.org/changeset/base/204348

Log:
  Support IFCAP_VLANHWTSO in cxgb(4).  It works with or without vlanhwtag.
  While here, remove old DPRINTFs and tidy up the capability code a bit.

Modified:
  head/sys/dev/cxgb/cxgb_main.c
  head/sys/dev/cxgb/cxgb_sge.c

Modified: head/sys/dev/cxgb/cxgb_main.c
==============================================================================
--- head/sys/dev/cxgb/cxgb_main.c       Fri Feb 26 06:44:00 2010        
(r204347)
+++ head/sys/dev/cxgb/cxgb_main.c       Fri Feb 26 07:08:44 2010        
(r204348)
@@ -972,7 +972,8 @@ cxgb_makedev(struct port_info *pi)
 }
 
 #define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
-    IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO)
+    IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
+    IFCAP_VLAN_HWTSO)
 #define CXGB_CAP_ENABLE (CXGB_CAP & ~IFCAP_TSO6)
 
 static int
@@ -1015,8 +1016,8 @@ cxgb_port_attach(device_t dev)
         * Disable TSO on 4-port - it isn't supported by the firmware.
         */     
        if (sc->params.nports > 2) {
-               ifp->if_capabilities &= ~IFCAP_TSO;
-               ifp->if_capenable &= ~IFCAP_TSO;
+               ifp->if_capabilities &= ~(IFCAP_TSO | IFCAP_VLAN_HWTSO);
+               ifp->if_capenable &= ~(IFCAP_TSO | IFCAP_VLAN_HWTSO);
                ifp->if_hwassist &= ~CSUM_TSO;
        }
 
@@ -2045,28 +2046,34 @@ fail:
 
                mask = ifr->ifr_reqcap ^ ifp->if_capenable;
                if (mask & IFCAP_TXCSUM) {
-                       if (IFCAP_TXCSUM & ifp->if_capenable) {
-                               ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4);
-                               ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP
-                                   | CSUM_IP | CSUM_TSO);
-                       } else {
-                               ifp->if_capenable |= IFCAP_TXCSUM;
-                               ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP
-                                   | CSUM_IP);
+                       ifp->if_capenable ^= IFCAP_TXCSUM;
+                       ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
+
+                       if (IFCAP_TSO & ifp->if_capenable &&
+                           !(IFCAP_TXCSUM & ifp->if_capenable)) {
+                               ifp->if_capenable &= ~IFCAP_TSO;
+                               ifp->if_hwassist &= ~CSUM_TSO;
+                               if_printf(ifp,
+                                   "tso disabled due to -txcsum.\n");
                        }
                }
-               if (mask & IFCAP_RXCSUM) {
+               if (mask & IFCAP_RXCSUM)
                        ifp->if_capenable ^= IFCAP_RXCSUM;
-               }
                if (mask & IFCAP_TSO4) {
-                       if (IFCAP_TSO4 & ifp->if_capenable) {
-                               ifp->if_capenable &= ~IFCAP_TSO4;
-                               ifp->if_hwassist &= ~CSUM_TSO;
-                       } else if (IFCAP_TXCSUM & ifp->if_capenable) {
-                               ifp->if_capenable |= IFCAP_TSO4;
-                               ifp->if_hwassist |= CSUM_TSO;
+                       ifp->if_capenable ^= IFCAP_TSO4;
+
+                       if (IFCAP_TSO & ifp->if_capenable) {
+                               if (IFCAP_TXCSUM & ifp->if_capenable)
+                                       ifp->if_hwassist |= CSUM_TSO;
+                               else {
+                                       ifp->if_capenable &= ~IFCAP_TSO;
+                                       ifp->if_hwassist &= ~CSUM_TSO;
+                                       if_printf(ifp,
+                                           "enable txcsum first.\n");
+                                       error = EAGAIN;
+                               }
                        } else
-                               error = EINVAL;
+                               ifp->if_hwassist &= ~CSUM_TSO;
                }
                if (mask & IFCAP_LRO) {
                        ifp->if_capenable ^= IFCAP_LRO;
@@ -2090,6 +2097,8 @@ fail:
                                PORT_UNLOCK(p);
                        }
                }
+               if (mask & IFCAP_VLAN_HWTSO)
+                       ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
                if (mask & IFCAP_VLAN_HWCSUM)
                        ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
 

Modified: head/sys/dev/cxgb/cxgb_sge.c
==============================================================================
--- head/sys/dev/cxgb/cxgb_sge.c        Fri Feb 26 06:44:00 2010        
(r204347)
+++ head/sys/dev/cxgb/cxgb_sge.c        Fri Feb 26 07:08:44 2010        
(r204348)
@@ -50,8 +50,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/smp.h>
 #include <sys/systm.h>
 #include <sys/syslog.h>
+#include <sys/socket.h>
 
 #include <net/bpf.h>   
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_vlan_var.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -1362,8 +1366,8 @@ write_wr_hdr_sgl(unsigned int ndesc, str
        }
 }
 
-/* sizeof(*eh) + sizeof(*vhdr) + sizeof(*ip) + sizeof(*tcp) */
-#define TCPPKTHDRSIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 20 + 20)
+/* sizeof(*eh) + sizeof(*ip) + sizeof(*tcp) */
+#define TCPPKTHDRSIZE (ETHER_HDR_LEN + 20 + 20)
 
 #define GET_VTAG(cntrl, m) \
 do { \
@@ -1399,10 +1403,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 
        prefetch(txd);
        m0 = *m;
-       
-       DPRINTF("t3_encap port_id=%d qsidx=%d ", pi->port_id, pi->first_qset);
-       DPRINTF("mlen=%d txpkt_intf=%d tx_chan=%d\n", m[0]->m_pkthdr.len, 
pi->txpkt_intf, pi->tx_chan);
-       
+
        mtx_assert(&qs->lock, MA_OWNED);
        cntrl = V_TXPKT_INTF(pi->txpkt_intf);
        KASSERT(m0->m_flags & M_PKTHDR, ("not packet header\n"));
@@ -1475,11 +1476,11 @@ t3_encap(struct sge_qset *qs, struct mbu
                check_ring_tx_db(sc, txq);
                return (0);             
        } else if (tso_info) {
-               int min_size = TCPPKTHDRSIZE, eth_type, tagged;
+               int eth_type;
                struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd;
+               struct ether_header *eh;
                struct ip *ip;
                struct tcphdr *tcp;
-               char *pkthdr;
 
                txd->flit[2] = 0;
                GET_VTAG(cntrl, m0);
@@ -1487,13 +1488,7 @@ t3_encap(struct sge_qset *qs, struct mbu
                hdr->cntrl = htonl(cntrl);
                hdr->len = htonl(mlen | 0x80000000);
 
-               DPRINTF("tso buf len=%d\n", mlen);
-
-               tagged = m0->m_flags & M_VLANTAG;
-               if (!tagged)
-                       min_size -= ETHER_VLAN_ENCAP_LEN;
-
-               if (__predict_false(mlen < min_size)) {
+               if (__predict_false(mlen < TCPPKTHDRSIZE)) {
                        
printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
                            m0, mlen, m0->m_pkthdr.tso_segsz,
                            m0->m_pkthdr.csum_flags, m0->m_flags);
@@ -1501,25 +1496,23 @@ t3_encap(struct sge_qset *qs, struct mbu
                }
 
                /* Make sure that ether, ip, tcp headers are all in m0 */
-               if (__predict_false(m0->m_len < min_size)) {
-                       m0 = m_pullup(m0, min_size);
+               if (__predict_false(m0->m_len < TCPPKTHDRSIZE)) {
+                       m0 = m_pullup(m0, TCPPKTHDRSIZE);
                        if (__predict_false(m0 == NULL)) {
                                /* XXX panic probably an overreaction */
                                panic("couldn't fit header into mbuf");
                        }
                }
-               pkthdr = m0->m_data;
 
-               if (tagged) {
+               eh = mtod(m0, struct ether_header *);
+               if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
                        eth_type = CPL_ETH_II_VLAN;
-                       ip = (struct ip *)(pkthdr + ETHER_HDR_LEN +
-                           ETHER_VLAN_ENCAP_LEN);
+                       ip = (struct ip *)((struct ether_vlan_header *)eh + 1);
                } else {
                        eth_type = CPL_ETH_II;
-                       ip = (struct ip *)(pkthdr + ETHER_HDR_LEN);
+                       ip = (struct ip *)(eh + 1);
                }
-               tcp = (struct tcphdr *)((uint8_t *)ip +
-                   sizeof(*ip)); 
+               tcp = (struct tcphdr *)(ip + 1);
 
                tso_info |= V_LSO_ETH_TYPE(eth_type) |
                            V_LSO_IPHDR_WORDS(ip->ip_hl) |
@@ -1527,12 +1520,10 @@ t3_encap(struct sge_qset *qs, struct mbu
                hdr->lso_info = htonl(tso_info);
 
                if (__predict_false(mlen <= PIO_LEN)) {
-                       /* pkt not undersized but fits in PIO_LEN
+                       /*
+                        * pkt not undersized but fits in PIO_LEN
                         * Indicates a TSO bug at the higher levels.
-                        *
                         */
-                       DPRINTF("**5592 Fix** 
mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
-                           m0, mlen, m0->m_pkthdr.tso_segsz, 
m0->m_pkthdr.csum_flags, m0->m_flags);
                        txsd->m = NULL;
                        m_copydata(m0, 0, mlen, (caddr_t)&txd->flit[3]);
                        flits = (mlen + 7) / 8 + 3;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to