Use the new ethernet eeprom API to allow the user to read/write the
EEPROM.

Change-Id: I21233b6ee805a75bd8a03ca12e22c41421b7629c
Signed-off-by: Alban Bedel <alban.be...@avionic-design.de>
---
 drivers/usb/eth/smsc95xx.c | 199 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 192 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index 6bca34d..eb29565 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -59,6 +59,8 @@
 
 #define E2P_CMD                                0x30
 #define E2P_CMD_BUSY_                  0x80000000
+#define E2P_CMD_EWEN_                  0x20000000
+#define E2P_CMD_WRITE_                 0x30000000
 #define E2P_CMD_READ_                  0x00000000
 #define E2P_CMD_TIMEOUT_               0x00000400
 #define E2P_CMD_LOADED_                        0x00000200
@@ -146,6 +148,131 @@ struct smsc95xx_private {
        int have_hwaddr;  /* 1 if we have a hardware MAC address */
 };
 
+#ifdef CONFIG_CMD_ETH_EEPROM
+static u8 eeprom_defaults[] = {
+       /* 0x00 */
+       0xA5,           /* Signature */
+       0xFF, 0xFF,     /* MAC bytes 0-1 */
+       0xFF, 0xFF,     /* MAC bytes 2-3 */
+       0xFF, 0xFF,     /* MAC bytes 4-5 */
+       0x01,           /* FS Polling Interval for Interrupt Endpoint */
+       0x01,           /* HS Polling Interval for Interrupt Endpoint */
+       0x01,           /* Configuration Flags */
+       0x09, 0x04,     /* Language ID */
+       0x0a,           /* Manufacturer ID String Descriptor Length (bytes) */
+       0x2f,           /* Manufacturer ID String Descriptor EEPROM Word Offset 
*/
+       0x10,           /* Product Name String Descriptor Length (bytes) */
+       0x34,           /* Product Name String Descriptor EEPROM Word Offset */
+       /* 0x10 */
+       0x12,           /* Serial Number String Descriptor Length (bytes) */
+       0x3c,           /* Serial Number String Descriptor EEPROM Word Offset */
+       0x08,           /* Configuration String Descriptor Length (bytes) */
+       0x45,           /* Configuration String Descriptor Word Offset */
+       0x08,           /* Interface String Descriptor Length (bytes) */
+       0x49,           /* Interface String Descriptor Word Offset */
+       0x12,           /* Hi-Speed Device Descriptor Length (bytes) */
+       0x1d,           /* Hi-Speed Device Descriptor Word Offset */
+       0x12,           /* Hi-Speed Configuration and Interface Descriptor 
Length (bytes) */
+       0x26,           /* Hi-Speed Configuration and Interface Descriptor Word 
Offset */
+       0x12,           /* Full-Speed Device Descriptor Length (bytes) */
+       0x1d,           /* Full-Speed Device Descriptor Word Offset */
+       0x12,           /* Full-Speed Configuration and Interface Descriptor 
Length (bytes) */
+       0x26,           /* Full-Speed Configuration and Interface Descriptor 
Word Offset */
+       0x00, 0x00,     /* RESERVED */
+       /* 0x20 */
+       0x24, 0x04,     /* Vendor ID */
+       0x14, 0x95,     /* Product ID */
+       0x00, 0x01,     /* Device ID */
+       0x9b,           /* Config Data Byte 1 Register (CFG1) */
+       0x18,           /* Config Data Byte 2 Register (CFG2) */
+       0x00,           /* Config Data Byte 3 Register (CFG3) */
+       0x32,           /* Non-Removable Devices Register (NRD) */
+       0x00,           /* Port Disable (Self) Register (PDS) */
+       0x00,           /* Port Disable (Bus) Register (PDB) */
+       0x01,           /* Max Power (Self) Register (MAXPS) */
+       0x00,           /* Max Power (Bus) Register (MAXPB) */
+       0x01,           /* Hub Controller Max Current (Self) Register (HCMCS) */
+       0x00,           /* Hub Controller Max Current (Bus) Register (HCMCB) */
+       /* 0x30 */
+       0x32,           /* Power-on Time Register (PWRT) */
+       0x00,           /* Boost_Up Register (BOOSTUP) */
+       0x00,           /* Boost_5 Register (BOOST5) */
+       0x00,           /* Boost_4:2 Register (BOOST42) */
+       0x00,           /* RESERVED */
+       0x00,           /* Port Swap Register (PRTSP) */
+       0x21,           /* Port Remap 12 Register (PRTR12) */
+       0x43,           /* Port Remap 34 Register (PRTR34) */
+       0x05,           /* Port Remap 5 Register (PRTR5) */
+       0x01,           /* Status/Command Register (STCD) */
+       /* 0x3A          - Device Descriptor */
+       0x12, 0x01,
+       0x00, 0x02,
+       0xff, 0x00,
+       /* 0x40 */
+       0xff, 0x40,
+       0x24, 0x04,
+       0x00, 0xec,
+       0x00, 0x01,
+       0x01, 0x02,
+       0x03, 0x01,
+       /* 0x4C          - Configuration and Interface Descriptor */
+       0x09, 0x02,
+       0x27, 0x00,
+       /* 0x50 */
+       0x01, 0x01,
+       0x04, 0xc0,
+       0x00, 0x09,
+       0x04, 0x00,
+       0x00, 0x03,
+       0xff, 0x00,
+       0xff, 0x05,
+       /* 0x5E          - Manufacturer ID String Descriptor */
+       0x0a, 0x03,
+       /* 0x60 */
+       0x53, 0x00,     /* S */
+       0x4d, 0x00,     /* M */
+       0x53, 0x00,     /* S */
+       0x43, 0x00,     /* C */
+       /* 0x68          - Product Name String */
+       0x10, 0x03,
+       0x4c, 0x00,     /* L */
+       0x41, 0x00,     /* A */
+       0x4e, 0x00,     /* N */
+       /* 0x70 */
+       0x39, 0x00,     /* 9 */
+       0x35, 0x00,     /* 5 */
+       0x31, 0x00,     /* 1 */
+       0x34, 0x00,     /* 5 */
+       /* 0x78          - Serial Number String Descriptor */
+       0x12, 0x03,
+       0x31, 0x00,     /* 1 */
+       0x32, 0x00,     /* 2 */
+       0x33, 0x00,     /* 3 */
+       /* 0x80 */
+       0x34, 0x00,     /* 4 */
+       0x35, 0x00,     /* 5 */
+       0x36, 0x00,     /* 6 */
+       0x37, 0x00,     /* 7 */
+       0x38, 0x00,     /* 8 */
+       /* 0x8A          - Configuration String Descriptor */
+       0x08, 0x03,
+       0x43, 0x00,     /* C */
+       0x66, 0x00,     /* f */
+       /* 0x90 */
+       0x67, 0x00,     /* g */
+       /* 0x92          - Interface String Descriptor */
+       0x08, 0x03,
+       0x69, 0x00,     /* i */
+       0x2f, 0x00,     /* / */
+       0x66, 0x00,     /* f */
+       /* 0x9A - END */
+       0x00, 0x00,
+       0x00, 0x00,
+       0x00, 0x00,
+       /* 0xA0 */
+};
+#endif
+
 /*
  * Smsc95xx infrastructure commands
  */
