diff options
| -rw-r--r-- | arch/arm/mach-orion5x/common.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/chrp/pegasos_eth.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mv64x60_dev.c | 2 | ||||
| -rw-r--r-- | arch/ppc/syslib/mv64x60.c | 3 | ||||
| -rw-r--r-- | drivers/net/mv643xx_eth.c | 160 | ||||
| -rw-r--r-- | include/linux/mv643xx_eth.h | 16 | 
6 files changed, 148 insertions, 39 deletions
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 968deb58be0..0ecff5a6197 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c  | |||
| @@ -223,7 +223,9 @@ static struct platform_device orion5x_eth = { | |||
| 223 | 223 | ||
| 224 | void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) | 224 | void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) | 
| 225 | { | 225 | { | 
| 226 | eth_data->shared = &orion5x_eth_shared; | ||
| 226 | orion5x_eth.dev.platform_data = eth_data; | 227 | orion5x_eth.dev.platform_data = eth_data; | 
| 228 | |||
| 227 | platform_device_register(&orion5x_eth_shared); | 229 | platform_device_register(&orion5x_eth_shared); | 
| 228 | platform_device_register(&orion5x_eth); | 230 | platform_device_register(&orion5x_eth); | 
| 229 | } | 231 | } | 
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 5bcc58d9a4d..130ff72d99d 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c  | |||
| @@ -58,7 +58,9 @@ static struct resource mv643xx_eth0_resources[] = { | |||
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | static struct mv643xx_eth_platform_data eth0_pd = { | 60 | static struct mv643xx_eth_platform_data eth0_pd = { | 
| 61 | .shared = &mv643xx_eth_shared_device, | ||
| 61 | .port_number = 0, | 62 | .port_number = 0, | 
| 63 | |||
| 62 | .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, | 64 | .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, | 
| 63 | .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, | 65 | .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, | 
| 64 | .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, | 66 | .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, | 
| @@ -88,7 +90,9 @@ static struct resource mv643xx_eth1_resources[] = { | |||
| 88 | }; | 90 | }; | 
| 89 | 91 | ||
| 90 | static struct mv643xx_eth_platform_data eth1_pd = { | 92 | static struct mv643xx_eth_platform_data eth1_pd = { | 
| 93 | .shared = &mv643xx_eth_shared_device, | ||
| 91 | .port_number = 1, | 94 | .port_number = 1, | 
| 95 | |||
| 92 | .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, | 96 | .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, | 
| 93 | .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, | 97 | .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, | 
| 94 | .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, | 98 | .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, | 
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 41af1223e2a..a132e0de8ca 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c  | |||
| @@ -239,6 +239,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id, | |||
| 239 | 239 | ||
| 240 | memset(&pdata, 0, sizeof(pdata)); | 240 | memset(&pdata, 0, sizeof(pdata)); | 
| 241 | 241 | ||
| 242 | pdata.shared = shared_pdev; | ||
| 243 | |||
| 242 | prop = of_get_property(np, "reg", NULL); | 244 | prop = of_get_property(np, "reg", NULL); | 
| 243 | if (!prop) | 245 | if (!prop) | 
| 244 | return -ENODEV; | 246 | return -ENODEV; | 
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 90fe904d361..418f3053de5 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c  | |||
| @@ -341,6 +341,7 @@ static struct resource mv64x60_eth0_resources[] = { | |||
| 341 | }; | 341 | }; | 
| 342 | 342 | ||
| 343 | static struct mv643xx_eth_platform_data eth0_pd = { | 343 | static struct mv643xx_eth_platform_data eth0_pd = { | 
| 344 | .shared = &mv64x60_eth_shared_device; | ||
| 344 | .port_number = 0, | 345 | .port_number = 0, | 
| 345 | }; | 346 | }; | 
| 346 | 347 | ||
| @@ -366,6 +367,7 @@ static struct resource mv64x60_eth1_resources[] = { | |||
| 366 | }; | 367 | }; | 
| 367 | 368 | ||
| 368 | static struct mv643xx_eth_platform_data eth1_pd = { | 369 | static struct mv643xx_eth_platform_data eth1_pd = { | 
| 370 | .shared = &mv64x60_eth_shared_device; | ||
| 369 | .port_number = 1, | 371 | .port_number = 1, | 
| 370 | }; | 372 | }; | 
| 371 | 373 | ||
| @@ -391,6 +393,7 @@ static struct resource mv64x60_eth2_resources[] = { | |||
| 391 | }; | 393 | }; | 
| 392 | 394 | ||
| 393 | static struct mv643xx_eth_platform_data eth2_pd = { | 395 | static struct mv643xx_eth_platform_data eth2_pd = { | 
| 396 | .shared = &mv64x60_eth_shared_device; | ||
| 394 | .port_number = 2, | 397 | .port_number = 2, | 
| 395 | }; | 398 | }; | 
| 396 | 399 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 381b36e5f64..b7915cdcc6a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c  | |||
| @@ -91,6 +91,11 @@ | |||
| 91 | */ | 91 | */ | 
| 92 | #define PHY_ADDR_REG 0x0000 | 92 | #define PHY_ADDR_REG 0x0000 | 
| 93 | #define SMI_REG 0x0004 | 93 | #define SMI_REG 0x0004 | 
| 94 | #define WINDOW_BASE(i) (0x0200 + ((i) << 3)) | ||
| 95 | #define WINDOW_SIZE(i) (0x0204 + ((i) << 3)) | ||
| 96 | #define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2)) | ||
| 97 | #define WINDOW_BAR_ENABLE 0x0290 | ||
| 98 | #define WINDOW_PROTECT(i) (0x0294 + ((i) << 4)) | ||
| 94 | 99 | ||
| 95 | /* | 100 | /* | 
| 96 | * Per-port registers. | 101 | * Per-port registers. | 
| @@ -507,9 +512,23 @@ struct mv643xx_mib_counters { | |||
| 507 | u32 late_collision; | 512 | u32 late_collision; | 
| 508 | }; | 513 | }; | 
| 509 | 514 | ||
| 515 | struct mv643xx_shared_private { | ||
| 516 | void __iomem *eth_base; | ||
| 517 | |||
| 518 | /* used to protect SMI_REG, which is shared across ports */ | ||
| 519 | spinlock_t phy_lock; | ||
| 520 | |||
| 521 | u32 win_protect; | ||
| 522 | |||
| 523 | unsigned int t_clk; | ||
| 524 | }; | ||
| 525 | |||
| 510 | struct mv643xx_private { | 526 | struct mv643xx_private { | 
| 527 | struct mv643xx_shared_private *shared; | ||
| 511 | int port_num; /* User Ethernet port number */ | 528 | int port_num; /* User Ethernet port number */ | 
| 512 | 529 | ||
| 530 | struct mv643xx_shared_private *shared_smi; | ||
| 531 | |||
| 513 | u32 rx_sram_addr; /* Base address of rx sram area */ | 532 | u32 rx_sram_addr; /* Base address of rx sram area */ | 
| 514 | u32 rx_sram_size; /* Size of rx sram area */ | 533 | u32 rx_sram_size; /* Size of rx sram area */ | 
| 515 | u32 tx_sram_addr; /* Base address of tx sram area */ | 534 | u32 tx_sram_addr; /* Base address of tx sram area */ | 
| @@ -614,19 +633,14 @@ static const struct ethtool_ops mv643xx_ethtool_ops; | |||
| 614 | static char mv643xx_driver_name[] = "mv643xx_eth"; | 633 | static char mv643xx_driver_name[] = "mv643xx_eth"; | 
| 615 | static char mv643xx_driver_version[] = "1.0"; | 634 | static char mv643xx_driver_version[] = "1.0"; | 
| 616 | 635 | ||
| 617 | static void __iomem *mv643xx_eth_base; | ||
| 618 | |||
| 619 | /* used to protect SMI_REG, which is shared across ports */ | ||
| 620 | static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); | ||
| 621 | |||
| 622 | static inline u32 rdl(struct mv643xx_private *mp, int offset) | 636 | static inline u32 rdl(struct mv643xx_private *mp, int offset) | 
| 623 | { | 637 | { | 
| 624 | return readl(mv643xx_eth_base + offset); | 638 | return readl(mp->shared->eth_base + offset); | 
| 625 | } | 639 | } | 
| 626 | 640 | ||
| 627 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) | 641 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) | 
| 628 | { | 642 | { | 
| 629 | writel(data, mv643xx_eth_base + offset); | 643 | writel(data, mp->shared->eth_base + offset); | 
| 630 | } | 644 | } | 
| 631 | 645 | ||
| 632 | /* | 646 | /* | 
| @@ -1119,7 +1133,6 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) | |||
| 1119 | * | 1133 | * | 
| 1120 | * INPUT: | 1134 | * INPUT: | 
| 1121 | * struct mv643xx_private *mp Ethernet port | 1135 | * struct mv643xx_private *mp Ethernet port | 
| 1122 | * unsigned int t_clk t_clk of the MV-643xx chip in HZ units | ||
| 1123 | * unsigned int delay Delay in usec | 1136 | * unsigned int delay Delay in usec | 
| 1124 | * | 1137 | * | 
| 1125 | * OUTPUT: | 1138 | * OUTPUT: | 
| @@ -1130,10 +1143,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) | |||
| 1130 | * | 1143 | * | 
| 1131 | */ | 1144 | */ | 
| 1132 | static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | 1145 | static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | 
| 1133 | unsigned int t_clk, unsigned int delay) | 1146 | unsigned int delay) | 
| 1134 | { | 1147 | { | 
| 1135 | unsigned int port_num = mp->port_num; | 1148 | unsigned int port_num = mp->port_num; | 
| 1136 | unsigned int coal = ((t_clk / 1000000) * delay) / 64; | 1149 | unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; | 
| 1137 | 1150 | ||
| 1138 | /* Set RX Coalescing mechanism */ | 1151 | /* Set RX Coalescing mechanism */ | 
| 1139 | wrl(mp, SDMA_CONFIG_REG(port_num), | 1152 | wrl(mp, SDMA_CONFIG_REG(port_num), | 
| @@ -1158,7 +1171,6 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | |||
| 1158 | * | 1171 | * | 
| 1159 | * INPUT: | 1172 | * INPUT: | 
| 1160 | * struct mv643xx_private *mp Ethernet port | 1173 | * struct mv643xx_private *mp Ethernet port | 
| 1161 | * unsigned int t_clk t_clk of the MV-643xx chip in HZ units | ||
| 1162 | * unsigned int delay Delay in uSeconds | 1174 | * unsigned int delay Delay in uSeconds | 
| 1163 | * | 1175 | * | 
| 1164 | * OUTPUT: | 1176 | * OUTPUT: | 
| @@ -1169,9 +1181,9 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | |||
| 1169 | * | 1181 | * | 
| 1170 | */ | 1182 | */ | 
| 1171 | static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, | 1183 | static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, | 
| 1172 | unsigned int t_clk, unsigned int delay) | 1184 | unsigned int delay) | 
| 1173 | { | 1185 | { | 
| 1174 | unsigned int coal = ((t_clk / 1000000) * delay) / 64; | 1186 | unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; | 
| 1175 | 1187 | ||
| 1176 | /* Set TX Coalescing mechanism */ | 1188 | /* Set TX Coalescing mechanism */ | 
| 1177 | wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); | 1189 | wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); | 
| @@ -1413,11 +1425,11 @@ static int mv643xx_eth_open(struct net_device *dev) | |||
| 1413 | 1425 | ||
| 1414 | #ifdef MV643XX_COAL | 1426 | #ifdef MV643XX_COAL | 
| 1415 | mp->rx_int_coal = | 1427 | mp->rx_int_coal = | 
| 1416 | eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL); | 1428 | eth_port_set_rx_coal(mp, MV643XX_RX_COAL); | 
| 1417 | #endif | 1429 | #endif | 
| 1418 | 1430 | ||
| 1419 | mp->tx_int_coal = | 1431 | mp->tx_int_coal = | 
| 1420 | eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL); | 1432 | eth_port_set_tx_coal(mp, MV643XX_TX_COAL); | 
| 1421 | 1433 | ||
| 1422 | /* Unmask phy and link status changes interrupts */ | 1434 | /* Unmask phy and link status changes interrupts */ | 
| 1423 | wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); | 1435 | wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); | 
| @@ -1827,6 +1839,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
| 1827 | return -ENODEV; | 1839 | return -ENODEV; | 
| 1828 | } | 1840 | } | 
| 1829 | 1841 | ||
| 1842 | if (pd->shared == NULL) { | ||
| 1843 | printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); | ||
| 1844 | return -ENODEV; | ||
| 1845 | } | ||
| 1846 | |||
| 1830 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); | 1847 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); | 
| 1831 | if (!dev) | 1848 | if (!dev) | 
| 1832 | return -ENOMEM; | 1849 | return -ENOMEM; | 
| @@ -1877,8 +1894,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
| 1877 | 1894 | ||
| 1878 | spin_lock_init(&mp->lock); | 1895 | spin_lock_init(&mp->lock); | 
| 1879 | 1896 | ||
| 1897 | mp->shared = platform_get_drvdata(pd->shared); | ||
| 1880 | port_num = mp->port_num = pd->port_number; | 1898 | port_num = mp->port_num = pd->port_number; | 
| 1881 | 1899 | ||
| 1900 | if (mp->shared->win_protect) | ||
| 1901 | wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); | ||
| 1902 | |||
| 1903 | mp->shared_smi = mp->shared; | ||
| 1904 | if (pd->shared_smi != NULL) | ||
| 1905 | mp->shared_smi = platform_get_drvdata(pd->shared_smi); | ||
| 1906 | |||
| 1882 | /* set default config values */ | 1907 | /* set default config values */ | 
| 1883 | eth_port_uc_addr_get(mp, dev->dev_addr); | 1908 | eth_port_uc_addr_get(mp, dev->dev_addr); | 
| 1884 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; | 1909 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; | 
| @@ -1983,30 +2008,91 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
| 1983 | return 0; | 2008 | return 0; | 
| 1984 | } | 2009 | } | 
| 1985 | 2010 | ||
| 2011 | static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, | ||
| 2012 | struct mbus_dram_target_info *dram) | ||
| 2013 | { | ||
| 2014 | void __iomem *base = msp->eth_base; | ||
| 2015 | u32 win_enable; | ||
| 2016 | u32 win_protect; | ||
| 2017 | int i; | ||
| 2018 | |||
| 2019 | for (i = 0; i < 6; i++) { | ||
| 2020 | writel(0, base + WINDOW_BASE(i)); | ||
| 2021 | writel(0, base + WINDOW_SIZE(i)); | ||
| 2022 | if (i < 4) | ||
| 2023 | writel(0, base + WINDOW_REMAP_HIGH(i)); | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | win_enable = 0x3f; | ||
| 2027 | win_protect = 0; | ||
| 2028 | |||
| 2029 | for (i = 0; i < dram->num_cs; i++) { | ||
| 2030 | struct mbus_dram_window *cs = dram->cs + i; | ||
| 2031 | |||
| 2032 | writel((cs->base & 0xffff0000) | | ||
| 2033 | (cs->mbus_attr << 8) | | ||
| 2034 | dram->mbus_dram_target_id, base + WINDOW_BASE(i)); | ||
| 2035 | writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); | ||
| 2036 | |||
| 2037 | win_enable &= ~(1 << i); | ||
| 2038 | win_protect |= 3 << (2 * i); | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | writel(win_enable, base + WINDOW_BAR_ENABLE); | ||
| 2042 | msp->win_protect = win_protect; | ||
| 2043 | } | ||
| 2044 | |||
| 1986 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) | 2045 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) | 
| 1987 | { | 2046 | { | 
| 1988 | static int mv643xx_version_printed = 0; | 2047 | static int mv643xx_version_printed = 0; | 
| 2048 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; | ||
| 2049 | struct mv643xx_shared_private *msp; | ||
| 1989 | struct resource *res; | 2050 | struct resource *res; | 
| 2051 | int ret; | ||
| 1990 | 2052 | ||
| 1991 | if (!mv643xx_version_printed++) | 2053 | if (!mv643xx_version_printed++) | 
| 1992 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); | 2054 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); | 
| 1993 | 2055 | ||
| 2056 | ret = -EINVAL; | ||
| 1994 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2057 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 
| 1995 | if (res == NULL) | 2058 | if (res == NULL) | 
| 1996 | return -ENODEV; | 2059 | goto out; | 
| 1997 | 2060 | ||
| 1998 | mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1); | 2061 | ret = -ENOMEM; | 
| 1999 | if (mv643xx_eth_base == NULL) | 2062 | msp = kmalloc(sizeof(*msp), GFP_KERNEL); | 
| 2000 | return -ENOMEM; | 2063 | if (msp == NULL) | 
| 2064 | goto out; | ||
| 2065 | memset(msp, 0, sizeof(*msp)); | ||
| 2066 | |||
| 2067 | msp->eth_base = ioremap(res->start, res->end - res->start + 1); | ||
| 2068 | if (msp->eth_base == NULL) | ||
| 2069 | goto out_free; | ||
| 2070 | |||
| 2071 | spin_lock_init(&msp->phy_lock); | ||
| 2072 | msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; | ||
| 2073 | |||
| 2074 | platform_set_drvdata(pdev, msp); | ||
| 2075 | |||
| 2076 | /* | ||
| 2077 | * (Re-)program MBUS remapping windows if we are asked to. | ||
| 2078 | */ | ||
| 2079 | if (pd != NULL && pd->dram != NULL) | ||
| 2080 | mv643xx_eth_conf_mbus_windows(msp, pd->dram); | ||
| 2001 | 2081 | ||
| 2002 | return 0; | 2082 | return 0; | 
| 2003 | 2083 | ||
| 2084 | out_free: | ||
| 2085 | kfree(msp); | ||
| 2086 | out: | ||
| 2087 | return ret; | ||
| 2004 | } | 2088 | } | 
| 2005 | 2089 | ||
| 2006 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) | 2090 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) | 
| 2007 | { | 2091 | { | 
| 2008 | iounmap(mv643xx_eth_base); | 2092 | struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); | 
| 2009 | mv643xx_eth_base = NULL; | 2093 | |
| 2094 | iounmap(msp->eth_base); | ||
| 2095 | kfree(msp); | ||
| 2010 | 2096 | ||
| 2011 | return 0; | 2097 | return 0; | 
| 2012 | } | 2098 | } | 
| @@ -2906,15 +2992,16 @@ static void eth_port_reset(struct mv643xx_private *mp) | |||
| 2906 | static void eth_port_read_smi_reg(struct mv643xx_private *mp, | 2992 | static void eth_port_read_smi_reg(struct mv643xx_private *mp, | 
| 2907 | unsigned int phy_reg, unsigned int *value) | 2993 | unsigned int phy_reg, unsigned int *value) | 
| 2908 | { | 2994 | { | 
| 2995 | void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; | ||
| 2909 | int phy_addr = ethernet_phy_get(mp); | 2996 | int phy_addr = ethernet_phy_get(mp); | 
| 2910 | unsigned long flags; | 2997 | unsigned long flags; | 
| 2911 | int i; | 2998 | int i; | 
| 2912 | 2999 | ||
| 2913 | /* the SMI register is a shared resource */ | 3000 | /* the SMI register is a shared resource */ | 
| 2914 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 3001 | spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); | 
| 2915 | 3002 | ||
| 2916 | /* wait for the SMI register to become available */ | 3003 | /* wait for the SMI register to become available */ | 
| 2917 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 3004 | for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { | 
| 2918 | if (i == PHY_WAIT_ITERATIONS) { | 3005 | if (i == PHY_WAIT_ITERATIONS) { | 
| 2919 | printk("%s: PHY busy timeout\n", mp->dev->name); | 3006 | printk("%s: PHY busy timeout\n", mp->dev->name); | 
| 2920 | goto out; | 3007 | goto out; | 
| @@ -2922,11 +3009,11 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
| 2922 | udelay(PHY_WAIT_MICRO_SECONDS); | 3009 | udelay(PHY_WAIT_MICRO_SECONDS); | 
| 2923 | } | 3010 | } | 
| 2924 | 3011 | ||
| 2925 | wrl(mp, SMI_REG, | 3012 | writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, | 
| 2926 | (phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ); | 3013 | smi_reg); | 
| 2927 | 3014 | ||
| 2928 | /* now wait for the data to be valid */ | 3015 | /* now wait for the data to be valid */ | 
| 2929 | for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) { | 3016 | for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { | 
| 2930 | if (i == PHY_WAIT_ITERATIONS) { | 3017 | if (i == PHY_WAIT_ITERATIONS) { | 
| 2931 | printk("%s: PHY read timeout\n", mp->dev->name); | 3018 | printk("%s: PHY read timeout\n", mp->dev->name); | 
| 2932 | goto out; | 3019 | goto out; | 
| @@ -2934,9 +3021,9 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
| 2934 | udelay(PHY_WAIT_MICRO_SECONDS); | 3021 | udelay(PHY_WAIT_MICRO_SECONDS); | 
| 2935 | } | 3022 | } | 
| 2936 | 3023 | ||
| 2937 | *value = rdl(mp, SMI_REG) & 0xffff; | 3024 | *value = readl(smi_reg) & 0xffff; | 
| 2938 | out: | 3025 | out: | 
| 2939 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 3026 | spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); | 
| 2940 | } | 3027 | } | 
| 2941 | 3028 | ||
| 2942 | /* | 3029 | /* | 
| @@ -2962,17 +3049,16 @@ out: | |||
| 2962 | static void eth_port_write_smi_reg(struct mv643xx_private *mp, | 3049 | static void eth_port_write_smi_reg(struct mv643xx_private *mp, | 
| 2963 | unsigned int phy_reg, unsigned int value) | 3050 | unsigned int phy_reg, unsigned int value) | 
| 2964 | { | 3051 | { | 
| 2965 | int phy_addr; | 3052 | void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; | 
| 2966 | int i; | 3053 | int phy_addr = ethernet_phy_get(mp); | 
| 2967 | unsigned long flags; | 3054 | unsigned long flags; | 
| 2968 | 3055 | int i; | |
| 2969 | phy_addr = ethernet_phy_get(mp); | ||
| 2970 | 3056 | ||
| 2971 | /* the SMI register is a shared resource */ | 3057 | /* the SMI register is a shared resource */ | 
| 2972 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 3058 | spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); | 
| 2973 | 3059 | ||
| 2974 | /* wait for the SMI register to become available */ | 3060 | /* wait for the SMI register to become available */ | 
| 2975 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 3061 | for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { | 
| 2976 | if (i == PHY_WAIT_ITERATIONS) { | 3062 | if (i == PHY_WAIT_ITERATIONS) { | 
| 2977 | printk("%s: PHY busy timeout\n", mp->dev->name); | 3063 | printk("%s: PHY busy timeout\n", mp->dev->name); | 
| 2978 | goto out; | 3064 | goto out; | 
| @@ -2980,10 +3066,10 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp, | |||
| 2980 | udelay(PHY_WAIT_MICRO_SECONDS); | 3066 | udelay(PHY_WAIT_MICRO_SECONDS); | 
| 2981 | } | 3067 | } | 
| 2982 | 3068 | ||
| 2983 | wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | | 3069 | writel((phy_addr << 16) | (phy_reg << 21) | | 
| 2984 | ETH_SMI_OPCODE_WRITE | (value & 0xffff)); | 3070 | ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); | 
| 2985 | out: | 3071 | out: | 
| 2986 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 3072 | spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); | 
| 2987 | } | 3073 | } | 
| 2988 | 3074 | ||
| 2989 | /* | 3075 | /* | 
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 30e11aa3c1c..a15cdd4a8e5 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h  | |||
| @@ -1,19 +1,31 @@ | |||
| 1 | /* | 1 | /* | 
| 2 | * MV-643XX ethernet platform device data definition file. | 2 | * MV-643XX ethernet platform device data definition file. | 
| 3 | */ | 3 | */ | 
| 4 | |||
| 4 | #ifndef __LINUX_MV643XX_ETH_H | 5 | #ifndef __LINUX_MV643XX_ETH_H | 
| 5 | #define __LINUX_MV643XX_ETH_H | 6 | #define __LINUX_MV643XX_ETH_H | 
| 6 | 7 | ||
| 7 | #define MV643XX_ETH_SHARED_NAME "mv643xx_eth_shared" | 8 | #include <linux/mbus.h> | 
| 8 | #define MV643XX_ETH_NAME "mv643xx_eth" | 9 | |
| 10 | #define MV643XX_ETH_SHARED_NAME "mv643xx_eth" | ||
| 11 | #define MV643XX_ETH_NAME "mv643xx_eth_port" | ||
| 9 | #define MV643XX_ETH_SHARED_REGS 0x2000 | 12 | #define MV643XX_ETH_SHARED_REGS 0x2000 | 
| 10 | #define MV643XX_ETH_SHARED_REGS_SIZE 0x2000 | 13 | #define MV643XX_ETH_SHARED_REGS_SIZE 0x2000 | 
| 11 | #define MV643XX_ETH_BAR_4 0x2220 | 14 | #define MV643XX_ETH_BAR_4 0x2220 | 
| 12 | #define MV643XX_ETH_SIZE_REG_4 0x2224 | 15 | #define MV643XX_ETH_SIZE_REG_4 0x2224 | 
| 13 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 | 16 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 | 
| 14 | 17 | ||
| 18 | struct mv643xx_eth_shared_platform_data { | ||
| 19 | struct mbus_dram_target_info *dram; | ||
| 20 | unsigned int t_clk; | ||
| 21 | }; | ||
| 22 | |||
| 15 | struct mv643xx_eth_platform_data { | 23 | struct mv643xx_eth_platform_data { | 
| 24 | struct platform_device *shared; | ||
| 16 | int port_number; | 25 | int port_number; | 
| 26 | |||
| 27 | struct platform_device *shared_smi; | ||
| 28 | |||
| 17 | u16 force_phy_addr; /* force override if phy_addr == 0 */ | 29 | u16 force_phy_addr; /* force override if phy_addr == 0 */ | 
| 18 | u16 phy_addr; | 30 | u16 phy_addr; | 
| 19 | 31 | ||
