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