aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex/benet/be_ethtool.c
diff options
context:
space:
mode:
authorAjit Khaparde <ajitkhaparde@gmail.com>2012-04-21 14:53:22 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-23 17:23:29 -0400
commit42f11cf20cc5b76766fd1f0e591eda26283a38ec (patch)
treea5520b1b1fd26a30be075dd0da7f8eb476231ee1 /drivers/net/ethernet/emulex/benet/be_ethtool.c
parentac807fa8e625aff58060876d70298c93a59c4252 (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.c245
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
436static 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
463static 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
515static 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
537bool 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
436static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) 544static 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
554static int 645static int