0001
0002
0003
0004 #include <linux/pcs/pcs-xpcs.h>
0005 #include <linux/of_mdio.h>
0006 #include "sja1105.h"
0007
0008 #define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc)
0009
0010 int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
0011 {
0012 struct sja1105_mdio_private *mdio_priv = bus->priv;
0013 struct sja1105_private *priv = mdio_priv->priv;
0014 u64 addr;
0015 u32 tmp;
0016 u16 mmd;
0017 int rc;
0018
0019 if (!(reg & MII_ADDR_C45))
0020 return -EINVAL;
0021
0022 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0023 addr = (mmd << 16) | (reg & GENMASK(15, 0));
0024
0025 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
0026 return 0xffff;
0027
0028 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
0029 return NXP_SJA1105_XPCS_ID >> 16;
0030 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
0031 return NXP_SJA1105_XPCS_ID & GENMASK(15, 0);
0032
0033 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
0034 if (rc < 0)
0035 return rc;
0036
0037 return tmp & 0xffff;
0038 }
0039
0040 int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
0041 {
0042 struct sja1105_mdio_private *mdio_priv = bus->priv;
0043 struct sja1105_private *priv = mdio_priv->priv;
0044 u64 addr;
0045 u32 tmp;
0046 u16 mmd;
0047
0048 if (!(reg & MII_ADDR_C45))
0049 return -EINVAL;
0050
0051 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0052 addr = (mmd << 16) | (reg & GENMASK(15, 0));
0053 tmp = val;
0054
0055 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
0056 return -EINVAL;
0057
0058 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
0059 }
0060
0061 int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
0062 {
0063 struct sja1105_mdio_private *mdio_priv = bus->priv;
0064 struct sja1105_private *priv = mdio_priv->priv;
0065 const struct sja1105_regs *regs = priv->info->regs;
0066 int offset, bank;
0067 u64 addr;
0068 u32 tmp;
0069 u16 mmd;
0070 int rc;
0071
0072 if (!(reg & MII_ADDR_C45))
0073 return -EINVAL;
0074
0075 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
0076 return -ENODEV;
0077
0078 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0079 addr = (mmd << 16) | (reg & GENMASK(15, 0));
0080
0081 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
0082 return NXP_SJA1110_XPCS_ID >> 16;
0083 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
0084 return NXP_SJA1110_XPCS_ID & GENMASK(15, 0);
0085
0086 bank = addr >> 8;
0087 offset = addr & GENMASK(7, 0);
0088
0089
0090
0091
0092 if (WARN_ON(offset == 0xff))
0093 return -ENODEV;
0094
0095 tmp = bank;
0096
0097 rc = sja1105_xfer_u32(priv, SPI_WRITE,
0098 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
0099 &tmp, NULL);
0100 if (rc < 0)
0101 return rc;
0102
0103 rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset,
0104 &tmp, NULL);
0105 if (rc < 0)
0106 return rc;
0107
0108 return tmp & 0xffff;
0109 }
0110
0111 int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
0112 {
0113 struct sja1105_mdio_private *mdio_priv = bus->priv;
0114 struct sja1105_private *priv = mdio_priv->priv;
0115 const struct sja1105_regs *regs = priv->info->regs;
0116 int offset, bank;
0117 u64 addr;
0118 u32 tmp;
0119 u16 mmd;
0120 int rc;
0121
0122 if (!(reg & MII_ADDR_C45))
0123 return -EINVAL;
0124
0125 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
0126 return -ENODEV;
0127
0128 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0129 addr = (mmd << 16) | (reg & GENMASK(15, 0));
0130
0131 bank = addr >> 8;
0132 offset = addr & GENMASK(7, 0);
0133
0134
0135
0136
0137 if (WARN_ON(offset == 0xff))
0138 return -ENODEV;
0139
0140 tmp = bank;
0141
0142 rc = sja1105_xfer_u32(priv, SPI_WRITE,
0143 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
0144 &tmp, NULL);
0145 if (rc < 0)
0146 return rc;
0147
0148 tmp = val;
0149
0150 return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset,
0151 &tmp, NULL);
0152 }
0153
0154 enum sja1105_mdio_opcode {
0155 SJA1105_C45_ADDR = 0,
0156 SJA1105_C22 = 1,
0157 SJA1105_C45_DATA = 2,
0158 SJA1105_C45_DATA_AUTOINC = 3,
0159 };
0160
0161 static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv,
0162 int phy, enum sja1105_mdio_opcode op,
0163 int xad)
0164 {
0165 const struct sja1105_regs *regs = priv->info->regs;
0166
0167 return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0);
0168 }
0169
0170 static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg)
0171 {
0172 struct sja1105_mdio_private *mdio_priv = bus->priv;
0173 struct sja1105_private *priv = mdio_priv->priv;
0174 u64 addr;
0175 u32 tmp;
0176 int rc;
0177
0178 if (reg & MII_ADDR_C45) {
0179 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0180
0181 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
0182 mmd);
0183
0184 tmp = reg & MII_REGADDR_C45_MASK;
0185
0186 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
0187 if (rc < 0)
0188 return rc;
0189
0190 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
0191 mmd);
0192
0193 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
0194 if (rc < 0)
0195 return rc;
0196
0197 return tmp & 0xffff;
0198 }
0199
0200
0201 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
0202
0203 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
0204 if (rc < 0)
0205 return rc;
0206
0207 return tmp & 0xffff;
0208 }
0209
0210 static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg,
0211 u16 val)
0212 {
0213 struct sja1105_mdio_private *mdio_priv = bus->priv;
0214 struct sja1105_private *priv = mdio_priv->priv;
0215 u64 addr;
0216 u32 tmp;
0217 int rc;
0218
0219 if (reg & MII_ADDR_C45) {
0220 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
0221
0222 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
0223 mmd);
0224
0225 tmp = reg & MII_REGADDR_C45_MASK;
0226
0227 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
0228 if (rc < 0)
0229 return rc;
0230
0231 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
0232 mmd);
0233
0234 tmp = val & 0xffff;
0235
0236 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
0237 if (rc < 0)
0238 return rc;
0239
0240 return 0;
0241 }
0242
0243
0244 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
0245
0246 tmp = val & 0xffff;
0247
0248 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
0249 }
0250
0251 static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
0252 {
0253 struct sja1105_mdio_private *mdio_priv = bus->priv;
0254 struct sja1105_private *priv = mdio_priv->priv;
0255 const struct sja1105_regs *regs = priv->info->regs;
0256 u32 tmp;
0257 int rc;
0258
0259 rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
0260 &tmp, NULL);
0261 if (rc < 0)
0262 return rc;
0263
0264 return tmp & 0xffff;
0265 }
0266
0267 static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
0268 u16 val)
0269 {
0270 struct sja1105_mdio_private *mdio_priv = bus->priv;
0271 struct sja1105_private *priv = mdio_priv->priv;
0272 const struct sja1105_regs *regs = priv->info->regs;
0273 u32 tmp = val;
0274
0275 return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
0276 &tmp, NULL);
0277 }
0278
0279 static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
0280 struct device_node *mdio_node)
0281 {
0282 struct sja1105_mdio_private *mdio_priv;
0283 struct device_node *np;
0284 struct mii_bus *bus;
0285 int rc = 0;
0286
0287 np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio");
0288 if (!np)
0289 return 0;
0290
0291 if (!of_device_is_available(np))
0292 goto out_put_np;
0293
0294 bus = mdiobus_alloc_size(sizeof(*mdio_priv));
0295 if (!bus) {
0296 rc = -ENOMEM;
0297 goto out_put_np;
0298 }
0299
0300 bus->name = "SJA1110 100base-TX MDIO bus";
0301 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx",
0302 dev_name(priv->ds->dev));
0303 bus->read = sja1105_base_tx_mdio_read;
0304 bus->write = sja1105_base_tx_mdio_write;
0305 bus->parent = priv->ds->dev;
0306 mdio_priv = bus->priv;
0307 mdio_priv->priv = priv;
0308
0309 rc = of_mdiobus_register(bus, np);
0310 if (rc) {
0311 mdiobus_free(bus);
0312 goto out_put_np;
0313 }
0314
0315 priv->mdio_base_tx = bus;
0316
0317 out_put_np:
0318 of_node_put(np);
0319
0320 return rc;
0321 }
0322
0323 static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv)
0324 {
0325 if (!priv->mdio_base_tx)
0326 return;
0327
0328 mdiobus_unregister(priv->mdio_base_tx);
0329 mdiobus_free(priv->mdio_base_tx);
0330 priv->mdio_base_tx = NULL;
0331 }
0332
0333 static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
0334 struct device_node *mdio_node)
0335 {
0336 struct sja1105_mdio_private *mdio_priv;
0337 struct device_node *np;
0338 struct mii_bus *bus;
0339 int rc = 0;
0340
0341 np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio");
0342 if (!np)
0343 return 0;
0344
0345 if (!of_device_is_available(np))
0346 goto out_put_np;
0347
0348 bus = mdiobus_alloc_size(sizeof(*mdio_priv));
0349 if (!bus) {
0350 rc = -ENOMEM;
0351 goto out_put_np;
0352 }
0353
0354 bus->name = "SJA1110 100base-T1 MDIO bus";
0355 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1",
0356 dev_name(priv->ds->dev));
0357 bus->read = sja1105_base_t1_mdio_read;
0358 bus->write = sja1105_base_t1_mdio_write;
0359 bus->parent = priv->ds->dev;
0360 mdio_priv = bus->priv;
0361 mdio_priv->priv = priv;
0362
0363 rc = of_mdiobus_register(bus, np);
0364 if (rc) {
0365 mdiobus_free(bus);
0366 goto out_put_np;
0367 }
0368
0369 priv->mdio_base_t1 = bus;
0370
0371 out_put_np:
0372 of_node_put(np);
0373
0374 return rc;
0375 }
0376
0377 static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv)
0378 {
0379 if (!priv->mdio_base_t1)
0380 return;
0381
0382 mdiobus_unregister(priv->mdio_base_t1);
0383 mdiobus_free(priv->mdio_base_t1);
0384 priv->mdio_base_t1 = NULL;
0385 }
0386
0387 static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
0388 {
0389 struct sja1105_mdio_private *mdio_priv;
0390 struct dsa_switch *ds = priv->ds;
0391 struct mii_bus *bus;
0392 int rc = 0;
0393 int port;
0394
0395 if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write)
0396 return 0;
0397
0398 bus = mdiobus_alloc_size(sizeof(*mdio_priv));
0399 if (!bus)
0400 return -ENOMEM;
0401
0402 bus->name = "SJA1105 PCS MDIO bus";
0403 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs",
0404 dev_name(ds->dev));
0405 bus->read = priv->info->pcs_mdio_read;
0406 bus->write = priv->info->pcs_mdio_write;
0407 bus->parent = ds->dev;
0408
0409
0410
0411 bus->phy_mask = ~0;
0412 mdio_priv = bus->priv;
0413 mdio_priv->priv = priv;
0414
0415 rc = mdiobus_register(bus);
0416 if (rc) {
0417 mdiobus_free(bus);
0418 return rc;
0419 }
0420
0421 for (port = 0; port < ds->num_ports; port++) {
0422 struct mdio_device *mdiodev;
0423 struct dw_xpcs *xpcs;
0424
0425 if (dsa_is_unused_port(ds, port))
0426 continue;
0427
0428 if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII &&
0429 priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX)
0430 continue;
0431
0432 mdiodev = mdio_device_create(bus, port);
0433 if (IS_ERR(mdiodev)) {
0434 rc = PTR_ERR(mdiodev);
0435 goto out_pcs_free;
0436 }
0437
0438 xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
0439 if (IS_ERR(xpcs)) {
0440 rc = PTR_ERR(xpcs);
0441 goto out_pcs_free;
0442 }
0443
0444 priv->xpcs[port] = xpcs;
0445 }
0446
0447 priv->mdio_pcs = bus;
0448
0449 return 0;
0450
0451 out_pcs_free:
0452 for (port = 0; port < ds->num_ports; port++) {
0453 if (!priv->xpcs[port])
0454 continue;
0455
0456 mdio_device_free(priv->xpcs[port]->mdiodev);
0457 xpcs_destroy(priv->xpcs[port]);
0458 priv->xpcs[port] = NULL;
0459 }
0460
0461 mdiobus_unregister(bus);
0462 mdiobus_free(bus);
0463
0464 return rc;
0465 }
0466
0467 static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
0468 {
0469 struct dsa_switch *ds = priv->ds;
0470 int port;
0471
0472 if (!priv->mdio_pcs)
0473 return;
0474
0475 for (port = 0; port < ds->num_ports; port++) {
0476 if (!priv->xpcs[port])
0477 continue;
0478
0479 mdio_device_free(priv->xpcs[port]->mdiodev);
0480 xpcs_destroy(priv->xpcs[port]);
0481 priv->xpcs[port] = NULL;
0482 }
0483
0484 mdiobus_unregister(priv->mdio_pcs);
0485 mdiobus_free(priv->mdio_pcs);
0486 priv->mdio_pcs = NULL;
0487 }
0488
0489 int sja1105_mdiobus_register(struct dsa_switch *ds)
0490 {
0491 struct sja1105_private *priv = ds->priv;
0492 const struct sja1105_regs *regs = priv->info->regs;
0493 struct device_node *switch_node = ds->dev->of_node;
0494 struct device_node *mdio_node;
0495 int rc;
0496
0497 rc = sja1105_mdiobus_pcs_register(priv);
0498 if (rc)
0499 return rc;
0500
0501 mdio_node = of_get_child_by_name(switch_node, "mdios");
0502 if (!mdio_node)
0503 return 0;
0504
0505 if (!of_device_is_available(mdio_node))
0506 goto out_put_mdio_node;
0507
0508 if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
0509 rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
0510 if (rc)
0511 goto err_put_mdio_node;
0512 }
0513
0514 if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
0515 rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
0516 if (rc)
0517 goto err_free_base_tx_mdiobus;
0518 }
0519
0520 out_put_mdio_node:
0521 of_node_put(mdio_node);
0522
0523 return 0;
0524
0525 err_free_base_tx_mdiobus:
0526 sja1105_mdiobus_base_tx_unregister(priv);
0527 err_put_mdio_node:
0528 of_node_put(mdio_node);
0529 sja1105_mdiobus_pcs_unregister(priv);
0530
0531 return rc;
0532 }
0533
0534 void sja1105_mdiobus_unregister(struct dsa_switch *ds)
0535 {
0536 struct sja1105_private *priv = ds->priv;
0537
0538 sja1105_mdiobus_base_t1_unregister(priv);
0539 sja1105_mdiobus_base_tx_unregister(priv);
0540 sja1105_mdiobus_pcs_unregister(priv);
0541 }