diff options
-rw-r--r-- | arch/arm/plat-orion/common.c | 54 | ||||
-rw-r--r-- | arch/powerpc/platforms/chrp/pegasos_eth.c | 20 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mv64x60_dev.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/Kconfig | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 195 | ||||
-rw-r--r-- | include/linux/mv643xx_eth.h | 1 |
7 files changed, 84 insertions, 209 deletions
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 2d4b6414609f..251f827271e9 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c | |||
@@ -238,6 +238,7 @@ static __init void ge_complete( | |||
238 | struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, | 238 | struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, |
239 | struct resource *orion_ge_resource, unsigned long irq, | 239 | struct resource *orion_ge_resource, unsigned long irq, |
240 | struct platform_device *orion_ge_shared, | 240 | struct platform_device *orion_ge_shared, |
241 | struct platform_device *orion_ge_mvmdio, | ||
241 | struct mv643xx_eth_platform_data *eth_data, | 242 | struct mv643xx_eth_platform_data *eth_data, |
242 | struct platform_device *orion_ge) | 243 | struct platform_device *orion_ge) |
243 | { | 244 | { |
@@ -247,6 +248,8 @@ static __init void ge_complete( | |||
247 | orion_ge->dev.platform_data = eth_data; | 248 | orion_ge->dev.platform_data = eth_data; |
248 | 249 | ||
249 | platform_device_register(orion_ge_shared); | 250 | platform_device_register(orion_ge_shared); |
251 | if (orion_ge_mvmdio) | ||
252 | platform_device_register(orion_ge_mvmdio); | ||
250 | platform_device_register(orion_ge); | 253 | platform_device_register(orion_ge); |
251 | } | 254 | } |
252 | 255 | ||
@@ -258,8 +261,6 @@ struct mv643xx_eth_shared_platform_data orion_ge00_shared_data; | |||
258 | static struct resource orion_ge00_shared_resources[] = { | 261 | static struct resource orion_ge00_shared_resources[] = { |
259 | { | 262 | { |
260 | .name = "ge00 base", | 263 | .name = "ge00 base", |
261 | }, { | ||
262 | .name = "ge00 err irq", | ||
263 | }, | 264 | }, |
264 | }; | 265 | }; |
265 | 266 | ||
@@ -271,6 +272,19 @@ static struct platform_device orion_ge00_shared = { | |||
271 | }, | 272 | }, |
272 | }; | 273 | }; |
273 | 274 | ||
275 | static struct resource orion_ge_mvmdio_resources[] = { | ||
276 | { | ||
277 | .name = "ge00 mvmdio base", | ||
278 | }, { | ||
279 | .name = "ge00 mvmdio err irq", | ||
280 | }, | ||
281 | }; | ||
282 | |||
283 | static struct platform_device orion_ge_mvmdio = { | ||
284 | .name = "orion-mdio", | ||
285 | .id = -1, | ||
286 | }; | ||
287 | |||
274 | static struct resource orion_ge00_resources[] = { | 288 | static struct resource orion_ge00_resources[] = { |
275 | { | 289 | { |
276 | .name = "ge00 irq", | 290 | .name = "ge00 irq", |
@@ -295,26 +309,25 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, | |||
295 | unsigned int tx_csum_limit) | 309 | unsigned int tx_csum_limit) |
296 | { | 310 | { |
297 | fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, | 311 | fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, |
298 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 312 | mapbase + 0x2000, SZ_16K - 1, NO_IRQ); |
313 | fill_resources(&orion_ge_mvmdio, orion_ge_mvmdio_resources, | ||
314 | mapbase + 0x2004, 0x84 - 1, irq_err); | ||
299 | orion_ge00_shared_data.tx_csum_limit = tx_csum_limit; | 315 | orion_ge00_shared_data.tx_csum_limit = tx_csum_limit; |
300 | ge_complete(&orion_ge00_shared_data, | 316 | ge_complete(&orion_ge00_shared_data, |
301 | orion_ge00_resources, irq, &orion_ge00_shared, | 317 | orion_ge00_resources, irq, &orion_ge00_shared, |
318 | &orion_ge_mvmdio, | ||
302 | eth_data, &orion_ge00); | 319 | eth_data, &orion_ge00); |
303 | } | 320 | } |
304 | 321 | ||
305 | /***************************************************************************** | 322 | /***************************************************************************** |
306 | * GE01 | 323 | * GE01 |
307 | ****************************************************************************/ | 324 | ****************************************************************************/ |
308 | struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = { | 325 | struct mv643xx_eth_shared_platform_data orion_ge01_shared_data; |
309 | .shared_smi = &orion_ge00_shared, | ||
310 | }; | ||
311 | 326 | ||
312 | static struct resource orion_ge01_shared_resources[] = { | 327 | static struct resource orion_ge01_shared_resources[] = { |
313 | { | 328 | { |
314 | .name = "ge01 base", | 329 | .name = "ge01 base", |
315 | }, { | 330 | } |
316 | .name = "ge01 err irq", | ||
317 | }, | ||
318 | }; | 331 | }; |
319 | 332 | ||
320 | static struct platform_device orion_ge01_shared = { | 333 | static struct platform_device orion_ge01_shared = { |
@@ -349,26 +362,23 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, | |||
349 | unsigned int tx_csum_limit) | 362 | unsigned int tx_csum_limit) |
350 | { | 363 | { |
351 | fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, | 364 | fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, |
352 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 365 | mapbase + 0x2000, SZ_16K - 1, NO_IRQ); |
353 | orion_ge01_shared_data.tx_csum_limit = tx_csum_limit; | 366 | orion_ge01_shared_data.tx_csum_limit = tx_csum_limit; |
354 | ge_complete(&orion_ge01_shared_data, | 367 | ge_complete(&orion_ge01_shared_data, |
355 | orion_ge01_resources, irq, &orion_ge01_shared, | 368 | orion_ge01_resources, irq, &orion_ge01_shared, |
369 | NULL, | ||
356 | eth_data, &orion_ge01); | 370 | eth_data, &orion_ge01); |
357 | } | 371 | } |
358 | 372 | ||
359 | /***************************************************************************** | 373 | /***************************************************************************** |
360 | * GE10 | 374 | * GE10 |
361 | ****************************************************************************/ | 375 | ****************************************************************************/ |
362 | struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = { | 376 | struct mv643xx_eth_shared_platform_data orion_ge10_shared_data; |
363 | .shared_smi = &orion_ge00_shared, | ||
364 | }; | ||
365 | 377 | ||
366 | static struct resource orion_ge10_shared_resources[] = { | 378 | static struct resource orion_ge10_shared_resources[] = { |
367 | { | 379 | { |
368 | .name = "ge10 base", | 380 | .name = "ge10 base", |
369 | }, { | 381 | } |
370 | .name = "ge10 err irq", | ||
371 | }, | ||
372 | }; | 382 | }; |
373 | 383 | ||
374 | static struct platform_device orion_ge10_shared = { | 384 | static struct platform_device orion_ge10_shared = { |
@@ -402,24 +412,21 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, | |||
402 | unsigned long irq_err) | 412 | unsigned long irq_err) |
403 | { | 413 | { |
404 | fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, | 414 | fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, |
405 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 415 | mapbase + 0x2000, SZ_16K - 1, NO_IRQ); |
406 | ge_complete(&orion_ge10_shared_data, | 416 | ge_complete(&orion_ge10_shared_data, |
407 | orion_ge10_resources, irq, &orion_ge10_shared, | 417 | orion_ge10_resources, irq, &orion_ge10_shared, |
418 | NULL, | ||
408 | eth_data, &orion_ge10); | 419 | eth_data, &orion_ge10); |
409 | } | 420 | } |
410 | 421 | ||
411 | /***************************************************************************** | 422 | /***************************************************************************** |
412 | * GE11 | 423 | * GE11 |
413 | ****************************************************************************/ | 424 | ****************************************************************************/ |
414 | struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = { | 425 | struct mv643xx_eth_shared_platform_data orion_ge11_shared_data; |
415 | .shared_smi = &orion_ge00_shared, | ||
416 | }; | ||
417 | 426 | ||
418 | static struct resource orion_ge11_shared_resources[] = { | 427 | static struct resource orion_ge11_shared_resources[] = { |
419 | { | 428 | { |
420 | .name = "ge11 base", | 429 | .name = "ge11 base", |
421 | }, { | ||
422 | .name = "ge11 err irq", | ||
423 | }, | 430 | }, |
424 | }; | 431 | }; |
425 | 432 | ||
@@ -454,9 +461,10 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, | |||
454 | unsigned long irq_err) | 461 | unsigned long irq_err) |
455 | { | 462 | { |
456 | fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, | 463 | fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, |
457 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 464 | mapbase + 0x2000, SZ_16K - 1, NO_IRQ); |
458 | ge_complete(&orion_ge11_shared_data, | 465 | ge_complete(&orion_ge11_shared_data, |
459 | orion_ge11_resources, irq, &orion_ge11_shared, | 466 | orion_ge11_resources, irq, &orion_ge11_shared, |
467 | NULL, | ||
460 | eth_data, &orion_ge11); | 468 | eth_data, &orion_ge11); |
461 | } | 469 | } |
462 | 470 | ||
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 039fc8e82199..2b4dc6abde6c 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c | |||
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = { | |||
47 | .resource = mv643xx_eth_shared_resources, | 47 | .resource = mv643xx_eth_shared_resources, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | ||
51 | * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1 | ||
52 | */ | ||
53 | static struct resource mv643xx_eth_mvmdio_resources[] = { | ||
54 | [0] = { | ||
55 | .name = "ethernet mdio base", | ||
56 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4, | ||
57 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | static struct platform_device mv643xx_eth_mvmdio_device = { | ||
63 | .name = "orion-mdio", | ||
64 | .id = -1, | ||
65 | .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), | ||
66 | .resource = mv643xx_eth_shared_resources, | ||
67 | }; | ||
68 | |||
50 | static struct resource mv643xx_eth_port1_resources[] = { | 69 | static struct resource mv643xx_eth_port1_resources[] = { |
51 | [0] = { | 70 | [0] = { |
52 | .name = "eth port1 irq", | 71 | .name = "eth port1 irq", |
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = { | |||
82 | 101 | ||
83 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | 102 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { |
84 | &mv643xx_eth_shared_device, | 103 | &mv643xx_eth_shared_device, |
104 | &mv643xx_eth_mvmdio_device, | ||
85 | ð_port1_device, | 105 | ð_port1_device, |
86 | }; | 106 | }; |
87 | 107 | ||
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 0f6af41ebb44..4a25c26f0bf4 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c | |||
@@ -214,15 +214,27 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev( | |||
214 | struct device_node *np, int id) | 214 | struct device_node *np, int id) |
215 | { | 215 | { |
216 | struct platform_device *pdev; | 216 | struct platform_device *pdev; |
217 | struct resource r[1]; | 217 | struct resource r[2]; |
218 | int err; | 218 | int err; |
219 | 219 | ||
220 | err = of_address_to_resource(np, 0, &r[0]); | 220 | err = of_address_to_resource(np, 0, &r[0]); |
221 | if (err) | 221 | if (err) |
222 | return ERR_PTR(err); | 222 | return ERR_PTR(err); |
223 | 223 | ||
224 | /* register an orion mdio bus driver */ | ||
225 | r[1].start = r[0].start + 0x4; | ||
226 | r[1].end = r[0].start + 0x84 - 1; | ||
227 | r[1].flags = IORESOURCE_MEM; | ||
228 | |||
229 | if (id == 0) { | ||
230 | pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1); | ||
231 | if (!pdev) | ||
232 | return pdev; | ||
233 | } | ||
234 | |||
224 | pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, | 235 | pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, |
225 | r, 1); | 236 | &r[0], 1); |
237 | |||
226 | return pdev; | 238 | return pdev; |
227 | } | 239 | } |
228 | 240 | ||
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index edfba9370922..5170ecb00acc 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig | |||
@@ -23,6 +23,7 @@ config MV643XX_ETH | |||
23 | depends on (MV64X60 || PPC32 || PLAT_ORION) && INET | 23 | depends on (MV64X60 || PPC32 || PLAT_ORION) && INET |
24 | select INET_LRO | 24 | select INET_LRO |
25 | select PHYLIB | 25 | select PHYLIB |
26 | select MVMDIO | ||
26 | ---help--- | 27 | ---help--- |
27 | This driver supports the gigabit ethernet MACs in the | 28 | This driver supports the gigabit ethernet MACs in the |
28 | Marvell Discovery PPC/MIPS chipset family (MV643XX) and | 29 | Marvell Discovery PPC/MIPS chipset family (MV643XX) and |
@@ -38,9 +39,7 @@ config MVMDIO | |||
38 | interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, | 39 | interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, |
39 | Dove, Armada 370 and Armada XP). | 40 | Dove, Armada 370 and Armada XP). |
40 | 41 | ||
41 | For now, this driver is only needed for the MVNETA driver | 42 | This driver is used by the MV643XX_ETH and MVNETA drivers. |
42 | (used on Armada 370 and XP), but it could be used in the | ||
43 | future by the MV643XX_ETH driver. | ||
44 | 43 | ||
45 | config MVNETA | 44 | config MVNETA |
46 | tristate "Marvell Armada 370/XP network interface support" | 45 | tristate "Marvell Armada 370/XP network interface support" |
diff --git a/drivers/net/ethernet/marvell/Makefile b/drivers/net/ethernet/marvell/Makefile index 7f63b4aac434..5c4a7765ff0e 100644 --- a/drivers/net/ethernet/marvell/Makefile +++ b/drivers/net/ethernet/marvell/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # Makefile for the Marvell device drivers. | 2 | # Makefile for the Marvell device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o | ||
6 | obj-$(CONFIG_MVMDIO) += mvmdio.o | 5 | obj-$(CONFIG_MVMDIO) += mvmdio.o |
6 | obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o | ||
7 | obj-$(CONFIG_MVNETA) += mvneta.o | 7 | obj-$(CONFIG_MVNETA) += mvneta.o |
8 | obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o | 8 | obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o |
9 | obj-$(CONFIG_SKGE) += skge.o | 9 | obj-$(CONFIG_SKGE) += skge.o |
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index d1ecf4bf7da7..a65a92ef19ec 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -69,14 +69,6 @@ static char mv643xx_eth_driver_version[] = "1.4"; | |||
69 | * Registers shared between all ports. | 69 | * Registers shared between all ports. |
70 | */ | 70 | */ |
71 | #define PHY_ADDR 0x0000 | 71 | #define PHY_ADDR 0x0000 |
72 | #define SMI_REG 0x0004 | ||
73 | #define SMI_BUSY 0x10000000 | ||
74 | #define SMI_READ_VALID 0x08000000 | ||
75 | #define SMI_OPCODE_READ 0x04000000 | ||
76 | #define SMI_OPCODE_WRITE 0x00000000 | ||
77 | #define ERR_INT_CAUSE 0x0080 | ||
78 | #define ERR_INT_SMI_DONE 0x00000010 | ||
79 | #define ERR_INT_MASK 0x0084 | ||
80 | #define WINDOW_BASE(w) (0x0200 + ((w) << 3)) | 72 | #define WINDOW_BASE(w) (0x0200 + ((w) << 3)) |
81 | #define WINDOW_SIZE(w) (0x0204 + ((w) << 3)) | 73 | #define WINDOW_SIZE(w) (0x0204 + ((w) << 3)) |
82 | #define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2)) | 74 | #define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2)) |
@@ -266,25 +258,6 @@ struct mv643xx_eth_shared_private { | |||
266 | void __iomem *base; | 258 | void __iomem *base; |
267 | 259 | ||
268 | /* | 260 | /* |
269 | * Points at the right SMI instance to use. | ||
270 | */ | ||
271 | struct mv643xx_eth_shared_private *smi; | ||
272 | |||
273 | /* | ||
274 | * Provides access to local SMI interface. | ||
275 | */ | ||
276 | struct mii_bus *smi_bus; | ||
277 | |||
278 | /* | ||
279 | * If we have access to the error interrupt pin (which is | ||
280 | * somewhat misnamed as it not only reflects internal errors | ||
281 | * but also reflects SMI completion), use that to wait for | ||
282 | * SMI access completion instead of polling the SMI busy bit. | ||
283 | */ | ||
284 | int err_interrupt; | ||
285 | wait_queue_head_t smi_busy_wait; | ||
286 | |||
287 | /* | ||
288 | * Per-port MBUS window access register value. | 261 | * Per-port MBUS window access register value. |
289 | */ | 262 | */ |
290 | u32 win_protect; | 263 | u32 win_protect; |
@@ -1122,97 +1095,6 @@ out_write: | |||
1122 | wrlp(mp, PORT_SERIAL_CONTROL, pscr); | 1095 | wrlp(mp, PORT_SERIAL_CONTROL, pscr); |
1123 | } | 1096 | } |
1124 | 1097 | ||
1125 | static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) | ||
1126 | { | ||
1127 | struct mv643xx_eth_shared_private *msp = dev_id; | ||
1128 | |||
1129 | if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) { | ||
1130 | writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE); | ||
1131 | wake_up(&msp->smi_busy_wait); | ||
1132 | return IRQ_HANDLED; | ||
1133 | } | ||
1134 | |||
1135 | return IRQ_NONE; | ||
1136 | } | ||
1137 | |||
1138 | static int smi_is_done(struct mv643xx_eth_shared_private *msp) | ||
1139 | { | ||
1140 | return !(readl(msp->base + SMI_REG) & SMI_BUSY); | ||
1141 | } | ||
1142 | |||
1143 | static int smi_wait_ready(struct mv643xx_eth_shared_private *msp) | ||
1144 | { | ||
1145 | if (msp->err_interrupt == NO_IRQ) { | ||
1146 | int i; | ||
1147 | |||
1148 | for (i = 0; !smi_is_done(msp); i++) { | ||
1149 | if (i == 10) | ||
1150 | return -ETIMEDOUT; | ||
1151 | msleep(10); | ||
1152 | } | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | if (!smi_is_done(msp)) { | ||
1158 | wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), | ||
1159 | msecs_to_jiffies(100)); | ||
1160 | if (!smi_is_done(msp)) | ||
1161 | return -ETIMEDOUT; | ||
1162 | } | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | static int smi_bus_read(struct mii_bus *bus, int addr, int reg) | ||
1168 | { | ||
1169 | struct mv643xx_eth_shared_private *msp = bus->priv; | ||
1170 | void __iomem *smi_reg = msp->base + SMI_REG; | ||
1171 | int ret; | ||
1172 | |||
1173 | if (smi_wait_ready(msp)) { | ||
1174 | pr_warn("SMI bus busy timeout\n"); | ||
1175 | return -ETIMEDOUT; | ||
1176 | } | ||
1177 | |||
1178 | writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg); | ||
1179 | |||
1180 | if (smi_wait_ready(msp)) { | ||
1181 | pr_warn("SMI bus busy timeout\n"); | ||
1182 | return -ETIMEDOUT; | ||
1183 | } | ||
1184 | |||
1185 | ret = readl(smi_reg); | ||
1186 | if (!(ret & SMI_READ_VALID)) { | ||
1187 | pr_warn("SMI bus read not valid\n"); | ||
1188 | return -ENODEV; | ||
1189 | } | ||
1190 | |||
1191 | return ret & 0xffff; | ||
1192 | } | ||
1193 | |||
1194 | static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val) | ||
1195 | { | ||
1196 | struct mv643xx_eth_shared_private *msp = bus->priv; | ||
1197 | void __iomem *smi_reg = msp->base + SMI_REG; | ||
1198 | |||
1199 | if (smi_wait_ready(msp)) { | ||
1200 | pr_warn("SMI bus busy timeout\n"); | ||
1201 | return -ETIMEDOUT; | ||
1202 | } | ||
1203 | |||
1204 | writel(SMI_OPCODE_WRITE | (reg << 21) | | ||
1205 | (addr << 16) | (val & 0xffff), smi_reg); | ||
1206 | |||
1207 | if (smi_wait_ready(msp)) { | ||
1208 | pr_warn("SMI bus busy timeout\n"); | ||
1209 | return -ETIMEDOUT; | ||
1210 | } | ||
1211 | |||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | |||
1216 | /* statistics ***************************************************************/ | 1098 | /* statistics ***************************************************************/ |
1217 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) | 1099 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) |
1218 | { | 1100 | { |
@@ -2688,47 +2570,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2688 | goto out_free; | 2570 | goto out_free; |
2689 | 2571 | ||
2690 | /* | 2572 | /* |
2691 | * Set up and register SMI bus. | ||
2692 | */ | ||
2693 | if (pd == NULL || pd->shared_smi == NULL) { | ||
2694 | msp->smi_bus = mdiobus_alloc(); | ||
2695 | if (msp->smi_bus == NULL) | ||
2696 | goto out_unmap; | ||
2697 | |||
2698 | msp->smi_bus->priv = msp; | ||
2699 | msp->smi_bus->name = "mv643xx_eth smi"; | ||
2700 | msp->smi_bus->read = smi_bus_read; | ||
2701 | msp->smi_bus->write = smi_bus_write, | ||
2702 | snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d", | ||
2703 | pdev->name, pdev->id); | ||
2704 | msp->smi_bus->parent = &pdev->dev; | ||
2705 | msp->smi_bus->phy_mask = 0xffffffff; | ||
2706 | if (mdiobus_register(msp->smi_bus) < 0) | ||
2707 | goto out_free_mii_bus; | ||
2708 | msp->smi = msp; | ||
2709 | } else { | ||
2710 | msp->smi = platform_get_drvdata(pd->shared_smi); | ||
2711 | } | ||
2712 | |||
2713 | msp->err_interrupt = NO_IRQ; | ||
2714 | init_waitqueue_head(&msp->smi_busy_wait); | ||
2715 | |||
2716 | /* | ||
2717 | * Check whether the error interrupt is hooked up. | ||
2718 | */ | ||
2719 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
2720 | if (res != NULL) { | ||
2721 | int err; | ||
2722 | |||
2723 | err = request_irq(res->start, mv643xx_eth_err_irq, | ||
2724 | IRQF_SHARED, "mv643xx_eth", msp); | ||
2725 | if (!err) { | ||
2726 | writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK); | ||
2727 | msp->err_interrupt = res->start; | ||
2728 | } | ||
2729 | } | ||
2730 | |||
2731 | /* | ||
2732 | * (Re-)program MBUS remapping windows if we are asked to. | 2573 | * (Re-)program MBUS remapping windows if we are asked to. |
2733 | */ | 2574 | */ |
2734 | dram = mv_mbus_dram_info(); | 2575 | dram = mv_mbus_dram_info(); |
@@ -2743,10 +2584,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2743 | 2584 | ||
2744 | return 0; | 2585 | return 0; |
2745 | 2586 | ||
2746 | out_free_mii_bus: | ||
2747 | mdiobus_free(msp->smi_bus); | ||
2748 | out_unmap: | ||
2749 | iounmap(msp->base); | ||
2750 | out_free: | 2587 | out_free: |
2751 | kfree(msp); | 2588 | kfree(msp); |
2752 | out: | 2589 | out: |
@@ -2756,14 +2593,7 @@ out: | |||
2756 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) | 2593 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) |
2757 | { | 2594 | { |
2758 | struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); | 2595 | struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); |
2759 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; | ||
2760 | 2596 | ||
2761 | if (pd == NULL || pd->shared_smi == NULL) { | ||
2762 | mdiobus_unregister(msp->smi_bus); | ||
2763 | mdiobus_free(msp->smi_bus); | ||
2764 | } | ||
2765 | if (msp->err_interrupt != NO_IRQ) | ||
2766 | free_irq(msp->err_interrupt, msp); | ||
2767 | iounmap(msp->base); | 2597 | iounmap(msp->base); |
2768 | kfree(msp); | 2598 | kfree(msp); |
2769 | 2599 | ||
@@ -2826,14 +2656,21 @@ static void set_params(struct mv643xx_eth_private *mp, | |||
2826 | mp->txq_count = pd->tx_queue_count ? : 1; | 2656 | mp->txq_count = pd->tx_queue_count ? : 1; |
2827 | } | 2657 | } |
2828 | 2658 | ||
2659 | static void mv643xx_eth_adjust_link(struct net_device *dev) | ||
2660 | { | ||
2661 | struct mv643xx_eth_private *mp = netdev_priv(dev); | ||
2662 | |||
2663 | mv643xx_adjust_pscr(mp); | ||
2664 | } | ||
2665 | |||
2829 | static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, | 2666 | static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, |
2830 | int phy_addr) | 2667 | int phy_addr) |
2831 | { | 2668 | { |
2832 | struct mii_bus *bus = mp->shared->smi->smi_bus; | ||
2833 | struct phy_device *phydev; | 2669 | struct phy_device *phydev; |
2834 | int start; | 2670 | int start; |
2835 | int num; | 2671 | int num; |
2836 | int i; | 2672 | int i; |
2673 | char phy_id[MII_BUS_ID_SIZE + 3]; | ||
2837 | 2674 | ||
2838 | if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) { | 2675 | if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) { |
2839 | start = phy_addr_get(mp) & 0x1f; | 2676 | start = phy_addr_get(mp) & 0x1f; |
@@ -2843,17 +2680,19 @@ static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, | |||
2843 | num = 1; | 2680 | num = 1; |
2844 | } | 2681 | } |
2845 | 2682 | ||
2683 | /* Attempt to connect to the PHY using orion-mdio */ | ||
2846 | phydev = NULL; | 2684 | phydev = NULL; |
2847 | for (i = 0; i < num; i++) { | 2685 | for (i = 0; i < num; i++) { |
2848 | int addr = (start + i) & 0x1f; | 2686 | int addr = (start + i) & 0x1f; |
2849 | 2687 | ||
2850 | if (bus->phy_map[addr] == NULL) | 2688 | snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, |
2851 | mdiobus_scan(bus, addr); | 2689 | "orion-mdio-mii", addr); |
2852 | 2690 | ||
2853 | if (phydev == NULL) { | 2691 | phydev = phy_connect(mp->dev, phy_id, mv643xx_eth_adjust_link, |
2854 | phydev = bus->phy_map[addr]; | 2692 | PHY_INTERFACE_MODE_GMII); |
2855 | if (phydev != NULL) | 2693 | if (!IS_ERR(phydev)) { |
2856 | phy_addr_set(mp, addr); | 2694 | phy_addr_set(mp, addr); |
2695 | break; | ||
2857 | } | 2696 | } |
2858 | } | 2697 | } |
2859 | 2698 | ||
@@ -2866,8 +2705,6 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex) | |||
2866 | 2705 | ||
2867 | phy_reset(mp); | 2706 | phy_reset(mp); |
2868 | 2707 | ||
2869 | phy_attach(mp->dev, dev_name(&phy->dev), PHY_INTERFACE_MODE_GMII); | ||
2870 | |||
2871 | if (speed == 0) { | 2708 | if (speed == 0) { |
2872 | phy->autoneg = AUTONEG_ENABLE; | 2709 | phy->autoneg = AUTONEG_ENABLE; |
2873 | phy->speed = 0; | 2710 | phy->speed = 0; |
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 49258e0ed1c6..141d395bbb5f 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | struct mv643xx_eth_shared_platform_data { | 20 | struct mv643xx_eth_shared_platform_data { |
21 | struct mbus_dram_target_info *dram; | 21 | struct mbus_dram_target_info *dram; |
22 | struct platform_device *shared_smi; | ||
23 | /* | 22 | /* |
24 | * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default | 23 | * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default |
25 | * limit of 9KiB will be used. | 24 | * limit of 9KiB will be used. |