return skip_txbd(bdp, 1, base, ring_size);
 }
 
+/* eTSEC12: csum generation not supported for some fcb offsets */
+static inline bool gfar_csum_errata_12(struct gfar_private *priv,
+                                      unsigned long fcb_addr)
+{
+       return (gfar_has_errata(priv, GFAR_ERRATA_12) &&
+              (fcb_addr % 0x20) > 0x18);
+}
+
+/* eTSEC76: csum generation for frames larger than 2500 may
+ * cause excess delays before start of transmission
+ */
+static inline bool gfar_csum_errata_76(struct gfar_private *priv,
+                                      unsigned int len)
+{
+       return (gfar_has_errata(priv, GFAR_ERRATA_76) &&
+              (len > 2500));
+}
+
 /* This is called by the kernel when a frame is ready for transmission.
  * It is pointed to by the dev->hard_start_xmit function pointer
  */
        unsigned long flags;
        unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
 
-       /* TOE=1 frames larger than 2500 bytes may see excess delays
-        * before start of transmission.
-        */
-       if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) &&
-                    skb->ip_summed == CHECKSUM_PARTIAL &&
-                    skb->len > 2500)) {
-               int ret;
-
-               ret = skb_checksum_help(skb);
-               if (ret)
-                       return ret;
-       }
-
        rq = skb->queue_mapping;
        tx_queue = priv->tx_queue[rq];
        txq = netdev_get_tx_queue(dev, rq);
        /* Set up checksumming */
        if (CHECKSUM_PARTIAL == skb->ip_summed) {
                fcb = gfar_add_fcb(skb);
-               /* as specified by errata */
-               if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) &&
-                            ((unsigned long)fcb % 0x20) > 0x18)) {
+               lstatus |= BD_LFLAG(TXBD_TOE);
+               gfar_tx_checksum(skb, fcb, fcb_length);
+
+               if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
+                   unlikely(gfar_csum_errata_76(priv, skb->len))) {
                        __skb_pull(skb, GMAC_FCB_LEN);
                        skb_checksum_help(skb);
-               } else {
-                       lstatus |= BD_LFLAG(TXBD_TOE);
-                       gfar_tx_checksum(skb, fcb, fcb_length);
+                       lstatus &= ~(BD_LFLAG(TXBD_TOE));
+                       fcb = NULL;
                }
        }