Commit ae5d3372 authored by Duc Dang's avatar Duc Dang Committed by David S. Miller

powerpc/44x: Add more changes for APM821XX EMAC driver

This patch includes:

  Configure EMAC PHY clock source (clock from PHY or internal clock).

  Do not advertise PHY half duplex capability as APM821XX EMAC does not support half duplex mode.

  Add changes to support configuring jumbo frame for APM821XX EMAC.

[ Fix coding style -DaveM ]
Signed-off-by: default avatarDuc Dang <dhdang@apm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8dfc2b45
...@@ -434,6 +434,11 @@ static inline u32 emac_iff2rmr(struct net_device *ndev) ...@@ -434,6 +434,11 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
else if (!netdev_mc_empty(ndev)) else if (!netdev_mc_empty(ndev))
r |= EMAC_RMR_MAE; 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; return r;
} }
...@@ -965,6 +970,7 @@ static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) ...@@ -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_sync_size = emac_rx_sync_size(new_mtu);
int rx_skb_size = emac_rx_skb_size(new_mtu); int rx_skb_size = emac_rx_skb_size(new_mtu);
int i, ret = 0; int i, ret = 0;
int mr1_jumbo_bit_change = 0;
mutex_lock(&dev->link_lock); mutex_lock(&dev->link_lock);
emac_netif_stop(dev); emac_netif_stop(dev);
...@@ -1013,7 +1019,15 @@ static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) ...@@ -1013,7 +1019,15 @@ static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu)
} }
skip: skip:
/* Check if we need to change "Jumbo" bit in MR1 */ /* 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() */ /* This is to prevent starting RX channel in emac_rx_enable() */
set_bit(MAL_COMMAC_RX_STOPPED, &dev->commac.flags); set_bit(MAL_COMMAC_RX_STOPPED, &dev->commac.flags);
...@@ -2471,6 +2485,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) ...@@ -2471,6 +2485,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
/* Disable any PHY features not supported by the platform */ /* Disable any PHY features not supported by the platform */
dev->phy.def->features &= ~dev->phy_feat_exc; dev->phy.def->features &= ~dev->phy_feat_exc;
dev->phy.features &= ~dev->phy_feat_exc;
/* Setup initial link parameters */ /* Setup initial link parameters */
if (dev->phy.features & SUPPORTED_Autoneg) { if (dev->phy.features & SUPPORTED_Autoneg) {
...@@ -2568,6 +2583,11 @@ static int __devinit emac_init_config(struct emac_instance *dev) ...@@ -2568,6 +2583,11 @@ static int __devinit emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-405ex") || if (of_device_is_compatible(np, "ibm,emac-405ex") ||
of_device_is_compatible(np, "ibm,emac-405exr")) of_device_is_compatible(np, "ibm,emac-405exr"))
dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; 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")) { } else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4; dev->features |= EMAC_FTR_EMAC4;
if (of_device_is_compatible(np, "ibm,emac-440gx")) if (of_device_is_compatible(np, "ibm,emac-440gx"))
...@@ -2816,6 +2836,13 @@ static int __devinit emac_probe(struct platform_device *ofdev) ...@@ -2816,6 +2836,13 @@ static int __devinit emac_probe(struct platform_device *ofdev)
dev->stop_timeout = STOP_TIMEOUT_100; dev->stop_timeout = STOP_TIMEOUT_100;
INIT_DELAYED_WORK(&dev->link_work, emac_link_timer); 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 */ /* Find PHY if any */
err = emac_init_phy(dev); err = emac_init_phy(dev);
if (err != 0) if (err != 0)
......
...@@ -325,7 +325,14 @@ struct emac_instance { ...@@ -325,7 +325,14 @@ struct emac_instance {
* Set if we need phy clock workaround for 460ex or 460gt * Set if we need phy clock workaround for 460ex or 460gt
*/ */
#define EMAC_FTR_460EX_PHY_CLK_FIX 0x00000400 #define EMAC_FTR_460EX_PHY_CLK_FIX 0x00000400
/*
* APM821xx requires Jumbo frame size set explicitly
*/
#define EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE 0x00000800
/*
* APM821xx does not support Half Duplex mode
*/
#define EMAC_FTR_APM821XX_NO_HALF_DUPLEX 0x00001000
/* Right now, we don't quite handle the always/possible masks on the /* Right now, we don't quite handle the always/possible masks on the
* most optimal way as we don't have a way to say something like * most optimal way as we don't have a way to say something like
...@@ -353,7 +360,9 @@ enum { ...@@ -353,7 +360,9 @@ enum {
EMAC_FTR_NO_FLOW_CONTROL_40x | EMAC_FTR_NO_FLOW_CONTROL_40x |
#endif #endif
EMAC_FTR_460EX_PHY_CLK_FIX | EMAC_FTR_460EX_PHY_CLK_FIX |
EMAC_FTR_440EP_PHY_CLK_FIX, EMAC_FTR_440EP_PHY_CLK_FIX |
EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
}; };
static inline int emac_has_feature(struct emac_instance *dev, static inline int emac_has_feature(struct emac_instance *dev,
......
...@@ -212,6 +212,8 @@ struct emac_regs { ...@@ -212,6 +212,8 @@ struct emac_regs {
#define EMAC4_RMR_RFAF_64_1024 0x00000006 #define EMAC4_RMR_RFAF_64_1024 0x00000006
#define EMAC4_RMR_RFAF_128_2048 0x00000007 #define EMAC4_RMR_RFAF_128_2048 0x00000007
#define EMAC4_RMR_BASE EMAC4_RMR_RFAF_128_2048 #define EMAC4_RMR_BASE EMAC4_RMR_RFAF_128_2048
#define EMAC4_RMR_MJS_MASK 0x0001fff8
#define EMAC4_RMR_MJS(s) (((s) << 3) & EMAC4_RMR_MJS_MASK)
/* EMACx_ISR & EMACx_ISER */ /* EMACx_ISR & EMACx_ISER */
#define EMAC4_ISR_TXPE 0x20000000 #define EMAC4_ISR_TXPE 0x20000000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment