Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] PPC 44x EMAC driver: add 440SPe support

For some reason, the hardware designers made the polarity of one bit
in the 440SPe's PHY interface register the opposite of all other PPC
440 chips. To handle this, abstract our access to this bit and do the
right thing based on the configured CPU type.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

authored by

Eugene Surovegin and committed by
Jeff Garzik
7ad8a89c be15cd72

+29 -8
+20 -1
drivers/net/ibm_emac/ibm_emac.h
··· 26 26 /* This is a simple check to prevent use of this driver on non-tested SoCs */ 27 27 #if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \ 28 28 !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \ 29 - !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) 29 + !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE) 30 30 #error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK" 31 31 #endif 32 32 ··· 245 245 #define EMAC_STACR_PCDA_MASK 0x1f 246 246 #define EMAC_STACR_PCDA_SHIFT 5 247 247 #define EMAC_STACR_PRA_MASK 0x1f 248 + 249 + /* 250 + * For the 440SPe, AMCC inexplicably changed the polarity of 251 + * the "operation complete" bit in the MII control register. 252 + */ 253 + #if defined(CONFIG_440SPE) 254 + static inline int emac_phy_done(u32 stacr) 255 + { 256 + return !(stacr & EMAC_STACR_OC); 257 + }; 258 + #define EMAC_STACR_START EMAC_STACR_OC 259 + 260 + #else /* CONFIG_440SPE */ 261 + static inline int emac_phy_done(u32 stacr) 262 + { 263 + return stacr & EMAC_STACR_OC; 264 + }; 265 + #define EMAC_STACR_START 0 266 + #endif /* !CONFIG_440SPE */ 248 267 249 268 /* EMACx_TRTR */ 250 269 #if !defined(CONFIG_IBM_EMAC4)
+7 -6
drivers/net/ibm_emac/ibm_emac_core.c
··· 546 546 547 547 /* Wait for management interface to become idle */ 548 548 n = 10; 549 - while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { 549 + while (!emac_phy_done(in_be32(&p->stacr))) { 550 550 udelay(1); 551 551 if (!--n) 552 552 goto to; ··· 556 556 out_be32(&p->stacr, 557 557 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ | 558 558 (reg & EMAC_STACR_PRA_MASK) 559 - | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT)); 559 + | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) 560 + | EMAC_STACR_START); 560 561 561 562 /* Wait for read to complete */ 562 563 n = 100; 563 - while (!((r = in_be32(&p->stacr)) & EMAC_STACR_OC)) { 564 + while (!emac_phy_done(r = in_be32(&p->stacr))) { 564 565 udelay(1); 565 566 if (!--n) 566 567 goto to; ··· 595 594 596 595 /* Wait for management interface to be idle */ 597 596 n = 10; 598 - while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { 597 + while (!emac_phy_done(in_be32(&p->stacr))) { 599 598 udelay(1); 600 599 if (!--n) 601 600 goto to; ··· 606 605 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE | 607 606 (reg & EMAC_STACR_PRA_MASK) | 608 607 ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) | 609 - (val << EMAC_STACR_PHYD_SHIFT)); 608 + (val << EMAC_STACR_PHYD_SHIFT) | EMAC_STACR_START); 610 609 611 610 /* Wait for write to complete */ 612 611 n = 100; 613 - while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) { 612 + while (!emac_phy_done(in_be32(&p->stacr))) { 614 613 udelay(1); 615 614 if (!--n) 616 615 goto to;
+2 -1
drivers/net/ibm_emac/ibm_emac_mal.h
··· 34 34 #if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \ 35 35 defined(CONFIG_440EP) || defined(CONFIG_NP405H) 36 36 #define MAL_VERSION 1 37 - #elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) 37 + #elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) || \ 38 + defined(CONFIG_440SPE) 38 39 #define MAL_VERSION 2 39 40 #else 40 41 #error "Unknown SoC, please check chip manual and choose MAL 'version'"