diff options
author | Ajit Khaparde <ajitkhaparde@gmail.com> | 2012-04-21 14:53:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-23 17:23:29 -0400 |
commit | 42f11cf20cc5b76766fd1f0e591eda26283a38ec (patch) | |
tree | a5520b1b1fd26a30be075dd0da7f8eb476231ee1 /drivers/net/ethernet/emulex/benet/be_ethtool.c | |
parent | ac807fa8e625aff58060876d70298c93a59c4252 (diff) |
be2net: fix ethtool get settings
ethtool get settings was not displaying all the settings correctly.
use the get_phy_info to get more information about the PHY to fix this.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 245 |
1 files changed, 168 insertions, 77 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index c1ff73cb0e62..dc9f74c69c40 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -433,102 +433,193 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) | |||
433 | } | 433 | } |
434 | } | 434 | } |
435 | 435 | ||
436 | static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len) | ||
437 | { | ||
438 | u32 port; | ||
439 | |||
440 | switch (phy_type) { | ||
441 | case PHY_TYPE_BASET_1GB: | ||
442 | case PHY_TYPE_BASEX_1GB: | ||
443 | case PHY_TYPE_SGMII: | ||
444 | port = PORT_TP; | ||
445 | break; | ||
446 | case PHY_TYPE_SFP_PLUS_10GB: | ||
447 | port = dac_cable_len ? PORT_DA : PORT_FIBRE; | ||
448 | break; | ||
449 | case PHY_TYPE_XFP_10GB: | ||
450 | case PHY_TYPE_SFP_1GB: | ||
451 | port = PORT_FIBRE; | ||
452 | break; | ||
453 | case PHY_TYPE_BASET_10GB: | ||
454 | port = PORT_TP; | ||
455 | break; | ||
456 | default: | ||
457 | port = PORT_OTHER; | ||
458 | } | ||
459 | |||
460 | return port; | ||
461 | } | ||
462 | |||
463 | static u32 convert_to_et_setting(u32 if_type, u32 if_speeds) | ||
464 | { | ||
465 | u32 val = 0; | ||
466 | |||
467 | switch (if_type) { | ||
468 | case PHY_TYPE_BASET_1GB: | ||
469 | case PHY_TYPE_BASEX_1GB: | ||
470 | case PHY_TYPE_SGMII: | ||
471 | val |= SUPPORTED_TP; | ||
472 | if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) | ||
473 | val |= SUPPORTED_1000baseT_Full; | ||
474 | if (if_speeds & BE_SUPPORTED_SPEED_100MBPS) | ||
475 | val |= SUPPORTED_100baseT_Full; | ||
476 | if (if_speeds & BE_SUPPORTED_SPEED_10MBPS) | ||
477 | val |= SUPPORTED_10baseT_Full; | ||
478 | break; | ||
479 | case PHY_TYPE_KX4_10GB: | ||
480 | val |= SUPPORTED_Backplane; | ||
481 | if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) | ||
482 | val |= SUPPORTED_1000baseKX_Full; | ||
483 | if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) | ||
484 | val |= SUPPORTED_10000baseKX4_Full; | ||
485 | break; | ||
486 | case PHY_TYPE_KR_10GB: | ||
487 | val |= SUPPORTED_Backplane | | ||
488 | SUPPORTED_10000baseKR_Full; | ||
489 | break; | ||
490 | case PHY_TYPE_SFP_PLUS_10GB: | ||
491 | case PHY_TYPE_XFP_10GB: | ||
492 | case PHY_TYPE_SFP_1GB: | ||
493 | val |= SUPPORTED_FIBRE; | ||
494 | if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) | ||
495 | val |= SUPPORTED_10000baseT_Full; | ||
496 | if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) | ||
497 | val |= SUPPORTED_1000baseT_Full; | ||
498 | break; | ||
499 | case PHY_TYPE_BASET_10GB: | ||
500 | val |= SUPPORTED_TP; | ||
501 | if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) | ||
502 | val |= SUPPORTED_10000baseT_Full; | ||
503 | if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) | ||
504 | val |= SUPPORTED_1000baseT_Full; | ||
505 | if (if_speeds & BE_SUPPORTED_SPEED_100MBPS) | ||
506 | val |= SUPPORTED_100baseT_Full; | ||
507 | break; | ||
508 | default: | ||
509 | val |= SUPPORTED_TP; | ||
510 | } | ||
511 | |||
512 | return val; | ||
513 | } | ||
514 | |||
515 | static int convert_to_et_speed(u32 be_speed) | ||
516 | { | ||
517 | int et_speed = SPEED_10000; | ||
518 | |||
519 | switch (be_speed) { | ||
520 | case PHY_LINK_SPEED_10MBPS: | ||
521 | et_speed = SPEED_10; | ||
522 | break; | ||
523 | case PHY_LINK_SPEED_100MBPS: | ||
524 | et_speed = SPEED_100; | ||
525 | break; | ||
526 | case PHY_LINK_SPEED_1GBPS: | ||
527 | et_speed = SPEED_1000; | ||
528 | break; | ||
529 | case PHY_LINK_SPEED_10GBPS: | ||
530 | et_speed = SPEED_10000; | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | return et_speed; | ||
535 | } | ||
536 | |||
537 | bool be_pause_supported(struct be_adapter *adapter) | ||
538 | { | ||
539 | return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB || | ||
540 | adapter->phy.interface_type == PHY_TYPE_XFP_10GB) ? | ||
541 | false : true; | ||
542 | } | ||
543 | |||
436 | static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 544 | static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
437 | { | 545 | { |
438 | struct be_adapter *adapter = netdev_priv(netdev); | 546 | struct be_adapter *adapter = netdev_priv(netdev); |
439 | struct be_phy_info phy_info; | 547 | u8 port_speed = 0; |
440 | u8 mac_speed = 0; | ||
441 | u16 link_speed = 0; | 548 | u16 link_speed = 0; |
442 | u8 link_status; | 549 | u8 link_status; |
550 | u32 et_speed = 0; | ||
443 | int status; | 551 | int status; |
444 | 552 | ||
445 | if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { | 553 | if (adapter->phy.link_speed < 0 || !(netdev->flags & IFF_UP)) { |
446 | status = be_cmd_link_status_query(adapter, &mac_speed, | 554 | if (adapter->phy.forced_port_speed < 0) { |
447 | &link_speed, &link_status, 0); | 555 | status = be_cmd_link_status_query(adapter, &port_speed, |
448 | if (!status) | 556 | &link_speed, &link_status, 0); |
449 | be_link_status_update(adapter, link_status); | 557 | if (!status) |
450 | 558 | be_link_status_update(adapter, link_status); | |
451 | /* link_speed is in units of 10 Mbps */ | 559 | if (link_speed) |
452 | if (link_speed) { | 560 | et_speed = link_speed; |
453 | ethtool_cmd_speed_set(ecmd, link_speed*10); | 561 | else |
562 | et_speed = convert_to_et_speed(port_speed); | ||
454 | } else { | 563 | } else { |
455 | switch (mac_speed) { | 564 | et_speed = adapter->phy.forced_port_speed; |
456 | case PHY_LINK_SPEED_10MBPS: | ||
457 | ethtool_cmd_speed_set(ecmd, SPEED_10); | ||
458 | break; | ||
459 | case PHY_LINK_SPEED_100MBPS: | ||
460 | ethtool_cmd_speed_set(ecmd, SPEED_100); | ||
461 | break; | ||
462 | case PHY_LINK_SPEED_1GBPS: | ||
463 | ethtool_cmd_speed_set(ecmd, SPEED_1000); | ||
464 | break; | ||
465 | case PHY_LINK_SPEED_10GBPS: | ||
466 | ethtool_cmd_speed_set(ecmd, SPEED_10000); | ||
467 | break; | ||
468 | case PHY_LINK_SPEED_ZERO: | ||
469 | ethtool_cmd_speed_set(ecmd, 0); | ||
470 | break; | ||
471 | } | ||
472 | } | 565 | } |
473 | 566 | ||
474 | status = be_cmd_get_phy_info(adapter, &phy_info); | 567 | ethtool_cmd_speed_set(ecmd, et_speed); |
475 | if (!status) { | 568 | |
476 | switch (phy_info.interface_type) { | 569 | status = be_cmd_get_phy_info(adapter); |
477 | case PHY_TYPE_XFP_10GB: | 570 | if (status) |
478 | case PHY_TYPE_SFP_1GB: | 571 | return status; |
479 | case PHY_TYPE_SFP_PLUS_10GB: | 572 | |
480 | ecmd->port = PORT_FIBRE; | 573 | ecmd->supported = |
481 | break; | 574 | convert_to_et_setting(adapter->phy.interface_type, |
482 | default: | 575 | adapter->phy.auto_speeds_supported | |
483 | ecmd->port = PORT_TP; | 576 | adapter->phy.fixed_speeds_supported); |
484 | break; | 577 | ecmd->advertising = |
485 | } | 578 | convert_to_et_setting(adapter->phy.interface_type, |
579 | adapter->phy.auto_speeds_supported); | ||
486 | 580 | ||
487 | switch (phy_info.interface_type) { | 581 | ecmd->port = be_get_port_type(adapter->phy.interface_type, |
488 | case PHY_TYPE_KR_10GB: | 582 | adapter->phy.dac_cable_len); |
489 | case PHY_TYPE_KX4_10GB: | 583 | |
490 | ecmd->autoneg = AUTONEG_ENABLE; | 584 | if (adapter->phy.auto_speeds_supported) { |
585 | ecmd->supported |= SUPPORTED_Autoneg; | ||
586 | ecmd->autoneg = AUTONEG_ENABLE; | ||
587 | ecmd->advertising |= ADVERTISED_Autoneg; | ||
588 | } | ||
589 | |||
590 | if (be_pause_supported(adapter)) { | ||
591 | ecmd->supported |= SUPPORTED_Pause; | ||
592 | ecmd->advertising |= ADVERTISED_Pause; | ||
593 | } | ||
594 | |||
595 | switch (adapter->phy.interface_type) { | ||
596 | case PHY_TYPE_KR_10GB: | ||
597 | case PHY_TYPE_KX4_10GB: | ||
491 | ecmd->transceiver = XCVR_INTERNAL; | 598 | ecmd->transceiver = XCVR_INTERNAL; |
492 | break; | 599 | break; |
493 | default: | 600 | default: |
494 | ecmd->autoneg = AUTONEG_DISABLE; | 601 | ecmd->transceiver = XCVR_EXTERNAL; |
495 | ecmd->transceiver = XCVR_EXTERNAL; | 602 | break; |
496 | break; | ||
497 | } | ||
498 | } | 603 | } |
499 | 604 | ||
500 | /* Save for future use */ | 605 | /* Save for future use */ |
501 | adapter->link_speed = ethtool_cmd_speed(ecmd); | 606 | adapter->phy.link_speed = ethtool_cmd_speed(ecmd); |
502 | adapter->port_type = ecmd->port; | 607 | adapter->phy.port_type = ecmd->port; |
503 | adapter->transceiver = ecmd->transceiver; | 608 | adapter->phy.transceiver = ecmd->transceiver; |
504 | adapter->autoneg = ecmd->autoneg; | 609 | adapter->phy.autoneg = ecmd->autoneg; |
610 | adapter->phy.advertising = ecmd->advertising; | ||
611 | adapter->phy.supported = ecmd->supported; | ||
505 | } else { | 612 | } else { |
506 | ethtool_cmd_speed_set(ecmd, adapter->link_speed); | 613 | ethtool_cmd_speed_set(ecmd, adapter->phy.link_speed); |
507 | ecmd->port = adapter->port_type; | 614 | ecmd->port = adapter->phy.port_type; |
508 | ecmd->transceiver = adapter->transceiver; | 615 | ecmd->transceiver = adapter->phy.transceiver; |
509 | ecmd->autoneg = adapter->autoneg; | 616 | ecmd->autoneg = adapter->phy.autoneg; |
617 | ecmd->advertising = adapter->phy.advertising; | ||
618 | ecmd->supported = adapter->phy.supported; | ||
510 | } | 619 | } |
511 | 620 | ||
512 | ecmd->duplex = DUPLEX_FULL; | 621 | ecmd->duplex = DUPLEX_FULL; |
513 | ecmd->phy_address = adapter->port_num; | 622 | ecmd->phy_address = adapter->port_num; |
514 | switch (ecmd->port) { | ||
515 | case PORT_FIBRE: | ||
516 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | ||
517 | break; | ||
518 | case PORT_TP: | ||
519 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); | ||
520 | break; | ||
521 | case PORT_AUI: | ||
522 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI); | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | if (ecmd->autoneg) { | ||
527 | ecmd->supported |= SUPPORTED_1000baseT_Full; | ||
528 | ecmd->supported |= SUPPORTED_Autoneg; | ||
529 | ecmd->advertising |= (ADVERTISED_10000baseT_Full | | ||
530 | ADVERTISED_1000baseT_Full); | ||
531 | } | ||
532 | 623 | ||
533 | return 0; | 624 | return 0; |
534 | } | 625 | } |
@@ -548,7 +639,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) | |||
548 | struct be_adapter *adapter = netdev_priv(netdev); | 639 | struct be_adapter *adapter = netdev_priv(netdev); |
549 | 640 | ||
550 | be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause); | 641 | be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause); |
551 | ecmd->autoneg = 0; | 642 | ecmd->autoneg = adapter->phy.fc_autoneg; |
552 | } | 643 | } |
553 | 644 | ||
554 | static int | 645 | static int |