diff options
Diffstat (limited to 'drivers/net/ethernet/ibm/emac/core.c')
-rw-r--r-- | drivers/net/ethernet/ibm/emac/core.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index dac7ffb4eaf1..a0fe6e3fce61 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -434,6 +434,11 @@ static inline u32 emac_iff2rmr(struct net_device *ndev) else if (!netdev_mc_empty(ndev)) r |= EMAC_RMR_MAE; + if (emac_has_feature(dev, EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE)) { + r &= ~EMAC4_RMR_MJS_MASK; + r |= EMAC4_RMR_MJS(ndev->mtu); + } + return r; } @@ -965,6 +970,7 @@ static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) int rx_sync_size = emac_rx_sync_size(new_mtu); int rx_skb_size = emac_rx_skb_size(new_mtu); int i, ret = 0; + int mr1_jumbo_bit_change = 0; mutex_lock(&dev->link_lock); emac_netif_stop(dev); @@ -1013,7 +1019,15 @@ static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) } skip: /* Check if we need to change "Jumbo" bit in MR1 */ - if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) { + if (emac_has_feature(dev, EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE)) { + mr1_jumbo_bit_change = (new_mtu > ETH_DATA_LEN) || + (dev->ndev->mtu > ETH_DATA_LEN); + } else { + mr1_jumbo_bit_change = (new_mtu > ETH_DATA_LEN) ^ + (dev->ndev->mtu > ETH_DATA_LEN); + } + + if (mr1_jumbo_bit_change) { /* This is to prevent starting RX channel in emac_rx_enable() */ set_bit(MAL_COMMAC_RX_STOPPED, &dev->commac.flags); @@ -2471,6 +2485,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) /* Disable any PHY features not supported by the platform */ dev->phy.def->features &= ~dev->phy_feat_exc; + dev->phy.features &= ~dev->phy_feat_exc; /* Setup initial link parameters */ if (dev->phy.features & SUPPORTED_Autoneg) { @@ -2568,6 +2583,11 @@ static int __devinit emac_init_config(struct emac_instance *dev) if (of_device_is_compatible(np, "ibm,emac-405ex") || of_device_is_compatible(np, "ibm,emac-405exr")) dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; + if (of_device_is_compatible(np, "ibm,emac-apm821xx")) { + dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE | + EMAC_FTR_APM821XX_NO_HALF_DUPLEX | + EMAC_FTR_460EX_PHY_CLK_FIX); + } } else if (of_device_is_compatible(np, "ibm,emac4")) { dev->features |= EMAC_FTR_EMAC4; if (of_device_is_compatible(np, "ibm,emac-440gx")) @@ -2816,6 +2836,13 @@ static int __devinit emac_probe(struct platform_device *ofdev) dev->stop_timeout = STOP_TIMEOUT_100; INIT_DELAYED_WORK(&dev->link_work, emac_link_timer); + /* Some SoCs like APM821xx does not support Half Duplex mode. */ + if (emac_has_feature(dev, EMAC_FTR_APM821XX_NO_HALF_DUPLEX)) { + dev->phy_feat_exc = (SUPPORTED_1000baseT_Half | + SUPPORTED_100baseT_Half | + SUPPORTED_10baseT_Half); + } + /* Find PHY if any */ err = emac_init_phy(dev); if (err != 0) |