/* This is a simple check to prevent use of this driver on non-tested SoCs */
 #if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
     !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
-    !defined(CONFIG_440EP) && !defined(CONFIG_NP405H)
+    !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE)
 #error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
 #endif
 
 #define EMAC_STACR_PCDA_SHIFT          5
 #define EMAC_STACR_PRA_MASK            0x1f
 
+/*
+ * For the 440SPe, AMCC inexplicably changed the polarity of
+ * the "operation complete" bit in the MII control register.
+ */
+#if defined(CONFIG_440SPE)
+static inline int emac_phy_done(u32 stacr)
+{
+       return !(stacr & EMAC_STACR_OC);
+};
+#define EMAC_STACR_START               EMAC_STACR_OC
+
+#else /* CONFIG_440SPE */
+static inline int emac_phy_done(u32 stacr)
+{
+       return stacr & EMAC_STACR_OC;
+};
+#define EMAC_STACR_START               0
+#endif /* !CONFIG_440SPE */
+
 /* EMACx_TRTR */
 #if !defined(CONFIG_IBM_EMAC4)
 #define EMAC_TRTR_SHIFT                        27
 
 
        /* Wait for management interface to become idle */
        n = 10;
-       while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
+       while (!emac_phy_done(in_be32(&p->stacr))) {
                udelay(1);
                if (!--n)
                        goto to;
        out_be32(&p->stacr,
                 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ |
                 (reg & EMAC_STACR_PRA_MASK)
-                | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT));
+                | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT)
+                | EMAC_STACR_START);
 
        /* Wait for read to complete */
        n = 100;
-       while (!((r = in_be32(&p->stacr)) & EMAC_STACR_OC)) {
+       while (!emac_phy_done(r = in_be32(&p->stacr))) {
                udelay(1);
                if (!--n)
                        goto to;
 
        /* Wait for management interface to be idle */
        n = 10;
-       while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
+       while (!emac_phy_done(in_be32(&p->stacr))) {
                udelay(1);
                if (!--n)
                        goto to;
                 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE |
                 (reg & EMAC_STACR_PRA_MASK) |
                 ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) |
-                (val << EMAC_STACR_PHYD_SHIFT));
+                (val << EMAC_STACR_PHYD_SHIFT) | EMAC_STACR_START);
 
        /* Wait for write to complete */
        n = 100;
-       while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
+       while (!emac_phy_done(in_be32(&p->stacr))) {
                udelay(1);
                if (!--n)
                        goto to;
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \
     defined(CONFIG_440EP) || defined(CONFIG_NP405H)
 #define MAL_VERSION            1
-#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
+      defined(CONFIG_440SPE)
 #define MAL_VERSION            2
 #else
 #error "Unknown SoC, please check chip manual and choose MAL 'version'"