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