unsigned long tx_underflow ____cacheline_aligned;
        unsigned long tx_carrier;
        unsigned long tx_losscarrier;
-       unsigned long tx_heartbeat;
+       unsigned long vlan_tag;
        unsigned long tx_deferred;
        unsigned long tx_vlan;
        unsigned long tx_jabber;
        unsigned long tx_ip_header_error;
        /* Receive errors */
        unsigned long rx_desc;
-       unsigned long rx_partial;
-       unsigned long rx_runt;
-       unsigned long rx_toolong;
+       unsigned long sa_filter_fail;
+       unsigned long overflow_error;
+       unsigned long ipc_csum_error;
        unsigned long rx_collision;
        unsigned long rx_crc;
        unsigned long rx_length;
 
        union {
                struct {
                        /* RDES0 */
-                       u32 reserved1:1;
+                       u32 payload_csum_error:1;
                        u32 crc_error:1;
                        u32 dribbling:1;
                        u32 mii_error:1;
                        u32 receive_watchdog:1;
                        u32 frame_type:1;
                        u32 collision:1;
-                       u32 frame_too_long:1;
+                       u32 ipc_csum_error:1;
                        u32 last_descriptor:1;
                        u32 first_descriptor:1;
-                       u32 multicast_frame:1;
-                       u32 run_frame:1;
+                       u32 vlan_tag:1;
+                       u32 overflow_error:1;
                        u32 length_error:1;
-                       u32 partial_frame_error:1;
+                       u32 sa_filter_fail:1;
                        u32 descriptor_error:1;
                        u32 error_summary:1;
                        u32 frame_length:14;
-                       u32 filtering_fail:1;
+                       u32 da_filter_fail:1;
                        u32 own:1;
                        /* RDES1 */
                        u32 buffer1_size:11;
                        u32 buffer2_size:11;
-                       u32 reserved2:2;
+                       u32 reserved1:2;
                        u32 second_address_chained:1;
                        u32 end_ring:1;
-                       u32 reserved3:5;
+                       u32 reserved2:5;
                        u32 disable_ic:1;
+
                } rx;
                struct {
                        /* RDES0 */
                        u32 underflow_error:1;
                        u32 excessive_deferral:1;
                        u32 collision_count:4;
-                       u32 heartbeat_fail:1;
+                       u32 vlan_frame:1;
                        u32 excessive_collisions:1;
                        u32 late_collision:1;
                        u32 no_carrier:1;
                        u32 loss_carrier:1;
-                       u32 reserved1:3;
+                       u32 payload_error:1;
+                       u32 frame_flushed:1;
+                       u32 jabber_timeout:1;
                        u32 error_summary:1;
-                       u32 reserved2:15;
+                       u32 ip_header_error:1;
+                       u32 time_stamp_status:1;
+                       u32 reserved1:13;
                        u32 own:1;
                        /* TDES1 */
                        u32 buffer1_size:11;
                        u32 buffer2_size:11;
-                       u32 reserved3:1;
+                       u32 time_stamp_enable:1;
                        u32 disable_padding:1;
                        u32 second_address_chained:1;
                        u32 end_ring:1;
                        u32 crc_disable:1;
-                       u32 reserved4:2;
+                       u32 checksum_insertion:2;
                        u32 first_segment:1;
                        u32 last_segment:1;
                        u32 interrupt:1;
 
                        stats->collisions += p->des01.tx.collision_count;
                ret = -1;
        }
-       if (unlikely(p->des01.tx.heartbeat_fail)) {
-               x->tx_heartbeat++;
-               stats->tx_heartbeat_errors++;
-               ret = -1;
+
+       if (p->des01.etx.vlan_frame) {
+               CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+               x->tx_vlan++;
        }
+
        if (unlikely(p->des01.tx.deferred))
                x->tx_deferred++;
 
 
 /* This function verifies if each incoming frame has some errors
  * and, if required, updates the multicast statistics.
- * In case of success, it returns csum_none because the device
- * is not able to compute the csum in HW. */
+ * In case of success, it returns good_frame because the GMAC device
+ * is supposed to be able to compute the csum in HW. */
 static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
                               struct dma_desc *p)
 {
-       int ret = csum_none;
+       int ret = good_frame;
        struct net_device_stats *stats = (struct net_device_stats *)data;
 
        if (unlikely(p->des01.rx.last_descriptor == 0)) {
        if (unlikely(p->des01.rx.error_summary)) {
                if (unlikely(p->des01.rx.descriptor_error))
                        x->rx_desc++;
-               if (unlikely(p->des01.rx.partial_frame_error))
-                       x->rx_partial++;
-               if (unlikely(p->des01.rx.run_frame))
-                       x->rx_runt++;
-               if (unlikely(p->des01.rx.frame_too_long))
-                       x->rx_toolong++;
+               if (unlikely(p->des01.rx.sa_filter_fail))
+                       x->sa_filter_fail++;
+               if (unlikely(p->des01.rx.overflow_error))
+                       x->overflow_error++;
+               if (unlikely(p->des01.rx.ipc_csum_error))
+                       x->ipc_csum_error++;
                if (unlikely(p->des01.rx.collision)) {
                        x->rx_collision++;
                        stats->collisions++;
                x->rx_mii++;
                ret = discard_frame;
        }
-       if (p->des01.rx.multicast_frame) {
-               x->rx_multicast++;
-               stats->multicast++;
-       }
+#ifdef STMMAC_VLAN_TAG_USED
+       if (p->des01.rx.vlan_tag)
+               x->vlan_tag++;
+#endif
        return ret;
 }
 
 {
        p->des01.tx.first_segment = is_fs;
        norm_set_tx_desc_len(p, len);
+
+       if (likely(csum_flag))
+               p->des01.tx.checksum_insertion = cic_full;
 }
 
 static void ndesc_clear_tx_ic(struct dma_desc *p)
 
        STMMAC_STAT(tx_underflow),
        STMMAC_STAT(tx_carrier),
        STMMAC_STAT(tx_losscarrier),
-       STMMAC_STAT(tx_heartbeat),
+       STMMAC_STAT(vlan_tag),
        STMMAC_STAT(tx_deferred),
        STMMAC_STAT(tx_vlan),
        STMMAC_STAT(rx_vlan),
        STMMAC_STAT(tx_payload_error),
        STMMAC_STAT(tx_ip_header_error),
        STMMAC_STAT(rx_desc),
-       STMMAC_STAT(rx_partial),
-       STMMAC_STAT(rx_runt),
-       STMMAC_STAT(rx_toolong),
+       STMMAC_STAT(sa_filter_fail),
+       STMMAC_STAT(overflow_error),
+       STMMAC_STAT(ipc_csum_error),
        STMMAC_STAT(rx_collision),
        STMMAC_STAT(rx_crc),
        STMMAC_STAT(rx_length),
 
 static int stmmac_get_hw_features(struct stmmac_priv *priv)
 {
        u32 hw_cap = 0;
+
        if (priv->hw->dma->get_hw_feature) {
                hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
 
 
        stmmac_get_hw_features(priv);
 
+       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
        if (priv->rx_coe)
                pr_info("stmmac: Rx Checksum Offload Engine supported\n");
        if (priv->plat->tx_coe)
 #endif
                        skb->protocol = eth_type_trans(skb, priv->dev);
 
-                       if (unlikely(status == csum_none)) {
-                               /* always for the old mac 10/100 */
+                       if (unlikely(!priv->rx_coe)) {
+                               /* No RX COE for old mac10/100 devices */
                                skb_checksum_none_assert(skb);
                                netif_receive_skb(skb);
                        } else {