| .. | .. |
|---|
| 224 | 224 | * |
|---|
| 225 | 225 | * See the SFF-8472 specification and related documents for the definition |
|---|
| 226 | 226 | * of these structure members. This can be obtained from |
|---|
| 227 | | - * ftp://ftp.seagate.com/sff |
|---|
| 227 | + * https://www.snia.org/technology-communities/sff/specifications |
|---|
| 228 | 228 | */ |
|---|
| 229 | 229 | struct sfp_eeprom_id { |
|---|
| 230 | 230 | struct sfp_eeprom_base base; |
|---|
| .. | .. |
|---|
| 275 | 275 | __be16 cal_v_offset; |
|---|
| 276 | 276 | } __packed; |
|---|
| 277 | 277 | |
|---|
| 278 | +/* SFF8024 defined constants */ |
|---|
| 279 | +enum { |
|---|
| 280 | + SFF8024_ID_UNK = 0x00, |
|---|
| 281 | + SFF8024_ID_SFF_8472 = 0x02, |
|---|
| 282 | + SFF8024_ID_SFP = 0x03, |
|---|
| 283 | + SFF8024_ID_DWDM_SFP = 0x0b, |
|---|
| 284 | + SFF8024_ID_QSFP_8438 = 0x0c, |
|---|
| 285 | + SFF8024_ID_QSFP_8436_8636 = 0x0d, |
|---|
| 286 | + SFF8024_ID_QSFP28_8636 = 0x11, |
|---|
| 287 | + |
|---|
| 288 | + SFF8024_ENCODING_UNSPEC = 0x00, |
|---|
| 289 | + SFF8024_ENCODING_8B10B = 0x01, |
|---|
| 290 | + SFF8024_ENCODING_4B5B = 0x02, |
|---|
| 291 | + SFF8024_ENCODING_NRZ = 0x03, |
|---|
| 292 | + SFF8024_ENCODING_8472_MANCHESTER= 0x04, |
|---|
| 293 | + SFF8024_ENCODING_8472_SONET = 0x05, |
|---|
| 294 | + SFF8024_ENCODING_8472_64B66B = 0x06, |
|---|
| 295 | + SFF8024_ENCODING_8436_MANCHESTER= 0x06, |
|---|
| 296 | + SFF8024_ENCODING_8436_SONET = 0x04, |
|---|
| 297 | + SFF8024_ENCODING_8436_64B66B = 0x05, |
|---|
| 298 | + SFF8024_ENCODING_256B257B = 0x07, |
|---|
| 299 | + SFF8024_ENCODING_PAM4 = 0x08, |
|---|
| 300 | + |
|---|
| 301 | + SFF8024_CONNECTOR_UNSPEC = 0x00, |
|---|
| 302 | + /* codes 01-05 not supportable on SFP, but some modules have single SC */ |
|---|
| 303 | + SFF8024_CONNECTOR_SC = 0x01, |
|---|
| 304 | + SFF8024_CONNECTOR_FIBERJACK = 0x06, |
|---|
| 305 | + SFF8024_CONNECTOR_LC = 0x07, |
|---|
| 306 | + SFF8024_CONNECTOR_MT_RJ = 0x08, |
|---|
| 307 | + SFF8024_CONNECTOR_MU = 0x09, |
|---|
| 308 | + SFF8024_CONNECTOR_SG = 0x0a, |
|---|
| 309 | + SFF8024_CONNECTOR_OPTICAL_PIGTAIL= 0x0b, |
|---|
| 310 | + SFF8024_CONNECTOR_MPO_1X12 = 0x0c, |
|---|
| 311 | + SFF8024_CONNECTOR_MPO_2X16 = 0x0d, |
|---|
| 312 | + SFF8024_CONNECTOR_HSSDC_II = 0x20, |
|---|
| 313 | + SFF8024_CONNECTOR_COPPER_PIGTAIL= 0x21, |
|---|
| 314 | + SFF8024_CONNECTOR_RJ45 = 0x22, |
|---|
| 315 | + SFF8024_CONNECTOR_NOSEPARATE = 0x23, |
|---|
| 316 | + SFF8024_CONNECTOR_MXC_2X16 = 0x24, |
|---|
| 317 | + |
|---|
| 318 | + SFF8024_ECC_UNSPEC = 0x00, |
|---|
| 319 | + SFF8024_ECC_100G_25GAUI_C2M_AOC = 0x01, |
|---|
| 320 | + SFF8024_ECC_100GBASE_SR4_25GBASE_SR = 0x02, |
|---|
| 321 | + SFF8024_ECC_100GBASE_LR4_25GBASE_LR = 0x03, |
|---|
| 322 | + SFF8024_ECC_100GBASE_ER4_25GBASE_ER = 0x04, |
|---|
| 323 | + SFF8024_ECC_100GBASE_SR10 = 0x05, |
|---|
| 324 | + SFF8024_ECC_100GBASE_CR4 = 0x0b, |
|---|
| 325 | + SFF8024_ECC_25GBASE_CR_S = 0x0c, |
|---|
| 326 | + SFF8024_ECC_25GBASE_CR_N = 0x0d, |
|---|
| 327 | + SFF8024_ECC_10GBASE_T_SFI = 0x16, |
|---|
| 328 | + SFF8024_ECC_10GBASE_T_SR = 0x1c, |
|---|
| 329 | + SFF8024_ECC_5GBASE_T = 0x1d, |
|---|
| 330 | + SFF8024_ECC_2_5GBASE_T = 0x1e, |
|---|
| 331 | +}; |
|---|
| 332 | + |
|---|
| 278 | 333 | /* SFP EEPROM registers */ |
|---|
| 279 | 334 | enum { |
|---|
| 280 | 335 | SFP_PHYS_ID = 0x00, |
|---|
| .. | .. |
|---|
| 309 | 364 | SFP_SFF8472_COMPLIANCE = 0x5e, |
|---|
| 310 | 365 | SFP_CC_EXT = 0x5f, |
|---|
| 311 | 366 | |
|---|
| 312 | | - SFP_PHYS_ID_SFF = 0x02, |
|---|
| 313 | | - SFP_PHYS_ID_SFP = 0x03, |
|---|
| 314 | 367 | SFP_PHYS_EXT_ID_SFP = 0x04, |
|---|
| 315 | | - SFP_CONNECTOR_UNSPEC = 0x00, |
|---|
| 316 | | - /* codes 01-05 not supportable on SFP, but some modules have single SC */ |
|---|
| 317 | | - SFP_CONNECTOR_SC = 0x01, |
|---|
| 318 | | - SFP_CONNECTOR_FIBERJACK = 0x06, |
|---|
| 319 | | - SFP_CONNECTOR_LC = 0x07, |
|---|
| 320 | | - SFP_CONNECTOR_MT_RJ = 0x08, |
|---|
| 321 | | - SFP_CONNECTOR_MU = 0x09, |
|---|
| 322 | | - SFP_CONNECTOR_SG = 0x0a, |
|---|
| 323 | | - SFP_CONNECTOR_OPTICAL_PIGTAIL = 0x0b, |
|---|
| 324 | | - SFP_CONNECTOR_MPO_1X12 = 0x0c, |
|---|
| 325 | | - SFP_CONNECTOR_MPO_2X16 = 0x0d, |
|---|
| 326 | | - SFP_CONNECTOR_HSSDC_II = 0x20, |
|---|
| 327 | | - SFP_CONNECTOR_COPPER_PIGTAIL = 0x21, |
|---|
| 328 | | - SFP_CONNECTOR_RJ45 = 0x22, |
|---|
| 329 | | - SFP_CONNECTOR_NOSEPARATE = 0x23, |
|---|
| 330 | | - SFP_CONNECTOR_MXC_2X16 = 0x24, |
|---|
| 331 | | - SFP_ENCODING_UNSPEC = 0x00, |
|---|
| 332 | | - SFP_ENCODING_8B10B = 0x01, |
|---|
| 333 | | - SFP_ENCODING_4B5B = 0x02, |
|---|
| 334 | | - SFP_ENCODING_NRZ = 0x03, |
|---|
| 335 | | - SFP_ENCODING_8472_MANCHESTER = 0x04, |
|---|
| 336 | | - SFP_ENCODING_8472_SONET = 0x05, |
|---|
| 337 | | - SFP_ENCODING_8472_64B66B = 0x06, |
|---|
| 338 | | - SFP_ENCODING_256B257B = 0x07, |
|---|
| 339 | | - SFP_ENCODING_PAM4 = 0x08, |
|---|
| 340 | 368 | SFP_OPTIONS_HIGH_POWER_LEVEL = BIT(13), |
|---|
| 341 | 369 | SFP_OPTIONS_PAGING_A2 = BIT(12), |
|---|
| 342 | 370 | SFP_OPTIONS_RETIMER = BIT(11), |
|---|
| .. | .. |
|---|
| 428 | 456 | SFP_TEC_CUR = 0x6c, |
|---|
| 429 | 457 | |
|---|
| 430 | 458 | SFP_STATUS = 0x6e, |
|---|
| 459 | + SFP_STATUS_TX_DISABLE = BIT(7), |
|---|
| 460 | + SFP_STATUS_TX_DISABLE_FORCE = BIT(6), |
|---|
| 461 | + SFP_STATUS_TX_FAULT = BIT(2), |
|---|
| 462 | + SFP_STATUS_RX_LOS = BIT(1), |
|---|
| 431 | 463 | SFP_ALARM0 = 0x70, |
|---|
| 432 | 464 | SFP_ALARM0_TEMP_HIGH = BIT(7), |
|---|
| 433 | 465 | SFP_ALARM0_TEMP_LOW = BIT(6), |
|---|
| .. | .. |
|---|
| 464 | 496 | struct fwnode_handle; |
|---|
| 465 | 497 | struct ethtool_eeprom; |
|---|
| 466 | 498 | struct ethtool_modinfo; |
|---|
| 467 | | -struct net_device; |
|---|
| 468 | 499 | struct sfp_bus; |
|---|
| 469 | 500 | |
|---|
| 470 | 501 | /** |
|---|
| 471 | 502 | * struct sfp_upstream_ops - upstream operations structure |
|---|
| 503 | + * @attach: called when the sfp socket driver is bound to the upstream |
|---|
| 504 | + * (mandatory). |
|---|
| 505 | + * @detach: called when the sfp socket driver is unbound from the upstream |
|---|
| 506 | + * (mandatory). |
|---|
| 472 | 507 | * @module_insert: called after a module has been detected to determine |
|---|
| 473 | 508 | * whether the module is supported for the upstream device. |
|---|
| 474 | 509 | * @module_remove: called after the module has been removed. |
|---|
| 510 | + * @module_start: called after the PHY probe step |
|---|
| 511 | + * @module_stop: called before the PHY is removed |
|---|
| 475 | 512 | * @link_down: called when the link is non-operational for whatever |
|---|
| 476 | 513 | * reason. |
|---|
| 477 | 514 | * @link_up: called when the link is operational. |
|---|
| .. | .. |
|---|
| 481 | 518 | * been removed. |
|---|
| 482 | 519 | */ |
|---|
| 483 | 520 | struct sfp_upstream_ops { |
|---|
| 521 | + void (*attach)(void *priv, struct sfp_bus *bus); |
|---|
| 522 | + void (*detach)(void *priv, struct sfp_bus *bus); |
|---|
| 484 | 523 | int (*module_insert)(void *priv, const struct sfp_eeprom_id *id); |
|---|
| 485 | 524 | void (*module_remove)(void *priv); |
|---|
| 525 | + int (*module_start)(void *priv); |
|---|
| 526 | + void (*module_stop)(void *priv); |
|---|
| 486 | 527 | void (*link_down)(void *priv); |
|---|
| 487 | 528 | void (*link_up)(void *priv); |
|---|
| 488 | 529 | int (*connect_phy)(void *priv, struct phy_device *); |
|---|
| .. | .. |
|---|
| 492 | 533 | #if IS_ENABLED(CONFIG_SFP) |
|---|
| 493 | 534 | int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, |
|---|
| 494 | 535 | unsigned long *support); |
|---|
| 536 | +bool sfp_may_have_phy(struct sfp_bus *bus, const struct sfp_eeprom_id *id); |
|---|
| 495 | 537 | void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, |
|---|
| 496 | 538 | unsigned long *support); |
|---|
| 497 | 539 | phy_interface_t sfp_select_interface(struct sfp_bus *bus, |
|---|
| 498 | | - const struct sfp_eeprom_id *id, |
|---|
| 499 | 540 | unsigned long *link_modes); |
|---|
| 500 | 541 | |
|---|
| 501 | 542 | int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo); |
|---|
| .. | .. |
|---|
| 503 | 544 | u8 *data); |
|---|
| 504 | 545 | void sfp_upstream_start(struct sfp_bus *bus); |
|---|
| 505 | 546 | void sfp_upstream_stop(struct sfp_bus *bus); |
|---|
| 506 | | -struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode, |
|---|
| 507 | | - struct net_device *ndev, void *upstream, |
|---|
| 508 | | - const struct sfp_upstream_ops *ops); |
|---|
| 509 | | -void sfp_unregister_upstream(struct sfp_bus *bus); |
|---|
| 547 | +void sfp_bus_put(struct sfp_bus *bus); |
|---|
| 548 | +struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode); |
|---|
| 549 | +int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, |
|---|
| 550 | + const struct sfp_upstream_ops *ops); |
|---|
| 551 | +void sfp_bus_del_upstream(struct sfp_bus *bus); |
|---|
| 510 | 552 | #else |
|---|
| 511 | 553 | static inline int sfp_parse_port(struct sfp_bus *bus, |
|---|
| 512 | 554 | const struct sfp_eeprom_id *id, |
|---|
| 513 | 555 | unsigned long *support) |
|---|
| 514 | 556 | { |
|---|
| 515 | 557 | return PORT_OTHER; |
|---|
| 558 | +} |
|---|
| 559 | + |
|---|
| 560 | +static inline bool sfp_may_have_phy(struct sfp_bus *bus, |
|---|
| 561 | + const struct sfp_eeprom_id *id) |
|---|
| 562 | +{ |
|---|
| 563 | + return false; |
|---|
| 516 | 564 | } |
|---|
| 517 | 565 | |
|---|
| 518 | 566 | static inline void sfp_parse_support(struct sfp_bus *bus, |
|---|
| .. | .. |
|---|
| 522 | 570 | } |
|---|
| 523 | 571 | |
|---|
| 524 | 572 | static inline phy_interface_t sfp_select_interface(struct sfp_bus *bus, |
|---|
| 525 | | - const struct sfp_eeprom_id *id, |
|---|
| 526 | 573 | unsigned long *link_modes) |
|---|
| 527 | 574 | { |
|---|
| 528 | 575 | return PHY_INTERFACE_MODE_NA; |
|---|
| .. | .. |
|---|
| 548 | 595 | { |
|---|
| 549 | 596 | } |
|---|
| 550 | 597 | |
|---|
| 551 | | -static inline struct sfp_bus *sfp_register_upstream( |
|---|
| 552 | | - struct fwnode_handle *fwnode, |
|---|
| 553 | | - struct net_device *ndev, void *upstream, |
|---|
| 554 | | - const struct sfp_upstream_ops *ops) |
|---|
| 598 | +static inline void sfp_bus_put(struct sfp_bus *bus) |
|---|
| 555 | 599 | { |
|---|
| 556 | | - return (struct sfp_bus *)-1; |
|---|
| 557 | 600 | } |
|---|
| 558 | 601 | |
|---|
| 559 | | -static inline void sfp_unregister_upstream(struct sfp_bus *bus) |
|---|
| 602 | +static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) |
|---|
| 603 | +{ |
|---|
| 604 | + return NULL; |
|---|
| 605 | +} |
|---|
| 606 | + |
|---|
| 607 | +static inline int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, |
|---|
| 608 | + const struct sfp_upstream_ops *ops) |
|---|
| 609 | +{ |
|---|
| 610 | + return 0; |
|---|
| 611 | +} |
|---|
| 612 | + |
|---|
| 613 | +static inline void sfp_bus_del_upstream(struct sfp_bus *bus) |
|---|
| 560 | 614 | { |
|---|
| 561 | 615 | } |
|---|
| 562 | 616 | #endif |
|---|