aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2013-08-05 10:20:10 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-05 15:29:15 -0400
commit0d0cffdcc6fc4f57080b9a443401e8dad5ca77f8 (patch)
treed347a4f950c7f552e25055bca28d4652b8a84f22 /drivers
parent02d88fb4fb6a580b0224b3bf07bbfd9d4806f6fb (diff)
gianfar: Cleanup TxFCB insertion on xmit
Cleanup gfar_start_xmit()'s fast path by factoring out "redundant" FCB insertion code (repeated gfar_add_fcb() calls and related) and by reducing the number of if() clauses (i.e. if(fcb) checks). Improve maintainability (e.g. there's less code and easier to read) also by introducing do_csum and do_vlan to mark the other 2 Tx TOE functionalities, following the same model as do_tstamp. fcb_len may also be 0 now, to mark that Tx FCB insertion conditions (do_csum, do_vlan, do_tstamp) have not been met. Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c62
1 files changed, 33 insertions, 29 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 352035e440d8..3cb464780777 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2081,10 +2081,11 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2081 struct txfcb *fcb = NULL; 2081 struct txfcb *fcb = NULL;
2082 struct txbd8 *txbdp, *txbdp_start, *base, *txbdp_tstamp = NULL; 2082 struct txbd8 *txbdp, *txbdp_start, *base, *txbdp_tstamp = NULL;
2083 u32 lstatus; 2083 u32 lstatus;
2084 int i, rq = 0, do_tstamp = 0; 2084 int i, rq = 0;
2085 int do_tstamp, do_csum, do_vlan;
2085 u32 bufaddr; 2086 u32 bufaddr;
2086 unsigned long flags; 2087 unsigned long flags;
2087 unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; 2088 unsigned int nr_frags, nr_txbds, length, fcb_len = 0;
2088 2089
2089 rq = skb->queue_mapping; 2090 rq = skb->queue_mapping;
2090 tx_queue = priv->tx_queue[rq]; 2091 tx_queue = priv->tx_queue[rq];
@@ -2092,21 +2093,23 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2092 base = tx_queue->tx_bd_base; 2093 base = tx_queue->tx_bd_base;
2093 regs = tx_queue->grp->regs; 2094 regs = tx_queue->grp->regs;
2094 2095
2096 do_csum = (CHECKSUM_PARTIAL == skb->ip_summed);
2097 do_vlan = vlan_tx_tag_present(skb);
2098 do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
2099 priv->hwts_tx_en;
2100
2101 if (do_csum || do_vlan)
2102 fcb_len = GMAC_FCB_LEN;
2103
2095 /* check if time stamp should be generated */ 2104 /* check if time stamp should be generated */
2096 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && 2105 if (unlikely(do_tstamp))
2097 priv->hwts_tx_en)) { 2106 fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
2098 do_tstamp = 1;
2099 fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
2100 }
2101 2107
2102 /* make space for additional header when fcb is needed */ 2108 /* make space for additional header when fcb is needed */
2103 if (((skb->ip_summed == CHECKSUM_PARTIAL) || 2109 if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) {
2104 vlan_tx_tag_present(skb) ||
2105 unlikely(do_tstamp)) &&
2106 (skb_headroom(skb) < fcb_length)) {
2107 struct sk_buff *skb_new; 2110 struct sk_buff *skb_new;
2108 2111
2109 skb_new = skb_realloc_headroom(skb, fcb_length); 2112 skb_new = skb_realloc_headroom(skb, fcb_len);
2110 if (!skb_new) { 2113 if (!skb_new) {
2111 dev->stats.tx_errors++; 2114 dev->stats.tx_errors++;
2112 kfree_skb(skb); 2115 kfree_skb(skb);
@@ -2189,37 +2192,38 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2189 memset(skb->data, 0, GMAC_TXPAL_LEN); 2192 memset(skb->data, 0, GMAC_TXPAL_LEN);
2190 } 2193 }
2191 2194
2192 /* Set up checksumming */ 2195 /* Add TxFCB if required */
2193 if (CHECKSUM_PARTIAL == skb->ip_summed) { 2196 if (fcb_len) {
2194 fcb = gfar_add_fcb(skb); 2197 fcb = gfar_add_fcb(skb);
2195 lstatus |= BD_LFLAG(TXBD_TOE); 2198 lstatus |= BD_LFLAG(TXBD_TOE);
2196 gfar_tx_checksum(skb, fcb, fcb_length); 2199 }
2200
2201 /* Set up checksumming */
2202 if (do_csum) {
2203 gfar_tx_checksum(skb, fcb, fcb_len);
2197 2204
2198 if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) || 2205 if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
2199 unlikely(gfar_csum_errata_76(priv, skb->len))) { 2206 unlikely(gfar_csum_errata_76(priv, skb->len))) {
2200 __skb_pull(skb, GMAC_FCB_LEN); 2207 __skb_pull(skb, GMAC_FCB_LEN);
2201 skb_checksum_help(skb); 2208 skb_checksum_help(skb);
2202 lstatus &= ~(BD_LFLAG(TXBD_TOE)); 2209 if (do_vlan || do_tstamp) {
2203 fcb = NULL; 2210 /* put back a new fcb for vlan/tstamp TOE */
2211 fcb = gfar_add_fcb(skb);
2212 } else {
2213 /* Tx TOE not used */
2214 lstatus &= ~(BD_LFLAG(TXBD_TOE));
2215 fcb = NULL;
2216 }
2204 } 2217 }
2205 } 2218 }
2206 2219
2207 if (vlan_tx_tag_present(skb)) { 2220 if (do_vlan)
2208 if (unlikely(NULL == fcb)) {
2209 fcb = gfar_add_fcb(skb);
2210 lstatus |= BD_LFLAG(TXBD_TOE);
2211 }
2212
2213 gfar_tx_vlan(skb, fcb); 2221 gfar_tx_vlan(skb, fcb);
2214 }
2215 2222
2216 /* Setup tx hardware time stamping if requested */ 2223 /* Setup tx hardware time stamping if requested */
2217 if (unlikely(do_tstamp)) { 2224 if (unlikely(do_tstamp)) {
2218 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 2225 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
2219 if (fcb == NULL)
2220 fcb = gfar_add_fcb(skb);
2221 fcb->ptp = 1; 2226 fcb->ptp = 1;
2222 lstatus |= BD_LFLAG(TXBD_TOE);
2223 } 2227 }
2224 2228
2225 txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data, 2229 txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data,
@@ -2231,9 +2235,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2231 * the full frame length. 2235 * the full frame length.
2232 */ 2236 */
2233 if (unlikely(do_tstamp)) { 2237 if (unlikely(do_tstamp)) {
2234 txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length; 2238 txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_len;
2235 txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | 2239 txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) |
2236 (skb_headlen(skb) - fcb_length); 2240 (skb_headlen(skb) - fcb_len);
2237 lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; 2241 lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
2238 } else { 2242 } else {
2239 lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); 2243 lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);