Author: yongari
Date: Tue Dec  2 02:30:12 2008
New Revision: 185540
URL: http://svn.freebsd.org/changeset/base/185540

Log:
  Add VLAN hardware tag insertion/stripping support. Tx/Rx checksum
  offload for VLAN frames are also supported. The VLAN hardware
  assistance is available only on 82550/82551 based controllers.
  While I'm here change the confusing name of bit1 in byte 22 of
  configuration block to vlan_drop_en. The bit controls whether
  hardware strips VLAN tagged frame or not. Special thanks to wpaul
  who sent valuable VLAN related information to me.
  
  Tested on:    i386, sparc64

Modified:
  head/sys/dev/fxp/if_fxp.c
  head/sys/dev/fxp/if_fxpreg.h

Modified: head/sys/dev/fxp/if_fxp.c
==============================================================================
--- head/sys/dev/fxp/if_fxp.c   Tue Dec  2 02:26:15 2008        (r185539)
+++ head/sys/dev/fxp/if_fxp.c   Tue Dec  2 02:30:12 2008        (r185540)
@@ -830,6 +830,12 @@ fxp_attach(device_t dev)
        ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
        ifp->if_capabilities |= IFCAP_VLAN_MTU;
        ifp->if_capenable |= IFCAP_VLAN_MTU; /* the hw bits already set */
+       if ((sc->flags & FXP_FLAG_EXT_RFA) != 0) {
+               ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING |
+                   IFCAP_VLAN_HWCSUM;
+               ifp->if_capenable |= IFCAP_VLAN_HWTAGGING |
+                   IFCAP_VLAN_HWCSUM;
+       }
 
        /*
         * Let the system queue as many packets as we have available
@@ -1554,6 +1560,12 @@ fxp_encap(struct fxp_softc *sc, struct m
                    FXP_IPCB_TCP_PACKET |
                    FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
        }
+       /* Configure VLAN hardware tag insertion. */
+       if ((m->m_flags & M_VLANTAG) != 0) {
+               cbp->ipcb_vlan_id = htons(m->m_pkthdr.ether_vtag);
+               txp->tx_cb->ipcb_ip_activation_high |=
+                   FXP_IPCB_INSERTVLAN_ENABLE;
+       }
 
        txp->tx_mbuf = m;
        txp->tx_cb->cb_status = 0;
@@ -1913,6 +1925,12 @@ fxp_intr_body(struct fxp_softc *sc, stru
                         /* Do IP checksum checking. */
                        if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
                                fxp_rxcsum(sc, ifp, m, status, total_len);
+                       if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
+                           (status & FXP_RFA_STATUS_VLAN) != 0) {
+                               m->m_pkthdr.ether_vtag =
+                                   ntohs(rfa->rfax_vlan_id);
+                               m->m_flags |= M_VLANTAG;
+                       }
                        /*
                         * Drop locks before calling if_input() since it
                         * may re-enter fxp_start() in the netisr case.
@@ -2284,6 +2302,8 @@ fxp_init_body(struct fxp_softc *sc)
        cbp->multi_ia =         0;      /* (don't) accept multiple IAs */
        cbp->mc_all =           sc->flags & FXP_FLAG_ALL_MCAST ? 1 : 0;
        cbp->gamla_rx =         sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0;
+       cbp->vlan_strip_en =    ((sc->flags & FXP_FLAG_EXT_RFA) != 0 &&
+           (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) ? 1 : 0;
 
        if (sc->tunable_noflow || sc->revision == FXP_REV_82557) {
                /*
@@ -2763,9 +2783,15 @@ fxp_ioctl(struct ifnet *ifp, u_long comm
                        if (ifp->if_flags & IFF_UP)
                                reinit++;
                }
-               if (reinit > 0)
+               if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
+                   (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) {
+                       ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+                               reinit++;
+               }
+               if (reinit > 0 && ifp->if_flags & IFF_UP)
                        fxp_init_body(sc);
                FXP_UNLOCK(sc);
+               VLAN_CAPABILITIES(ifp);
                break;
 
        default:

Modified: head/sys/dev/fxp/if_fxpreg.h
==============================================================================
--- head/sys/dev/fxp/if_fxpreg.h        Tue Dec  2 02:26:15 2008        
(r185539)
+++ head/sys/dev/fxp/if_fxpreg.h        Tue Dec  2 02:30:12 2008        
(r185540)
@@ -224,7 +224,7 @@ struct fxp_cb_config {
 
        /* Bytes 22 - 31 -- i82550 only */
        u_int           __FXP_BITFIELD3(gamla_rx:1,
-                           vlan_drop_en:1,
+                           vlan_strip_en:1,
                            :6);
        uint8_t         pad[9];
 };
@@ -377,6 +377,7 @@ struct fxp_rfa {
 #define FXP_RFA_STATUS_RNR     0x0200  /* no resources */
 #define FXP_RFA_STATUS_ALIGN   0x0400  /* alignment error */
 #define FXP_RFA_STATUS_CRC     0x0800  /* CRC error */
+#define FXP_RFA_STATUS_VLAN    0x1000  /* VLAN tagged frame */
 #define FXP_RFA_STATUS_OK      0x2000  /* packet received okay */
 #define FXP_RFA_STATUS_C       0x8000  /* packet reception complete */
 #define FXP_RFA_CONTROL_SF     0x08    /* simple/flexible memory mode */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to