]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/net/phy/smsc.c
karo: merge with Ka-Ro specific tree for secure boot support
[karo-tx-uboot.git] / drivers / net / phy / smsc.c
index 23da3da7113b208b4923a2e75160a98d4810710f..1001d448524c90fda2a72c04abb15e48ebdab8c0 100644 (file)
@@ -7,7 +7,7 @@
  *   Copyright 2010-2011 Freescale Semiconductor, Inc.
  *   author Andy Fleming
  *
- * Some code get from linux kenrel
+ * Some code copied from linux kernel
  * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
  */
 #include <miiphy.h>
@@ -17,6 +17,7 @@
 #define MII_LAN83C185_EDPWRDOWN                (1 << 13) /* EDPWRDOWN */
 #define MII_LAN83C185_ENERGYON         (1 << 1)  /* ENERGYON */
 
+/* This code does not check the partner abilities. */
 static int smsc_parse_status(struct phy_device *phydev)
 {
        int bmcr;
@@ -113,6 +114,51 @@ static int smsc_startup(struct phy_device *phydev)
        return smsc_parse_status(phydev);
 }
 
+static int smsc_mdix_setup(struct phy_device *phydev)
+{
+       int ret;
+       static const char *mdix = "_mdi";
+       char varname[strlen(phydev->bus->name) + strlen(mdix) + 1];
+       const char *val;
+
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, mdix);
+
+       val = getenv(varname);
+       if (val) {
+               if (strcasecmp(val, "auto") == 0) {
+                       ret = 0;
+               } else if (strcasecmp(val, "mdix") == 0) {
+                       ret = 1;
+               } else if (strcasecmp(val, "mdi") == 0) {
+                       ret = 2;
+               } else {
+                       printf("Improper setting '%s' for %s\n", val, varname);
+                       printf("Expected one of: 'auto', 'mdi', 'mdix'\n");
+                       return -EINVAL;
+               }
+       } else {
+               ret = 0;
+       }
+       return ret;
+}
+
+static int smsc_config(struct phy_device *phydev)
+{
+       int mdix = smsc_mdix_setup(phydev);
+
+       if (mdix < 0) {
+               return mdix;
+       } else if (mdix) {
+               int ret = phy_write(phydev, MDIO_DEVAD_NONE, 0x1b,
+                               (1 << 15) | ((mdix & 1) << 13));
+               if (ret) {
+                       printf("Failed to setup MDI/MDIX mode: %d\n", ret);
+                       return ret;
+               }
+       }
+       return genphy_config_aneg(phydev);
+}
+
 static struct phy_driver lan8700_driver = {
        .name = "SMSC LAN8700",
        .uid = 0x0007c0c0,
@@ -137,8 +183,8 @@ static struct phy_driver lan8710_driver = {
        .name = "SMSC LAN8710/LAN8720",
        .uid = 0x0007c0f0,
        .mask = 0xffff0,
-       .features = PHY_GBIT_FEATURES,
-       .config = &genphy_config_aneg,
+       .features = PHY_BASIC_FEATURES,
+       .config = &smsc_config,
        .startup = &smsc_startup,
        .shutdown = &genphy_shutdown,
 };