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