Author: yongari
Date: Thu Jun 18 05:50:45 2009
New Revision: 194423
URL: http://svn.freebsd.org/changeset/base/194423

Log:
  MFC r193298-193299:
  r193298:
    Add Rx checksum offloading support for Yukon FE+ and Yukon Extreme.
    These controllers use newer descriptor format and the new descriptor
    format uses status LE to indicate the status of checksum. Rx
    checksummed value used in previous controllers were very cryptic
    and I failed to understand how to use them. In addition most
    controllers in previous generations had Rx checksum offloading bug.
  
    While I'm here introduce a MSK_FLAG_NORX_CSUM flag to bypass
    checking Rx checksum offloading as Yukon FE+ A0 has status LE bug.
  
  r193299:
    Add Yukon Extreme device ids, 88E8071 and 88E8072.
    While I'm here correct description of 88E8070. 88E8070 is Yukon
    Extreme and have gigabit PHY.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/msk/if_msk.c
  stable/7/sys/dev/msk/if_mskreg.h

Modified: stable/7/sys/dev/msk/if_msk.c
==============================================================================
--- stable/7/sys/dev/msk/if_msk.c       Thu Jun 18 05:46:33 2009        
(r194422)
+++ stable/7/sys/dev/msk/if_msk.c       Thu Jun 18 05:50:45 2009        
(r194423)
@@ -203,8 +203,6 @@ static struct msk_product {
            "Marvell Yukon 88E8040T Fast Ethernet" },
        { VENDORID_MARVELL, DEVICEID_MRVL_8048,
            "Marvell Yukon 88E8048 Fast Ethernet" },
