1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6xxx SERDES manipulation, via SMI bus 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch> 8 */ 9 10 #include <linux/interrupt.h> 11 #include <linux/irqdomain.h> 12 #include <linux/mii.h> 13 14 #include "chip.h" 15 #include "global2.h" 16 #include "phy.h" 17 #include "port.h" 18 #include "serdes.h" 19 20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg, 21 u16 *val) 22 { 23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES, 24 MV88E6352_SERDES_PAGE_FIBER, 25 reg, val); 26 } 27 28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg, 29 u16 val) 30 { 31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES, 32 MV88E6352_SERDES_PAGE_FIBER, 33 reg, val); 34 } 35 36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 37 int lane, int device, int reg, u16 *val) 38 { 39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 40 41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val); 42 } 43 44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, 45 int lane, int device, int reg, u16 val) 46 { 47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 48 49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val); 50 } 51 52 static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on) 53 { 54 u16 val, new_val; 55 int err; 56 57 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 58 if (err) 59 return err; 60 61 if (on) 62 new_val = val & ~BMCR_PDOWN; 63 else 64 new_val = val | BMCR_PDOWN; 65 66 if (val != new_val) 67 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val); 68 69 return err; 70 } 71 72 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) 73 { 74 u8 cmode = chip->ports[port].cmode; 75 76 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) || 77 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) || 78 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) 79 return true; 80 81 return false; 82 } 83 84 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) 85 { 86 int err; 87 88 if (mv88e6352_port_has_serdes(chip, port)) { 89 err = mv88e6352_serdes_power_set(chip, on); 90 if (err < 0) 91 return err; 92 } 93 94 return 0; 95 } 96 97 struct mv88e6352_serdes_hw_stat { 98 char string[ETH_GSTRING_LEN]; 99 int sizeof_stat; 100 int reg; 101 }; 102 103 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = { 104 { "serdes_fibre_rx_error", 16, 21 }, 105 { "serdes_PRBS_error", 32, 24 }, 106 }; 107 108 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 109 { 110 if (mv88e6352_port_has_serdes(chip, port)) 111 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 112 113 return 0; 114 } 115 116 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 117 int port, uint8_t *data) 118 { 119 struct mv88e6352_serdes_hw_stat *stat; 120 int i; 121 122 if (!mv88e6352_port_has_serdes(chip, port)) 123 return 0; 124 125 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 126 stat = &mv88e6352_serdes_hw_stats[i]; 127 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 128 ETH_GSTRING_LEN); 129 } 130 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 131 } 132 133 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, 134 struct mv88e6352_serdes_hw_stat *stat) 135 { 136 u64 val = 0; 137 u16 reg; 138 int err; 139 140 err = mv88e6352_serdes_read(chip, stat->reg, ®); 141 if (err) { 142 dev_err(chip->dev, "failed to read statistic\n"); 143 return 0; 144 } 145 146 val = reg; 147 148 if (stat->sizeof_stat == 32) { 149 err = mv88e6352_serdes_read(chip, stat->reg + 1, ®); 150 if (err) { 151 dev_err(chip->dev, "failed to read statistic\n"); 152 return 0; 153 } 154 val = val << 16 | reg; 155 } 156 157 return val; 158 } 159 160 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 161 uint64_t *data) 162 { 163 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; 164 struct mv88e6352_serdes_hw_stat *stat; 165 u64 value; 166 int i; 167 168 if (!mv88e6352_port_has_serdes(chip, port)) 169 return 0; 170 171 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > 172 ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); 173 174 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 175 stat = &mv88e6352_serdes_hw_stats[i]; 176 value = mv88e6352_serdes_get_stat(chip, stat); 177 mv88e6xxx_port->serdes_stats[i] += value; 178 data[i] = mv88e6xxx_port->serdes_stats[i]; 179 } 180 181 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 182 } 183 184 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) 185 { 186 struct dsa_switch *ds = chip->ds; 187 u16 status; 188 bool up; 189 190 mv88e6352_serdes_read(chip, MII_BMSR, &status); 191 192 /* Status must be read twice in order to give the current link 193 * status. Otherwise the change in link status since the last 194 * read of the register is returned. 195 */ 196 mv88e6352_serdes_read(chip, MII_BMSR, &status); 197 198 up = status & BMSR_LSTATUS; 199 200 dsa_port_phylink_mac_change(ds, port, up); 201 } 202 203 static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id) 204 { 205 struct mv88e6xxx_port *port = dev_id; 206 struct mv88e6xxx_chip *chip = port->chip; 207 irqreturn_t ret = IRQ_NONE; 208 u16 status; 209 int err; 210 211 mutex_lock(&chip->reg_lock); 212 213 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status); 214 if (err) 215 goto out; 216 217 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) { 218 ret = IRQ_HANDLED; 219 mv88e6352_serdes_irq_link(chip, port->port); 220 } 221 out: 222 mutex_unlock(&chip->reg_lock); 223 224 return ret; 225 } 226 227 static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip) 228 { 229 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 230 MV88E6352_SERDES_INT_LINK_CHANGE); 231 } 232 233 static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip) 234 { 235 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0); 236 } 237 238 int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) 239 { 240 int err; 241 242 if (!mv88e6352_port_has_serdes(chip, port)) 243 return 0; 244 245 chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, 246 MV88E6352_SERDES_IRQ); 247 if (chip->ports[port].serdes_irq < 0) { 248 dev_err(chip->dev, "Unable to map SERDES irq: %d\n", 249 chip->ports[port].serdes_irq); 250 return chip->ports[port].serdes_irq; 251 } 252 253 /* Requesting the IRQ will trigger irq callbacks. So we cannot 254 * hold the reg_lock. 255 */ 256 mutex_unlock(&chip->reg_lock); 257 err = request_threaded_irq(chip->ports[port].serdes_irq, NULL, 258 mv88e6352_serdes_thread_fn, 259 IRQF_ONESHOT, "mv88e6xxx-serdes", 260 &chip->ports[port]); 261 mutex_lock(&chip->reg_lock); 262 263 if (err) { 264 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n", 265 err); 266 return err; 267 } 268 269 return mv88e6352_serdes_irq_enable(chip); 270 } 271 272 void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) 273 { 274 if (!mv88e6352_port_has_serdes(chip, port)) 275 return; 276 277 mv88e6352_serdes_irq_disable(chip); 278 279 /* Freeing the IRQ will trigger irq callbacks. So we cannot 280 * hold the reg_lock. 281 */ 282 mutex_unlock(&chip->reg_lock); 283 free_irq(chip->ports[port].serdes_irq, &chip->ports[port]); 284 mutex_lock(&chip->reg_lock); 285 286 chip->ports[port].serdes_irq = 0; 287 } 288 289 /* Return the SERDES lane address a port is using. Only Ports 9 and 10 290 * have SERDES lanes. Returns -ENODEV if a port does not have a lane. 291 */ 292 static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 293 { 294 u8 cmode = chip->ports[port].cmode; 295 296 switch (port) { 297 case 9: 298 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 299 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 300 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 301 return MV88E6390_PORT9_LANE0; 302 return -ENODEV; 303 case 10: 304 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 305 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 306 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 307 return MV88E6390_PORT10_LANE0; 308 return -ENODEV; 309 default: 310 return -ENODEV; 311 } 312 } 313 314 /* Return the SERDES lane address a port is using. Ports 9 and 10 can 315 * use multiple lanes. If so, return the first lane the port uses. 316 * Returns -ENODEV if a port does not have a lane. 317 */ 318 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 319 { 320 u8 cmode_port9, cmode_port10, cmode_port; 321 322 cmode_port9 = chip->ports[9].cmode; 323 cmode_port10 = chip->ports[10].cmode; 324 cmode_port = chip->ports[port].cmode; 325 326 switch (port) { 327 case 2: 328 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 329 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 330 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 331 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 332 return MV88E6390_PORT9_LANE1; 333 return -ENODEV; 334 case 3: 335 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 336 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 337 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 338 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 339 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 340 return MV88E6390_PORT9_LANE2; 341 return -ENODEV; 342 case 4: 343 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 344 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 345 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 346 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 347 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 348 return MV88E6390_PORT9_LANE3; 349 return -ENODEV; 350 case 5: 351 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 352 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 353 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 354 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 355 return MV88E6390_PORT10_LANE1; 356 return -ENODEV; 357 case 6: 358 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 359 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 360 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 361 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 362 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 363 return MV88E6390_PORT10_LANE2; 364 return -ENODEV; 365 case 7: 366 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 367 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 368 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 369 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 370 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) 371 return MV88E6390_PORT10_LANE3; 372 return -ENODEV; 373 case 9: 374 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 375 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 376 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 377 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || 378 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 379 return MV88E6390_PORT9_LANE0; 380 return -ENODEV; 381 case 10: 382 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 383 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 384 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 385 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || 386 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 387 return MV88E6390_PORT10_LANE0; 388 return -ENODEV; 389 default: 390 return -ENODEV; 391 } 392 } 393 394 /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ 395 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane, 396 bool on) 397 { 398 u16 val, new_val; 399 int err; 400 401 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 402 MV88E6390_PCS_CONTROL_1, &val); 403 404 if (err) 405 return err; 406 407 if (on) 408 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | 409 MV88E6390_PCS_CONTROL_1_LOOPBACK | 410 MV88E6390_PCS_CONTROL_1_PDOWN); 411 else 412 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN; 413 414 if (val != new_val) 415 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 416 MV88E6390_PCS_CONTROL_1, new_val); 417 418 return err; 419 } 420 421 /* Set the power on/off for SGMII and 1000Base-X */ 422 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane, 423 bool on) 424 { 425 u16 val, new_val; 426 int err; 427 428 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 429 MV88E6390_SGMII_CONTROL, &val); 430 if (err) 431 return err; 432 433 if (on) 434 new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET | 435 MV88E6390_SGMII_CONTROL_LOOPBACK | 436 MV88E6390_SGMII_CONTROL_PDOWN); 437 else 438 new_val = val | MV88E6390_SGMII_CONTROL_PDOWN; 439 440 if (val != new_val) 441 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 442 MV88E6390_SGMII_CONTROL, new_val); 443 444 return err; 445 } 446 447 static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port, 448 int lane, bool on) 449 { 450 u8 cmode = chip->ports[port].cmode; 451 452 switch (cmode) { 453 case MV88E6XXX_PORT_STS_CMODE_SGMII: 454 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: 455 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 456 return mv88e6390_serdes_power_sgmii(chip, lane, on); 457 case MV88E6XXX_PORT_STS_CMODE_XAUI: 458 case MV88E6XXX_PORT_STS_CMODE_RXAUI: 459 return mv88e6390_serdes_power_10g(chip, lane, on); 460 } 461 462 return 0; 463 } 464 465 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) 466 { 467 int lane; 468 469 lane = mv88e6390_serdes_get_lane(chip, port); 470 if (lane == -ENODEV) 471 return 0; 472 473 if (lane < 0) 474 return lane; 475 476 switch (port) { 477 case 9 ... 10: 478 return mv88e6390_serdes_power_lane(chip, port, lane, on); 479 } 480 481 return 0; 482 } 483 484 int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) 485 { 486 int lane; 487 488 lane = mv88e6390x_serdes_get_lane(chip, port); 489 if (lane == -ENODEV) 490 return 0; 491 492 if (lane < 0) 493 return lane; 494 495 switch (port) { 496 case 2 ... 4: 497 case 5 ... 7: 498 case 9 ... 10: 499 return mv88e6390_serdes_power_lane(chip, port, lane, on); 500 } 501 502 return 0; 503 } 504 505 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, 506 int port, int lane) 507 { 508 struct dsa_switch *ds = chip->ds; 509 int duplex = DUPLEX_UNKNOWN; 510 int speed = SPEED_UNKNOWN; 511 int link, err; 512 u16 status; 513 514 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 515 MV88E6390_SGMII_PHY_STATUS, &status); 516 if (err) { 517 dev_err(chip->dev, "can't read SGMII PHY status: %d\n", err); 518 return; 519 } 520 521 link = status & MV88E6390_SGMII_PHY_STATUS_LINK ? 522 LINK_FORCED_UP : LINK_FORCED_DOWN; 523 524 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { 525 duplex = status & MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? 526 DUPLEX_FULL : DUPLEX_HALF; 527 528 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) { 529 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000: 530 speed = SPEED_1000; 531 break; 532 case MV88E6390_SGMII_PHY_STATUS_SPEED_100: 533 speed = SPEED_100; 534 break; 535 case MV88E6390_SGMII_PHY_STATUS_SPEED_10: 536 speed = SPEED_10; 537 break; 538 default: 539 dev_err(chip->dev, "invalid PHY speed\n"); 540 return; 541 } 542 } 543 544 err = mv88e6xxx_port_setup_mac(chip, port, link, speed, duplex, 545 PAUSE_OFF, PHY_INTERFACE_MODE_NA); 546 if (err) 547 dev_err(chip->dev, "can't propagate PHY settings to MAC: %d\n", 548 err); 549 else 550 dsa_port_phylink_mac_change(ds, port, link == LINK_FORCED_UP); 551 } 552 553 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, 554 int lane) 555 { 556 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 557 MV88E6390_SGMII_INT_ENABLE, 558 MV88E6390_SGMII_INT_LINK_DOWN | 559 MV88E6390_SGMII_INT_LINK_UP); 560 } 561 562 static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip, 563 int lane) 564 { 565 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 566 MV88E6390_SGMII_INT_ENABLE, 0); 567 } 568 569 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, 570 int lane) 571 { 572 u8 cmode = chip->ports[port].cmode; 573 int err = 0; 574 575 switch (cmode) { 576 case MV88E6XXX_PORT_STS_CMODE_SGMII: 577 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: 578 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 579 err = mv88e6390_serdes_irq_enable_sgmii(chip, lane); 580 } 581 582 return err; 583 } 584 585 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, 586 int lane) 587 { 588 u8 cmode = chip->ports[port].cmode; 589 int err = 0; 590 591 switch (cmode) { 592 case MV88E6XXX_PORT_STS_CMODE_SGMII: 593 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: 594 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 595 err = mv88e6390_serdes_irq_disable_sgmii(chip, lane); 596 } 597 598 return err; 599 } 600 601 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, 602 int lane, u16 *status) 603 { 604 int err; 605 606 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 607 MV88E6390_SGMII_INT_STATUS, status); 608 609 return err; 610 } 611 612 static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) 613 { 614 struct mv88e6xxx_port *port = dev_id; 615 struct mv88e6xxx_chip *chip = port->chip; 616 irqreturn_t ret = IRQ_NONE; 617 u8 cmode = port->cmode; 618 u16 status; 619 int lane; 620 int err; 621 622 lane = mv88e6390x_serdes_get_lane(chip, port->port); 623 624 mutex_lock(&chip->reg_lock); 625 626 switch (cmode) { 627 case MV88E6XXX_PORT_STS_CMODE_SGMII: 628 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: 629 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 630 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 631 if (err) 632 goto out; 633 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 634 MV88E6390_SGMII_INT_LINK_UP)) { 635 ret = IRQ_HANDLED; 636 mv88e6390_serdes_irq_link_sgmii(chip, port->port, lane); 637 } 638 } 639 out: 640 mutex_unlock(&chip->reg_lock); 641 642 return ret; 643 } 644 645 int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) 646 { 647 int lane; 648 int err; 649 650 lane = mv88e6390x_serdes_get_lane(chip, port); 651 652 if (lane == -ENODEV) 653 return 0; 654 655 if (lane < 0) 656 return lane; 657 658 chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, 659 port); 660 if (chip->ports[port].serdes_irq < 0) { 661 dev_err(chip->dev, "Unable to map SERDES irq: %d\n", 662 chip->ports[port].serdes_irq); 663 return chip->ports[port].serdes_irq; 664 } 665 666 /* Requesting the IRQ will trigger irq callbacks. So we cannot 667 * hold the reg_lock. 668 */ 669 mutex_unlock(&chip->reg_lock); 670 err = request_threaded_irq(chip->ports[port].serdes_irq, NULL, 671 mv88e6390_serdes_thread_fn, 672 IRQF_ONESHOT, "mv88e6xxx-serdes", 673 &chip->ports[port]); 674 mutex_lock(&chip->reg_lock); 675 676 if (err) { 677 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n", 678 err); 679 return err; 680 } 681 682 return mv88e6390_serdes_irq_enable(chip, port, lane); 683 } 684 685 int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) 686 { 687 if (port < 9) 688 return 0; 689 690 return mv88e6390x_serdes_irq_setup(chip, port); 691 } 692 693 void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) 694 { 695 int lane = mv88e6390x_serdes_get_lane(chip, port); 696 697 if (lane == -ENODEV) 698 return; 699 700 if (lane < 0) 701 return; 702 703 mv88e6390_serdes_irq_disable(chip, port, lane); 704 705 /* Freeing the IRQ will trigger irq callbacks. So we cannot 706 * hold the reg_lock. 707 */ 708 mutex_unlock(&chip->reg_lock); 709 free_irq(chip->ports[port].serdes_irq, &chip->ports[port]); 710 mutex_lock(&chip->reg_lock); 711 712 chip->ports[port].serdes_irq = 0; 713 } 714 715 void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) 716 { 717 if (port < 9) 718 return; 719 720 mv88e6390x_serdes_irq_free(chip, port); 721 } 722 723 int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) 724 { 725 u8 cmode = chip->ports[port].cmode; 726 727 if (port != 5) 728 return 0; 729 730 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || 731 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 732 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 733 return mv88e6390_serdes_power_sgmii(chip, MV88E6341_ADDR_SERDES, 734 on); 735 736 return 0; 737 } 738