diff options
author | Alok Makhariya <B46187@freescale.com> | 2014-03-28 11:49:18 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-03-28 14:16:51 (GMT) |
commit | 14bc1055d1415408999b4ac1660a261daddd3b55 (patch) | |
tree | f1e8fb79b0fb2c2e0af086819e48cf6c867acd6c /drivers/net/ethernet/freescale/gianfar.h | |
parent | 5e8ab76d971d561480bed27078a06cfbbe759442 (diff) | |
download | linux-fsl-qoriq-14bc1055d1415408999b4ac1660a261daddd3b55.tar.xz |
gianfar: Moving inline static function to gianfar.h
Static inline function used by ASF moved to gianfar.h
CQ ID : ENGR00304852
Signed-off-by: Alok Makhariya <B46187@freescale.com>
Change-Id: Iafbc62267be60064625305c97dbee1fc8d15a4ec
Reviewed-on: http://git.am.freescale.net:8181/10477
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.h')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 4ec37d4..34e5693 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -38,6 +38,10 @@ #include <linux/mm.h> #include <linux/mii.h> #include <linux/phy.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/udp.h> + #include <asm/io.h> #include <asm/irq.h> @@ -1463,4 +1467,152 @@ struct filer_table { /* The gianfar_ptp module will set this variable */ extern int gfar_phc_index; +static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, + struct txbd8 *base, int ring_size) +{ + struct txbd8 *new_bd = bdp + stride; + return (new_bd >= (base + ring_size)) ? (new_bd - ring_size) : new_bd; +} + +static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, + int ring_size) +{ + return skip_txbd(bdp, 1, base, ring_size); +} + +static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) +{ + struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN); + memset(fcb, 0, GMAC_FCB_LEN); + return fcb; +} + +static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, + int fcb_length) +{ + /* If we're here, it's a IP packet with a TCP or UDP + * payload. We set it to checksum, using a pseudo-header + * we provide + */ + u8 flags = TXFCB_DEFAULT; + + /* Tell the controller what the protocol is + * And provide the already calculated phcs + */ + if (ip_hdr(skb)->protocol == IPPROTO_UDP) { + flags |= TXFCB_UDP; + fcb->phcs = udp_hdr(skb)->check; + } else + fcb->phcs = tcp_hdr(skb)->check; + + /* l3os is the distance between the start of the + * frame (skb->data) and the start of the IP hdr. + * l4os is the distance between the start of the + * l3 hdr and the l4 hdr + */ + fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length); + fcb->l4os = skb_network_header_len(skb); + fcb->flags = flags; +} + +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; +} + +static inline bool gfar_csum_errata_76(struct gfar_private *priv, + unsigned int len) +{ + return gfar_has_errata(priv, GFAR_ERRATA_76) && + (len > 2500); +} + +static inline void gfar_init_rxbdp(struct gfar_priv_rx_q *rx_queue, + struct rxbd8 *bdp, dma_addr_t buf) +{ + u32 lstatus; + + bdp->bufPtr = buf; + + lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT); + if (bdp == rx_queue->rx_bd_base + rx_queue->rx_ring_size - 1) + lstatus |= BD_LFLAG(RXBD_WRAP); + + eieio(); + + bdp->lstatus = lstatus; +} + +static inline void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, + struct rxbd8 *bdp, struct sk_buff *skb) +{ + struct net_device *dev = rx_queue->dev; + struct gfar_private *priv = netdev_priv(dev); + dma_addr_t buf; + + buf = dma_map_single(priv->dev, skb->data, + priv->rx_buffer_size, DMA_FROM_DEVICE); + gfar_init_rxbdp(rx_queue, bdp, buf); +} + +static inline void count_errors(unsigned short status, struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct gfar_extra_stats *estats = &priv->extra_stats; + + /* If the packet was truncated, none of the other errors matter */ + if (status & RXBD_TRUNCATED) { + stats->rx_length_errors++; + + atomic64_inc(&estats->rx_trunc); + + return; + } + /* Count the errors, if there were any */ + if (status & (RXBD_LARGE | RXBD_SHORT)) { + stats->rx_length_errors++; + + if (status & RXBD_LARGE) + atomic64_inc(&estats->rx_large); + else + atomic64_inc(&estats->rx_short); + } + if (status & RXBD_NONOCTET) { + stats->rx_frame_errors++; + atomic64_inc(&estats->rx_nonoctet); + } + if (status & RXBD_CRCERR) { + atomic64_inc(&estats->rx_crcerr); + stats->rx_crc_errors++; + } + if (status & RXBD_OVERRUN) { + atomic64_inc(&estats->rx_overrun); + stats->rx_crc_errors++; + } +} + +static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) +{ + /* If valid headers were found, and valid sums + * were verified, then we tell the kernel that no + * checksumming is necessary. Otherwise, it is [FIXME] + */ + if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb_checksum_none_assert(skb); +} + +static inline void gfar_align_skb(struct sk_buff *skb) +{ + /* We need the data buffer to be aligned properly. We will reserve + * as many bytes as needed to align the data properly + */ + skb_reserve(skb, RXBUF_ALIGNMENT - + (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); +} + #endif /* __GIANFAR_H */ |