summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale/gianfar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.c')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c96
1 files changed, 48 insertions, 48 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 2aa7b401cc3b..cb80dba8dd2b 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2389,6 +2389,47 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp = txbdp_start = tx_queue->cur_tx;
lstatus = be32_to_cpu(txbdp->lstatus);
+ /* Add TxPAL between FCB and frame if required */
+ if (unlikely(do_tstamp)) {
+ skb_push(skb, GMAC_TXPAL_LEN);
+ memset(skb->data, 0, GMAC_TXPAL_LEN);
+ }
+
+ /* Add TxFCB if required */
+ if (fcb_len) {
+ fcb = gfar_add_fcb(skb);
+ lstatus |= BD_LFLAG(TXBD_TOE);
+ }
+
+ /* Set up checksumming */
+ if (do_csum) {
+ gfar_tx_checksum(skb, fcb, fcb_len);
+
+ 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);
+ if (do_vlan || do_tstamp) {
+ /* put back a new fcb for vlan/tstamp TOE */
+ fcb = gfar_add_fcb(skb);
+ } else {
+ /* Tx TOE not used */
+ lstatus &= ~(BD_LFLAG(TXBD_TOE));
+ fcb = NULL;
+ }
+ }
+ }
+
+ if (do_vlan)
+ gfar_tx_vlan(skb, fcb);
+
+ bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
+ goto dma_map_err;
+
+ txbdp_start->bufPtr = cpu_to_be32(bufaddr);
+
/* Time stamp insertion requires one additional TxBD */
if (unlikely(do_tstamp))
txbdp_tstamp = txbdp = next_txbd(txbdp, base,
@@ -2404,6 +2445,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
}
} else {
+ u32 lstatus_start = lstatus;
+
/* Place the fragment addresses and lengths into the TxBDs */
for (i = 0; i < nr_frags; i++) {
unsigned int frag_len;
@@ -2432,56 +2475,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp->lstatus = cpu_to_be32(lstatus);
}
- lstatus = be32_to_cpu(txbdp_start->lstatus);
+ lstatus = lstatus_start;
}
- /* Add TxPAL between FCB and frame if required */
- if (unlikely(do_tstamp)) {
- skb_push(skb, GMAC_TXPAL_LEN);
- memset(skb->data, 0, GMAC_TXPAL_LEN);
- }
-
- /* Add TxFCB if required */
- if (fcb_len) {
- fcb = gfar_add_fcb(skb);
- lstatus |= BD_LFLAG(TXBD_TOE);
- }
-
- /* Set up checksumming */
- if (do_csum) {
- gfar_tx_checksum(skb, fcb, fcb_len);
-
- 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);
- if (do_vlan || do_tstamp) {
- /* put back a new fcb for vlan/tstamp TOE */
- fcb = gfar_add_fcb(skb);
- } else {
- /* Tx TOE not used */
- lstatus &= ~(BD_LFLAG(TXBD_TOE));
- fcb = NULL;
- }
- }
- }
-
- if (do_vlan)
- gfar_tx_vlan(skb, fcb);
-
- /* Setup tx hardware time stamping if requested */
- if (unlikely(do_tstamp)) {
- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
- fcb->ptp = 1;
- }
-
- bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
- DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
- goto dma_map_err;
-
- txbdp_start->bufPtr = cpu_to_be32(bufaddr);
-
/* If time stamping is requested one additional TxBD must be set up. The
* first TxBD points to the FCB and must have a data length of
* GMAC_FCB_LEN. The second TxBD points to the actual frame data with
@@ -2498,6 +2494,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_tstamp->bufPtr = cpu_to_be32(bufaddr);
txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
+
+ /* Setup tx hardware time stamping */
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ fcb->ptp = 1;
} else {
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
}