1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright 2021 NXP 3 */ 4 #include <linux/pcs/pcs-xpcs.h> 5 #include <linux/of_mdio.h> 6 #include "sja1105.h" 7 8 #define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc) 9 10 int sja1105_pcs_mdio_read_c45(struct mii_bus *bus, int phy, int mmd, int reg) 11 { 12 struct sja1105_mdio_private *mdio_priv = bus->priv; 13 struct sja1105_private *priv = mdio_priv->priv; 14 u64 addr; 15 u32 tmp; 16 int rc; 17 18 addr = (mmd << 16) | reg; 19 20 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2) 21 return 0xffff; 22 23 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1) 24 return NXP_SJA1105_XPCS_ID >> 16; 25 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2) 26 return NXP_SJA1105_XPCS_ID & GENMASK(15, 0); 27 28 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); 29 if (rc < 0) 30 return rc; 31 32 return tmp & 0xffff; 33 } 34 35 int sja1105_pcs_mdio_write_c45(struct mii_bus *bus, int phy, int mmd, 36 int reg, u16 val) 37 { 38 struct sja1105_mdio_private *mdio_priv = bus->priv; 39 struct sja1105_private *priv = mdio_priv->priv; 40 u64 addr; 41 u32 tmp; 42 43 addr = (mmd << 16) | reg; 44 tmp = val; 45 46 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2) 47 return -EINVAL; 48 49 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); 50 } 51 52 int sja1110_pcs_mdio_read_c45(struct mii_bus *bus, int phy, int mmd, int reg) 53 { 54 struct sja1105_mdio_private *mdio_priv = bus->priv; 55 struct sja1105_private *priv = mdio_priv->priv; 56 const struct sja1105_regs *regs = priv->info->regs; 57 int offset, bank; 58 u64 addr; 59 u32 tmp; 60 int rc; 61 62 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR) 63 return -ENODEV; 64 65 addr = (mmd << 16) | reg; 66 67 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1) 68 return NXP_SJA1110_XPCS_ID >> 16; 69 if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2) 70 return NXP_SJA1110_XPCS_ID & GENMASK(15, 0); 71 72 bank = addr >> 8; 73 offset = addr & GENMASK(7, 0); 74 75 /* This addressing scheme reserves register 0xff for the bank address 76 * register, so that can never be addressed. 77 */ 78 if (WARN_ON(offset == 0xff)) 79 return -ENODEV; 80 81 tmp = bank; 82 83 rc = sja1105_xfer_u32(priv, SPI_WRITE, 84 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG, 85 &tmp, NULL); 86 if (rc < 0) 87 return rc; 88 89 rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset, 90 &tmp, NULL); 91 if (rc < 0) 92 return rc; 93 94 return tmp & 0xffff; 95 } 96 97 int sja1110_pcs_mdio_write_c45(struct mii_bus *bus, int phy, int reg, int mmd, 98 u16 val) 99 { 100 struct sja1105_mdio_private *mdio_priv = bus->priv; 101 struct sja1105_private *priv = mdio_priv->priv; 102 const struct sja1105_regs *regs = priv->info->regs; 103 int offset, bank; 104 u64 addr; 105 u32 tmp; 106 int rc; 107 108 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR) 109 return -ENODEV; 110 111 addr = (mmd << 16) | reg; 112 113 bank = addr >> 8; 114 offset = addr & GENMASK(7, 0); 115 116 /* This addressing scheme reserves register 0xff for the bank address 117 * register, so that can never be addressed. 118 */ 119 if (WARN_ON(offset == 0xff)) 120 return -ENODEV; 121 122 tmp = bank; 123 124 rc = sja1105_xfer_u32(priv, SPI_WRITE, 125 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG, 126 &tmp, NULL); 127 if (rc < 0) 128 return rc; 129 130 tmp = val; 131 132 return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset, 133 &tmp, NULL); 134 } 135 136 enum sja1105_mdio_opcode { 137 SJA1105_C45_ADDR = 0, 138 SJA1105_C22 = 1, 139 SJA1105_C45_DATA = 2, 140 SJA1105_C45_DATA_AUTOINC = 3, 141 }; 142 143 static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv, 144 int phy, enum sja1105_mdio_opcode op, 145 int xad) 146 { 147 const struct sja1105_regs *regs = priv->info->regs; 148 149 return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0); 150 } 151 152 static int sja1105_base_t1_mdio_read_c22(struct mii_bus *bus, int phy, int reg) 153 { 154 struct sja1105_mdio_private *mdio_priv = bus->priv; 155 struct sja1105_private *priv = mdio_priv->priv; 156 u64 addr; 157 u32 tmp; 158 int rc; 159 160 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); 161 162 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); 163 if (rc < 0) 164 return rc; 165 166 return tmp & 0xffff; 167 } 168 169 static int sja1105_base_t1_mdio_read_c45(struct mii_bus *bus, int phy, 170 int mmd, int reg) 171 { 172 struct sja1105_mdio_private *mdio_priv = bus->priv; 173 struct sja1105_private *priv = mdio_priv->priv; 174 u64 addr; 175 u32 tmp; 176 int rc; 177 178 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, mmd); 179 180 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, ®, NULL); 181 if (rc < 0) 182 return rc; 183 184 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, mmd); 185 186 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); 187 if (rc < 0) 188 return rc; 189 190 return tmp & 0xffff; 191 } 192 193 static int sja1105_base_t1_mdio_write_c22(struct mii_bus *bus, int phy, int reg, 194 u16 val) 195 { 196 struct sja1105_mdio_private *mdio_priv = bus->priv; 197 struct sja1105_private *priv = mdio_priv->priv; 198 u64 addr; 199 u32 tmp; 200 201 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); 202 203 tmp = val & 0xffff; 204 205 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); 206 } 207 208 static int sja1105_base_t1_mdio_write_c45(struct mii_bus *bus, int phy, 209 int mmd, int reg, u16 val) 210 { 211 struct sja1105_mdio_private *mdio_priv = bus->priv; 212 struct sja1105_private *priv = mdio_priv->priv; 213 u64 addr; 214 u32 tmp; 215 int rc; 216 217 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, mmd); 218 219 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, ®, NULL); 220 if (rc < 0) 221 return rc; 222 223 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, mmd); 224 225 tmp = val & 0xffff; 226 227 return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); 228 } 229 230 static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg) 231 { 232 struct sja1105_mdio_private *mdio_priv = bus->priv; 233 struct sja1105_private *priv = mdio_priv->priv; 234 const struct sja1105_regs *regs = priv->info->regs; 235 u32 tmp; 236 int rc; 237 238 rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, 239 &tmp, NULL); 240 if (rc < 0) 241 return rc; 242 243 return tmp & 0xffff; 244 } 245 246 static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg, 247 u16 val) 248 { 249 struct sja1105_mdio_private *mdio_priv = bus->priv; 250 struct sja1105_private *priv = mdio_priv->priv; 251 const struct sja1105_regs *regs = priv->info->regs; 252 u32 tmp = val; 253 254 return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, 255 &tmp, NULL); 256 } 257 258 static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv, 259 struct device_node *mdio_node) 260 { 261 struct sja1105_mdio_private *mdio_priv; 262 struct device_node *np; 263 struct mii_bus *bus; 264 int rc = 0; 265 266 np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio"); 267 if (!np) 268 return 0; 269 270 if (!of_device_is_available(np)) 271 goto out_put_np; 272 273 bus = mdiobus_alloc_size(sizeof(*mdio_priv)); 274 if (!bus) { 275 rc = -ENOMEM; 276 goto out_put_np; 277 } 278 279 bus->name = "SJA1110 100base-TX MDIO bus"; 280 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx", 281 dev_name(priv->ds->dev)); 282 bus->read = sja1105_base_tx_mdio_read; 283 bus->write = sja1105_base_tx_mdio_write; 284 bus->parent = priv->ds->dev; 285 mdio_priv = bus->priv; 286 mdio_priv->priv = priv; 287 288 rc = of_mdiobus_register(bus, np); 289 if (rc) { 290 mdiobus_free(bus); 291 goto out_put_np; 292 } 293 294 priv->mdio_base_tx = bus; 295 296 out_put_np: 297 of_node_put(np); 298 299 return rc; 300 } 301 302 static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv) 303 { 304 if (!priv->mdio_base_tx) 305 return; 306 307 mdiobus_unregister(priv->mdio_base_tx); 308 mdiobus_free(priv->mdio_base_tx); 309 priv->mdio_base_tx = NULL; 310 } 311 312 static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv, 313 struct device_node *mdio_node) 314 { 315 struct sja1105_mdio_private *mdio_priv; 316 struct device_node *np; 317 struct mii_bus *bus; 318 int rc = 0; 319 320 np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio"); 321 if (!np) 322 return 0; 323 324 if (!of_device_is_available(np)) 325 goto out_put_np; 326 327 bus = mdiobus_alloc_size(sizeof(*mdio_priv)); 328 if (!bus) { 329 rc = -ENOMEM; 330 goto out_put_np; 331 } 332 333 bus->name = "SJA1110 100base-T1 MDIO bus"; 334 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1", 335 dev_name(priv->ds->dev)); 336 bus->read = sja1105_base_t1_mdio_read_c22; 337 bus->write = sja1105_base_t1_mdio_write_c22; 338 bus->read_c45 = sja1105_base_t1_mdio_read_c45; 339 bus->write_c45 = sja1105_base_t1_mdio_write_c45; 340 bus->parent = priv->ds->dev; 341 mdio_priv = bus->priv; 342 mdio_priv->priv = priv; 343 344 rc = of_mdiobus_register(bus, np); 345 if (rc) { 346 mdiobus_free(bus); 347 goto out_put_np; 348 } 349 350 priv->mdio_base_t1 = bus; 351 352 out_put_np: 353 of_node_put(np); 354 355 return rc; 356 } 357 358 static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv) 359 { 360 if (!priv->mdio_base_t1) 361 return; 362 363 mdiobus_unregister(priv->mdio_base_t1); 364 mdiobus_free(priv->mdio_base_t1); 365 priv->mdio_base_t1 = NULL; 366 } 367 368 static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) 369 { 370 struct sja1105_mdio_private *mdio_priv; 371 struct dsa_switch *ds = priv->ds; 372 struct mii_bus *bus; 373 int rc = 0; 374 int port; 375 376 if (!priv->info->pcs_mdio_read_c45 || !priv->info->pcs_mdio_write_c45) 377 return 0; 378 379 bus = mdiobus_alloc_size(sizeof(*mdio_priv)); 380 if (!bus) 381 return -ENOMEM; 382 383 bus->name = "SJA1105 PCS MDIO bus"; 384 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs", 385 dev_name(ds->dev)); 386 bus->read_c45 = priv->info->pcs_mdio_read_c45; 387 bus->write_c45 = priv->info->pcs_mdio_write_c45; 388 bus->parent = ds->dev; 389 /* There is no PHY on this MDIO bus => mask out all PHY addresses 390 * from auto probing. 391 */ 392 bus->phy_mask = ~0; 393 mdio_priv = bus->priv; 394 mdio_priv->priv = priv; 395 396 rc = mdiobus_register(bus); 397 if (rc) { 398 mdiobus_free(bus); 399 return rc; 400 } 401 402 for (port = 0; port < ds->num_ports; port++) { 403 struct dw_xpcs *xpcs; 404 405 if (dsa_is_unused_port(ds, port)) 406 continue; 407 408 if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII && 409 priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX) 410 continue; 411 412 xpcs = xpcs_create_mdiodev(bus, port, priv->phy_mode[port]); 413 if (IS_ERR(xpcs)) { 414 rc = PTR_ERR(xpcs); 415 goto out_pcs_free; 416 } 417 418 priv->xpcs[port] = xpcs; 419 } 420 421 priv->mdio_pcs = bus; 422 423 return 0; 424 425 out_pcs_free: 426 for (port = 0; port < ds->num_ports; port++) { 427 if (!priv->xpcs[port]) 428 continue; 429 430 xpcs_destroy(priv->xpcs[port]); 431 priv->xpcs[port] = NULL; 432 } 433 434 mdiobus_unregister(bus); 435 mdiobus_free(bus); 436 437 return rc; 438 } 439 440 static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv) 441 { 442 struct dsa_switch *ds = priv->ds; 443 int port; 444 445 if (!priv->mdio_pcs) 446 return; 447 448 for (port = 0; port < ds->num_ports; port++) { 449 if (!priv->xpcs[port]) 450 continue; 451 452 xpcs_destroy(priv->xpcs[port]); 453 priv->xpcs[port] = NULL; 454 } 455 456 mdiobus_unregister(priv->mdio_pcs); 457 mdiobus_free(priv->mdio_pcs); 458 priv->mdio_pcs = NULL; 459 } 460 461 int sja1105_mdiobus_register(struct dsa_switch *ds) 462 { 463 struct sja1105_private *priv = ds->priv; 464 const struct sja1105_regs *regs = priv->info->regs; 465 struct device_node *switch_node = ds->dev->of_node; 466 struct device_node *mdio_node; 467 int rc; 468 469 rc = sja1105_mdiobus_pcs_register(priv); 470 if (rc) 471 return rc; 472 473 mdio_node = of_get_child_by_name(switch_node, "mdios"); 474 if (!mdio_node) 475 return 0; 476 477 if (!of_device_is_available(mdio_node)) 478 goto out_put_mdio_node; 479 480 if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) { 481 rc = sja1105_mdiobus_base_tx_register(priv, mdio_node); 482 if (rc) 483 goto err_put_mdio_node; 484 } 485 486 if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) { 487 rc = sja1105_mdiobus_base_t1_register(priv, mdio_node); 488 if (rc) 489 goto err_free_base_tx_mdiobus; 490 } 491 492 out_put_mdio_node: 493 of_node_put(mdio_node); 494 495 return 0; 496 497 err_free_base_tx_mdiobus: 498 sja1105_mdiobus_base_tx_unregister(priv); 499 err_put_mdio_node: 500 of_node_put(mdio_node); 501 sja1105_mdiobus_pcs_unregister(priv); 502 503 return rc; 504 } 505 506 void sja1105_mdiobus_unregister(struct dsa_switch *ds) 507 { 508 struct sja1105_private *priv = ds->priv; 509 510 sja1105_mdiobus_base_t1_unregister(priv); 511 sja1105_mdiobus_base_tx_unregister(priv); 512 sja1105_mdiobus_pcs_unregister(priv); 513 } 514