1 diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c 2 index 5c235b5b7022..a285041d0eba 100644 3 --- a/drivers/net/dsa/mv88e6xxx/chip.c 4 +++ b/drivers/net/dsa/mv88e6xxx/chip.c 5 @@ -6538,6 +6538,104 @@ static int __maybe_unused mv88e6xxx_resume(struct device *dev) 6 7 static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume); 8 9 +#define XXX(n) \ 10 +static ssize_t n##_show(struct device *dev, struct device_attribute *a, \ 11 + char *buf) \ 12 +{ \ 13 + struct dsa_switch *ds = dev_get_drvdata(dev); \ 14 + struct mv88e6xxx_chip *chip = ds->priv; \ 15 + \ 16 + return sprintf(buf, "0x%04x\n", chip->regacc_##n); \ 17 +} \ 18 + \ 19 +static ssize_t n##_store(struct device *dev, struct device_attribute *a, \ 20 + const char *buf, size_t count) \ 21 +{ \ 22 + struct dsa_switch *ds = dev_get_drvdata(dev); \ 23 + struct mv88e6xxx_chip *chip = ds->priv; \ 24 + unsigned long val; \ 25 + \ 26 + if (kstrtoul(buf, 16, &val)) \ 27 + return -EINVAL; \ 28 + \ 29 + chip->regacc_##n = val; \ 30 + \ 31 + return count; \ 32 +} \ 33 +static DEVICE_ATTR_RW(n); 34 + 35 +XXX(lane) 36 +XXX(dev) 37 +XXX(reg) 38 + 39 +int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, int lane, int device, int reg, u16 *val); 40 +int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, int lane, int device, int reg, u16 val); 41 + 42 +static ssize_t val_show(struct device *dev, struct device_attribute *a, char *buf) 43 +{ 44 + struct dsa_switch *ds = dev_get_drvdata(dev); 45 + struct mv88e6xxx_chip *chip = ds->priv; 46 + u16 val; 47 + int ret; 48 + 49 + mv88e6xxx_reg_lock(chip); 50 + ret = mv88e6390_serdes_read(chip, chip->regacc_lane, chip->regacc_dev, chip->regacc_reg, &val); 51 + mv88e6xxx_reg_unlock(chip); 52 + 53 + if (ret) 54 + return ret; 55 + 56 + return sprintf(buf, "0x%04x\n", val); 57 +} 58 + 59 +static ssize_t val_store(struct device *dev, struct device_attribute *a, const char *buf, size_t count) 60 +{ 61 + struct dsa_switch *ds = dev_get_drvdata(dev); 62 + struct mv88e6xxx_chip *chip = ds->priv; 63 + unsigned long val; 64 + int ret; 65 + 66 + if (kstrtoul(buf, 16, &val)) 67 + return -EINVAL; 68 + 69 + mv88e6xxx_reg_lock(chip); 70 + ret = mv88e6390_serdes_write(chip, chip->regacc_lane, chip->regacc_dev, chip->regacc_reg, val); 71 + mv88e6xxx_reg_unlock(chip); 72 + 73 + return ret < 0 ? ret : count; 74 +} 75 +static DEVICE_ATTR_RW(val); 76 + 77 +static ssize_t phy_mode_port_9_store(struct device *dev, struct device_attribute *a, const char *buf, size_t count) 78 +{ 79 + struct dsa_switch *ds = dev_get_drvdata(dev); 80 + struct mv88e6xxx_chip *chip = ds->priv; 81 + unsigned long val; 82 + int ret; 83 + 84 + if (kstrtoul(buf, 16, &val) || !val || val >= PHY_INTERFACE_MODE_MAX) 85 + return -EINVAL; 86 + 87 + dev_err(dev, "setting port 9 mode to %s\n", phy_modes(val)); 88 + 89 + mv88e6xxx_reg_lock(chip); 90 + ret = mv88e6xxx_port_setup_mac(chip, 9, LINK_UNFORCED, SPEED_UNFORCED, DUPLEX_UNFORCED, PAUSE_ON, val); 91 + mv88e6xxx_reg_unlock(chip); 92 + 93 + return ret < 0 ? ret : count; 94 +} 95 +static DEVICE_ATTR_WO(phy_mode_port_9); 96 + 97 +static struct attribute *mv88e6xxx_attrs[] = { 98 + &dev_attr_lane.attr, 99 + &dev_attr_dev.attr, 100 + &dev_attr_reg.attr, 101 + &dev_attr_val.attr, 102 + &dev_attr_phy_mode_port_9.attr, 103 + NULL, 104 +}; 105 +ATTRIBUTE_GROUPS(mv88e6xxx); 106 + 107 static int mv88e6xxx_probe(struct mdio_device *mdiodev) 108 { 109 struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data; 110 @@ -6665,6 +6763,9 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev) 111 if (err) 112 goto out_mdio; 113 114 + if (devm_device_add_groups(dev, mv88e6xxx_groups)) 115 + dev_warn(dev, "Could not add attribute group!\n"); 116 + 117 return 0; 118 119 out_mdio: 120 diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h 121 index 73b337478378..0e3b2449b7f7 100644 122 --- a/drivers/net/dsa/mv88e6xxx/chip.h 123 +++ b/drivers/net/dsa/mv88e6xxx/chip.h 124 @@ -290,6 +290,8 @@ struct mv88e6xxx_region_priv { 125 struct mv88e6xxx_chip { 126 const struct mv88e6xxx_info *info; 127 128 + u16 regacc_lane, regacc_dev, regacc_reg; 129 + 130 /* Currently configured tagging protocol */ 131 enum dsa_tag_protocol tag_protocol; 132 133 diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c 134 index d9817b20ea64..8814538e4dd3 100644 135 --- a/drivers/net/dsa/mv88e6xxx/port.c 136 +++ b/drivers/net/dsa/mv88e6xxx/port.c 137 @@ -555,6 +555,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 138 break; 139 case PHY_INTERFACE_MODE_SGMII: 140 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; 141 + cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX; 142 break; 143 case PHY_INTERFACE_MODE_2500BASEX: 144 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; 145 @@ -588,9 +589,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 146 return err; 147 } 148 149 - err = mv88e6xxx_serdes_power_down(chip, port, lane); 150 - if (err) 151 - return err; 152 +// err = mv88e6xxx_serdes_power_down(chip, port, lane); 153 +// if (err) 154 +// return err; 155 } 156 157 chip->ports[port].cmode = 0; 158 @@ -613,6 +614,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 159 if (lane < 0) 160 return lane; 161 162 + err = mv88e6xxx_serdes_power_down(chip, port, lane); 163 + if (err) 164 + return err; 165 err = mv88e6xxx_serdes_power_up(chip, port, lane); 166 if (err) 167 return err; 168 diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c 169 index b70979bd07df..21cb56db08e4 100644 170 --- a/drivers/net/dsa/mv88e6xxx/serdes.c 171 +++ b/drivers/net/dsa/mv88e6xxx/serdes.c 172 @@ -33,7 +33,8 @@ static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg, 173 reg, val); 174 } 175 176 -static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 177 +//static 178 +int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 179 int lane, int device, int reg, u16 *val) 180 { 181 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 182 @@ -41,7 +42,8 @@ static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 183 return mv88e6xxx_phy_read(chip, lane, reg_c45, val); 184 } 185 186 -static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, 187 +//static 188 +int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, 189 int lane, int device, int reg, u16 val) 190 { 191 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;