-       { VENDORID_MARVELL, DEVICEID_MRVL_8070,
-           "Marvell Yukon 88E8070 Fast Ethernet" },
        { VENDORID_MARVELL, DEVICEID_MRVL_4361,
            "Marvell Yukon 88E8050 Gigabit Ethernet" },
        { VENDORID_MARVELL, DEVICEID_MRVL_4360,
@@ -215,8 +213,14 @@ static struct msk_product {
            "Marvell Yukon 88E8055 Gigabit Ethernet" },
        { VENDORID_MARVELL, DEVICEID_MRVL_4364,
            "Marvell Yukon 88E8056 Gigabit Ethernet" },
+       { VENDORID_MARVELL, DEVICEID_MRVL_4365,
+           "Marvell Yukon 88E8070 Gigabit Ethernet" },
        { VENDORID_MARVELL, DEVICEID_MRVL_436A,
            "Marvell Yukon 88E8058 Gigabit Ethernet" },
+       { VENDORID_MARVELL, DEVICEID_MRVL_436B,
+           "Marvell Yukon 88E8071 Gigabit Ethernet" },
+       { VENDORID_MARVELL, DEVICEID_MRVL_436C,
+           "Marvell Yukon 88E8072 Gigabit Ethernet" },
        { VENDORID_DLINK, DEVICEID_DLINK_DGE550SX,
            "D-Link 550SX Gigabit Ethernet" },
        { VENDORID_DLINK, DEVICEID_DLINK_DGE560T,
@@ -258,8 +262,8 @@ static void msk_intr_hwerr(struct msk_so
 #ifndef __NO_STRICT_ALIGNMENT
 static __inline void msk_fixup_rx(struct mbuf *);
 #endif
-static void msk_rxeof(struct msk_if_softc *, uint32_t, int);
-static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, int);
+static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
+static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
 static void msk_txeof(struct msk_if_softc *, int);
 static int msk_encap(struct msk_if_softc *, struct mbuf **);
 static void msk_tx_task(void *, int);
@@ -267,6 +271,7 @@ static void msk_start(struct ifnet *);
 static int msk_ioctl(struct ifnet *, u_long, caddr_t);
 static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t);
 static void msk_set_rambuffer(struct msk_if_softc *);
+static void msk_set_tx_stfwd(struct msk_if_softc *);
 static void msk_init(void *);
 static void msk_init_locked(struct msk_if_softc *);
 static void msk_stop(struct msk_if_softc *);
@@ -991,12 +996,17 @@ msk_ioctl(struct ifnet *ifp, u_long comm
                        else
                                ifp->if_hwassist &= ~MSK_CSUM_FEATURES;
                }
+               if ((mask & IFCAP_RXCSUM) != 0 &&
+                   (IFCAP_RXCSUM & ifp->if_capabilities) != 0)
+                       ifp->if_capenable ^= IFCAP_RXCSUM;
                if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
                    (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
                        ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
                        msk_setvlan(sc_if, ifp);
                }
-
+               if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
+                   (IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0)
+                       ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
                if ((mask & IFCAP_TSO4) != 0 &&
                    (IFCAP_TSO4 & ifp->if_capabilities) != 0) {
                        ifp->if_capenable ^= IFCAP_TSO4;
@@ -1492,6 +1502,13 @@ msk_attach(device_t dev)
         * make Rx checksum offload work on Yukon II hardware.
         */
        ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4;
+       /*
+        * Enable Rx checksum offloading if controller support new
+        * descriptor format.
+        */
+       if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && 
+           (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
+               ifp->if_capabilities |= IFCAP_RXCSUM;
        ifp->if_hwassist = MSK_CSUM_FEATURES | CSUM_TSO;
        ifp->if_capenable = ifp->if_capabilities;
        ifp->if_ioctl = msk_ioctl;
@@ -1535,6 +1552,13 @@ msk_attach(device_t dev)
                 * for VLAN interface.
                 */
                ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+               /*
+                * Enable Rx checksum offloading for VLAN taggedd frames
+                * if controller support new descriptor format.
+                */
+               if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 && 
+                   (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
+                       ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
        }
        ifp->if_capenable = ifp->if_capabilities;
 
@@ -1711,7 +1735,8 @@ mskc_attach(device_t dev)
                         * Just pass received frames to upper stack with
                         * minimal test and let upper stack handle them.
                         */
-                       sc->msk_pflags |= MSK_FLAG_NOHWVLAN | MSK_FLAG_NORXCHK;
+                       sc->msk_pflags |= MSK_FLAG_NOHWVLAN |
+                           MSK_FLAG_NORXCHK | MSK_FLAG_NORX_CSUM;
                }
                break;
        case CHIP_ID_YUKON_XL:
@@ -2942,7 +2967,8 @@ msk_fixup_rx(struct mbuf *m)
 #endif
 
 static void
-msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
+msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
+    int len)
 {
        struct mbuf *m;
        struct ifnet *ifp;
@@ -2994,6 +3020,18 @@ msk_rxeof(struct msk_if_softc *sc_if, ui
                        msk_fixup_rx(m);
 #endif
                ifp->if_ipackets++;
+               if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
+                   (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+                       m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+                       if ((control & CSS_IPV4_CSUM_OK) != 0)
+                               m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+                       if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+                           (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+                               m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+                                   CSUM_PSEUDO_HDR;
+                               m->m_pkthdr.csum_data = 0xffff;
+                       }
+               }
                /* Check for VLAN tagged packets. */
                if ((status & GMR_FS_VLAN) != 0 &&
                    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3010,7 +3048,8 @@ msk_rxeof(struct msk_if_softc *sc_if, ui
 }
 
 static void
-msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
+msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
+    int len)
 {
        struct mbuf *m;
        struct ifnet *ifp;
@@ -3051,6 +3090,18 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_
                        msk_fixup_rx(m);
 #endif
                ifp->if_ipackets++;
+               if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
+                   (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+                       m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+                       if ((control & CSS_IPV4_CSUM_OK) != 0)
+                               m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+                       if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+                           (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+                               m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+                                   CSUM_PSEUDO_HDR;
+                               m->m_pkthdr.csum_data = 0xffff;
+                       }
+               }
                /* Check for VLAN tagged packets. */
                if ((status & GMR_FS_VLAN) != 0 &&
                    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3379,9 +3430,9 @@ msk_handle_events(struct msk_softc *sc)
                case OP_RXSTAT:
                        if (sc_if->msk_framesize >
                            (MCLBYTES - MSK_RX_BUF_ALIGN))
-                               msk_jumbo_rxeof(sc_if, status, len);
+                               msk_jumbo_rxeof(sc_if, status, control, len);
                        else
-                               msk_rxeof(sc_if, status, len);
+                               msk_rxeof(sc_if, status, control, len);
                        rxprog++;
                        /*
                         * Because there is no way to sync single Rx LE

Modified: stable/7/sys/dev/msk/if_mskreg.h
==============================================================================
--- stable/7/sys/dev/msk/if_mskreg.h    Thu Jun 18 05:46:33 2009        
(r194422)
+++ stable/7/sys/dev/msk/if_mskreg.h    Thu Jun 18 05:50:45 2009        
(r194423)
@@ -139,8 +139,10 @@
 #define DEVICEID_MRVL_4362     0x4362
 #define DEVICEID_MRVL_4363     0x4363
 #define DEVICEID_MRVL_4364     0x4364
-#define DEVICEID_MRVL_8070     0x4365
+#define DEVICEID_MRVL_4365     0x4365
 #define DEVICEID_MRVL_436A     0x436A
+#define DEVICEID_MRVL_436B     0x436B
+#define DEVICEID_MRVL_436C     0x436C
 
 /*
  * D-Link gigabit ethernet device ID
@@ -2255,8 +2257,19 @@ struct msk_stat_desc {
 #define OP_PUTIDX      0x70000000
 
 #define        STLE_OP_MASK    0xff000000
+#define        STLE_CSS_MASK   0x00ff0000
 #define        STLE_LEN_MASK   0x0000ffff
 
+/* CSS defined in status LE(valid for descriptor V2 format). */
+#define        CSS_TCPUDP_CSUM_OK      0x00800000
+#define        CSS_UDP                 0x00400000
+#define        CSS_TCP                 0x00200000
+#define        CSS_IPFRAG              0x00100000
+#define        CSS_IPV6                0x00080000
+#define        CSS_IPV4_CSUM_OK        0x00040000
+#define        CSS_IPV4                0x00020000
+#define        CSS_PORT                0x00010000
+
 /* Descriptor Bit Definition */
 /*     TxCtrl          Transmit Buffer Control Field */
 /*     RxCtrl          Receive  Buffer Control Field */
@@ -2505,6 +2518,7 @@ struct msk_if_softc {
 #define        MSK_FLAG_AUTOTX_CSUM    0x0080
 #define        MSK_FLAG_NOHWVLAN       0x0100
 #define        MSK_FLAG_NORXCHK        0x0200
+#define        MSK_FLAG_NORX_CSUM      0x0400
 #define        MSK_FLAG_SUSPEND        0x2000
 #define        MSK_FLAG_DETACH         0x4000
 #define        MSK_FLAG_LINK           0x8000
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to