@@ -285,9 +412,10 @@ static int smsc95xx_wait_eeprom(struct ueth_data *dev)
        return 0;
 }
 
-static int smsc95xx_read_eeprom(struct ueth_data *dev, u32 offset, u32 length,
-                               u8 *data)
+static int smsc95xx_read_eeprom(struct eth_device *eth, u32 offset, u32 length,
+                       u8 *data)
 {
+       struct ueth_data *dev = (struct ueth_data *)eth->priv;
        u32 val;
        int i, ret;
 
@@ -310,6 +438,58 @@ static int smsc95xx_read_eeprom(struct ueth_data *dev, u32 
offset, u32 length,
        return 0;
 }
 
+#ifdef CONFIG_CMD_ETH_EEPROM
+static int smsc95xx_write_eeprom(struct eth_device *eth, u32 offset, u32 
length,
+                       u8 *data)
+{
+       struct ueth_data *dev = (struct ueth_data *)eth->priv;
+       u32 val;
+       int i, ret;
+
+       ret = smsc95xx_eeprom_confirm_not_busy(dev);
+       if (ret)
+               return ret;
+
+       /* Issue write/erase enable command */
+       val = E2P_CMD_BUSY_ | E2P_CMD_EWEN_;
+       ret = smsc95xx_write_reg(dev, E2P_CMD, val);
+       if (ret < 0)
+               return ret;
+
+       ret = smsc95xx_wait_eeprom(dev);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < length; i++) {
+               /* Fill data register */
+               val = data[i];
+               ret = smsc95xx_write_reg(dev, E2P_DATA, val);
+               if (ret < 0)
+                       return ret;
+
+               /* Send "write" command */
+               val = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ |
+                       (offset & E2P_CMD_ADDR_);
+               ret = smsc95xx_write_reg(dev, E2P_CMD, val);
+               if (ret < 0)
+                       return ret;
+
+               ret = smsc95xx_wait_eeprom(dev);
+               if (ret < 0)
+                       return ret;
+
+               offset++;
+       }
+       return 0;
+}
+
+static int smsc95xx_defaults_eeprom(struct eth_device *eth)
+{
+       return smsc95xx_write_eeprom(eth, 0, sizeof(eeprom_defaults),
+                               eeprom_defaults);
+}
+#endif
+
 /*
  * mii_nway_restart - restart NWay (autonegotiation) for this interface
  *
@@ -349,12 +529,11 @@ static int smsc95xx_phy_initialize(struct ueth_data *dev)
        return 0;
 }
 
-static int smsc95xx_init_mac_address(struct eth_device *eth,
-               struct ueth_data *dev)
+static int smsc95xx_init_mac_address(struct eth_device *eth)
 {
        /* try reading mac address from EEPROM */
-       if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
-                       eth->enetaddr) == 0) {
+       if (smsc95xx_read_eeprom(eth, EEPROM_MAC_OFFSET, ETH_ALEN,
+                                eth->enetaddr) == 0) {
                if (is_valid_ether_addr(eth->enetaddr)) {
                        /* eeprom values are valid so use them */
                        debug("MAC address read from EEPROM\n");
@@ -507,7 +686,7 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd)
                debug("timeout waiting for PHY Reset\n");
                return -1;
        }
-       if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0)
+       if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth) == 0)
                priv->have_hwaddr = 1;
        if (!priv->have_hwaddr) {
                puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n");
@@ -894,6 +1073,12 @@ int smsc95xx_eth_get_info(struct usb_device *dev, struct 
ueth_data *ss,
        eth->recv = smsc95xx_recv;
        eth->halt = smsc95xx_halt;
        eth->write_hwaddr = smsc95xx_write_hwaddr;
+#ifdef CONFIG_CMD_ETH_EEPROM
+       eth->eeprom_read = smsc95xx_read_eeprom;
+       eth->eeprom_write = smsc95xx_write_eeprom;
+       eth->eeprom_defaults = smsc95xx_defaults_eeprom;
+       eth->eeprom_mac_offset = EEPROM_MAC_OFFSET;
+#endif
        eth->priv = ss;
        return 1;
 }
-- 
2.1.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to