diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 446e9c99379dd31273dc339e2106e10429c6b331..728078fe400ea3042abaff6489769d1b8323dceb 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -329,14 +329,35 @@ static void gfar_init_tx_rx_base(struct gfar_private *priv) } } -static void gfar_mac_rx_config(struct gfar_private *priv) +static void gfar_rx_buff_size_config(struct gfar_private *priv) { - struct gfar __iomem *regs = priv->gfargrp[0].regs; - u32 rctrl = 0; + int frame_size = priv->ndev->mtu + ETH_HLEN; /* set this when rx hw offload (TOE) functions are being used */ priv->uses_rxfcb = 0; + if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX)) + priv->uses_rxfcb = 1; + + if (priv->hwts_rx_en) + priv->uses_rxfcb = 1; + + if (priv->uses_rxfcb) + frame_size += GMAC_FCB_LEN; + + frame_size += priv->padding; + + frame_size = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + + INCREMENTAL_BUFFER_SIZE; + + priv->rx_buffer_size = frame_size; +} + +static void gfar_mac_rx_config(struct gfar_private *priv) +{ + struct gfar __iomem *regs = priv->gfargrp[0].regs; + u32 rctrl = 0; + if (priv->rx_filer_enable) { rctrl |= RCTRL_FILREN; /* Program the RIR0 reg with the required distribution */ @@ -347,15 +368,11 @@ static void gfar_mac_rx_config(struct gfar_private *priv) if (priv->ndev->flags & IFF_PROMISC) rctrl |= RCTRL_PROM; - if (priv->ndev->features & NETIF_F_RXCSUM) { + if (priv->ndev->features & NETIF_F_RXCSUM) rctrl |= RCTRL_CHECKSUMMING; - priv->uses_rxfcb = 1; - } - if (priv->extended_hash) { - rctrl |= RCTRL_EXTHASH; - rctrl |= RCTRL_EMEN; - } + if (priv->extended_hash) + rctrl |= RCTRL_EXTHASH | RCTRL_EMEN; if (priv->padding) { rctrl &= ~RCTRL_PAL_MASK; @@ -363,15 +380,11 @@ static void gfar_mac_rx_config(struct gfar_private *priv) } /* Enable HW time stamping if requested from user space */ - if (priv->hwts_rx_en) { + if (priv->hwts_rx_en) rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; - priv->uses_rxfcb = 1; - } - if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) { + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; - priv->uses_rxfcb = 1; - } /* Init rctrl based on our settings */ gfar_write(®s->rctrl, rctrl); @@ -393,6 +406,9 @@ static void gfar_mac_tx_config(struct gfar_private *priv) gfar_write(®s->tr47wt, DEFAULT_WRRS_WEIGHT); } + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_TX) + tctrl |= TCTRL_VLINS; + gfar_write(®s->tctrl, tctrl); } @@ -1029,7 +1045,11 @@ static void gfar_mac_reset(struct gfar_private *priv) udelay(3); - /* Initialize the max receive buffer length */ + /* Compute rx_buff_size based on config flags */ + gfar_rx_buff_size_config(priv); + + /* Initialize the max receive frame/buffer lengths */ + gfar_write(®s->maxfrm, priv->rx_buffer_size); gfar_write(®s->mrblr, priv->rx_buffer_size); /* Initialize the Minimum Frame Length Register */ @@ -1037,8 +1057,15 @@ static void gfar_mac_reset(struct gfar_private *priv) /* Initialize MACCFG2. */ tempval = MACCFG2_INIT_SETTINGS; - if (gfar_has_errata(priv, GFAR_ERRATA_74)) + + /* If the mtu is larger than the max size for standard + * ethernet frames (ie, a jumbo frame), then set maccfg2 + * to allow huge frames, and to check the length + */ + if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || + gfar_has_errata(priv, GFAR_ERRATA_74)) tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK; + gfar_write(®s->maccfg2, tempval); /* Clear mac addr hash registers */ @@ -2353,77 +2380,9 @@ static int gfar_set_mac_address(struct net_device *dev) return 0; } -/* Check if rx parser should be activated */ -void gfar_check_rx_parser_mode(struct gfar_private *priv) -{ - struct gfar __iomem *regs; - u32 tempval; - - regs = priv->gfargrp[0].regs; - - tempval = gfar_read(®s->rctrl); - /* If parse is no longer required, then disable parser */ - if (tempval & RCTRL_REQ_PARSER) { - tempval |= RCTRL_PRSDEP_INIT; - priv->uses_rxfcb = 1; - } else { - tempval &= ~RCTRL_PRSDEP_INIT; - priv->uses_rxfcb = 0; - } - gfar_write(®s->rctrl, tempval); -} - -/* Enables and disables VLAN insertion/extraction */ -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features) -{ - struct gfar_private *priv = netdev_priv(dev); - struct gfar __iomem *regs = NULL; - unsigned long flags; - u32 tempval; - - regs = priv->gfargrp[0].regs; - local_irq_save(flags); - lock_rx_qs(priv); - - if (features & NETIF_F_HW_VLAN_CTAG_TX) { - /* Enable VLAN tag insertion */ - tempval = gfar_read(®s->tctrl); - tempval |= TCTRL_VLINS; - gfar_write(®s->tctrl, tempval); - } else { - /* Disable VLAN tag insertion */ - tempval = gfar_read(®s->tctrl); - tempval &= ~TCTRL_VLINS; - gfar_write(®s->tctrl, tempval); - } - - if (features & NETIF_F_HW_VLAN_CTAG_RX) { - /* Enable VLAN tag extraction */ - tempval = gfar_read(®s->rctrl); - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); - gfar_write(®s->rctrl, tempval); - priv->uses_rxfcb = 1; - } else { - /* Disable VLAN tag extraction */ - tempval = gfar_read(®s->rctrl); - tempval &= ~RCTRL_VLEX; - gfar_write(®s->rctrl, tempval); - - gfar_check_rx_parser_mode(priv); - } - - gfar_change_mtu(dev, dev->mtu); - - unlock_rx_qs(priv); - local_irq_restore(flags); -} - static int gfar_change_mtu(struct net_device *dev, int new_mtu) { - int tempsize, tempval; struct gfar_private *priv = netdev_priv(dev); - struct gfar __iomem *regs = priv->gfargrp[0].regs; - int oldsize = priv->rx_buffer_size; int frame_size = new_mtu + ETH_HLEN; if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { @@ -2431,42 +2390,12 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } - if (priv->uses_rxfcb) - frame_size += GMAC_FCB_LEN; - - frame_size += priv->padding; - - tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + - INCREMENTAL_BUFFER_SIZE; - - /* Only stop and start the controller if it isn't already - * stopped, and we changed something - */ - if ((oldsize != tempsize) && (dev->flags & IFF_UP)) + if (dev->flags & IFF_UP) stop_gfar(dev); - priv->rx_buffer_size = tempsize; - dev->mtu = new_mtu; - gfar_write(®s->mrblr, priv->rx_buffer_size); - gfar_write(®s->maxfrm, priv->rx_buffer_size); - - /* If the mtu is larger than the max size for standard - * ethernet frames (ie, a jumbo frame), then set maccfg2 - * to allow huge frames, and to check the length - */ - tempval = gfar_read(®s->maccfg2); - - if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || - gfar_has_errata(priv, GFAR_ERRATA_74)) - tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); - else - tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); - - gfar_write(®s->maccfg2, tempval); - - if ((oldsize != tempsize) && (dev->flags & IFF_UP)) + if (dev->flags & IFF_UP) startup_gfar(dev); return 0; diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 2a59398f8cf0fc4562cb998ad460b4fec0502f29..9db95563f8aa3b587a3ed74772d555f9a01ed094 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1211,8 +1211,6 @@ void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable, u32 regnum, u32 read); void gfar_configure_coalescing_all(struct gfar_private *priv); int gfar_set_features(struct net_device *dev, netdev_features_t features); -void gfar_check_rx_parser_mode(struct gfar_private *priv); -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features); extern const struct ethtool_ops gfar_ethtool_ops; diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 19557ec31f3385ee990f3c3171cc7bf7cf05ee27..dd7ccec506f1a1803c537a0a2b627b8bc1828511 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -582,18 +582,15 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) netdev_features_t changed = dev->features ^ features; int err = 0; - if (changed & (NETIF_F_HW_VLAN_CTAG_TX|NETIF_F_HW_VLAN_CTAG_RX)) - gfar_vlan_mode(dev, features); - - if (!(changed & NETIF_F_RXCSUM)) + if (!(changed & (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_RXCSUM))) return 0; + dev->features = features; + if (dev->flags & IFF_UP) { /* Now we take down the rings to rebuild them */ stop_gfar(dev); - - dev->features = features; - err = startup_gfar(dev); netif_tx_wake_all_queues(dev); }