dsa: mv88e6xxx: Handle eeprom-length property
authorAndrew Lunn <andrew@lunn.ch>
Tue, 10 May 2016 21:27:25 +0000 (23:27 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 May 2016 23:36:29 +0000 (19:36 -0400)
A switch can export an attached EEPROM using the standard ethtool API.
However the switch itself cannot determine the size of the EEPROM, and
multiple sizes are allowed. Thus a device tree property is supported
to indicate the length of the EEPROM. Parse this property during
device probe, and implement a callback function to retrieve it.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx.c
drivers/net/dsa/mv88e6xxx.h

index ee7830935a737f91dc9d8c54162a894038a58629..a3f0e7ec406766733df313f0bc1f7c73d24461e3 100644 (file)
@@ -869,6 +869,16 @@ error:
        return ret;
 }
 
+static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
+{
+       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+       if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+               return ps->eeprom_len;
+
+       return 0;
+}
+
 static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
                                struct ethtool_eeprom *eeprom, u8 *data)
 {
@@ -3610,6 +3620,7 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
        .set_temp_limit         = mv88e6xxx_set_temp_limit,
        .get_temp_alarm         = mv88e6xxx_get_temp_alarm,
 #endif
+       .get_eeprom_len         = mv88e6xxx_get_eeprom_len,
        .get_eeprom             = mv88e6xxx_get_eeprom,
        .set_eeprom             = mv88e6xxx_set_eeprom,
        .get_regs_len           = mv88e6xxx_get_regs_len,
@@ -3631,9 +3642,11 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
 int mv88e6xxx_probe(struct mdio_device *mdiodev)
 {
        struct device *dev = &mdiodev->dev;
+       struct device_node *np = dev->of_node;
        struct mv88e6xxx_priv_state *ps;
        int id, prod_num, rev;
        struct dsa_switch *ds;
+       u32 eeprom_len;
        int err;
 
        ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL);
@@ -3676,6 +3689,10 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev)
                }
        }
 
+       if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM) &&
+           !of_property_read_u32(np, "eeprom-length", &eeprom_len))
+               ps->eeprom_len = eeprom_len;
+
        dev_set_drvdata(dev, ds);
 
        dev_info(dev, "switch 0x%x probed: %s, revision %u\n",
index 9ef7673f0c61f363207a5c26dd8d4ba87a6ddc3e..40e8721ecfb1d0832697bf653f90d2d84792f011 100644 (file)
@@ -602,6 +602,9 @@ struct mv88e6xxx_priv_state {
         * switch soft reset.
         */
        struct gpio_desc *reset;
+
+       /* set to size of eeprom if supported by the switch */
+       int             eeprom_len;
 };
 
 enum stat_type {