net: dsa: mv88e6xxx: add EEPROM support to 6390
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Thu, 12 Jan 2017 23:07:16 +0000 (18:07 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sat, 14 Jan 2017 01:17:01 +0000 (20:17 -0500)
The Marvell 6352 chip has a 8-bit address/16-bit data EEPROM access.
The Marvell 6390 chip has a 16-bit address/8-bit data EEPROM access.

This patch implements the 8-bit data EEPROM access in the mv88e6xxx
driver and adds its support to chips of the 6390 family.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/global2.c
drivers/net/dsa/mv88e6xxx/global2.h
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h

index eea8e0176e33819fdf2dcdf2191f390ad5c0f52b..987b2dbbd35ae81172d9213db08e195f4511db33 100644 (file)
@@ -3453,6 +3453,8 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
 
 static const struct mv88e6xxx_ops mv88e6190_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3478,6 +3480,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
 
 static const struct mv88e6xxx_ops mv88e6190x_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3503,6 +3507,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
 
 static const struct mv88e6xxx_ops mv88e6191_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3556,6 +3562,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
 
 static const struct mv88e6xxx_ops mv88e6290_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3714,6 +3722,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
 
 static const struct mv88e6xxx_ops mv88e6390_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3741,6 +3751,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
 
 static const struct mv88e6xxx_ops mv88e6390x_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
@@ -3768,6 +3780,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 
 static const struct mv88e6xxx_ops mv88e6391_ops = {
        /* MV88E6XXX_FAMILY_6390 */
+       .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+       .set_eeprom = mv88e6xxx_g2_set_eeprom8,
        .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
        .phy_read = mv88e6xxx_g2_smi_phy_read,
        .phy_write = mv88e6xxx_g2_smi_phy_write,
index 3e77071949ab0ebba03237e0dfb87249fea8b3e4..ead2e265c9ef93d0bca39ecdb918d9b6aec63206 100644 (file)
@@ -218,7 +218,8 @@ static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip)
 }
 
 /* Offset 0x14: EEPROM Command
- * Offset 0x15: EEPROM Data
+ * Offset 0x15: EEPROM Data (for 16-bit data access)
+ * Offset 0x15: EEPROM Addr (for 8-bit data access)
  */
 
 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
@@ -239,6 +240,50 @@ static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
        return mv88e6xxx_g2_eeprom_wait(chip);
 }
 
+static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
+                                    u16 addr, u8 *data)
+{
+       u16 cmd = GLOBAL2_EEPROM_CMD_OP_READ;
+       int err;
+
+       err = mv88e6xxx_g2_eeprom_wait(chip);
+       if (err)
+               return err;
+
+       err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_ADDR, addr);
+       if (err)
+               return err;
+
+       err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
+       if (err)
+               return err;
+
+       err = mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_CMD, &cmd);
+       if (err)
+               return err;
+
+       *data = cmd & 0xff;
+
+       return 0;
+}
+
+static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
+                                     u16 addr, u8 data)
+{
+       u16 cmd = GLOBAL2_EEPROM_CMD_OP_WRITE | GLOBAL2_EEPROM_CMD_WRITE_EN;
+       int err;
+
+       err = mv88e6xxx_g2_eeprom_wait(chip);
+       if (err)
+               return err;
+
+       err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_ADDR, addr);
+       if (err)
+               return err;
+
+       return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
+}
+
 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
                                      u8 addr, u16 *data)
 {
@@ -273,6 +318,52 @@ static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
        return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 }
 
+int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
+                            struct ethtool_eeprom *eeprom, u8 *data)
+{
+       unsigned int offset = eeprom->offset;
+       unsigned int len = eeprom->len;
+       int err;
+
+       eeprom->len = 0;
+
+       while (len) {
+               err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
+               if (err)
+                       return err;
+
+               eeprom->len++;
+               offset++;
+               data++;
+               len--;
+       }
+
+       return 0;
+}
+
+int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
+                            struct ethtool_eeprom *eeprom, u8 *data)
+{
+       unsigned int offset = eeprom->offset;
+       unsigned int len = eeprom->len;
+       int err;
+
+       eeprom->len = 0;
+
+       while (len) {
+               err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
+               if (err)
+                       return err;
+
+               eeprom->len++;
+               offset++;
+               data++;
+               len--;
+       }
+
+       return 0;
+}
+
 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
                              struct ethtool_eeprom *eeprom, u8 *data)
 {
index 9aefb7d8b0ad78dbec865593e0842b91ffc2062b..2918f22388f79ac459c16ff22d85dbb3a37ed9ea 100644 (file)
@@ -28,10 +28,17 @@ int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, int addr, int reg,
 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr, int reg,
                               u16 val);
 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
+
+int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
+                            struct ethtool_eeprom *eeprom, u8 *data);
+int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
+                            struct ethtool_eeprom *eeprom, u8 *data);
+
 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
                              struct ethtool_eeprom *eeprom, u8 *data);
 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
                              struct ethtool_eeprom *eeprom, u8 *data);
+
 int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip);
 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
@@ -67,6 +74,20 @@ static inline int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip,
        return -EOPNOTSUPP;
 }
 
+static inline int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
+                                          struct ethtool_eeprom *eeprom,
+                                          u8 *data)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
+                                          struct ethtool_eeprom *eeprom,
+                                          u8 *data)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
                                            struct ethtool_eeprom *eeprom,
                                            u8 *data)
index a224d66dafd94983fc14bd33923d60e3cfeb4cbe..466cfdadb7bd689c96e31cfa52f5b4c50d8f03f1 100644 (file)
 #define GLOBAL2_EEPROM_CMD_WRITE_EN    BIT(10)
 #define GLOBAL2_EEPROM_CMD_ADDR_MASK   0xff
 #define GLOBAL2_EEPROM_DATA    0x15
+#define GLOBAL2_EEPROM_ADDR    0x15 /* 6390 */
 #define GLOBAL2_PTP_AVB_OP     0x16
 #define GLOBAL2_PTP_AVB_DATA   0x17
 #define GLOBAL2_SMI_PHY_CMD                    0x18